etc...

[etc] Detail about HTTP Method, Status and Field

빛나유 2015. 1. 5. 16:51

이번 포스팅은 HTTP의 Method, Status code 그리고 Request/Response에 존재하는 각각의 Field에 대해서 공부해보기로 하자.


우선 함수부분이다.

OPTIONS

이 Method는 인터넷 찾아보면 “요청 URI에 대하여 허용되어있는 method를 알려준다”라고 되어있는데, 맞아요. 그런데 조금 더 자세하게 말하면, 특정 URI에 대한 Request/Response Chain의 정보를 표현해주는 Method이다. 즉, 명시되어있는 URI에 대한 정보를 나타낸다는 것이다. 어떤 정보들이 있을까? 생각해보면 가장 만만한 정보가 명시되어있는 URI에 대하여 사용 가능한 method이다. 참 RFC 2616 문서는 이해하기 어렵게? 써놓은 것 같다.


#Request

OPTIONS / HTTP/1.1

Host: 192.168.0.106


#Response

HTTP/1.1 200 OK

Date: Fri, 02 Jan 2015 02:44:29 GMT

Server: Apache/2.2.22 (Ubuntu)

Allow: GET,HEAD,POST,OPTIONS

Vary: Accept-Encoding

Content-Length: 0

Content-Type: text/html


OPTIONS Method에 대한 Request와 Response이다. Response에서 Allow Field가 있는데 이 부분에 어떤 Method를 사용할 수 있는지 명시되어 있다.


GET

Request URI에 있는 정보를 얻기 위한 Method이다. partial GET과 conditional GET이 있는데, 둘 다 기본적으로 network에서의 불필요한 부하를 줄이기 위해 만들어졌다. conditional GET은 HTTP Cache를 사용하여 이미 Cache에 받은 내용이 있다면(conditional) Cache에 쌓여있는 데이터를 대신 사용하겠다는 것이다. HTTP Cache partial GET도 비슷하다. HTTP Request에 Range header field가 포함되면 그것을 partial GET Request라고 하는데, 이 필드에 명시되어있는 양만큼만 GET하겠다는 뜻이다. 3000 byte짜리의 파일을 GET 할 경우, 예를 들어 나는 0 byte부터 1024 bytes만 필요할 경우 Range: byte=0-1024 라고 써주면 그만큼만 딱 받는다. 나머지는 안 받아도 되므로 Network의 부하를 줄인다.


HEAD

HEAD Method는 기본적으로 GET과 같으나 Response에 Body가 포함되지 않는다는 차이가 있다. (영진씨, 경아씨 이 부분 한글 RFC 2616에 번역이 반대로 되있더라고요.)


POST

특정(Body내의) 데이터를 Request URI 내의 sub-data로 보내겠다는 Method이다. 


# Request

POST /admin/data.php HTTP/1.1

…….


abcdef


이런 요청이 있을 경우 data.php가 처리하도록 하는 데이터로서 abcdef를 보내겠다는 뜻이다. 이럴 경우, 성공을 했을 경우 200 OK가 Response로 return되며, 요청에 Body 내용이 없는 요청일 경우에는 성공 시 204 No Content가 return된다. 마지막으로, 만일 POST로 인해서 특정 파일이 생성이 되었을 경우에는 201 Created가 return된다고 한다. 


PUT

PUT method는 Body내에 있는 데이터를 서버에 업로드하는 method이다. 이 Method는 응답을 구분하는 것이 중요한 것 같다. 이 요청에 대하여 200 OK 또는 204 No Content가 Response로 왔을 경우에는 이미 존재하는 resource가 수정되었다는 뜻이다. 즉, 

PUT /abc.txt HTTP/1.1


abcdef

라고 Request를 보냈는데 200 OK가 돌아왔으면 이전에 이미 서버에 abc.txt는 존재했고, 그 파일이 성공적으로 “abcdef”로 수정되었다는 뜻이다. 그런데 왜 204가 return되는지는 잘 모르겠다. 제대로 수정되었다는 Response로 No Content?? 잘 와닿지 않는다. PUT method에 대하여 201 Created가 나왔을 경우는 파일이 새로 생성되었다는 뜻이다. 만일 관제 업무를 하던 중 PUT webshell.php가 탐지되었고 200 OK가 탐지되었고 200 OK가 제대로 수정되었다는 Response로 나왔다면, 그것은 기존에도 이미 webshell.php가 있었다고 추측할 수 있지 않을까? 반면 201 Created가 Response로 왔다면, 그것은 그 당시 webshell.php가 업로드되었다고 분석할 수 있지 않을까?


TRACE

TRACE method는 RFC 2616문서에는 조금 어렵게 쓰여있지만 간단한 내용이다. Client가 요청을 보냈을 때, 마지막으로 응답을 받은 end(서버이든 proxy이든)가 Client의 요청을 그대로 Body에 넣어서 보내준다.


# Request

TRACE / HTTP/1.1

Host: www.tutorialspoint.com

User-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT)


# Response

HTTP/1.1 200 OK

Date: Mon, 27 Jul 2009 12:28:53 GMT

Server: Apache/2.2.14 (Win32)

Connection: close

Content-Type: message/http

Content-Length: 39


TRACE / HTTP/1.1

Host: www.tutorialspoint.com

User-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT)


빨간 글씨로 쓴 부분이 Request에 대한 Response Body이다. Request와 같다. TRACE Method는 디버깅을 하기 위한 목적으로 쓰인다고 한다.


이제 Method는 어느 정도 정리가 된 듯 하니, Response Status Code를 살펴보려고 한다. HTTP Response는 다들 잘 알다시피, 숫자의 첫 자리를 통해 Response의 성격이 구분된다. 비슷한 성격의 Response끼리 앞자리로 묶어놨다는 말이다. 아래와 같다.


1xx : Request를 처리 중이며 아직 끝나지 않았다는 것을 알림. 즉, 작업을 마치려면 추가적인 Request가 필요하다는 것을 뜻함.

2xx : Request를 성공적으로 받았고, 서버가 이해했음.

3xx : 보통 이 부분은 Redirect를 의미한다고 알고 있으나, 그것보다 더 정확한 말은 Request를 완벽하게 수행하기 위해서는 추가적인 무언가가 필요하다는 것을 의미

4xx : Client가 요청한 Request에 문제가 있음

5xx : 요청은 정상적이나 서버가 그것을 수행하는데 문제가 생겼음


조금 더 자세하게 아래와 같이 분류된다.


1xx

101 Continue : Request가 부분적으로 받아들여졌음. Client가 추가적으로 Request를 계속해야함
101 Switching Protocol : 서버가 프로토콜을 변경함(정확히 뭔지는...)

2xx
200 OK : 정상적인 Request
201 Created : Request한 작업이 완료되었으며 새로운 Resource 생성됨
202 Accepted : Request가 받아들여졌지만 아직 완료되지 않음
203 Non-authritative Information : 잘 모르겠음.

204 No Content : Request에 대한 작업을 완료했으나 굳이 Body를 포함해서 보내지 않아도 됨. No body exists with 204
205 Reset Content : 잘 모르겠음.

206 Partial Content : Partial Get에 대한 작업 완료


3xx

300 Multiple Choices : Request에 해당하는 resource가 여러 개 있음. 가령, GET /index.html에 대한 300 Response이면, 


# Response
HTTP/1.1 300 Multiple Choices


/a/index.html

/b/index.html


index.html이 경우에 따라 어떨 때는 /a/index.html, /b/index.html이 될 수 있음. 위의 예시는 실제 예시로 받아들이지 말고, 개념적으로만 받아들일 것. (개념은 확실하나 구체적인 예시를 찾지 못함)


301 Moved Permanently : Requested resource가 새로운 resource로 redirect됨

302 Found : Requested resource가 일시적으로 다른 곳에 존재함

303 See Other : HTTP/1.1에서 거의 받아들여지지 않음.

304 Not Modified : 수정되지 않음. 304는 Conditional GET에 대한 응답으로 가능함. 메일로 보내준 Cache문서 참고.

305 Use Proxy : Location Field에 명시되어있는 Proxy를 사용하여 접근할 것

306 Unused : Not Used

307 Temporary Redirect : Requested URI가 일시적으로 다른 URI에 존재함. 그 다른 URI는 보통 Location field에 주어짐.


4xx
400 Bad Request : Request를 서버가 이해하지 못 함.
401 Unauthorized : Request는 user authentication을 포함해야만 함.
WWW-Authenticate Header Field를 반드시 가지고 있어야 함.
403 Forbidden : 서버가 request를 이해했으나 작업 수행을 거부함. 거부하는 이유는 보통 Body에 명시되어 있음.
404 Not Found : 서버가 Requested URI에 맞는 resource를 찾지 못함.
405 Method Not Allowed : Request method가 Requested URI에 대하여 수행되도록 허가되어 있지 않음. Response에는 Allow header field를 포함시켜서 어떠한 Method가 허용되는지 알려야 함.
406 Not Acceptable : "서버는 오로지 Client가 받아들일 수 없는 Response를 발생시킨다" 라는데 무슨 말인지 잘 이해가 안 감.
407 - 417도 있는데 이 부분은 자율 학습 -_-으로 두겠다.

5xx
500 Internal Server Error : Request 완료되지 않음. 예상치 못 한 상황 발생함.
501 Not Implemented : 서버가 해당 요청을 수행하는데 필요한 함수를 가지고 있지 않아서 수행 불가능.
502 Bad Gateway : 서버(A)가 Proxy나 Gateway로서 동작할 경우, A가 request를 실제로 수행할 서버(B)에게 Client의 Request를 전달했을 때, B로부터 invalid response를 받으면 A가 Client에게 502 Bad Gateway를 보냄
Client – A – B
즉, Client가 A를 거쳐 최종적으로 B에게 요청을 했을 때, A가 B로부터 받은 응답이 invalid Response일 경우, A가 Client에게 “야~ 니가 보내준 그 요청 뭔가 이상한가바~” 하고 알려줌.
503 Service Unavailable : 서버가 일시적으로 장애 혹은 다운 상태
504 Gateway Timeout : Client – A – B
위와 같은 구조에서, Gateway 또는 Proxy로 동작하고 있는 A가 제 시간에 B로부터 응답을 받지 못 할 경우 504 Gateway Timeout 발생함.

이제 절반 정도 온 듯하다. 조금만 더 힘내서 아래의 내용을 읽어보자.(글 쓰고 있는 나는 더 힘들다.) 마지막으로 Request와 Response에 나오는 Header에 대해서 자세하게 알아보자. 사실 이 부분은 내용이 너무 많다. 따라서 중요한 것 위주로 설명할 것이고 굳이 필요하지 않는 Field라고 판단되는 것들은 그냥 과감하게 생략하고 넘어갈 생각이다. 자 하나 하나씩 봐보자. 중요하다고 판단되는 필드는 빨간색으로 적어놨다.

Accept
Response에서 어떤 내용이 올지 미리 뜸을 두는 것이다. Accept: text/plain 이라고 되어있다면 이 부분은 Response로 text/plain만을 기대하겠다는 뜻이다. (text/plain: 그냥 단수 문자열) 이 부분에 가능한 값들로는 text/html, image/jpeg 등등 여러가지가 있으며 */*는 어떤 type도 response body에 포함시켜도 좋다는 뜻이다. 이럴 경우 Body에 Image raw data 가 오든 plain text가 오든 상관하지 않겠다는 뜻이 될 것이다. 

Accept-Charset
Acceptable Character set을 명시함. Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.3 라고 하면 windows-1251의 utf-8을 character-set으로 받아들이겠다는 것이다.

Accept-Encoding :
Acceptable Content Encoding Type을 명시함. Accept-Encoding: compress, gzip 라고 되어있으면 압축형태로서 gzip 파일 Encoding 형식을 따르겠다는 뜻이다. 이 Field는 Request header에 명시할 수 있는 내용으로 Client가 브라우저에서 해석가능한 type을 적어 보내게 된다. (아래의 Content-Encoding과 잘 구별하자)

Accept-Language
알아들을수 있는 언어 명시

Accept-Ranges
받아들이는 데이터의 단위를 명시. Accept-Range: bytes라고 되어있다면 응답으로서 받아들이는 response를 byte단위로 받아들인다는 뜻.

Age
Response가 서버에서 생성된 이후의 시간을 초단위로 나타낸다. 딱 보니 Cache 목적으로 쓰이는 것이다. 특정 시간이 넘기 전까지(less than) response를 가장 fresh한 Response로 받아들임.
Allow
Requested URI에 대하여 허용되는 모든 Method를 리스트함

Authorization
사용자 인증을 위한 정보가 이곳에 들어감. 예를 들어 Authorization : admin:admin 이런식으로 나온다면 ID/PW가 admin:admin인 사람이 들어왔다는 것이다. 그런데 이렇게 해놓으면 너무 취약하다. 그래서 이 문자열을 암호화한다. Base64로 암호화하면 YWRtaW46YWRtaW4=로 암호화 된다. 이 부분은 웹로그를 볼 때도 유심히 보면 좋다. 예를 들어 manager/html 페이지에 접근했는데 Authorization Field가 특정 문자열로 암호화되있더라. 그러면 우리는 그것을 Base64로 디코딩한다 그러면 공격자가 시도한 ID/PW 쌍을 확인할 수 있다. 이럴 경우 공격자가 공격을 성공했는지 직접적으로 테스트 할 수 있다.

Cache-Control
Cache-Control 굳이 다시 설명하지 않겠다. 이 부분의 값에 따라서 Cache를 사용할지 안 할지 경정할 수도 있으며 그 외에 다른 Option도 제공할 것으로 보임.

Connection
이 Field는 connection이 이후에 계속 있을지 없을지를 정해준다. 이 Field가 no-close로 되어있으면 이후에 더 이상 HTTP 연결이 없다는 것이다.(물론 같은 세션에 한하여..)
GET / HTTP/1.1
Connection: no-close
Host: 192.168.0.100
이렇게 Request를 보내면 Response를 받은 후 연결이 바로 끊어진다. 그런데 
GET / HTTP/1.1
Connection: keep-alive
Host: 192.168.0.100
이렇게 보내면 Response를 받은 후에도 연결이 남아있는 것을 확인할 수 있다.

Content-Encoding
Content-Encoding은 위의 Accept-Encoding과는 다르게 서버의 입장이다. 서버가 Response를 보낼 때 어떤 압축알고리즘을 사용했는지를 알려주는 부분이다. 즉, 이 Field는 Response Header에만 나올 수 있다는 말이다.

Content-Language
Response로 보내려는 내용이 어느 나라 언어로 표현되는 것인지를 알려줌.

Content-Length
Response의 길이를 나타냄. RFC 2616문서에 The size of the entity-body라고 되어있는 것을 보니 Header 값을 제외한 Body의 길이만을 의미하는 것으로 보인다. 

Content-Location
응답에서 포함된 resource의 위치가 Requested URI와 다를 경우, 제대로 된 Resource의 위치를 이 Field에 명시해준다. 가령, 아래와 같다.
# Request
GET /index.html HTTP/1.1
Host: 192.168.0.100

# Response
HTTP/1.1 200 OK
Content-Location: http://192.168.0.100/abc/index.html
….

이런 식으로 Request와 Response가 있을 경우, 요청 시에는 index.html을 요청했으나 실제 Response로 받은 Resource는 /index.html이 아닌 /abc/index.html이라는 뜻이다. 이 Field 같은 경우 관제할 때 조심해야되는 필드일 수도 있다. 무턱대고 /index.html을 검사했다가 “어라? 없네?” 하고 넘어갈 수 있다.” 반드시 Content-Location 부분에 있는 내용도 확인을 해야 한다.

Content-Range
Partial GET을 Request했을 때 나오는 Response header 이다. 굳이 길게 설명하지 않겠다. 별로 안 중요한 듯 하다.

Content-Type
서버가 보내는 Entity Body의 Type이다. Content-Type: text/html로 되어있으면 서버가 Body를 text/html 형식으로 보냈다는 뜻이다.

Date
Response가 서버에서 생성된 시간

ETag
ETag Field는 이전에 Cache 설명한 문서에서 확인하면 됨

Expect
Client가 특정 행위를 서버로부터 기대할 때 사용됨. 예를 들어, Request header field에 Expect: 100-continue라고 되어있다면 서버는 이를 받아들이고 추가적인 data를 기다리기 위해 100 Continue를 response로 준다고 한다. 그런데 이 Field를 제대로 구현해놓은 application은 드물다고 한다. 따라서 굳이 중요하게 공부하지 않아도 될 듯 하다.

Expires
Cache를 제대로 구현하기 위해서 만들어진 Field이다. 이 Field에[는 시간 값이 명시되어있는데(Date header처럼) 이 시간 이후에는 Cache에 있는 유효하지 않다는 뜻이다.

From
Request에 명시되어 있을 경우 user-agent를 컨트롤하는 사람의 email 주소를 포함한다고 한다. 이게 가령, Firefox이면 Firefox를 제작하고 관리하는 사람의 Email을 뜻하는지 아니면 그냥 그 Firefox를 사용하고 있는 일반 사용자의 Email을 의미하는지는 잘 모르겠다. 확실한 것은.. 별로 중요하지 않다는 것이다.

Host
중요한 필드이다. 일반적으로 IP 또는 IP:Port 또는 Domain 형태로 사용된다. 서버의 IP 정보를 포함한다. 이 필드는 HTTP header에서 반드시 포함되어야 하는 필드 중에 하나로 알고 있다.

If-Match
If-Modified-Since
If-None-Match
If-Range
If-Unmodified-Since
If로 시작하는 Field는 Conditional GET 또는 Partial GET 관련된 Field이다. 특히 Conditional GET 부분은 Cache 설명했을 때 자세하게 설명했던 부분이므로 이 부분은 생략하련다.

Last-Modified
이 Field 역시 Cache 관련된 Field이다. 마지막으로 수정된 시간 정보를 포함하여 보내준다. Cache 설명해준 문서에 보면 이 Field를 직접적으로 설명을 했는지 안 했는지 기억은 잘 안 나지만, 그 내용을 이해하면 충분히 이해할 수 있을 것이다.

Location
Client를 Requested URI에 명시되어있는 그 resource말고 다른 곳으로 redirect 시키기 위해 사용된다. 위에 나오는 Content-Location은 새로운 resource의 위치 정보이고, Location은 새로운 resource를 사용자가 얻을 수 있도록 새롭게 redirect시키는 정보이다. Content-Location에서와 비슷한 이유로, 이 필드 역시 관제할 때 자세하게 보면 좋다.

Max-Forwards
Proxy와 Gateway가 request를 Forwarding할 수 있는 최대 개수를 의미함.

Pragma
잘 모르겠다.

Proxy-Authenticate
Proxy-Authorization
Proxy 관련된 Header 정보로만 생각해도 충분할 것으로 판단됨.

Range
Content의 범위를 나타냄. Range: bytes=0-499이면 처음부터 499byte까지의 내용을 의미

Referer
Client가 Request URI를 어느 URL로부터 얻었는지를 나타냄. 서버의 이득을 위해서 이렇게 한다고 한다.(구체적으로 어떤 이득인지는 잘 모르겠다.) 이 Field 역시 관제할 때 많은 정보를 주는 Field이다. 예전에 이 Field의 값을 무시해서 발견했어야 하는 것을 발견하지 못 했었던 실수 아닌 실수를 한 적도 있었다. 항상 Referer는 확인하자. 그리고 자세하게 알아두자.

Retry-After
503 Service Unavailable Response를 받을 때 특정 시간 이후에 다시 시도하라고 명시해둔 필드. 시덥지 않은 Field이다. -_- 무시하자.

Server
소프트웨어 정보를 포함. 이 부분에 보통 어느 웹서버 프로그램을 이용하는지가 나온다. Nginx를 쓰는지 Apache를 쓰는지 IIS를 쓰는지.. 이 부분을 통해 알 수 있다.

TE
Trailer
잘 모르겠다.

Transfer-Encoding
이 필드는 Transfer Encoding 즉, 전송 시 어떤 암호화 알고리즘을 사용했는지를 알려준다. Content-Encoding과는 다르다. Content-Encoding은 어떤 파일 타입으로 인지를 말해주고, Transfer-Encoding은 어떤 암호화 알고리즘을 사용했는지를 알려준다. 예를 들어, 우리가 그림파일을 보낸다고 하자. 그림파일 보낼 때 그림파일은 이미지 파일 형식으로 짜여있는데.. 우리는 이것을 보고 그림파일이 암호화되었다고 말하지 않는다. 이 그림파일을 DRM을 걸면 우리는 그때야 비로소 그림파일이 암호화되었다고 말한다. 그 차이다.

Upgrade
추가적으로 어떤 protocol을 지원하는지 알려줌. 예를 들어 
Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11
이와 같이 쓰임

User-Agent
어떤 User-Agent를 사용했는지 알 수 있다. 이 부분 역시 중요하다. 이 부분에 이름 모를 스캐너 툴이 명시되어있으면 그 사용자는 우리 웹서버에 스캐너 툴을 이용하여 악의?적으로 접근했다는 뜻이 된다. 공격 여부를 판단하는데 약간의 영향력을 줄 수 있다. (스캐너 툴을 사용해도, 스캐너 툴을 이용해 이 필드 내용을 정상적인 브라우저로 바꿔버리면 그만이기 때문에 약간의 영향력이라고 적었다.)

Vary
잘 모르겠다.

Via
Gateway나 Proxy에 의해서 사용되는 필드. 별로 안 중요하다.

Warning
잘 모르겠다.

WWW-Authenticate
401 Unauthorized Error에 반드시 포함되어야 하는 Field로, 이 Field의 값을 통해 Client가 Request URI에 명시되어있는 resource를 이용하기 위해서는 어떤 인증 방식을 거쳐야 하는지를 알려준다.

아후 힘들다. TE, Trailer, Pragma, Warning, Vary 이 다섯 개는 나도 확실히 잘 모르겠다. 무엇보다도 중요한 Field는 아니니까 굳이 특별히 자세하게 할 필요는 없을 것 같다.

이로서 HTTP에 대한 설명을 마치련다. 음... 처음으로 etc에 뭔가를 작성했는데 왠지 뭔가 중구난방이 된 것 같은 기분이 없지 않아 있지만, 그래도 많은 사람들이 정보 많이 공유했으면 해서 이렇게 작성해놓는다. etc폴더는 생각보다 꽤 활용도가 높지 않을까 싶다. 꺠알같이 공부한 내용들은 전부 여기다 넣으면 되니까... 일종의 조커랄까?

참고 : 


# How Cache Works

https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching#cache-control

http://www.mobify.com/blog/beginners-guide-to-http-cache-headers/


# HTTP CACHE

http://odino.org/don-t-rape-http-if-none-match-the-412-http-status-code/

# METHOD

http://www.tutorialspoint.com/http/http_methods.htm