[IT] HTTP

노유성·2023년 8월 4일
0
post-thumbnail

IP란

IP는 "Internet Protocol"의 약어로, 인터넷에서 컴퓨터와 기기들이 서로 통신하기 위해 사용되는 프로토콜입니다. IP는 네트워크에서 데이터를 주고받을 수 있도록 패킷을 주소지정하고 전달하는 역할을 합니다.
-chatGPT

나는 IP를 이렇게 얘기하고 싶다. 인터넷 세상에서 사람들은 자신만의 고유한 주소를 갖고 나를 식별하고 남을 식별한다. 그리고 IP(Internet Protocol)을 통해서 패킷을 보내고 우리는 자신만의 고유한 주소, IP주소를 가지고 서로를 식별하고 데이터를 주고 받는다.

IP 패킷 정보

IP 패킷은 인터넷 프로토콜(IP)을 기반으로 데이터를 전송하는 데 사용되는 작은 데이터 덩어리입니다. IP 패킷은 데이터를 주고받을 때 컴퓨터와 기기들 사이에서 이동하며, 전송하는 데이터의 단위로 사용됩니다.
-chatGPT

IP 패킷은 다음과 같은 정보들롤 이루어져 있다.

  • 헤더: 20~60byte의 크기를 가지며 출발지, 도착지의 IP주소 패킷의 크기, 일련번호 등이 저장되어 있다.
  • 페이로드: 실제로 전송되는 데이터

IP의 한계

  • 비연결성: 패킷을 받을 대상이 없거나 서비스 불능 상태여도 패킷을 전송한다.
  • 비신뢰성: 중간에 패킷이 사라지거나 순서대로 오지 않을 수도 있다.
  • 프로그램 구분: 같은 IP를 사용하는 서버에서 통신하는 APP이 2개 이상이라면?
    쉽게 말해서, 내 노트북에서 브라우저와 음악 스트리밍 앱을 어떻게 구분할 것이냐는 뜻이다. 이 문제를 해결하기 위해 TCP가 있따.

인터넷 프로토콜


인터넷 프로토콜은 위와 같이 간단하게 4계층으로 분리해서 생각할 수 있다. 각각의 계층에 대해서 간단하게 설명하자면

  1. 네트워크 인터페이스 계층: 데이터를 전기신호로 변환한 뒤, 물리적 주소인 MAC 주소를 사용해, 알맞은 기기로 데이터를 전달하는 계층
  2. 인터넷 게층: 패킷을 최종 목적지까지 라우팅하는 계층
  3. 전송 계층: 통신 노드 간 신뢰성 있는 데이터 전송을 보장하는 계층, 포트 번호를 사용해 데이터를 정확한 애플리케이션에 전달하는 역할도 함
  4. 어플리케이션 게층: 사용자와 가장 가까운 계층으로, 사용자-소프트웨어 간 소통을 담당하는 계층


위 그림은 hello, world 메세지를 생성해서 다른 서버에게 데이터를 패킷으로 전송하는 과정을 아주 간단하게 도식화한 그림이다.

TCP

TCP는 "Transmission Control Protocol"의 약어로, 인터넷에서 데이터를 안정적으로 전송하기 위해 사용되는 통신 프로토콜입니다. TCP는 인터넷 프로토콜 스택의 핵심 구성 요소 중 하나이며, 인터넷에서 데이터를 전송하는 데에 매우 중요한 역할을 수행합니다.

TCP는 다음과 같은 특징을 가지고 있습니다:

  • 신뢰성: TCP는 데이터를 전송할 때 신뢰성을 보장합니다. 데이터가 손실되거나 손상되는 것을 방지하기 위해 패킷을 보내고 받는 과정에서 오류 검사와 재전송을 수행합니다.
  • 연결 기반: TCP는 연결 지향 프로토콜입니다. 데이터를 전송하기 전에 클라이언트와 서버 사이에 신뢰성 있는 연결을 설정해야 합니다. 이 연결은 데이터를 전송한 후에는 명시적으로 종료되어야 합니다.
  • 순서 보장: TCP는 데이터의 순서를 보장합니다. 데이터가 보낸 순서대로 수신되도록 관리하여 데이터를 올바른 순서로 재조립합니다.
  • 흐름 제어: TCP는 데이터의 흐름을 조절합니다. 수신자가 처리할 수 있는 속도에 따라 데이터의 전송 속도를 조절하여 네트워크 혼잡을 방지합니다


TCP/IP 기반의 인터넷 통신에서 IP의 헤더에는 송수신지의 IP주소를 담았다면 TCP헤더에서는 송수신지의 PORT번호가 있음을 알 수 있다.

위에서 얘기했듯이 TCP는 각 바이트마다 번호가 매겨져 순서를 보장할 수 있으며 3-way-handshake를 통해서 상대방과 연결이 되어있음을 알 수 있다.

위와 같이 클라이언트가 syn을 보내면 서버에서 syn + ack를 보내고 마지막으로 클라이언트가 ack을 보내면서 서로 연결되었음을 알 수 있으며 최근에는 마지막 ack와 함께 데이터도 같이 보낸다고 한다.


그리고 위와 같이 패킷의 순서가 다르게 도착한다면 패킷을 다시 보내라는 요청을 하고 순서를 보장할 수 있다. 실제로는 패킷을 다시 보내라고 요청하는 것이 아니라 내부적으로 순서를 맞추게 해서 최적화를 한다고 한다.

UDP(User Datagram Protocol)

UDP는 "User Datagram Protocol"의 약어로, 인터넷에서 데이터를 비신뢰적으로 전송하는 통신 프로토콜입니다. TCP와 마찬가지로 UDP도 인터넷 프로토콜 스택의 핵심 구성 요소 중 하나이며, 데이터를 전송하는 데에 사용됩니다. 그러나 UDP는 TCP와 달리 신뢰성과 연결 기반 기능을 제공하지 않습니다.

UDP의 주요 특징은 다음과 같습니다:

  • 비신뢰성: UDP는 데이터의 전송을 보장하지 않습니다. 데이터를 전송하는 동안 손실이 발생할 수 있으며, 손실된 데이터는 재전송되지 않습니다.
  • 비연결성: TCP와 달리 UDP는 연결을 설정하지 않고 데이터를 전송합니다.따라서 클라이언트와 서버 간에 미리 연결을 설정하지 않고도 데이터를 전송할 수 있습니다.
  • 단순성: TCP에 비해 UDP는 간단하고 가벼운 프로토콜입니다. 이로 인해 처리 속도가 빠르고, 오버헤드가 적습니다.
  • 흐름 제어와 순서 보장 없음: UDP는 흐름 제어 및 순서 보장 기능을 제공하지 않습니다. 따라서 데이터 패킷이 도착하는 순서와 속도를 보장하지 않습니다.

IP와 거의 같으며 PORT 정보와 checksum 정도만 추가되어 있다. 어플리케이션 계층에서 추가적인 작업을 필요로 하며 TCP보다 부족한 면이 있지만 빠르다는 장점이 있다. 그래서 실시간 스트리밍, 음성 통화, 온라인 게임에서 주로 사용되면 HTTP 3 스펙에서는 UDP를 사용한다.


Port정보는 위와 같이, 같은 IP내에서 프로세스를 구분하기 위해서 사용된다.

DNS

DNS는 한 마디로 전화번호 부이다. ip주소는 변하기도 하고 하나하나 일일이 외우고 있기 힘들기 때문에 도메인과 IP를 매핑하고 우리는 도메인을 외우고 사이트에 접속을 한다. 도메인이 매핑된 정보가 저장된 곳이 DNS 서버이다.

DNS의 구성요소

  • 도메인 네임 스페이스(Domain Name Space)
  • 네임 서버(Name Server) = 권한이 있는 DNS 서버
  • 리졸버(Resolvor, 해결사 서버) = 권한이 없는 DNS 서버

상위 기관에서는 인증된 기관에게 도메인을 생성하거나 IP 주소를 변경할 수 있는 '권한'을 부여한다. DNS는 상위 기관과 하위 기관과 같은 계층 구조를 가지는 분산형 데이터베이스이다. (분산형 데이터베이스란, 논리적으로는 하나의 시스템이지만 물리적으로는 네트워크를 통해 연결된 여러 개의 컴퓨터 사이트에 분산되어 있는 데이터베이스를 의미한다.)

  • 도메인과 IP 주소를 매핑한 텍스트를 저장할 데이터베이스가 있다.
  • 분산된 데이터를 찾아줄 프로그램이 필요하다. 찾았다면 해당 IP 주소로 이동할 브라우저가 필요하다.
  • Domain Name Space라는 규칙으로 도메인 이름 저장을 분산한다.
  • 네임 서버가 해당 도메인 이름의 IP 주소를 찾는다.
  • 리졸버가 DNS 클라이언트의 요청을 네임 서버로 전달하고 찾은 정보를 클라이언트에게 전달한다.

그렇다면 왜 이런 하는걸까?

  • 네임 서버가 여러 대가 존재하기 때문이다.
  • 그렇다면 모든 도메인과 IP 주소를 모든 서버에서 공유해야한다. 안 그러면 특정 네임 서버에서는 특정 도메인을 모른다고 답변할 수도 있다.
  • 그래서 도메인은 계층적으로 구분하는, 정보를 분산하는 구조를 선택했다.
  • 그래서 도메인에는 dot이 존재한다. 예를 들어 www.naver.com에서 .은 계층을 의미힌다.

DNS 동작 방식

  • Browser은 해결사 서버에 요청한다.

    • www.xxxx.kr의 IP 주소를 알려주세요
  • 해결사 서버는 최상위 기관에서 관리하는 네임 서버에게 요청한다.

    • .kr이라는 도메인이 있나요?
  • 최상위 기관에서 관리하는 네임 서버는 응답한다.

    • .kr는 한국 국가 도메인입니다. .kr 네임 서버로 가세요
  • 해결사 서버는 .kr 네임 서버에게 요청한다.

    • xxxx.kr가 있나요?
  • .kr 네임 서버는 응답한다.

    • 네 12.345.678.901 으로 가세요~!
  • 해결사 서버는 Browser에게 알려준다.

    • 12.345.678.901 으로 가세요~!

dot으로 구분되는 네임 서버들간의 상호작용으로 특정 도메인의 IP 주소를 알아낸다. 그래서 DNS는 계층 구조를 가지는 분산형 데이터베이스 시스템이라는 것이다.

URI(Uniform Resource Identifier)

URI는 "Uniform Resource Identifier"의 약어로, 인터넷에서 특정 리소스를 고유하게 식별하는 문자열입니다. URI는 웹에서 문서, 이미지, 동영상, 파일 등 다양한 유형의 리소스를 식별하는 데 사용됩니다.

URI는 URL와 URN으로 나뉜다. URL은 리소스의 위치 URN은 리소스의 이름인데 URN만으로 실제 리소스를 찾는 방법이 보편화가 되어있지 않아 요층은 거의 안 쓰는 추세이다.

URI 읽기

• scheme://[userinfo@]host[:port][/path][?query][#fragment]
https://www.google.com:443/search?q=hello&hl=ko

  • scheme: 주로 프로토콜을 사용하며 어떤 식으로 자원에 접근할 것인지에 대해 약속하는 것이다. http는 80번, https는 443번 포트를 주로 이용한다.
  • userinfo: URL에 사용자 정보를 포함해서 인증하는 거싱나 요즘은 거의 사용하지 않는다.
  • host: 도메인명 또는 IP주소를 직접 사용이 가능하다.
  • port: 일반적으로 생략한다.
  • path: 리소스의 경로를 의미하며 계층적 구조이다.
  • query: key=value의 형태이며 query string, query parameter라고 불린다. 특정 URI에서 리소스를 찾을 때 서버에 조건을 부여할 수 있다.
  • fragment: 서버에 전송하는 정보는 아니며 html 북마크 등에 사용된다.

이렇게 URI를 통해 특정 서버에 클라이언트가 요청을 보내면, 인터넷 프로토콜 4계층에 의해서 다양한 메타데이터가 부여된 패킷을 서버에 전송하고, 서버에서는 그 정보를 받은 후 패킷 정보를 버린 후 순수한 메세지만 받아서 프로세스를 이어간다. 역으로 클라이언트가 정보를 받았을 때도 마찬가지이다.

HTTP

HTTP는 TCP/IP 기반으로 동작하며 요즘은 이미지, 파일, 동영상 등등 거의 모든 정보를 HTTP로 전송하며 서버 간에 데이터를 전송할 때도 HTTP를 사용한다.

HTTP의 역사

HTTP의 특징

클라이언트-서버 구조

클라이언트가 서버에 요청을 보내면, 서버가 요청에 대한 응답을 보내는 클라이언트-서버 구조로 이루어져 있다.

무상태 프로토콜(stateless)

HTTP에서는 서버가 클라이언트의 상태를 보존하지 않는다. 그러므로 요청과 응답은 모두 독립적이며 서버의 확장가능성이 높다. 하지만 클라이언트가 매번 서버에 추가 정보를 제공해야한다는 단점이 있다.


위 그림과 같이 요청은 어떤 서버에게 주어져도 상관이 없기 때문에(stateless하기에) 수평적으로 확장이 용이하다.

HTTP 지속 연결


기존의 http는 stateless하기 때문에 모든 요청에 대해서 연결을 종료해야하기에 불필요하게 연결과 종료를 자주 해야했다.

하지만 지속연결 이후에는 연결과 종료 비용이 감소할 수 있다. 일반적으로 몇 초동안 연결을 유지하거나 한 번의 요청을 모두 처리할 때까지 기다리는 메커니즘을 이용한다.

HTTP 구조


HTTP는 위와 같은 구조를 갖고 있다.

HTTP method

우리가 API설계를 하면 URI라는 말을 많이 쓴다. 리소스란 무엇일까? '미네랄을 캐라'에서 미네랄이 리소스일까 아니면 캐라 까지가 리소스일까? 리소스란 자원을 뜻하며 행위는 자원이 아니다. 그래서 우리가 회원을 조회하는 URI를 만든다고 해서

/read-member-list

이렇게 지어서는 안될 것이다. 그러면 어떻게 해야할까?

GET /members

이렇게 api를 설계하면 uri는 자원 그 자체만을 의미하게 된다.

http메소드에는 다음과 같은 메소드들이 있다.

  • GET: 리소스 조회
  • POST: 요청 데이터 처리, 주로 등록에 사용
  • PUT: 리소스를 대체, 리소스가 없으면 생성
  • PATCH: 리소스를 부분 변경
  • DELETE: 리소스 삭제
    이 외에도 HEAD, OPTIONS, CONNECT, TRACE와 같은 기타 메소드들도 있다.

GET에서도 메세지 바디를 사용할 수 있지만 지원하지 않는 곳이 많아서 권장하지 않는다.

POST는 요청 데이터를 처리한다. 요청 데이터를 처리한다는 것은 어떤 의미일까? 데이터를 제공해서 회원가입을 처리할 수도 있고 새로운 게시판에 게시글을 등록할 수도 있다. 또는

POST /{id}/delete

처럼 uri에 행위를 적어서 게시글을 삭제할 수도 있다. 그렇다 POST는 무적이다!

PUT은 기존의 데이터를 완전히 덮어쓰는 메소드이고 혹은 새로 생성한다. POST와의 차이점은, POST는 구체적인 리소스의 URI를 서버가 만들지만 PUT같은 경우에는 구체적인 리소스의 URI를 클라이언트가 설정한다는 점이 다르다. PATCH는 기존의 데이터를 덮어쓰는 것이 아니라 데이터를 부분 변경한다.

HTTP method의 속성

안전(safe)

safe는 리소스를 호출해도 리소스가 안전하다는 것을 의미한다. GET요청의 경우 수백번, 수천번을 호출해도 데이터가 안전하다. 하지만 DELETE, PUT, POST등 서버의 데이터에 변화를 줄 수 있는 데이터들을 안전하지 않은 메소드인 것이다.

멱등(Idempotent)

몇 번을 호출하던 간에 같은 결과를 내주는 메소드를 뜻한다. GET요청의 경우 몇 번을 요청하던 같은 결과를 내어주며 DELETE 메소드 같은 경우에도 게시글이 존재하던 존재하지 않던 게시글을 삭제한 같은 결과를 내어주므로 멱등하다. 하지만 POST의 경우에는 같은 데이터로 같은 요청을 보낸다할지라도 요청마다 다른 URI가 생성될 수도 있으므로 멱등하지 않다.

멱등을 알아야 하는 이유 중 하나는 바로 클라이언트가 같은 요청을 다시 보내도 되는 지에 대한 이유가 있다. 예를 들어서 옷을 주문하는 서비스를 클라이언트가 요청했다고 가정할 시에 새로고침을 통해서 (새로고침을 하면 직전의 요청을 다시 보내게 된다.) 또 같은 요청을 보내게 되면 주문이 2번 들어가는 경우가 발생할 수 있기 때문이다. 해당 경우에는 멱등성을 고려해서 사용자가 동일한 요청을 2번 보내는 것을 고려해서 설계를 해야한다.

캐시 가능(Cacheable)

응답 결과 리소스를 캐시해서 사용가능한가에 대한 여부이다. POST는 요청마다 다른 결과를 반환하기에 캐시해서는 안된다. 하지만 같은 URI로 같은 GET요청을 보내는 것은 서버의 데이터가 변하지 않는 이상 같은 결과를 반환하므로 캐시를 해도 상관이 없다. 즉, 캐시가 가능하다.

전송 데이터 종류

  • 정적 데이터: 이미지, 정적 텍스트
  • 동적 데이터: 검색, 게시판 처럼 요청에 따른 유동적인 데이터
  • HTML Form: 회원 가입, 상품 주문, 데이터 변경
  • HTTP API: 서버 to 서버, 웹 프론트 to 서버 등

정적 데이터, 동적 데이터는 대부분 GET요청을 사용하며 동적 데이터의 경우는 query string을 이용해서 원하는 데이터를 받을 수 있다.


HTML Form을 이용한 데이터 전송은 위 그림과 같다. form 태그를 이용해서 데이터를 전송하며 content-type은 application/x-www-form-urlencoded이다. 하지만 HTML Form에서 아래와 같이 GET요청을 하게 되면

query string으로 값이 들어간다.

multipart/form-data

multipart/form-data는 웹에서 파일 업로드와 같이 바이너리 데이터와 텍스트 데이터를 함께 서버로 전송하기 위한 MIME(Multipurpose Internet Mail Extensions) 타입 중 하나입니다. 이는 HTML 폼(form) 요소에서 사용되며, 사용자가 파일을 서버로 업로드하거나 대용량의 데이터를 전송해야 할 때 유용하게 사용됩니다.
일반적으로 웹 폼(form)에서는 사용자로부터 텍스트 데이터를 입력받을 수 있지만, 파일을 전송해야 할 경우에는 특별한 방식으로 데이터를 처리해야 합니다. 이때, 폼 요소의 enctype 속성을 multipart/form-data로 설정하여 파일 업로드를 지원합니다.
multipart/form-data를 사용하면 폼 데이터를 여러 부분으로 나누어 각각의 부분을 별도로 인코딩하여 서버로 전송합니다. 각 부분은 boundary로 구분되어 있으며, 이 boundary는 각 부분의 시작과 끝을 나타내는 구분자 역할을 합니다.
파일 업로드와 같이 큰 데이터를 전송해야 할 때, 또는 텍스트 데이터와 바이너리 데이터를 동시에 전송해야 할 때는 multipart/form-data를 사용하여 데이터를 안전하게 전송할 수 있습니다. 이 방식은 대부분의 웹 프로그래밍 언어와 서버 사이드 플랫폼에서 지원되며, 웹 애플리케이션 개발에서 매우 흔히 사용되는 방식 중 하나입니다.

마지막으로 HTML Form은 HTTP METHOD에서 GET과 POST만을 지원한다. 그러므로 다른 동작을 수행하고 싶다면 /new, /edit, /delete와 같은 Control URI를 이용한다.

HTTP 상태 코드

2XX

  • 200: 요청 성공
  • 201: 요청 성공해서 새로운 리소스가 생성됨
  • 202: 요청이 접수되었으나 처리가 완료되지 않음. 주로 배치처리에 이용된다.
  • 204: 요청을 성공적으로 접수했으나 보내줄 본문(payload)가 없을 때 사용한다.

3XX

리다이렉션과 관련된 상태 코드이다. 웹 브라우저는 3XX 코드에 Location 헤더가 있으면 Location 위치로 자동 이동한다.

리다이렉션에는 3가지 종류가 있다.

  1. 영구 리다이렉션: 특정 리소스의 URI가 영구적으로 이동했다.
  2. 일시 리다이렉션: 내용을 일시적으로 변경하는 것이다. 주문 완료 후에 주문 내역 화면을 이동시키기(PRG)
  3. 특수 리다이렉션: 결과 대신 캐시를 사용한다.
  • 301: Moved Permanently, 리다이렉트 시에 요청 메소드가 GET으로 변하고 본문이 제거될 수 있음.
  • 308: 301과 기능은 같으나 HTTP method와 본문을 유지한다.

    하지만 실무에서는 301을 주로 쓴다.
  • 302: Found, 리다이렉트 시에 메소드가 GET으로 변하며 본문이 제거될 수 있음
  • 307: Temporay Redirect, 302와 기능은 같으나 method와 본문을 유지한다.
  • 303: See Other, 302와 기능은 같으나 method가 GET으로 변경

PRG

PRG란 Post/Redirect/Get의 약자로, Post로 주문 후에 웹 브라우저를 새로고침하면 주문이 2번 들어가는 실수가 발생할 수 있으므로 이를 방지하기 위해서 POST요청 후에는 리다이렉션으로 직전 메소드를 GET으로 만드는 기법을 의미한다.

4XX

클라이언트의 요청에 실수가 있어서 응답을 받을 수 없는 상태, 5XX 와의 차이점은, 4XX는 클라이언트의 실수이기 때문에 몇 번을 재시도해도 똑같이 실패한다.

  • 400: Bad Request, 잘못 요청함
  • 401: Unauthorized, 인증되지 않음. 401 응답 시에는 www-authenticate 헤더와 함께 인증 방식을 알려준다. 이름이 좀 아쉽다.
  • 403: Forbidden, 요청을 이해했지만 허용하지 않음. 권한이 부족할 때 발생한다.
  • 404: Not Found, 요청 리소스를 찾을 수 없음. 요청 리소스가 서버에 없을 때 발생하며, 권한이 부족한 클라이언트에게 리소스를 숨기고 싶을 때도 사용한다.

5XX

서버 문제로 오류가 발생

  • 500: Internal Server Error, 서버 내부 문제로 발생. 대부분 애매함녀 500에러로 처리함
  • 503: 서버가 일시적인 과부하로 인해서 잠시 요청을 처리할 수 없음 Retry-After 헤더 필드로 얼마 뒤에 복구될 건지에 대해서 알려줄 수 있다.

HTTP 헤더

HTTP 헤더는 HTTP 전송에 필요한 모든 부가정보를 담고 있다. message body의 내용, 크기, 압축, 인증 등의 정보를 담고 있다. 헤더의 종류는 엄청 나게 많으며

https://en.wikipedia.org/wiki/List_of_HTTP_header_fields

위 사이트에서 전부 확인이 가능하다.

메세지 본문을 통해서 표현 데이터를 전달하며 본문은 payload라고 부른다. 표현(representation)은 요청, 응답에서 전달하는 실제 데이터이며 표현 헤더는 표현 데이터를 해석할 수 있는 정보를 제공한다.

  • Content-Type: 표현 데이터의 형식
  • Content-Encoding: 표현 데이터의 압축 방식
  • Content-Language: 표현 데이터의 자연 언어
  • Content-Length: 표현 데이터의 길이

Content-Encoding은 표현 데이터를 압축하기 위해서 사용하며 헤더 값으로 identity가 들어오면 압축되지 않았음을 의미한다.

Transfer-Encoding(chunked, etc..)를 사용하면 Content-Length를 사용해서는 안 된다.

협상

content-negotiation은 클라이언트가 선호하는 표현 요청에 대해서 알려주는 것을 의미한다.

  • Accept: 클라이언트가 선호하는 미디어 타입 전달
  • Accept-Charset: 클라이언트가 선호하는 문자 인코딩
  • Accept-Encoding: 클라이언트가 선호하는 압축 인코딩
  • Accept-Language: 클라이언트가 선호하는 자연 언어

협상 헤더는 요청 시에만 사용된다.

협상에는 우선 순위가 있다.

Accept-Language: ko;q=0.9,en;q=0.77

위처럼 0~1사이의 수를 고를 수 잇고 클 수록 높은 우선순위를 갖는다. 생략 시에는 1이다. 또 협상은 구체적인 것을 우선시 한다. 예를 들어서

Accept: text/*, text/plain, text/plain;format=flowed

에서는 text/plain;format=flowed 가 제일 높은 우선순위를 갖는다.

전송 방식

단순 전송


단순 전송은 말 그대로 값을 그대로 전송하는 것이다.

압축 전송


압축 전송은 단순 전송에서 값을 압축해서 전달하는 것을 의미한다.

분할 전송


분할 전송은 위와 같이 전송을 여러 번 나눠서 보내는 것을 의미하며 이럴 시에는 content-length가 헤더에 포함되어서는 안 된다. 마지막에 길이가 0인 응답을 보내면은 분할 전송이 끝났음을 의미한다.

범위 전송


특정 범위의 바이트를 전송하는 것을 의미한다. 특정 길이의 이미지를 보내다가 중간에 네트워크가 끊겼을 때, 다시 처음부터 전송을 하면 비효율적이니 중간에 끊긴 부분부터 요청을 하는 것이 범위 전송의 한 예가 될 수 있다.

일반 헤더 정보

특수 헤더 정보


Host는 request에서 사용되며 필수이다. 하나의 서버가 여러 도메인을 처리하는 경우에 외부의 요청이 어느 서버로 향하는 것인지를 host의 정보로 알 수 있다.

Retry-After헤더는 503(서비스 불능)일 때 서비스가 언제까지 불능인지를 알려주는 헤더이다. 날짜로 표기할 수도 있고 초 단위로 표기할 수도 있다.

캐싱

캐시는 서버에서 가져온 데이터를 클라이언트 단에서 일부 저장하고 관리하는 것을 의미한다. 데이터가 변경되지 않았음에도 캐시가 없다면 같은 데이터를 계속 다운로드 받아야한다. 인터넷은 매우 느리고 비싸다. 그래서 매번 데이터를 요구하는 것을 비효율적이고, 매번 모든 자료를 다운로드 받으면은 브라우저 로딩 속도가 매우 느려지며 이는 곧 사용자가 느린 경험을 하게 만든다.


브라우저가 요청을 보낸 후에 일정 시간동안 브라우저에 캐시를 저장할 수 있다. 그리고 요청을 보내기 전에 캐시를 확인하고 캐시가 유효하다면 서버에 요청을 보내지 않고 캐시를 활용한다.

캐시의 시간이 초과 되면은 다시 서버에 요청을 보내게 되는데 이 때 다시 네트워크 다운로드가 발생한다. 하지만 서버에서 만약에 기존 데이터를 변경하지 않았다면 굳이 데이터를 다시 다운로드 받을 필요가 없다. 그러면 캐시된 데이터와 서버의 데이터가 같다면 다시 다운로드 받을 필요가 없는데 이를 식별하는 방법이 있다.


바로 검증 헤더를 이용하는 방법이다. 마지막으로 데이터가 수정된 날짜를 기입하고 캐시의 내용과 서버의 내용이 같다면 서버에서는

304 Not Modified 에러를 내리면서 HTTP Body를 비워서 내려보낸다. 이러면 클라이언트는 캐시를 재사용한다.

하지만 Last-Modified 헤더의 단점이 있다. 바로 1초 미만으로 캐시를 조정하지 못 하고 날짜 기반의 로직을 사용하며, 데이터가 수정되었지만 데이터의 결과가 똑같은 경우를 고려하지 않았다. 이를 방지하는 방법으로 E-tag가 있다.

캐시용 데이터에 임의의 버전을 기입한 후 해당 값을 기준으로 다시 네트워크에서 다운로드할 지 말지를 결정하게 된다.

캐시 제어 헤더

캐시 제어 헤더에는 Cache-Control, Pragma, Expires 헤더가 있다. Pragma와 Expires는 각각 캐시 제어 기능, 캐시 유효 시간 체크 기능이 있으며 Cache-Control의 하위 호환이다.

Cache-Control은 3가지 값을 가질 수 있다.

  • max-age: 캐시의 유효 시간, 초단위
  • no-cache: 캐시해도 되지만 항상 원서버에서 검증하고 사용해야한다.
  • no-store: 민감한 정보이므로 최대한 빨리 삭제해야함.

프록시 캐시


외국에 있는 서버에서 요청을 보내면은 실제로는 500ms가 걸린다고 가정해보자(물리적으로 거리가 멀어서). 그런데 한국에 프록시 캐시 서버를 두면은 100ms만에 가져올 수 있다. 이렇게 origin server에서 특정 값들을 캐시해두는 서버를 프록시 캐시 서버라고 한다.

캐시 지시어에는 다음과 같은 값들이 있으며 자미가으로 캐시 무효화를 위해서는
위와 같은 정보를 기입하면 된다.

profile
풀스택개발자가되고싶습니다:)

0개의 댓글