내가 공부한것을 올리며, 중요한 단원은 저 자신도 곱씹어 볼겸 상세히 기록하고 얕은부분들은 가겹게 포스팅 하겠습니다.
1. HTTP 헤더 개요
HTTP 헤더의 header-field를 예전에 설명한적이 있다. 다시한번 확인하고 시작하자.
● header-field => field-name":" OWS field-value OWS (OWS:띄어쓰기 허용)
- HTTP 전송에 필요한 모든 부가정보가 헤더에 포함되어있다.
- 예를 들어 메시지 바디의 내용, 바디의 크기, 압축, 인증, 요청 클라이언트 등등...
- 또한 표준 헤더가 너무 많다는 단점이 있다.
우선 과거의 분류 기준을 살펴보자. RFC2616은 1999년도 만들어진 과거의 방식이다.
헤더의 분류는 다음과 같이 할수있다.
- General 헤더: 메시지 전체에 적용되는 정보, 예) Connection: close
- Request 헤더: 요청 정보, 예) User-Agent: Mozilla/5.0 (Macintosh; ..)
- Response 헤더: 응답 정보, 예) Server: Apache
- Entity 헤더: 엔티티 바디 정보, 예) Content-Type: text/html, Content-Length: 3423
메시지 본문(message body)는 엔티티 본문(entity body)를 전달하는데 사용된다.
전달되는 엔티티 본문은 요청이나 응답에서 전달할 실질적인 데이터 부분이다.
엔티티 헤더는 엔티티 본문의 데이터를 해석할 수 있는 정보를 제공해 준다. 예를 들면 데이터 유형, 데이터 길이, 압축 정보 등등
하지만! 2014년 RFC2616이 폐기되고, RFC7230~7235가 등장하였다!
새로 등장한 RFC723x 는 기존의 엔티티(Entity)를 표현(Representation)이라 부르기로 했다.
=> Representation = representation Metadata + representation Data
● RFC7230
- 메시지 본문을 통해 표현데이터를 전달한다.
- 메시지 본문을 payload라고도 부른다.
- 표현은 요청이나 응답에서 전달할 실제 데이터이다.
- 표현 헤더는 표현 데이터를 해석할 수 있는 정보(표현 메타데이터)를 제공한다.
표현 헤더안에 표현 메타데이터가 들어가 있으며 데이터 유형, 데이터 길이, 압축 정보등이 들어있다.
2. 표현 (Representation)
회원 정보를 서버에 HTML라는 데이터 형태의 표현으로 전달할지? Json이라는 데이터 형태의 표현으로 전달할지?
즉! "리소스를 HTML로 표현한다, Json으로 표현한다, XML로 표현한다" 라고 이해하면 된다.
- Content-Type: 표현 데이터의 형식
미디어 타입이나, 문자 인코딩에 대한 정보를 갖고있다.
예를 들어 text/html; charset=utf-8 이나, application/json, image/png 와 같은 정보를 담고있다.
- Content-Encoding: 표현 데이터의 압축 방식
표현 데이터를 압축하기 위해 사용한다. 데이터를 전달하는 쪽에서 압축을 한 후 전달할때 인코딩 정보를 헤더에 추가하는 것 이다.
데이터를 받는 쪽에서는 이 인코딩 정보를 읽어 알맞게 압축을 해제하게 된다.
예를 들어 gzip이 있으며, 압축을 하지 않은경우 identity라고 적는다.
- Content-Language: 표현 데이터의 자연 언어
표현 데이터의 자연언어를 표현한다. 한국어라면 ko, 영어라면 en을 사용하게 된다.
- Content-Length: 표현 데이터의 길이
바이트 단위의 정보를 제공하며, Transfer-Encoding(전송 코딩)을 사용하면 Content-Length를 사용하면 안된다!
3. 협상 (Content Negotitation)
협상이란 클라이언트가 선호하는 표현을 서버에게 달라고 요청하는 것 이다.
- Accept: 클라이언트가 선호하는 미디어 타입 전달
- Accept-Charset: 클라이언트가 선호하는 문자 인코딩
- Accept-Encoding: 클라이언트가 선호하는 압축 인코딩
- Accept-Language: 클라이언트가 선호하는 자연 언어
협상 헤더는 요청시에만 사용할수 있다.
우선 Accept-Languagge 적용 전을 생각해 보자. 다음 그림을 보자
클라이언트가 GET/event 를 보내면 이를 받은 서버는 서버의 default값인 영어로 결과값을 보여준다.
이럴때 Client가 요청을 할때 Accept-Languagge 로 ko 를 적어서 보내면 서버가 이를 인지하고 한글로 보여주는 것 이다!
위의 그림을 보면 Accept-Languagge: ko 로 요청하고, 서버가 이를 인지하여 "안녕하세요" 라고 한글로 보여주고 있다.
그렇다면 협상에서 우선순위는 어떻게 적용될까?
● 협상과 우선순위1
Quality Values(q)값이 높을수록 우선순위가 높다. 0~1의 숫자를 사용하며, 생략하면 자동으로 1로 인식한다.
우선순위는 다음과 같다. 숫자가 큰 1이 가장 높다.
1. ko-KR;q=1 (q생략)
2. ko;q=0.9
3. en-US;q=0.8
4. en:q=0.7
이번에는 좀 복잡한 상황을 생각해보자.
우리의 클라이언트는 한국어를 사용하는 유저이다. 하지만 방문하고 있는 싸이트에서 한글을 지원하지 않고있다.
대신 서버의 기본값이 (de)독일어로 지정되어있으며, 또한 영어도 2번째 언어로 지원하고있는 서버이다.
이때 클라이언트는 뭐라고 보내야 독일어보단 그나마 읽히는 영어로 응답받을 수 있을까?
위에서 en-US가 0.8로 선언되어있다. 이는 독일어 보다는 영어를 더 선호한다는 의미로 받아들이며, 서버는 영어를 보내주게 된다.
● 협상과 우선순위2
구체적일수록 우선순위가 높다!
위와 같이 보냈다면 우선순위는 다음과 같다.
1. text/plain;format=flowed (가장 구체적이다)
2. text/plain
3. text/*
4. */* (가장 포괄적이다)
● 협상과 우선순위3
구체적인 것을 기준으로 미디어 타입을 맞춘다.
4. 전송 방식
● 단순 전송
이 방식은 Content-Length를 알고있을때 사용한다. 한번에 요청하고, 한번에 다 받는다.
● 압축 전송
Content-Encoding 정보를 추가로 적어줘야 하며, 보통 압축하게 되면 용량이 크게 감소한다.
위의 그림을 보면 gzip으로 압축하여 보내는것을 알 수 있다.
● 분할 전송
용량이 큰 데이터를 한번에 전송하면 시간이 오래걸린다.
대신 여러개로 분할하여 나누어 보내면, 먼저 도착한 덩어리들은 먼저 유저에게 보여줄수가 있다.
(이때는 Cotent-Length를 적으면 안된다. 예상할수가 없다) 각 Chunk안에 길이 정보가 담겨있다.
● 범위 전송
데이터를 보내던 중간에 끊기면 처음부터 다시 새로 보내기에는 아깝다. 이럴때 끊어진 부분 주변만 범위로 지정해서 요청할 수 있다.
5. 일반 정보
● From: 유저 에이전트의 이메일 정보
요청에서 사용된다.
● Referer: 이전 웹 페이지 주소를 말한다.
A -> B로 이동하는 경우 B를 요청할때 Referer: A를 포함해서 요청하게 됩니다. 이를 통해 사용자의 유입경로 분석이 가능합니다.
(참고로 Referer 철자 맞습니다. 처음 HTTP 규약이 생길때 부터 있었던 referrer의 오타입니다...)
요청에서 사용된다.
● User-Agent: 유저 에이전트 애플리케이션 정보
예를 들어 Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/ 537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36 와 같이 클라이언트의 애플리케이션 정보를 알수있다.
어떤 종류의 브라우저에서 장애가 발생하는지 파악이 가능하다!
요청에서 사용된다.
● Server: 요청을 처리하는 오리진 서버의 소프트웨어 정보
요청을 보낼때 거치는 중간의 서버와 프록시 서버가 아닌! 최종적으로 처리하는 진정한 서버를 알수있다.
응답에서 사용된다.
● Date: 메시지가 생성된 날짜
메시지가 발생한 날짜와 시간을 보여준다.
응답에서 사용된다.
6. 특별한 정보
● Host: 요청한 호스트 정보(도메인)
요청에서 필수로 사용해야한다. 하나의 서버안에 여러 도메인이 있을때 사용자의 요청을 어떤 도메인이 처리해야 할까?
이럴때 Host를 사용하여 해결한다.
클라이언트와 서버는 IP를 갖고 데이터를 보낸다. 따라서 클라이언트가 200.200.200.2 라는 IP로 데이터를 보낼때 Host를 필수로 지정해야된다!
● Location: 페이지 리다이렉션
- 웹 브라우저는 3xx 응답의 결과에 Location 헤더가 있으면, Location 위치로 자동 이동 (리다이렉트)하게 된다.
- 201 (Created): Location 값은 요청에 의해 생성된 리소스 URI 를 클라이언트에게 알려준다.
- 3xx (Redirection): Location 값은 요청을 자동으로 리디렉션하기 위한 대상 리소스를 가리킨다.
● Allow: 허용 가능한 HTTP 메서드
클라이언트가 POST로 요청했는데, 서버가 GET, HEAD, PUT만을 지원한다면 이를 클라이언트에게 알려줘야 한다.
이럴때 Allow: GET, HEAD, PUT 로 적어보내 알려준다.
● Retry-After: 유저 에이전트가 다음 요청을 하기까지 기다려야 하는 시간
- 503 (Service Unavailable): 서비스가 언제까지 불능인지 알려줄 수 있음
7. 쿠키
● Set-Cookie: 서버에서 클라이언트로 쿠키 전달(응답)
● Cookie: 클라이언트가 서버에서 받은 쿠키를 저장하고, HTTP 요청시 서버로 전달
HTTP 는 stateless한 프로토콜이다. 클라이언트가 요청하고 서버가 이를 받아 처리하여 응답하면 연결이 끊어진다.
클라이언트가 다시 요청하면 서버는 이전 상태를 기억하지 않기때문에 이전에 왔었던 클라이언트인지 알수가 없다.
=> 이때 쿠키를 사용하면 된다!
1) 처음 클라이언트가 요청했을때 서버가 응답에 쿠키를 포함시켜 전달한다.
2) 이를 받은 클라이언트는 쿠키를 저장해 둔다.
3) 이후 다시 서버에 접근하면서 요청메시지에 쿠키를 포함시켜 보내면
4) 서버가 이를 인지하고 누구인지 알수있다.
모든 요청에 쿠키정보가 자동 포함된다.
다음은 서버에서 쿠키를 지정하는 예시이다.
예) set-cookie: sessionId=abcde1234; expires=Sat, 26-Dec-2020 00:00:00 GMT; path=/; domain=.google.com; Secure
sessionId를 지정하고, 생명주기(expires)를 지정하며, domain, path, secure를 지정한다.
● Domain
예) domain=example.org
명시: 명시한 문서 기준 도메인 + 서브 도메인 포함
domain=example.org를 지정해서 쿠키 생성했다면, example.org는 물론이고 dev.example.org도 쿠키 접근이 가능해진다.
생략: 현재 문서 기준 도메인만 적용
example.org 에서 쿠키를 생성하고 domain 지정을 생략했다면 example.org 에서만 쿠키 접근 가능하다.
dev.example.org는 쿠키에 접근할수 없다.
● Path
예) path=/home
이 경로를 포함한 하위 경로 페이지만 쿠키 접근
일반적으로 path=/ 루트로 지정
● Secure
쿠키는 HTTP, HTTPS를 구분하지 않고 전송한다. 하지만 보안을 적용하면 https인 경우에만 전송할 수 있다.
이외에도 HttpOnly, SameSite 등 보안적 기술이 있다.
'BackEnd > WEB' 카테고리의 다른 글
[WEB] JWT (Json Web Token)이란? (0) | 2022.05.11 |
---|---|
[HTTP] HTTP 헤더 - 캐시와 조건부 요청 (0) | 2022.02.03 |
[HTTP] HTTP 상태 코드 (0) | 2022.02.01 |
[HTTP] HTTP 메서드 활용 (0) | 2022.01.31 |
[HTTP] HTTP 메서드 (0) | 2022.01.28 |
댓글