Network

HTTP 프로토콜의 구조

ju_young 2021. 5. 2. 12:15
728x90

TCP/IP에 있는 다른 많은 프로토콜과 마찬가지로 HTTP도 클라이언트와 서버 간에 통신을 한다. 텍스트와 이미지 등과 같은 리소스를 필요하다고 요구하는 쪽이 클라이언트가 되고, 이러한 리소스를 제공하는 쪽이 서버가 된다.

 

HTTP는 클라이언트와 서버의 역할을 명확하게 구별한다.

 

요청(Request)과 응답(Response)

 

HTTP는 클라이언트로부터 요청(Request)이 송신되며, 그 결과가 서버로부터 응답(Response)으로 되돌아온다. 서버 측은 요청을 받지 않고서는 응답을 송신하는 일이 없다. 간단히 말해 서버는 말걸지 않으면 대답하지 않는다.

 

구체적인 예를 들어 클라이언트 측에서 HTTP 서버에 다음과 같은 요청을 송신했다고 하자.

GET /index.html HTTP /1.1
Host: www.hackr.jp

1. "GET" : 서버에 요구하는 종류, 메소드

2. "/index.html" : 요청 URI (요구 대상인 리소스를 나타냄)

3. "HTTP/1.1" : 클라이언트 기능을 식별하기 위한 HTTP 버전 번호

 

즉, 위 요청 내용은 HTTP 서버 상에 있는 "/index.html"이라는 리소스가 필요하다는 것이다.

 

요청(Request) 내용은 다음과 같이 구성되어 있다.

 

Request Structure

그러면 이제 요청을 받은 서버가 처리한 결과를 응답(Response)으로 클라이언트에게 되돌려주자.

 

결과 내용은 다음과 같다고 하자.

HTTP /1.1 200 OK
Date: Tue, 10 Jul  2012 06:50:15 GMT
Content-Length: 362
Content-Type: text/html

<html>
...

 

1. HTTP /1.1 : 서버의 HTTP 버전을 나타냄

2. 200 OK : 요청 처리 결과를 나태내는 상태 코드와 설명

3. Date ~ : 응답이 발생한 일시를 나타내고 헤더 필드라고 불리는 것 중 하나

4. <html> ~ : 바디(body)라고 불리는 리소스 본체, 헤더 필드와는 빈 줄로 구분된다.

 

HTTP는 상태를 유지하지 않는 프로토콜

 

HTTP는 상태를 계속 유지하지 않는 스테이트리스(stateless) 프로토콜이다. HTTP 프로토콜 독자적으로, 요청과 응답을 교환하는 동안 상태를 관리하지 않는다. 즉, 이전에 했던 것들을 전혀 기억하지 못하는 새대가리같은 녀석이다.

 

이는 많은 데이터를 매우 빠르고 확실하게 처리하는 범위성(scalability)을 확보하기 위해서 간단하게 설계된 것이다. 그러나 웹이 진화하면서, 예를 들어 쇼핑 사이트의 로그인 상태를 유지할 필요가 있을 때 스테이트리스 특성만으로 처리하기 어려워지기 시작하였다.

 

그래서 상태를 계속 유지하고 싶은 요구에 부응하기 위해서 쿠키(Cookie)라는 기술이 도입되었다. 쿠키로 인해 HTTP를 이용한 통신에서도 상태를 계속 관리할 수 있게 되었다.

 

요청(Request) URI로 리소스를 식별

 

HTTP는 URI(Uniform Resource Identifiers)를 사용하여 인터넷 상의 리소스를 지정한다. 이 URI가 있는 덕분에 인터넷 상의 어떤 장소에 있는 리소스도 호출할 수 있다.

 

클라이언트는 리소스를 호출할 때 마다 요청시 안에 URI를 Request URI라고 불리는 형식으로 포함해야 할 필요가 있다. Request URI 지정 방법에는 "모든 URI를 Request URI에 포함하는 방법", "Host 레더 필드에 네크워크 로케이션을 포함하는 방법" 등이 있다. 이외에도 특정 리소스가 아닌 서버 자신에게 요청하는 경우에는 Request URI에 [*]을 지정할 수 있다. 예를 들어 "OPTIONS * HTTP/1.1"처럼...

 

HTTP 메소드

 

GET : 리소스 획득

 

GET 메소드는 Request URI로 식별된 리소스를 가져올 수 있도록 요구한다. 가져올 리소스 내용은 지정된 리소스를 서버가 해석한 결과이다. 즉, 리소스가 텍스트이면 그대로 반환하고 GGI와 같은 프로그램이면 실행해서 출력된 내용을 돌려준다.

 

보통 웹 서버에 액세스하여 페이지의 데이터를 읽을 때 사용하는 것이 GET 메소드이다.

 

 

<GET 메소드를 사용한 요청/응답 예>

 

요청 GET /index.html HTTP /1.1
Host: www.hackr.jp
응답 Index.html 리소스를 받아 화면에 표시

 

요청 GET /index.html HTTP /1.1
Host: www.hackr.jp
If-Modified-Sice: Thu. 12 Jul 2012 07:30:0 GMT
응답 Index.html 리소스가 2012년 7월 12일 7시 30분 이후에 갱신된 경우에만 리소스를 되돌려 준다. 그 이전이면 304 Not Modified를 돌려준다.

 

POST : 엔티티 전송

 

POST 메소드는 엔티티를 전송하기 위해서 사용된다. GET으로도 엔티티를 전송할 수 있지만, 일반적으로 POST를 사용한다. POST는 GET과 기능이 비슷하지만 응답에 의한 엔티티를 획득하는 것만이 목적은 아니다.

 

폼에 입력한 데이터를 송신하는 경우에 사용한다. 예를 들어 인터넷 쇼핑이나 이름을 입력하는 것과 같은 입력 필드를 폼이라고 한다.

 

POST 메소드는 요청 메시지 안에 CGI 프로그램(웹 애플리케이션)이나 스크립트에 건네주는 데이터도 쓰는데 이 데이터는 폼에 입력한 값이다. 메시지가 서버에 도착하면 웹 서버 소프트웨어는 URI에 지정된 애플리케이션 프로그램에게 요청 메시지 안에 쓰여있는 데이터를 건네준다. 그리고 이 프로그램이 출력하는 데이터를 받아서 응답 메시지에 포함시킨 후 클라이언트에게 반송한다. (클라이언트 -> 서버 -> 애플리케이션 -> 서버 -> 클라이언트)

 

<POST 메소드를 사용한 요청/응답 예>

 

요청 POST /submit.cgi HTTP /1.1
Host: www.hackr.jp
Content-Length: 1560(1560바이트 데이터)
응답 submit.cgi가 수신한 데이터의 처리한 결과를 돌려줌

 

PUT : 파일 전송

 

PUT 메소드는 파일을 전송하기 위해서 사용된다. FTP(File Transfer Protocol)에 의한 파일 업로드와 같이, 요청 중에 포함된 엔티티를 Request URI로 지정한 곳에 보존하도록 요구한다. (FTP란 한 컴퓨터에서 다른 컴퓨터로 파일을 전송할 수 있도록 하는 방법과 그런 프로그램을 말한다.) URI로 지정한 파일이 없는 경우에는 새로 파일을 작성한다.

 

HTTP/1.1 PUT 자체에는 인증 기능이 없어 누구든지 파일을 업로드 가능하다는 보안 상의 문제도 있어 일반적인 웹사이트에서는 사용되지 않는다. 하지만 웹 애플리케이션 등에 의한 인증 기능과 짝을 이후는 경우나 REST(Representational State Transfer)와 같이 웹끼리 연계하는 설계 양식을 사용할 때 이용하는 경우가 있다.

 

<POST 메소드를 사용한 요청/응답 예>

 

요청 PUT /example.html HTTP /1.1
Host: www.hackr.jp
Content-type: text/html
Content-Length: 1560(1560 바이트 데이터)
응답 상태 코드 204 No Content 응답을 돌려준다(서버 상에 example.html이 작성되어 있다.)

 

HEAD : 메시지 헤더 취득

 

HEAD 메소드는 GET과 같은 기능이지만 메시지 바디는 돌려주지 않는다. URI 유효성과 리소스 갱신 시간을 확인하는 목적 등으로 사용된다. 즉, 서버에 정보를 알려달라고 요청하는 것과 같다고 보면 된다.

 

DELETE : 파일 삭제

 

DELETE 메소드는 파일을 삭제하기 위해 사용된다. Request URI로 지정된 리소스의  삭제를 요구한다.

 

HTTP /1.1의 DELETE 자체에는 PUT 메소드와 같이 인증 기능이 없기 때문에 일반적인 웹 사이트에서는 사용되지 않는다. 사용되는 경우도 PUT 메소드와 같다.

 

OPTIONS : 제공하고 있는 메소드의 문의

 

OPTIONS 메소드는 Request URI로 지정한 리소스가 제공하고 있는 메소드를 조사하기 위해 사용된다. 간단히 말해 서버가 제공하고 있는 메소드들을 알아내기 위해 사용한다는 것이다. 통신 옵션을 통지하거나 조사할 때 사용.

 

TRACE : 경로 조사

 

TRACE 메소드는 Web 서버에 접속해서 자신에게 통신을 되돌려 받는 루프백(loop-back)을 발생시킨다.

 

요청을 보낼 때에 "Max-Forwards"라는 헤더 필드에 수치를 포함시켜 서버를 통과할 때마다 그 수치를 줄여간다. 수치가 0이 된곳을 끝으로, 요청을 마지막으로 수신한 곳에서 상태 코드 "200 OK" 응답을 돌려준다.

 

이것은 프록시 등을 중계하여 오리진(origin) 서버에 접속할 때 그 동작을 확인하기 위해서 사용된다. 프록시 서버 등을 경유할 때 요청 내용이 가공될 경우가 있기 때문에 어떤 요청 내용이 가공되어 있는지 등을 조사할 수 있다.

 

하지만 크로스 사이트 트레이싱(XST)과 같은 공격을 일으키는 보안 상의 문제도 있기 때문에 보통은 사용되지 않는다.

 

*프록시 : 클라이언트가 자신을 통해서 다른 네트워크 서비스에 간접적으로 접속할 수 있게 해 주는 컴퓨터 시스템이나 응용 프로그램을 가리킨다. 서버와 클라이언트 사이에 중계기로서 대리로 통신을 수행하는 것을 가리켜 '프록시', 그 중계 기능을 하는 것을 프록시 서버라고 부른다.

 

CONNECT : 프록시에 터널링 요구

 

CONNECT 메소드는 프록시에 터널 접속 확립을 요함으로서, TCP 통신을 터널링 시키기위해서 사용된다. 주로 SSL과 TLS 등의 프로토콜로 암호화 된 것을 터널링 시키기 위해서 사용된다.

 

암호화한 메시지를 프록시로 전송할 때 이용하는 메소드이다.

 

*터널링

 

 

GET 리소스 취득
POST 엔티티 바디 전송
PUT 파일 전송
HEAD 메시지 헤더 취득
DELETE 파일 삭제
OPTIONS 서포트하고 있는 메소드 문의
TRACE 경로 조사
CONNECT 프록시에의 터널링 요구

 

지속 연결

 

HTTP 초기 버전에서는 HTTP 통신을 한 번 할 때마다 TCP에 의해 연결과 종료를 할 필요가 있었다. 초기 당시에는 작은 용량의 텍스트를 보내는 정도였기 때문에 문제는 없었다. 그러나 현재 HTTP가 널리 보급되면서 다량의 이미지를 포함한 문서 등이 늘어났다.

 

예를 들어 하나의 HTML에 여러 이미지가 포함되어있다면 브라우저를 사용해서 요청을 보내게 된다. 그러면 HTML 문서에 포함되어 있는 여러 이미지들을 가져오기 위해서 여러 요청을 송신하게 된다. 그렇기 때문에 요청을 보낼 떄마다 매변 TCP 연결과 종료를 하게 되는 일이 발생되어 통신량이 늘어나게 된다.

 

이런 문제를 HTTP/1.1과 일부 HTTP/1.0에서는 지속 연결(Persistent Connections)이라는 방법을 고안하였다. 지속 연결의 특징은 어느 한 쪽이 명시적으로 연결을 종료하지 않는 이상 TCP 연결을 계속 유지한다. 또한 TCP 커넥션의 연결과 종료를 반복되는 오버헤드를 줄여주기 때문에 서버에 대한 부하가 경감된다.

 

파이프라인화

 

지속 연결은 여러 요청을 보낼 수 있도록 파이프라인(HTTP pipelining)화를 가능하게 합니다. 파이프라인화에 의해서 이전에는 요청 송신 후에 응답을 수신할 때까지 기다린 뒤에 요청을 발행하던 것을 응답을 기다리지 않고 바로 다음 요청을 보낼 수 있다. 이로 인해 여러 요청을 병행해서 보내는 것이 가능하기 때문에 일일이 응답을 기다릴 필요가 없다.

 

예를 들어 HTML 한 페이지에 10개의 이미지를 포함한 웹 페이지를 요청할 경우에는 개별 연결보다 지속 연결이 요청 완료가 빠르고 지속 연결보다 파이프라인화가 더 빠르다. 이 차이는 요청 수가 늘어날수록 현저하게 나타난다.

 

쿠키

 

HTTP는 스테이트리스 프로토콜이기 때문에 과거에 교환했었던 요청과 응답의 상태를 관리하지 않는다. 상태를 유지하지 않는다는 점에서 서버의 CPU나 메모리 같은 리소스의 소비를 억제할 수 있거나 단순한 프로토콜이기에 HTTP가 다양한 곳에서 이용되는 이점이 있긴 하다.

 

쿠키는 요청과 응답에 쿠키 정보를 추가해서 클라이언트의 상태를 파악하기 위한 시스템이다. 서버에서 응답으로 보내진 Set-Cookie라는 헤더 필드에 의해 쿠키를 클라이언트에 보존하게 된다. 다음으로 클라이언트가 같은 서버로 요청을 보낼 때 자동으로 쿠키 값을 넣어서 송신한다. 서버는 클라이언트가 보내온 쿠키를 확인해서 어느 클라이언트가 접속했는지 체크하고 서버 상의 기록을 확인해서 이전 상태를 알 수 있다.

 

다시 말하면 서버에 처음으로 요청을 보낼 때는 서버가 누구에게 무엇을 전달했는지를 기억하고 쿠키를 발행하여 클라이언트로 응답을 돌려준다. 그러면 서버에는 기록이 남게되고 클라이언트는 발행받는 쿠키를 이후에 요청과 함께 송신하게 된다. 쿠키와 함께 요청을 수신받은 서버는 이전의 기록을 보고 이전 상태를 알 수 있게된다.

 

간단히 비유하면 쿠키는 출입증과 비슷하다고 할 수 있을 것같다.

 

 

**본 글은 "그림으로 배우는 Http&Network Basic"의 내용을 정리하였습니다

728x90

'Network' 카테고리의 다른 글

[웹 브라우저의 동작] 2. IP  (0) 2021.05.14
[웹 브라우저의 동작] 1. HTTP  (0) 2021.05.12
HTTP 상태 코드  (0) 2021.05.05
HTTP 메시지  (0) 2021.05.04
웹과 네트워크의 기본  (0) 2021.04.25