HTTP - 김영한님 강의 정리
- IP(인터넷 프로토콜)
- 복잡한 인터넷 망에서 ip주소를 통해 탐색
- 지정한 IP 주소에 데이터 전달
- 패킷이라는 통신 단위로 전달
- IP 패킷 정보
- 서버에서 패킷을 받았을 경우 출발지로 다시 OK 패킷을 보내준다
- 경로가 서로는 다를 수 있다
- IP의 한계
- 비연결성
- 패킷을 받을 대상이 없거나 서비스 불능 상태여도 패킷 전송 (서버 컴퓨터 다운)
- 비신뢰성
- 중간에 패킷이 사라지면? (패킷유실)
- 패킷이 순서대로 안오면? (순서대로 안오면..?)
- 프로그램 구분
- 같은 IP를 사용하는 서버에서 통신하는 애플리케이션이 둘 이상이면?
- IP의 한계 해결 → TCP(UDP)
- TCP
- 계층
- 애플리케잇현 계층 - HTTP, FTP
- 전송 계층 - TCP, UDP
- 인터넷 계층 - IP
- 네트워크 인터페이스 계층
- TCP/IP 패킷 정보
- 출발지 port
- 목적지 port
- 전송 제어
- 순서
- 검증 정보
- 특징
- 연결 지향 (TCP 3 way handshake - 가상 연결)
- 3 way handshake 연결 과정
- SYN
- SYN + ACK
- ACK (요즘은 최적화되서 ACK을 보낼 때 데이터 전송)
- 데이터 전송
- 연결 오류 시 보내지 않음
- 개념적으로 연결된 것
- 데이터 전달 보증
- 순서 보장
- 패킷이 다른 순서로 도착하더라도 원래의 순서 보장
- 신뢰할 수 있는 프로토콜
- 현재는 대부분 TCP 사용
- UDP
- 특징
- 기능이 거의 없다(하얀 도화지)
- 연결지향 X
- 데이터 전달 보증 X
- 순서 보장 X
- 단순하고 빠름
- IP와 거의 같으나 PORT와 checksum이 존재
- 애플리케이션에서 추가 작업 필요
- 장점
- TCP는 3 way handshake에 시간 소요
- TCP는 더 이상 최적화할 수 없음 - 그렇게 만들어졌기 때문
- UDP에서 원하는 기능만 넣으면 최적화 가능 (HTTP3.0)
- HTTP 3.0에서 더욱 최적화를 하면서 UDP 사용
- PORT
- 한 IP에서 게임, 화상통화 등 여러가지 사용 중이라면 각 프로그램에 대해 구분이 필요
- IP는 아파트, PORT는 몇 동 몇 호인지
- PORT 범위
- 0~65535
- 0~1023 자주 사용되는 포트, 사용하지 않는 것이 좋음
- FTP - 20, 21
- TELNET - 23
- HTTP - 80
- HTTPS - 443
- DNS
- IP는 변경될 수 있다. 그렇기 때문에 다시 접근할 수 있을 방법이 필요
- DNS (Doman Name System)
- 전화번호부같은 시스템
- 도메인 명을 보내면 해당하는 IP를 답해준다
- www.google.com → dns 서버 → 100.100.100.2
- URI
- Uniform Resource Identifier
- Uniform : 리소스를 식별하는 통합된 방법
- Resource : 자원, URI로 식별할 수 있는 모든 것(제한없음)
- Identifier : 다른 항목과 구분하는데 필요한 정보
- URI vs URL vs URN
- URI : 로케이터, 이름 또는 둘다 추가로 분류될 수 있다
- URI 내부에 URL(locator - 리소스 위치)과 URN(name - 리소스 이름) 존재
- URL : 웹페이지에 작성하는 것, 리소스가 있는 위치를 지정
- URN : 리소스에 이름을 부여하는 것
- urn:isbn:8960777331 (어떤 책의 isbn URN)
- URN 이름만으로 실제 리소스를 찾을 수 있는 방법이 보편화 되지 않음
- URL Scheme
- scheme://[userinfo@]host[:port][/path][?query][#fragment]
- scheme
- 주로 프로토콜 사용
- 프로토콜 : 어떤 방식으로 자원에 접근할 것인가 하는 약속 규칙
- http는 80포트, https는 443포트를 주로 사용, 포트는 생략 가능
- https는 http에 보안 추가(HTTP secure)
- userinfo
- host
- port
- path : 리소스 경로, 계층적 구조 (/members/100)
- query : key=value 형태, ?로 시작, &로 추가 가능 - query parameter, query string 등으로 불림, 웹 서버에 제공하는 파라미터, 문자 형태
- fragment : html 내부 북마크 등에 사용, 서버에 전송하는 정보 아님
- https://www.google.com:443/search?q=hello&hl=ko
- 웹 브라우저 요청 흐름
- 도메인 입력 → DNS 서버 → IP, PORT 조회
- Scheme
- GET /search?q=hello&hl=ko HTTP/1.1
- 동작과정
- 웹 브라우저가 HTTP 메시지 생성
- SOCKET 라이브러리를 통해 전달
- TCP/IP 연결
- 데이터 전달
- TCP/IP 패킷 생성, HTTP 메세지 포함
- HTTP 메시지가 패킷에 포함된다
- HTTP
- HyperText Transfer Protocol
- 모든 것을 HTTP에 담아서 보낸다
- HTML, TEXT
- Image, 음성, 영상, 파일
- Json, XML(API)
- 거의 모든 형태의 데이터 전송 가능
- 서버간에 데이터를 주고 받을 때도 대부분 HTTP 사용
- 게임 같은 경우만 특수 케이스
- HTTP 1.1
- 이 스펙에 대부분의 기능이 들어있다
- HTTP 2.0, 3.0은 성능 개선을 위한 것
- TCP : http 1.1, http 2.0
- UDP : http 3.0
- 특징
- 클라이언트 서버 구조
- 무상태 프로토콜(stateless), 비연결성
- HTTP 메시지
- 단순함, 확장 가능
- 클라이언트 서버 구조
- 동작과정
- request + response 구조
- 클라이언트는 서버에 요청을 보내고, 응답을 대기
- 서버가 요청에 대한 결과를 만들어서 응답
- 클라이언트와 서버를 구분함으로 써 각자가 독립적인 역할에 최선을 다할 수 있다
- 무상태 프로토콜
- 서버가 클라이언트의 상태를 보존하지 않는다
- 서버 확장성 높음(스케일 아웃)
- 클라이언트가 추가 데이터 전송
- Stateful vs Stateless
- Stateful
- 중간에 다른 상대로 바뀌면 안된다
- 바뀔 때 상태 정보를 다른 상대에게 미리 알려야 한다
- Stateless
- 갑자기 고객이 증가해도 상대를 대거 투입할 수 있다
- 갑자기 클라이언트의 요청이 증가해도 서버를 대거 투입할 수 있다
- 무상태는 응답 서버를 쉽게 바꿀 수 있다. → 무한한 서버 증설 가능
- Stateless 실무한계
- 모든 것을 무상태로 설계할 수 있는 경우도 있고 없는 경우도 있다
- 로그인한 사용자의 경우 로그인했다는 상태를 서버에 유지
- 일반적으로 브라우저 쿠키와 서버 세션등을 사용해서 상태 유지
- 상태 유지는 최소한만 사용
- 비 연결성(Connetionless)
- 모델의 차이점
- 연결을 유지하는 모델
- 연결을 유지하지 않는 모델
- 필요한 요청/응답 후 바로 연결을 끊으므로서 최소한의 자원 유지
- 단점
- TCP/IP 연결을 새로 맺어야 함 - 3 way handshake 시간 추가
- 웹 브라우저로 사이트를 요청하면 HTML 뿐만 아니라 js, css, 추가 이미지 등 수 많은 자원이 함께 다운로드
- 지금은 HTTP 지속 연결로 문제 해결 (persistance connections)
- HTTP/2 HTTP/3에서 더 많은 최적화
- 서버 개발자들이 어려워하는 업무
- 선착순 이벤트, 명절 KTX 예약 등
- 수만명 동시 요청
- 최대한 stateless하게 하는게 중요하다
- 로그인도 필요없는 정적 페이지를 뿌리고, 이벤트 참여토록 생성
- HTTP 메시지
- HTTP 요청/응답 메시지
- 메시지 구조
- 시작라인
- request-line / status-line
- request-line
- method 공백 request-target 공백 http-version 엔터
- method - GET, POST, PUT, DELETE
- 서버가 수행해야 할 동작 지정
- status-line
- HTTP-version SP status-code SP reason-phrase CRLF
- HTTP 버전
- HTTP 상태 코드 : 요청 성공, 실패를 나타냄
- 200 : 성공
- 400 : 클라이언트 요청 오류
- 500 : 서버 내부 오류
- 헤더
- HTTP 전소엥 필요한 모든 부가정보 포함
- 표준 헤더가 너무 많음
- 필요시 임의의 헤더 추가 가능
- 공백라인(CRLF)
- 메시지 바디
- 실제 전송할 데이터
- HTML 문서, 이미지, 영상, JSON 등 byte로 표현할 수 있는 모든 데이터 포함
- 단순함, 확장 가능
- HTTP는 단순하다
- HTTP 메시지도 매우 단순
- 크게 성공하는 표준 기술은 단순하지만 확장 가능한 기술
- HTTP 메서드
- HTTP API 제작
- API URL 설계
- 가장 중요한 것은 리소스 식별
- 리소스의 의미는?
- 회원을 등록하고 수정하고 조회하는게 리소스가 아니다.
- 회원이라는 개념 자체가 리소스다
- method 이름은 모두 배제하는 것이 좋다
- 회원 리소스만 URI에 매핑
- 회원 목록 조회 /members
- 회원 조회 /members/{id}
- 회원 등록 /members/{id}
- 회원 업데이트 /members/{id}
- 회원 삭제 /members/{id}
- 리소스만 식별하면 구분은 어떻게 할까?
- HTTP method로 구분(Get, Post 등)
- HTTP 메서드 종류
- GET : 리소스 조회
- 서버에 전달하고 싶은 데이터는 쿼리를 통해서 전달
- 메시지 바디를 사용해서 데이터르 전달할 수 있지만, 지원하지 않은 곳이 많아서 권장하지 않음
- url 쿼리를 통해서 데이터를 전달하여 보안적인 이슈가 있다
- POST : 요청 데이터 처리, 주로 등록에 사용
- 요청 데이터 처리
- 메시지 바디를 통해 서버로 요청 데이터 전달
- 서버는 요청 데이터를 처리
- 메시지 바디를 통해 들어온 데이터를 처리하는 모든 기능을 수행
- 주로 전달된 데이터로 신규 리소스 등록, 프로세스 처리에 사용
- 다음과 같은 기능에 사용
- HTML 양식에 입력 된 필드와 같은 데이터 블록을 데이터 처리 프로세스에 제공
- 게시판, 뉴스 그룹, 메일링 리스트, 블로그 또는 유사한 기사 그룹에 메시지 게시
- 서버가 아직 식별하지 않은새 리소스 생성
- 기존 자원에 데이터 추가
- 정리
- 새 리소스 생성
- 요청 데이터 처리
- 데이터 생성, 변경을 넘어서 프로세스 처리해야하는 경우
- POST로 새로운 리소스가 생성되지 않을 수 있음
- 다른 메서드로 처리 애매할 경우
- PUT : 리소스 대체, 해당 리소스 없으면 생성
- 리소스를 대체
- 리소스가 있으면 대체
- 리소스가 없으면 생성
- 덮어쓰기
- 클라이언트가 리소스를 식별
- 클라이언트가 리소스 위치를 알고 URI 지정
- POST와의 차이점
- 주의
- 리소스를 완전히 대체한다
- 고로 수정하지 않는 기존에 있던 field도 모두 추가해주어야한다
- PATCH : 리소스 부분 변경
- PUT이 리소스를 완전히 대체해 변경하지 않는 field를 모두 제거하므로 그를 고치기 위해 제안된 것
- PATCH가 지원되지 않는 서버도 있다
- 그럴 경우에는 POST 사용
- DELETE : 리소스 삭제
- HEAD
- OPTIONS
- CONNECT
- TRACE
- HTTP 메서드 속성
- 안전
- 호출해도 리소스를 변경하지 않는다 - GET
- 안전은 해당 리소스만 고려한다 - 로그 쌓이고 이런건 고려 X
- 멱등(idempotent)
- f(f(x)) = f(x)
- 한 번 호출하든 두 번 호출하든 100번 호출하든 결과가 똑같다
- 멱등 메서드
- GET
- PUT : 결과를 대체한다. 따라서 같은 요청을 여러번 해도 최종 결과는 같다
- DELETE : 결과를 삭제한다. 같은 요청을 여러번 해도 삭제된 결과는 같다
- POST : 멱등이 아니다. 두 번 호출하면 같은 결제가 중복해서 발생할 수 있다
- 자동 복구 메커니즘
- 서버가 TIMEOUT으로 정상 응답을 못주었을 때, 클라이언트가 같은 요청을 다시 해도 되는가에 대한 판단 근거
- 특수 케이스
- 재요청 중간에 다른 곳에서 리소스를 변경해버리면?
- 멱등은 외부 요인으로 중간에 리소스가 변경되는 것 까지는 고려하지는 않는다(개인의 요청에 대해서만)
- 캐시 가능
- 응답 결과 리소스를 캐시해서 사용해도 되는가?
- GET, HEAD, POST, PATCH 캐시 가능
- 실제로는 GET, HEAD 정도만 캐시로 사용
- POST, PATCH는 본문 내용까지 캐시 키로 고려해야 하는데, 구현이 쉽지 않다
- 클라이언트에서 서버로 데이터 전송
- 전송방법
- 쿼리 파라미터를 통한 데이터 전송
- 메시지 바디를 통한 데이터 전송
- 4가지 상황
- 정적 데이터 조회
- 쿼리 파라미터 미사용
- 이미지, 정적 텍스트 문서
- 조회는 GET 사용
- 정적 데이터는 단순 리소스 경로로 조회 가능
- 동적 데이터 조회
- 쿼리 파라미터 사용
- 주로 검색, 게시판 목록에서 정렬 필터(검색어)
- 조회 조건을 줄여주는 필터, 조회 결과를 정렬하는 정렬 조건에 주로 사용
- 조회는 GET 사용
- GET은 쿼리 파라미터 사용해서 데이터를 전달
- HTML Form을 통한 데이터 전송
- POST 전송 - 저장
- HTTP body에 쿼리 파라미터와 비슷한 방식으로 데이터 전송
- form의 method를 post에서 get으로 바꾸면?
- multipart/form-data
- 파일을 같이 전송하는 경우 사용하는 enctype
- 파일들을 경계로 잘라서 바디에 보관
- 파일 업로드 같은 바이너리 데이터 전송 시 사용
- HTML Form 전송은 GET, POST만 지원
- HTTP API를 통한 데이터 전송
- JSON과 같은 형태로 전송
- 서버 to 서버(백엔드 시스템 통신)
- 앱 클라이언트, 웹 클라이언트
- POST, PUT, PATCH : 메시지 바디를 통해 데이터 전송
- GET : 조회, 쿼리 파라미터로 데이터 전달
- Content-Type : application/json을 주로 사용
- HTTP API 설계 예시
- POST 기반 등록 예시
- 회원 관리 시스템
- 회원 목록 → GET
- 회원 등록 → POST
- 회원 조회 → GET
- 회원 수정 → PATCH, PUT, POST
- 회원 삭제 → DELETE
- 클라이언트는 등록될 리소스의 URI를 모른다
- 서버가 새로 등록된 리소스 URI를 생성해준다
- 컬렉션
- 서버가 관리하는 리소스 디렉토리
- 서버가 리소스의 URI를 생성하고 관리
- 여기서 컬렉션은 /members
- PUT 기반 등록 예시
- 파일 관리 시스템
- 파일 목록 /files → GET
- 파일 조회 /files/{filename} → GET
- 파일 등록 /files/{filename} → PUT (덮어쓰기)
- 파일 삭제 /files/{filename} → DELETE
- 파일 대량 등록 /files → POST
- PUT을 사용하므로 클라이언트가 리소스 URI를 가지고 있어야한다
- 왜냐하면 원래 있던 것을 덮어쓰기 해야되기 때문에
- PUT /files/star.jpg
- 클라이언트가 직접 리소스의 URI를 지정
- 스토어
- 클라이언트가 관리하는 리소스 저장소
- 클라리언트가 리소스의 URI를 알고 관리
- 여기서 스토어는 /files
- HTML FORM 사용 예시
- HTML FORM은 GET, POST만 지원
- AJAX 같은 기술을 사용해서 해결 가능 → 회원 API 참고
- 회원 관리 시스템
- 회원 목록 /members → GET
- 회원 등록 폼 /members/new → GET
- 회원 등록 /members/new, /members → POST
- 회원 조회 /members/{id} → GET
- 회원 수정 폼 /members/{id}/edit → GET
- 회원 수정 /members/{id}/edit, /members/{id} → POST
- 회원 삭제 /members/{id}/delete → post
- 컨트롤 URI
- GET, POST만 지원하므로 제약이 있음
- 이런 제약을 해결하기 위해 동사로 된 리소스 경로 사용
- POST의 /new /edit /delete가 컨트롤 URI
- HTTP 메서드로 해결하기 애매한 경우 사용(HTTP API 포함)
- 주의점
- 무식하게 사용하면 안된다
- 리소스 개념으로 사용하고 부족할 때만 사용해야 한다
- 참고하면 좋은 URI 설계 개념
- 문서(document)
- 단일 개념(파일 하나, 객체 인스턴스, 데이터베이스 row)
- /members/100, /files/star.jpg
- 컬렉션(collection)
- 서버가 관리하는 리소스 디렉토리
- 서버가 리소스의 URI를 생성하고 관리
- /members
- 스토어(store)
- 클라이언트가 관리하는 자원 저장소
- 클라이언트가 리소스의 URI를 알고 관리
- /files
- 컨트롤러(controller), 컨트롤 URI
- 문서, 컬렉션, 스토어로 해결하기 어려운 추가 프로세스 실행
- 동사를 직접 사용
- /members/{id}/delete
- HTTP 상태코드
- 종류
- 1XX (Infomational) : 요청이 수신되어 처리중
- 2XX (Successful) : 요청 정상 처리
- 200 OK
- 201 Created
- 202 Accepted
- 요청이 접수되었으나 처리가 완료되지 않았음
- 배치 처리 같은 곳에서 사용
- 요청 접수 후 1시간 뒤에 배치 프로세스가 요청을 처리
- 204 No Content
- 서버가 요청을 성공적으로 수행했지만, 응답 페이로드 본문에 보낼 데이터가 없음
- save 버튼
- save 버튼의 결과로 아무 내용이 없어도 된다
- save 버튼을 눌러도 같은 화면을 유지해야 한다
- 결과 내용이 없어도 204 메시지만으로 성공을 인식할 수 있다
- 3XX (Redirection) : 요청이 완료되려면 추가 행동이 필요
- 리다이렉션이란? 응답의 결과에 Location 헤더가 있으면, Location 위치로 자동 이동
- 종류
- 영구 리다이렉션 - 특정 리소스의 URI가 영구적으로 이동
- 리소스의 URI가 영구적으로 이동했음을 알려준다
- 301
- 리다이렉트 시 요청 메서드가 GET으로 변하고, 본문이 제거될 수 있음
- 308
- 리다이렉트시 요청 메서드와 본문 유지(처음 POST 시, 리다이렉트도 POST)
- 일시 리다이렉션 - 일시적인 변경
- 주문 완료 후 주문 내역 화면으로 이동
- 302 Found → GET으로 변할 수 있음
- 리다이렉트시 요청 메서드가 GET으로 변하고, 본문이 제거될 수 있음
- 307 Temporary Redirect → Method가 변하면 안됨
- 302와 기능은 같음
- 리다이렉트시 요청 메서드와 본문 유지(요청 메서드를 변경하면 안된다)
- 303 See Other → 메서드가 GET으로 변경
- 302와 기능은 같음
- 리다이렉트 시 요청 메서드가 GET으로 변경
- PRG(Post Redirect Get)
- POST로 주문 후에 웹 브라우저를 새로고침하면?
- 새로 고침은 다시 요청되서 다시 재주문이 될 수 있다
- POST로 주문 후에 새로 고침으로 인한 중복 주문 방지
- POST로 주문 후에 주문 겨로가 화면을 GET 메서드로 리다이렉트
- 새로고침해도 결과 화면을 GET으로 조회
- 중복 주문 대신에 결과 화면만 GET으로 다시 요청
- 특수 리다이렉션
- 결과 대신 캐시를 사용
- 300 Multiple Choices : 안 쓴다
- 304 Not Modified
- 캐시를 목적으로 사용
- 클라이언트에게 리소스가 수정되지 않았음을 알려줌. 따라서 클라이언트는 로컬 PC에 저장된 캐시를 재사용(캐시로 리다이렉트)
- 304 응답은 응답에 메시지 바디를 포함하면 안된다 (로컬 캐시 사용으로)
- 조건부 GET, HEAD 요청 시 사용
- 4XX (Client Error) : 클라이언트 오류, 잘못된 문법 등으로 서버가 요청을 수행할 수 없음
- 똑같은 재시도가 실패를 계속한다 (400대는 복구 불가, 500대와의 차이)
- 요청 구문, 메시지 등등 오류
- 401 Unauthorized
- 클라이언트가 해당 리소스에 대한 인증이 필요
- 인증 : 본인이 누군인지 확인(로그인)
- 인가 : 권한부여(Admin 권한처럼 특정 리소스에 접근할 수 있는 권한, 인증이 있어야 인가가 있음)
- 403 Forbidden
- 서버가 요청을 이해했지만 승인을 거부함
- 주로 인증 자격 증명이 있지만, 접근 권한이 불충분한 경우
- 404 Not Found
- 요청 리소스가 서버에 없음
- 또는 클라이언트가 권한이 부족한 리소스에 접근할 때 해당 리소스를 숨기고 싶을 때
- 5XX (Server Error) : 서버 오류, 서버가 정상 요청을 처리하지 못함
- 서버에 문제가 있기 때문에 재시도 시 성공할 수도 있음
- 500 Internal Server Error
- 503 Service Unavailable
- 서비스 이용 불가
- 서버가 일시적인 과부하 또는 예정된 작업으로 잠시 요청을 처리할 수 없음
- Retry-After 헤더 필드로 얼마뒤에 복귀되는지 보낼 수도 있음
- 만약 모르는 상태코드가 나타나면?
- HTTP 헤더
- 헤더 분류
- General 헤더 : 메시지 전체에 적용되는 정보
- Request 헤더 : 요청 정보
- Response 헤더 : 응답 정보
- Entrity 헤더 : 엔티티 바디 정보
- 엔티티 본문의 데이터를 해석할 수 있는 정보 제공
- 데이터 유형, 데이터 길이, 압축 정보 등
- Representation으로 변경
- HTTP BODY
- 메시지 본문을 통해 표현 데이터 전달
- 메시지 본문 = 페이로드(payload)
- Representation은 요청이나 응답에서 전달할 실제 데이터
- 표현 헤더는 표현 데이터를 해석할 수 있는 정보 제공
- Representation
- Content-Type : 표현 데이터의 형식
- 미디어 타입, 문자 인코딩
- text/html, charset=utf-8, application/json, image/png
- Content-Encoding : 표현 데이터의 압축 방식
- 표현 데이터를 압축하기 위해 사용
- 데이터를 전달하는 곳에서 압축 후 인코딩 헤더 추가
- 데이터를 읽는 쪽에서 인코딩 헤더의 정보로 압축 해제
- gzip, deflate, identity
- Content-Language : 표현 데이터의 자연 언어
- 표현 데이터의 자연 언어를 표현
- ko, en, en-US
- Content-Length : 표현 데이터의 길이
- 바이트 단위
- Transfer-Encoding을 사용하면 Content-Length를 사용하면 안된다
- 표현 헤더는 전송, 응답 둘다 사용
- 협상(콘텐츠 네고시에이션)
- 클라이언트가 선호하는 표현 요청
- Accept : 클라이언트가 선호하는 미디어 타입 전달
- Accept-Charset : 클라이언트가 선호하는 문자 인코딩
- Accept-Encoding : 클라이언트가 선호하는 압축 인코딩
- Accept-Language : 클라이언트가 선호하는 자연 언어
- 협상 헤더는 요청시에만 사용
- 지원하는 것 중 선호하는 것이 있을 시 지원해주지만, 없을 경우 지원 불가
- 협상과 우선순위 Quality Values
- Quality values range 0~1, 클수록 높은 우선순위(생략시 1)
- 구체적인 것이 우선순위이다
- text/plain;format=flowed > text/*
- 구체적인 것을 기준으로 미디어 타입을 맞춘다
- 전송 방식
- 단순 전송
- Content-Length를 지정하여 전송
- 한번에 요청, 한번에 수락
- 압축 전송
- gzip과 같은 압축 기술 사용
- Content-Encoding 사용
- 분할 전송
- Transfer-Encoding 사용 (chunked)
- size / data 페어로 보낸다
- /r/n으로 종료
- Content-Length를 넣으면 안된다
- 범위 전송
- 범위를 지정해서 요청할 수 있다
- Range 사용
- 일반 정보
- From (요청)
- Referer (요청)
- 이전 웹 사이트의 주소
- 현재 요청된 페이지의 이전 웹 사이트 주소
- 유입경로 분석 등에 사용
- referrer의 오타이나 너무 오래 사용되어 그냥 사용한다
- User-Agent (요청)
- 내 웹 브라우저 정보
- 클라이언트의 애플리케이션 정보
- 통계 정보
- 어떤 종류의 브라우저에서 장애가 발생하는지 파악 가능
- Server (응답)
- 요청을 처리하는 origin 서버의 소프트웨어 정보
- 나의 요청이 있는 마지막 서버
- Date (응답)
- 특별한 정보
- Host (요청)
- 필수값 헤더
- 하나의 서버가 여러 도메인을 처리해야할 때
- (여러 도메인을 하나의 서버로 띄우는 중)
- 하나의 IP 주소에 여러 도메인이 적용되어 있을 때
- 가상 호스트를 통해 여러 도메인을 한 번에 처리 가능
- Location
- 웹 브라우저는 3XX 응답의 결과에 Location 헤더가 있으면 그 위치로 자동 이동
- Location 값은 요청에 의해 생성된 리소스 URI
- Allow
- 405에서 응답에 포함해야한다
- GET, HEAD, PUT
- Retry-After
- 503에서 서비스가 언제까지 불능인지 알려줄 수 있다
- 유저 에이전트가 다음 요청을 하기까지 기다려야 하는 시간을 표기한다
- 인증
- Authorization
- 클라이언트 인증 정보를 서버에 전달
- 각 인증마다 필요로 하는 인증 값이 다르다
- WWW-Authenticate
- 리소스 접근 시 필요한 인증 방법 정의
- 401 응답과 함께 사용
- 쿠키
- 쿠키 미사용 시 stateless인 HTTP는 로그인 한 유저인지 확인 불가
- 모든 요청에 사용자 정보 포함 시 보안적, 자원적 문제가 많음..
- 지정한 서버에 대해서는 쿠키값을 계속 보유 중
- 사용처
- 항상 쿠키 정보는 서버에 전송되므로 네트워크 트래픽 추가 유발
- 그래서 최소한의 정보만 사용 & 서버에 전송하지 않고 웹 브라우저 내부에 데이터를 저장하고 싶으면 웹 스토리지(로컬스토리지, 세션 스토리지) 사용
- 보안에 민감한 데이터를 저장하면 안됨
- Set-Cookie
- 서버에서 클라이언트로 쿠키 전달(응답)
- expires
- max-age
- 남은 시간 지정, 0이나 음수를 지정 시 쿠키 삭제
- 세션 쿠키 : 만료 날짜를 생략하면 브라우저 종료 시 까지만 유지
- 영속 쿠키 : 만료 날짜를 입력하면 해당 날짜까지 유지
- 도메인
- 명시한 문서 기준 도메인 + 서브 도메인에서만 쿠키 유지하도록 설정
- 생략 시 해당 도메인에서만 적용
- 경로
- 이 경로를 포함한 하위 경로 페이지만 쿠키 접근
- 일반적으로 루트로 지정
- Secure
- 쿠키는 http, https를 구분하지 않고 전송하나 secure 시 https인 경우에만 전송
- HttpOnly - XSS 공격 방지, JS에서 접근 불가
- SameSite - XSRF 공격 방지, 요청 도메인과 쿠키에 설정된 도메인이 같은 경우에만 쿠키 전송
- Cookie
- 클라이언트가 서버에서 받은 쿠키를 저장하고, HTTP 요청 시 서버로 전달
- 캐시
- 캐시가 없는 경우??
- 과정
- 원하는 리소스를 서버로 부터 요청 받아 가져온다
- http 헤더가 0.1, 바디가 1.0이면 1.1을 가져온다
- 또 다시 리소스를 요청할 경우 같은 작업을 반복한다
- 단점
- 데이터가 변경되지 않아도 계속 네트워크를 통해서 데이터를 다운
- 네트워크는 비싸고 느림
- 느린 사용자 경험 제공
- 캐시 적용
- 과정
- cache-control 이라는 헤더를 넣는다
- max-age동안 유지
- 응답 결과를 캐시에 저장
- 두번 째 요청 시 캐시부터 확인
- 캐시 시간 초과
- 서버를 통해 데이터를 다시 조회하고, 캐시를 갱신
- 이때 다시 네트워크 다운로드가 발생
- 리프래쉬할만한 리소스가 아닌경우에는??
- 캐시 만료 후에도 서버에서 데이터를 변경하지 않은 경우에는 데이터를 전송하는 대신 재사용가능하다는 걸 확인해야한다
- 검증 헤더 사용 (Last-Modified)
- 데이터 최종 수정일을 추가
- if-modified-since를 서버에 담아서 보내는데 서버의 데이터 최종 수정일과 동일하다면 데이터가 수정되지 않았음이 검증
- 그러면 304 Not Modified를 보내며 HTTP Body를 비워둠
- 그 뒤 브라우저 캐시 응답 결과를 재사용, 헤더 데이터 갱신
- 단점 → ETag 보완
- 시간을 사용하므로 1초 미만 단위로 캐시 조정이 불가능
- 날짜 기반의 로직 사용
- 데이터를 수정해서 날짜가 다르지만, 같은 데이터를 수정해서 데이터 결과가 같은 경우
- 서버에서 별도의 캐시 로직을 관리하고 싶은 경우
- 스페이스나 주석처럼 크게 영향이 없는 변경에서 캐시 유지
- 검증 헤더 사용 (ETag → Entity Tag)
- 캐시용 데이터에 임의의 고유한 버전 이름을 달아둔다
- If-none-matched 데이터가 변경되면 이 이름을 바꾸어서 변경한다(해쉬값)
- 진짜 단순하게 ETag만 보내서 같으면 유지, 다르면 다시 받기
- 해쉬를 정하는 기준을 주석, 스페이스에 가중치를 두지 않으면 해결!
- 캐시 제어 로직을 서버에서 완전히 관리
- 클라이언트는 캐시 메커니즘을 모름
- 장점
- 캐시 덕분에 캐시 가능 시간동안 네트워크를 사용하지 않아도 된다
- 비싼 네트워크 사용량을 줄일 수 있다
- 빠른 사용자 경험(빠른 브라우저 로딩)
- 캐시 제어 헤더
- Cache-Control
- max-age
- no-cache
- 데이터는 캐시해도 되지만, 항상 원래 서버에 검증하고 사용
- no-store
- 데이터에 민감한 정보가 있으므로 저장하면 안됨
- (메모리에서 사용하고 최대한 빠르게 삭제)
- Pragma - no cahce
- Expires
- 조건부 요청 헤더
- if-match, if-none-match : ETag
- if-modified-since, if-unmodified-since : Last-Modified
- 프록시 캐시
- origin 서버 직접 접근 시 생기는 문제?
- 한국 → 미국 : 너무 느리다
- 프록시 캐시 서버를 어딘가 도입해둔다(한국 어딘가)
- 그래서 처음 접근한 사람이 요청하면 오래 걸리고, 프록시 캐시 서버에 저장
- 이후 접근한 사람은 빠르게 접속한다
- 유투브 같은게 이런식으로 개발되어있다
- cdn access
- 그래서 프록시 캐시를 public 캐시, 브라우저 캐시를 private 캐시라고 한다
- 제어 헤더 Cache-Control
- public
- private
- s-maxage
- age
- origin 서버에서 응답 후 프록시 캐시 내에 머문 시간
- 캐시 무효화
- 확실한 캐시 무효화 응답
- 캐시를 적용 안해도 임의로 캐시를 해버리기도 한다
- 절~대 캐시가 되면 안된다? 하면 이걸 다 넣어주어야한다
- Cache-Control: no-cache, no-store, must-revalidate
- must-revalidate : 캐시 만료 후 최초 조회 시 origin 서버 검증 필요
- origin 서버 접근 실패 시 반드시 오류 발생
- Pragma: no-cache
- no cache vs must-revalidate
- no cache는 origin 서버 검증 과정에서 오류 발생 시 이전 저장된 캐시를 주지만, must-revalidate는 아예 오류를 뱉는다