HTTP에 대한 이론
컴퓨터는 어떻게 통신할 까?
IP 컴퓨터 끼리 통신하려면 서로의 IP를 통해 통신한다.
- 인터넷 프로토콜의 역할
- 지정 IP 주소에 데이터 전달
- 패킷 단위로 데이터 전달
- 내 IP랑 목적지 IP 같은거랑 데이터랑 묶어서 던진다
IP 프로토콜의 한계
- 비연결성 : 패킷을 받을 대상이 없거나 서비스 불능이여도 패킷을 전송한다
- 비신뢰성 : 중간에 패킷이 사라지거나, 순서대로 오지 않으면?
- 프로그램 구분 : 같은 IP를 사용하는 서버에서 통신하는 애플리케이션이 둘 이상이면??
-> TCP, UDP에 대해 알아보자
- 애플리케이션 (HTTP,FTP)
- 전송 계층 (TCP, UDP)
- 인터넷 계층 (IP)
- 네트워크 인터페이스 계층
전송 제어 프로토콜
신뢰할 수 있는 프로토콜이다
- 연결지향 - TCP 3 way handshake (가상연결)
- 클라이언트 SYN -> 안녕~
- 클라이언트 <- SYN+ ACK 서버 :( 클라이언트야 안녕~, 나도 안녕~)
- ACK -> (서버야 반가워~)
- 자 데이터야
- 데이터 전달 보증
- 순서 보장 ( 전송 제어, 순서 정보를 통해)
데이터가 순서를 보장하고 손실없이 와야 끝난다. 만약에 작은 손실이 나도 무조건 다시 실행한다.
사용자 데이터그램 프로토콜
- 그냥 보내고 전달 보증안하고 순서도 보장안한다.
- PORT + 체크섬 정도 추가
- 단순하고 빠르다.
한번에 둘 이상 연결해야하면 어떻게 할까?(웹브라우저도 쓰고, 게임도 하고 있고 ,화상통화도 하는 중임)
패킷이 날라오면 이게 어떤 애플리케이션꺼인지를 모름
- 출발지 PORT, 도착지 PORT를 통해 구분한다.
- IP(아파트) PORT(몇동 몇호)
IP주소를 통해서 통신하는데 이거를 기억할 수 있나요?? naver 들어가는데 naver 서버의 IP주소를 치고 들어간다고 생각해보자… 답답하다
- 전화번호부라고 생각하자
- DNS에 도메인 이름을 넣으면 해당 이름의 IP 주소를 반환해준다.
URI(URL,URN) : 식별할 때 위치로 식별, 이름으로 식별
- 리소스를 식별하는 통일된 방식
- 자원, URI로 식별할 수 있는 모든 것
- 다른 항목과 구분하는데 필요한 정보
- scheme://[userinfo@]host[:port][/path][?query][# fragment]
- 쿼리는 key=value , ?로 시작하며 &로 추가
-
DNS 서버를 조회(포트 정보도 확인) -> HTTP 요청 메세지 작성 (GET/search?q=hello … , host: www.google.com..
-
소켓 라이브러리를 통해 전달(TCP/IP 연결, 데이터 전달)
-
TCP/IP 패킷 생성(데이터 포함 -> HTTP 메세지)
-
HTTP 응답 메세지를 만든다
-
응답 패킷을 전송한다
- 클라이언트는 서버에 요청을 보내고 응답을 대기한다
- 서버가 요청에 대한 결과를 만들어서 응답한다
무상태 프로토콜
- 서버가 클라이언트의 상태를 유지하지 않는다
- 무상태는 응답 서버를 쉽게 바꿀 수 있다 -> 무한한 서버 증설이 가능하다
하지만 모든 것을 무상태로 설계할 수 는 없다
- 로그인 상태 유지
- 일반적으로는 브라우저 쿠기와 서버의 세션 등을 사용해서 상태를 유지한다
- 상태 유지는 최소한만 사용한다.
- HTTP는 기본이 연결을 유지하지 않는 모델이다
- 일반적으로 초 단위 이하의 빠른 속도로 응답한다.
- 서버 자원을 매우 효율적으로 사용할 수 있다.
하지만 이 것들이 계속 반복된다고 하자.
- TCP/IP 연결을 새로 맺어야 한다(3-way)
- 웹 브라우저로 사이트를 요청하면 HTML 뿐만 아니라 수 많은 자원이 함께 다운로드 된다
- 지금은 HTTP 지속 연결(Persistent Connections)로 문제를 해결한다
초기
HTTP 지속 연결
첫 페이지에 트래픽이 너무 쏠린다 -> 첫 페이지를 정적 페이지로 설계를 해서 텀을 만든다
- start-line 시작 라인 : request line / status line
- 요청 메시지/요청 대상/HTTP버전이 들어간다
- header 헤더 : HTTP 전송에 필요한 모든 부가정보를 넣는다
- empty line
- message Body : 실제 전송할 데이터를 넣는다
API URI 설계 리소스 식별하는 것이 주 포인트!
- URI를 만들 때 member-view, member-delete 이렇게 만들면 안되고
- 행위는 헤더에 담고 리소스는 회원이다
리소스와 해당 리소스를 대상으로 하는 행위를 분리하자
- GET : 리소스 조회
- 서버에 전달하고 싶은 데이터는 query를 통해서 전달한다
- 메세지 바디를 사용해서 데이터를 전달할 수 있지만, 권장하지는 않는다
- POST: 요청 데이터 처리, 주로 등록에 사용
- 메세지 바디를 통해 서버로 요청 데이터 전달
- 신규 리소스 등록(신규리소스 아이디)
- 프로세스를 처리해야 하는 경우
- 요청 데이터를 어떻게 처리할지 리소스마다 따로 정해야한다
- PUT : 리소스를 대체, 해당 리소스가 없으면 생성
- 덮어버린다고 생각하자
- 클라이언트가 리소스 위치를 알고 URI를 지정한다
- 그냥 기존 리소스를 없애고 넣는다고 생각하면 편함
- PATCH : 리소스 부분 변경
- PATCH로 하면 내가 부분적으로 변경할 수 있다.
- DELETE: 리소스 삭제
- 호출해도 리소스를 변경하지 않는다
- 몇 번 호출하던 결과가 동일하다.
- 자동 복구 매커니즘
-
응답 결과 리소스를 캐시해서 사용해도 되는가
-
GET,HEAD 정도만 가능
-
정적 데이터 조회 : 이미지, 정적 텍스트 문서, 조회는 GET 사용, 정적 데이터는 일반적으로 쿼리 파라미터 없이 리소스 경로로 단순하게 조회 가능
-
동적 데이터 조회: 쿼리 파라메터 사용: 주로 검색, 게시판 목록, 조회 조건을 줄여주는 필터, 조회는 GET 사용
- 클라이언트는 등록될 리소스의 URI를 모른다.
- 서버가 새로 등록된 리소스 URI를 생성한다
- 컬렉션 : 서버가 관리하는 리소스 디렉토리
- 파일 등록 시 /files/{filename} 형식으로 PUT
- 클라이언트가 리소스 URI를 알고있어야한다.
- 직접 리소스의 URI를 지정한다
- 스토어 : 클라이언트가 관리하는 리소스 디렉토리
- GET,POST만 사용가능하므로 이러한 제약을 해결하기 위해 동사로 된 리소스 경로를 사용한다
- POST의 /new, /edit, /delete
- 1xx : 요청이 수신되어 처리 중 -> 거의 사용하지 않음
- 2xx : 요청 정상 처리
- 200: OK,
- 201 : Created ,요청을 처리해서 새로운 리소스가 생성됨
- 202 : Accepted : 요청이 접수됐으나 처리가 완료되지 않음
- 204 : No Content : 서버가 요청을 성공적으로 수행했지만, 응답 바디에 데이터가 없음
- 3xx : 요청을 완료하려면 추가 행동이 필요, 응답의 결과에 Location이 있으면 해당 URI로 이동한다.
- 영구 리다이렉션 : 특정 리소스의 URI가 영구적으로 이동
- 원래 URL를 사용 X
- 301(GET으로 변하고,본문이 제거될수있음),
- 308(원래 요청과 본문을 유지)
- 일시 리다이렉션 : 일시적인 변경, 주문 완료 후 주문 내역 화면으로 이동
- 302 : 301과 비슷
- 307 : 308처럼 요청과 본문을 유지
- 303 : 요청 메서드가 GET으로 변경
- PRG : POST/Redirect/Get : POST로 주문후에 웹 브라우저를 새로고침하면 -> 다시 요청 -> 다시 주문될수있음(만약에 영구 유지라고 하면)
- POST로 주문 후 주문 결과를 GET 메소드로 리다이렉트를 한다 (새로 고침해도 GET이 나옴)
- 304 : 캐시를 목적으로 사용, 클라이언트에게 리소스가 수정되지 않았음을 알려준다. 따라서 클라이언트는 로컬 PC에 저장된 캐시를 재사용한다
- 영구 리다이렉션 : 특정 리소스의 URI가 영구적으로 이동
- 4xx : 클라이언트 오류, 잘못된 문법
- 오류의 원인이 클라이언트
- 재시도해도 똑같이 실패함
- 400 Bad Request :요청 구문,메세지 등의 오류
- 401 Unauthorized : 클라이언트가 해당 리소스에 대한 인증이 필요하다.WWW-Authenticate 헤더와 함께 인증 방법을 설명
- 403 Forbidden : 인증 자격 증명은 있지만, 접근 권한이 불충분하다
- 404 Not Found : 요청 리소스가 서버에 없다 또른 권한이 부족한 리소스에 접근할 때 해당 리소스를 숨기고 싶을 경우
- 5xx : 서버 오류, 정상 요청을 처리하지 못함
- 서버에 문제가 있기 때문에 재시도 하면 성공할 수도 있다
- 500 : 서버 내부 문제로 오류 발생
- 503 : 서비스 이용 불가
- HTTP 전송에 필요한 모든 부가정보
- HTTP body: 엔티티 헤더는 엔티티 본문의 데이터를 해석할 수 있는 정보를 제공한다.
- 엔티티 -> 표현
- 표현 메타데이터와 표현 데이터
- 메세지 본문 -> PayLoad
- 요청을 표현한다
- 클라이언트가 선호하는 표현 요청
- 협상 헤더는 요청 시에만 사용한다
- Accept {Language} {encoding} {charset}
- Quality Values(q)를 사용해서 내가 원하는 우선순위 대로 받아온다.(클수록 높은 순위)
- 구체적인 것이 우선한다
- 단순 전송 : Content-Length
- 압축 전송 : Content-Encoding
- 분할 전송 : Transfer-Encoding
- 범위 전송 : Range, Content-Range
- Form : 유저 에이전트의 이메일 정보
- Referer : 이전 웹 페이지의 주소
- User-Agent : 유저 에이전트 애플리케이션 정보, 통계 정보, 어떤 종류의 브라우저에서 장애가 발생하는지 파악 가능
- Server : 요청을 처리하는 ORIGIN 서버의 소프트웨어 정보,
- Date: 메세지가 발생한 시간
-
Host : 요청에서 사용 필수 , 하나의 서버가 여러 도메인을 처리할 때.
- 가상 호스트에 여러개의 서버 도메인이 구성 될 수 있다.
- 그러면 요청이 오면 어떤 도메인으로 들어가야할지를 모른다.
- 이를 해결하기 위해 Host 헤더 필드를 추가해서 넣는다.
-
Location : 페이지 리다이렉션
-
Allow : 허용 가능한 HTTP 메소드
-
Retry-After : 유저 에이전트가 다음 요청을 하기까지 기다려야하는 시간
-
Authorization : 클라이언트 인증 정보를 서버에 전달
-
WWW-Authenticatae : 리소스 접근 시 필요한 인증 방법 정의
- Set-Cookie : 서버에서 클라이언트로 쿠키 전달
- HTTP 는 무상태 프로토콜이다
- 클라이언트가 다시 요청하면 서버는 이전 요청을 기억하지 못한다. 즉 서로 상태를 유지하지 않는다
- 대안으로 모든 요청에 사용자 정보를 포함한다
- 보안 문제와 모든 요청에 포함하면 힘들다
- 이걸 해결하기 위해 쿠키를 사용한다
- 최초 로그인 시 쿠키를 만들어서 쿠키 저장소에 넣는다.
- 로그인 이후 쿠키를 포함해서 헤더를 만들어 넣는다
- 사용처 : 사용자 로그인 세션 관리, 광고 정보 트래킹
- 쿠키 정보는 항상 서버에 전송된다
- 네트워크 트래픽 추가 유발
- 최소한의 정보만 사용한다
- 서버에 전송하지 않고, 웹 브라우저 내부에 데이터를 저장하고 싶으면 웹 스토리지를 사용한다
- 캐시가 없을 경우: 요청할때마다 서버에서 온다. 즉, 계속 네트워크를 통해서 데이터를 다운로드해야한다
- 캐시를 적용해서 브라우저 캐시에 설정 값(유효시간) 대로 브라우저 캐시에 저장한다(응답 결과를)
- 만약에 캐시 시간이 초과되면 다시 서버에서 받아온다. 다시 받아온 걸 브라우저 캐시에 넣는다.
- 서버에서 기존 데이터를 변경함
- 서버에서 기존 데이터를 변경하지 않음
- 저장해두었던 데이터를 다시 사용할 수 있다
- 하지만 데이터의 변경 여부를 확인해야 한다.
- Last-Modified의 값이 서버랑 브라우저 캐시꺼랑 동일하면 수정이 안된거라서 서버에 확인 요청 시 응답에 HTTP body가 없다
- Last-Modified : 1초 미안으로 캐시 조정이 불가능하다, 날짜 기반의 로직을 사용하기 때문.
- ETag(Entity Tag) : 임의의 고유한 버전 이름을 달아둔다. 데이터가 변경되면 이 이름을 바꾸어서 변경한다. 그 뒤로 단순하게 비교해서 같으면 유지, 다르면 다시 받기
- 데이터가 미변경되면 ,304 Not Modified
- 데이터가 변경되었다면 : 200 OK
- 웹 브라우저랑 원 서버랑의 거리가 멀다고 하면 중간에(한국 어딘가)에 프록시 캐시 서버를 둘 수 있다.
- private 캐시 : 웹 브라우저 내 캐시
- public 캐시 : 프록시 캐시 서버
- Cache-Control : no-cachce(캐시는 사용해도 되는데 사용할 때 원서버에 검증), no-store (데이터에 민감한 정보가 있어서 빨리 삭제),must-revalidate
- Pragma : no-cache
- 다 넣어서 해결하자