치춘짱베리굿나이스

HTTP 기본 본문

이론적인 부분들/웹

HTTP 기본

치춘 2022. 8. 4. 17:30

HTTP 기본

HTTP 소개

Hypertext Transfer Protocol

응용 계층 (Application Layer) 에서 사용되는 프로토콜로, 1989년에 팀 버너스 리에 의해 고안되었다

참고로 www랑 URL 개념도 이분이 고안하셨다 역시 CERN인가? 대박천재시다

 

처음에는 웹 브라우저 - 웹 서버 간 하이퍼미디어 문서 (이름에도 나와있듯, 말그대로 Hypertext 문서) 를 주고받기 위해 만들어진 프로토콜이지만, 지금은 일반 텍스트나 JSON 객체, 이미지 등 미디어 파일들도 주고받을 수 있게 확장되었으며, 어플리케이션이나 IoT 등 웹과 관계없는 분야에서도 이 프로토콜을 이용하여 데이터를 주고받는다

HTTP는 www (월드 와이드 웹) 에 내재되어 있으며, 일반적인 웹 브라우저에는 http 응답을 파싱하고 요청을 보내는 기능이 내장되어 있다

브라우저에서 보여지는 링크에 https라고 써있는 것은 곧 http 방식으로 정보를 주고받겠다는 의미이다

(ftp 프로토콜을 쓰는 경우 ftp:// 라고 명시된다)

웹 브라우저는 기본적으로 http 프로토콜을 이용하여 통신하므로, 평소에는 이렇게 숨김처리 되어있다 (클릭하면 숨어있는 http:// 또는 https://를 볼 수 있다

특징

  • 간단하다
    • 요청, 응답 모두 사람이 읽기 쉽게 구성되어 있다
    • 개발자 도구의 네트워크 탭을 이용하여 패킷의 헤더와 데이터를 뜯어보면, 어떤 요소가 무슨 역할을 하는지 이름부터 명확하게 정의되어 있다
    • HTTP 2.0이 조금 복잡해지긴 했지만, 그래도 크게 어렵지 않아 웹 초심자들도 쉽게 데이터가 오가는 형태를 이해할 수 있다
  • 확장 가능하다
    • 요청 및 응답에 붙는 헤더의 확장성이 높다
    • 서버와 클라이언트가 사용할 헤더에 대해 합의만 한다면, 둘이 원하는 기능을 더 추가할 수도 있다
  • 상태를 저장하지 않지만, 세션은 존재한다
    • 모든 요청은 독립적으로 발생하므로 (한 요청이 처리 완료되면 연결을 끊어버리므로), 요청끼리는 서로 영향을 주지 않는다
    • 따라서 이전에 발생한 요청 및 응답에 의해 현재의 요청 및 응답이 다르게 처리되지도 않는다
    • 다만, 요청 헤더를 확장하면 세션과 쿠키를 이용하여 이전 응답의 상태를 공유할 수 있다
  • TCP 표준에 의존한다
    • TCP의 가장 큰 특징은 1대 1 연결이 유지되므로 신뢰할 수 있는 데이터를 주고받는다는 것이다
    • 따라서 클라이언트-서버간 데이터의 신뢰도가 높다
    • HTTP 구버전은 매 요청마다 TCP 연결을 종료했다가 다시 성사시키기 때문에 이 과정에서 일어나는 핸드쉐이킹 등으로 효율이 떨어지지만, 최신 버전에서는 다중 전송 (Multiplexing) 을 이용하여 개선하였다
    • 지금은 TCP의 효율성 때문에 더 나은 프로토콜을 개발하고 있다고 한다 (언젠간 TCP 표준에 의존하지 않는 날이 올 지도 모른다)

TCP 의존?

HTTP는 TCP/IP 프로토콜 위에서 동작한다고 한다

이때 TCP/IP 프로토콜은 4계층 (전송 계층) 에서 동작하고, HTTP는 7계층 (응용 계층) 엑서 동작하기 때문에 얼핏 들으면 엥? 어떻게 그 위에서 동작하지? 싶은데, HTTP와 TCP가 같은 개념이라는 것이 아니라 TCP의 특징을 살려서 만든 프로토콜이 HTTP인 것이다

HTTP는 연결지향적이며 (클라이언트-서버), 데이터의 신뢰도가 높다

다만 HTTP는 클라이언트-서버간 한 번의 요청 주고받기가 끝나면 연결을 끊어버린다는 특징이 있다

HTTP 1.1과 HTTP 2.0의 차이

  • HTTP 1.1은 하나의 클라이언트-서버 연결에서 한번에 한 요청밖에 처리하지 못한다
    • 하나의 요청이 처리될 때까지 다른 요청이 처리되지 못한다
    • 이는 병목 현상을 유발하며, 하나의 요청이 늦어지면 다른 요청들이 덩달아 밀리면서 대기시간이 계속 길어지는 것이다
    • 또한 TCP 위에서 동작하는 HTTP 특성상 매번 요청이 들어올 때마다 3-way handshake를 해 주어야 연결이 성립하므로, 매 요청마다 handshake를 반복하다 보면 불필요한 성능 및 네트워크 지연이 발생한다 (Round Trip Time 증가)
    • HTTP 2.0은 한 연결 안에서도 동시에 여러 요청을 처리할 수 있도록 개선되어 속도가 월등히 빨라졌다 (Multiplexed Streams 방식)
  • HTTP 1.1은 Head of line blocking이 발생할 여지가 있다
    • 네트워크상의 큐에서 첫 번째 패킷 때문에 뒤에 있는 패킷들이 전부 지연되고 성능 저하가 발생하는 현상이다
    • 성능 저하가 심해지면 결국 특정 패킷을 드랍할 수도 있으며, 결국 클라이언트는 원하는 응답을 받지 못하게 된다
    • HTTP 2.0은 리소스간 의존관계에 따라 우선순위를 두어 나중에 큐에 들어온 패킷이라도 먼저 처리될 수 있도록 개선하였다
  • HTTP 1.1의 헤더는 정보가 많아 무겁고, 이 헤더를 매 요청마다 반복적으로 보내므로 비효율적이다
    • HTTP 2.0은 헤더를 HPACK 방식으로 압축해 메타데이터의 크기를 대폭 줄이고, 헤더 정보 중 중복값에 대해서는 색인으로 처리하여 효율을 높였다

HTTP 3?

2022년에 표준화된 기술이라고 한다 (헉) 완전 예전도 아니다 불과 저저번달이다

HTTP 3은 더이상 TCP 기반으로 동작하지 않고, 구글에서 개발한 UDP 기반의 프로토콜 QUIC을 사용한다

구글에서 개발한 만큼, 브라우저 중 Chrome에 가장 빠르게 도입되었고, Firefox와 Safari도 (부분적으로나마) 도입하였다

웹 사이트 중에서도 구글에서 제공중인 서비스라면 HTTP3을 이용하고 있다

  • TCP를 더이상 사용하지 않는다
    • TCP는 1대1 연결을 위한 과정 (핸드쉐이킹) 때문에 기본적으로 느리며, 속도를 개선하기 위해서는 TCP 표준의 몇몇 요소를 버려야만 하므로 이를 보완하기 위해 아예 다른 프로토콜을 제안하였다
  • UDP 기반?
    • UDP 특성상 ‘데이터를 보내고 받는다' 를 제외하곤 아무런 기능도 설정도 되어있지 않기 때문에 오히려 확장이 용이하다
    • TCP는 신뢰도 높은 연결을 위해 이런저런 표준을 지켜야 하므로 이를 포기하면 결국 TCP 규약을 어기는 것이 되는데, UDP는 표준이 없다는 점이 ‘오히려 좋아' 가 된 것이다
    • UDP의 가장 큰 단점으로 ‘신뢰도가 낮다’ 는 점이 있었는데, UDP의 단점을 보완하고 장점을 살린 QUIC 프로토콜을 개발함으로써 기존의 문제점들을 다수 해결할 수 있었다
  • 더이상 핸드쉐이킹을 하지 않는다
    • UDP 기반으로 바뀌면서 더이상 3-way Handshaking을 사용하지 않게 되었다
    • 기존의 HTTP 프로토콜은 핸드쉐이킹 때문에 여러 번 요청과 응답을 보내느라 RTT (Round Trip Time) 가 증가했었다
    • QUIC에서는 이를 없애버리고 대신 첫 번째 핸드쉐이킹 때 바로 데이터까지 보내버리는 식으로 (?!) RTT를 극적으로 빠르게 개선했다
  • 암호화 방식이 바뀌었다
    • 핸드쉐이킹이 날아가버려 데이터의 신뢰도가 하락했을 것 같지만, QUIC에서는 이를 보완하기 위해 클라이언트-서버간 첫 번째 연결에 초기화 키를 사용하여 통신을 암호화하고, 이 설정을 캐싱한 뒤 이후의 연결에서 해당 설정을 사용하여 지속적인 암호화가 가능해졌다
  • 멀티플렉싱을 지원하여 Head of Line Blocking을 방지하였다
    • 이제 맨 앞 패킷때문에 다른 패킷들까지 느려질 염려를 하지 않아도 좋다
  • IP 주소 대신 Connection ID를 이용하여 연결을 유지하기 때문에, 중간에 연결 변경이 감지되어도 통신을 끊어버리지 않는다

UDP를 사용하기 때문에 속도만 빠르고 신뢰도는 하락했겠지… 라고 생각하면 오산일 정도로 많은 부분이 개선되었다

작동 방식

HTTP 는 서버-클라이언트 모델을 따르므로, 서버 프로그램과 클라이언트 프로그램이 필요하다

실제로는 네트워크 연결 때문에 라우터, 모뎀 등 훨씬 많은 컴퓨터들이 중간에 존재하지만 이들은 네트워크 계층 내에 숨겨지고, 응용 계층에서 동작하는 HTTP에서 가장 중요한 객체는 서버와 클라이언트라고 할 수 있다

작동 흐름은 다음과 같다

  1. TCP 연결을 열고, 서버-클라이언트간 Handshaking을 통해 연결을 성립시킨다
  2. 클라이언트가 서버에 특정한 규격에 맞추어 요청을 보낸다
  3. 서버에 요청이 잘 도착했을 경우, 서버에서는 요청의 헤더와 내용을 파싱한다
  4. 서버에서 클라이언트의 요구사항을 파악한 후, 그에 맞는 응답을 보낸 뒤, 연결을 닫거나 재사용을 위해 남겨놓는다
  5. 클라이언트가 응답을 받으면, 필요에 맞게 가공하여 사용한다

HTTP는 클라이언트가 서버에 정보를 요청할 때에만 서버와 클라이언트가 연결되고, 원하는 데이터를 주고받은 뒤 바로 연결을 끊는다

클라이언트

  • 서버에게 요청을 보내며, 서버에서 받은 리소스를 사용하는 주체이다
  • 웹 브라우저, 모바일 어플리케이션 등이 이에 해당한다
  • 클라이언트는 서버가 될 수 없으며, 응답을 보내지 않고 오직 특정 서버에 요청을 보내고, 그 응답을 가공하는 로직만 구현된다

서버

  • 네트워크 어딘가에 존재하며, 요청이 들어올 때마다 응답을 보내주는 리소스 관리자이다
  • 오직 요청만을 처리하는 하나의 기계라고 보면 된다

HTTP 메시지 형식

HTTP 요청 - 응답 메시지는 개발자 도구의 네트워크 탭에서 간단하게 확인할 수 있다

기본값으로 브라우저에서 자체 파싱한 데이터를 보여주지만, 옵션으로 원본 소스를 볼 수도 있다

요청

GET / HTTP/1.1 // Startline
host: localhost: 8000 // 헤더 데이터
...

[요청 Method] [요청 URI] [HTTP 버전]
[헤더 데이터]

[요청 본문] // POST인 경우에만 존재한다

요청 헤더와 본문은 클라이언트-서버마다 조금씩 다르지만, 첫 번째 줄은 항상 같은 형식을 띈다

  • 요청 메서드에는 GET, POST등의 메서드 종류가 온다
  • 요청 URI는 내가 요청을 보낸 URI 주소이다
    • origin 형식 (상대경로처럼, / 이나 /index.html?query=hello 이런 식으로 쿼리 문자열이 붙는 방식이다)
    • absolute 형식 (절대경로처럼, localhost:8080/index.html 처럼 전체 링크를 다 명시하는 방식이다
    • 그 외에도 CONNECT에만 사용되는 authority 형식, OPTIONS에만 사용되는 asterisk 형식이 있으나 자주 사용되진 않는다
  • HTTP 버전은 통신을 위해 사용한 프로토콜의 버전을 명시한다
    • 이를 명시함으로써 메시지의 나머지 구조들을 파싱할 수 있도록 한다
    • 버전에 따라 암호화가 되거나 캡슐화가 되는 등 조금씩 차이가 있기 때문
  • 헤더는 기본적으로 HTTP 헤더의 기본 구조 (키와 값을 :으로 구분하는 방식) 을 따르나 서버별로 들어가는 값들이 제각각이다
  • 본문은 POST와 같이 클라이언트의 데이터를 가지고 서버의 데이터를 변경해야 하는 경우에 사용되고, 어떤 데이터를 어떻게 POST할 것인지 명시된다

응답

HTTP/1.1 200 OK // Startline
host: localhost: 8000 // 헤더 데이터
...

[HTTP 버전] [상태 코드] [상태 메시지]
[헤더 데이터]

[응답 본문]

응답도 마찬가지로 세부적인 헤더의 형태나 본문의 형태는 서버별로 다르지만, 첫 줄은 항상 같은 형식을 띈다

  • HTTP 버전은 마찬가지로 프로토콜 버전을 명시하여 파싱을 용이하게 한다
  • 상태 코드와 상태 텍스트는 서버별로 요청이 잘 받아졌는지, 어떤 이슈가 발생하진 않았는지 명시한다
  • 헤더는 요청 헤더와 마찬가지로 서버별로 다르며, 메타데이터를 포함한다
  • 응답에는 요청에서 요구한 자원이 들어간다

URL?

http://[IP주소 또는 도메인 이름]:[포트번호]/[자원의 경로]/[자원의 이름]

Uniform Resource Locator

인터넷 상에서 자원이 어디 있는지 알려주는 주소

00시 XX구 aa동 101-1호에 찾아가면 너가 원하는 자원 있어요~ 같은 느낌이다

포트번호는 기본적으로 8080이며, 이 경우 브라우저에서는 생략되어 출력된다

URI?

http://[IP주소 또는 도메인 이름]:[포트번호]/[자원의 경로]

Uniform Resource Identifier

자원의 식별자로, URL의 상위 개념이다

URL도 결국 자원의 위치를 표시한다는 점에서 자원의 식별자로 사용될 수 있으므로, URI에 URL이 포함되는 것

HTTPS

HTTP는 전송 데이터가 암호화되어있지 않아 외부에 노출될 수 있지만, HTTPS는 암호화 과정을 거쳐 안전하게 전송한다

2021년 1월부터 크롬 브라우저는 HTTPS 연결이 아닐 경우 경고문구를 표시한다

인증, 결제 관련 페이지에서는 반드시 HTTPS 연결을 사용해야 하고, 그렇지 않으면 카드번호나 비밀번호가 도용될 수 있다

요청 메서드

메서드는 해당 요청의 종류를 알려준다

서버에서는 요청을 읽어들일 때 종류를 파악하고 어떻게 요청을 처리할 지 고민한다

GET, HEAD 메서드는 모든 서버들이 필수로 지원해야 한다

  • GET: 서버에 자원을 요청할 때 사용한다 (필수)
  • POST: 서버에 특정 자원을 추가하기 위해 사용한다
  • PUT: 서버상에 존재하는 특정 자원을 업데이트하기 위해 사용한다
  • PATCH: 서버상 자원의 일부만을 수정하기 위해 사용한다
  • DELETE: 서버상에 존재하는 특정 자원을 삭제하기 위해 사용한다
  • HEAD: 헤더 정보만 요청한다 (필수)
    • 자원의 존재 여부 또는 서버의 정상 작동 여부를 확인하기 위해 사용한다
  • CONNECT: 서버와 연결을 시도한다
  • OPTIONS: 웹서버에서 지원하는 메서드의 종류를 알려준다
  • TRACE: 클라이언트의 요청을 그대로 반환하며, 서버 상태를 알기 위해 사용한다

대부분의 서버는 GET, POST 정도만으로 동작하며, DELETEPUT도 사실 POST로 대체할 수 있기 때문이다

다만 CRUD에 따라 기능을 분리하기 위해 DELETE, PUT을 같이 사용하여 가독성을 높이기도 한다


참고자료

Chapter 5 Web Servers | Introduction to Web Mapping

HTTP1.1과 HTTP2.0의 차이

HTTP/1.1과 HTTP/2의 차이점

HTTP/3는 왜 UDP를 선택한 것일까?

 

HTTP3 란 무엇일까

HTTP 메시지 - HTTP | MDN

[Network] HTTP의 동작 및 HTTP Message 형식 - Heee's Development Blog

HTTP 요청 메서드 - HTTP | MDN

'이론적인 부분들 > ' 카테고리의 다른 글

DOM과 웹 렌더링  (0) 2023.05.19
JWT  (0) 2022.10.10
로그인, 인증, 인가  (0) 2022.10.08
쿠키와 세션  (0) 2022.10.08
HTTP 응답 코드 종류  (2) 2022.08.04
Comments