모바일에서 잘 안 보일 수 있습니다.
0. 클라이언트와 서버 간에 통신하는 HTTP
텍스트와 이미지 등과 같은 리소스를 필요하다고 요구하는 쪽이 클라이언트가 되고, 이러한 리소스를 제공하는 쪽이 서버가 됩니다.
HTTP를 사용하여 2대의 컴퓨터 간에 통신을 하는 경우, 한 번 통신을 할 때마다 반드시 어느 한쪽은 클라이언트가 되고 다른 한쪽은 서버가 됩니다. 이와 같이 HTTP는 클라이언트와 서버의 역할을 명확하게 구별하고 있습니다.
1. 리퀘스트와 리스폰스
HTTP는 클라이언트로부터 리퀘스트(요청, Request)가 송신되고, 그 결과가 서버로부터 리스폰스(응답, Response)로 되돌아옵니다. HTTP 통신의 시작은 클라이언트가 되겠고 마무리는 서버쪽에서 됩니다.
클라이언트 리퀘스트
GET /index.html HTTP /1.1
Host: www.google.com
맨 앞에 나와있는 "GET"은 메소드라고 합니다. 요구하는 방법을 나타내 줍니다. 그다음 문자열 "/index.html"은 요구 대상입니다. 이 리소스를 리퀘스트하는데 이 URL을 "리퀘스트 URL"이라고 합니다. 그리고 "HTTP/1.1"는 클라이언트 기능을 식별하기 위한 HTTP 버전 번호입니다. 리퀘스트 헤더 필드와 엔티디에 대해서는 자중에 설명해 드리겠습니다ㅎㅎ
서버 리스폰스
HTTP /1.1 200 OK
Date: Fri 29 May 2020 11:50:30 GMT
Content-Length: 456
Content-Type: text/html
<html>
...
첫 번째 줄 "HTTP /1.1"은 서버의 HTTP 버전을 나타내고 있습니다. 앞에서 클라이언트의 HTTP 버전을 확인한 것과 같이 각 버전에 맞는 통신을 위해 버전을 확인합니다. 그리고 "200 OK"는 리퀘스트의 처리 결과를 나타내는 상태 코드와 설명입니다. 그다음 줄은 리스폰스가 발생한 일시를 나타내고 있습니다. 이것을 헤더 필드라고 부릅니다. 그리고 한 줄 공백이 있고 그다음 줄부터 body라고 부르는 리스폰스 본체가 있습니다.
2. HTTP는 Stateless 프로토콜
HTTP는 상태를 계속 유지하지 않는 스테이트리스(statelsess) 프로토콜입니다. HTTP 프로토콜은 리퀘스트와 리스폰스를 교환하는 동안에 상태(status)를 관리하지 않습니다. 결국 HTTP 프로토콜 단계에서 이루어진 리퀘스트와 리스폰스는 보존되지 않습니다.
그 이유는 데이터를 매우 빠르고 확실하게 처리하는 범위성(scalability)을 확보하기 위해서 이와같이 설계되었습니다. 전에 처리했던 리퀘스트와 리스폰스를 관리하고 있다면 클라이언트와 서버에 큰 무리가 될 것입니다.
하지만 웹서비스가 발달하면서 이런 스테이트리스가 걸림돌이 되기 시작했습니다. 한마디로 상태를 유지할 필요가 있다는 뜻인데요, 그중 한 예를 들자면 로그인이 될 수 있겠습니다. 상품을 고르고 주문을 할 때 로그인창이 새롭게 뜹니다. 다른 페이지에서 로그인을 한 후에 다시 되돌아가면 로그인이 돼있는 모습을 볼 수 있습니다. 이 기능을 해주는 것은
"쿠키(Cookie)"라는 기술이 도입되었습니다.
3. 서버에 임무를 부여하는 HTTP 메소드
- GET : 리소스 획득
GET 메소드는 리퀘스트 URI로 식별된 리소스를 가져올 수 있도록 요구합니다. 리소스가 텍스트이면 그대로 반환하고 GGI와 같은 프로그램이면 실행하여 보여줍니다.
리퀘스트 : GET/index.html HTTP/1.1
HOST: www.google.com
리스폰스 : index.html을 되돌려 준다.
- POST : 엔티티 전송
이 메소드는 엔티티를 전송하기 위해서 사용됩니다. GET으로도 엔티티를 전송할 수 있지만, 자주 사용하지 않고 일반적으로 POST를 많이 사용합니다.
리퀘스트 : POST/submit.cgi HTTP/1.1
HOST: www.google.com
Content-Length: 1500(1506바이트 데이터)
리스폰스 : submit.cgi가 수신한 데이터의 처리한 결과를 되돌려준다.
- PUT : 파일 전송
파일을 전송하기 위해서 사용됩니다. FTP에 의한 파일 업로드와 같이, 리퀘스트 중에 포함된 엔티티를 리퀘스트 URI로 지정한 곳에 보존하도록 요구합니다.
하지만 HTTP/1.1 PUT 자체에는 인증 기능이 없어 누구든지 파일을 업로드 가능하다는 보안 문제로 일반적인 웹 사이트에서는 사용하지 않습니다.
리퀘스트 : POST/example.html HTTP/1.1
HOST: www.google.com/
Content-type: text/html
Content_Length: 1500(1506바이트 데이터)
리스폰스 : 205 No Content 리스폰스를 되돌려준다(서버 상에 example.html이 작성되어 있다)
- HEAD : 메시지 헤더 취득
GET 메소드와 같은 기능이지만 메시지 바디는 돌려주지 않습니다. URI 유효성과 리소스 갱신 시간을 확인하는 목적 등으로 사용됩니다.
리퀘스트 : POST/index.html HTTP/1.1
HOST: www.google.com/
리스폰스 : index.html에 관련된 리스폰스 헤더를 되돌려준다.
- DELETE : 파일 삭제
PUT 메소드와는 반대로 리퀘스트 URI로 지정된 리소스의 삭제를 요구합니다. PUT과 마찬가지로 인증 기능이 없기 때문에 일반적인 웹 사이트에서는 사용되고 있지 않습니다.
리퀘스트 : POST/example.html HTTP/1.1
HOST: www.google.com/
리스폰스 : 205 No Content 리스폰스를 되돌려준다(서버 상에 example.html이 작성되어 있다)
- OPTIONS : 제공하고 있는 메소드의 문의
리퀘스트 URI로 지정한 리소스가 제공하고 있는 메소드를 조사하기 위해 사용됩니다.
리퀘스트 : OPTIONS * HTTP/1.1
Host: www.google.com
리스폰스 : HTTP /1.1 200 OK
Allow: GET, POST, HEAD, OPTIONS
(서버가 제공하고 있는 메소드를 리스폰스한다.)
- TRACE : 경로 조사
TRACE 매소드는 Web 서버에 접속해서 자신에게 통신을 되돌려 받는 루프백을 발생시킵니다. 리퀘스트를 보낼 때에 "Max-Forwards"라는 헤더 필드에 수치를 포함시켜 서버를 통과할 때마다 그 수치를 줄여갑니다. 수치가 0이 된 곳을 끝으로 어떤 리스폰스가 발생하는지 알아냅니다. 하지만 TRACE 메소드는 거의 사용되지 않고, 크로스 사이트 트레이싱(XST)과 같은 공격을 일으키는 보안 상의 문제도 있기 때문에 보통은 사용하지 않습니다.
리퀘스트 : TRACE / HTTP / 1.1
Host: www.google.com
Max-Forwards: 2
리스폰스 : HTTP /1.1 200 OK
Content-Type: message/http
Content-Length: 1024
TRACE / HTTP /1.1
HOST; www.google.com
Max-Fprwards:2 (리퀘스트 내용을 리스폰스에 포함해서 되돌려준다)
- CONNECT : 프록시에 터널링 요구
프록시에 터널 접속 확립을 요구해, TCP 통신을 터널링 시키기 위해서 사용됩니다. 주로 SSL, TLS 등의 프로토콜로 암호화 된 것을 터널링 시키기 위해서 사용됩니다.
리퀘스트 : CONNECT proxy.www.google.com:8080 HTTP /1.1
HOST: proxy.www.google.com
리스폰스 : HTTP /1.1 200 OK
4. 접속량 절약하기
초시 통신에서는 작은 사이즈의 텍스트를 보내는 것이 다였습니다. 그래서 통신마다 연결과 종료를 반복하는 것이 문제가 되지 않았습니다. 하지만 시간이 지나며 다량의 이미지를 포함한 문서 등이 늘어나며 문제가 생기기 시작했습니다. 예를 들면, 하나의 HTML에 여러 이미지가 포함되어 있는 경우 먼저 브라우저를 사용해 리퀘스트하여 HTML을 가져옵니다. 그리고 HTML에 포함되어 있는 이미지를 또 리퀘스트하여 받아옵니다. 만약 이미지가 50개라면 1개당 연결과 종료를 반복하기 때문에 쓸대없는 부하가 생겨납니다.
4.1 지속 연결
HTTP/1.1와 일부 HTTP/1.0 에서는 TCP의 연결 문제를 해결하기 위해 지속 연결(Persistent Connections)이라는 방법을 고안하게 되었습니다. 지속 연결의 특징은 어느 한쪽이 명시적으로 연결을 종료하지 않으면 TCP는 계속 연결을 유지합니다.
이와 같이 TCP 커넥션의 연결과 종료에서 나오는 반복된 오버해드를 줄여주기 때문에 서버에 대한 부하를 줄여줍니다. 또 오버해드를 줄였기 때문에 리퀘스트와 리스폰스가 빨리 끝나게 됩니다.
4.2 파이프라인화
지속 연결은 여러 리퀘스트를 한 번에 보낼 수 있도록 파이프라인(HTTP pipelining)화를 가능하게 합니다. 이 파이프라인은 리퀘스트를 병렬로 보낼 수 있게 해 줍니다. 이전에는 리퀘스트를 보내고 필수적으로 리스폰스를 받아야 했지만 병렬로 보내게 되면서 리스폰스 없이 요청을 할 수 있게 되었습니다.
5. 쿠키를 사용한 상태 관리
앞에서 살짝 다뤘지만 지금부터 자세히 알아보겠습니다. HTTP는 스테이트리스(stateless) 프로토콜이기 때문에 과거에 교환했던 정보는 남아있지 않습니다. 과거 리퀘스트와 리스폰스를 관리하지 않기 때문에 빠르게 통신할 수 있었지만, 과거 상태를 근거로 하는 리퀘스트는 처리할 수 없었습니다.
예를 들어, 네이버에 로그인을 하고 뉴스를 눌러 새 창으로 보면 로그인이 풀린 상태가 됩니다. 과거에 로그인했던 정보가 없어졌기 때문에 로그인이 풀린 것입니다.
이를 보완하기 위해 쿠키라는 시스템이 도입되었습니다. 리퀘스트와 리스폰스에 쿠키 정보를 추가해서 클라이언트의 상태를 파악할 수 있습니다.
쿠키
쿠키는 서버에서 리스폰스로 보내진 Set-Cookie라는 헤더 필드에 의해 쿠키를 클라이언트에 보존합니다. 다음번에 클라이언트가 같은 서버로 리퀘스트를 보낼 때, 자동으로 쿠키 값을 넣어서 전송합니다. 서버는 클라이언트가 보낸 리퀘스트(쿠키)를 확인해 어느 클라이언트가 접속했는지 보고 서버 상의 기록을 확인해 이전 상태를 확인합니다.
- 리퀘스트(쿠키를 가지고 있지 않은 상태)
GET /reader/ HTTP /1.1
Host: www.google.com
- 리스폰스(서버가 쿠키를 발행)
HTTP /1.1 200 OK
Date: Thu, 12 Jun 2020 15:30:00 GMT
Server: Apache
<Set-Cookie: sid=1342077140226724; path=/;expires=wed, => 10-Oct-12 15:30:00 GMT>
Content-Type: text/plain; charest=UTF-8
- 리퀘스트(보관하고 있던 쿠키를 자동 송신)
GET /image/ HTTP /1.1
Host: www.google.com
Cookie: sid=1342077140226724
(더 자세한 내용을 다음 포스팅에서)
'study > network' 카테고리의 다른 글
3. HTTP 메시지 (0) | 2020.06.24 |
---|---|
1.4 IP, TCP, DNS 그리고 URI와 UR (0) | 2020.04.21 |
1.3 네트워크의 TCP/IP (0) | 2020.04.14 |
1.2 웹과 HTTP 탄생 배경 (0) | 2020.04.06 |
1.1 웹 HTTP로 나타낸다 (0) | 2020.04.06 |
댓글