지난번 글에 이어서 HTTP에 대해 마저 정리해보려고 합니다.
원문 : https://developer.mozilla.org/en-US/docs/Web/HTTP/Overview
HTTP로 제어할 수 있는 것
HTTP의 확장 가능한 특성이 시간이 지남에 따라 HTTP가 웹에서 더 많은 것을 제어하고 더 많은 기능을 수행할 수 있도록 했습니다. 캐시나 인증 메서드들은 HTTP 초기에도 가능했던 기능들이며 origin 제약 완화와 같은 기능은 2010년대에 새로 추가되었습니다.
다음은 HTTP가 제어할 수 있는 기능들입니다.
캐싱
문서가 어떻게 캐시 될 것인지 HTTP가 결정할 수 있습니다. HTTP를 이용해서 서버는 프록시와 client에게 무엇을, 얼마나 오래 캐시 할지를 지시할 수 있습니다. 그리고 client는 중간에 있는 캐시 프록시에게 저장된 문서를 무시하라고 지시할 수 있습니다.
origin constraint 완화
스누핑(몰래 데이터 훔쳐보는 것)과 기타 해킹 공격을 막기위해 웹 브라우저는 웹 사이트들 사이에 엄격한 분리를 강제합니다. 같은 origin(URI 스킴(http:// 인지 https://인지 등), host name, port 가 모두 같은 서버)에서 온 페이지만이 웹 페이지의 모든 정보에 접근할 수 있습니다. 이러한 제약은 서버 성능 저하의 원인이 되기 때문에 HTTP header가 이러한 엄격한 분리의 조건을 완화시켜 다른 도메인으로부터 온 웹 페이지들이 상호작용할 수 있게 해 줍니다. 하지만 이렇게 되면 보안상의 문제가 생길 수 있습니다.
인증
몇몇의 페이지들에 특정한 사용자만이 접근할 수 있어야 하는 경우가 있습니다. 이를 위해 HTTP는 기본적인 인증 기능을 제공합니다. HTTP는 'WWW-Authenticate'나 이와 유사한 header 항목을 통해 인증 기능을 제공합니다. HTTP 쿠키를 이용한 특정 세션 설정을 통해서도 인증 기능이 제공될 수 있습니다.
프록시와 터널링
server나 client가 인트라넷에 존재해 실제 IP주소가 다른 컴퓨터에 공개되지 않을 수 있습니다. 이런 상황에서 HTTP 요청이 프록시를 통해 다른 네트워크로 전달될 수 있습니다.(즉, 프록시를 통하면 인트라넷에서 일반 인터넷과 통신할 수 있다는 뜻, 이것을 터널링이라고 하는 것 같다) 이런 프록시들이 HTTP에만 해당되는 것은 아닙니다. lower level에서 작동하는 SOCKS 프로토콜이나 FTP 같은 다른 프로토콜도 이런 식으로 처리될 수 있습니다.
세션
HTTP 쿠키를 이용하면 서버로 전송되는 요청들이 상태를 가질 수 있게 해준다. 이것이 HTTP가 기본적으로 stateless 프로토콜임에도 불구하고 세션을 생성해준다. 이런 기능은 온라인 쇼핑몰에서 장바구니뿐만 아니라 사용자의 상태를 저장해야 하는 모든 웹 사이트에 아주 유용하다.
HTTP의 흐름
client가 server와 통신하고자 할 때(그 서버가 중간에 있는 프록시 서버이든 마지막에 있는 서버이든) 다음과 같은 과정을 거친다.
1. TCP 연결을 수립한다 : TCP 연결은 하나 또는 여러 개의 요청을 보내서 응답을 받기 위해 사용됩니다. client는 새로운 연결을 수립할 수도 있고 기존에 사용하고 있던 연결을 재사용할 수도 있고 서버에 여러 개의 연결을 수립할 수 있습니다.
2. HTTP 메시지를 보낸다 : HTTP 메시지(HTTP/2 이전의 메시지)는 사람이 읽을 수 있습니다. 하지만 HTTP/2에서는 이 메시지들이 프레임에 캡슐화돼서 직접 읽을 수 없습니다. 하지만 메시지의 형식은 같습니다. 예를 들면 다음과 같은 형식으로 보내집니다.
GET / HTTP/1.1
Host : developer.mozilla.org
Accept-Language : fr
3. 서버로부터 응답받은 다음과 같은 형식의 메시지를 읽는다 :
HTTP/1.1 200 OK
Date: Sat, 09 Oct 2010 14:28:02 GMT
Server: Apache
Last-Modified: Tue, 01 Dec 2009 20:18:22 GMT
ETag: "51142bc1-7449-479b075b2891b"
Accept-Ranges: bytes
Content-Length: 29769
Content-Type: text/html
<!DOCTYPE html... (here comes the 29769 bytes of the requested web page)
4. TCP 연결을 종료하거나 다음 요청에 재사용하기 위해 연결상태를 유지해놓는다.
만약 HTTP 파이프라인이 동작한다면 처음 보낸 요청의 응답이 오지 않아도 다음 요청들을 보낼 수 있습니다. 하지만 HTTP 파이프라인은 오래된 소프트웨어와 최신의 소프트웨어가 뒤섞여 있는 현재의 네트워크 상에서는 구현되기 어렵다는 것이 입증되었습니다. 그래서 HTTP 파이프라인은 프레임을 통해 더 안정적인 다중 전송을 HTTP/2로 대체되고 있습니다.
HTTP 메시지
HTTP/1.1과 그 이전에 정의된 HTTP 메시지들은 사람이 읽을 수 있습니다. HTTP/2에서는 이러한 메시지들을 binary 구조의 프레임 안에 숨겨서 보냅니다. 프레임은 헤더 압축과 다중 전송과 같은 최적화를 가능하게 합니다. 원래 HTTP 메시지의 일부분만 HTTP/2를 통해 전송된다 하더라도 client가 원래의 HTTP/1.1 메시지를 재구성하여 보내기 때문에 메시지의 의미가 변하지 않게 됩니다. 그래서 HTTP/1.1 포맷에서도 HTTP/2를 이해하는 것이 의미가 있습니다.
HTTP 메시지에는 각각의 형식을 가진 request와 response 두 가지가 있습니다.
Requests
HTTP request는 다음과 같은 형식을 가집니다.
request는 다음과 같은 구성요소를 가집니다.
- HTTP 메서드 : GET, POST 같은 동사나 OPTIONS, HEAD 같은 명사로 이뤄져 있으며 client가 원하는 동작을 의미합니다. 일반적으로 client가 서버로부터 자원을 가져오고 싶을 때는 GET을 사용하고 HTML form 태그 내에 작성된 데이터를 서버로 보내고자 할 때에는 POST를 사용합니다. 이외에도 다른 상황들에서는 다른 동작들이 요구될 수 있습니다.
- client가 원하는 동작의 대상이 되는 자원의 경로 : http://와 같은 프로토콜, 도메인(여기서는 developer.mozilla.org), TCP 포트번호(여기서는 80)를 제외한 자원의 URL입니다.
- HTTP의 버전
- 서버에 추가적인 정보를 보내기 위한 headers가 들어갈 수도 있습니다.
- POST 같은 몇몇의 메서드에는 response 메시지와 비슷하게 보내고자하는 데이터를 포함한 body 부분이 추가될 수 있습니다.
Responses
response의 형식은 다음과 같습니다.
response는 다음과 같은 구성요소를 가집니다.
- HTTP의 버전
- 요청이 성공적으로 처리되었는지 실패했는지 그리고 그 이유를 알려주는 상태 코드
- 단순히 상태 코드에 대한 간략한 설명을 제공하는 상태 메시지
- HTTP headers
- client가 GET과 같이 서버로부터 데이터를 가져오는 동작을 요청했을 경우 그 내용을 포함한 body가 추가될 수 있습니다.
HTTP에 기반한 API들
가장 많이 사용되는 HTTP 기반의 API는 XMLHttpRequeset 입니다. 이 API는 user agent와 서버 사이의 데이터 교환이 필요할 때 사용됩니다. 최신의 Fetch API는 더 강력하고 유연한 데이터 교환 기능을 제공합니다.
또 다른 API인 server-sent events는 HTTP 전송 방식을 이용해 서버가 클라이언트로 이벤트를 보내게 해주는 단방향 서비스입니다. EventSource 인터페이스를 이용하여 클라이언트가 연결을 열고 이벤트 핸들러를 수립합니다. 클라이언트 브라우저는 HTTP 스트림을 통해 도착한 메시지를 적절한 Event 객체로 자동변환합니다. 그리고 그 이벤트가 등록된 이벤트라면 알맞은 이벤트 핸들러로 보내지고 등록되지 않은 이벤트라면 onmessage 이벤트 핸들러로 보내집니다.
결론
HTTP는 사용하기 쉬운 확장가능한 프로토콜입니다. 간단하게 headers를 추가할 수 있는 기능을 가진 client-server 구조가 웹의 확장된 기능과 함께 HTTP도 발전할 수 있게 합니다.
HTTP/2에서 성능을 올리기 위해 HTTP 메시지가 프레임 속으로 들어가면서 살짝 복잡해졌지만 메시지의 기본 구조는 HTTP/1.0 이후로 계속 그대로입니다. 세션 흐름도 여전히 단순해서 간단한 HTTP message monitor로 세션을 조사하고 디버그 할 수 있습니다.
공식 한글 번역문은 여기
https://developer.mozilla.org/ko/docs/Web/HTTP/Overview
'Web' 카테고리의 다른 글
JWT(JSON Web Token) 란? (0) | 2021.01.13 |
---|---|
HTTPS는 왜 안전한가? (0) | 2020.11.28 |
HTTP에 대해서(1) (0) | 2020.01.21 |
Express로 만든 웹 사이트 heroku에 올리기 (0) | 2019.08.18 |