Computer Science/네트워크

[CS] HTTP 메세지

findTheValue 2021. 7. 18. 02:10
  • HTTP는 서버와 클라이언트간에 데이터가 교환되는 방식(약속)
  • ASCII코드로 인코딩 된 text정보이며 여러줄로 되어있다.
  • HTTP 초기버전과 HTTP/1.1에서는 클라이언트와
  • HTTP/2 에서는 최적화 성능 향상을 위해 HTTP 프레임으로 나누어집니다.

 

HTTP Request Message 구조.

  • Request Line : 첫라인으로 method, URI, http version으로 구성
    • HTTP Method : GET, POST 등의 server가 동작해야할 action을 정의한다.
      • GET : 리소스를 client로 요청하는 것.
      • POST: data가 server로 들어가야 할 때.
    • Request target : 두번째로 오는 요청 타겟은 주로 URL, 또는 프로토콜, 포트, 도메인의 절대 경로로 나타낼 수도 있으며 이들은 요청 컨텍스트에 의해 특정지어 집니다. 요청 타겟 포맷은 HTTP 메소드에 따라 달라집니다. 포맷에는 다음과 같은 것들이 있습니다.
      • origin 형식: 끝에 '?'와 쿼리 문자열이 붙는 절대 경로입니다. 이는 가장 일반적인 형식이며, GET, POST, HEAD, OPTIONS 메서드와 함께 사용합니다.
        POST / HTTP 1.1
        GET /background.png HTTP/1.0
        HEAD /test.html?query=alibaba HTTP/1.1
        OPTIONS /anypage.html HTTP/1.0
      • absolute 형식: 완전한 URL 형식입니다. 프록시에 연결하는 경우 대부분 GET과 함께 사용됩니다.
        GET http://developer.mozilla.org/en-US/docs/Web/HTTP/Messages HTTP/1.1
      • authority 형식: 도메인 이름 및 옵션 포트(':'가 앞에 붙습니다)로 이루어진 URL의 authority component 입니다.​​​​ HTTP 터널을 구축하는 경우에만 CONNECT와 함께 사용할 수 있습니다.
        CONNECT developer.mozilla.org:80 HTTP/1.1
      • asterisk 형식: OPTIONS와 함께 별표('*') 하나로 간단하게 서버 전체를 나타냅니다. ​​​​​
        OPTIONS * HTTP/1.1
    • Http Version
  • Request Headers
    • 다양한 종류의 요청 헤더가 있는데, 이들은 다음과 같이 몇몇 그룹으로 나눌 수 있습니다.
  • -----------------------------------------------------------------------------------------------
    • General 헤더: Via와 같은 헤더는 메시지 전체에 적용됩니다.
    • Request 헤더: User-Agent (en-US), Accept-Type와 같은 헤더는 요청의 내용을 좀 더 구체화 시키고(Accept-Language), 컨텍스를 제공하기도 하며(Referer), 조건에 따른 제약 사항을 가하기도 하면서(If-None) 요청 내용을 수정합니다.
    • Entity 헤더: Content-Length와 같은 헤더는 요청 본문에 적용됩니다. 당연히 요청 내에 본문이 없는 경우 entity 헤더는 전송되지 않습니다.
  • -------------------------------------------------------------------------------------------------------------------- 
    • Host : request가 전송되는 target의 host (URL)
    • Accept : 해당 request가 받을 수 있는 Response type
    • Connection : 해당 요청이 끝난 후에 클라이언트와 서버가 계속 네크워크 커넥션을 유지할 것인지 아니면 끊을 것인지에 대해 지시하는 부분.(Keep-alive or cancel)
    • User-Agent : 요청을 보내는 클라이언트에 대한 정보 : 사용하는 웹 브라우저, 버전, OS
    • Content-Type : 해당 요청이 보내는 메세지 body타입
      ex) JSON을 보내는 application/json
    • Content-Length : 메세지 body 길이
    • HTTP/1.1 404 Not Found
    • empty line : 요청에 대한 meta 정보가 전송되었음을 알린다.
  • Requests Message Body
    • 실제 메세지, 내용.(XML or JSON) GET HEAD,DELETE,OPTIONS은 대부분 BODY가 없다.
    • 리소스를 달라고 요청하는 것이기 때문)
    • 보통 UPDATE를 위한 POST요청(HTML 폼 데이터를 포함한)일 경우가 많다.

 


 

HTTP Response Message 구조.

  • status line : response의 상태를 간략하게 나타내며, 3부분으로 구성되어 있다.
    • HTTP Version
    • status code : 응답 상태를 나타내는 코드
    • status text : 응답 상태의 설명 (ex: 404 Not Found)
  • Headers :
    • request의 header와 동일하다
    • response에서만 사용되는 header 값이 있다 (예: User-Agent가 없고, Server가 있음).

예시

  • empty line

 

  • body : 실제 응답하는 데이터를 나타낸다. status 2XX의 경우, 존재하지 않는 경우가 많다.

 

 

Http2 :

Http1.1 에서 업그레이드된 버전으로, 2015년에 등장했다.
이전 버전에 비해서 더욱 빠르고 효율적이며 secure한 특징을 가진다.

HTTP/2의 이진 프레이밍 메커니즘(binary framing mechanism)은 사용 중인 API나 설정 파일 등을 변경하지 않아도 되도록 설계 되었기 때문에, 사용자가 보고 이해하기 쉽습니다.

 

HTTP/1.x 메시지는 성능상의 결함을 몇가지 내포하고 있습니다.

  • 본문은 압축이 되지만 헤더는 압축이 되지 않습니다.
  • 연속된 메시지들은 비슷한 헤더 구조를 띄기 마련인데, 그럼에도 불구하고 메시지마다 반복되어 전송되고 있습니다.
  • 다중전송(multiplexing)이 불가능합니다. 서버 하나에 연결을 여러개 열어야 합니다. 적극적인(warm) TCP 연결이 소극적인(cold) TCP 연결보다 효율적인데 말이죠.

HTTP/2에서는 추가적인 단계가 도입되었습니다. HTTP/1.x 메시지를 프레임으로 나누어 스트림에 끼워 넣는 것입니다. 데이터와 헤더 프레임이 분리 되었기 때문에 헤더를 압축할 수 있습니다. 스트림 여러개를 하나로 묶을 수 있어서(이러한 과정을 멀티플렉싱이라 합니다), 기저에서 수행되는 TCP 연결이 좀 더 효율적이게 이루어집니다.

이제 웹 개발자 입장에서는 HTTP 프레임을 매우 쉽게 살펴볼 수 있게 되었습니다. HTTP 프레임은 HTTP/2에서 추가된 단계이며, HTTP/1.1 메시지와 그 기저를 이루는 전송 프로토콜 사이를 메워주는 존재입니다. 그렇다고 해서 HTTP 프레임 때문에 개발자들이 API를 바꿔야 할 필요는 없습니다. 브라우저와 서버 둘 다 모두 HTTP 프레임을 받아 들일 수 있다면, HTTP/2가 활성화 된 후에 사용될 것입니다.


서버 ~ 백엔드 API ~ 프론트 ~ 클라이언트

유저가 로그인 기능을 사용하고자 할 때, 프론트에게 입력한 정보를 전달한다. 프론트는 이 정보를 백엔드에 전달하고, 백엔드api가 원격호출로 http요청을 서버에 보낸다. 서버에 저장된 해당 기능의 함수가 http요청에 따라 호출되고, 다시 백엔드가 이 정보를 받아 처리를 하여 프론트에게, 그리고 프론트가 클라이언트에게 응답해 준다

=> 프록시나 서버는 설정파일로, 브라우저는 API 혹은 다른 인터페이스로 메세지를 수령함.

 

---

 


 

결론

HTTP 메시지는 HTTP에서 핵심적인 역할을 합니다. 메시지 구조는 단순하게 이루어져 있으며, 확장성도 매우 좋습니다. HTTP/2 프레이밍 메커니즘 덕분에 HTTP/1.x 구문과 기저가 되는 전송 프로토콜 사이에 새로운 중간 단계가 추가 되었습니다. 프로토콜을 자체적으로 수정하지 않고 이미 입증된 메커니즘을 바탕으로 이뤄낸 것입니다.

 

 

참고링크: https://velog.io/@rosewwross/Http-and-Request-and-Response-hok6exbnfb

 

Http의 정의, 메소드, 메세지 형식

Http (Hyper Text Transfer Protocol) 정의: 서버(Apache, Nginx, Nginx 등)와 클라이언트(브라우저)가 인터넷 상에서 서로 통신을 주고받을 수 있도록 하기 위해 만든 규약을 말하며, Tim Berners Lee가 1991년에

velog.io

https://developer.mozilla.org/ko/docs/Web/HTTP/Messages

 

HTTP 메시지 - HTTP | MDN

HTTP 메시지는 서버와 클라이언트 간에 데이터가 교환되는 방식입니다. 메시지 타입은 두 가지가 있습니다. 요청(request)은 클라이언트가 서버로 전달해서 서버의 액션이 일어나게끔 하는 메시지

developer.mozilla.org

 


 

1. 웹 브라우저에 url을 입력하면

2. 브라우저는 자동으로 http 메세지를 만든다. http 요청 메세지는 method(get,post,delete,put),uri, http version, header, body(실제 전달하는데이터)

3. OS에 데이터 송출을 의뢰한다(프로토콜 스택) (브라우저에는 이 메세지를 네트워크에 송출하는 기능이 없기 떄문)

하지만 OS에 의뢰할 때는 도메인 명이 아니라 ip주소로 메세지를 받을 상대를 지정해야 한다. 이 과정에서 DNS서버를 조회해야 한다.

4. 브라우저는 socket 라이브러리(네트워크 기능을 App단에서 호출할 수 있게 해주는 라이브러리)를 이용 dns 서버로 도메인 주소를 보내면 dns가 ip주소로 응답해준다. (socket을 이용해 dns로 어떤 요청을 보낸다는 것 역시 OS 내부에 포함 된 프로토콜 스택을 호출해 의뢰하는 것이다.)

-프로토콜 스택이란? : OS내부에 내장된 네트워크 제어용 tcp/ip 소프트웨어

5. ip주소를 얻었으면 이제 웹 서버에 메세지를 송신하도록 os내부의 프로토콜 스택에 의뢰한다. 그러나 사실 의뢰 한다는 것은 결국 또 socket 라이브러리를 사용하는 것이다. 위에서 프로토콜 스택은 tcp/ip 소프트웨어라고 설명해쓴데, tcp는 연결형이다.

즉 socket 라이브러리를 이용해 의뢰를 하게되면 데이터를 송수신하는 컴퓨터 사이에 데이터 통로같은 것이 생긴다. 클라이언트와 서버간 통로가 생기는 것이다. 이통로를 통해서로 데이터를 주고 받을 수 있다.

하지만 tcp의 단점 중 하나가 초기 회선 설정비용인 만큼 데이터 송수신 하기 전 매번 통로를 설정해야 하는 단점을 안고 가야 한다.

 

결과적으로 클라이언트에도 서버에도 통로의 입구가 존재하게 된다(socket)

1. 서버와 클라이언트 모두 소켓을 만든다.

2. 서버측의 소켓에 클라이언트의 소켓이 다가가서 통로를 연결한다. (접속)

3. 데이터를 송수신한다.

4. 송수신이 끝나면 통로를 분리하고 소켓을 없앤다.

 

이와 같은 과정이 일반적인데 http는 비효율적인게 특성상 html문서, 이미지파일등의 데이터를 하나하나 별도의 것으로 취급하기 때문에 여러개의 이미지를 요청할 경우 매번 각각의 새로운 통신을 해야 한다는 점이다.

 

프로토콜 스택

위에서 아래로 프로토콜 스택은 app(브라우저)에서 메세지를 전달 받는다. 메시지를 아주 작은 데이터 패킷들로 나누고 수신처 주소 등 제어정보를 덧붙인다. 그리고 프로토콜 스택과 LAN 어댑터가 연대하여 패킷을 전기나 빛의 신호로 변환하고, LAN어댑터가 실제로 송수신 동작, 즉 케이블에 대해 신호를 송수신하는 동작을 실행한다.

 

결과적으로 프로토콜 스택이란 TCP 프로토콜을 사용하여 데이터 송수신을 담당하는 부분과, UDP를 ㅇ사용하여 송수신을 담당하는 부분, 또 IP를 사용하는 부분의 집합에 다른 부가적인 기능이 포함된 것이라고 볼 수 있다.

 

 

서버에 접속(통신 가능한 상태로 만들기)

 

브라우저에서 프로토콜 스택으로 메시지를 전달하면 프로토콜 스택은 여러가지 부가정보를 메모리에 저장한다. 부가적인 정보란, 통신 동작을 제어하기 위한 제어 정보인데, 예를 들면 통신 상대의 IP주소, 포트번호, 오류 유무, 전송 시간, 데이터 오프셋 등등이다. 프로토콜 스택은 이 제어 정보를 참조하면서 오류를 제어하거나 재송신한다.

 

부가적인 정보는 tcp통신 의뢰를 받았다면 tcp박스가 담당한다. 정확히 말하면 부가적인 정보들을 담을 메모리 확보 절차를 소켓 작성이라 한다. tcp박스, 더 큰 개념으로 포로토콜 스택이 소켓을 작서 오안료하면 브라우저에게 이 사실을 알리고, 언제든 이 소켓을 사용해 통신 할 수 있게끔 일종의 리모콘을 준다.

그림에서 보듯이 통신을 위한 부가적인 제어 정보는 포트 번호, 시퀀스 번호(송신 데이터의 일련 번호), ACK 번호(수신 데이터의 일련 번호) 등 많은 정보가 있다. 이런 정보는 클라이언트와 서버가 대화할 때 마다 늘 필요하다. 따라서 클라이언트와 서버 사이에 주고받는 패킷의 맨 앞부분에 추가하는데, 이 추가하는 영역을 헤더 영역이라고 한다. 물론 ip영역에서도 ip나름의 헤더가 붙게된다.

 

3-way-handshake

클라이언트 컴퓨터의 tcp 부분에서 헤더를 만들고나면 tcp역시 ip 부분에 헤더를 건네주며 송신을 의뢰한다. IP부분이 패킷 송신 동작을 실행하고 네트워크를 통해 패킷이 서버에 도착하면 서버측의 IP부분이 이것을 받아 서버측의 TCP 부분으로 넘겨주는 방식이다.

TCP통신 방식은, 최초 통신때 이런 방식으로 서버와 클라이언트 사이에 파이프와 같은 연결 통로를 확보해야 한다. 파이프가 연결되어야 데이터를 마음껏 주고 받을 수 있기 때문인데, 이 초기 설정 과정에 3-way-handshake 방식이 사용된다.

쉽게 설명하자면 아래와 같이 3단계를 거친다.

  1. 클라이언트 : 서버야, 너와 통신하고 싶어! 너가 이 메세지를 받았다면 잘 받았다고 나한테 알려줘. 그럼 이만!
  2. 서버 : 그래 클라이언트야. 네가 보낸 메세지 잘 받았어 우리 통신하자! 그나저나 내 메세지도 잘 전달 될지 모르겠네? 너도 내 메세지를 정상적으로 받았다면 나한테 다시 알려줘~
  3. 클라이언트 : 메세지 잘 받았어! 이제 서로 통신이 잘 된다는 것을 알았으니 마음편히 통신하자

이렇게 연결이 되고 나면 둘중 한 측이 close를 호출하여 연결을 끊을 때까지 연결이 계속 존재한다.

 

 

TCP가 신뢰성있게 데이터를 송수신하는 원리

tcp헤더에는 sequence number와 ack가 있다. tcp를 통해 신뢰성 있는 전송을 하기 위해서는 sequence number와 ack가 상당히 중요하다.

  • Sequence Number : tcp는 애플리케이션(브라우저)에서 넘겨 받는 데이터가 크다면 이를 여러개의 패킷(세그먼트)으로 쪼개어 서버로 전송한다. 이때 세그먼트들의 순서를 의미하는 것이 sequence number라고 볼 수 있다. 예를 들어 3000byte 짜리 파일을 전송한다고 하자. 이때 한번에 보낼 수 있는 데이터가 100byte라면 tcp는 30개의 세그먼트로 쪼개어 서버로 전송할 것이다. 이럴 경우, 각 세그먼트의 sequence number field에 순서를 의미하는 번호를 붙인다. 1,2,3 이렇게 나타내는게 아니라 byte형식으로 나타낸다. 즉, 첫 번째 세그먼트가 0이라면, 두 번째는 100, 세 번째는 200. 이런 식으로 Sequence Number를 할당하여 서버측으로 함께 보낸다.
  • ACK : 받은 것에 대한 응답이다. 즉, 클라이언트에서 요청을 받은 후, 다시 클라이언트로 보내는 값이다. 어떤 값을 다시 클라이언트로 보낼까? 서버는 클라이언트로부터 앞으로 받아야 할 다음 데이터의 squence number를 ACK로 설정하고 보낸다. 즉, 클라이언트로 부터 sequence number가 0인 세그먼트를 받았다면, 서버는 이에 대한 응답으로 ack : 100 을 응답한다. 0번을 받았으니 이제 다음으로 받고 싶은 sequence number 100를 ack로 보내는 것이다.

이렇게 할 경우, 클라이언트 측이 서버로부터 받을 것이라고 기대했던 ack값이 오지 않을 경우 tcp가 다시 해당 세그먼트를 전송하기 때문에 신뢰가 있다. 다음은 tcp가 의뢰하는 ip에 대해 공부하자.

'Computer Science > 네트워크' 카테고리의 다른 글

[CS][네트워크] TCP / UDP  (0) 2021.07.21
[CS] HTTP1.1 HTTP2.0 QUIC  (0) 2021.07.19
[CS] OSI 7 Layer  (0) 2021.07.18
[CS] Forward Proxy, Reverse Proxy, Load Balancer  (0) 2021.07.16
[CS] 웹서버 vs WAS  (0) 2021.07.13