-> 블로그 이전

[Network] 애플리케이션 계층 : HTTP

2022. 2. 10. 16:00Major`/컴퓨터 네트워크

HTTP

- 웹의 Application-Layer Protocol

- HTTP를 통해서 인터넷상에서 데이터를 주고받을 수 있다

- 웹 페이지는 여러 객체들로 구성되어 있다

  • 객체 : 이미지 파일/HTML 파일/오디오 파일/....
  • 객체는 서버 호스트 이름/경로 이름, 즉 URL로 지정된다
    • www.google.com/image.jpg

 

클라이언트-서버 모델을 따른다

Client (웹 브라우저)

1. 웹 객체를 서버에 요청

2. 서버로부터 요청한 객체를 받는다

3. 해당 객체를 display

 

Server (웹 서버)

1. Client의 Contact를 기다린다

2. Request를 받으면 Reqeust한 객체를 보내준다

 

TCP 사용 

- Client : (서버 IP주소 + 포트번호 80)을 이용해서 TCP 연결

  • TCP 연결 == 소켓을 생성

- Server : Client의 TCP연결을 수락한다

- TCP연결을 통해서 HTTP 메시지를 교환한다

 

Stateless 프로토콜이다

- Server는 Client의 과거 Request 정보를 저장하지 않는다

 

 

 

HTTP 비지속 연결

- TCP연결을 통해서 하나의 객체만 전송할 수 있다

 

과정

1. TCP 연결

  1. HTTP 클라이언트가 80번 포트로 TCP 연결 시도
  2. HTTP 서버는 클라이언트의 TCP 연결을 수락

 

2. HTTP 클라이언트는 TCP 연결 소켓을 통해서 Request Message를 보낸다

  • Request Message에는 원하는 객체를 지정해야 한다
  • ex) someDepartment/home.index

 

3. HTTP 서버는 Request Message를 받고, 요청된 객체를 포함한 Response Message를 생성하고 소켓을 통해 송신한다

  • 여기서 HTTP 서버는 Response Message를 보내자마자 TCP 연결을 종료한다

4. HTTP 클라이언트는 Response Message의 based-HTML-File을 parsing해서 각 객체에 대한 참조를 획득한다

 

응답 시간

RTT (Round-Trip Time) 

  • Client에서 보낸 패킷이 Server로 전달되고, 다시 Client로 돌아오는데 걸리는 시간

1. Client와 Server 간 TCP 연결 : 1RTT

2. HTTP Message를 요청하고, 다시 응답 받음 : 1RTT + 파일전송시간

  • 최종 응답시간 : 2RTT + 파일전송시간 

 

단점

- 객체 당 2RTT의 응답시간이 필요하다

  • 이를 해결하기 위해 병렬 TCP 연결을 시도할 수도 있다 (소켓 여러개 생성)
    • 병렬 TCP 연결을 시도하면 OS 오버헤드가 발생한다

 

 

HTTP 지속 연결

- TCP연결을 하면 여러 개의 객체를 전송할 수 있다

 

1. Client와 Server 간 TCP 연결 : 1RTT

2. based-HTML-File을 parsing해서 각 객체 참조 : 1RTT

  • Client는 객체를 참조하자마자 Request를 송신한다

>> 이후 모든 객체 : 1RTT


GET

1. Client가 해당 URL을 요청

2. 그러면 Server가 해당 URL을 전송해준다

 

폼 입력

POST

- user가 입력한 폼이 entity body에 실려서 전달이 된다

 

URL

- GET 방식을 사용

- '?'을 통해서 user가 원하는 폼을 입력한다

  • /animal?monkey?banana?tiger
  GET POST
URL에 데이터 노출 O X
데이터 위치 헤더 바디
캐싱 가능 여부 O X

HTTP /1.0

- GET

- POST

- HEAD

  • GET방식과 유사하지만, Server는 Client가 요청한 객체는 보내지 않는다
  • Response Message는 존재 / 요청한 객체는 존재 X

 

HTTP /1.1

- GET

- POST

- HEAD

- PUT

  • 서버의 URL에 클라이언트가 해당 파일을 업로드

- DELETE

  • URL 필드에 명시된 파일을 삭제

쿠키 (Cookie)

HTTP는 Stateless한 프로토콜이다

- 그래서 Server는 Client의 과거 요청에 대한 정보를 저장하지 않는다

- Server에서 Client의 Request 정보들을 저장하려고 쿠키를 사용한다

 

서버

1. 처음 접속한 Client의 Request Message를 받으면, 해당 Client에 대한 Unique ID를 생성한다

2. 서버에 존재하는백엔드 DB에 해당 Unique ID로 인덱스되는 Entry를 생성한다

3. Response Message를 보낼 때, 해당 Client의 Unique ID 쿠키 헤더 라인을 통해서 보내준다

4. 그 다음부터는, Client의 Request Message가 올 때마다, Unique ID를 쿠키 헤더 라인에 달고 온다

5. Request Message에 존재하는 Client의 정보들을 백엔드 DB의 해당 ID Entry에 계속해서 저장한다

 

클라이언트

- 서버로부터 Unique ID를 받으면, 해당 Unique ID를 쿠키 파일에 저장해놓는다

 

 

※ Example :: Client가 Amazon Server에 처음 접속

1. Client가 처음 Amazon Server에 접속한다 (Request Message 보냄)

 

2. Amazon Server는 Client에 대한 Unique ID(1678)를 생성한다

  • 본인의 백엔드 DB에 해당 Unique ID에 대한 Entry를 생성한다

 

3. 그 다음, Server는 Client에게 Response Message를 보내준다

  • 이 Response Message는 Client에 대해서 생성된 Unique ID(1678)을 쿠키 헤더 라인을 통해서 보내준다
  • 그러면, Client의 쿠키 파일에는 Amazon Unique ID : 1678이 저장된다

 

4. 이 다음부터 Client는 Request Message를 보낼 때마다, 쿠키 헤더 라인에 Unique ID(1678)을 달아서 보내준다


웹 캐시 (프록시 서버)

- Client가 Request를 보내면 저 멀리 반대편에 있는 Server에 해당 Request가 도착하고, 서버는 Response를 저 멀리 반대편에 있는 Client로 보내줘야 한다

  • 이러면 응답시간이 매우 길어지고, 트래픽의 양 또한 많아진다

>> 웹 캐시를 통해서 Client가 자주 Request하는 Data들을 저장해놓으면 굳이 Server까지 도달하지 않아도 웹 캐시자체에서 Response를 보내줄 수 있다

  • 웹 캐시는 객체의 사본을 저장해두고, 객체의 원본은 Origin Server에 존재한다

 

HTTP Request & Respone 과정 (With Web-Cache)

1. Client와 웹 캐시간에 TCP 연결을 설정하고, Client는 웹 캐시에게 객체에 대한 HTTP Request를 보낸다

2. 웹 캐시는 해당 객체의 사본이 캐시에 저장되어 있는지 확인한다

3-1. 저장되어 있다면

  • 웹 캐시 자체에서 Response Message를 통해서 객체를 Client에게 보내준다

3-2. 저장이 안되어 있다면

  1. 웹 캐시와 Origin Server간에 TCP 연결을 설정하고, 웹 캐시는 Origin Server에게 해당 객체에 대한 HTTP Request를 보낸다
  2. 그러면 Origin Server는 해당 객체에 대한 Response Message를 웹 캐시에게 보내준다
  3. Origin Server로부터 해당 객체를 받은 웹 캐시는 일단 해당 객체에 대한 사본을 본인 캐시에 저장을 해두고, Client에게 Response Message를 통해서 객체를 보내준다

 

Example)

  •  

- Client 1, 2 모두 프록시 서버에게 HTTP Request를 보낸다

 

Client 1

- 해당 객체가 프록시 서버에 존재 X

  1. 프록시 서버에서 다시 Origin Server로 해당 객체에 대한 Request를 보내고,
  2. Origin Server로부터 Response를 받고
  3. 최종적으로 Client 1에게 해당 객체에 대한 Response Message를 전달해준다

Client 2

- 해당 객체가 프록시 서버에 존재 O,

  • 프록시 서버 자체에서 해당 객체에 대한 Response Message를 Client 2에게 전달해준다

 

>> 이를 통해서 웹 캐시(프록시 서버)는 Client역할, Server역할 둘 다 하는것을 알 수 있다


조건부 GET (Conditional GET)

- 무작정 Client의 Request에 대해서 프록시 서버가 해당 객체에 대한 Response를 보내주면

  • 만약에, Server가 해당 객체를 Update해도, 프록시 서버는 객체의 옛날 버전만 보내주게 된다

>> 이를 해결하기 위해 조건부 GET을 사용한다

 

웹 캐시 → Origin Server

- Request받은 객체가 가장 최신버전인지 Origin Server에게 확인을 받는다

  • Origin Server로 보내는 Request Message에 If-modified-since : <Date>를 명시해서 보내준다
    • Data는 캐시가 현재 보유하고 있는 객체의 복사본의 수정 시간이다

 

Origin Server → 웹 캐시

해당 <Date> 이후 수정 X

  • 객체를 굳이 보내줄 필요가 없으니까, 객체를 생략한 Response Message만 보내준다
    • ex) HTTP /1.1 304 Not Modified

해당 <Date> 이후 수정 O

  • 수정된 객체를 포함해서 Response Message를 보내야 한다
    • ex) HTTP /1.1 200 OK ~~~ <Data> ~~~