[Network] HTTP 구조

- 19 mins

INDEX

Http


HTTP

Hyper Text Transfer Protocol

웹 상에서 데이터를 주고 받기 위해 고안된 통신규약(protocol). 원래는 html 문서를 주고받기 위한 용도로 고안되었으나, 현대에는 다양한 데이터를 주고 받는데 사용되고 있다.

HTTP는 연결 상태를 유지하지 않는 무상태 프로토콜 이다. 때문에 요청을 보내면 응답을 보내고 연결을 끊는다. 즉, 양방향 통신이 아닌 단방향 통신 을 한다.

Stateless vs State

무상태의 단점을 보완하기 위한 방법

1. polling

2. long polling

3. Web Socket

HTML5 표준 어플리케이션 계층의 양방향 통신 프로토콜. 서버와 가장 부담이 적은 방식으로 양방향 통신을 할 수 있다.

단, 지원하는 브라우저가 아닐 경우 사용할 수 없다.

HTTP 메시지 구조

메시지의 각 영역은 줄바꿈(“\n”)으로 구분한다.

screenshot

  1. (Request/ Status) Line : HTTP 프로토콜의 버전, 요청의 METHOD Type, url 혹은 응답의 상태코드가 담긴 영역
  2. Header : header field가 key: value 형식으로 담겨있는 영역
  3. Blank : Body 영역과 Header 영역을 나누기 위해 명시적으로 공백을 준다.
  4. Body : 요청 혹은 응답에 실려 옮겨갈 데이터가 담길 영역

HTTP 메소드

서버에 보내는 요청이 어떤 식으로 처리되길 바라는지 명시적으로 방식을 정해주는 것이다. 서버는 주어진 메소드에 해당하는 작업을 수행한다.

주요 메소드

GET : 리소스 취득
POST : 엔티티 바디 전송
PUT : 요청한 리소스를 바디의 내용으로 업데이트
DELETE : 요청한 리소스를 삭제

GET

GET /login?userId=tester&password=1234 HTTP/1.1

GET 메소드는 리퀘스트 URI로 식별된 리소스를 요구한다. 가져올 리소스의 내용은 서버가 URI를 해석한 결과이다.

POST

POST /login HTTP/1.1
...
...

userId=tester&password=1234

POST 메소드는 엔티티를 전송하기 위해서 사용한다. GET으로도 엔티티를 전송할 수 있지만 목적을 더 명확하게 하고, 보낼 엔티티를 노출하지 않기 위해 POST 메소드를 사용한다.

PUT

PUT 메소드는 목적 리소스 모든 현재 상태를 HTTP 메시지 바디의 데이터로 업데이트 한다.

DELETE

DELETE 메소드는 특정 리소스를 삭제한다.

PATCH

PATCH 메소드는 PUT과 유사하게 요청된 자원을 수정(UPDATE)할 때 사용한다. PUT의 경우 자원 전체를 갱신하는 의미지만, PATCH는 해당자원의 일부를 교체하는 의미로 사용.

HEAD 메소드는 GET 메소드의 요청과 동일한 응답을 요구하지만, 응답 본문(바디)을 포함하지 않는다. 즉, 헤더들만 응답받고 싶을 때 사용한다.

CONNECT

CONNECT 메소드는 목적 리소스로 식별되는 서버로의 터널을 맺는다. TCP 통신을 터널링 시키기 위해서 사용한다.

OPTIONS

OPTIONS 메소드는 목적 리소스가 어떤 메소드를 제공하고 있는지 확인할 때 사용한다.

TRACE

TRACE 메소드는 목적 리소스의 경로를 따라 메시지 loop-back 테스트를 한다.


HTTP 상태코드

상태코드는 요청에 대한 처리결과를 알려준다. 브라우저는 응답을 받았을 때 제일 먼저 상태코드를 확인하여 성공여부를 파악한다.

Screenshot

응답으로 돌아온 상태코드와 실제 상황이 불일치할 수 있다. 서버의 설계에 따라 요청처리 내용과 상태코드가 일치 하지 않을 수 도 있다.

101

protocol 변경 시 사용

ex) Web Socket으로 프로토콜을 변경할 경우

- 2xx (Success)

2xx번대 리스폰스는 요청이 정상처리 되었음을 나타냄

200 OK
201 Created

Post 요청에 대한 응답으로 하나 이상의 새로운 자원이 서버 상에 성공적으로 생성되었음을 나타낸다. 보통 Restful API의 Post 요청에 대한 응답으로 쓰인다.

204 No Content
207 Partial Content

Range에 의해 범위가 지정된 만큼 엔티티를 전달

3xx (Redirection)

리퀘스트가 정상적으로 종료되기 위해서 브라우저에서 특별한 처리(다른 url로 리퀘스트를 다시 보내는 행위)를 수행해야 함.

301 Moved Permanently

원하는 리퀘스트를 처리할 url에 새로운 url이 부여 되어있기에 다음 요청부터는 해당 url을 참조해야한다고 명시. 브라우저의 캐시를 삭제하지 않으면 서버의 변경사항이 적용되지 않을 수 있다. 때문에 주의해서 사용해야 한다.

302 Found

요청을 보낸 리소스에 새로운 URI가 할당 되어 있기 때문에 일시적으로 해당 URI를 참조하라는 뜻. location 헤더에 있는 url로 다시 요청을 보낸다. (POST method를 GET으로 치환)

304 Not Modified

클라이언트에 있는 리소스(캐싱한 리소스)와 서버에 있는 리소스이 서로 같으므로 클라이언트에 있는 파일을 사용하라 라는 의미(실제 리소스 전송은 이루어지지 않는다.)

만약 리소스에 변경이 있으면 200 응답으로 변경된 리소스를 전송한다.

307 Temporary Redirect

4xx (Client Error)

클라이언트에 에러가 발생했을 때

400 Bad Request

요청의 구문이 잘못 되었음을 나타냄 (브라우저는 200 OK랑 똑같이 취급함)

401 Unauthorized

받은 요청에 대해 Http 인증(Basic, Digest)이 필요하다는 것을 나타냄. 만약 한번 인증요청이 이루어진 경우 유저인증이 실패한 것을 표시함. 처음 401 응답을 받을 때 인증을 위한 다이얼이 표시된다.

403 Forbidden

권한이 없는 경우

요청을 받은 리소스의 액세스가 거부되었을 때(허가되지 않은 접근), 거부된 이유는 엔티티 바디에 넣어 응답해줌

404 Not Found

요청한 리소스가 서버상에 없을 때(url 잘못찍었을 때)

5xx (Server Error)

서버에 에러가 발생했을 때

500 Internal Server Error

요청을 처리하는 도중 서버에서 에러가 발생하였을 경우

503 Service Unavailable

일시적으로 서버가 과부하 상태이거나 점검중일 때 현재 요청을 처리할 수 없음을 뜻함


Http 메시지 헤더

메시지 헤더에는 클라이언트나 서버가 리퀘스트나 리스폰스를 처리하기 위한 정보가 들어있다.

메시지 바디의 크기나 사용하고 있는 언어, 인증정보 등을 포함하고 있다.

헤더 필드 이름 : 값

헤더 영역은 이름과 값을 갖고 하나의 필드는 여러 값을 가질 수 있다.

Request

request

REQUEST LINE
메소드, URI, HTTP 버전
HTTP HEADER FIELD
일반 헤더 : 인코딩, 캐시조작 정보
리퀘스트 헤더 : 리퀘스트의 부가정보, 클라이언트의 정보, 리스폰스 콘텐츠에 대한 우선순위
엔티티 헤더 : 바디에 담긴 엔티티의 정보

Response

response

STATUS LINE
Http 버전, 상태코드
HTTP HEADER FILED
일반 헤더 : 인코딩, 캐시조작 정보
리스폰스 헤더 : 리스폰스의 정보, 서버의 정보, 클라이언트의 추가 정보 요구
엔티티 헤더 : 바디에 담긴 엔티티의 정보

end-to-end 헤더, hop-by-hop 헤더

캐시와 비캐시 프록시의 동작을 정의하기 위한 두 가지 카테고리

end-to-end 헤더

http/1.1에서 정의된 헤더는 모두 end-to-end 헤더이다.

종단간 통신. 리퀘스트나 리스폰스의 최종 수신자에게 전송됨, 캐시에서 구축된 리스폰스는 보존되야 한다. 만약 제대로 전송되지 않으면 다시 전송하도록 설계되어있음

hop-by-hop 헤더

한 번 전송에 대해서만 유효함. 네트워크 상의 한 노드와 그 다음 노드 사이에서만 유요한 헤더이다.

캐시와 프록시에 의해서 전송되지 않는 것도 있다. http 1.1에서는 첫 전송 이후에 사용되는 hop-by-hop 헤더는 connection 헤더 필드에 열거해야 한다.

- Connection
- Keep-Alive
- Proxy-Authenticate
- Proxy-Authorization
- Trailer
- TE
- Transfer-Encoding
- Upgrade

위의 8개의 헤더 필드 이외에는 모두 end-to-end 헤더에 분류됨




1. General Header Field

일반 헤더 필드는 리퀘스트와 리스폰스 양 쪽에서 사용되는 헤더필드이다.

- Cache-Control

디렉티브로 불리는 명령을 사용하여 캐싱동작을 지정함

캐시 요청 디렉티브

HTTP 요청 내에서 클라이언트에 의해 사용될 수 있는 표준 Cache-Control 디렉티브.

Cache-Control: max-age=<seconds>
Cache-Control: max-stale[=<seconds>]
Cache-Control: min-fresh=<seconds>
Cache-control: no-cache
Cache-control: no-store
Cache-control: no-transform
Cache-control: only-if-cached
캐시 응답 디렉티브

HTTP 응답 내에서 서버에 의해 사용될 수 있는 표준 Cache-Control 디렉티브.

Cache-control: must-revalidate
Cache-control: no-cache
Cache-control: no-store
Cache-control: no-transform
Cache-control: public
Cache-control: private
Cache-control: proxy-revalidate
Cache-Control: max-age=<seconds>
Cache-control: s-maxage=<seconds>

디렉티브

참고 https://developer.mozilla.org/ko/docs/Web/HTTP/Caching

캐시 능력
만료
재검증과 리로딩
기타

- Connection

http 1.1에서는 지속적인 접속이 기본이지만 예전 버전(1.0 이하)은 지속적인 접속이 기본값이 아니다. 때문에 Connection : Keep-Alive를 지정해야함

- Transfer-Encoding

메시지 바디의 전송 코딩형식을 정의한다. http 1.1 버전에는 chunked 방식만 있다.

chunked의 뜻은 덩어리란 뜻. 덩어리로 쪼개서 보내는 전송방식을 뜻함

Transfer-Encoding : chunked

2. Request Header Field

클라이언트 측에서 서버 측으로 송신된 리퀘스트 메시지에 사용되는 헤더. 부가 정보, 클라이언트 정보, 리스폰스의 콘텐츠에 관한 우선 순위 등이 추가됨

- Accept

요청을 보낼 때 클라이언트가 응답을 받아 처리할 수 있는 엔티티형식을 알려주는 필드

브라우저에서 처리 가능한 미디어 타입을 표시한다. 품질 지수(q)는 표시 안할 경우 가장 높은 값(1.0)이고, ;q=0.9 이런 방식으로 품질 값을 정해 선호 순서를 지정할 수 있다.

Accept: text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8

미디어 타입의 지정은 타입/서브 타입으로 지정. 한번에 여러 번 설정가능함

- Accept-Charset

유저 에이전트에서 처리할 수 있는 문자셋. 문자셋의 상대적인 우선순위를 전달하기 위해 사용. 한번에 여러개 가능. 품질 지수를 지정할 수 있다.

Accept-Charset: utf-8, iso-8859-1;q=0.5

- Accept-Encoding

유저 에이전트가 처리할 수 있는 콘텐츠 코딩과 콘텐츠 코딩의 상대적인 우선순위를 전달하기 위해 사용.(클라이언트가 해석할 수 있는 압축 알고리즘이 무엇인지 알려준다.)

한 번에 여러개 지정 가능.

서버는 Content-Encoding 응답 헤더로 선택된 것이 무엇인지 클라이언트에게 알려줌

Accept-Encoding: deflate, gzip;q=1.0, *;q=0.5

- Accept-Language

유저 에이전트가 처리할 수 있는 자연어의 세트와 자연어 세트의 우선순위를 전달 함

- Authorization

유저 에이전트의 인증정보(크리덴셜 값)을 전달하기 위해서 사용된다.

서버에서 인증이 필요하다는 상태 코드 401 Unauthorized 와 인증 타입이 응답으로 올 경우 인증 타입에 맞춰 사용자명, 비밀번호를 인코딩하여 전달

Authorization: <type> <credentials>
Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l

보통 Basic 인증 스킴이 사용된다.

- Host

리퀘스트한 리소스의 인터넷 호스트와 포트 번호를 전달한다. http/1.1에서 유일한 필수 헤더 필드 이다. 존재 이유는 한 서버에서 복수의 도메인을 할당할 수 있는 가상 호스트의 구조와 관련이 있다.

Host: <host>:<port>
Host: developer.cdn.mozilla.net

리퀘스트가 서버에 오면 호스트명을 IP 주소로 바꾸어 리퀘스트가 처리된다. 만약 같은 IP 주소로 복수의 도메인이 적용되어 있다면 Host 헤더 필드에 리퀘스트를 받을 호스트명을 정확히 입력할 필요가 있다.

http 프로토콜의 기본 port 번호는 80이고, 서버에 호스트명이 설정되어 있지 않으면 값을 비워서 보낸다.

- If-Match

조건부 리퀘스트.

서버상의 리소스를 특정하기 위해서 엔티티 태그(ETag)값을 전달한다. 이 때 서버는 약한 ETag값을 사용할 수 없다. 서버는 If-Match 필드의 값과 리소스의 Etag값이 일치하는 경우에만 리퀘스트를 받아 들일 수 있다. 일치하지 않으면 412 Precondition Failed 리스폰스를 반환한다.

If-Match: "bfc13a64729c4290ef5b2c2730249c88ca92d82d"

If-Match: W/"67ab43", "54ed21", "7892dd"

If-Match: *

- If-Modified-Since

조건부 리퀘스트.

리소스가 갱신된 날짜가 필드값보다 새롭다면 응답을 보내라는 뜻. 없다면 304 Not Modified를 응답함

- If-None-Match

조건부 리퀘스트.

필드에 지정된 Etag값이 지정된 리소스의 ETag 값과 일치하지 않으면 리퀘스트를 받아 응답을 해줌

- If-Range

조건부 리퀘스트.

필드의 Etag값 혹은 날짜와 지정한 리소스의 Etag값 혹은 날짜가 일치할 경우 Range 리퀘스트로 처리하고 싶다는 것을 전ㄱ달하고 일치 안하면 리소스 전체를 반환함

- If-Unmodified-Since

지정된 리소스가 필드값에 지정된 날짜 이후에 갱신 되어 있지 않은 경우만 리퀘스트를 받아들임

- Max-Forwards

필드에 값 만큼 서버를 경유할 수 있음 프록시 서버를 경유할 때 마다 1씩 감소됨. 문제가 발생한 경우의 원인조사에 활용되는 필드

- Proxy-Authorization

프록시 서버의 인증요구를 받아 들일 때 인증에 필요한 클라이언트의 정보를 전달 함. 클라이언트와 서버의 HTTP 인증과 비슷하지만 다른 점은 클라이언트와 프록시 사이라는 것

- Range

range 헤더 필드는 리소스의 일부분만 취득하는 Range 리퀘스트를 할 때 지정 범위를 전달 함.

- Referer

Referrer가 올바르지만 Referer로 쓰이고 있다.

리퀘스트가 발생한 본래 리소스의 URI를 전달한다. 만약 보안상 바람직 하지 않다고 생각하면 생략해도 좋다.

referer: https://developer.mozilla.org/ko/docs/Web/HTTP/Conditional_requests

- User-Agent

리퀘스트를 생성한 브라우저와 유저 에이전트의 이름을 전달하기 위한 필드

user-agent: Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Mobile Safari/537.36

3. Response Header Field

서버측으로 부터 클라이언트 측으로 송신되는 리스폰스 메시지에 적용된 헤더. 리스폰스의 부가 정보나 클라이언트에 부가 정보요구를 나타냄

- Accept-Ranges

Range 리퀘스트가 수신 가능한지 여부를 응답해주는 필드

Accept-Ranges: bytes // 가능
Accept-Ranges: none // 불가능

- Age

얼마나 오래전에 오리진 서버에서 리스폰스가 생성되었는지 전달함 (단위 : 초) 프록시에서 응답이 생성된 경우 해당 필드는 필수

Age: 600

- ETag

엔티티 태그라고 불리며 특정 버전의 리소스를 식별하는 식별자이다. url상 리소스가 변경, 갱신되면 그 때마다 ETag값도 갱신된다. Etag값으로 캐시 서버에서 오리진 서버와 비교하고 리소스 값을 갱신한다.

ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"

- Location

응답 수신자에게 요청한 URI가 아닌 다른 리소스로 액세스하도록 유도할 때 사용된다. 3xx 번 때 상태 코드로 응답할 때 같이 쓰인다. 대부분의 브라우저는 Location 헤더 필드를 포함한 응답 메시지를 받으면 강제로 해당 리소스에 엑세스 시도

- Proxy-Authenticate

프록시 서버에서의 인증요구를 클라이언트에 전달함

- Retry-After

클라이언트가 일정시간 후에 리퀘스트를 다시 시행해야하는 지 전달함

- Server

이 필드는 서버에 설치되어 있는 HTTP 서버의 소프트웨어를 전달한다.

Server: Apache/2.4.1 (Unix)

- WWW-Authenticate

리퀘스트 URI에 지정했던 리소스에 적용할 수 있는 인증 스키마(Basic or Digest)와 파라미터를 나타내는 challenge를 전달한다.

WWW-Authenticate: Basic realm="Access to the staging site", charset="UTF-8"

상태코드 401 Unauthorized 응답에 무조건 포함된다. realm은 인증의 범위(요청 URI의 보호공간을 식별하기 위한 문자열)이다.

4. Entity Header Field

리퀘스트, 리스폰스 메시지에 포함된 엔티티에 사용되는 헤더. 콘텐츠의 갱신 시간 같은 엔티티의 정보를 포함함

- Allow

리퀘스트 URI에 지정된 리소스가 제공하는 메소드의 일람을 전달함. 서버가 받을 수 없는 메소드를 수신한 경우 405 Method Not Allowed 상태코드와 함께 수신 가능한 메소드 일람을 기술한 헤더 필드를 반환함

Allow: GET,HEAD

- Content-Encoding

서버가 엔티티 바디에 대해서 실시한 콘텐츠 코딩 형식을 전달함. 엔티티의 정보가 누락되지 않도록 압축할 것을 지시한다.

Content-Encoding: gzip

콘텐츠 코딩의 형식은 Accept-Encoding 헤더 필드에 서술된 내용과 같다.

- Content-Language

엔티티 바디에 사용된 자연어를 전달

- Content-Length

엔티티 바디의 크기(단위 bytes)

- Content-Location

메시지 바디에 대응하는 URI를 전달함 Location헤더 필드와 달리 메시지 바디로 반환된 리소스의 URI를 나타냄

예를 들어 Accept_Language 필드를 이용해서 영어를 쓴다는 것을 알 경우 / url로 요청이 왔어도 실제 리소스는 index-en.html이 반환 될 수 있다.

- Content-Range

Range 리퀘스트가 왔을 때 지정된 범위에 대해 응답할 때 사용된다.

Content-Range: bytes 5001-10000/10000

- Content-Type

서버가 응답으로 보낸 바디안의 엔티티의 타입을 명시한 필드

엔티티 바디에 포함되는 리소스의 미디어 타입을 전달한다. Accept 필드와 같이 “타입/서브 타입”으로 기록함

charset 파라미터는 문자셋을 지정함

Content-Type: text/html; charset=utf-8

- Expires

리소스의 유효기한 날짜를 전달한다. 캐시 서버에서 Expires 헤더 필드를 포함한 리소스를 수신한 경우 지정된 날짜까지 응답의 복사본을 유지하고 리퀘스트가 왔을 때 응답한다.

만약 Cache-Control 헤더 필드에 max-age디렉티브가 지정되어 있는 경우 Expires에 우선하여 지정됨

- Last-Modified

리소스가 마지막으로 갱신되었던 날짜 정보를 전달. 기본적으로 요청 URI의 지정된 리소스가 갱신된 날짜가 되지만, 동적인 데이터를 다룰 경우 그 데이터의 최종 갱신날짜가 됨

5. 쿠키를 위한 헤더 필드

쿠키가 호출되었을 때는 쿠키의 유효기한과 송신지의 도메인, 경로, 프로토콜 등을 체크할 수 있다. 때문에 쿠키때문에 다른 웹사이트와 공격자의 공격에 의해 데이터가 도난 당하지 않게 조심해야한다.

Response에 쓰이는 헤더 필드. 클라이언트에게 쿠키를 저장하라고 전달한다.

Set-Cookie: <cookie-name>=<cookie-value>; <property>

Secure 쿠키는 HTTPS 프로토콜 상에서 암호화된(encrypted) 요청일 경우에만 전송된다. 하지만 Secure일지라도 민감한 정보는 절대 쿠키에 저장되면 안된다. 본질적으로 안전하지 않고 이 플래그가 당신에게 실질적인 보안(real protection)를 제공하지 않기 때문. 크롬52 혹은 파이어폭스52로 시작한다면, 안전하지 않은 사이트(http:) 는 쿠키에 Secure 설정을 지시할 수 없다.

Cross-site 스크립팅 (XSS) 공격을 방지하기 위해, HttpOnly쿠키는 JavaScript의 Document.cookie API에 접근할 수 없습니다; 그들은 서버에게 전송되기만 합니다. 예를 들어, 서버 쪽에서 지속되고 있는 세션의 쿠키는 JavaScript를 사용할 필요성이 없기 때문에 HttpOnly플래그가 설정될 것이다.

Request에 쓰이는 헤더 필드. 서버로 부터 수신한 쿠키를 이후의 리퀘스트에 포함해서 전달 함

Cookie: <cookie-name>=<cookie-value>; <cookie-name>=<cookie-value>;

Sehun Kim

Sehun Kim

하다보니 되더라구요.

comments powered by Disqus
rss facebook twitter github youtube mail spotify lastfm instagram linkedin google google-plus pinterest medium vimeo stackoverflow reddit quora quora