검색

검색어를 입력하세요

webserv - HTTP 완벽 가이드 3장 정리

2022-11-14
우당탕탕 webserv 이론공부

42 웹서브를 하는 팀이라면 한번쯤은 보는 것 같은 HTTP 완벽 가이드(책 정보 링크)의 3장을 읽고 정리해보았다.

아래의 내용은 거의 대부분 책의 내용과 동일합니다.

🌟 3.1 메시지의 흐름

텍스트 메타 정보로 시작 → 선택적으로 데이터가 온다.

인바운드, 아웃바운드, 업스트림, 다운스트림 : 메시지의 방향을 의미

  • 인바운드 : → 서버
  • 아웃바운드 : 처리가 끝난 후 → 사용자 에이전트 (클라이언트)

원 서버로 인바운드로 이동하고 클라이언트로 아웃바운드로 이동하는 메시지

  • 다운스트림: 모든 메시지는 다운스트림으로 흐른다. (수신자)
  • 업스트림: 메시지의 발송자는 수신자의 업스트림.

🌟 3.2 메시지의 각 부분

메시지의 구성: 시작줄, 헤더블록, 본문

  • 시작줄: 이것이 어떤 메시지인지
  • 헤더 블록: 속성
  • 본문: 데이터

시작줄과 헤더는 아스키 문자열.

각 줄은 캐리지 리턴 (13) 과 개행 문자 (10) 로 구성된 두 글자의 줄바꿈 문자열로 끝난다. (CRLF)

견고한 애플리케이션이라면 캐리지 리턴이 없는 단순한 개행문자라도 받아들일 수 있어야 한다. (51페이지) 오래된 HTTP 어플리케이션은 CRLF을 보내지 않는 경우도 있기 때문.

본문 (엔티티 본문, 메시지 본문)은 데이터 덩어리.

텍스트나 이진 데이터, 비어있을수도 있다. → 어떤 종류의 본문인지는 헤더에 나와있다.

✨ 3.2.1 메시지 문법

모든 HTTP 메시지는 요청 메시지이거나 응답 메시지. 구조는 기본적으로 같다.

  • 요청 메시지: 서버에 어떤 동작을 요구
  • 응답 메시지: 요청의 결과를 클라이언트에게 돌려줌
**[요청 메시지]**
<메서드><요청 URL><버전>
<헤더>

<엔티티 본문>

**[응답 메시지]** (시작줄만 조금 다르다.)
<버전><상태 코드><사유 구절>
<헤더>

<엔티티 본문>
  • 메서드: 서버가 수행해야 하는 동작, GET, POST
  • 요청 URL: 요청 대상이 되는 리소스의 완전한 URL 또는 URL의 경로 구성요소
  • 버전:
  • 상태코드
  • 사유 구절 (reason-phrase): 상태 코드에 매칭되는 문구. 오로지 사람이 읽기 위한 목적
  • 헤더들: 이름, 콜론(:), 선택적인 공백, 값, CRLF가 순서대로 나타나는 0개 이상의 헤더들. 헤더들의 목록은 CRLF로 끝나서 헤더 목록의 끝과 엔티티 본문의 시작을 구분한다.
    • ❓ 0개 이상의 헤더? 헤더가 없어도 되는건가 → HTTP 버전에 따라서는 헤더가 0개 있어도 괜찮은 것 같은데, 우리가 다룰 HTTP/1.1 같은 몇몇 버전에는 요청이나 응답에 특정 헤더가 포함되어 있어야 유효한 것으로 간주한다고 했으므로 ⇒ 우리의 경우에는 무조건 헤더 하나는 있어야 유효하다.
    • ❓ 여기서의 CRLF도 캐리지 리턴 없이 개행 문자만 있어도 되는건가 → CLRF로 끝나지 않는 메시지도 받아들여야 한다는걸 보면 그냥 모든 부분에서 CRLF 대신 단순 개행문자도 동일하게 처리해줘야 하는 것 같다.
  • 엔티티 본문: 본문이 있을수도, 없을수도 있음. 만약에 없으면 헤더의 끝인 CLRF로 메시지 끝남. (CLRF로 끝나지 않는 메시지도 받아들일 수 있어야 함)

✨ 3.2.2 시작줄

요청 메시지의 시작줄: 무엇을 해야 하는가

응답 메시지의 시작줄: 무슨 일이 일어났는가

  • 요청줄: 메서드(공백)요청URL(공백)HTTP버전
  • 응답줄: HTTP버전(공백)상태코드(공백)사유구절
  • 메서드 → 3.3에 몰아서 정리함
  • 상태 코드 → 3.4에 몰아서 정리함
  • 사유 구절 → 상태 코드와 일대일로 대응되는 문구. HTTP 명세에 사유 구절에 대한 엄격한 규칙이 없다.
  • 버전 번호: 자신이 따르는 버전을 상대방에게 알려주기 위함. (대화 상대의 능력과 메시지 형식의 단서를 얻는다.)

✨ 3.2.3 헤더

(3.5에 몰아서 정리함)

✨ 3.2.4 엔티티 본문

HTTP 메시지의 화물

텍스트 뿐 만 아니라 이미지, 비디오, … 등 여러 종류의 데이터를 나를 수 있다.

✨ 3.2.5 버전 0.9 메시지

응답 메시지에 헤더 없이 오직 본문만 있던 버전.

생략

🌟 3.3 메서드

GET: 서버에서 문서를 가져오는 것

POST: 서버가 처리했으면 하는 데이터를 보내는 것

메서드설명메시지 본문
GET서버에서 어떤 문서를 가져온다
POST서버가 처리해야 할 데이터를 보낸다⭕️
DELETE서버에서 문서를 제거한다🔺 (삭제한 파일에 대한 정보)

✨ 3.3.1 안전한 메서드

요청의 결과로 서버에 어떤 작용(변화, 작업 등)도 없는 메서드

→ 어떤 메서드가 안전한 메서드가 될지는 웹 개발자에게 달려 있음.

✨ 3.3.2 GET

서버에 리소스를 달라고 요청하는 메소드 (HTTP/1.1 필수)

✨ 3.3.3 ~ 3.3.4 HEAD, PUT

HEAD: GET과 정확히 동일하게 행동하지만 서버는 응답으로 헤더만 돌려준다.

  • 리소스를 가져오지 않고 그 정보만을 알기 위해
  • 상태코드를 보고 그 리소스의 존재 여부를 알기 위해
  • 리소스가 변경되었는지 알기 위해

사용한다.

HEAD 요청의 내용과 GET 요청의 헤더가 완전히 동일함을 보장해야 한다.


PUT: 서버에 문서를 “쓰는” 메서드

없는 문서라면 새로 만들어서 쓰고, 이미 존재하는 문서라면 그 안에 새로 쓴다.

콘텐츠를 변경할 수 있기 때문에 대부분의 웹서버는 사용자 인증 후에 PUT 메서드의 권한을 준다.

✨ 3.3.5 POST

서버에 입력 데이터를 “전송”하기 위해 사용

HTML form 태그를 지원하기 위해 사용된다.

POST 명령으로 전송된 데이터는 서버가 모아서 필요로 하는 곳에 보낸다.

✨ 3.3.6 ~ 3.3.7 TRACE, OPTIONS

TRACE: 클라이언트가 보낸 요청은 서버로 바로 갈수도 있지만 방화벽 같은 애플리케이션을 거쳐서 갈 수 있는데, 이 어플리케이션은 원본 요청을 수정할 수 있다. TRACE 메소드 응답의 엔티티 본문에는 실제 서버가 받은 요청의 내용이 그대로 들어있다. 주로 진단에 사용함.

OPTIONS: 특정 리소스에 대해 서버가 지원하는 메소드의 목록을 받아온다. 실제로 그 리소스에 접근하지 않고도 그것에 접근할 수 있는 최선의 방법을 알 수 있음.

✨ 3.3.8 DELETE

요청 URL로 지정한 리소스를 삭제할 것을 요청한다.

HTTP명세는 서버가 클라이언트에게 알리지 않고 요청을 무시하는 것을 허용 → 실제로 삭제가 수행되는 것을 보장하지는 않는다.

→ ❓ 200 OK 를 보냈음에도 불구하고 삭제하지 않는 경우가 뭐가 있을까.. 권한?

✨ 3.3.9 확장 메서드

HTTP는 쉽게 확장할 수 있도록 설계되었기 때문에 서버마다 그들만의 메서드를 구현할 수 있는데, 이렇게 구현된 메서드를 확장 메서드라고 함.

🌟 3.4 상태 코드

RFC 7230

클라이언트에게 서버에서 무슨 일이 일어났는지 말해줌.

전체 범위정의된 범위분류
100-199100-101정보
200-299200-206성공
300-399300-305리다이렉션
400-499400-415클라이언트 에러
500-599500-505서버 에러

인식할 수 없는 상태 코드를 받게 되면, 누군가가 현재 프로토콜의 확장으로 그 코드를 정의했을 수도 있다 ⇒ 그 상태 코드를 그것이 포함되는 범주의 일반적인 것으로 가정하고 다뤄야 한다.

✨ 3.4.1 100-199: 정보성 상태 코드

가치가 있는가에 대한 논란이 있음 (…)

상태 코드사유 구절의미
100Continue(요청의 Expect 헤더와 함께 사용) 요청의 시작 부분 일부가 받아들여짐. 클라이언트는 같은 “내용”의 요청을 다시 보내면 반드시 서버로부터 응답을 받을 수 있음을 보장받음 서버는 반드시 그 요청을 받아 응답해야 함
101Switching Protocols(요청의 Upgrade 헤더와 함께 사용) 서버가 프로토콜을 바꾸었음을 의미

100 Continue에 대한 설명… (필요한 내용인지 모르겠다)

  • 클라이언트와 100 Continue
    • 클라이언트가 100 코드를 기대하고 요청을 보낸다면, 그 요청 안의 헤더에는 Expect: 100-continue 라는 내용이 있어야 한다.
    • 처리 성공이 불확실한 큰 엔티티를 서버로 신중히 보내기 위한 목적.
    • 서버가 100 Continue 응답을 보낼 수 있다는 보장이 없기 때문에 (100 코드의 혼란 때문) 100 Continue를 받지 못하더라도 클라이언트는 엔티티를 보내야 한다. (타임아웃)
  • 서버와 100 Continue
    • Expect: 100-continue 를 받게 된 서버는 100 Continue 혹은 에러 코드로 답해야 한다.
    • 100 Continue 응답을 보내기 전에 같은 헤더의 엔티티를 받았다면 서버는 100 Continue에 대한 응답을 할 필요가 없다. 😵‍💫
    • 서버 측에서 100 Continue에 대한 응답 이후에 관련 엔티티 받지 않고 연결을 끊기로 했어도 응답 이후에 바로 연결을 끊어서는 안된다. 😵‍💫

✨ 3.4.2 200-299: 성공 상태 코드

여러가지 요청에 대한 성공 상태 코드를 반환한다.

상태 코드사유 구절의미
200OK요청은 정상이고, 엔티티 본문은 요청된 리소스를 포함하고 있다.
201Created개체를 생성하라는 요청(PUT 등)을 위한 것. (PUT 명령 구현 안해도돼서 생략함)
202Accepted❓ 요청은 받아들여졌으나 서버는 아직 그에 대한 어떤 동작도 수행하지 않았다. 요청이 처리하기 적법해 보임을 보장.
203Non-Authoritative Information❓ 엔티티 헤더에 들어있는 정보가 원래 서버가 아닌 리소스의 사본에서 왔다. 만약 엔티티 헤더가 원래 서버에서 온 것이라면 응답이 200이 되어야 할 요청. (선택 사항?)
204No Content응답 메시지는 헤더와 상태줄을 표시하지만 엔티티 본문은 포함하지 않는다. 웹 브라우저를 새 문서로 이동하지 않고 새로고침 하고 싶을 때 (입력창 새고 등) 주로 사용
205Reset Content브라우저에게 현재 페이지에 있는 폼에 채워진 모든 값을 비우라고 함.
206Partial Content(요청의 Range 헤더와 함께 사용) 범위 요청이 성공했음을 의미. 반드시 헤더에 Content-Rage와 Date를 포함해야 하고, Etag 또는 Content-Location 중 하나도 반드시 포함해야 함.

❓ 204와 205의 차이

✨ 3.4.3 300-399: 리다이렉션 상태 코드

상태 코드사유 구절의미
300Multiple Choice클라이언트의 요청이 동시에 여러 리소스를 가리키는 경우. 그 리소스의 목록과 함께 반환. (어떤 서버가 하나의 문서를 여러 언어로 제공하는 등)
301Moved Pernanently요청한 URL이 옮겨졌을 때. 응답의 Location 헤더에는 그 리소스의 새 위치를 포함해야 함.
302Found301과 동일한 경우에 사용. 클라이언트에서는 응답으로 받은 URL을 한번만 사용하고, 이후에는 다시 요청했던 URL을 사용해야 함.
303See Other리소스를 다른 URL에서 가져와아 한다는 것을 알려줌. 주로 POST 요청에 대한 응답으로 리소스의 위치를 알려주는 목적으로 사용.
304Not Modified조건부 요청 중에서 GET 과 같은 조건부 요청을 보냈는데 → 리소스가 수정된 적이 없다면 → 이걸 보내는 것. 이 코드의 응답은 엔티티 본문을 가지면 안된다.
305Use Proxy이 리소스는 반드시 프록시를 거쳐야 함을 알리고 Location에 프록시의 위치를 알려준다.
306(사용 x)(사용 x)
307Temporary Redirect302와 완전 똑같음 (HTTP/1.1에서 사용하는 302 코드라 이해함)

리다이렉션에 사용됨. 사용자가 직접 움직이지 않고 올바른 리소스로 이동하기 위함.

HEAD가 아닌 요청에 대해 리다이렉션 상태 코드의 응답을 할 경우에 본문에 리다이렉트 될 URL의 링크와 설명을 적는 것이 좋다.

301, 302, 307에 대하여 ⇒ HTTP/1.0, HTTP/1.1의 차이에 기반함

✨ 3.4.4 400-499: 클라이언트 상태 코드

상태 코드사유 구절의미
400Bad Request클라이언트의 잘못된 요청 (잘못된 시작줄?)
401Unauthorized리소스를 얻으려면 클라이언트가 스스로를 인증해야 함. (헤더에 관련 정보 함께 보냄)
402Payment Required미래에 사용될 가능성을 위해 준비해둠 (?)
403Forbidden요청이 서버에 의해 거부됨. 필요하다면 거부 이유를 엔티티 본문에 넣어도 되는데, 보통 이 상태 코드는 거절 이유를 숨기고 싶을 때 사용한다고 함.
404Not Found요청한 URL을 찾을 수 없음. 클라이언트에서 사용자에게 보여주기 위한 엔티티를 포함하기도 한다.
405Method Not Allowed요청한 URL을 지원하지 않는 메소드로 요청했을 때. 이 때 요청한 URL을 지원하는 메소드도 함께 알려주기 위해서는 Allow 헤더가 포함되어야 한다.
406Not Acceptivle클라이언트 본인이 어떤 종류의 엔티티를 기대하는지 요청에 적었을 때, 요청받은 URL에 해당하는 리소스가 클라이언트가 받을 수 없는 경우.
407Proxy Authentication Require401과 동일. 인증을 요구하는 프록시 서버를 위해 사용.
408Request Timeout클라이언트의 요청을 완수하기에 시간이 너무 걸리는 경우. 타임아웃은 서버마다 다르지만 대다수의 요청을 처리할 수 있을 정도로 길다.
409Confilt요청이 리소스에 대해 충돌을 일으킬 수 있는 경우. 응답 본문에 충돌에 대해 설명하는 내용을 포함시켜야 한다.
410Gone404와 비슷한데 원래 리소스가 서버에 있었음을 나타내기 위해 사용하는 코드
411Length Required서버가 요청 메시지에 Content-Length 헤더를 요구했을 때 사용.
412Precondition Failed클라이언트의 조건부 요청 중 하나가 실패했을 경우
413Request Entity Too Large서버가 처리할 수 있는, 처리하고자 하는 한계를 넘은 크기의 엔티티를 클라이언트가 요청한 경우
414Request URI Too Long서버의 한계를 넘는 길이의 URL을 포함한 요청을 클라이언트가 보낸 경우.
415Unsuppoted Media Type서버가 지원하지 않는 타입의 엔티티를 받은 경우
416Request Range Not Satisfiable리소스의 특정 범위를 요청했는데 그 범위가 맞지 않는 경우
417Expectation Failed요청의 Expect 헤더에 담긴 내용이 서버가 처리할 수 없는 내용의 경우.

✨ 3.4.5 500-599: 서버 에러 상태 코드

서버에서 문제가 발생한 경우.

서버의 제한에 걸렸거나, 서버의 보조 구성 요소(게이트웨이 리소스 등)에 문제가 생겼을수도 있다.

상태 코드사유 구절의미
500Internal Server Error서버가 요청을 처리할 수 없는 에러를 만났을 경우
501Not Implemented서버의 능력을 벗어난 요청을 한 경우 (지원하지 않는 메서드를 요청했다던가)
502Bad Gateway프록시/게이트웨이처럼 동작하는 서버에서 다음 링크로부터 가짜 응답을 받은 경우. (부모 게이트웨이에 접속이 불가능할때 등)
503Service Unavailable지금은 서버가 요청을 처리할 수 없지만, 나중에는 가능함을 의미. 언제 가능한지를 알고 있다면 Retry-After 헤더에 넣어서 응답할수도 있다.
504Gateway Timeout408과 비슷한데 게이트웨이/프록시에서 온 응답이라는 점이 다르다.
505HTTP Version Not Supported서버가 지원할 수 없는 버전의 프로토콜로 온 요청을 받았을 때 사용.

🌟 3.5 헤더

자유롭게 자신만의 헤더를 만들어 낼 수 있다. (확장 헤더)

헤더 문법

  • 이름, 콜론(쉼표라고 적혀 있는데 오타인듯?), 공백(없어도 된다), 필드 값, CRLF 🥹
    Content-type: image/gif
    Content-type:image/gif
  • 긴 헤더를 여러 줄로 쪼개서 적을 수도 있다. 위쪽에서 이어지는 줄을 표시하기 위해서는 최소 하나의 스페이스 또는 탭이 와야 한다. 🥹
    Server: Test Server
    (tab)Version 1.0
    Server: Test Server
    (space)Version 1.0
    Server: Test Server
    (space)(space)Version 1.0
    Server: Test Server
    (tab)(space)Version 1.0

✨ 3.5.1 일반 헤더

요청과 응답 양쪽에 나타날 수 있는 헤더

  • 일반 정보 헤더
  • 일반 캐시 헤더

✨ 3.5.2 요청 헤더

요청에 대한 부가 정보를 제공하는 헤더

  • 요청 정보 헤더
  • Accept 관련 헤더: 클라이언트가 어떤 내용들을 처리할 수 있는지 설명
  • 조건부 요청 헤더: 날짜, 범위, 변경여부 등에 조건을 걸 수 있음.
  • 요청 보안 헤더: HTTP 자체의 인증 체계를 위한 헤더
  • 프록시 요청 헤더: 프록시의 기능을 돕기 위한 헤더

✨ 3.5.3 응답 헤더

응답에 대한 부가 정보를 제공하는 헤더

  • 응답 정보 헤더
  • 협상 헤더
  • 응답 보안 헤더

✨ 3.5.4 엔티티 헤더

본문 크기와 콘텐츠 혹은 리소스 그 자체를 서술하는 헤더

  • 엔티티 정보 헤더: 자신이 다루고 있는게 무엇인지. (Allow, Location)
  • 콘텐츠 헤더: 콘텐츠에 대한 구체적인 정보
  • 엔티티 캐싱 헤더: 언제 어떻게 캐시가 되어야 하는지에 대한 정보

끝. 시간이 부족한게 너무 아쉽다.