최근 La Scala 코딩단에서 Scala로 정적서버를 구현하는 스터디를 진행하게 되면서 HTTP 스펙을 다시 보게되었다. 웹개발을 하다보니 HTTP 프로토콜을 많이 사용해서 익숙하기는 하지만 그렇다고 스펙을 찬찬히 본적은 없었기에 이번 기회를 삼아서 스펙을 좀 살펴보았고 HTTP 스펙을 잘 아시는 셈틀노리님의 설명도 들었다.
HTTP 1.1의 스펙은 IETF에 잘 나와있다. 일반적으로 웹프레임워크에서 대부분 처리해줘서 직접 헤더를 다뤄본 적은 없기 때문에 스터디의 범위에는 포함되어 있지 않았지만 HTTP 스펙을 좀 이해해보자는 차원에서 헤더 파싱도 간단하게 나마 시도해 봤었다. 스펙의 양이 아주 많지는 않은데 그렇다고 다 읽어본 것은 아니고 필요한 부분만 좀 찾아보았는데 셈틀노리님이 정리해서 설명도 해주었기 때문에 간단하게 나마 정리한다.
Request
요청 메시지는 스펙상 다음과 같이 생겼다.
Request-Line
*(( general-header | request-header | entity-header ) CRLF)
CRLF
[ message-body ]
*(( general-header | request-header | entity-header ) CRLF)
CRLF
[ message-body ]
간단히 말하면 첫줄은 Request-Line이 오고 이어서 여러 종류의 헤더가 나온 다음에 줄바꿈을 두번하고(한줄 건너띄고) 메시지 바디가 오게된다.
Request Line
요청의 첫 줄은 Request Line이라고 부르는데 스펙상은 Method SP Request-URI SP HTTP-Version CRLF 와 같이 정의하는데 보통 다음과 같이 생겼다.
GET /index.html HTTP/1.1맨 앞의 GET은 요청 Method를 의미하는데 OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT 8가지가 있다.
- OPTIONS : 요청 URI에서 사용할 수 있는 Method를 물어본다.(스펙 참고)
- GET : 요청 URI의 정보를 가져온다.(스펙 참고)
- HEAD : GET 요청에서 body는 제외하고 헤더만 가져온다.(스펙 참고)
- POST : 요청 URI의 리소스의 새로운 정보를 보낸다.(스펙 참고)
- PUT : 요청 URI에 저장될 정보를 보낸다. (스펙 참고)
- DELETE : 요청 URI의 리소스를 삭제한다.(스펙 참고)
- TRACE : 보낸 메시지를 다시 돌려보낸다. (스펙 참고)
- CONNECT : 프록시에 사용하기 위해 예약된 메서드이다.(스펙 참고)
추가: 김관래의 제보로 PATCH 메서드 추가합니다. partial resource modification 용도라는데 HTTP 1.1 스펙에 안들어있는걸 보면 진행중인 상태가 아닐까 혼자 추측해 봅니다. PATCH for HTTP
Headers
Request-Line 다음에는 header가 위치하는데 앞에서 본 스펙대로 general-header, request-header, entity-header 3가지 종류가 있고 요청에 따라 필요한 헤더만 사용하게 된다.
General Header에는 Cache-Control, Connection, Date, Pragma, Trailer, Transfer-Enco, Upgrade, Via, Warning가 있고 Request Header에는 Accept, Accept-Charset, Accept-Encoding, Accept-Language, Authorization, Expect, From, Host, If-Match, If-Modified-Since, If-None-Match, If-Range, If-Unmodified-Since, Max-Forwards, Proxy-Authorization, Range, Referer, TE, User-Agent등이 있고 Entity Header에는 Allow, Content-Encoding, Content-Language, Content-Length, Content-Location, Content-MD5, Content-Range, Content-Type, Expires, Last-Modified, extension-header가 있다. 헤더는 name : content의 형식이 되는데 content 부분은 각 헤더에 대한 상세 내용을 확인해 보면 되는데 각 값들은 공백이나 탭으로 구분될 수 있고 각 헤더는 CRLF로 구분된다.
Response
응답 메시지는 다음과 같이 정의되어 있다.
Status-Line
*(( general-header | response-header | entity-header ) CRLF)
CRLF
[ message-body ]
*(( general-header | response-header | entity-header ) CRLF)
CRLF
[ message-body ]
첫줄이 요청라인대신에 상태라인인것과 요청헤더 대신 응답헤더가 들어간 것만 빼면 요청 메시지와 동일한 형태이다.
Status Line
Status Line은 HTTP-Version SP Status-Code SP Reason-Phrase CRLF로 정의되어 있고 보통 다음과 같이 생겼다.
HTTP/1.1 200 OKHTTP 버전은 요청부분에서 설명한 것과 동일하고 상태코드(Status-Code)는 흔히 보는 3자리 숫자로 된 상태를 나타내는 코드로 각 번호대 별로 다음과 같은 의미를 가지고 있다.
- 1xx : 정보성
- 2xx : 성공
- 3xx : 리다이렉트
- 4xx : 클라이언트 오류
- 5xx : 서버 오류
Headers
헤더 부분의 General Header와 Entity Header는 요청부분에서 설명한 것과 동일하고 Response Header는 Accept-Ranges, Age, ETag, Location, Proxy-Authenticate, Retry-After, Server, Vary, WWW-Authenticate가 있다.
My Comment..
이 글을 갖고 오게 된 계기는 햄하고 좀 비슷할 것이라고 생각이 된다.. HTTP 는 너무 흔하게 쓰고 항상 사용하고 봐왔지만 실질적으로 그 부분에 대해서 고민을 해보거나 알아보려고 한 적은 없었다.. 기껏해야 과거에 대학생활하면서 시험을 위해서 잠시 찾아보거나 정보처리기사를 위해서 잠시 공부할 때나 본정도라고 해야될까..?? 난 엄두도 못내었고, 딱히 별도로 공부를 하거나 찾아봐야겠단 생각도 못하던터에 햄의 글이 있기에 옮겨오게 되었다..
댓글 없음:
댓글 쓰기