앱과 서버의 통신, 서버와 서버의 통신 등 모두 HTTP(HyperText Transfer Protocol)를 이용하여 데이터를 주고 받는다. 때문에 HTTP는 앱,웹 개발에 필수로 요하게 되는 기술이다.
이미지 출처 : 모든 개발자를 위한 HTTP 웹 기본지식 - 김영한님.
🔑 RFC 7230~7235: https://tools.ietf.org/html/rfc7230
- 지정한 IP 주소에 데이터 전달.
- 패킷(packet)이라는 통신 단위로 데이터 전달.
- 패킷 정보 : 출발지 IP, 목적지 IP, 데이터 ...
- 주소간 패킷을 전달. (노드들을 통해)
- 비 연결성 : 패킷을 수신할 대상이 없거나 서비스 불능 상태여도 패킷이 전송됨.
- 비 신뢰성 : 패킷의 소실, 패킷의 순서가 바뀌는 등의 문제.
- 프로그램 구분 : 같은 IP를 사용하는 서버에서 통신하는 애플리케이션이 둘 이상일 때의 구분.
- 해결 : TCP
- 전송 제어 프로토콜 (Transmission Control Protocol)
- 데이터 전달 보증
- 순서 보장
- 신뢰성 있는 프로토콜
- IP 패킷 : IP 주소
- TCP 세그먼트 :포트, 전송 제어, 순서, 검증 정보 등 ...
- 클라이언트 -> 서버로 SYN
- 서버 -> 클라이언트로 SYN + ACK
- 클라이언트 -> 서버 ACK + 데이터
- 클라이언트 서버 -> 데이터 전송
- 서버 -> 클라이언트 : 데이버 수신 응답.
- 패킷 1,2,3 을 순서대로 전송
- 서버에 1,3,2 순서로 도
- 패킷 2부터 재전송 요청
- 순서보장, 데이터 전달 보증이 되지 않는다.
- 단순하고 빠름. (handshake, 응답 등이 없음.)
- IP와 거의 같지만 + 포트정보 + 체크섬
- 애플리케이션에서 추가 작업 필요.
- 💡 HTTP3 에서 UDP를 사용하며 최근 대두되고 있다.
한 IP에서 둘 이상의 애플리케이션을 연결해야 한다면?
-
같은 IP 내에서 프로세스 구분.
-
비유 : 아파트(IP) 내의 호수(PORT)
-
할당 가능한 포트 번호 : 0~65535
-
잘 알려진 포트 : 0~1023 (사용하지 않는 것이 좋음)
- FTP : 20, 21
- Telnet : 23
- HTTP : 80
- HTTPS : 443
IP의 문제점 : 기억하기 어렵고 변경 가능성이 있다.
- 도메인 명을 IP 주소로 변환해준다.
ex) google.com - 200.200.200.2
*URI : Uniform Resource Identifier
- Uniform : 리소스를 식별하는 통일된 방식.
- Resource : 자원, URI로 식별할 수 있는 모든 것.
- Identifier : 다른 항목과 구분하는데 사용되는 정보.
- URL(Uniform Resource Locator) : 리소스의 위치
- URN(Uniform Resource Name) : 리소스의 이름
- URN 만으로 실제 리소스를 찾을 수 있는 방법이 보편화되지 않아 대부분 URL을 사용한다.
- Scheme
- 주로 프로토콜 사용(자원 접근 약속 규칙 http, https, ftp 등)
- 생략시 http로 동작.
- userinfo
- URL에 사용자 정보를 포함해서 인증, 거의 사용하지 않는다.
- Host
- 호스트명, 도메인명 또는 IP주소를 직접 입력
- PORT
- 접속 포트, 일반적으로 생략, 생략시 http는 80, http는 443
- Path
- 리소스 경로, 계층적 구조
- ex) /home/.../.../ file.png
- Query
- key=value 형태
- ?로 시작, &로 추가 가능
- ex) keyA=valueA&keyB=valueB
- query parameter, query string 등으로 불린다. 웹 서버에서 제공하는 파라미터, 문자열.
- fragment
- 다른곳으로 이동하는 html 내부 북마크 등에서 사용, 서버에 전송하는 정보가 아니다.
- 요청 :
https://www.google.com:443/search?q=heloo&hl=ko - DNS 조회, PORT 조회 : IP, PORT를 얻어온다.
- HTTP 요청 메시지 생성.
GET /search?q=hello&hl=ko HTTP/1.1
HOST: www.google.com
- Socket 라이브러리를 통해 전송 계층(TCP)으로 전달.
- TCP에서 IP,PORT 정보를 추가.
- 노드들을 통해 서버에 전달.
- 서버에서는 TCP/IP 패킷을 버리고, HTTP 메시지를 해석 및 처리.
- 서버에서 HTTP 응답 메시지 생성.
HTTP/1.1 200 OK
Content-Type: text/html;charset=URF-8
Content-Length: 3423
<html>
...
<html>
- (4~6)의 과정을 거치고 도착한 패킷에서 HTML을 렌더링해서 결과를 보여준다.
- HTML의 시작 : HyperText Transfer Protocol
- 현재 : 모든 것을 담아 전송
- HTML,Text, Image, 음성, 영상, 파일, JSON, XML 등..
-
HTTP/0.9(1991) : GET만 지원, 헤더가 존재하지 않는다.
-
HTTP/1.0(1996) : 다양한 메서드, 헤더 추가.
-
RFC2069(1997) -> RFC2616(1999) ->RFC7230~7235(2014)
-
HTTP/2(2015) : 성능 개선
-
HTTP/3(진행중) : TCP 대신 UDP를 사용, 성능의 개선.
- Request - Response 구조
- 클라이언트는 서버에 요청을 보내고 응답을 대기, 서버가 요청에 대한 결과를 생성하고 응답.
- 비즈니스 로직과 데이터는 서버에서 처리, 클라이언트는 UI에 집중.
각자의 역할에 집중, 독립적으로 작동할 수 있다.
-
[Stateful] : 서버가 상태를 저장하고 있다고 생각하고 클라이언트가 진행상황 이후의 요청만을 보낸다. 서버가 바뀌면 클라이언트의 요청을 이해하지 못하게 된다.
-
[Stateless] :서버가 클라이언트의 상태를 보존하지 않는다, 클라이언트가 그때 그때 필요한 요청을 모두 넘겨줌.
-
👍 장점
- 응답 서버를 쉽게 바꿀 수 있다.
- 요청이 증가해도 서버의 추가가 쉽다.(스케일 아웃- 수평 확장)
-
👎 단점
- 클라이언트가 요청을 추가 전송해야 한다.
-
🖍 실무 한계
- 모든 것을 무상태로 설계 할 수는 없다.
- ex) 상태를 서버에 유지해야 하는 로그, 일반적으로 브라우저 쿠키와 서버 세션등을 사용하여 상태를 유지한다.
- 상태 유지는 최소한만 사용한다.
-
🤔 Stateless 는 언제 유용할까?
- 같은 시간에 맞추어 발생하는 대용량 트래픽(선착순 이벤트 등 ..)
- 최대한 Stateless하게 설계해야 대응하기 용이하다.
서버와 클라이언트의 연결을 유지하지 않아, 최소한의 자원으로 서버를 유지할 수 있다. 단순하고 확장에 용이하다.
-
👎 한계 :
- TCP/IP 연결을 새로 맺어야 함(3 way handshake 시간이 추가로 필요하다.)
- 사이트를 요청하면 JS,CSS, 이미지 등 수 많은 자원이 함께 다운로드 된다.
-
👍 해결 :
- HTTP 지속연결(Persistent Connections) 사용.
HTTP/2,HTTP/3에서 더 많은 최적화가 이루어 졌다, 연결을 일정 시간 동안 지속한다.
- HTTP 지속연결(Persistent Connections) 사용.
Empty Line(CRLF)는 필수로 존재 (CR:Carriage return, LF:Line Feed)
(start-line) = request-line / status-line
-
method SP(공백) request-target SP HTTP-version CRLF -
ex)
GET /search?q=hello HTTP/1.1 -
method
GET, POST, PUT, DELETE ...
-
request-target
absolute-path[?query]
ex) /search?q=hello -
HTTP-version
HTTP/1.1, HTTP/2.0 ..
-
HTTP-version SP status-code SP reason-phrase CRLF -
HTTP/1.1 200 OK -
status-code
요청 성공, 실패 등의 상태 코드. 2xx, 4xx, 5xx ...
-
reason-phrase
사람이 이해할 수 있는 짧은 상태코드 설명.
OK, Server Error, Client Error ..
Host:www.google.com
Content-Type:text/html;charset=UTF-8
- field-name은 대소문자를 구분하지 않는다. value는 구분.
- HTTP 전송에 필요한 모든 부가 정보가 담긴다.
- 메시지 바디의 내용, 바디의 크기, 압축, 인증, 요청 클라이언트 정보, 서버 애플리케이션 정보, 캐시 관리 정보 ...
- 필요시 임의의 헤더 추가 가능 fieldName: value
- 실제 전송할 데이터
- 바이트로 표현할 수 있는 모든 데이터 전송 가능.
🖍️ 가장 중요한 것은 리소스 식별!
- 리소스 : 회원 등록에서 회원, 이미지 저장에서 이미지.
회원 목록 조회: /members
회원 조회: /members/{id}
회원 등록: /members/{id}
회원 수정: /members/{id}
회원 삭제: /members/{id}
- URI 계층 구조 활용, 상위를 컬렉션으로 보고 복수형 사용.
- 행위와 리소스를 분리.
- URI는 리소스 만을 식별 (주로 명사)
- 메소드에서 행위를 식별.
🖍 리소스의 조회.
GET /members/100 HTTP/1.1
...
- 서버에 전달하고 싶은 데이터는 쿼리 파라미터를 통해서 전달한다.
- 메시지 바디를 사용할 수 있지만, 지원하지 않는곳이 많아서 권장하지 않는다.
🖍 응답 데이터
HTTP/1.1 200 OK
...
{
조회된 리소스
}
🖍 요청 데이터 처리
POST /members HTTP/1.1
...
{
data ...
}
- 메시지 바디를 통해 서버로 요청 데이터를 전달한다
- 서버는 요청 데이터를 처리하고, 바디를 통해 들어온 데이터를 처리하는 모든 기능 수행한다.
- 주로 신규 리소스 등록, 프로세스 처리.
🖍 응답 데이터
HTTP/1.1 201 Created
...
Location: /members/100
{
생성된 리소스
}
- 201 Created 또는 200 OK
- 201일 경우 Location 헤더에는 생성된 리소스의 경로를 담아준다.
- 바디에는 생성된 리소스의 데이터.
🤔 요청의 처리?
- 대상 리소스 고유의 의미 체계에 따라 요청에 포함된 표현을 처리.
- ex) HTML 양식에 입력된 필드와 같은 데이터 블록의 처리 프로세스 (회원가입, 주문 등..)
- 메시지 게시 (게시판 글쓰기, 댓글 등)
- 서버가 아직 식별하지 않은 새 리소스 생성 (신규 주문 생성, 신규 회원 생)
- 기존 자원에 데이터 추가 (한 문서의 끝에 내용 추가하기)
- 새 리소스의 생성(등록)
서버가 아직 식별하지 않은 새 리소스 생성
- 요청 데이터 처리
- 데이터의 생성, 변경을 넘어 프로세스를 처리해야 하는 경우.
- POST의 결과로 리소스가 생성되지 않을수도 있다.
- ex) 주문시스템 : 결제 완료 -> 배달 시작 -> 배달 완료 에서는 단순한 값 변경을 넘어 프로세스의 상태를 변화시킨다.
- POST /orders/{orderId}/start-delivery (컨트롤 URL, 리소스 명시만으로 할 수 없을 때.)
- 다른 메서드로 처리하기 애매한 경우
ex) JSON으로 조회 데이터를 넘겨야 할 때
- GET을 사용하여 바디에 데이터를 넣게 되면 지원하지 않는 서버가 있을 수 있기 때문에 POST 사용.
🖍 리소스를 완전히 대체, 해당 리소스가 없으면 생성.
- 덮어쓰기. 해당하는 필드만 덮어쓰는것이 아닌 완전한 대체이다.
- 새로 보낸 데이터에 age만 존재하고, 기존 데이터가 age, name이 존재한다면 요청이 실행된 이후에 해당 리소스에는 대체된 age만 존재한다.
- PUT은 데이터의 수정이 아니다. 수정은 PATCH 사용.
PUT /members/100 HTTP/1.1
...
{
data ...
}
- POST와 달리 클라이언트가 구체적인 리소스 위치를 알고 URI를 지정한다.
🖍 리소스 부분 변경.
- 해당 리소스의 일치하는 부분만 변경.
- 대부분 지원하지만 지원하지 않는 서버가 있다면 POST로 대체하여 사용.
PATCH /members/100 HTTP/1.1
...
{
data ...
}
🖍 리소스 제거.
DELETE /members/100 HTTP/1.1
...
{
data ...
}
- HEAD : GET과 동일하지만 메시지 부분을 제외하고 상태 줄과, 헤더만 반환.
- OPTIONS : 대상 리소스에 대한 통신 가능 옵션(메서드)을 설명(주로 CORS에서 사용).
- CONNECT : 대상 자원으로 식별되느 서버에 대한 터널을 설정.
- TRACE : 대상 리소스에 대한 경로를 따라 메시지 루프백 테스트를 수행.
- GET의 경우 Body를 넣을 수 있으나, 지원하지 않는 서버가 존재하기 때문에 넣지 않는것이 좋다.
호출해도 리소스를 변경하지 않는다.
몇 번을 호출하든 결과가 같다.
- 외부 요인으로 중간에 리소스가 변경되는 것 까지는 고려하지 않는다.
- GET : 몇 번을 조회하든 같은 결과가 조회된다,
- PUT : 결과를 대체하므로, 같은 요청을 여러번 해도 최종 결과는 같다.
- DELETE : 결과를 삭제하므로, 같은 요청을 여러번 해도 결과는 리소스 삭제로 똑같다.
활용 : 자동 복구 메커니즘 - 서버가 TIMEOUT 등으로 정상 응답을 못 주었을 때, 같은 요청을 다시 해도 되는가?
응답 결과 리소스를 캐시해서 사용해도 되는가?
- GET, HEAD, POST, PATCH 캐시가능.
- 실제로는 GET, HEAD 정도만 사용한다.
🤔 POST, PATCH는 본문 내용까지 Cache Key로 고려해야 하기 때문에 구현이 어려움.
- 쿼리 파라미터를 통한 데이터 전송
- GET
- 정렬 필터 사용(검색어)
- 메시지 바디를 통한 데이터 전송
- POST, PUT, PATCH
- 리소스 등록, 리소스 변경.
- 이미지, 정적 텍스트 문서
- 쿼리 파라미터 없이 단순히 리소스 경로로 조회 가능.
- 주로 검색, 게시판 목록 정렬 필터, 정렬 조건 등..
- 쿼리 파라미터를 사용하여 추가적인 정보 전달.
- 회원 가입, 상품 주문, 데이터 변경 등..
- GET, POST 만 지원.
🖍 쿼리 파라미터와 유사한 Key=Value 쌍으로 데이터를 생성하여 바디에 추가.
🖍 Content-Type은 application/x-www-form-urlencoded 가 된다. (url 인코딩 처리)
🤔 method를 GET으로 사용하면 URL 경로에 쿼리 파라미터로 들어가게 되지만 GET을 리소스의 변경에는 사용해서는 안된다.
🖍 파일 업로드와 같은 바이너리 데이터 전송시 사용.
🖍 웹 브라우저가 자동으로 boundary를 생성하고 이를 기준으로 잘라서 읽는다.
🖍 여러 파일과 폼의 내용을 함께 전송 가능 (multipart)
- 회원가입, 상품 주문, 데이터 변경 등..
- 서버 to 서버 : 백엔드 시스템 통신
- 앱 클라이언트 : 안드로이드, 아이폰
- 웹 클라이언트 : 자바 스크립트를 통한 통신(AJAX) ex) VueJS, React
- POST, PUT, PATCH : 메시지 바디를 통해 데이터 전송
- GET : 조회, 쿼리 파라미터로 데이터 전달
- Content-Type : application/json을 주로 사용(사실상 표준)
TEXT, XML, JSON 등 ..
- 회원 목록 조회 :
/membersGET, 정렬 필터, 조건은 쿼리 파라미터에
- 회원 단건 조회 :
/members/{memberId}GET
- 회원 등록 :
/membersPOST
- 회원 수정 :
/members/{memberId}- PATCH(best), PUT, POST
- PUT: 모든 데이터를 보내기 때문에 게시글의 수정 등에서는 사용될 수 있다.
- 회원 삭제 :
/members/{memberId}DELETE
- 클라이언트는 등록될 리소스의 URI를 모른다.
- 서버가 새로 등록된 리소스 URI를 생성해준다.
- 컬렉션(Collection)
- 서버가 관리하 리소스 디렉토리
- 서버가 리소스의 URI를 생성하고 관리.
- 여기서는 /members
- 파일 목록 조회
/filesGET
- 파일 단건 조회
/files/{filename}GET
- 파일 등록
/files/{filename}- POST와의 차이, URI를 클라이언트가 리소스의 위치를 지정한다.
PUT
- 파일 업로드의 경우에는 기존 파일을 덮어 씌우기 때문에 PUT을 사용해도 된다.
- 파일 삭제
/files/{filename}DELETE
- 파일 대량 등록
/filesPOST
- 클라이언트가 리소스 URI를 알고 있어야 한다 (요청에 보내줘야 한다.)
- 클라이언트가 직접 리소스의 URI를 지정한다. (클라이언트가 리소스의 URI를 관리.)
- 스토어(Store)
- 클라이언트가 관리하는 리소스 저장소
- 클라이언트가 리소스의 URI를 알고 관리.
- 여기서는 /files
- GET, POST만 지원한다는 제약이 존재한다.
- AJAX 같은 기술을 사용해서 해결 가능.
- 회원 목록
/members - 회원 등록 폼
/members/new - 회원 조회
/members/{memberId} - 회원 수정 폼
/members/{memberId}/edit
- 회원 등록
/members/new or /members - 회원 수정
/members/{memberId}/edit or /members/{memberId} - 회원 삭제
/members/{memberId}/deleteControl URI
- GET, POST만을 지원, 제약이 있음.
- 컨트롤 URI
- GET, POST만 사용할 수 있는 제약을 해결하기 위해 동사로 된 리소스 경로 사용.
위의 예시에서 edit, delete에 해당.
- HTTP 메서드로 해결하기 애매한 경우에 사용.
- 최대한 지양.
- GET, POST만 사용할 수 있는 제약을 해결하기 위해 동사로 된 리소스 경로 사용.
- 단일 개념(파일하나, 객체 인스턴스 하나, DB row)
- ex) /members/100, /files/sample.jpg
- 서버가 관리하는 리소스 디렉터리
- 서버가 리소스의 URI를 생성하고 관리.
- 클라이언트가 관리하는 자원 저장소
- 클라이언트가 리소스의 URI를 알고 관리
- 문서, 컬렉션, 스토어로 해결하기 어려운 추가 프로세스 실행.
- 동사를 직접 사용.
클라이언트가 보낸 요청의 처리 상태를 응답에서 알려주는 기능.
요청 성공
- 요청 성공, 새로운 리소스가 생성됨.
- Location 헤더 필드로 생성된 리소스를 식별
- ex) Location:
/members/100
- 요청이 접수됨, 아직 처리가 완료되지는 않음.
- 배치 처리 같은 곳에서 사용. ex) 접수 후 일정시간 후 처리가 완료됨.
- 요청을 성공적으로 수행, 응답 페이로드 본문에 보낼 데이터가 없음.
- ex) save의 결과로 아무 내용이 없어도 된다, 같은 화면을 유지해야 한다.
요청을 완료하려면 추가 행동이 필요하다. 3xx 응답의 결과에 Location 헤더가 있으면, Location 위치로 자동 리다이렉트 한다.
특정 리소스의 URI가 영구적으로 이동. (301, 308) 원래의 URL을 사용하지 않고, 검색 엔진 등에서도 변경을 인지한다.
ex) /event --> /new-event
-
리다이렉트 요청시 요청 메서드가 GET으로 변하고, 본문이 제거될 수 있다.(수신 데이터 형식이 다를 수 있기 때문에 안전을 위해 GET으로 변경함.)
-
301과 기능은 같으나 요청 메서드와 본문을 유지한다.
주문 완료 후 주문 내역 화면으로 이동. 리소스의 URI가 일시적으로 변경되는 것이므로, 검색 엔진 등에서 URL을 변경하면 안됨.
리다이렉트 요청 메서드가 GET으로 변하고, 본문이 제거될 수 있음.(MAY)
302와 기능은 같지만, 요청 메서드와 본문 유지(요청 메서드를 변경하면 안된다. MUST NOT)
302와 기능은 같지만 리다이렉트시 요청 메서드를 GET 으로 변경.(MUST)
- POST로 주문후에 웹 브라우저를 새로고침 하면?
- 새로고침은 재요청.
- 중복 주문이 될 수 있다.
- POST로 주문 후에 결과 화면을 GET 메서드로 리다이렉트.
- 새로고침해도 결과 화면을 GET으로 조회.
- 중복 주문 대신에 결과 화면만 GET으로 다시 요청.
- 주문에 대한 응답을 302 Found나 308 See Other로 돌려 준다.(Method가 GET으로 변경된다.)
- PRG 이후 리다이렉트를 시도해도 URL이 이미 GET으로 리다이렉트 된다. 새로고침 해도 GET으로 화면만 조회.
-
캐시를 목적으로 사용.
-
클라이언트에서 서버에게 캐시 정보를 넘겨주며 사용 가능 여부확인.
-
서버에서는 다시 클라이언트에게 리소스가 수정되지 않았음을 알려준다.
-
클라이언트는 로컬PC에 저장된 캐시를 재사용(캐시로 리다이렉트)
-
응답에 메시지 바디를 포함하면 안된다(로컬 캐시를 사용하므로)
-
조건부 GET, HEAD 요청시 사용.
-
300 Multiple Choices 잘 사용하지 않음
클라이언트의 요청에 잘못된 문법등으로 서버가 요청을 수행할 수 없음. 오류의 원인이 클라이언트. 클라이언트가 잘못된 요청을 한 것이기 때문에 같은 요청을 반복해도 똑같이 실패한다. 요청을 수정하여 보내야 한다.
- 클라이언트가 잘못된 요청을 해서 서버가 요청을 처리할 수 없음.
- 요청 구문, 메시지 등
- ex) 요청 파라미터가 맞지 않을 때, API 스펙에 맞지 않을 때.
- 인증 되지 않음.
- 401 오류 발생시 응답에 WWW-Authenticate 헤더와 인증 방법을 설명
- 이름이 Anauthorized 이지만 인가가 아닌 인증이 안됐다는 응답이다.
💡 참고
- 인증(Authentication) : 본인이 누구인지 확인 , 로그인
- 인가(Authorization) : 권한 부여 (특정 리소스에 접근할 수 있는 권한 등.)
- 서버가 요청을 이해했지만 서버가 접근을 거부함.
- 주로 인증 자격 증명은 있지만, 접근 권한이 불충분한 경우
- ex) 일반 사용자가 어드민 등급의 리소스에 접근할 때.
- 요청 리소스가 서버에 없음
- 또는 클라이언트가 권한이 부족한 리소스에 접근할 때 해당 리소스를 숨기고 싶을 때
서버 문제로 오류 발생 서버에 문제가 있기 때문에 같은 요청을 재시도 했을 때 다시 성공할 수 있다.
- 서버 내부 문제로 오류 발생
- 애매하면 500 오류로 발생 시킨다.
- 서비스 이용 불가
- 서비스가 일시적인 과부하 또는 예정된 작업으로 잠시 요청 처리를 할 수 없음.
- Retry-After 헤더 필드로 얼마뒤 복구되는지 보낼 수 있다.
- 클라이언트가 인식할 수 없는 상태코드를 서버가 반환하면?
-> 클라이언트는 상위 상태코드로 해석해서 처리. - 미래에 새로운 상태 코드가 추가되어도 클라이언트를 변하지 않아도 된다.
- ex) 299 -> 2xx(Successful)로 해석, 451 -> 4xx(Client Error)로 해석 ..
-
엔티티(Entity) -> 표현(Representation)
-
Representation = representation Metadata + Representation Data
-
표현 : 요청이나 응답에서 전달할 실제 데이터
-
표현 헤더 : 표현 데이를 해석할 수 있는 정보 제공.
- 데이터 유형(html, json), 데이터 길이, 압축 정보 등 ..
표현 헤더는 전송, 응답 둘다에서 사용.
-
- 미디어 타입, 문자 인코딩
- text/html; charset=utf-8, application/json, image/png 등 ..
-
- 표현 데이터를 압축하기 위해 사용.
- 데이터를 전달하 곳에서 압축 후 인코딩 헤더 추가
- 데이터를 읽는 쪽에서 인코딩 헤더의 정보로 압축 헤제
- ex) gzip, deflate, identity ...
-
- 표현 데이터의 자연 언어를 표현.
- ex) ko, en, en-US ...
-
- 바이트 단위.
- Transfer-Encoding(전송 코딩)을 사용할 때는 사용하면 안된다.
협상 헤더는 요청시에만 사용한다.
- ###️ Accept-Language: 클라이언트가 선호하는 자연 언어
️
구체적인 것이 우선한다.
1. text/plain;format=flowed
2. text/plain
3. text/*
4. */*
구체적인 것을 기준으로 미디어 타입을 맞춘다.
-
Content-Length : 3300
-
Content-Encoding : gzip ..
-
- Transfer-Encoding: chunked
- \r\n 으로 끝을 알린다.
- Content-Length를 보내면 안된다. (예상이 안됨, 분할 청크에 길이가 있음.)
-
Range, Content-Range
-
- 일반적으로 잘 사용하지 않는다.
- 검색 엔진 같은 곳에서 주로 사용.
- 요청에서 사용한다.
-
- 해당 요청을 보내기 전에 있던 웹 페이지의 주소.
- A -> B로 이동하는 경우 B로 요청할떄 Referer: A를 포함해서 요청.
- Referer를 사용해서 유입 경로 분석 가능.
- 요청에서 사용한다.
- 참고: referer는 단어 referrer의 오타..
-
user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36- 클라이언트의 애플리케이션 정보(웹 브라우저 정보 등..)
- 통계 정보(어떤 브라우저로 많이 접속하는가. 등..)
- 어떤 종류의 브라우저에서 장애가 발생하는지 파악 가능.
- 요청에서 사용한다.
-
-
Server: Apache/2.2.22
-
server: nginx
-
응답에서 사용.
🤔 Origin Server? 실제로 표현 데이터를 만들어주는 종단의 서버.
-
-
- Data: Tue, 15, Nov 1994 15:50:31 GMT
- 응답에서 사용.
-
- 요청에서 사용.
- 하나의 서버가 여러 도메인을 처리해야 할 때.
- 하나의 IP 주소에 여러 도메인이 적용(가상호스트 사용)되어 있을 때 구분.
- IP로 구분할 수 없기 때문에, 호스트 도메인을 넣어준다.
-
- 웹 브라우저는 3xx의 응답의 결과에 Location 헤더가 있으면, 대상 리소스로 자동으로 리다이렉트.
- 201-Created 에서 Location 값은 요청에 의해 생성된 리소스의 URI
-
- 405(Method Not Allowed)에서 응답에 포함해야 한다.
- 지원하는 HTTP 메서드를 알려주는 역할을 한다.
- Allow: GET, HEAD, PUT
-
- 503(Service Unavailable): 서비스가 언제까지 불능인지 알려줄 때 사용한다.
- (날짜로 표기) Retry-After: Fit, 31 Dec 1999 23:59:59 GMT
- (초단위로 표기) Retry-After: 120
-
- Authorization: Basic xxxxxxxxxxxxxx
- 인증 방법에 따라 값은 달라진다.
-
- 401 Unauthorized 응답과 함께 사용한다.
- WWW-Authenticate: Newauth realm="apps", type=1, title="Login to"apps"", Basic realm="simple"
- 헤더 정보를 참고해서 제대로 된 인증 정보를 생성하게 된다.
- Set-Cookie: 서버에서 클라이언트로 쿠키 전달(응답)
- Cookie: 클라이언트가 서버에서 받은 쿠키를 저장하고, HTTP 요청시 서버로 전달.
HTTP는 무상태 프로토콜이기 때문에 클라이언트가 서버와 요청과 응답을 주고 받은 후 연결이 끊어지고, 다시 요청하더라도 서버는 이전 요청을 기억하지 않는다.
- 처음에 쿠키를 전달 받은뒤, 모든 요청에서 반드시 쿠키 저장소에서 정보를 가져와 함께 보낸다.
set-cooke: sessionId=aasd35sdd3sd23; expires-Sat, 26-Dec-2021 00:00:00 GMT; [ath=/; domain=.google.com; Secure
- 사용자 로그인 세션 관리에 사용.
- 광고 정보를 트래킹 할 때 사용.
- 쿠키정보는 항상 서버에 전송되기 때문에 네트워 트래픽을 추가 유발한다.
- 최소한의 정보만을 사용(Session Id, Authorization Token ...)
- 보안에 민감한 데이터는 저장하지 않도록 해야한다.
🤔 서버에 전송하지 않고 웹 브라우저 내부에 데이터 저장하고 싶다면 웹 스토리지(local, sessionStroage)사용.
-
- 만료일이 되면 쿠키를 삭제
- Set-Cookie: max-age=4600(초)
- 0이나 음수를 지정하면 쿠키를 삭제한다.
- ✏️ 세션 쿠키 : 만료 날짜를 생략하게 되면 브라우저 종료시 까지만 유지한다.
- ✏️ 영속 쿠키 : 만료 날짜를 입력하면 해당 날짜까지 유지한다.
-
- 명시: 명시한 문서 기준 도메인 + 서브 도메인까지 포함한다.
- dev.example.org도 쿠키에 접근할 수 있다.
- 생략 : 현재 문서 기준 도메인만 적용.
- example.org에서 쿠키를 생성했다면 example.org에서만 접근이 가능하고, dev.example.org(서브)에서는 접근할 수 없다.
- 명시: 명시한 문서 기준 도메인 + 서브 도메인까지 포함한다.
-
- 이 경로를 포함한 하위 경로 페이지만 쿠키 접근이 가능하다.
- 일반적으로는 루트로 지정.
- path=/ -> 모두 접근 가능
- path=/home -> /home/* -> 접근 가능, /hello -> 접근 불가능.
-
- 기본적으로 쿠키는 http, https를 구분하지 않고 전송,
- Secure를 적용하면 https인 경우에만 전송.
- *XSS 공격 방지 : 자바스크립트에서 쿠키에 접근할 수 없도록 한다.
- HTTP 전송에서만 사용한다.
💡 XXS? 사이트 간 스크립팅(Cross-Site Scripting) : 관리자가 아닌 권한이 없는 사용자가 웹 사이트에 스크립트를 삽입하는 공격. 사용자의 Session을 탈취하여 악의적으로 사용할 수 있다.
- *XSRF 공격 방지.
- 요청 도메인과 쿠키에 설정된 도메인이 같은 경우만 쿠키를 전송한다.
💡 XSRF? 사이트 간 요청 위조(Cross-site Request Forgery) : 사용자가 자신의 의지와는 무관하게 공격자가 의도한 행위를 특정 웹사이트에 요청하게 하는 공격.
- 60초간 유효한 캐시. (네트워크 다운로드가 발생하지 않는다.)
- 웹 브라우저에서 캐시에 접근할 때 유효기간이 지났다면, 다시 서버에서 요청하게 된다.
- 요청에 대한 응답을 다시 캐시에 저장하여 갱신한다.
캐시 유효시간이 초과해서 서버에 다시 요청할 때는 두 가지 상황이 존재한다.
- 서버에서 기존 데이터를 변경함.
- 서버에서 기존 데이터를 변경하지 않음.
-
이를 알기 위해 응답 데이터를 보낼 때 검증 헤더를 추가한다.
Last-Modified: Fri, 26-Dec-2021 00:00:00 GMT -
이후 캐시에서 해당 데이터가 사용될 때 데이터의 최종 수정일을 서버에 전송.
if-modified-since: Fri, 26-Dec-2021 00:00:00 GMT -
서버에서는 변경되었는지 검증
-
- 바디를 추가하지 않고 용량이 적은 헤더 정보만 다운로드 하기 때문에 네트워크의 부하를 줄일 수 있다.
- 캐시에 있는 데이터를 재사용, 응답 헤더로 캐시의 메타 정보를 갱신한다.(max-age)
-
200 OK, 서버에서 응답에 데이터를 담아 보내준다.
- 1초 미만의 단위로 캐시 조정이 불가능하다.
- 날짜 기반의 로직을 사용한다.
- 데이터를 수정하여 날짜는 달라졌지만, 데이터 결과가 동일한 경우를 구분할 수 없다.
- 서버에서 별도의 캐시 로직을 관리할 수 없다.
- ex) 스페이스, 주석 처럼 크게 영향이 없는 변경에서 캐시를 사용하고 싶은 경우.
- ETag: Entity Tag
- 캐시용 데이터에 임의의 고유한 버전 이름을 달아둠.
- 데이터가 변경되면 이 이름을 바꾸어서 변경함(Hash를 다시 생성) -> 동일한 데이터의 경우 같은 Hash값을 가짐.
- 단순하게 ETag만 보내서 같으면 유지, 다르면 다운로드.
- 캐시 제어 로직을 서버에서 완전히 관리.
- 클라이언트는 단순히 ETag를 서버에 제공(클라이언트 캐시 메커니즘을 몰라도 된다.)
- 일정 기간동안 ETag를 동일하게 유지하여 캐시에서 데이터를 사용하게 하거나, 배포 주기에 맞춰 ETag를 한번에 갱신하는 등으로 사용 가능하다.
-
-
- 캐시 유효 시간(초 단위)
-
- 데이터는 캐시하지만, 항상 Origin 서버에 검증하고 사용.
-
- 데이터에 민감한 정보가 있으므로 저장하면 안된다.(메모리에서 사용하고 최대한 빨리 삭제.)
-
-
- pragma: no-cache
- HTTP 1.0 하위 호환.
-
- expires: Mon, 01 Jan 2021 00:00:00 GMT
- 캐시 만료일을 정확한 날짜로 지정.
- HTTP 1.0 부터 사용.
- 지금은 더 유연한 Cache-Control: max-age를 권장하며, 함께 사용하면 Expires는 무시된다.
-
- ETag, Last-Modified
-
- If-Match, If-None-Match: Etag값 사용.
- If-Modified-Since, If-Unmodified-Since: Last-Modified 값 사용.
- 최초 접속자만 다운로드 하거나 혹은 원 서버에서 캐시 서버에 데이터를 밀어 넣는다.
- 공용 캐시 : public
- 로컬 캐시 : private
-
- 응답이 public 캐시에 저장되어도 된다.
-
- 응답이 해당 사용자만을 위한 것, private 캐시에 저장해야 함(default)
-
- 프록시 캐시에만 적용되는 max-age
-
- Origin 서버에서 응답 후 프록시 캐시 내에 머문 시간(초)
- Age: 60
-
- 절대 캐시가 되면 안되는 데이터.
- Cache-Control: no-cache, no-store, must-revalidate (모두 사용)
무조건 원서버에서 검증, 저장하지 않음.
- Pragma: no-cache (HTTP 1.0 대비)
-
원 서버 접근 실패시 반드시 오류가 발생해야한다 - 504 Gateway Timeout
-
must-revalidate는 캐시 유효 간이라면 캐시를 사용한다.
origin 서버에 접근할 수 없는 경우. no-cache 에서는 서버 설정에 따라 오래된 데이터를 결과를 받게될 수 있다. must-revalidate 에서는 반드시 504 오류가 발생한다.






























