인터넷 네트워크
인터넷 망을 통해 메세지를 전송하는데 해저 광테이블 ..인공위성 .. 등 수많은 중간 서버(노드)를 거쳐서 건너감
도대체 어떤 규칙으로 ? 수많은 복잡한 상황을 건너 목적지까지 잘 갈 수 있는 것인가? 이걸 이해하기 위해선 먼저 IP에 대한 이해가 필요하다.
IP주소를 통한 규칙
클라이언트가 주소를 부여받아야 한다.
서버도 IP 주소가 있어야 한다.
데이터를 전송하기 전에
출발지 IP, 목적지 IP를 적어야한다.
마찬가지로 출발지 IP, 목적지 IP가 있어야 한다.
클라이언트는 대상 서버가 패킷을 받을 수 있는 상태인지 모름
서버를 거쳐서 전달이 되던 중 중간 서버에 문제가 생겼을때 클라이언트가 보낸 패킷이 유실됨
위와 같은 문제들을 해결하기 위해선 TCP가 필요하다.
IP 패킷 : 덩어리, 버킷 의 합성어
TCP 세그먼트
전송제어 프로토콜
사용자 데이터그램 프로토콜
항구
클라이언트가 게임도 하고 화상통화도 하고 웹브라우저 요청도 하고
이런 경우 클라이언트가 여러 서버와 통신해야 한다.
서버에서 날라온 패킷이 게임인지 화상통화인지 웹브라우저인지 보낼때도 마찬가지로 알수가 없지 않나. 그래서 TCP 패킷 안에 PORT가 있는 것 !
200.200.200.2???
과거 IP와 신규 IP가 다를 수 있고 그러면 클라이언트는 접속할 수 가 없음
도메인 네임 시스템
DNS 서버가 있으면 위 두개의 문제가 해결됨.
URI와 웹 브라우저 요청 흐름
소스를 식별하기 위한 통합된 방법
URI는 로케이터, 이름 또는 둘다 추가로 분류될 수 있다.
URL은 scheme://authority/path/query/fragement
URN은 ResoureName
단어 뜻
Uniform : 리소스 식별하는 통일된 방식
Resource: 자원, URI로 식별할 수 있는 모든 것. 제한 없음
Identifier: 다른 항목과 구분하는데 필요한 정보
URL : Uniform Resource Locator
URN : Uniform Resource Name
스키마
GET /search?q=hello HTTP/1.1
Host: www.google.com
HTTP 기본
HTTP 메시지에 모든 것을 전송
서버 개발자들이 어려워하는 업무
HTTP 메서드
GET /search?q=hello&hi=ko HTTP/1.1
Host:www.google.com
POST /members HTTP/1.1
Content-Type:application/json
POST /members/100 HTTP/1.1
Content-Type:application/json
한번호출하든 두번호출하든 100번 호출하든 결과가 똑같다
GET
PUT
DELETE
POST : 멱등아님 ! 두번호출하면 중복결제 발생
활용 : 자동복구 매커니즘. 서버가 응답을 못했을때 클라이언트의 재요청 여부
HTTP 메서드 활용
데이터 전달 방식은 크게 2가지
정적 데이터 조회
동적 데이터 조회
HTML Form 데이터 전송
HTTP API를 통한 데이터 전송
- 회원가입,상품주문,데이터변경
HTTP 상태코드
HTTP 헤더1 - 일반 헤더
header-field = field-name ":" OWS field-value OWS (OWS:띄어쓰기 허용)
field-name 대소문자 구분 없음
메시지 본문(message body)은 엔티티 본문(entity body)을 전달하는데 사용
• 엔티티 본문은 요청이나 응답에서 전달할 실제 데이터
• 엔티티 헤더는 엔티티 본문의 데이터를 해석할 수 있는 정보 제공
• 데이터 유형(html, json), 데이터 길이, 압축 정보 등등
• 엔티티(Entity) -> 표현(Representation)
• Representation = representation Metadata + Representation Data
• 표현 = 표현 메타데이터 + 표현 데이터
• 메시지 본문(message body)을 통해 표현 데이터 전달
• 메시지 본문 = 페이로드(payload)
• 표현은 요청이나 응답에서 전달할 실제 데이터
• 표현 헤더는 표현 데이터를 해석할 수 있는 정보 제공
• 데이터 유형(html, json), 데이터 길이, 압축 정보 등등
• 참고: 표현 헤더는 표현 메타데이터와, 페이로드 메시지를 구분해야 하지만, 여기서는 생략
• Content-Type: 표현 데이터의 형식
• 미디어 타입, 문자 인코딩
• 예)
• text/html; charset=utf-8
• application/json
• image/png
• Content-Encoding: 표현 데이터의 압축 방식
• 표현 데이터를 압축하기 위해 사용
• 데이터를 전달하는 곳에서 압축 후 인코딩 헤더 추가
• 데이터를 읽는 쪽에서 인코딩 헤더의 정보로 압축 해제
• 예)
• gzip
• deflate
• identity
• Content-Language: 표현 데이터의 자연 언어 ko, en, en-US
• Content-Length: 표현 데이터의 길이
• 표현 헤더는 전송, 응답 둘다 사용
• Accept: 클라이언트가 선호하는 미디어 타입 전달
• Accept-Charset: 클라이언트가 선호하는 문자 인코딩
• Accept-Encoding: 클라이언트가 선호하는 압축 인코딩
• Accept-Language: 클라이언트가 선호하는 자연 언어
• 협상 헤더는 요청시에만 사용
• 단순 전송
• 압축 전송
• 분할 전송
• 범위 전송
• From: 유저 에이전트의 이메일 정보
• Referer: 이전 웹 페이지 주소
• User-Agent: 유저 에이전트 애플리케이션 정보
• Server: 요청을 처리하는 오리진 서버의 소프트웨어 정보
• Date: 메시지가 생성된 날짜
유저 에이전트의 이메일 정보
• 일반적으로 잘 사용되지 않음
• 검색 엔진 같은 곳에서, 주로 사용
• 요청에서 사용
이전 웹 페이지 주소
• 현재 요청된 페이지의 이전 웹 페이지 주소
• 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/86.0.4240.183 Safari/537.36
• 클리이언트의 애플리케이션 정보(웹 브라우저 정보, 등등)
• 통계 정보
• 어떤 종류의 브라우저에서 장애가 발생하는지 파악 가능
• 요청에서 사용
요청을 처리하는 ORIGIN 서버의 소프트웨어 정보
• Server: Apache/2.2.22 (Debian)
• server: nginx
• 응답에서 사용
메시지가 발생한 날짜와 시간
• Date: Tue, 15 Nov 1994 08:12:31 GMT
• 응답에서 사용
• Host: 요청한 호스트 정보(도메인)
• 요청에서 사용
• 필수
• 하나의 서버가 여러 도메인을 처리해야 할 때
• 하나의 IP 주소에 여러 도메인이 적용되어 있을 때
• Location: 페이지 리다이렉션
• Allow: 허용 가능한 HTTP 메서드
• Retry-After: 유저 에이전트가 다음 요청을 하기까지 기다려야 하는 시간
페이지 리다이렉션
• 웹 브라우저는 3xx 응답의 결과에 Location 헤더가 있으면, Location 위치로 자동 이동
(리다이렉트)
• 응답코드 3xx에서 설명
• 201 (Created): Location 값은 요청에 의해 생성된 리소스 URI
• 3xx (Redirection): Location 값은 요청을 자동으로 리디렉션하기 위한 대상 리소스를
가리킴
허용 가능한 HTTP 메서드
• 405 (Method Not Allowed) 에서 응답에 포함해야함
• Allow: GET, HEAD, PUT
유저 에이전트가 다음 요청을 하기까지 기다려야 하는 시간
• 503 (Service Unavailable): 서비스가 언제까지 불능인지 알려줄 수 있음
• Retry-After: Fri, 31 Dec 1999 23:59:59 GMT (날짜 표기)
• Retry-After: 120 (초단위 표기)
• Authorization: 클라이언트 인증 정보를 서버에 전달
• WWW-Authenticate: 리소스 접근시 필요한 인증 방법 정의
클라이언트 인증 정보를 서버에 전달
• Authorization: Basic xxxxxxxxxxxxxxxx
리소스 접근시 필요한 인증 방법 정의
• 리소스 접근시 필요한 인증 방법 정의
• 401 Unauthorized 응답과 함께 사용
• WWW-Authenticate: Newauth realm="apps", type=1,
title="Login to \"apps\"", Basic realm="simple"
• Set-Cookie: 서버에서 클라이언트로 쿠키 전달(응답)
• Cookie: 클라이언트가 서버에서 받은 쿠키를 저장하고, HTTP 요청시 서버로 전달
• HTTP는 무상태(Stateless) 프로토콜이다.
• 클라이언트와 서버가 요청과 응답을 주고 받으면 연결이 끊어진다.
• 클라이언트가 다시 요청하면 서버는 이전 요청을 기억하지 못한다.
• 클라이언트와 서버는 서로 상태를 유지하지 않는다
모든 요청에 정보를 넘기는 문제
• 모든 요청에 사용자 정보가 포함되도록 개발 해야함
• 브라우저를 완전히 종료하고 다시 열면?
• 예) set-cookie: sessionId=abcde1234; expires=Sat, 26-Dec-2020 00:00:00 GMT; path=/; domain=.google.com; Secure
• 사용처
• 사용자 로그인 세션 관리
• 광고 정보 트래킹
• 쿠키 정보는 항상 서버에 전송됨
• 네트워크 트래픽 추가 유발
• 최소한의 정보만 사용(세션 id, 인증 토큰)
• 서버에 전송하지 않고, 웹 브라우저 내부에 데이터를 저장하고 싶으면 웹 스토리지 (localStorage, sessionStorage) 참고
• 주의!
• 보안에 민감한 데이터는 저장하면 안됨(주민번호, 신용카드 번호 등등)
• Set-Cookie: expires=Sat, 26-Dec-2020 04:39:21 GMT
• 만료일이 되면 쿠키 삭제
• Set-Cookie: max-age=3600 (3600초)
• 0이나 음수를 지정하면 쿠키 삭제
• 세션 쿠키: 만료 날짜를 생략하면 브라우저 종료시 까지만 유지
• 영속 쿠키: 만료 날짜를 입력하면 해당 날짜까지 유지
• 예) domain=example.org
• 명시: 명시한 문서 기준 도메인 + 서브 도메인 포함
• domain=example.org를 지정해서 쿠키 생성
• example.org는 물론이고
• dev.example.org도 쿠키 접근
• 생략: 현재 문서 기준 도메인만 적용
• example.org 에서 쿠키를 생성하고 domain 지정을 생략
• example.org 에서만 쿠키 접근
• dev.example.org는 쿠키 미접근
• 예) path=/home
• 이 경로를 포함한 하위 경로 페이지만 쿠키 접근
• 일반적으로 path=/ 루트로 지정
• 예)
• path=/home 지정
• /home -> 가능
• /home/level1 -> 가능
• /home/level1/level2 -> 가능
• /hello -> 불가능
• Secure
• 쿠키는 http, https를 구분하지 않고 전송
• Secure를 적용하면 https인 경우에만 전송
• HttpOnly
• XSS 공격 방지
• 자바스크립트에서 접근 불가(document.cookie)
• HTTP 전송에만 사용
• SameSite
• XSRF 공격 방지
• 요청 도메인과 쿠키에 설정된 도메인이 같은 경우만 쿠키 전송
HTTP 헤더2 - 캐시와 조건부 요청
• 데이터가 변경되지 않아도 계속 네트워크를 통해서 데이터를 다운로드 받아야 한다.
• 인터넷 네트워크는 매우 느리고 비싸다.
• 브라우저 로딩 속도가 느리다.
• 느린 사용자 경험
• 캐시 덕분에 캐시 가능 시간동안 네트워크를 사용하지 않아도 된다.
• 비싼 네트워크 사용량을 줄일 수 있다.
• 브라우저 로딩 속도가 매우 빠르다.
• 빠른 사용자 경험
• 캐시 유효 시간이 초과하면, 서버를 통해 데이터를 다시 조회하고, 캐시를 갱신한다.
• 이때 다시 네트워크 다운로드가 발생한다.
• 캐시 유효 시간이 초과해서 서버에 다시 요청하면 다음 두 가지 상황이 나타난다.
1. 서버에서 기존 데이터를 변경함
2. 서버에서 기존 데이터를 변경하지 않음
• 캐시 만료후에도 서버에서 데이터를 변경하지 않음
• 생각해보면 데이터를 전송하는 대신에 저장해 두었던 캐시를 재사용 할 수 있다.
• 단 클라이언트의 데이터와 서버의 데이터가 같다는 사실을 확인할 수 있는 방법 필요
-> Last-Modified : 2020.11.10.10:10:10 검증할 수 있는 값
-> if-modified-since : 2020.11.10.10:10:10
-> 데이터가 아직 수정되지 않았다.
• 캐시 유효 시간이 초과해도, 서버의 데이터가 갱신되지 않으면
• 304 Not Modified + 헤더 메타 정보만 응답(바디X)
• 클라이언트는 서버가 보낸 응답 헤더 정보로 캐시의 메타 정보를 갱신
• 클라이언트는 캐시에 저장되어 있는 데이터 재활용
• 결과적으로 네트워크 다운로드가 발생하지만 용량이 적은 헤더 정보만 다운로드
• 매우 실용적인 해결책
• 검증 헤더
• 캐시 데이터와 서버 데이터가 같은지 검증하는 데이터
• Last-Modified , ETag
• 조건부 요청 헤더
• 검증 헤더로 조건에 따른 분기
• If-Modified-Since: Last-Modified 사용
• If-None-Match: ETag 사용
• 조건이 만족하면 200 OK
• 조건이 만족하지 않으면 304 Not Modified
• If-Modified-Since: 이후에 데이터가 수정되었으면?
• 데이터 미변경 예시
• 캐시: 2020년 11월 10일 10:00:00 vs 서버: 2020년 11월 10일 10:00:00
• 304 Not Modified, 헤더 데이터만 전송(BODY 미포함)
• 전송 용량 0.1M (헤더 0.1M, 바디 1.0M)
• 데이터 변경 예시
• 캐시: 2020년 11월 10일 10:00:00 vs 서버: 2020년 11월 10일 11:00:00
• 200 OK, 모든 데이터 전송(BODY 포함)
• 전송 용량 1.1M (헤더 0.1M, 바디 1.0M)
• 1초 미만(0.x초) 단위로 캐시 조정이 불가능
• 날짜 기반의 로직 사용
• 데이터를 수정해서 날짜가 다르지만, 같은 데이터를 수정해서 데이터 결과가 똑같은 경우
• 서버에서 별도의 캐시 로직을 관리하고 싶은 경우
• 예) 스페이스나 주석처럼 크게 영향이 없는 변경에서 캐시를 유지하고 싶은 경우
• 진짜 단순하게 ETag만 서버에 보내서 같으면 유지, 다르면 다시 받기!
• 캐시 제어 로직을 서버에서 완전히 관리
• 클라이언트는 단순히 이 값을 서버에 제공(클라이언트는 캐시 메커니즘을 모름)
• 예)
• 서버는 배타 오픈 기간인 3일 동안 파일이 변경되어도 ETag를 동일하게 유지
• 애플리케이션 배포 주기에 맞추어 ETag 모두 갱신
• Cache-Control: 캐시 제어
• Pragma: 캐시 제어(하위 호환)
• Expires: 캐시 유효 기간(하위 호환)
캐시 지시어
• Cache-Control: max-age
• 캐시 유효 시간, 초 단위
• Cache-Control: no-cache
• 데이터는 캐시해도 되지만, 항상 원(origin) 서버에 검증하고 사용
• Cache-Control: no-store
• 데이터에 민감한 정보가 있으므로 저장하면 안됨
(메모리에서 사용하고 최대한 빨리 삭제)
캐시 제어(하위 호환)
• Pragma: no-cache
• HTTP 1.0 하위 호환
캐시 만료일 지정(하위 호환)
• expires: Mon, 01 Jan 1990 00:00:00 GMT
• 캐시 만료일을 정확한 날짜로 지정
• HTTP 1.0 부터 사용
• 지금은 더 유연한 Cache-Control: max-age 권장
• Cache-Control: max-age와 함께 사용하면 Expires는 무시
• 검증 헤더 (Validator)
• ETag: "v1.0", ETag: "asid93jkrh2l"
• Last-Modified: Thu, 04 Jun 2020 07:19:24 GMT
• 조건부 요청 헤더
• If-Match, If-None-Match: ETag 값 사용
• If-Modified-Since, If-Unmodified-Since: Last-Modified 값 사용
캐시 지시어(directives) - 기타
• Cache-Control: public
• 응답이 public 캐시에 저장되어도 됨
• Cache-Control: private
• 응답이 해당 사용자만을 위한 것임, private 캐시에 저장해야 함(기본값)
• Cache-Control: s-maxage
• 프록시 캐시에만 적용되는 max-age
• Age: 60 (HTTP 헤더)
• 오리진 서버에서 응답 후 프록시 캐시 내에 머문 시간(초)
확실한 캐시 무효화 응답
• Cache-Control: no-cache, no-store, must-revalidate
• Pragma: no-cache
• HTTP 1.0 하위 호환
캐시 지시어(directives) - 확실한 캐시 무효화
• Cache-Control: no-cache
• 데이터는 캐시해도 되지만, 항상 원 서버에 검증하고 사용(이름에 주의!)
• Cache-Control: no-store
• 데이터에 민감한 정보가 있으므로 저장하면 안됨
(메모리에서 사용하고 최대한 빨리 삭제)
• Cache-Control: must-revalidate
• 캐시 만료후 최초 조회시 원 서버에 검증해야함
• 원 서버 접근 실패시 반드시 오류가 발생해야함 - 504(Gateway Timeout)
• must-revalidate는 캐시 유효 시간이라면 캐시를 사용함
• Pragma: no-cache
• HTTP 1.0 하위 호환