본문 바로가기

CS/Computer Network

[네트워크] Ch2.2 Web과 HTTP

 

본 글은 학교 네트워크 수업을 들으며, "Computer Networking: A Top-Down Approach 8ed(컴퓨터 네트워킹: 하향식 접근 제8판)"을 기반으로 공부한 내용을 정리한 글입니다.

 

Ch2.2 Web과 HTTP

- 웹 페이지는 `object`와 이들을 묶은 `base HTML-file`로 이루어져 있음.

- object는 HTML file, JPEG image 등 모든 걸 말함.

URL(Uniform Resource Locator)

- 각 object들은 URL을 통해 접근 가능함.

- `host name`과 `path name`으로 이루어져 있음.

ex. cuffyluv.tistory.com/21의 경우는, `cuffyluv.tistory.com`가 host name, `/21`가 path name


HTTP Overview

HTTP(HyperText Transfer Protocol)

- 앞서 살펴본 object들을 통해 브라우저 표현을 지원해주는 프로토콜임.

- 어플리케이션 레이어의 웹 프로토콜.

 

- Client-Server 모델임.

- `client(browser)` : request보내고, response받고, web object들을 사용자에게 보여주는 역할을 함.

- `server(Web server)` : client가 보낸 request을 보고 그에 따른 response를 보내줌.

 

History of HTTP

가볍게 읽자.

- 1963년에 `hypertext`(하이퍼링크를 사용한 비선형적 텍스트)라는 단어가 등장.

- 1989년에 WWW 프로젝트가 발표됨.

- 1991년에 WWW(Nexus)라는 첫 번째의 웹 브라우저가 나왔는데, 이 때의 문서 버전에 따라 이를 `HTTP/0.9`라고 부름.

- 1993년에 Mosaic이라는 편하게 쓸 수 있는 웹 브라우저가 발표됨. 이 때부터 웹 사이트 수가 유의미하게 늘기 시작.

- 1996년에 `HTTP/1.0` 발표

- 1997년에 `HTTP/1.1` 발표

- 2015년에 `HTTP/2` 발표

 

이제 여기까지는 TCP를 사용했음. object라는 파일을 전송하는 데 있어서, loss에 민감하기에 TCP를 사용한거임.

대신 당연히 통신 overhead가 컸고, TCP의 한계에서 벗어나지 못했음.

그래서, 아래에 QUIC부터는 UDP를 사용함.

 

- 2021년에 `QUIC` 발표

- 2022년에 QUIC을 기반으로 하여 개발된 `HTTP/3` 발표


HTTP Connections

HTTP는 TCP 위에서 작동함.

- object들이 file 단위로 되어있으니까, loss를 최소화하기 위해서 TCP를 사용하는 거임.

- 이 때, TCP가 연결을 수립할 때 SYN 세그먼트를 주고받는 행위를 `three way handshake`라 부름.

- `RTT(round trip time)` : 하나의 작은 패킷이 간 후에 그 response가 돌아오기까지의 시간

Non-persistent HTTP

- 만약 HTTP가 non-persistent하다면, 매 HTTP request 및 response마다 연결을 열고 닫고 열고 닫고 해야함.

- 연결 수립, 종료 오버헤드로 인해 보낼 패킷이 많아지면 비효율적임.

Persistent HTTP

- 우리가 현재 쓰는 HTTP는 persistent

- 서버는 response를 보낸 후에도 계속 연결을 유지해둠.

- 보낼 패킷이 많아져도 괜찮음.

 


HTTP Message - Format

2가지 유형의 HTTP 메시지가 있음

- request(요청)

- response(응답)

HTTP message는 모두 아스키 텍스트로 작성되어, 사람이 읽고 이해할 수 있음.

Request

request line

: 요청의 첫 번째 줄로, method, URL, version으로 나뉨.

- method : 클라이언트가 서버에 요청하는 작업의 유형을 나타냄. `GET`, `POST` 등이 쓰임.

`GET` : 주어진 URL을 사용하는 서버로부터 정보를 가져오겠다.

`POST` : 서버에게 데이터를 전송하겠다. ex. 파일 업로드

- URL : 클라이언트가 요청하는 리소스의 위치를 나타내는 주소.

- version : 사용 중인 http 프로토콜 버전을 나타냄.

* cr lf는 캐리지 리턴 + 라인 피드로, 줄바꿈을 의미

header lines

: 요청 또는 응답에 대한 추가 정보를 제공하는 `키-값(header field name-value) 쌍`의 목록임. `Host`, `User-Agent` 등이 있음.

- `Host` : 요청한 서버의 도메인 명

- `User-Agent` : 요청 클라이언트의 OS나 브라우저 등의 정보.

=> 해커가 해당 버전의 취약점 가진 object file 전송 가능

body

: 실제 데이터가 포함된 부분. 예를 들어, POST 요청에서 전송할 데이터가 포함될 수 있음. GET 요청에서는 일반적으로 body가 없음.

 

Response

status line

: 응답의 첫 번째 줄로, version, status code, phrase로 나뉨.

- version : 서버가 사용하고 있는 http 프로토콜 버전을 나타냄.

- status code : 요청의 처리 결과를 나타내는 3자리 숫자임.

기본적으로 `100번 대`는 요청이 처리중이라는 의미, `200 300번대`는 요청이 성공했다는 의미, `400 500번대`는 요청이 실패했다는 의미임.

- phrase : 상태 코드를 설명하는 짧은 메시지로 가독성을 높임. 예를 들어 200은 `OK`가 출력됨.

 

`100번대` : "네 request를 성공적으로 받았고, 해당 request를 처리 중이니 안심하고 기다려라."

 

`200번대` : "네 request를 성공적으로 받았고, 해당 requset를 성공적으로 accept했다."
ex. 200 OK - 요청이 성공했고, 정보가 응답으로 보내졌다.

 

`300번대` : "네 request를 완료하기 위해선 더 action이 필요하다."

ex. 301 Moved Permanetly - 성공이긴 한데, 너가 직접 request넣은 서버가 아닌 다른 서버에서 request를 받았음. 그 '다른 서버'는 이 메시지의 Location: 헤더에 나와 있음.

 

`400번대`(Client Error) : "네 request가 잘못된 문법을 포함하고 있거나 다 채워져있지가 않다."

ex. 404 Not Found - 네가 request한 문서가 이 서버에는 없음.

 

`500번대`(Server Error) : "서버가 너의 request를 처리하기 위한 조건을 충족하지 못한다."

ex. 505 HTTP Version Not Supported. - 네 요청 HTTP 버전을 서버가 지원하지 않음. 너는 HTTP 1.1이나 1.2 같은 걸로 서비스받기를 원하는데, 이 서버는 지금 HTTP 1.0만 지원해서 안된다.

 

header lines

: request 경우와 설명 동일. Server, Date 등이 있음.

=> 마찬가지로 해커가 해당 버전의 취약점 가진 object file 전송 가능

body

: request 경우와 설명 동일


HTTP Performance Improvements

HTTP의 성능(즉, 응답 속도)를 향상시키기 위한 방법엔 3가지가 있음.

- `Cookie`는 서버와 클라이언트의 상호작용을 해서 응답속도를 높이겠다.

- `Proxy`는 서버의 구조를 변경시키겠다.

- `Conditional GET`는 클라이언트의 기능을 활용하겠다.


HTTP Cookie

- HTTP는 `stateless`함 : 서버는 클라이언트의 이전 요청에 대한 정보를 유지하지 않음. 

=> 그러니, 서버에 state DB 같은 걸 설치해, 이전 클라이언트의 요청을 저장할 수 있게끔 해서 stateful한 기능을 추가시켜보자!!

 

HTTP Cookie

유저가 그 웹사이트에 방문할 때마다 웹 사이트로부터 받아서 유저 웹 브라우저에 저장해둠.

- stateful한 정보를 기억(ex. `장바구니`)

- 유저의 브라우징 활동을 기록(ex. `로그인 기록`, `방문 기록`, ...)

- 이러한 cookie는 웹 사이트가 유저에 대한 많은 정보들을 저장해줄 수 있게 하므로, 프라이버시 침해 문제가 있을 수 있음.

 

HTTP Cookie 작동 과정

1. 처음에 일반적인 HTTP request로 서버에게 요청을 보냄. 이 때는 쿠키가 아직 없을 수도 있음. 이 때, 처음이면은 내 id같은걸 입력해서 서버한테 보내겠지.

 

2. 서버가 쿠키 만들고 싶어졌다? 아니면 서버에 이미 만들어져 있는 쿠키를 클라이언트한테 보내고 싶다?

=> 그러면 클라이언트한테 쿠키를 설정하라고 `Set-Cookie: session_id=abc123; Expires=Wed, 01 Feb 2025 12:00:00 GMT;` 같은 식으로 HTTP response를 보내줌. 그럼 해당 정보가 클라이언트의 웹 브라우저에 저장됨.

- 한 번 이렇게 쿠키가 설정되고 나면, 유저가 다시 그 웹사이트에 방문할 때마다 저장된 cookie(state)를 서버로부터 받을 수 있음.

=> 유저는 자기 이름, 신용카드번호, 주소 같은 걸 재입력할 필요가 없음.

 

3. 이후, 클라이언트는 서버한테 메시지를 보낼 때마다 `Cookie: session_id=abc123`같은 식으로 내 cookie 정보를 명시하며 보내줌. '내가 당신이 설정한 쿠키를 가지고 있으니, 이걸 참고해서 처리하세요' 하는 의미.

 

4. 그럼 서버는 이 request의 쿠키를 보고 자기 DB랑 비교해서 처리 후 적절한 응답을 반환할 수 있음.


Proxy Server(= Web Cache)

- original server 기능을 대신해주는 서버.

목적 : `origin server`의 부담을 줄여주고 싶으니까, origin server가 관여하지 않은 채 `proxy server`로 클라이언트의 request를 처리하고 싶은 거임.

 

- 이 서버엔 origin server로부터 복사해온 내용이 저장된 own disk storage가 존재.

- 동시에 클라이언트와 서버 역할을 둘다 함.

IF. 클라이언트가 요청한 object가 프록시 서버에 없다? (Cache miss)

=> 그러면 프록시 서버가 origin 서버한테 그 object 달라고 똑같이 요청 보냄. 이후 클라이언트한테 응답.

IF. 클라이언트가 요청한 object가 프록시 서버에 있다? (Cache hit) 

=> 그러면 origin 서버랑 무관하게, 프록시 서버에 있는 object 클라이언트한테 응답.

=> 이는 메모리 계층 구조의 Cache와 동일한 작동 방식!! 따라서 Web Cache라고도 부르는 것.

- 이런 프록시 서버는 보통 ISP가 설치해서, 외부 네트워크와 연결되기 바로 직전 지점에 주로 설치됨. 

ex. 포탈, 회사, 대학, ...

 

Proxy Server(Web Cache)의 사용 이유

1. 클라이언트의 요청에 대한 반응 시간을 줄여줌. 병목 현상이 심할 수록 그 효과가 더 큼.

2. 기관의 access link(외부 네트워크와 연결되는 저 지점)에 부과되는 트래픽을 줄여줌. 즉, 어떤 기관에서 인터넷에 접속하는 총 웹 트래픽을 줄여줌. 따라서 기관은 자주 대역폭을 개선할 필요가 줄어들어 비용 절감 가능.

3. 인터넷 전체의 웹 트래픽을 실질적으로 줄여주어 모든 애플리케이션의 성능이 좋아짐.

만약 Access link에 병목 현상이 일어나 이를 개선하고 싶을 때,

- Solution 1: `대역폭을 100배` 늘림 -> 성능 향상은 확실하나, 비쌈!!!

- Solution 2: `local web cache`를 설치 -> 합리적인 가격에 적당한 성능 향상을 제공~!~!!


Conditional GET

- 웹 캐싱은 사용자가 느끼는 응답 시간을 줄일 순 있으나, `웹 캐시 내부에 있는 object 복사본이 up-to-date version이 아닐 수 있다`는 단점이 있다.

- 따라서, 우리는 `내가 가진 object가 up-to-date가 아닐 때는 새로운 version의 object을 받아오고, up-to-date일 때는 받아오지 않는` 시스템을 구축하고 싶음.

- 이러한 '브라우저로 전달되는 모든 객체가 최신의 것임을 클라이언트가 확인하면서 캐싱을 하게 해주는 기술'을 `Conditional GET` 이라고 한다. (어떻게 보면, 웹 캐시와 클라이언트 <-> 웹 서버 이렇게 2개의 집합 구조임)

 

Conditional GET의 작동 과정

1. 웹 캐시는 클라이언트(브라우저)를 대신해 그 요청을 웹 서버로 보냄.

 

2. 웹 서버는 캐시에게 object를 포함한 응답 메시지를 보냄.

이 때, `Last-Modified: Wed, 9 Sep 2015 09:23:24`와 같은 헤더 라인을 포함해서 보냄.

 

3. 웹 캐시는 브라우저에게 object를 보내주고 자신의 dist storage에도 object를 저장함.

 

4. 이후에 다른 브라우저가 같은 object를 웹 캐시에 요청할 때, 브라우저는 Conditional GET을 사용해 요청을 보냄.

즉, `If-modified-since: Wed, Wed, 9 Sep 2015 09:23:24`와 같은 헤더 라인을 포함해서 보냄. 이는 웹 캐시를 통해 웹 서버에 전달됨.

 

5. 만약 그 object가 웹 서버에서 변경되지 않았다면, 웹 서버는 웹 캐시의 캐싱된 복사본을 사용해도 된다는 의미의 응답 메시지를 클라이언트에게 보냄.(아마 웹 캐시에 보내지는 것 같음)

이는 `304 Not Modified`, `Date: ~~~(현재 날짜)` 와 같은 내용들을 포함함. 여기서 object를 같이 보내주지 않는다는게 중요. object는 웹 캐시에서 보내주는 거 알아서 쓰라는 거임.

 

6. 만약 그 object가 수정되었다면

`200 OK`와 함께 `<data>`를 보내줌. 니꺼 수정해야 하니까 직접 데이터를 보내줄게~~


HTTPS (HTTP Secure)

- 앞서 언급했듯이, HTTP 메시지들은 아스키 텍스트로 작성되었기 때문에, 누구든지 와이어샤크 같은걸로 패킷 가로채서 읽고 악용할 수 있음.

- 그래서 HTTP 메시지를 암호화해서 사람이 이해할 수 없도록 만들고자 함.

- 게다가, HTTP에는 내가 누구랑 패킷을 주고받고 있는지 그 사용자 인증 기능같은 게 존재하지도 않음.

=> 따라서, HTTPS를 적용해 통신을 Secure하게 만들자!!

 

HTTPS

- HTTPS는 HTTP의 익스텐션으로, 통신을 secure하게 만들어 줌.

- HTTP와 TCP 사이에 `TLS(Transport Layer Security)` 또는 `SSL`이라는 sublayer를 추가함. (요즘은 TLS 씀)

https://hpbn.co/transport-layer-security-tls/

- 오른쪽과 같이, `TCP connection establish(TCP 3-way handshake)` 이후에, `TLS connection establish(TLS handshake)`을 2번 걸쳐 수행함.

- 결국, HTTP 메시지 교환 시작 전까지 3RTT가 소요됨.

 

- 이제 HTTP 메시지들은 `전송되기 전에 암호화`되어 전송되고, `도착 후에는 복호화`됨.

- HTTPS가 적용된 웹사이트는 `"https://~~~"`로, 그렇지 않은 일반 HTTP 웹사이트는 `"http://~~~"`로 URL이 시작됨.

- HTTP의 default port numner는 `443`임 (HTTP는 `80`)

- HTTPS는 HTTP보다 약간 더 느림. 암호화와 복호화 과정에 사용되는 계산 오버헤드 때문.