과거의 내가 미래의 나에게
HTTP 학습 (3-2) - 요청 헤더 필드 본문
* HTTP/1.1을 기준으로 작성되었습니다.
리퀘스트 헤더 필드는 클라이언트에서 서버로 송신하는 리퀘스트 메시지에 쓰이는 헤더로, 리퀘스트의 부가 정보와 클라이언트 정보 그리고 리스폰스 콘텐츠에 관한 우선 순위 등을 추가한다.
1. Accept
클라이언트에서 서버에게 자신이 원하는 미디어 타입과 미디어 타입의 우선순위를 전달하기 위해 사용된다.
< 미디어 타입 >
왼쪽은 주 타입이고, 오른쪽은 보조 타입이다.텍스트 파일: text/html, text/plain, text/css, application/xml...
이미지 파일: image/png, image/gif...
동영상 파일: video/mpeg, video/quicktime...
애플리케이션 바이너리 파일: application/zip...
accept 헤더에 미디어 타입을 나열하는데 각 미디어 타입은 쉼표로 구분되어있으며 또 그 뒤에는 우선순위를 나타내는 "q(quality의 약자)"가 달려있다. 이는 0~1까지 나타낼 수 있으며 1에 가까울수록 높은 우선순위를 가진다. 1은 생략될 수 있다.
사용 예시를 살펴보면 아래와 같다.
Accept: application/json, text/plain;q=0.8, application/*;q=0.5
클라이언트가 application/json을 가장 우선시하고, 그 다음으로 text/plain은 0.8의 우선순위를 가지며, 마지막으로 application/*은 application이라면 어떠한 것도 괜찮다라는 뜻으로 0.5의 우선순위를 가진다.
이 내용을 이를 서버에게 보내면 서버는 이 목록 중에 하나를 선택하여 Content-Type 응답 헤더로 클라이언트에 자신이 선택한 타입을 알려주게 된다.
2. Accept-Charset
클라이언트가 자신이 원하는 문자셋의 종류를 알려주는 헤더로, 표시방식은 Accept와 비슷하다.
Accept-Charset: utf-8, iso-8859-1;q=0.5
3. Accept-Encoding
클라이언트가 원하는 압축방식을 나열한 것이다. 방대한 데이터를 보낼 때 이를 압축하여 보내면 응답 시간을 단축할 수 있는데, 이 때 클라이언트가 처리할 수 있는 압축방식을 서버에게 알려주고, 서버는 해당 방식으로 데이터를 압축하여 클라이언트에 보내게 된다.
Accept-Encoding: gzip, deflate
4. Accept-Language
클라이언트가 원하는 언어의 종류를 나열한 것이다.
Accept-Language: ko,en;q=0.9,en-US;q=0.8
위와 같이 나열함으로써, 클라이언트는 한국어를 가장 우선 시 해서 받길 원하며, 그 다음은 영어 그 다음은 US 영어를 받기를 원한다는 뜻이다.
5. Authoriaztion
사용자가 HTTP 요청을 통해 리소스를 받아오는데, 서버에서 사용자에 대한 인증을 요청해오면 클라이언트는 사용자의 인증 정보를 보내야한다. 이 때 Authoriaztion 헤더를 통해 사용자의 인증 정보를 보내고 서버에서 통과되면 리소스를 받아올 수 있게 된다.
6. Except
클라이언트가 서버에게 어떤 데이터를 전달하고자 할 때, 웹서버에게 해당 데이터가 처리 가능한 지 사전에 확인할 수 있는 헤더 필드이다. 만약 서버가 처리 불가한 데이터였다면 해당 데이터는 보내지 않을 수 있게 되고 처리 가능하다면 HTTP 응답코드 100 continue를 보내온다.
7. From
브라우저를 사용하고 있는 유저의 메일 주소를 전달하는 필드이다.
그러나 메일 주소는 개인정보의 영역이기 때문에 거의 사용되지 않으니 그냥 이런거구나~하고 알아만 두면 될 것 같다.
8. Host
HTTP/1.1부터 등장한 헤더 필드로, 유일하게 필수로 전달해야하는 헤더 필드이며 리퀘스트한 리소스의 인터넷 호스트와 포트 번호를 전달한다.
Host가 없던 때에는 서버에서 IP 주소로 리퀘스트 온 곳을 구분했어야 했는데, 하나의 IP가 여러 도메인을 호스팅하는 경우는 처리할 수 없는 등 이는 한계가 존재했다.
하지만 Host 헤더 필드가 나오면서 이 한계는 없어져 지금의 가상 호스팅을 처리 가능하게 만들어졌다.
9. If-xxx
If로 시작하는 이 헤더들은 조건부 리퀘스트라 부르며, 서버는 조건부 리퀘스트를 받으면 조건에 맞는 경우에만 리퀘스트를 받는다.
1) If-Match
If-Match의 값으로 E-Tag를 전달하는데, 이를 통해 서버 상의 리소스를 특정할 수 있게 된다.
< E-Tag >
ETag란 EntityTag의 줄임말로 웹 서버가 제공하는 리소스(컨텐츠)에 각각 부여되는 고유값이다.
웹 서버는 리소스에 ETag를 생성하여 응답 헤더에 달아 클라이언트에게 보내주는데, ETag를 활용하면 클라이언트가 요청한 리소스가 이전의 요청했던 리소스와 동일한지 확인할 수 있고, 동일한 리소스라 판단하면 바디값을 보내지 않고 캐시로 활용하게끔 하는 등 트래픽을 아낄 수 있는 수단이 될 수 있다.
더 자세한 건 후에 응답 헤더를 볼 때 살펴보겠다.
서버는 클라이언트의 If-Match 값과 리소스의 E-Tag 값이 동일한 경우에만 요청을 받아들인다. 만약 동일하지 않으면 서버는 412 Precondition Failed 리스폰스 값을 반환한다.
If-Match를 사용하는 경우는 보통 동일 리소스에 대한 동시 작업 시 데이터의 무결성을 보장받기 위해서라고 한다.
특정 상황을 예시로 들어보면 아래와 같다.
1. A와 B는 홈페이지에 올라가있는 "banner1"의 이미지를 바꾸기 위해 배너섹션의 이미지를 변경 할 수 있는 HTTP 요청을 동시에 한다.
2.서버는 약간의 차이로 A의 이미지 변경 요청을 먼저 받아 "banner1" 이미지를 A가 보낸 "banner2"로 변경한다.
3.이어서 서버는 B의 이미지 변경 요청을 받아 현재 이미지인 "banner2"를 B가 보낸 "banner3"로 변경한다.
위 상황에서 B가 원하는 작업은 "banner1"을 "banner3"로 바꾸는 일이었지만, 실제로는 "banner2"를 "banner3"으로 변경하는 작업이 이루어졌다.
이러한 상황에서 If-Match를 활용한다면 B의 요청은 412 Precondition Failed 리스폰스로 돌아오게 되었을 것이고, 요청자가 원한 상황으로 명확히 일이 진행될 것이다.
2) If-None-Match
If-None-Match는 바로 위의 If-Match와 정반대로 동작한다. If-None-Match 값과 리소스의 E-tag값이 일치하지 않으면 서버가 요청을 받아들여 새 응답을 준다는 것이다.
If-None-Match를 사용하는 경우는 E-Tag의 값을 이 곳에 담아서 보낼 때, 요청한 데이터의 E-Tag가 응답할 데이터의 E-Tag 값과 동일하다면 서버는 응답하지 않고, 두 값이 서로 다르면 서버가 응답하도록 한다. 즉, 요청한 데이터가 내용이 바뀌었다면 HTTP 응답코드 200으로써 새로운 데이터를 주고, 바뀌지 않았다면 HTTP 응답코드 304 Not Modified로 새로운 데이터를 받을 필요가 없다는 답변을 받는 것이다.
3) If-Modified-Since
리소스의 갱신날짜가 If-Modified-Since의 날짜 값보다 이전의 날이라면 서버는 HTTP 응답코드 304 Not Modified를 반환하고, 갱신날짜가 값보다 이후의 날이라면 HTTP 응답코드 200과 함께 리소스를 반환한다.
이는 GET과 HEAD에서만 쓸 수 있으며, 만약 If-None-Match와 같이 쓰인다면 If-None-Match가 우선적용된다.
4) If-Unmodified-Since
If-Unmodified-Since는 바로 위의 If-Modified-Since와 정반대로 동작한다.
리소스의 갱신날짜가 If-Unmodified-Since의 날짜 값보다 이전의 날이라면 서버는 HTTP 응답코드 200을 반환하고, 갱신날짜가 값보다 이전의 날이라면 HTTP 응답코드 412 Precondition Failed를 반환한다.
5) If-Range
If-Range 값에다 E-Tag값 혹은 날짜를 넣고, 리소스 값의 E-Tag 값 혹은 날짜에 해당하면 리소스를 반환하고, 만약 그렇지 않다면 전체 리소스를 전부 반환받는다.
If-Range 헤더는 보통 Range 헤더와 함께 사용되는데, 이를 같이 사용한다면 If-Range의 값이 리소스에 해당한다면 Range에 적어놓은 범위의 리소스를 반환받고 그렇지 않으면 전체 리소스를 반환받는 방식으로 사용한다.
10. Max-Forwards
리퀘스트를 한 번 보내면 프록시 서버 등 여러 대의 서버를 거쳐 최종 서버로 도착하곤 하는데, 가는 도중에 특정 서버에서 전송이 실패하는 경우도 있을 것이다. 이 때 클라이언트는 어디서 문제가 터졌는지를 알 수가 없는데 이를 파악할 수 있는 것이 Max-Forwards 헤더 필드이다.
그 방법에 대해서는 결국 이해를 못해서 적지 않고 넘어간다. 후에 숙성되어서 다시 돌아오겠다.
11. Proxy-Authorization
클라이언트가 프록시 서버에 접근할 때 프록시 서버에게 클라이언트의 인증 정보를 전달할 때 쓰이는 헤더 필드로, 프록시 서버가 요청을 받기 전에 클라이언트가 인증되어야 하는 경우에 활용된다.
12. Referer
현재 요청된 리소스를 어떤 URI을 통해서 접근하게되었는지 알 수 있는 헤더로, 리퀘스트가 발생한 본래 리소스의 URI를 전달한다.
이 태그로 사용자의 접속 경로를 파악하려 통계로 활용할 수 있지만 URI의 쿼리에 개인정보가 담겨있을 수도 있고 개인의 접근 위치를 알 수 있기에 보안상 주의를 해야할 것 같다.
13. TE
클라이언트가 리스폰스로 받을 수 있는 전송 인코딩 형식을 나열한 것이다. Accept-Encoding 헤더 필드와 비슷하지만 Accept-Encoding는 컨텐츠에 대한 인코딩 방식이고, TE는 전송 인코딩을 이야기하는 것이다.
TE 헤더 필드에는 인코딩 형식과 trailers라는 값을 넣을 수 있는데, trailers는 클라이언트가 청크 전송 코딩의 trailers 필드도 받길 원한다고 알려주는 것이다.
14. User-Agent
요청을 보내는 클라이언트의 식별 정보를 담고 있는 항목이다. 브라우저 종류와 버젼, 운영 체제, 웹 엔진 등을 알려준다.
참고 문서
'CS' 카테고리의 다른 글
HTTP 학습 (3-4) - 엔티티 헤더 필드 (2) | 2023.12.06 |
---|---|
HTTP 학습 (3-3) - 응답 헤더 필드 (0) | 2023.11.28 |
HTTP 학습 (3-1) - 일반 헤더 필드 (0) | 2023.11.01 |
HTTP 학습 (3) - HTTP 메시지 (0) | 2023.10.27 |
HTTP 학습 (2) - 동작 과정과 특징 (0) | 2023.10.22 |