• POST 메소드와 PUT 메소드는 HTTP 요청 방식(Method)에 사용될 때, 클라이언트가 웹서버에게 어떤 데이터를 전달하고자 할때 사용
  • Expect 헤더는 클라이언트가 웹서버에게 어떤 데이터를 전달하고자 할때, 사용되는 헤더
  • Expect 헤더는 "돌다리도 두들고 보고 건너라 "에 속하는 헤더
  • 클라이언트가 웹서버에 데이터를 전달할때, TCP 3-way handshake를 통해 세션이 맺어지면 HTTP 통신할 준비가 되었다고 보고 바로 전달하려는 데이터를 보낼 것
  • 웹서버가 클라이언트에게 전달받아서 처리할 수 있는 데이터의 사이즈가 고정 → 클라이언트는 전송할 수 있는 데이터 사이즈를 확인하고 보내야 보다 안전하고 정확하게 전달 가능(Expect 헤더 기능)
  • Expect 헤더를 사용하면, 서버가 처리불가능한 데이터(payload)는 보내지 않게 되므로, 불필요한 네트워크 대역폭 사용의 낭비를 줄일 수 있음
  • 일반적인 브라우저는 Expect 헤더를 전송하지 않지만, cURL과 같은 몇가지 클라이언트들은 전송함


문법 → 현재는 "100-continue" 를 제외하고 어떤 Expect 헤더의 값에 사용 X

Expect: 100-continue



Expect 헤더를 추가하여 클라이언트와 웹 서버간 통신하는 방식

  • 클라이언트가 전달할 데이터가 있는데, 처리 가능한지를 서버에게 확인 요청. (Expect 헤더 사용)
  • 서버는 가능한 경우 클라이언트에게 100 Continue 응답 코드를 통해 알림 (100 Continue)
  • 클라이언트가 데이터를 서버에게 전송
  • 서버는 클라이언트에게 정상적으로 처리되었음을 알림

webdav 서버에서 Expect 헤더를 추가하여 테스트 (제한한 데이터 사이즈보다 작은 데이터 전송)

  • webdav서버의 upload 파일용량을 1024 byte로 제한
  • 클라이언트가 WEBDAV 서버에 I love you 라는 텍스트가 담긴 파일을 업로드
  • 페이로드 사이즈(payload)가 1024 보다 작기 때문에 정상적으로 서버에 생성되었음을 응답코드(201 Created)를 통해 확인 가능

webdav 서버에서 Expect 헤더를 추가하여 테스트 (제한한 데이터 사이즈보다 큰 데이터 전송)

  • webdav서버의 upload 파일용량을 1024 byte로 제한
  • 데이터 사이즈를 웹서버의 제한용량보다 크게 설정 → 컨텐츠 사이즈를 1029 로 설정
  • 웹서버에서 100 continue가 아닌 "413 Request Entity Too Large"라는 에러코드를 보내고 세션을 끊음
  • 웹서버에서 처리할 수 있는 용량을 초과할 경우 불필요한 데이터 전송이 이루어 지지 않음
  • ETag 헤더는 캐시 관련 헤더
  • 서버에서 제공되는 컨텐츠의 식별번호 → 웹서버에서 제공하는 컨텐츠도 각각의 고유 식별정보을 가짐
  • ETag HTTP 응답 헤더는 특정 버전의 리소스를 식별하는 식별자
  • 웹 서버가 내용을 확인하고 변하지 않았으면, 웹 서버로 full 요청을 보내지 않기 때문에, 캐쉬가 더 효율적이게 되고, 대역폭도 아낄 수 있음
  • 내용이 변경되었다면, "mid-air collisions"이라는 리소스 간의 동시 다발적 수정 및 덮어쓰기 현상을 막는데 유용하게 사용
  • 특정 URL 의 리소스가 변경된다면, 새로운 ETag 가 생성
  • ETag 헤더는 지문(finger printer)과 같은 역할을 하면서 다른 서버들이 추적하는 용도에 이용
  • ETag 헤더를 비교하여 리소스가 서로 같은지의 여부를 빠르게 판단할 수 있지만, 서버에서 무기한으로 지속될 수 있도록 설정할 수도 있음
  • 캐시버서와 웹브라우저는 ETag 헤더를 이용해서 캐싱된 컨텐츠들이 유효한지 갱신이 필요한지를 결정


ETag의 두 가지종류 → Strong ETag와 Weak ETag

1. Strong ETag

  • Strong ETag는 바이트 단위로 컨텐츠가 동일함을 의미
  • Strong ETag를 가지고 있는 캐싱된 컨텐츠는 Range 요청에 대해서 응답이 가능
  • Strong ETag 예시
    Strong ETag : "abcdefg"

2. Weak ETag

  • Weak ETag는 바이트단위로 동일 X
  • 일반적으로 캐시된 컨텐츠로는 사용 가능
  • 바이트 단위까지 같지는 않기 때문에 Range 요청에 대한 응답이 불가능
  • Weak ETag 예시
    Weak ETag : w/"abcdefg"


실제 헤더의 ETag 값 예시

  • ETag 값은 보통 "리소스의 해시값 - 마지막 수정 시간의 해시값" 으로 구성
  • 아래 예시를 보면 대시(-)를 기준으로 "48ff5"는 리소스의 해시값, "55559540ad680"은 마지막 수정 시간의 해시값
  • 캐시서버는 일반적으로 자신의 캐싱된 컨텐츠를 비교할때 ETag 값을, If-Match, If-None-Match와 함께 사용

문법

1. W/ Optional

  • 'W/'는 weak validator가 사용 의미 → 대/소문자를 구분
  • Weak validators는 만들기는 쉽지만 비교하기에는 효율성이 떨어짐
  • 'W/'를 사용하지 않는 Strong validators는 비교하기에는 이상적이지만 효율적으로 만들기 어려움
  • 동일한 자원의 두 가지 Weak validator Etag 값은 동일할 수 있지만, 바이트 단위까지 동일하지 않음

2. etag_value

  • etag_value는 요청된 값을 ASCII 코드와 같이 고유한 형태로 나타냄 → 예 : "675af34563dc-tr34"
  • ETag의 값을 생성하는 방법(Method)은 단순히 한가지로 정해져있지 않음
  • 콘텐츠의 해시, 마지막으로 수정된 타임스탬프의 해시, 혹은 그냥 개정번호를 이용

3. ETag 사용 형식

ETag: W/"<etag_value>"
ETag: "<etag_value>"

4. ETag 사용 예시

ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
ETag: W/"0815"



공중 충돌 방지(Avoiding mid-air collisions)

  • ETag 헤더는 If-Match 헤더와 함께 사용함으로 공중 편집 충돌(mid-air edit collisions)을 감지 가능
  • 예를 들어 MDN을 편집할 때 현재 위키 콘텐츠가 해시되어 응답의 Etag를 넣음
    ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4
  • Wiki 페이지(데이터 게시)에 변경 사항을 저장하는 POST 요청에는 신선도(freshness)를 확인할 ETag 값이 있는 If-Match 헤더가 포함.
    If-Math: "33a64df551425fcc55e4d42a148795d9f25f89d4"
  • 해시가 일치하지 않으면 문서가 중간에 편집되었음을 의미하며 412 응답코드(Precondition Failed) 오류가 발생


변경되지 않은 리소스 캐싱(Caching of unchanged resources)

  • ETag 헤더의 또 다른 사용 사례는 변경되지 않은 리소스(Caching of unchanged resources)를 캐시하는 것
  • 사용자가 주어진 URL(기존 ETag 보유)을 다시 방문할 때, 클라이언트는 If-None-Match 헤더 필드를 활용하여 기존의 컨텐츠가 변경되었는지 확인
    If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"
  • 서버는 클라이언트의 ETag(If-None-Match와 함께 전송됨)를 현재 버전의 리소스에 대한 ETag와 비교하고 두 값이 일치하면(즉, 리소스가 변경되지 않은 경우) 서버는 304 Not Modified 상태를 다시 보냄
  • 응답의 캐시된 버전이 여전히 사용할 수 있음을 클라이언트에 알림(freshness)


클라이언트와 서버 간 통신 과정 설명

1. 첫 요청에 대한 응답

  • 클라이언트가 서버에게 요청을 보냄
    $ curl -H "Accept: application/json" -i http://localhost:8080/spring-boot-rest/foos/1
  • 서버는 ETag 헤더를 응답 Header에 담아 클라이언트에게 응답
    HTTP/1.1 200 OK
    ETag: "f88dd058fe004909615a64f01be66a7"
    Content-Type: application/json;charset=UTF-8
    Content-Length: 52

2. 재요청에 대한 응답

  • 클라이언트는 재요청할 때 ETag를 Header의 If-None-Match 헤더에 담아 서버에 요청을 보냄.

    $ curl -H "Accept: application/json"
      \ -H 'If-None-Match: "f88dd058fe004909615a64f01be66a7"'
      \ -i http://localhost:8080/spring-boot-rest/foos/1

  • 리소스가 바뀌지 않았기 때문에 서버는 304 Not Modified를 클라이언트에게 응답 (ETag는 이전 요청에 대한 응답과 같음)

    HTTP/1.1 304 Not Modified
    ETag: "f88dd058fe004909615a64f01be66a7"

  • PUT 메소드를 사용하여 서버의 컨텐츠를 변경

    $ curl -H "Content-Type: application/json"
       -i -X PUT --data '{ "id":1, "name":"Transformers2"}'
       http://localhost:8080/spring-boot-rest/foos/1

  • 서버의 컨텐츠가 정상적으로 변경되었다는 내용을 서버가 응답

    HTTP/1.1 200 OK
    ETag: "d41d8cd98f00b204e9800998ecf8427e"
    Content-Length: 0

  • 클라이언트가 이전 재요청 내용을 다시 서버에게 보냄 → 요청을 다시 할 때는 마지막으로 가지고 있던 ETag를 담아서 보냄

    $ curl -H "Accept: application/json"
       -H 'If-None-Match: "f88dd058fe004909615a64f01be66a7"'
       -i http://localhost:8080/spring-boot-rest/foos/1

  • 클라이언트에서 보낸 ETag와 서버의 ETag가 다르기 때문에 요청을 처리 → 리소스가 바뀌었으니 새로운 ETag를 Header에 담아 보내고, 새로운 요청을 처리했기 때문에 서버는 200 OK를 응답

    HTTP/1.1 200 OK
    ETag: "03cb37ca667706c68c0aad4cb04c3a211"
    Content-Type: application/json;charset=UTF-8
    Content-Length: 56

3. 304 Not Modified 응답 코드

  • 캐시를 목적으로 사용하는 status code
  • 클라이언트에게 응답이 수정되지 않았음을 알려줌
  • 클라이언트는 서버에게 304 응답 코드를 받으면, 클라이언트는 계속해서 응답의 캐시된 버전을 사용 가능

'HTTP > HTTP 헤더' 카테고리의 다른 글

HTTP 프로토콜 Expires 헤더  (0) 2022.06.25
HTTP 프로토콜 Expect 헤더  (0) 2022.06.25
HTTP 프로토콜 Date 헤더  (0) 2022.06.25
HTTP 프로토콜 Content-Type 헤더  (0) 2022.06.25
HTTP 프로토콜 Content-Encoding 헤더  (0) 2022.06.25
  • Date 헤더는 웹서버가 클라이언트의 요청에 응답한 시간을 표시
  • Date 헤더 값을 컨텐츠 자체의 생성/수정된 시간으로 알고 있지만, 해당 내용은 잘못된 정보임
  • 컨텐츠 자체의 생성/수정된 시간은 Last-Modified 라는 헤더에서 표시


HTTP 1.1에서는 아래 형식으로 시간 정보를 표시 → RFC 1123에 정의

  • HTTP 프로토콜에서 Date 헤더의 기본 형식
    Date: Thu, 17 Aug 2017 05:52:23 GMT


HTTP 1.1 이전 버전에서 사용되었던 시간 포맷도 HTTP 1.1에서 처리 가능

1. RFC 850에 정의한 Date 형식

Date: Thursday, 17-Aug-17 05:52:23 GMT

2. C-Language 라이브러리 표준인 Date 형식

Date: Thu Aug 17 05:52:23 2017



Date 정보가 포함하지 않는 경우

  • HTTP에서는 Date 정보를 웹서버에서 응답할 때 반드시 포함해야하지만, 특별한 경우에는 Date 정보를 포함하지 않아도 됨
  • Date 정보가 포함되지 않는 경우
    1. 상태 코드가 "100 Continue" 와 "101 Switching Protocols" 인 경우에 Date 정보 X
    2. 서버 에러(예, 500 Internal Server Error) 경우와 웹서버가 유효한 date 정보를 생성하지 못함

문법

 ### 문법
Date: <day-name>, <day> <month> <year> <hour>:<minute>:<second> GMT


 ### 사용 예제
Date: Wed, 21 Oct 2015 07:28:00 GMT

지시자

1. <day-name>

  • "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", 또는 "Sun" 중 하나가 표시
  • 대소문자 구분

2. <day>

  • 날짜
  • 두 글자로 표시
  • 예시 : "04" 또는 "23"

3. <month>

  • "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" 중 하나가 표시
  • 대소문자 구분

4. <year>

  • 연도
  • 네 글자로 표시
  • 예시 : "1990" 또는 "2016"

5. <hour>

  • 시간
  • 두 글자로 표시
  • 예시 : "09" 또는 "23"

6. <minute>

  • 두 글자로 표시
  • 예시 : "04" 또는 "59"

7. <second>

  • 두 글자로 표시
  • 예시 : "04" 또는 "59"

8. GMT

  • 그리니치 표준시
  • HTTP 날짜는 현지 시각이 아닌, 언제나 GMT로 표현

'HTTP > HTTP 헤더' 카테고리의 다른 글

HTTP 프로토콜 Expect 헤더  (0) 2022.06.25
HTTP 프로토콜 ETag 헤더  (0) 2022.06.25
HTTP 프로토콜 Content-Type 헤더  (0) 2022.06.25
HTTP 프로토콜 Content-Encoding 헤더  (0) 2022.06.25
HTTP 프로토콜 Connection 헤더  (0) 2022.06.25
  • HTTP 메시지(요청과 응답 모두)에 담겨 보내는 데이터의 형식을 알려주는 헤더
  • Content-Type 헤더는 리소스의 media type을 나타내기 위해 사용
  • HTTP 표준 스펙을 따르는 브라우저와 웹서버는 Content-Type 헤더를 기준으로 HTTP 메시지에 담긴 데이터를 분석과 파싱
  • 중요한점은 HTTP 요청의 경우 GET방식인 경우에는 무조건 URL 끝에 쿼리스트링으로 value=text 형식으로 보내지기 때문에 Content-Type은 필요 X → GET방식으로 데이터를 전송 시 웹서버 입장에서는 value=text 형식 데이터라고 판단
  • Content-Type은 POST나 PUT처럼 메시지 BODY에 데이터를 보낼때 필요
  • 브라우저를 기준으로 설명하자면 AJAX를 통해 json 형식의 데이터를 전송하는 경우 Content-Type 값을 application/json 으로 지정하여 전송
  • 브라우저들은 어떤 경우에는 MIME 스니핑을 해서 Content-Type 헤더의 값을 꼭 따르지는 않음 → 해당 현상을 막기 위해, X-Content-Type-Options (en-US) 헤더를 nosniff으로 설정 가능


문법

Content-Type: text/html; charset=utf-8
Content-Type: multipart/form-data; boundary=something



중요한 Content-Type

1. application/octet-stream

  • MIME의 개별 타입 중 application에 속하는 타입으로, 8비트 단위의 binary data 의미
  • 특별히 표현할 수 있는 프로그램이 존재하지 않는 데이터의 경우 기본값으로 octet-stream을 사용 → 브라우저가 보통 자동으로 실행하지 않거나 실행할지 묻기도 하는 타입
  • Content-Disposition 헤더를 attachment로 줌으로써 해당 데이터를 수신받은 브라우저가 파일을 저장 또는 다른이름으로 저장 여부를 설정 가능

※ Content-Disposition 헤더

  • Disposition이란 기질, 성향, 배치, 배열 이란 뜻
  • HTTP Response Header에 들어가는 Content-Disposition은 HTTP Response Body에 오는 컨텐츠의 기질/성향을 알려주는 속성
  • default 값은 inline으로 web에 전달되는 data라고 생각하면 됨
  • 특수한 경우는 Content-Disposition에 attachment를 주는 경우로, 이때 filename과 함께 주게 되면 Body에 오는 값을 다운로드 받으라는 의미
    Content-Disposition: attachment; filename="hello.jpg"


2. text/plain

  • 텍스트 파일에 대한 기본값
  • 실제로 알려지지 않은 텍스트 파일일지라도 브라우저들은 디스플레이할 수 있다고 가정함
  • text/plain이 모든 종류의 텍스트 데이터를 의미하지는 않음
  • CSS 파일을 선언한 alignment로부터 text/plain 파일을 다운로드할 경우, text/plain으로 표현된다면 브라우저는 유효한 CSS 파일로 감지 X → CSS의 MIME 타입인 text/css이 사용해야함


3. text/css

  • 웹 페이지 내에서 보통 인터프리트되어야 하는 모든 CSS 파일들은 text/css 파일이 되어야 함.
  • .css 접미사를 가진 파일들을 CSS 파일이라고 인식하지 못해 text/plain 혹은 application/octet-stream MIME 타입으로 전송 → 해당 사항은 대부분의 브라우저들이 CSS 파일이라고 인식하지 못 하며 실행 X
  • 올바른 타입으로 CSS 파일을 서브하는데 특별한 주의가 필요


4. text/html

  • Content-Type 헤더의 값을 직접 설정하지 않으면, HTML 문서의 MIME 타입인 text/html로 자동 설정


Content-Type의 종류

1, Multipart Related MIME 타입

  • Content-Type: Multipart/related → 기본 형태
  • Content-Type: Application/X-FixedRecord


2. XML Media의 타입

  • Content-Type: text/xml
  • Content-Type: Application/xml
  • Content-Type: Application/xml-external-parsed-entity
  • Content-Type: Application/xml-dtd
  • Content-Type: Application/mathtml+xml
  • Content-Type: Application/xslt+xml


3. Application의 타입

  • Content-Type: Application/EDI-X12 → Defined in RFC 1767
  • Content-Type: Application/EDIFACT → Defined in RFC 1767
  • Content-Type: Application/javascript → Defined in RFC 4329
  • Content-Type: Application/octet-stream → 디폴트 미디어 타입은 운영체제 종종 실행파일, 다운로드를 의미
  • Content-Type: Application/ogg → Defined in RFC 3534
  • Content-Type: Application/x-shockwave-flash → Adobe Flash files
  • Content-Type: Application/json → JavaScript Object Notation JSON; Defined in RFC 4627
  • Content-Type: Application/x-www-form-urlencode → HTML Form 형태
  • Content-Type: application/xml
  • Content-Type: application/pdf

※ 참고

  • x-www-form-urlencode와 multipart/form-data은 둘다 폼 형태
  • x-www-form-urlencode은 대용량 바이너리 테이터를 전송하기에 비능률적
  • 대부분 첨부파일은 multipart/form-data를 사용


4. 오디오 타입

  • Content-Type: audio/mpeg → MP3 or other MPEG audio
  • Content-Type: audio/x-ms-wma → Windows Media Audio;
  • Content-Type: audio/vnd.rn-realaudio → RealAudio; 등등


5. Multipart 타입

  • Content-Type: multipart/mixed → MIME E-mail
  • Content-Type: multipart/alternative → MIME E-mail
  • Content-Type: multipart/related → MIME E-mail → Defined in RFC 2387 and used by MHTML(HTML mail)
  • Content-Type: multipart/formed-data → 파일 첨부


6. TEXT 타입

  • Content-Type: text/css
  • Content-Type: text/html
  • Content-Type: text/javascript
  • Content-Type: text/plain
  • Content-Type: text/xml


7. file 타입

  • Content-Type: application/msword → doc
  • Content-Type: application/pdf → pdf
  • Content-Type: application/vnd.ms-excel → xls
  • Content-Type: application/x-javascript → js
  • Content-Type: application/zip → zip
  • Content-Type: image/jpeg → jpeg, jpg, jpe
  • Content-Type: text/css → css
  • Content-Type: text/html → html, htm
  • Content-Type: text/plain → txt
  • Content-Type: text/xml → xml
  • Content-Type: text/xsl → xsl


8. image 타입

  • Content-Type: image/gif → gif 이미지
  • Content-Type: image/png → PNG 이미지
  • Content-Type: image/jpeg → JPEG 이미지
  • Content-Type: image/bmp
  • Content-Type: image/webp
  • Content-Type: image/svg+xml → SVG 이미지 (벡터 이미지)


9. video 타입

  • Content-Type: video/webm
  • Content-Type: video/ogg

'HTTP > HTTP 헤더' 카테고리의 다른 글

HTTP 프로토콜 ETag 헤더  (0) 2022.06.25
HTTP 프로토콜 Date 헤더  (0) 2022.06.25
HTTP 프로토콜 Content-Encoding 헤더  (0) 2022.06.25
HTTP 프로토콜 Connection 헤더  (0) 2022.06.25
HTTP 프로토콜 Accept-Ranges 헤더  (0) 2022.06.25
  • 웹서버가 응답으로 전달하는 메시지의 인코딩 방식을 명시하는 헤더
  • 주로 Content-Type 헤더와 같이 사용 → Content-Type 헤더는 전달하는 컨텐츠의 포맷
  • Content-Encoding 헤더는 전달하는 메시지의 압축방식과 관련함
  • Content-Encoding 헤더는 HTTP 메시지 전송방식의 Transfer-Encoding 헤더와 비슷하면서도 차이가 있음
    1. Content-Encoding 헤더는 전달하는 컨텐츠 본래 형식으로 전송
    2. Transfer-Encoding 헤더는 HTTP 서버에 의해 적용되는 컨텐츠 전송
  • Content-Encoding 헤더는 미디어 타입을 압축하기 위해 사용
  • Content-Encoding 헤더가 존재하면, Content-Encoding 헤더의 값은 개체 본문에 컨텐츠 인코딩이 적용될지를 나타냄
  • Content-Type 헤더에 의해 참조되는 미디어 타입을 얻도록 디코드하는 방법을 클라이언트가 알게 해줌
  • 가능한 더 많은 데이터를 압축하기 위해 Content-Encoding 헤더 사용이 권고되지만, jpeg 이미지와 같은 유형의 리소스들은 이미 압축되어 때때로 추가적인 압축이 별 소용이 없고 페이로드를 더 길게 만들수도 있음


HTTP 에서는 Content-Encoding 의 값으로 총 4가지를 사용할 수 있음을 정의

  1. compress : 유닉스 시스템에서 사용하는 압축방식
  2. deflate : zlib 압축 포맷 -> RFC 1950에 정의
  3. gzip : gzip 프로그램을 이용하여 압축한 형태 -> RFC 1952에 정의
  4. identity : 특정한 압축 포맷이 사용되지 않았음을 의미


HTTP에서 Content-Encoding 사용 주의

  • 서버는 어떤 압축 방법도 사용하도록 강요받지 않음
  • 압축은 서버 설정과 사용되는 서버 모듈에 상당히 의존적


클라이언트가 요청한 aaa.pdf 파일에 대한 웹 서버의 응답 결과 확인

  • 웹서버의 응답헤더에서 Content-Encoding, Content-Type 결과 확인
    1. Content-Type : application/pdf → 문서가 PDF 형태의 문서
    2. Content-Encoding : gzip → 전달하는 메시지 인코딩 방식은 'gzip' 을 이용해서 전달

문법

Accept-Encoding: gzip
Accept-Encoding: compress
Accept-Encoding: deflate
Accept-Encoding: br
Accept-Encoding: identity



디렉티브

  1. gzip
    • 32비트 CRC와 함께 Lempel-Ziv coding (LZ77)를 사용하는 압축 포맷
    • Unix gzip 프로그램의 포맷
    • HTTP/1.1 표준 컨텐츠 인코딩을 지원하는 서버는 호환성 목적으로, x-gzip 별칭의 인지가 권고
  1. compress
    • Lempel-Ziv-Welch (LZW) 알고리즘을 사용하는 압축 포맷
    • Unix 배포판으로부터 사라진 압축 프로그램으로, 오늘낭의 브라우저에서 사용 X
  1. deflate
    • deflate 압축 알고리즘과 함께 zlib 구조를 사용하는 압축 포맷
  1. br
    • Brotli 알고리즘을 사용하는 압축 포맷
  1. identity
    • 압축하지 않거나 수정하지 않은 경우를 표시
    • identity 값은 존재하지 않은 경우에도 항상 수용 가능


gzip을 이용해 압축 예시

  • 클라이언트 측에서, HTTP 요청 내에 함께 전송될 압축 목록을 알릴 수 있음 → 클라이언트에서 Accept-Encoding 헤더를 사용하여 컨텐츠 인코딩 협상을 위해 사용
  • 클라이언트에서 Accept-Encoding을 사용하여 웹 서버에게 압축 목록을 전달
    Accept-Encoding: gzip, deflate
  • 웹 서버는 사용한 Content-Encoding 응답 헤더에 표시하여 응답
    Content-Encoding: gzip
  • HTTP 전송이 완료된 후에 TCP 연결을 차단할 지 열어둘지를 결정
  • HTTP/2를 사용하지 않는다면 보통 HTTP/1.1을 사용 → Connection: Keep-Alive 헤더는 HTTP/1.1에서는 default이기에 문제 없음
  • HTTP/2에서는 Connection: Keep-Alive 사용 X
  • Connection 일반 헤더는 현재의 전송이 완료된 후 네트워크 접속을 유지할지 말지를 제어
  • 전송된 값이 keep-alive면, 연결은 지속되고 끊기지 않으며, 동일한 서버에 대한 후속 요청을 수행 가능
  • 커넥션을 맺고 끝는데서 발생하는 지연을 없애기 위해서 한번 연결한 TCP 커넥션을 재활용하는 방법을 지속 커넥션(Persistent Connection)이라함
  • 서버 측에서 명시적으로 접속을 끊고 싶을 경우 Connection 헤더에 Close라고 지정
  • Connection와 Keep-Alive 같은 연결-지정(Connection-specific) 헤더 필드들은 HTTP/2에서 사용 금지됨
    • 크롬과 파이어폭스는 HTTP/2 응답에서 Connection과 Keep-Alive을 무시
    • 사파리는 HTTP/2 규격 요건에 따라 해당 필드가 포함된 응답은 처리 X


Connection: Keep-Alive가 없는 경우(HTTP/1.0버전)

  • HTTP/1.1 이전에는 클라이언트와 서버 사이에 트랜잭션 한번이 일어나면 HTTP Connection 이 끊어짐
  • TCP 커넥션을 맺는데 발생하는 지연과 느린 시작 지연이 트랜잭션마다 발생하기 때문에, 한 웹페이지에서 여러 이미지와 HTML을 요청해야 하는 경우 성능이 매우 안 좋아짐
  • 지속 커넥션(Persistent connetion)을 HTTP/1.0에서 활용하기 위해는 특정한 헤더들을 추가해줘야함
  • 지속 커넥션을 사용하기 위해서 활용하는 헤더는 Connection헤더와 Keep-Alive헤더
  • HTTP 요청을 보낼때 Connection: Keep-Alive와 같이 Connection 헤더에 Keep-Alive를 보낼 수 있음
  • 클라이언트 측에서 커넥션을 유지하기를 바라는 요청하지만, 서버가 Connection: Keep-Alive를 지켜준다는 보장은 없음


Connection 헤더의 두가지 기능

1. Connection 헤더는 중간에 위치한 프록시 서버에게 실제 서버로 전달하지 말아야 할 헤더를 알려주는 역할 → 기능은 있지만 활용 X

  • 아래 그림처럼 프록시 서버를 통해 실제 웹서버로 전달되지 말아야 할 헤더 정보(Upgrade 헤더 정보)를 Connection에 명시하면, 프록시 서버는 명시된 헤더는 실제 웹서버로 전달 X
  • 실제로 활용되는 사례를 찾기 어려움

2. HTTP는 Connection 헤더를 통해 연결 유지 기능(Persist Connection)을 관리

  • Connection 헤더를 통해 연결을 즉시 끊을 수도 있고, 또는 연결 유지를 지속적으로 가능함
  • 연결 유지(Persist Connection)는 HTTP 1.1 의 기본 동작 → default 설정
  • 하나의 TCP 연결을 통해 동일한 웹서버에 여러개의 HTTP 트랜잭션을 수행 가능 → 연결 유지 기능(Persist Connection)를 통해 가능
  • 연결 유지 기능을 사용하지 않고자 하는 경우 → Connection 헤더에 close 값을 명시

    • 웹서버는 해당 요청을 받게 되면 요청한 컨텐츠에 대해 응답하고 바로 세션을 끊게 됨
    • Connection: close는 요청 또는 응답 모두 사용 가능
      Connection: close
  • 연결 유지 기능을 사용하고자 하는 경우에는 Connection 헤더에 내용을 추가

    • Connection: Keep-Alive를 통해 연결 유지 기능을 사용
    • Keep-Alive 헤더는 옵션으로 연결 유지를 얼마나 할것인지 초단위로 정의가 가능
      GET / HTTP /1.1
      Connection: Keep-Alive
      Keep-Alive: timeout=10

  • 웹서버가 연결 유지를 지원하는 경우 아래와 같은 응답헤더 내용을 확인 가능

    • 응답 헤더에서도 Connection: Keep-Alive를 통해 연결 유지 기능을 사용할 수 있음을 확인 가능
    • Keep-Alive 헤더는 옵션으로 연결 유지를 얼마나 할것인지 초단위로 정의가 가능
      HTTP /1.1 200 OK
      Connection: Keep-Alive
      Keep-Alive: timeout=10, max=120
      Content-Type: text/html


다음(www.daum.net) 메인 페이지를 접속한 헤더 정보

  • 클라이언트는 연결유지를 사용하기 위해 Connection: Keep-Alive 헤더를 전송
  • 클라이언트에 Keep-Alive 요청을 하였지만, 서버에서는 연결유지를 사용하지 않고 응답과 함께 세션을 끊어버림
  • HTTP 요청에 대해 HTTPS 접속으로 리다이렉트 하기 위한 것 → HTTP 요청에 대해서는 끊어버리고, 새로 HTTPS 접속 요청
  • http://www.daum.net으로 요청

보배드림(https://www.bobaedream.co.kr/) 메인 페이지를 접속한 헤더 정보

  • 클라이언트와 서버에서 모두 연결 유지를 사용
    • Connection: kepp-alive 설정
    • Keep-Alive: timeout=15, max=9999 → 연결 유지를 기본 15초이며, 연결 최대 횟수를 9999회로 정의
  • 서버에서 연결 유지를 얼만큼 할것인지에 대해 추가적인 정보를 Keep-alive 헤더를 통해 클라이언트에게 전달

Connection의 Keep Alive

  • 연결된 socket에 IN/OUT의 access가 마지막으로 종료된 시점부터 정의된 시간까지 access가 없더라도 대기하는 구조
  • 정의된 시간내에 access가 이루어진다면 계속 연결된 상태를 유지
  • time out 내에 requset 재요청시 이미 열려있는 port로 연결


문법

Connection: keep-alive
Connection: close

디렉티브

  1. close
    • 클라이언트 혹은 서버가 연결을 닫으려고 하는 것
    • HTTP/1.0 요청에서 기본 값
  1. 쉼표로 구분된 HTTP 헤더 목록 [보통 keep-alive 만 해당]
    • 클라이언트가 연결을 열린 상태로 유지하려는 것
    • 영속적인 연결을 가지는 것은 HTTP/1.1 요청의 경우 기본
    • 헤더 목록은 첫번째 반투명 프록시 혹은 중간 캐시에 의해 제거될 헤더의 이름
    • 헤더들은 목적지 노드가 아닌 (요청) 발행자와 첫번째 개체 사이의 연결을 정의
  • Accept-Ranges 응답 HTTP 헤더는 부분 요청의 지원을 알리기 위해 서버에 의해 사용
  • Accept-Ranges 필드의 값은 범위를 정의하기 위해 사용될 수 있는 단위를 표시
  • Accept-Ranges 헤더가 존재하면, 브라우저는 처음부터 다시 다운로드를 시작하지 않고, 중단된 다운로드를 연속으로 가능 → Range 헤더
  • 클라이언트가 Range 헤더를 이용해서 요청하는 경우 서버 역시 Range 요청을 처리할 준비 필요 → 서버가 클라이언트에게 Range 헤더에 대한 처리 지원 여부를 알려주는데 Accept-Range 헤더가 사용


HTTP 1.1에서는 Accept-Range의 두가지 형태의 값

  1. Accept-Range: bytes
    • Range 요청을 처리 가능
  1. Accept-Ragne: none
    • Range 요청을 지원 X

※ 침고

  • 클라이언트의 Range 요청에 대해 서버는 Accept-Range 헤더를 반드시 포함하고 있어야하는 것 아님 → 서버가 Accept-Range 헤더를 포함하지 않아도 Range 헤더 사용 가능
  • 클라이언트의 Range 요청을 서버가 지원하지 않는다면, Range 요청에도 불구하고 전체 컨텐츠를 전달


Range 헤더를 포함하여 요청한 예

  • 서버에서 Range 요청을 지원하기 때문에 206 Partial Contents 메시지와 함께 데이터를 전달
  • 60~65 바이트를 전달해 줄것을 요청
  • 웹서버가 클라이언트의 Range 헤더 요청에 대한 응답을 정상적으로 전송
  • 응답헤더의 Accept-Range: bytes 와 Content-Length: 6을 통해 데이터 확인 가능 → Content-Length는 6 bytes
  • Content-Range은 전송하는 "bytes 용량/최종 용량"을 표시

서버에서 Range 요청을 지원하지 않는 예

  • 클라이언트에서 Range 요청을 했음에도 불구하고 서버는 컨텐츠의 전체 용량을 전달
  • 응답헤더의 Accept-Ranges: none 헤더와 Content-Length: 298997을 통해 전체 사이즈가 모두 전달되었음을 확인

문법

Accept-Ranges: bytes
 # 또는
Accept-Ranges: none

디렉티브(directive)

  1. none
    • 지원되는 범위의 단위가 없음을 표시
    • none은 헤더가 존재하지 않는 경우와 동일하므로 거의 사용 X
    • IE9 같은 브라우저의 경우 다운로드 매니저의 일시중지 버튼을 비활설화(disable) 혹은 제거(remove)할 때 사용
  1. bytes
    • 범위는 바이트로 표현 가능
  • 웹의 여러 요소들은 그냥 주고 받기에는 너무 큼 → 여러 압축 알고리즘을 통해 압축을 한 후 주고 받음
  • 어떤 것들은 이미 압축이 되어 다시 압축할 필요가 없는 경우도 있고, 클라이언트나 서버에서 어떤 알고리즘은 지원하고 어떤 것은 지원하지 않는지 확인이 필요함
  • 클라이언트가 서버에게 Accept-Encoding 헤더를 보냄으로써 사용 가능한 압축 알고리즘을 알 수 있음
  • 즉, Accept-Encoding 헤더는 클라이언트(브라우저)가 지원하는 압축방식을 열거함으로써, 클라이언트는 웹서버에게 요청할 때 "나는 이런이런 형태의 압축을 풀어 볼수 있으니, 원하면 명시된 압축방식을 이용해서 보내도 괜찮아요.."라는 메시지를 주는것


Accept-Encoding 헤더 사용 예시

  • 클라이언트가 Accept-Encoding 헤더에 gzip, br, 그리고 가중치를 함께 적음으로서 서버에게 사용할 알고리즘을 전달함
  • gzip, compress, br을 함께 적으면, 셋 모두 클라이언트에서 처리할 수 있으니 서버에게 셋 알고리즘 중 아무 형태든 보내달라고 함
    Accept-Encoding: gzip  
    Accept-Encoding: gzip, compress, br  
    Accept-Encoding: br;q=1.0, gzip;q=0.8, \*;q=0.1
  • 네이버의 PC 홈 화면에서 날라가는 request를 캡쳐 → Accept-Encoding 헤더가 gzip, deflate, br 으로 구성

의미

  • gzip의 경우 그 유명한 gzip 알고리즘 의미
  • br의 경우 구글에서 만든 Brotli 압축 알고리즘을 의미 → 크롬의 경우 버전 50 이후(2016년 배포), 파이어폭스는 44 이후(16년), 사파리는 11 이후 (17년 배포) 버전을 이용한다면 이용 가능
  • br의 경우 css, js, html 파일에 대해 gzip보다 대략 15~20% 크기 측면에서 효율적
  • 2개 이상의 압축방식을 지원하는 경우 쉼표(,) 로 구분하여 표시
  • "압축방식; 퀄리티 정보" 형식 → 퀄리티 부분은 1일 경우 마찬가지로 생략 가능
  • 가중치를 주어서 계산 가능
    1. deflate → deflate 압축 알고리즘과 함께 zlib 구조를 사용하는 압축 포맷으로, q값이 생략됨으로 선호도는 1임
    2. gzip;q=1.0 → gzip 압축 알고리즘을 사용하는 압축 포맷으로, q=1.0으로 선호도는 1임
    3. *;q=0.5 → 표현된 선호 대상이 없다는 것을 의미로 아무 압축 알고리즘을 사용하여 전송해달라는 것, q=0.5로 q=1.0이 없는 경우 전송 요청
      Accept-Encoding: deflate, gzip;q=1.0, \*;q=0.5

※ q는 quality의 약자로 품질의 의미

  • 가중치를 줘서 선호하는 압축 알고리즘을 서버에게 알려줌
  • q 의 값은 0 ~ 1 사이의 값이 부여
  • 1이 최고로 선호하는 품질
  • q는 값이 1일때 생략 가능
  • 웹서버는 클라이언트가 선호하는 형태의 요청을 받게 되면, 압축 알고리즘을 클라이언트가 선호하는 방법으로 제공하여 데이터 전송


문법

Accept-Encoding: gzip  
Accept-Encoding: compress  
Accept-Encoding: deflate  
Accept-Encoding: br  
Accept-Encoding: identity  
Accept-Encoding: \*

 # Multiple algorithms, weighted with the quality value (en-US) syntax:  
Accept-Encoding: deflate, gzip;q=1.0, \*;q=0.5



디렉티브

  1. gzip
    • 32비트 CRC와 함께 Lempel-Ziv coding (LZ77)를 사용하는 압축 포맷
  1. compress
    • Lempel-Ziv-Welch (LZW) 알고리즘을 사용하는 압축 포맷
  1. deflate
    • deflate 압축 알고리즘과 함께 zlib 구조를 사용하는 압축 포맷
  1. br
    • Brotli 알고리즘을 사용하는 압축 포맷
  1. identity
    • 압축하지 않거나 수정하지 않은 경우를 표시
    • identity 값은 존재하지 않은 경우에도 항상 수용 가능
  1. *(asterisk)
    • 헤더 내에 아직 나열되지 않은 컨텐츠 인코딩이라도 일치
    • 헤더가 존재하지 않을 경우, 기본값 → 모든 알고리즘이 지원된다는 것을 의미 X
    • 표현된 선호 대상이 없다는 것을 의미
  1. ;q= (q값 가중치)
    • weight라고 부르는 상대적인 퀄리티 값을 사용
    • 표현한 선호도에 따라 배치된 값

+ Recent posts