HTTP
HTTP/1.1, HTTP/2 그리고 HTTP/3
그림 이름 바꾸고 다시 넣을것
P-message
= start-line
*( header-field CRLF )
CRLF
[ message-body ]
https://tools.ietf.org/html/rfc7230#section-3
공식 스펙
헤더부분에 임의의 헤더 추가가 가능하다(노란색부분)
helloworld: hihi
=> 로그인 등에도 여기에 유저정보라던지 인터셉터에서 넣어서 전달하거나 이런거 가능
HTTP 메소드의 속성
- 안전(Safe Methods) : 호출해도 리소스를 변경하지 않는다.
- 멱등(Idempotent Methods) : f(f(x)) = f(x)
- 활용 : 자동복구 메커니즘, 서버가 타임아웃 등으로 정상 응답을 못주었을 때, 클라이언트가 같은 요청을 다시 해도 되는가 같은 판단 근거가 된다.
- 캐시가능(Cacheable Methods) : 응답결과 리소스를 캐시해서 사용해도 되는가?
파일업로드
- Content-Type: multipart/form-data
```
POST /save HTTP/1.1
Host: localhost:8080
Content-Type: multipart/form-data; boundary=——-XXX
——-XXX
Content-Disposition: form-data; name=”username”
——-XXX
Content-Disposition: form-data; name=”file1”; filename=”intro.png”
Content-Type: image/png
1092342abddd21342348989234…
——-XXX—
- 끝에는 —이 추가되어야 한다.
HTTP2 3 점유율 그림
### 헤더
header-field = field-name ":" OWS field-value OWS (OWS:띄어쓰기 허용)
### 옛날 RFC2616(1999년 나온거고 2014년 7230~7235로 대체)

General 헤더: 메시지 전체에 적용되는 정보, 예) Connection: close
Request 헤더: 요청 정보, 예) User-Agent: Mozilla/5.0 (Macintosh; ..)
Response 헤더: 응답 정보, 예) Server: Apache
Entity 헤더: 엔티티 바디 정보, 예) Content-Type: text/html, Content-Length: 3423
### RFC723X
- Entity => Representation
- Representation = representation Metadata + representation Data
- REST의 영향 아닐까
#### Representation
Content-Type: 표현 데이터의 형식 Content-Encoding: 표현 데이터의 압축 방식 Content-Language: 표현 데이터의 자연 언어 Content-Length: 표현 데이터의 길이
### Content Negotiation
클라이언트가 선호하는 표현 요청
Accept: 클라이언트가 선호하는 미디어 타입 전달 Accept-Charset: 클라이언트가 선호하는 문자 인코딩 Accept-Encoding: 클라이언트가 선호하는 압축 인코딩 Accept-Language: 클라이언트가 선호하는 자연 언어
협상 헤더는 요청시에만 사용
#### Quality Values(협상시 가중치, 생략하면 1이다, 구체적인것이 우선한다)
GET /event
Accept: text/, text/plain, text/plain;format=flowed, */ => 가장 구체적인 것이 우선한다
Accept-Language: ko-KR, ko;q=0.9, en-US;q=0.8
```
Content-Encoding(전송방법)
일반 => 헤더에 아무것도 없을때 => 그냥전송
Content-Encoding: gzip => 압축전송
범위전송
일반정보
From: 유저 에이전트의 이메일 정보
Referer: 이전 웹 페이지 주소
User-Agent: 유저 에이전트 애플리케이션 정보(어떤 종류의 브라우저에서 장애가 발생하는지 파악가능)
Server: 요청을 처리하는 오리진 서버의 소프트웨어 정보 Date: 메시지가 생성된 날짜
특별한 정보
Host: 요청한 호스트 정보(도메인) - 필수
Location: 페이지 리다이렉션(201의 경우에는 생성된 uri)
Allow: 허용 가능한 HTTP 메서드
Retry-After: 유저 에이전트가 다음 요청을 하기까지 기다려야 하는 시간
인증
Authorization: 클라이언트 인증 정보를 서버에 전달 WWW-Authenticate: 리소스 접근시 필요한 인증 방법
Response
상태코드
1xx (Informational): 요청이 수신되어 처리중
2xx (Successful): 요청 정상 처리
3xx (Redirection): 요청을 완료하려면 추가 행동이 필요
4xx (Client Error): 클라이언트 오류, 잘못된 문법등으로 서버가 요청을 수행할 수 없음 5xx (Server Error): 서버 오류, 서버가 정상 요청을 처리하지 못함
만약 모르는 상태 코드가 나타나면?
• • • •
• • •
클라이언트가 인식할 수 없는 상태코드를 서버가 반환하면? 클라이언트는 상위 상태코드로 해석해서 처리
미래에 새로운 상태 코드가 추가되어도 클라이언트를 변경하지 않아도 됨 예)
299 ??? -> 2xx (Successful) 451 ??? -> 4xx (Client Error) 599 ??? -> 5xx (Server Er
1xx : 거의 사용하지 않음
2xx
201 Created
- 202 Accepted : 요청이 접속되었으나 처리가 완료되지 않았음
- 배치 처리 같은 곳에서 사용 (예) 요청 접수 후 1시간 뒤에 배치 프로세스가 요청을 처리함
- 204 No Content
- 예를 들어 웹 문서 편집기의 세이브 버튼. 결과 내용없이도 성공을 인식할 수 있다.
3xx Redirection
웹 브라우저는 300대 응답의 결과에 로케이션 헤더가 있으면 로케이션 위치로 자동 이동한다
- 영구 리다이렉션
- 301 Moved Permanently : 리다이렉트시 요청 메서드가 겟으로 변하고 본문이 제거될’수도’ 있음
- 308 Permanent Redirect : 301과 기능은 같지만 메소드와 본문이 유지된다.
- 일시 리다이렉션 : 리소스의 유알아이가 일시적으로 변경 => 검색엔진 등에서도 저장하지 않는다.
- 302 Found : 301처럼 GET으로변하고 본문제거가능
- 307 Temporary Redirect : 308처럼 메소드와 본문 유지
-
303 See Other 302와 같은데 GET으로변함
- PRG: Post/Redirect/Get
- 포스트로 주문 후에 웹 브라우저를 새로고침하면? 새로고침은 다시 요청-=>중복주문 가능
- PRG를 이용한 일시적인 리다이렉션
- POST로주문 후에 주문 결과 화면을 GET메소드로 리다이렉트한다.
- 새로고침해도 GET으로조회될뿐이다.
리다이렉트는 307, 303을 권장하지만 많은 라이브러리들이 302를 기본값으로 사용한다
그래서 GET으로바뀌는 경우를 주의해야한다.
300 Multiple Choices 안쓴다
304 Not Modified
- 캐시를 목적으로 사용한다.
- 클라이언트에게 리소스가 수정되지 않았음을 알려준다. 따라서 클라이언트는 로컬 피씨에 저장된 캐시를 재사용(리다이렉트) 한다
- 304는 응답에 메시지 바디를 포함하면 안된다.
- 400 Bad Request
- 클라이언트의 잘못된 요청(파라미터나 에이피아이 스펙에 안맞을때)
- 401 Unauthorized
- 응답에 WWW-Authenticate 헤더와 함께 인증방법을 설명해야 한다.
- 403 Forbidden
- 인증은 됐지만 인가가 되지 않은 경우
- 503 Service Unavailable
- 서비스이용불가
- Retry-After 헤더 필드로 얼마뒤에 복귀되는지 보낼수도 있음
쿠키(요청 응답 외 카테고리로 뺒)
예) set-cookie: sessionId=abcde1234; expires=Sat, 26-Dec-2020 00:00:00 GMT; path=/; domain=.google.com; Secure
Set-Cookie: 서버에서 클라이언트로 쿠키 전달(응답)
Cookie: 클라이언트가 서버에서 받은 쿠키를 저장하고, HTTP 요청시 서버로 전달
특정 도메인 설정
domain=example.org
=> 도메인을 지정해서 쿠키 생성 => 서브 도메인에서도 쿠키 포함
=> 도메인을 생략하면 현재 문서 기준 도메인에서만 적용
path => 하위 경로 페이지에서만 쿠키 접근
Secure => https일때만 전송(HttpOnly나 SameSite(xsrf공격방지) 옵션도 있음)
캐시
데이터가 수정되지 않아야 캐시를 쓸텐데 어떻게 알지?
마지막 수정시간(캐시 저장시간)을 본내고 서버는 저 시간으로 확인해서 수정이 없었다면 스테이터스 코드에서 설명한거처럼 304에 빈 바디로 응답을 준다. 그러면 캐시를 사용하면 된다.
캐시를 사용한다면 헤더만 다운받으면 되므로 효율적
조건부 요청 헤더
검증 헤더로 조건에 따른 분기 If-Modified-Since: Last-Modified 사용 If-None-Match: ETag 사용
조건이 만족하면 200 OK
조건이 만족하지 않으면 304 Not Modified
etag는 entity tag => 고유한 이름을 붙여서 변경됐는지 확인 => 같으면 유지 다르면 다시 받기
받는 정보로 캐시 제어 로직을 서버에서 관리할 수 있다.
Cache-Control
ache-Control 캐시 지시어(directives)
•
캐시 유효 시간, 초 단위
•
•
데이터에 민감한 정보가 있으므로 저장하면 안됨
(메모리에서 사용하고 최대한 빨리 삭제)
Pragma
캐시 제어(하위 호환)
• •
Pragma: no-cache
HTTP 1.0 하위 호환함을 말함’
Expires
캐시 만료일을 정확한 날짜로 지정하는건데 지금은 잘 안쓴다함(Cache-Control: max-age를 쓰면 무시됨)
프록시 캐시
Cache-Control: public
응답이 public 캐시에 저장되어도 됨
Cache-Control: private
응답이 해당 사용자만을 위한 것임, private 캐시에 저장해야 함(기본값) Cache-Control: s-maxage
프록시 캐시에만 적용되는 max-age
Age: 60 (HTTP 헤더)
오리진 서버에서 응답 후 프록시 캐시 내에 머문 시간(초)
캐시 무효화
Cache-Control: no-cache
데이터는 캐시해도 되지만, 항상 원 서버에 검증하고 사용(이름에 주의!) Cache-Control: no-store
데이터에 민감한 정보가 있으므로 저장하면 안됨
(메모리에서 사용하고 최대한 빨리 삭제)
Cache-Control: must-revalidate
캐시 만료후 최초 조회시 원 서버에 검증해야함
원 서버 접근 실패시 반드시 오류가 발생해야함 - 504(Gateway Timeout) must-revalidate는 캐시 유효 시간이라면 캐시를 사용함
Pragma: no-cache
HTTP 1.0 하위 호환
전송할 리소스가 증가했다
(옛날 야후 요즘 야후, 이미지나 동영상)
http/1.0에서는 매 요청마다 커넥션을 열었다 닫았다
1.1에서는 persistent connection 개념이 생겼다
(무선통신 스펙의 keep alive같은 개념)
그리고 http pipelining이라는 개념으로 요청들을 큐에 버퍼링했다가
한번 커넥션열때 같이 처리하는 개념도 있다
위 두개는 그림 첨부하자
근데 파이프라인에서 처리하다가 특정 요청에 문제가 발생하면 뒤 요청들이 줄줄이 처리되지 못하고 블로킹되는 병목 문제가 있다.
이를 막기위해 분산된 도메인으로 요청과 페이지를 나누는 방식등을 쓰기도 하는데,
어찌되었건 아직 문제가
도메인마다 커넥션을 맺고 끊음
상당한 시간과 대역폭을 소모
연결할 수 있는 커넥션 수의 제한
2.0 => 근본적인 해결을 위해 멀티플렉싱(latency 줄이기), 헤더압축(오버헤드 최소화), 서버푸시 기능 지원
멀티플렉싱
=> 프레임(2.0에서의 통신최소단위, 최소 하나의 프레임헤더, 바이너리로 인코딩)
프레임들로 메시지 구성
메시지는 요청 응답의 단위
=> 여기까지는 1.1고 ㅏ크게 다른건 없지만
스트림(양방향 통신을 통해 전달되는 한개 이상의 메시지)이라는 개념이 생겨서
(유튜브 그림들 찾아서 다 첨부하자)
헤더압축은 hpack방식
서버푸시는
기존에 방식이 html 요청, tag파싱, 리소스 재요청(css, js, png등), 완성 이런단계였는데,
그림첨부
한방에 요청으로 가능해짐
이렇게함에도 2.0은 tcp의 한계가 아직 있어서
3.0에서는 udp채용
https://www.youtube.com/watch?v=xcrjamphIp4&list=WL&index=5