목요일, 5월 9
Shadow

#002 HTTP 1.0 전송규약

HTTP/1.0 (HyperText Transfer Protocol, Version 1.0, RFC 1945)

1. HTTP 개요

1.1 HTTP vs. TCP/IP

HTTP는 World Wide Web에서 사용하고 있는 데이타 전송 프로토콜이며 MIME으로
지정할 수 있는 모든 데이타 형식에 대해 8bit 이진모드로 전송할 수 있다.
(8bit 이진모드 전송이라 함은 1bit도 빠짐없이 완전무결하게 전송한다는 것이며
7bit 아스키모드 전송이라 함은 8bit 기본 단위에서 MSB 1bit의 완전무결성을
보장하지 못 한다는 것이므로 데이타 전송에 오류가 생길 가능성이 있다. 따라서
ASCII 텍스트 문서를 전송할 때는 7bit 아스키모드로 전송을 해도 되지만
실행파일과 같은 binary data를 전송하고자 할 때는 반드시 8bit 이진모드로
전송하여야만 한다.) 이것은 FTP의 경우에서와 같이 이진모드로 데이타 송수신이
가능함을 뜻하며, 다만 WWW용의 추가적인 정보가 HTTP 프로토콜에서 활용되고
있을 뿐이다. 따라서 HTTP 프로토콜은 TCP/IP 프로토콜 체계 가운데 TELNET이나
FTP와 같은 응용 프로토콜의 한 가지이다. 즉, 아래의 그림에서 보이는 것처럼
HTTP는 TELNET처럼 TCP 수송계층 프로토콜을 이용해서 데이타 송수신을 하는 응용
계층 프로토콜의 일종이라는 것이다.

+——+ +——+ +——–+ +——+ +————+ +—–+ +——+ +—–+
| ping | | http | | telnet | | smtp | | traceroute | | dns | | snmp | | nfs |
+–+—+ +–+—+ +—-+—+ +—-+-+ +——+—–+ +-+—+ +—+–+ +—+-+
\        \         |         /           |          \        |       /
\        \        |        /            |           \       |      /
\        \       |       /             |            \      |     /
\        \      |      /              |             \     |    /
\     +–+—–+—–+———-+    |    +———+—-+—+——+
\    |         T C P           |    |    |          U D P          |
\   +——————-+—–+    |    +—-+——————–+
\                       \         |        /
\                       \        |       /
\                       \       |      /
+—–+———-+        +—+——+—–+—+     +————–+
|    I C M P     +——–+        I P         +—–+   I G M P    |
+—————-+        +———-+———+     +————–+
|
|
+—————-+        +———-+———+     +————–+
|      A R P     +——–+     Data Link      +—–+    R A R P   |
+—————-+        +———-+———+     +————–+
|
media

TCP/IP 프로토콜에서는 TCP 전송 프로토콜을 이용하는 응용 프로토콜들 사이의
구별을 port 번호를 통해 해결하고 있다. 그러므로 HTTP 응용 프로토콜에
할당되어 사용하는 TCP 포트가 있으며 80번으로 지정되어 있다. 정의되어 있지
않은 다른 임의의 포트를 이용할 수도 있으나 기본적으로 정의되어 있는 번호는
80번이다.

그렇다고 해서 HTTP 프로토콜은 TCP/IP에서만 동작할 수 있는 것은 아니다.
OSI 참조모델을 이용한 프로토콜 체계에서도 수송계층의 전송 프로토콜
상위에서 HTTP 프로토콜은 응용 프로토콜로서 활용될 수 있는 것이다.
다만 다른 프로토콜 체계에서 사용하고자 할 때는 그에 맞게끔 약간의 적절한
수정을 해야만 가능할 것이다.

버전 1.0 HTTP 프로토콜(HTTP/1.0)은 IETF (Internet Engineering Task
Forces)에 의해 RFC 1945로 정식 등록되었으며, 버전 1.1은(HTTP/1.1)은
Proposed Standard로 등록되어 RFC editor에 의해 재작성된 후 RFC로서 새로이
등록될 예정이다. 현재의 WWW에서 쓰이고 있는 HTTP 프로토콜은 1.0 버전이며
1.1 버전의 것이 구현되고 있는 중이고 ’97년 10월 현재 W3C에서 발표한
Amaya가 1.1 버전을 구현한 것이다.
1.2 HTTP의 등장 배경

실제적인 정보시스템에서는 검색, 정보 갱신, 및 주석 등과 같은 간단한
작업보다는 보다 다양한 기능을 필요로 하고 있다. 또한 분산 환경, 공동작업
환경, 하이퍼미디어 정보시스템 등의 상황에서 필요로 하는 빠른 속도와
간편성을 제공하기 위한 프로토콜이 필요하게 되었고 이를 목적으로 HTTP 응용
프로토콜이 설계되었다.

이에 따라 대상체의 위치나 이름을 지정하는 URI에 의해 제공되는 정보를
이용하여, 대상 화일을 어떻게 활용할 것인가 지정하는 method의 집합에
따라서 적절한 기능 동작을 하게끔 HTTP는 설계되어 있다. 이에 따라
송수신되는 프로토콜 구성체는 메시지라는 이름으로 불리우며 Internet Mail과
MIME에서 사용하는 방식과 비슷하게 구성되어 송수신된다.
1.3 HTTP 프로토콜 규격서에 쓰이는 용어

HTTP 프로토콜 설명서에는 여러 가지 용어들이 쓰이고 있으며 주요 용어들에
대해 설명하도록 한다.

연결(connection)
데이타 송수신을 위해 두 개의 응용 프로그램 사이에 TCP 데이타 전송
프로토콜을 이용해서 만들어진 가상적인 연결선

메시지(message)
HTTP 프로토콜의 통신을 위해 사용되는 기본적인 송수신 단위

요구(request)
HTTP 프로토콜 상에서 브라우저가 어떤 데이타 요구를 하기 위해 보내는
HTTP 메시지

응답(response)
HTTP 프로토콜 상에서 서버가 수신한 요구에 대해 처리한 결과를
브라우저에게 응답으로 보내는 HTTP 메시지

리소스(resource), 자원
URI에 의해 지정될 수 있는 서비스 또는 통신망 상의 데이타

엔터티(entity)
전송 가능한 데이타 자원 또는 어느 서비스 제공용 서버로부터의 응답이
엔터티가 될 수 있으며, 이것은 요구 또는 응답 메시지에 포함될 수
있어야 한다. 엔터티는 그 자체 정보(content)와 이것이 어떤 종류의
데이타인지 알려주는 metainformation으로 구성되어 있다.

클라이언트(client)
HTTP 프로토콜 규약에 맞추어 요구를 보내고 서버가 보내오는 응답을
수신하는 역할을 하며, 이런 송수신을 위해 연결을 설립하는 응용 프로그램.
브라우저라고 불리기도 한다.

브라우저(browser), 사용자 에이전트(user agent)
요구를 발생시키는 역할을 하는 클라이언트 프로그램

서버(server)
요청받은 서비스를 제공해주기 위해 연결을 허용하는 응용 프로그램

origin server
실제 데이타를 저장해두고 있거나 요구에 의해 저장할 수 있는 장소

프락시(proxy)
다른 클라이언트 프로그램과의 사이에서 서버로서도 클라이언트로서도
동작하는 중계 프로그램. requests는 내부적인 동작에 의해 처리되어
제공되든지, 아니면 다른 서버로 전달되든지 한다.

게이트웨이(gateway)
다른 서버와의 중계 역할을 하는 서버. 프락시와는 달리 브라우저가
요구한 것에 대해 마치 실제 서버인양 서비스를 제공해준다. 따라서
브라우저에서는 제공받은 서비스가 게이트웨이로부터 전달된 것인지
모른다.

캐시(cache)
응답받은 메시지를 자신의 컴퓨터에 저장한 장소 또는 저장/검색/삭제가
가능하도록 만든 저장 시스템. 이미 가져온 데이타를 저장해두고 있다가
같은 데이타인 경우 다시 가져오지 않고 저장되어 있는 것을 보여주도록
하여 응답 시간을 빠르게 하고 통신망 이용의 효율성을 높인다.

터널(tunnel)
두 개의 연결 사이에서 무조건 중계(blind relay)의 역할을 하는 중간
프로그램.
1.4 HTTP 프로토콜의 동작

HTTP 프로토콜은 요구/응답 (Request/Response) 방식을 이용하여 동작하고 있다.
즉, 원하는 프로토콜 기능(예: GET, HEAD, POST)에 대해 서비스 요구를 하면
데이타 송수신을 위한 TCP 연결이 만들어지고, 서버가 응답을 보내어 데이타
전송을 끝내면 자동적으로 연결이 끊어지게 되는 것이다.

즉, 클라이언트는 서버와의 사이에 TCP를 기반으로 한 HTTP 연결을 만들고
method, URI, protocol version, 클라이언트 정보, 사용자 데이타 등과 같이
규정되어 있는 요구 형식에 따라 서버에게 요구 메시지를 보낸다. 서버는
프로토콜 버전, 성공 또는 오류코드 번호, 서버 정보, 데이타 정보, 사용자
데이타 등을 포함하는 응답 메시지를 보낸다.

아래 1.4.1과 1.4.2에 요구와 응답의 경우에 대한 간단한 예를 보이고 있다.
1.4.1 Requests

HTTP의 Request 형식은 아주 간단하다. 첫 번째 줄 처음에 어떤 기능을
이용하려는지 지정을 한다. 가장 일반적으로 쓰이고 있는 것이 GET 이다.
이것은 브라우저가 서버에게 문서를 보내달라고 요청하는 것이다. 그 다음에는
화일 이름처럼 대상이 되는 것을 지정하고 현재 쓰이고 있는 HTTP 프로토콜의
버전을 지정한다. 이 다음에는 일련의 지정 사항들을 덧붙일 수가 있은데,
예를 들어 브라우저의 종류나 브라우저가 다룰 수 있는 데이타 형식 등이다.
아래와 같은 예를 볼 수 있다.

Request Example

GET  /index.html  HTTP/1.0
Accept: text/plain
Accept: text/html
Accept: */*
User-Agent: Netscape 1.2
1.4.2 Responses

HTTP에서의 응답 형식도 아주 간단하게 구성되어 있다. 서버에서 쓰이고
있는 프로토콜 버전, Request에 대한 실행 결과, 전달해줄 데이타의 형식,
데이타 길이 등과 같은 추가적인 정보가 전달되고, 이러한 헤더 정보의 끝을
나타내는 빈줄이 들어가고, 뒤이어 실제 데이타가 전달된다. 데이타 전달이
끝나면 서버는 연결을 끊는다. 아래와 같은 예를 볼 수 있다.

Response Example

HTTP/1.0 200 OK
Server: MDMA/0.1
MIME-version: 1.0
Content-type: text/html
Last-Modified: Thu Jul 7 00:25:33 1994
Content-Length: 2003

Right here waiting for you…
1.5 HTTP 프로토콜의 구성

HTTP 프로토콜이 구성되어 있는 형식을 표현하기 위한 방법이 있는데 여기서
사용하는 것은 BNF (Backus-Naur Form) 형식이며 여기에 약간의 보충을 하여
이용하도록 한다. 이를 위해 표현 형식에 대한 설명을 먼저 하도록 하고,
프로토콜 형식의 표기상 사용한 약속을 정의하고, 이어서 HTTP 프로토콜로서
동작하는 메시지의 종류와 구조를 살펴보도록 한다. TCP/IP 연결을 통해
송수신되는 HTTP 프로토콜 데이타는 메시지라는 종류로 구분되고 있다.
즉, 요구 메시지와 이에 대한 응답 메시지가 바로 그것이다. 이 속에 구성되어
있는 규격이 HTTP 프로토콜 규격이 된다.
2. BNF (Backus-Naur Form) 형식

2.1 확장 BNF

이 문서에 포함되어 있는 모든 메카니즘들은 RFC 822에서 사용하고 있는 것과
비슷하게 BNF와 이에 대한 정의 설명으로 표현되어 있다. 구현자들은 이것을
숙지하여 HTTP 프로토콜 규격서를 이해하면서 구현하여야 한다. 확장 BNF는
다음과 같다.

name=definition
어떤 규격의 이름과 이에 대한 정의를 나타내고 있으며 ‘=’ 표시에 의해
구분되고 있다. 빈 공백은(whitespace)는 한 줄 이상의 여러 줄로서
표시되는 규약에 있어 연이은 줄임을 나타내는 들여쓰기(indentation)의
의미로서만 쓰인다. 예를 들어 다음과 같은 예가 있다.

Request = Simple-Request | Full-Request

또는,

Method = “GET”
| “HEAD”
| “POST”
| extension-method

“literal”
‘”‘ 표시 사이에 들어가는 것은 단어 그 자체로서 표현되는 것이다. 따라서
HTTP 프로토콜에서는 이 문자 그대로 송수신된다. 다음과 같은 예를 살펴볼
수 있는데, 뒤에서 나올 프로토콜 규격에 나오는 weekday란 부분은 일곱
가지 요일 가운데 하나가 글자 그대로 전달된다는 것이다.

weekday = “Monday” | “Tuesday” | “Wednesday” | “Thursday”
| “Friday” | “Saturday” | “Sunday”

rule1 | rule2
OR 조건을 나타낸다. 따라서 두 가지 가운데 한 가지를 택할 수 있다는
뜻이다.

(rule1 rule2)
두 가지 요소로 구성되어 있으나 하나의 요소로서 취급한다는 뜻이다.
아래와 같은 예의 경우에,

“(elem (foo | bar) elem)”

이것은 “elem foo elem” 과 “elem bar elem” 두 가지로 구성된다는 뜻이다.

*rule
이것은 반복을 의미하는 것으로서 뒤이어서 나올 #rule과 혼동을 일으키는
표현 방식이므로 유의해야 한다. 반복을 통해 이루어지는 결과는 하나의
단어나 한 개의 수 표현 형태로 되는 것이며 #rule에서는 똑같은 반복이지만
단어나 수의 열 형태로 여러 개가 나올 수 있다. *rule의 표기 방법은
아래와 같이 해서 쓰인다.

<n>*<m>element

이것은 적어도 n개와 최대 m개의 element 요소로 구성되는 한 가지 결과를
의미한다. 즉, 1*2DIGIT 라는 표현은 숫자가 적어도 한 개 최대 두 개로
구성되어 한 개의 수를 나타낸다는 뜻이다. 4는 한 가지 예이며, 45도 한
가지 예가 된다. 그러나 345의 경우에는 숫자 세 개로 구성되어 있으므로
최소 갯수와 최대 갯수에 위배되어 적합하지 않다.

n의 기본값은 0이며 m의 기본값은 무한대이다. 그러므로 “*(element)”는
0개를 포함해서 어떤 갯수라도 가능한 표현법이다. “1*element”의 경우는
적어도 한 개는 있어야 하며 최대 갯수에는 제한이 없다.

[rule]
선택적으로 사용할 수 있다는 뜻이다. 예를 들어, “[foo bar]” 이것은
“foo bar”를 사용할 수도 있고 사용하지 않을 수도 있다는 것이다.
그러므로 “*1(foo bar)”로 표현할 수 있다.

N rule
특정 횟수만큼의 반복을 나타낸다. 2DIGIT은 두 자리 숫자를 나타낸다는
것이다. 따라서 “<n>*<n>(element)”로 나타낼 수 있는 것이다.

#rule
앞서 설명한 것처럼 반복을 나타내긴 하지만 요소들의 나열로서 표현되는
것이다. 즉, 1#Method 라고 하면 Method의 요소들은 GET, HEAD, POST
등이므로 적어도 한 개의 Method가 있어야 하고 최대 갯수는 제한이 없다는
것으로 이해할 수 있다. 다시 말해 GET 하나만으로 구성될 수도 있고,
GET, HEAD, POST 이렇게 세 가지 요소들의 나열로서 표현될 수도 있다는
것이다. 각 요소들 사이의 구분은 ‘,’를 이용한다. 또 다른 예를 들자면,

1#2(2DIGIT)

이것은 숫자 두 개로 구성된 수가 적어도 한 개가 있어야 하며 최대 두
개까지 가능하다는 것이다. 즉, 23 이렇게 표현될 수도 있고, 23, 56
이렇게 두 개로 표현될 수도 있다.

이것이 *rule과의 차이점이고, #rule 에서도 “<n>#<m>element” 의 구성이
그대로 성립함을 볼 수 있다. 이에 대한 설명은 *rule 의 경우와 같다.

‘,’를 이용하여 나열함에 있어, null element가 허용된다. 예를 들어,
1#3(2DIGIT)과 같은 표현식에 대해

23, , 56, 34

이렇게 null element 표시가 가능하지만, 실제 갯수는 세 개로서 간주된다.
따라서 최소 한 개 최대 세 개의 제한에 위배되지 않는다.

; comment
이것은 규칙에 대한 설명을 하기 위해 표시하는 부분이다. 줄의 끝까지가
이 표시가 미치는 영향이다. 따라서 다음 줄까지 설명문을 연장하려면
다음 줄 처음에 ; 표시를 하여야 한다. 즉, 다음과 같다.

Sun, 06 Nov 1994 08:49:37 GMT   ; RFC 822
; updated by RFC 1123

implied *LWS
두 개의 인접한 단어 (token or quoted-string) 또는 인접한
토큰(tokens)과 식별자 (tspecials) 사이에 LWS(linear whitespace)가
포함될 수 있다. 여기서 두 개의 토큰 사이에는 반드시 적어도 하나의
식별자가 존재하여 서로 하나의 토큰으로 간주되지 않게끔 구별되어야
한다.
2.2 기본적인 규칙

OCTET     = <any 8-bit sequence of data>
; 8 비트로 구성되어 있는 데이타열

CHAR      = <any US-ASCII character (octets 0 – 127)>
; US-ASCII 문자 (octets 0-127)

UPALPHA   = <any US-ASCII oppercase letter “A” .. “Z”>
; 대문자 A 에서 대문자 Z 까지의 ASCII 영문자

LOALPHA   = <any US-ASCII lowercase letter “a” .. “z”>
; 소문자 a 에서 소문자 z 까지의 ASCII 영문자

ALPHA     = UPALPHA | LOALPHA

DIGIT     = <any US-ASCII digit “0” .. “9”>
; 0 에서 9 까지의 숫자

CTL       = <any US-ASCII control character (octets 0-31) and DEL(127)>
; DEL(127) 을 포함하는 ASCII 제어 문자 (octets 0-31)

CR        = <US-ASCII CR, carriage return (13)>

LF        = <US-ASCII LF, linefeed (10)>

SP        = <US-ASCII SP, space (32)>

HT        = <US-ASCII HT, horizontal-tab (9)>

<“>       = <US-ASCII double-quote mark (34)>

CRLF      = CR LF
; CR LF로 구성되어 있으며 Entity-Body를 제외한 모든 프로토콜
; 요소들에 대한 줄의 끝 (end-of-line)을 표시한다.

LWS       = [CRLF] 1*(SP | HT)
; HTTP 프로토콜 헤더가 여러 줄로 구성될 수 있는데, 이때 다음
; 줄로의 계속 표시를 나타내는 데에 쓰인다. 줄의 첫 시작에
; SP나 HT가 있으면 앞 줄의 계속으로서 인식된다.

TEXT      = <any OCTET except CTLs, but including LWS>
; LWS는 포함하나 모든 CTL 요소를 제외한 OCTET. 내용 설명 및
; 값 표시로서 쓰일 수 있으며 메시지 해석기(parser)에서
; 번역되지는 않는다. US-ASCII 문자세트 이외의 octets를
; 포함하는 TEXT 필드의 경우에는 ISO-8859-1 문자로 표현된
; 것이라고 간주한다.

HEX       = “A” | “B” | “C” | “D” | “E” | “F”
| “a” | “b” | “c” | “d” | “e” | “f” | DIGIT

word      = token | quoted-string
; HTTP 프로토콜의 헤더 필드는 LWS 또는 특수 문자들에 의해
; 구분되는 단어들로 구성되어 있다. 이러한 특수 문자들은
; 파라미터 값 속에 ” (quoted string) 표시에 의해 나타내진다.

token     = 1*<any CHAR except CTLs or tspecials>
; CTL 문자나 tspecials 문자를 제외한 하나 이상의 문자로
; 구성된 글자.

tspecials = “(” | “)” | “<” | “>” | “@” | “,” | “;” | “:” | “\” | <“>
| “/” | “[” | “]” | “?” | “=” | “{” | “}” | SP | HT
; 위에서 <“> 표기는 “(” 의 경우와 똑같이 그 문자 자체를
; 나타낸다.

comment   = “(” *(ctext | comment) “)”
; HTTP 프로토콜 헤더 속에 괄호 표시로서 설명문을 포함시킬
; 수 있다.

ctext     = <any TEXT excluding “(” and “)”>
; 괄호를 제외한 어떤 문자라도 가능하다.

quoted-string = (<“> *(qdtext) <“>)
; 괄호 표시 속에 전체가 들어 있으므로 한 가지 요소로서
; 취급된다. 예를 들어, “I Love You!” 가 이의 예가 된다.

qdtext    = <any CHAR except <“> and CTLs, but including LWS>

여기서 “\”를 사용하는 single-character quoting은 HTTP/1.0에서는 허용되지
않는다.
3. HTTP 프로토콜 파라미터

HTTP 프로토콜 규격 설명서는 메시지 단위의 설명으로 이루어져 있으며 이를
위하여 여러 가지 파라미터가 표현되어 있다. 이러한 기본적인 파라미터들의
종류와 내용을 살펴보도록 한다.
3.1 HTTP Version

HTTP 프로토콜의 버전을 표현하기 위해 “<major>.<minor>” 방식을 사용한다.
여기서 major 부분은 프로토콜 메시지 형식의 변경과 같이 중요한 변경 사항이
있을 때 사용하는 것이고, minor 부분은 파라미터 변경과 같이 부수적인
사항들의 변경이 있을 때 사용하는 것이다. 현재 이루어지고 있는 프로토콜의
버전은 1.0이다. 각 숫자는 양의 정수를 사용하여 1씩 증가하도록 되어
있으므로, HTTP/2.13은 HTTP/2.4보다 상위 버전이다.

프로토콜의 버전을 나타내는 것은 송신측이 요구(request)를 보낼 때 사용하는
메시지의 표현 형식을 나타내고, 이것은 서버나 브라우저가 어떤 형식의
메시지를 이해하고 처리할 수 있는지 표시하는 중요한 요소이다.

minor 번호가 바뀔 때는 메시지 해석 알고리즘을 변경하지 않고도 프로토콜
기능에 대한 변화를 줄 수 있을 때이고, 프로토콜 내의 메시지 형식이 바뀔
때와 같은 큰 변화가 뒤따를 때 major 번호를 바꾼다.

HTTP 메시지의 버전은 HTTP-Version 필드를 통해 표시하며 메시지의 첫 번째
줄에 자리한다. 만약 프로토콜 버전이 표시되지 않으면 수신측에서는
HTTP/0.9 버전의 단순 형식으로 간주한다.

HTTP-Version = “HTTP” “/” 1*DIGIT “.” 1*DIGIT

서버나 브라우저를 구현하고자 할 때 반드시 포함되어야 하는 HTTP 프로토콜은
0.9와 1.0 버전 모두이며, 이 문서 속에서는 둘 다 기술되어 있다.

이 문서에 정의되어 있는 Full-Request 또는 Full-Response 형식의 메시지를
전송하는 응용 프로그램에서는 “HTTP/1.0″이란 HTTP-Version을 나타내어야 한다.

HTTP/1.0 서버는, HTTP/0.9와 HTTP/1.0 요구를 위한 Request-Line 표현 형식을
인식할 수 있어야 하고, HTTP/0.9와 HTTP/1.0 형식으로 되어 있는 유효한 요구를
(valid request)를 이해할 수 있어야 하고, 또한 클라이언트가

3.2 URI (Uniform Resource Identifiers)

URI는 현재 여러 가지 이름으로 불리우고 쓰이고 있다. 예를 들어, WWW addresses,
Universal Document Identifiers, Universal Resource Identifiers 등이며, 최종적으로
URL (Uniform Resource Locators) 와 URN (Uniform Resource Names)의 결합으로
정의되고 있다. 이것은 하나의 대상체에 대해 이름, 위치, 서비스, 프로토콜 요소 등등
여러 가지 요소들을 참조할 수 있게 하는 인식 요소이다.
3.2.1 일반적 형식

URI         = (absoluteURI | relativeURI) [“#” fragment]
absoluteURI = scheme “:” *(uchar | reserved)
relativeURI = net_path | abs_path | rel_path
net_path    = “//” net_loc [abs_path]
abs_path    = “/” rel_path
rel_path    = [path] [“;” params] [“?” query]
path        = fsegment *(“/” segment)
fsegment    = 1*pchar
segment     = *pchar
params      = param *(“;” param)
param       = *(pchar | “/”)
scheme      = 1*(ALPHA | DIGIT | “+” | “-” | “.”)
net_loc     = *(pchar | “;” | “?”)
query       = *(uchar | reserved)
fragment    = *(uchar | reserved)
pchar       = uchar | “:” | “@” | “&” | “=”
uchar       = unreserved | escape
unreserved  = ALPHA | DIGIT | safe | extra | national
escape      = “%” hex hex
hex         = “A” | “B” | “C” | “D” | “E” | “F” | “a”
| “b” | “c” | “d” | “e” | “f” | DIGIT
reserved    = “;” | “/” | “?” | “:” | “@” | “&” | “=”
safe        = “$” | “-” | “_” | “.” | “+”
extra       = “!” | “*” | “‘” | “(” | “)” | “,”
national    = <any OCTET excluding CTLs, SP, ALPHA, DIGIT,
reserved, safe, and extra>
3.2.2 HTTP URL 형식

http_URL = “http:” “//” host [“:” port] abs_path
host     = <A legal Internet host domain name or IP address (in dotted-decimal
form), as defined by Section 2.1 of RFC 1123>
port     = *DIGIT

위 규정은 URL 표시를 하기 위한 것이며, port 부분에 아무런 숫자가 없다면
WWW 서비스를 위해 할당되어 있는 80번으로 인식한다. 위 규정에 의한 예를
살펴보면 다음과 같다.

http://pec.etri.re.kr/~qkim/who.am.i.html
http://pec.etri.re.kr:80/~qkim/qkim.html
http://129.254.201.2/
3.2.3 Date/Time 형식

HTTP/1.0 응용에서는 세 가지 형식의 일자/시간 표현 방식을 지원한다.

RFC 822, updated by RFC 1123
Sun, 06 nov 1994 08:49:30 GMT

RFC 850, obsoleted by RFC 1036
Sunday, 06-Nov-94 08:49:30 GMT

ANSI C’s asctime() 형식
Sun Nov 6 08:49:30 1994

이것을 프로토콜 규격의 형식으로 다시 표현하면 아래와 같다.

HTTP-date    = rfc1123-date | rfc850-date | asctime-date
rfc1123-date = wkday “,” SP date1 SP time SP “GMT”
rfc850-date  = weekday “,” SP date2 SP time SP “GMT”
asctime-date = wkday SP date3 SP time SP 4DIGIT
date1        = 2DIGIT SP month SP 4DIGIT        ; e.g., 16 Nov 1995)
date2        = 2DIGIT “-” month “-” 2DIGIT      ; e.g., 16-Nov-95)
date3        = month SP (2DIGIT | (SP 1DIGIT))  ; e.g., Jun 2)
time         = 2DIGIT “:” 2DIGIT “:” 2DIGIT     ; e.g., 21:34:24
wkday        = “Mon” | “Tue” | “Wed” | “Thu” | “Fri” | “Sat” | “Sun”
weekday      = “Monday” | “Tuesday” | “Wednesday” | “Thursday” | “Friday”
| “Saturday” | “Sunday”
month        = “Jan” | “Feb” | “Mar” | “Apr” | “May” | “Jun” | “Jul” | “Aug”
| “Sep” | “Oct” | “Nov” | “Dec”
3.2.4 Character Sets

이것은 8bit로 되어 있는 데이타를 일련의 글자로 변환하게끔 하는 정의 방식에
관한 사항이다. 다음과 같은 종류들이 정의되어 쓰이고 있다.

charset = “US-ASCII”
| “ISO-8859-1” | “ISO-8859-2” | “ISO-8859-3”
| “ISO-8859-4” | “ISO-8859-5” | “ISO-8859-6”
| “ISO-8859-7” | “ISO-8859-8” | “ISO-8859-9”
| “ISO-2022-JP” | “ISO-2022-JP-2” | “ISO-2022-KR”
| “UNICODE-1-1” | “UNICODE-1-1-UTF-7” | “UNICODE-1-1-UTF-8”
| token
3.2.5 Content Codings

인코딩 변환 방식을 지정하기 위해 사용한다. 이것은 실제 데이타를 압축하기
위해서 또는 보안을 위해 암호화할 때 등의 경우에 쓰일 수 있다.

content-coding = “x-gzip” | “x-compress” | token

여기서 gzip 또는 compress는 x-gzip과 x-compress로 각각 동일하게 취급된다.
3.2.6 Media Types

HTTP 프로토콜에서는 데이타 형식 표현의 개방성과 확장성을 위해 Content-Type 헤더
필드를 두고서 데이타 형식을 표현하고 있다.

media-type     = type “/” subtype *( “;” parameter )
type           = token
subtype        = token
parameter      = attribute “=” value
attribute      = token
value          = token | quoted-string

3.2.7 Product Tokens

사용하고 있는 응용 프로그램에 대한 정보를 알려주기 위해 사용된다.

product         = token [“/” product-version]
product-version = token

이에 의한 예를 들어보면 아래와 같다.

User-Agent: CERN-LineMode/2.15 libwww/2.17b3

또 다른 예로서,

Server: Apache/0.8.4

이러한 것을 볼 수 있다.
4. HTTP Message

4.1 HTTP 메시지 종류

HTTP 프로토콜의 동작을 위해 존재하는 메시지는 모두 네 가지 종류로 해서 구성된다.
이것을 이용해서 모든 데이타 송수신이 이루어지게 된다.
두 가지는 예전의 0.9 버전의 프로토콜에서 쓰이던 것이고 나머지 두 가지는 현재의
1.0 버전 프로토콜에서 쓰이는 것이다. 각각의 두 가지 메시지는 브라우저가 서버에게
문서 요청을 하기 위해 사용하는 요구 메시지이고 나머지는 이에 대한 응답 메시지이다.
이러한 네 가지로 구성되어 있다. 이에 대한 표현 형식이 아래와 같다.

HTTP-message = Simple-Request     ; HTTP/0.9 messages
| Simple-Response
| Full-Request     ; HTTP/1.0 messages
| Full-Response

브라우저가 서버에게 문서 요청을 할 때, 브라우저가 사용하고 있는 프로토콜 버전에
따라서 Simple-Request 형식이나 Full-Request 형식이나 둘 중 하나를 만들어서
요구하게 된다. 그러면 서버는 브라우저가 요구한 프로토콜 버전에 따라서 이에 대한
응답으로 Simple-Response 나 Full-Response 형식의 응답을 전달한다.

이러한 메시지는 응용 프로토콜 레벨에서 만들어지는 것이므로 실제로 인터넷을 통해
전달이 될 때는 추가적인 과정이 더 존재하게 된다. 먼저 브라우저는 문서 요구를 위한
메시지를 위에 정의에 따라 만들고 이것을 TCP/IP 프로토콜을 기반으로 하는 인터넷을
통해 보내어야 하므로, 위에서 만든 메시지 앞에다 TCP 프로토콜을 위한 헤더를
추가하고 이어서 IP 프로토콜을 위한 헤더를 더 추가해서 보내게 된다.
IP 프로토콜에서 만들어진 헤더는 인터넷을 여행하는 가운데 중간 경로상의
라우터에서 목적지까지의 경로를 찾기 위해 참조가 되고, TCP 프로토콜에서 만들어진
헤더는 목적지에 도착해서 속에 든 HTTP 메시지에 문제가 없이 제대로 도착했는지
확인해보기 위해 쓰이게 된다. 그런 다음에 HTTP 메시지를
서버가 해석하여 적절하게 동작하게끔 한다.

따라서 HTTP 프로토콜이 어떻게 구성되어 있는지 알고자 한다면 위 네 가지 메시지의
구성 형식을 살펴보면 되는 것이다. 이것이 HTTP 프로토콜의 모든 것이다.
4.2 HTTP/0.9 메시지 형식

0.9 버전에서의 HTTP 메시지 형식은 아래와 같이 단순하게 되어 있다.

Simple-Request = “GET” SP Request-URI CRLF
Simple-Response = [Entity-Body]

이러한 0.9 버전 HTTP 프로토콜 요구/응답에서 사용할 수 있는 method 는
GET 하나 뿐이다. 그러므로 브라우저는 서버에게 문서를 보내 달라고 하는 요청만
가능하며 서버에게 문서를 올리거나 지우거나 하는 기능은 불가능하다. GET 을 통해
문서를 요청하면서 해당하는 문서의 URI 를 지정해야 할 것이며 이것이
Request-URI에 해당한다. 이러한 요청에 따른 응답이 Entity-Body로서 실려오게 된다.
4.3 HTTP/1.0 메시지 형식

HTTP/1.0 버전에서는 0.9 버전에 비해 보다 다양한 기능들을 제공한다. 이에 따라
메시지 구성 형식은 훨씬 더 복잡한 형태를 띠고 있다.

Full-Request  = Request-Line *(General-Header | Request-Header
| Entity-Header) CRLF [Entity-Body]
Full-Response = Status-Line  *(General-Header | Response-Header
| Entity-Header) CRLF [Entity-Body]

위에서 Full-Request 의 예를 들자면 이와 같은 표현 방식에 의해 다음과 같은 예들이
가능함을 알 수 있다. 그리고 이러한 헤더의 순서는 중요하지 않으나 가능하다면
아래에 나열하고 있는 순서대로 송수신하는 것이 좋다.

Full-Request = Request-Line CRLF
Full-Request = Request-Line General-Header CRLF
Full-Request = Request-Line General-Header Request-Header CRLF
Full-Request = Request-Line General-Header Request-Header
Entity-Header CRLF Entity-Body

Full-Response 의 경우도 마찬가지로 살펴볼 수 있다.

Full-Response = Status-Line CRLF
Full-Response = Status-Line General-Header CRLF
Full-Response = Status-Line General-Header Response-Header CRLF
Full-Response = Status-Line General-Header Response-Header
Entity-Header CRLF Entity-Body

각 경우에서 보듯이 Entity-Body 는 CRLF 에 의해 공백 줄이 추가되어 구분되고 있다.

이상과 같은 전체적인 분류에 뒤이어 세부적인 형식들에 대해 알아보도록 한다.
4.4 Message Headers

앞서 메시지 필드들에 보면, General-Header, Request-Header, Response-Header,
Entity-Header 등과 같이 네 가지 헤더 형식이 있다. 여기에 공통적으로 정의되어 있는
헤더 정보가 있으며 아래와 같다.
이러한 HTTP-header 정보는 모든 헤더에 공통적으로 들어가 있다.

HTTP-header    = field-name “:” [ field-value ] CRLF
field-name     = token
field-value    = *( field-content | LWS )
field-content  = <the OCTETs making up the field-value
and consisting of either *TEXT or combinations
of token, tspecials, and quoted-string>

5. General-Header

General Header는 Full-Request 메시지와 Full-Response 메시지에 공통적으로 포함되어
있는 헤더 형식이다. 이것은 전송되고 있는 사용자 데이타에 관한 사항을 알리는 것이
아니고, 전송되고 있는 메시지에 관한 사항을 알리는 것이다.

General-Header = Date
| MIME-Version
| Pragma
Date           = “Date” “:” HTTP-date
MIME-Version   = “MIME-Version” “:” 1*DIGIT “.” 1*DIGIT
Progma         = “Pragma” “:” 1#pragma-directive
pragma-directive = “no-cache” | extension-pragma
extension-pragma = token [“=” word]

이러한 헤더 형식을 다시 풀어서 살펴보면 아래와 같이 나타내 보일 수 있다.

General-Header = Date | MIME-Version | Pragma
Date         = “Date” “:” HTTP-date
HTTP-date        = rfc1123-date | rfc850-date | asctime-date
rfc1123-date     = wkday “,” SP date1 SP time SP “GMT”
rfc850-date      = weekday “,” SP date2 SP time SP “GMT”
asctime-date     = wkday SP date3 SP time SP 4DIGIT
date1   = 2DIGIT SP month SP 4DIGIT             ; e.g., 02 Jun 1982
date2   = 2DIGIT “-” month “-” 2DIGIT           ; e.g., 02-Jun-82
date3   = month SP (2DIGIT | (SP 1DIGIT))       ; e.g., Jun 2
time    = 2DIGIT “:” 2DIGIT “:” 2DIGIT          ; 00:00:00 ~ 23:59:59
wkday   = “Mon” | “Tue” | “Wed” | “Thu” | “Fri” | “Sat” | “Sun”
weekday = “Monday” | “Tuesday”
| “Wednesday” | “Thursday”
| “Friday” | “Saturday” | “Sunday”
month   = “Jan” | “Feb” | “Mar” | “Apr” | “May” | “Jun”
| “Jul” | “Aug” | “Sep” | “Oct” | “Nov” | “Dec”
MIME-Version = “MIME-Version” “:” 1*DIGIT “.” 1*DIGIT
Pragma       = “Pragma” “:” 1#pragma-directive
pragma-directive = “no-cache” | extension-pragma
extension-pragma = token [“=” word]
6. Entity-Header

요구와 응답을 할 때 사용자 데이타를 함께 실어서 보낼 수가 있다. 이때 Full-Request
메시지와 Full-Response 메시지에 Entity Header가 포함되고 Entity가 전달된다.
Full-Request 메시지에 Entity가 포함되는 경우라면, 요구 메시지 헤더 속에 있는
Content-Length 필드가 반드시 사용되어야 한다.
이를 통해 요구 메시지 속에 사용자 데이타가 포함되어 전달되고 있음을 알게 된다.

Entity-Header  = Allow
| Content-Encoding
| Content-Length
| Content-Type
| Expires
| Last-Modified
| extension-header
extension-header = HTTP-header

이것을 풀어서 보다 상세히 나타내면 아래와 같다.

Entity-Header = Allow | Content-Encoding | Content-Length
| Content-Type | Expires | Last-Modified | extension-header
Allow            = “Allow” “:” 1#method
Content-Encoding = “Content-Encoding” “:” content-coding
econtent-coding = “x-gzip” | “x-compress” | token
Content-Length   = “Content-Length” “:” 1*DIGIT
Content-Type     = “Content-Type” “:” media-type
media-type      = type “/” subtype *(“;” parameter)
type      = token
subtype   = token
parameter = attribute “=” value
attribute = token
value     = token | quoted-string
Expires          = “Expires” “:” HTTP-date
Last-Modified    = “Last-Modified” “:” HTTP-date
extension-header = HTTP-header

이런 헤더 정보와 함께 전송되는 Entity Body 부분은 아래와 같이 정의된다.

Entity-Body    = *OCTET
6.1 Allow

Request-URI에 의해 지정되는 대상체에 지원되는 methods들을 나열하고 있다. 이것은
전송할 문서에 대해 송신자가 허용할 수 있는 method의 종류들을 수신측에게 알려주기
위해 사용된다. POST를 사용하는 method에 대한 요구 메시지에는 Allow 필드가
허용되지 않는다. 다음과 같이 구성되어 있다.

Allow          = “Allow” “:” 1#method

이의 예를 아래와 같이 보일 수 있다.

Allow: GET, HEAD
6.2 Content-Encoding

전송하고자 하는 개체가 어떤 방식으로 인코딩되어 있는지 나타낸다.
따라서 수신측의 입장에서 볼 때는 Content-Type 헤더 필드에 지정되어 있는 데이타
형식을 원상 복구하기 위해 어떤 디코딩 알고리즘을 사용해야 할지 결정하는 역할을
하게 된다. 이것은 주로 데이타 압축이나 보안을 위한 암호화의 과정에서 쓰인다.
다음과 같이 구성되어 있다.

Content-Encoding = “Content-Encoding” “:” content-coding

이의 예를 아래와 같이 보일 수 있다.

Content-Encoding: x-gzip
6.3 Content-Length

Entity-Body의 크기를 바이트 단위로 표시한다. 요구 메시지의 method가 GET이라면
전송하는 데이타의 실제 크기란 의미로서 전달되지만, HEAD라면 전송되어야 하는
데이타의 크기가 어느 정도인지 의미하는 것이다. 다음과 같이 구성되어 있다.

Content-Length = “Content-Length” “:” 1*DIGIT

이의 예를 아래와 같이 보일 수 있다.

Content-Length: 3495
6.4 Content-Type

수신측에게 전달하는 Entity-Body의 데이타 형식을 표시한다. 요구 메시지의 method가
GET이라면 전송하는 데이타의 형식이란 의미로서 전달되지만, HEAD라면 전송되어야
하는 데이타의 형식이 어떤 것인지 표시하는 의미이다. 다음과 같이 구성되어 있다.

Content-Type   = “Content-Type” “:” media-type

이의 예를 아래와 같이 보일 수 있다.

Content-Type: text/html
6.5 Expires

전달하는 데이타가 의미없는 대상으로 간주하는 시기를 표시한다. 다시 말해, 가격표와
같이 일정 기간 유효한 대상에 대해 그 시각을 지나서는 유효하지 않다고 지정할 때
사용하는 것이다. 만약 캐시되어 있는 데이타에 대해 이렇게 표시되어 있을 때 지정한
시각이 지나고 난 다음에는 캐시되어 있는 데이타를 지워도 되는 것이다. 다음과 같이
구성되어 있다.

Expires        = “Expires” “:” HTTP-date

이의 예를 아래와 같이 보일 수 있다.

Expires: Thu, 01 Dec 1994 16:00:00 GMT
6.6 Last-Modified

문서를 전송할 때 송신측에서 이 문서의 마지막 작업 시간을 알려주는 것이다.
만약 수신측에서 수신하는 문서의 Last-Modified 날짜가 수신측에 똑같이
저장되어 있는 복사본 문서의 날짜보다 이후의 것이라면 수신측이 이 문서를
대치할 수 있는 가능성을 만들어 주는 것이다. 이러한 정보를 어떻게 활용할 것인가
하는 것은 구현하기 나름일 것이다. 다음과 같이 구성되어 있다.

Last-Modified  = “Last-Modified” “:” HTTP-date

이의 예를 아래와 같이 보일 수 있다.

Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT
7. Request

브라우저로부터 사용자의 요구 사항을 받은 클라이언트가 HTTP 프로토콜에 따라서
서버에게 요구 사항을 전달할 때 정의되어 있는 요구 메시지가 사용된다. 이러한
요구 메시지는 프로토콜의 버전에 따라서 두 가지 종류가 있음을 앞서 4.1절에서 보였으며
Simple-Request와 Full-Request가 바로 그것이다. Full-Request 메시지의 구성
형식을 앞서 4.3절에서 살펴보았으며, 이 가운데 General-Header의 형식은 5장에서
살펴보았고 Entity-Header는 6장에서 살펴보았다. 여기서는 Full-Request 메시지와
관련해서 나머지 헤더와 형식을 살펴보기로 한다.

요구 메시지의 형식을 다음과 같이 나타내 보일 수 있다.

Request        = Simple-Request | Full-Request
Simple-Request = “GET” SP Request-URI CRLF
Full-Request   = Request-Line *( General-Header
|  Request-Header
|  Entity-Header )
CRLF
[ Entity-Body ]
7.1 Request-Line

요구 메시지에 들어가는 첫 번째 줄의 첫 순서 내용이 Request-Line이며 아래와 같은
구성 형식으로 되어 있다. 각각의 파라미터들은 SP에 의해 구분되고 있다. 메시지 정보의
끝을 나타내는 CRLF은 마지막 이외의 장소에는 허용되지 않는다. 다만 사용자 정보와
같은 Entity 부분은 CRLF에 뒤이어 나타날 수 있다. 따라서 실제 사용자 데이타를
보내기 위해서는 메시지 정보 다음에 공백의 빈줄을 반드시 집어 넣어야 인식할 수 있다.

Request-Line   = Method SP Request-URI SP HTTP-Version CRLF

보다 상세하게 풀어서 나타내면 아래와 같다.

Request-Line = Method SP Request-URI SP HTTP-Version CRLF
Method = “GET” | “HEAD” | “POST” | extension-method
extension-method = token
Request-URI  = absoluteURI | abs_path
absoluteURI = scheme “:” *(uchar | reserved)
scheme    = 1*(ALPHA | DIGIT | “+” | “-” | “.”)
uchar     = unreserved | escape
unreserved = ALPHA | DIGIT | safe | extra | national
safe     = “$” | “-” | “_” | “.” | “+”
extra    = “!” | “*” | “‘” | “(” | “)” | “,”
national = <any OCTET excluding CTLs, SP, ALPHA, DIGIT,
reserved, safe, and extra>
escape     = “%” hex hex
hex      = “A” | “B” | “C” | “D” | “E” | “F”
| “a” | “b” | “c” | “d” | “e” | “f”
| DIGIT
reserved = “;” | “/” | “?” | “:” | “@” | “&” | “=”
abs_path = “/” rel_path
rel_path  = [path] [“;” params] [“?” query]
path       = fsegment *(“/” segment)
fsegment = 1*pchar
segment  = *pchar
pchar = uchar | “:” | “@” | “&” | “=”
params     = param *(“;” param)
param    = *(pchar | “/”)
query      = *(uchar | reserved)
HTTP-Version = “HTTP” “/” 1*DIGIT “.” 1*DIGIT
7.1.1 Method

Request-URI로 지정되는 대상체에 대해 어떤 기능을 부과할 것인지 결정한다.
예를 들어 GET이란 method로 지정되어 있으면 Request-URI로 지정되어 있는
데이타 화일을 가지고 오라는 뜻이 되며, POST란 method로 지정되어 있으면
Request-URI로 지정되어 있는 장소에 글을 올릴 수 있다. 현재 세 가지 종류가
정의되어 쓰이고 있으며 다음과 같다.

GET
지정되어 있는 곳의 데이타를 보내달라고 요구하는 것이다. If-Modified-Since 필드와
함께 사용하면 조건부 GET의 기능을 구현할 수 있다.

HEAD
응답 메시지에 사용자 데이타를 전달하는 Entity-Body를 포함시키지 않는 것을
제외하고는 GET과 똑같은 역할을 한다. If-Modified-Since 필드는 HEAD 요구
메시지에서는 무시된다. HEAD 메시지를 이용하여 서버에 있는 실제 문서는 가져오지
않으면서도 문서 속에 포함되어 있는 metainformation을 가져올 수 있다.
즉, HTML 문서를 만들 때 <HEAD>와 </HEAD> 표시 속에 들어가는 문서 정보만을 갖고
올 수 있다는 것이다.

POST
Request-URI로 지정되어 있는 장소에 글을 올릴 수 있다. 이런 기능으로 분류할 수
있는 것들이 다음과 같다.

– 기존 문서에 주석을 붙일 때
– BBS나 메일링 리스트, 뉴스그룹 등에 글을 올릴 때
– 어떤 프로그램의 수행 결과를 전달할 때

다음과 같은 표시 형식으로 나타낼 수 있다.

Method         = “GET”
| “HEAD”
| “POST”
| extension-method
extension-method = token
7.1.2 Request-URI

method에 의해 지정되는 동작을 어느 장소에서 실행할 것인지 지정한다.
GET 또는 HEAD는 method라면 어느 장소의 어느 데이타를 가져올 것인지 정의하고
POST라면 어느 장소에 함께 전달되는 데이타를 글로서 올릴 것인지 정의하는 것이다.
다음과 같은 표시 형식으로 나타낼 수 있다.

Request-URI    = absoluteURI | abs_path
7.1.3 Examples

이러한 Request-Line의 예로서 다음의 것을 보일 수 있다.

GET http://www.w3.org/hypertext/WWW/TheProject.html HTTP/1.0
GET /hypertext/WWW/TheProject.html HTTP/1.0

두 번째 예의 경우는 이미 한 번 접속했던 서버에서 다시 데이타를 갖고 오고자
할 때 쓰인다.
7.2 Request-Header

Request-Header 필드는 Request-Line에서 요구하는 사항이나 클라이언트에 대한
추가적인 정보를 전달할 때 쓰인다. 다음과 같이 표현된다.

Request-Header = Authorization
| From
| If-Modified-Since
| Referer
| User-Agent

이것을 보다 상세히 풀어서 나타내면 아래와 같다.

Request-Header = Authorization | From | If-Modified-Since | Referer | User-Agent
Authorization     = “Authorization” “:” credentials
credentials = basic-credentials | (auth-scheme #auth-param)
basic-credentials = “Basic” SP basic-cookie
basic-cookie = <base64 [5] encoding of userid-password, except not
limited to 76 char/line>
userid-password = [token] “:” *TEXT
auth-scheme = token
auth-param  = token “=” quoted-string
From              = “From” “:” mailbox
If-Modified-Since = “If-Modified-Since” “:” HTTP-date
Referer           = “Referer” “:” (absoluteURI | relativeURI)
relativeURI = net_path | abs_path | rel_path
net_path = “//” net_loc [abs_path]
net_loc = *(pchar | “;” | “?”)
abs_path = “/” rel_path
rel_path = [path] [“;” params] [“?” query]
User-Agent        = “User-Agent” “:” 1*(product | comment)
product     = token [“/” product-version]
product-version = token
7.2.1 Authorization

브라우저가 서버에게 서비스 요청을 할 때 자신의 신분을 밝히고 인정받는 동작을 위해
사용되는 필드이다. 다음과 같이 구성되어 있다.

Authorization = “Authorization” “:” credentials
7.2.2 From

브라우저를 사용하여 요구 메시지를 보낸 사용자의 E-mail 주소가 전달된다.
이를 통해 서버에서는 이용자 정보를 축적할 수 있으며 이용자 접근 제한을
가할 수도 있다. 다음과 같이 구성되어 있다.

From           = “From” “:” mailbox

이의 예를 아래와 같이 보일 수가 있다.

From: qkim@pec.etri.re.kr
7.2.3 If-Modified-Since

이것은 앞서 설명한 것처럼 GET method와 함께 조건부 동작으로 활용한다. 브라우저가
요구하는 문서에 대해 서버는 이 필드에 지정되어 있는 시각 이후에 수정된 화일만
제공해준다. 다음과 같이 구성되어 있다.

If-Modified-Since = “If-Modified-Since” “:” HTTP-date

이의 예를 아래와 같이 보일 수가 있다.

If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT
7.2.4 Referer

브라우저가 요구하는 문서가 있을 때 이를 지정하는 Request-URI를 명시하여야 한다.
이때 이 Request-URI를 알게 된 원래 문서가 있을 수 있다. 이에 대한 정보를 표시한다.
이를 통해 서버는 하나의 문서에 대해 링크되어 있는 이전 문서들의 back-links를 구성할
수 있게 된다. 만약 사용자가 직접 입력한 URI에 대해서라면 원래 문서가 없을 것이므로
Referer가 전달되지 않는다. 다음과 같이 구성되어 있다.

Referer        = “Referer” “:” ( absoluteURI | relativeURI )

이의 예를 아래와 같이 보일 수가 있다.

Referer: http://www.w3.org/hypertext/DataSources/Overview.html
7.2.5 User-Agent

사용자가 이용하고 있는 브라우저에 대한 정보를 나타낸다. 다음과 같이 구성되어 있다.

User-Agent     = “User-Agent” “:” 1*( product | comment )

이의 예를 아래와 같이 보일 수 있다.

User-Agent: CERN-LineMode/2.15 libwww/2.17b3
8. Response

서버는 수신한 요구 메시지를 HTTP 프로토콜에 맞게 번역하여 적절한 내부처리를 거치고
프로토콜의 응답 메시지 형식에 맞춰 결과를 전달한다.
이러한 응답 메시지는 프로토콜의 버전에 따라서 두 가지 종류가 있음을 4.1절에서
보였으며 Simple-Response와 Full-Response가 그것이다. Full-Response 메시지의 구성
형식을 앞서 4.3절에서 살펴보았으며, 이 가운데 General-Header의 형식은 5장에서
살펴보았고 Entity-Header는 6장에서 살펴보았다. 여기서는 Full-Response 메시지와
관련해서 나머지 헤더와 형식을 살펴보기로 한다.

요구 메시지의 형식을 다음과 같이 나타내 보일 수 있다.

Response        = Simple-Response | Full-Response
Simple-Response = [ Entity-Body ]
Full-Response   = Status-Line *( General-Header
|  Response-Header
|  Entity-Header )
CRLF
[ Entity-Body ]
8.1 Status-Line

응답 메시지에 들어가는 첫 번째 줄의 첫 순서 내용이 Status-Line이며 아래와 같은
구성 형식으로 되어 있다. 각각의 파라미터들은 SP에 의해 구분되고 있으며, 메시지
정보의 끝을 나타내는 CRLF는 마지막 이외의 장소에는 허용되지 않는다. 다만 사용자
데이타와 같은 Entity 부분은 CRLF에 뒤이어 나타날 수 있다. 따라서 실제 사용자
데이타를 보내기 위해서는 메시지 정보 다음에 공백의 빈줄을 반드시 집어넣어야
인식할 수 있다.

Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF

보다 상세하게 풀어서 나타내면 아래와 같다.

Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
HTTP-Version = “HTTP/” 1*DIGIT “.” 1*DIGIT
Status-Code =   “200”               ; OK
|   “201”               ; Created
|   “202”               ; Accepted
|   …
|   extension-code
extension-code = 3DIGIT
Reason-Phrase = *<TEXT, excluding CR and LF>
8.1.1 Status-Code

세 자리의 정수로 표현되는 처리 결과 번호이다. 첫번째 자리 숫자는 분류 기호이며
나머지 두 자리 숫자는 일련번호이다. 현재 다섯 가지로 분류되어 쓰이고 있다.

1xx  Informatinal – 일반적 정보 표현, 향후의 사용을 위해 예약
2xx Success – 성공적으로 수신되고 해독되고 처리된 경우
3xx Redirection – 완전한 처리를 위해 추가적인 동작이 필요로 하는 경우
4xx Client Error – 요구 메시지에 문제가 있는 경우
5xx Server Error – 서버가 요구 메시지를 처리하는 가운데 문제가 발생한 경우

현재 다음과 같은 예들이 쓰이고 있다.

Status-Code    = “200”                 ; OK
| “201”                 ; Created
| “202”                 ; Accepted
| “204”                 ; No Content
| “301”                 ; Moved Permanently
| “302”                 ; Moved Temporarily
| “304”                 ; Not Modified
| “400”                 ; Bad Request
| “401”                 ; Unauthorized
| “403”                 ; Forbidden
| “404”                 ; Not Found
| “500”                 ; Internal Server Error
| “501”                 ; Not Implemented
| “502”                 ; Bad Gateway
| “503”                 ; Service Unavailable
| extension-code
8.1.2 Reason-Phrase

위에서 표시한 Status-Code에 대해 사용자를 위해 추가적인 정보를 제공하고자
할 때 Reason-Phrase에 포함되어 전달된다.
8.2 Response-Header

Response-Header 필드는 응답 메시지의 Status-Line에 포함시킬 수 없는 추가적인
정보을 전달할 때 쓰인다. 뒤따르는 Entity-Body에 대한 정보는 담지 않으며
서버 자체에 대한 정보만을 다룬다. 다음과 같이 표현된다.

Response-Header = Location
| Server
| WWW-Authenticate

이것을 보다 상세히 풀어서 나타내면 아래와 같다.

Response-Header = Location | Server | WWW-Authenticate
Location = “Location” “:” absoluteURI
Server = “Server” “:” 1*(product | comment)
WWW-Authenticate = “WWW-Authenticate” “:” 1#challenge
challenge = auth-scheme 1*SP realm *(“,” auth-param)
realm = “realm” “=” realm-value
realm-value = quoted-string
8.2.1 Location

Request-URI에 의해 지정되어 있는 대상체의 정확한 위치를 표시한다. Request-URI에서는
상대적인 경로로 표시될 수 있었으나, 여기서는 절대 경로만 표시된다.

Location       = “Location” “:” absoluteURI

이의 예를 아래와 같이 보일 수 있다.

Location: http://www.w3.org/hypertext/WWW/NewLocation.html
8.2.2 Server

요구 메시지를 처리하기 위해 서버가 사용하는 프로그램에 대한 정보를 담고 있다.
다음과 같이 구성되어 있다.

Server         = “Server” “:” 1*( product | comment )

이의 예를 아래와 같이 보일 수 있다.

Server: CERN/3.0 libwww/2.17
8.2.3 WWW-Authenticate

사용자의 요구 메시지에 지정되어 있는 정보가 보안이 필요로 하는 것이라면
서버는 서비스를 제공해주기 위해 사용자의 인증을 요구할 것이다. 그러므로
서버는 WWW-Authenticate 필드를 포함시켜 응답 메시지를 브라우저에게 전달한다.
이러한 목적을 위해 사용하고 있다. 다음과 같이 구성되어 있다.

WWW-Authenticate = “WWW-Authenticate” “:” 1#challenge
9. HTTP Next Generation

9.1 HTTP 프로토콜의 문제점

FTP 프로토콜의 경우 하나의 화일을 송신 또는 수신하고 난 다음에도 그 연결은
끊어지지 않아 또 다른 요구를 할 수 있지만, HTTP 프로토콜의 경우에는 다시 연결을
만들어 요구해야 하는 방식이다.

이러한 요구/응답 방식은 나름대로 장단점을 갖고 있다. URL (Uniform Resource Locator)을
이용한 하이퍼링크로 구성되어 있는 HTML 문서에서는 각종 프로토콜과 전세계의 어떤
호스트라도 지정하여 문서 요청을 위한 연결을 만들어 데이타를 갖고 올 수 있다. FTP의
경우처럼 하나의 호스트에 오래 연결을 맺고서 여러 가지 문서들을 갖고 오는 것이 아니라
하이퍼텍스트 문서에 있는 하이퍼링크를 통해 전혀 다른 호스트에 접속하여 문서를 요청할
수 있기 때문에 연결이 지속적으로 유지되는 방식보다는 요구/응답의 방식으로 동작하는
것이 보다 효율적이게 된다.

하지만 같은 호스트에서 여러가지 문서를 갖고 올려고 한다면 각각의 문서마다 별도의
연결을 만들고 문서 요청을 하는 부담이 생기게 된다. FTP의 경우에는 한 번 맺어진
연결을 통해서 여러 번 문서 요청을 하면 되지만 HTTP 프로토콜에서는 문서마다 각각의
연결을 만들어야 하는 추가적인 부담이 발생하는 것이다. 따라서 같은 장소에서 많은
문서를 갖고 올려고 할 때 HTTP 프로토콜은 성능저하를 초래하는 단점도 동시에 갖고 있다.
9.2 HTTP Next Generation의 시작

이러한 문제점을 해결하고, On-Line 쇼핑과 같은 상업적인 응용들을 염두에 둔
기능들을 보완하여 새로운 프로토콜을 설계하고자 하고 있다. 이것은 두 가지
방식으로 진행되고 있는데 현재의 프로토콜을 보완하는 방법이 하나이고,
아예 새로운 프로토콜을 설계해서 기존의 HTTP 프로토콜을 대체하는 방법이
나머지 한 가지이다.
9.2.1 HTTP-NG Activities

HTTP는 인터넷에서 가장 빠르게 성장하고 있는 프로토콜이다. 구현하기도
손쉬우며 지금 이 순간에도 엄청난 양의 데이타가 이 프로토콜에 의해 전송되고
있다. 이렇게 잘 동작하고 있음에도 HTTP를 대체하는 새로운 프로토콜을
설계하고자 하는 것은 앞서 말한 성능상의 문제와 사용자 확인 및 사용료 징수
등과 같은 수단으로 상업적 응용의 목적을 달성하기 위해서이다.

기존의 프로토콜에다 각종 기능들을 추가하고 개선하여 활용하는 방법도 있으나
필요한 요건들이 프로토콜 동작의 기본 모델과 관련한 것이기 때문에 이를 바꾸지
않고서는 문제를 더 복잡하고 어렵게 만든다. 이에 따라 다른 동작 모델을
사용하여 새로운 프로토콜을 설계하고자 하는 것이다.

새로운 프로토콜을 개발하고자 할 때 검토할 수 있는 요구사항들은 세 가지
대상에 대한 것으로 나누어볼 수 있다. 즉, 다음과 같다.

서비스 사용자
사용자들은 웹서비스를 이용하면서 문서를 갖고 오는 데 걸리는 시간 없이
즉시 받아보고자 한다.

서비스 제공자
가능한한 많은 사용자를 확보하고 등록된 사용자에게만 접근을 허용하며
이를 통해 상업적인 성공을 추구하고자 한다.

소프트웨어 개발자
구현하기가 쉽고 개발 작업이 편해야 한다.

각 대상들이 갖는 이런 요구사항들을 충족시키는 프로토콜이 개발되어야 한다.
이를 위해 필요한 사항들과 현재의 TCP/IP 프로토콜상의 문제점들을 나열해
보도록 한다.

Simplicity
HTTP-NG는 구현하기가 쉬운 프로토콜이어야 한다.

Performance
전세계에 걸친 네트워크 상에서 데이타 송수신이 효율적이어야 한다.

Asynchronicity
앞서 요청했던 서비스 요구에 상관없이 언제든지 원하는 서비스 요구를 할
수 있어야 한다. 즉, 앞서 요구한 서비스에 의해 현재의 서비스 요구가
제한받아서는 안 된다. 또한 하나의 연결 상에서 동시에 여러 개의 데이타를
수신할 수 있어야 한다.

Security
보안을 위해 암호화 되어 있는 데이타를 전송할 수 있어야 한다. 이를 위해
한 가지 메카니즘만 제공되면 안 된다.

Authentication
사용자에 대한 인증이 가능해야 한다.

Charging
사용량에 비례하는 과금을 할 수 있어야 한다. 이를 위해 한 가지 방법만
제공해서는 안 된다.

Intermediate Servers
캐시와 미러의 기능을 위해 중간 게이트웨이 역할을 할 수 있어야 하며,
서버와 서버 사이의 동작도 가능해야 한다.

Mandatory Displays
저작권 사항이나 저자에 관한 것 처럼 반드시 표시되어야 할 사항에 대해
지원할 수 있어야 한다.

Logging Information
중간 게이트웨이 역할을 하는 서버와 원래 호스트 서버 사이에서 logging
information이 관리되어야 한다.

Network Requirements
TCP와 같은 전송 프로토콜에 상관없이 데이타 전송이 가능해야 한다. 다시
말해서 TCP가 아닌 다른 수송계층 프로토콜에도 적용할 수 있어야 한다는
것이다. 그러나 현재의 응용들은 전부 TCP 프로토콜 위에서 이루어지고
있으므로 TCP 상황에서도 잘 동작해야 한다.

TCP and Internet
HTTP 프로토콜은 결국 TCP 프로토콜을 이용할 수밖에 없으므로 HTTP
프로토콜 성능의 상당 부분은 TCP 프로토콜에 의해 영향을 받는다. 따라서
프로토콜의 설계에서는 TCP 프로토콜의 특성을 잘 파악해야 한다.

Connection Setup Costs
TCP 연결을 맺으면서 RTT(Round Trip Time) 만큼의 지연이 생긴다.

Slow Start limits transfer rates during start up.
하나의 데이타 패킷 속에 요구하는 정보를 전부 지정할 수 없다면 몇 개의
데이타 패킷으로 나뉘어져 요구정보가 전달될 것이고 slow start 알고리즘에
의해 추가적인 RTT 지연이 발생하게 된다.

Congestion information is not shared between connections.
브라우저와 서버 사이에 여러 개의 데이타 전송 연결이 만들어져 있을 때
각각의 연결 사이에 아무런 정보 교환이 없기 때문에 전송상의 문제가
생기더라도 대처할 방도가 없다. 이에 따라 성능상의 문제를 더 크게 한다.

이러한 사항들을 감안하여 새로운 프로토콜을 설계하고자 하는 것이며, 이를 위해
제안되고 있는 프로토콜 모델은 세션의 개념을 이용하는 것이다. 즉,
각 문서 요구에 대해 별도의 연결을 만들기 보다는 여러 개의 문서
요구에 대해 하나의 연결만 만들도록 하고, 이 하나의 TCP 연결 속에서
‘세션(session)’이라고 불리우는 여러 개의 가상적 연결을 만들도록 하는 것이다.
이 가운데 하나는 세션 연결에서 제어 정보를 주고 받기 위해 쓰인다. 나머지 세션
연결선에 실제 데이타가 전달된다.

이렇게 하면 하나의 호스트에 대해 여러 개의 문서를 요청할 수 있으며
실제적인 TCP 연결은 하나만으로 이루어지기 때문에 각각의 연결을 맺기 위한
추가적인 부담이 발생하지 않게 되는 것이다. 이와 함께 데이타 전달을 끝내고
나서도 FTP의 경우처럼 연결을 지속시켜 두는 방법도 사용할 수 있다.
9.2.2 HTTP Working Group’s Issues

이미 앞서 열거했던 HTTP 프로토콜의 문제점들이 파악되어 있기 때문에 현재
프로토콜을 개선하고자 하는 논의가 이루어지고 있으며, 다양한 응용들과
사용자들의 요구사항을 반영하고자 하는 논의가 이루어지고 있다. 여기에서는
현재 HTTP 프로토콜 개발 작업에서 논의되고 있는 주요한 사항들에 대해
살펴보고자 한다. 이러한 사항들은 아직 논의 단계에 있기 때문에 향후의 HTTP
상위 버전에 반영될지는 알 수가 없다.

Session Extension
앞서 말한 HTTP 프로토콜의 가장 대표적 문제점이 같은 서버에서 여러
문서를 가져올 때 매번 새로운 연결을 맺어서 가져온다는 것이다. 이에 대한
대처 방안이 하나의 TCP 연결 위에 여러 개의 세션연결을 두어서 해결하는
것이었다. HTTP 개발 작업에도 이 개념이 도입되어 논의되고 있다.

State Information
이것은 위에 있는 Session 연결의 개념과 관련되어 있다. 현재의 HTTP
프로토콜은 앞서 보냈던 요구 사항에 대한 아무런 정보도 갖고 있지 않다.
그래서 상호 독립성은 유지가 되나 상호 관련이 있는 요구 사항들일
경우에는 같은 정보를 매번 전달해야 하는 비효율성이 등장하게 된다. 이에
따라 상호 관련이 있는 요구 사항을 보낼 때는 이미 앞서 보낸 요구에 대한
정보를 갖고 있다가 뒤이어 도착하는 요구 사항에도 적용할 수 있게 한다.
이러한 개념은 위에 있는 세션연결과 관련시켜 적용할 수 있다.

KeepAlive or Persistent Connection
위 문제를 해결하기 위한 또 다른 방안이 바로 이것이다. KeepAlive 개념은
이미 NCSA HTTPD에 구현되어 쓰이고 있다. 다만 브라우저에 이것이 구현되어
있어야만 제대로 동작한다. 이것은 하나의 연결에 대해 여러 개의 요구를
보내도록 하고 있으며, PC 윈도우즈용 NCSA Mosaic에 구현하여 확인해본
결과 30 퍼센트 정도의 성능 향상을 보았다고 한다. 이를 위해 httpd.conf
화일 속에 세 가지의 변수를 서버에서 지정해주어야 한다. 다음과 같다.

KeepAlive on | off
KeepAliveTimeout N
MaxKeepAliveRequests N

Color Content Negotiation
사용자가 사용하는 화면은 흑백만 지원할 수도 있고 칼라를 지원할 수도
있으며, 칼라의 경우 다양한 색 해상도가 선택될 수 있다. 이러한 경우를
위해 Accept-Color, MIME 형식에서의 파라미터, Accept-Parameter 등 갖가지
방법에 대한 논의가 이루어지고 있다.

Proxy Naming
현재의 proxy server는 중간 게이트웨이로서 firewall을 통과할 때, 또는
보다 빠른 응답을 위한 캐시로서 쓰거나 대역폭을 절약할 목적으로 쓰이고
있는데, 이것은 client 측면의 proxy로서 동작하는 것이다. 왜냐하면 사용자
브라우저에서는 이 proxy 서버의 존재를 알고 있어야 하기 때문이다. 이러한
proxy 서버 개념을 확장하여 client proxy와 server proxy의 개념 도입을
위한 토론이 이루어지고 있다. server proxy는 사용자 브라우저에서는
존재를 알 수가 없다.
9.2.3 향후 전망

 

[출처] HTTP 1.0 전송규약|작성자 씀바귀

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

이 사이트는 스팸을 줄이는 아키스밋을 사용합니다. 댓글이 어떻게 처리되는지 알아보십시오.