메뉴 건너뛰기


Developer > Network
제4장. HTTP Message Header
 
더 강의를 진행하기 전에 한가지만 규칙을 정하겠습니다.
여러분이 실습을 해볼 수 있는 내용을 다음과 같이 표시토록하겠습니다.
 
요청OPTIONS / HTTP/1.1
HOST: 
www.w3.org
명령testhttp www.w3.org 80 w3.txt
응답HTTP/1.1 200 OK
Date: Sun, 01 Apr 2007 15:04:28 GMT
Server: Apache/1.3.37 (Unix) PHP/4.4.5
P3P: policyref="
http://www.w3.org/2001/05/P3P/p3p.xml"
Cache-Control: max-age=600
Expires: Sun, 01 Apr 2007 15:14:28 GMT
Content-Length: 0
Allow: GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, PATCH, PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK, TRACE
 
위의 표는 요청항목의 내용을 w3.txt파일에 입력하고 command창에서 명령항목을 실행하면 응답항목의 메시지를 볼 수 있다는 내용입니다. 
 
 
1. HTTP Message Header
 
HTTP Message에 대해서는 이미 1장의 "HTTP의 구성"이라는 주제로 간단히 살펴본 바가 있습니다.
이번장에서는 좀더 자세하게 살펴보도록 하겠습니다.
 
1) HTTP Message의 종류
 
이미 이야기 한대로 HTTP Message에는 요청(Request)과 응답(Response) Message로 나눠집니다.
또한 HTTP Message는 HTTP Version에 따라 HTTP/0.9에서는 Simple Message를 사용하게 되고 HTTP/1.0이상에서는 Full Message를 사용하게 됩니다.
Simple메시지는 Simple 요청으로 "GET Request-URI"라고 보내면 Simple 응답으로 요청한 문서의 본문이 온다는 겁니다. 이런 이유로 Simple메시지는 GET밖에 사용할 수 없고 응답도 Media 형식을 알려 줄 수 없기 때문에 text만 요청하고 돌려줄 수 밖에 없습니다.
하지만 현재의 Web은 이미 HTTP/1.1로 대부분으로 돌아가기 때문에 Simple Message를 굳이 공부할 필요도 없지만 Simple메시지 자체는 정말 Simple하기 때문에 공부할 것도 없습니다.(위에서 이야기 한게 전부니깐요. ㅋㅋ)
 
그럼 Full-Message를 공부해 보도록 하겠습니다. 이미 본 그림이지만 다시 한번 보면서 이야기 하도록 하지요.
http1.gif
 
요청과 응답의 각 Message는 헤더(Header)부분과 본문(Body)부분으로 크게 나뉠 수 있습니다. 헤더부부과 본문부분은 공백라인으로 구분되게 됩니다.
각 메시지 본문부분은 필요하지 않은 경우 생략될 수 있습니다.
또한 각 헤더부분의 제일 첫 라인은 독특한 형식과 의미를 갖습니다. 이를 각각 요청라인(Request Line)과 응답라인(Response Line)이라고 합니다.
메시지 본문을 제외한 부분에서 각 라인의 구분은 연속된 CR/LF문자로 합니다.
CR(Carriage Return) 문자는 10진수로 13, 16진수로 0x0D문자를 의미합니다.
LF(Linefeed) 문자는 10진수로 10, 16진수로 0x0A문자를 의미합니다.
즉, C언어로 Application을 구현한다면 "\n"만을 사용해서는 안되고 "\r\n"으로 라인을 구분해 줘야 한다는 이야기 입니다.
 
2) Message Header의 종류
 
HTTP를 공부하면서 가장 중요한 것은 Header에 사용되는 각 필드의 의미와 사용법을 익히는 것입니다. Header는 크게 일반(General)헤더, 요청(Request)헤더, 응답(Response)헤더, 엔티티(Entity) 네가지로 나눌 수 있습니다.
헤더를 구성할 때는 위의 순서대로 나열할 것을 RFC에서는 권고 하고 있습니다.
그런데 뭐 대부분 이를 지키지 않아도 잘 돌아가는것 같더라구요.
 
일반헤더는 요청과 응답에 모두 사용할 수 있는 헤더를 의미합니다.
요청과 응답헤더는 각각 요청시와 응답시에 사용되는 헤더를 의미합니다.
엔티티헤더는 인코딩 방식, 최종 수정 일자와 같은 외형적인 정보를 나타내기 위해 쓰이는 헤더입니다.
사용자가 필요에 따라 헤더필드를 정의해서 사용할 수도 있는데 이러한 헤더는 엔티티 헤더로 취급됩니다.
 
3) 요청라인과 응답라인
 
요청과 응답 메시지의 첫라인에 사용되는 요청라인과 응답라인은 다음과 같은 형식을 갖습니다.
 
■ 요청라인
 
<Method> <Request-URI> <HTTP Version>
 
앞에서 이야기 한 것 처럼 HTTP/0.9에서 Method는 "GET"만을 사용할 수 있습니다.
HTTP/1.0에서는 "GET", "POST", "HEAD"를 사용할 수 있습니다.
HTTP/1.1에서는 "GET", "POST", "HEAD", "OPTIONS", "PUT", "DELETE", "TRACE", "CONNECT"를 사용할 수 있습니다. HTTP/1.1이 되면서 좀 많죠? 하지만 Web 서버에서 꼭 제공되어야 할 Method는 "GET"과 "HEAD"입니다.
즉, Web 서버 구현에 따라서 다른 Method는 지원되지 않을 수도 있다는 이야기입니다. 
예) GET / HTTP/1.1
 
다음은 각 Method에 대한 설명입니다.
 
- OPTIONS
OPTIONS 메소드는 주로 Web 서버가 어떤 Method를 지원하는지를 알기 위해 사용합니다. 
그럼 www.w3.org의 Web Server가 어떤 Method들을 제공하는지 한번 알아보죠.
 
요청OPTIONS / HTTP/1.1
HOST: 
www.w3.org
명령testhttp www.w3.org 80 w3.txt
응답HTTP/1.1 200 OK
Date: Sun, 01 Apr 2007 15:04:28 GMT
Server: Apache/1.3.37 (Unix) PHP/4.4.5
P3P: policyref="
http://www.w3.org/2001/05/P3P/p3p.xml"
Cache-Control: max-age=600
Expires: Sun, 01 Apr 2007 15:14:28 GMT
Content-Length: 0
Allow: GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, PATCH, PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK, TRACE
 
여기서 주목해야 할 부분이 바로 헤더중 Allow필드입니다. w3의 Web 서버는 GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, PATCH, PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK, TRACE와 같은 Method들을 지원하는 군요.
위의 HTTP/1.1에서 정의한 Method보다 더 많은 Method들을 지원하는 군요.
이것 처럼 모든 Web Server가 정의된 Method를 모두 지원하는 것은 아닙니다. 또한 확장메소드를 만들어 사용할 수도 있죠.
 
- GET
Request-URI의 자원을 Web서버에게 보내달라고 요청합니다.
 
요청GET / HTTP/1.1
HOST: 
www.w3.org
명령testhttp www.w3.org 80 w3_1.txt
응답
HTTP / 1.1 200 OK
Date: Sun, 01 Apr 2007 15:28:28 GMT
Server: Apache/1.3.37 (Unix) PHP/4.4.5
Content-Location: Home.html
Vary: negotiate,accept
TCN: choice
P3P: policyref="http://www.w3.org/2001/05/P3P/p3p.xml"
Cache-Control: max-age=600
Expires: Sun, 01 Apr 2007 15:38:28 GMT
Last-Modified: Sat, 31 Mar 2007 00:31:09 GMT
ETag: "460dabcd;42380ddc"
Accept-Ranges: bytes
Content-Length: 37928
Content-Type: text/html; charset=utf-8
 
<?xml version="1.0" encoding="utf-8"?>
...생략...
 
지금은 응답헤더의 내용을 살펴보기 보다는 Response Body부분으로 온 메시지 본문에 주목해야 될 것입니다. www.w3.org에 /를 요청했더니 Web 서버가 보내준 /에 대한 본문입니다.

- HEAD
서버의 정보 요청합니다.
  
요청HEAD / HTTP/1.1
HOST: 
www.w3.org
명령testhttp www.w3.org 80 w3_2.txt
응답HTTP / 1.1 200 OK
Date: Sun, 01 Apr 2007 15:28:28 GMT
Server: Apache/1.3.37 (Unix) PHP/4.4.5
Content-Location: Home.html
Vary: negotiate,accept
TCN: choice
P3P: policyref="http://www.w3.org/2001/05/P3P/p3p.xml"
Cache-Control: max-age=600
Expires: Sun, 01 Apr 2007 15:38:28 GMT
Last-Modified: Sat, 31 Mar 2007 00:31:09 GMT
ETag: "460dabcd;42380ddc"
Accept-Ranges: bytes
Content-Length: 37928
Content-Type: text/html; charset=utf-8
 
위에서 보는 것과 같이 HEAD Method를 사용하면 Web Server는 GET Method의 응답 중에 Header정보만 보내는 것과 같은 역할을 합니다.
이는 요청하는 URI의 자원이 실제로 있는지를 확인하는데 주로 사용됩니다.
 
- POST
POST Method는 요청메시지 본문의 내용을 Requset URI에 지정되어 있는 자원에서 정한대로 서버에게 수용해 달라고 요청하는 것입니다.
요청
POST /study/http/viewheader.php HTTP/1.1
HOST: 
bbs.nicklib.com
Content-Length: 10
 
1234567890
명령testhttp bbs.nicklib.com 80 nicklib.txt
응답
HTTP/1.1 200 OK
Date: Sun, 01 Apr 2007 15:45:59 GMT
Server: Apache/2.2.3 (Fedora)
X-Powered-By: PHP/5.1.6
Content-Length: 1770
Content-Type: text/html
 
<html>
...생략...
 
확인하기는 좀 어렵습니다만은 "1234567890"이라는 내용을 /study/http/viewheader.php 파일에게 보내고 결과로 응답을 받은 내용을 볼 수 있습니다. POST Method의 특징은 보내는 메시지의 본문이 웹브라우져의 주소창에 나타나지 않는다는 점과 첨부파일과 같이 커다란 메시지를 Web 서버에게 보낼 수 있다는 점이 있습니다. 주로 로그인시 ID와 Password를 전송하거나 파일을 Web 서버로 Upload시킬때 주로 사용합니다.

- PUT
메시지 본문의 내용을 실제 서버쪽에 URI의 위치에 파일로 기록하게 하는 기능을 갖습니다.
이런 기능은 외부에서 Web 서버의 파일을 조작하는 행위가 되기 때문에 대부분의 Web Server에서 지원하지 않는 기능입니다.

- DELETE
URI에 지정된 자원을 삭제하게 됩니다.
PUT과 마찬가지로 보안 문제로 대부분의 Web Server에서 지원하지 않는 기능입니다.

- TRACE
요청한 자원이 수신되는 경로를 보여줍니다.
 
요청
TRACE / HTTP/1.1
HOST: 
www.w3.org
 
명령testhttp www.w3.org 80 w3_3.txt
응답
HTTP/1.1 200 OK
Date: Sun, 01 Apr 2007 15:55:20 GMT
Server: Apache/1.3.37 (Unix) PHP/4.4.5
Transfer-Encoding: chunked
Content-Type: message/http
 
TRACE / HTTP/1.1
HOST: www.w3.org
X_Fwd_IP_Addr: 124.56.134.243
 
- CONNECT
프락시와 같은 중간의 서버에 터널을 형성하여 요청하기 위해 사용합니다.
 
여기서 중요한 Method들은 GET, POST 두가지 입니다.
이 부분은 나중에 다시 설명할 기회가 있을 것입니다.
 
- Request URI
Method 다음에 사용한 Request URI는 앞장에서 이야기한 URI 형식을 사용하면 됩니다.
일반적으로 schem과 호스트 정보 그리고 포트번호가 제거된 상대 URI 상태로 전송됩니다.
예를 들면 절대 URI가 http://www.naver.com:8080/abc/123.htm 인 자원을 요청한다면
 
GET /abc/123.htm HTTP/1.1
 
이라고 요청하면 됩니다.
만약 Proxy Server에게 요청한다면 절대 URI를 이용하여 요청하여야 합니다.
 
 
과 같이 합니다.
 
여기까지는 HTTP/1.0의 스펙이구요. HTTP/1.1에서는 *를 사용할 수 있습니다.
*의 의미는 특정 자원을 지정하지 않고 서버 자체를 의미할 때 사용합니다.
예를 들어 Options과 같은 Method는 서버가 지원하는 Method들이 무엇인지 알기 위해 일반적으로 사용하는데 이때는 특정 자원을 지정할 필요가 없죠. 이럴때 *를 사용합니다.
 
OPTIONS * HTTP/1.1
 
이런식이죠.
 
만약 Proxy Server로 * 를 전송하기 위해서는 다음과 같이 전송하여야 합니다.
 
OPTIONS http://www.naver.com:8080 HTTP/1.1
 
여기서 주의할 점은 절대 URI 뒤에 /가 없다는 것입니다.
/가 있고 없고를 가지고 Proxy는 /로 전송할지 *로 전송할지를 결정하게 되지요.
 
현재 거의 모든 Client가 상대 URI로 전송한다고 할지라도 추후 HTTP 확장을 위해 Web Server는 절대 URI를 처리할 수 있어야 합니다.
절대 URI가 들어오면 HOST헤더 필드에 뭐라고 적혀있더라도 절대 URI에 적혀있는 호스트로 인식해야 합니다.
 
 
■  응답라인
 
<HTTP Version> <Status Code> [Status Message]
 
Status Code는 세자리의 숫자값으로 되어 있으며 백단위로 별로 각 숫자의 의미가 다음과 같이 사용하도록 정의되어 있습니다.
 
1xx : Informational
2xx : Successful
3xx : Redirection
4xx : Client Error
5xx : Server Error
 
Web 서버에 따라 Status Message는 달라질 수도 있고 생략될 수도 있습니다. 하지만 일반적으로 Status Code에 관한 상세 Message가 출력됩니다. RFC에서 정의된 코드별 메시지는 다음과 같습니다.
※ 상태코드 앞에 *를 붙인 것은 HTTP/1.0에서도 지원되는 상태코드입니다. 
"100" Continue (계속)
"101" Switching Protocols (규약 전환)

*"200" OK (성공)
*"201" Created (생성 되었음)
*"202" Accepted (접수 되었음)
"203" Non-Authoritative Information (비 인증 정보)
*"204" No Content (내용이 없음)
"205" Reset Content (내용을 지움)
"206" Partial Content (부분 내용)

"300" Multiple Choices (복수 선택)
*"301" Moved Permanently (영구 이동)
*"302" Found (리소스를 찾았음)
"303" See Other (다른 것을 참조)
*"304" Not Modified (변경되지 않았음)
"305" Use Proxy (프락시를 사용 할 것)
"307" Temporary Redirect (임시 리다이렉트)
 
 
*"400" Bad Request (잘못된 요구)
*"401" Unauthorized (인증되지 않았음)
"402" Payment Required (요금 지불 요청)
*"403" Forbidden (금지되었음)
*"404" Not Found (찾을 수 없음)
"405" Method Not Allowed (Method를 사용할 수 없음)
"406" Not Acceptable (접수 할 수 없음)
"407" Proxy Authentication Required (프락시 인증 필요)
"408" Request Time-out (요구 시간 초과)
"409" Conflict (충돌)
"410" Gone (내용물이 사라졌음)
"411" Length Required (길이가 필요함)
"412" Precondition Failed (사전 조건 충족 실패)
"413" Request Entity Too Large (요구 엔티티가 너무 큼)
"414" Request-URI Too Large (Request URI가 너무 김)
"415" Unsupported Media Type (지원되지 않는 미디어 유형)
"416" Requested range not satisfiable (요청된 범위가 잘못되음)
"417" Expectation Failed (실폐가 기대됨)
 
*"500" Internal Server Error (서버 내부 에러)
*"501" Not Implemented (구현되지 않음)
*"502" Bad Gateway (불량 게이트웨이)
*"503" Service Unavailable (서비스를 사용할 수 없음)
"504" Gateway Time-out (게이트웨이 시간 초과)
"505" HTTP Version not supported (지원되지 않는 HTTP 버전)
 
Status Code는 확장될 수 있습니다. Web Server의 경우 위의 모든 상태를 꼭 처리할 필요는 없지만 첫단위(백단위)의 상태코드는 의미를 지켜 구현해 주어야 합니다.
Status Code의 상세 설명은 필요시에 설명하도록 하겠습니다.
예) HTTP/1.1 200 OK
 
 
4) Message Header의 형식
 
헤더는 "필드명: 필드값"의 형식으로 사용하게 됩니다. (주의 ":" 다음에 한문자 공백이 있어야 합니다.)
필드명은 대소문자를 구별하지 않습니다.
될 수 있으면 하나의 헤더필드는 한라인 안에서 사용할 것을 권장하지만 필드값이 여러라인으로 적혀야 할 경우 두번째 이상의 라인의 첫부분에 적어도 한개의 SP(공백문자) 또는 HT(Horizontal-Tab)문자를 적어 여러 라인으로 하나의 헤더를 구성할 수 있습니다.
또한 같은 필드명에 필드값이 여러번 올 경우 각 필드값들을 comma(,)로 구분하여 나열할 수도 있습니다.
 
규칙을 말로 하니깐 좀 복잡하네요.
다음의 예를 보면 쉽게 이해가 가실 거라 생각됩니다.
 
- 일반적인 헤더의 예
Date: Sun, 01 Apr 2007 12:20:01 GMT
 
- 여러 필드값이 있는 헤더의 예
Cache-control: no-cache, no-store, must-revalidate
위의 헤더는 아래와 같이 사용할 수도 있습니다.
Cache-control: no-cache
Cache-control: no-store
Cache-control: must-revalidate
 
- 여러라인에 필드값을 나눠 쓰는 헤더의 예
Content-Type: multipart/related; type="text/xml";
              boundary="----=_part_0_675311469.1092213273096"
 
 
Creative Commons License
Creative Commons License이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-동일조건변경허락 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
Copyright 조희창(Nicholas Jo). Some rights reserved. http://bbs.nicklib.com