Request & Respond Message

Violet_Evgadn·2023년 4월 26일
0

네트워크

목록 보기
5/37

이전까지 HTTP Protocol에 대해서 알아보았다.

HTTP Protocol은 웹 서버와 HTTP Reqeust & HTTP Respond를 주고받으며 통신하는데 이때 HTTP에 의해 포맷이 정해져 있는 "Message"에 데이터를 담아 통신을 수행한다.

이번 Section에서는 HTTP Protocol에 의해 정해져 있는 포맷인 "Message"에 대해 알아보겠다.


Request Message

Request Message 형식

<Method>(공백)<URI>(공백)<HTTP Version> - Request Line
<필드명>:<필드값> - Message Header
.... - Message Header
(공백 행)
<Message Body>

가장 첫 번째 줄을 Request Line이라고 한다.

<필드명>:<필드값>으로 되어 있으며 공백 행 이전까지 나온 모든 내용이 Message Header이다.

마지막으로 데이터가 저장되어 있는 메시지 본문(Message Body)이 존재한다.

Request Line

Request Message의 첫 번째 행인 "Request Line(리퀘스트 라인)"을 먼저 알아보자.

이 행에는 HTTP Method와 URI, HTTP Version이 입력되어 있다.

이전에 말했듯 메서드와 URI가 HTTP의 핵심이므로 이 리퀘스트 라인만 보더라도 리퀘스트의 내용을 대충 파악할 수 있다.

어떤 Method를 사용하여 요청을 보낼지는 개발자가 미리 정해 놓았기 때문에 사용자는 고민하지 않아도 된다.

예를 들어 사용자가 휴대폰 번호를 입력한 후 제출하는 것은 'POST"를 사용하며 "www.sample.com"에 접속하게 하는 동작은 "GET"을 사용하도록 미리 정해 놓았다.

메서드를 썼으면 한 칸 띄운 뒤 URI가 입력된다. 도메인명을 제외하고 파일이나 프로그램의 경로명을 쓰는 것이 보통이다.

즉, 엄밀히 따지자면 URI가 아닌 도메인 명을 제외시킨 URN이 입력된다고 말하는 것이 적절할 것 같다.

예를 들어 "http://www.sample.com/sample1.html?param=value"로 접근하고 싶을 경우 "/sample1.html?param=value"가 입력된다.

마지막으로는 HTTP Version을 입력함으로써 어떤 HTTP 버전 Format으로 Request Message를 썼는지 밝혀준다.

Request Message Header

Request Line을 통해 대략적인 리퀘스트 정보를 밝혔다면 부가적인 자세한 정보를 메시지 헤더에 적는다.

이 헤더에는 날짜, 클라이언트가 취급하는 데이터 종류, 언어, 압축 형식 등 다수의 Field가 존재한다.

아래 여러 개의 Header Field를 설명하겠지만 모든 것을 외우거나 이해할 필요는 없으며 브라우저의 종류나 버전, 설정 등에 따라 달라지는 경우도 있으므로 필요할 때 검색해 보는 방식 정도로만 활용하면 된다.

출처 : https://medium.com/@jsguyhenry/how-to-read-get-response-header-from-ajax-http-service-api-call-or-response-c873c5fbf9b8

Request Message Body(메시지 본문)

메시지 헤더를 모두 썼다면 아무것도 쓰지 않은 하나의 공백 행을 넣은 뒤 메시지 본문을 넣는다.

이 메시지 본문이 메시지의 실제 내용을 의미하며 이곳에 서버 측으로 송신할 데이터를 쓴다.

단, GET 메서드의 경우 URI에 기입한 URL Parameter를 통해 모든 것을 파악할 수 있으므로 메시지 본문에 쓰는 송신 데이터는 아무것도 없으며 메시지 헤더가 끝나는 순간 Request Message가 종료된다.

메시지가 POST인 경우에는 사용자가 폼에 입력한 데이터(웹 서버에 보낼 데이터)가 메시지 본문에 담겨 리퀘스트 메시지가 작성되는 것이다.


Respond Message

Respond Message 간단 설명

웹 서버 측에 Request Message를 보냈다면 웹 서버는 이를 받아 원하는 동작을 수행하여 결과물을 만든다.

그리고 이 결과물을 Respond Message에 담아 클라이언트(브라우저) 측에 보내게 된다.

Respond Message의 포맷은 Request Message와 매우 유사하다.

데이터(Request 처리 결과물)를 Respond Message Body에 담으며 사용하는 Hedaer Field는 다르겠지만 어쨌든 Respond Header 또한 Request Message Header와 똑같은 방식으로 만든다.

여기서 자주 잘 봐야 하는 것은 메시지 첫 줄이다.

응답 메시지는 Request Line 대신 메시지 첫 줄에 "Status Code" 및 "응답 문구"를 입력한다.

Status Code란 Request에 대한 처리가 정상 종료되었는지 클라이언트 측에 알려주기 위해 숫자로 쓴 값으로써 프로그램(브라우저)에 실행 결과를 알려주기 위한 값이다.

Status Code가 프로그램에 실행 결과를 알려주기 위한 값이라면 응답 문구는 문장으로 쓰여 있으며 사람에게 실행 결과를 알리기 위한 목적의 값이다.

응답 메시지가 브라우저로 되돌아오면 메시지에 포함된 데이터를 추출하여 화면에 표시함으로써 사용자는 웹 페이지를 눈으로 볼 수 있는 것이다.

Status Code

1XX : Information

서버가 요청을 받았으며 현재 요청을 처리하고 있으니 Client는 작업을 계속 진행하라는 의미이다.

참고로 HTTP 1.0 버전에서는 지원되지 않는다.

100(Continue) : 현재 요청이 진행 중이며 문제가 없음

2XX : Success

서버가 요청을 성공적으로 처리하였음을 나타낸다.

200(OK) : 요청이 성공적으로 처리되었음

201(Created) : 요청이 성공적으로 완료되었고 새로운 리소스가 생성되었음. 주로 POST 아니면 PUT 요청의 응답 Status Code로 사용됨

3XX : Redirection messages

요청 완료를 위해서는 추가 작업 조치가 필요다는 것을 나타낸다.

300(Multiple Choice) : 요청에 대해 하나 이상의 응답이 가능함

301(Moved Permanently) : 요청한 Resource의 URI가 변경되었음을 알림

4XX : Client Error

클라이언트(사용자) 측에서 Request 할 때 잘못된 문법으로 요청했거나 Request에 대한 처리를 수행할 수 없을 경우(ex. 권한 문제) 발생한다.

400(Bad Request) : 잘못된 문법으로 인해 서버가 요청을 이해하지 못함

401(Unauthroized) : 요청을 보낸 Client가 인증되지 않았음을 알림

403(Forbidden) : Client가 리소스에 접근할 권리가 없음

404(Not Found) : 서버가 요청받은 리소스를 찾을 수 없음

408(Request Timeout) : 요청 중 Timeout 시간이 초과되어 처리를 수행하지 못함

참고로 공부를 하다 보니 418(I'm a teapot)이라는 상태 코드도 있었는데 일단 현실에서는 거의 보지 못하는 에러겠지만 재밌어 설명해 보겠다.

국제 인터넷 표준화 기구(IETF)는 매년 만우절에 장난스러운 RFC를 출판하고 있는데 1998년 만우절에 출판한 장난스러운 RFC에 의해 만들어지는 에러가 418 에러이다.

원래는 HTCPCP(HyperText Coffee Pot Control Protocol)에 커피 서버에 커피를 끓여달라는 요청을 해야 하는데 차 서버(Teapot Server)에 커피를 끓여달라는 요청을 보내면 발생하는 에러라고 한다.

(만우절에 진심이시군...)

5XX : Server Error

Request는 유효하지만 서버 측에서 이를 처리하지 못했을 경우 발생한다.

500(Internal Server Error) : 서버에 문제는 있지만 정확한 문제 이유에 대해선 더 구체적으로 설명할 수 없음

502(Bad Gateway) : 서버가 게이트웨이로부터 잘못된 응답을 받았음

503(Service Temporarilty Unavailable) : 일시적으로 서버를 이용할 수 없음(ex : 서버가 꺼져있거나 과부하로 인해 다운되었음)

504(Gateway Timeout) : 서버가 게이트웨이 역할을 하고 있으며 다른 서버로부터 시간에 응답을 받지 못했음

다른 HTTP Status Code에 대해 알고 싶다면 아래 2가지 사이트에서 확인해 보자.

HTTP 상태 코드 정리 | 와탭 블로그

HTTP Cats

(http.cat은 도움이 된다기보단 이런 사이트가 있다는 것이 신기해서 넣어봤다)

태그

응답 메시지로 페이지를 받았을 때 페이지가 문장으로 되어 있으면 페이지를 브라우저에 띄우고 그대로 작업이 끝나지만 영상 등이 포함되어 있는 경우 추가 작업 과정이 필요하다.

영상 등을 포함하는 경우에는 페이지 내에 영상(미디어) 파일임을 나타내는 "태그"라는 제어 정보가 포함되어 있다.

태그란 HTML 문법에서 결정된 제어 정보를 의미한다.

만약 페이지 내에 미디어가 존재하는 경우 <img src="image.jpg"> 형태의 태그가 포함되어 있다.

그렇다면 미디어 파일이 포함된 페이지 같은 경우 어떻게 작업을 수행할까?

먼저 브라우저는 화면에 대한 요청을 보내고 페이지에 대한 텍스트 내용(HTML 파일)을 받는다.

이후 브라우저는 텍스트 내용에 포함되어 있는 태그를 탐색하는데 만약 미디어와 관련된 태그를 만나면 일단 그곳에 미디어용 공백을 만들어두고 문장을 표시한다.

이후 웹 서버 측에 다시 미디어 파일에 대한 Request를 보내 미디어 파일만을 받아온다.

Response로 받은 미디어 파일을 이전에 비워두었던 미디어용 공백에 넣어줌으로써 1개 페이지를 완벽히 로드하는 것이다.

즉, 만약 미디어 파일이 N개 있는 페이지일 경우 웹 서버 측에 총 (N+1) 번의 Request를 보내야 한다는 말이다.

이때 웹 서버는 브라우저가 이러한 사정 때문에 1개 페이지에 대하여 Request를 여러 번 보낸다는 것은 모른다.

단지 웹 서버는 Request가 왔으니 그에 따른 Respond를 보내주기만 할 뿐이다.

이 과정에서 첫 번째 Response로 보낸 HTML 텍스트 파일은 계속해서 브라우저에서 저장하고 있는 것이다.


HTTP Message Header Field

General Header

Request와 Respond Message에서 모두 사용하는 헤더 필드이다.

  • Date : Request나 Respond Message가 작성된 날짜
  • Pragma : 데이터 캐시를 허용할지 여부를 나타내는 통신 옵션을 지정함
  • Cache-Control : 캐시를 제어하기 위한 정보
  • Connection : Respond 송신 후 TCP에 계속 접속할지 연결을 끊을지 나타내는 통신 옵션을 지정
  • Transfer-Encoding : 메시지 본문의 인코딩 방식
  • Via : 도중에 경유한 프록시나 게이트웨이를 기록

Request Header

Request Message에서 사용하는 헤더 필드이다.

  • Authroization : 사용자 인증용 데이터
  • From : 리퀘스트 발신자의 메일 주소
  • If-Modified-Since : 클라이언트 측에서 캐시에 저장된 정보를 비교하여 오래되었을 경우 새 정보를 받기 위해 사용
  • Referer : 하이퍼링크를 거쳐 통해 어느 페이지를 읽은 경우 링크 대상 URI를 나타냄
    • 어떤 사이트를 통해 현재 사이트에 접속하였는지 알 수 있음
    • 사이트 접속 통계를 위해 많이 활용됨
  • User-Agent : 클라이언트 SW 명칭이나 버전에 관한 정보
  • Accept-Charset : 클라이언트 측이 받은 문자 코드 세트
  • Accept-Encoding : 클라이언트 측이 Content-Encoding으로 받은 인코딩 방식으로 주로 데이터 압축 형식을 나타냄
  • Accept-Language : 클라이언트 측이 받은 언어 종류. 한글은 ko, 영어는 en
  • Range : 데이터 전체가 아니라 일부만 읽을 때 범위를 지정

Response Hedaer

Respond Message에서 사용되는 헤더 필드이다.

  • Location : 정보의 정확한 장소를 나타낸다. 리퀘스트 URI가 상대 경로일 경우 절대 경로 위치를 통지하기 위해 사용
  • Server : 서버 SW 명칭이나 버전에 관한 정보
  • WWW-Authenticate : 요청 정보에 대한 액세스가 제한되어 있을 경우 사용자 인증용 데이터를 반송
  • Accept-Ranges : 데이터 일부만 요청하는 Range를 지정할 경우 서버가 해당 기능을 가지고 있는지 알림

Entity Header

엔티티(메시지 본문) 부가정보로써 사용되는 Header Field이다.

  • Allow : 지정한 URI로 사용 가능한 메서드
  • Content-Encoding : 메시지 본문 압축 등의 인코딩 처리가 되어 있는 경우 인코딩 방식을 나타냄
  • Content-Length : 메시지 본문 길이를 나타냄
  • Content-Type : 메시지 본문의 데이터 종류를 나타냄
  • MIME 사양으로 정의된 데이터 타입으로 알려줌
  • Expires : 메시지 본문의 유효 기간
  • Last-Modified : 정보를 최종 변경한 일시
  • Content-Language : 메시지 본문 언어
  • Content-Location : 메시지 본문이 서버의 어디에 위치해 있는지 위치를 URI로 나타냄
  • Content-Range : 데이터 일부만 Request 된 경우 메시지 본문의 어느 범위 데이터가 포함되어 있는지 나타냄
  • Etag : 갱신 처리 등에서 이전 요청의 응답을 바탕으로 한 갱신 데이터를 다음 요청에서 송신하는 경우가 있는데 이전 응답과 다음 요청을 관련시키기 위해 사용하는 정보. 쿠키라는 필드와 역할이 유사함

Content-Type Header 종류

application/x-www-form-urlencoded

Form의 내용을 HTTP Message Body를 통해 전송할 때 사용하는 Content-Type으로 "key=value"의 Query Parameter 형식으로 데이터를 전송한다.

전송 데이터를 URL Encoding 처리한다는 특징을 가지고 있다.

multipart/form-data

일반 텍스트 데이터와 파일 같은 Binary 데이터를 같이 전송하고 싶을 때 사용한다.

application/json

Text, XML, JSON 데이터를 전송 할 때 사용한다.


이미지 파일을 포함하는 페이지에 대한 처리 과정

sample.html 파일을 불러오는데 sample.html에 cat.jpg라는 이미지가 포함된 있는 경우를 생각해 보자.

전체 과정

  1. /sample.html 파일을 읽기 위해 Request 보냄
  1. /sample.html 내용을 Response에 담아 보냄
  1. /cat.jpg 파일을 읽기 위하여 Request 보냄
  1. /cat.jpg 파일 내용을 Response에 담아 보냄

1번 Request Message

GET /sample.html?param=value HTTP/1.1
Accept : */*
Accept-Language : ko
Accept-Encoding : gzip, deflate
User-Agent : Mozilla/4.0(compatible; ~)
Host: www.sample.com
Connection: Keep-Alive

먼저 GET Method이기 때문에 Connection 이후에 Message Body 부분이 없음을 확인할 수 있다.

만약 POST였다면 Connection: Keep-Alive 아래 빈 행이 추가된 뒤 param=value라는 Message Body가 추가되었을 것이다.

두 번째로 자세히 봐야 할 것은 Message Header의 "Host"이다.

위에서 설명했듯 Request Line의 URI 부분에는 읽어올 파일의 이름만을 기입한다. 따라서 /sample.html만 기입된 것을 확인할 수 있다.

그렇다면 어떤 웹 서버에 존재하는 sample.html을 불러올지 어떻게 아는 걸까?

이를 위해 Host라는 Message Header 값에 도메인명을 입력해 줌으로써 웹 서버 위치를 알려주는 것이다.

2번 Respond Message

HTTP/1.1 200 OK
Date : THU, 2 MAR 2023 00:25:14 GMT
Server: Apache
Last-Modified : THU, 2 FEB 2023 00:25:14 GMT
Content-Type: text/html
Connection: close
Content-Length : 632

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>제목<title>
</head>

<body>
...
<img src="cat.jpg">
...
</body>
</html>

200 Status Code를 통해 정상 종료되었다는 것을 알 수 있고 현재 웹 서버는 Apache Server임을 확인할 수 있다.

또한 Response로 제공된 데이터는 "text/html" 형식의 데이터인 HTML 문서임을 알 수 있다.

문제는 <img> 태그로 불러오는 "cat.jpg"는 "image/jpeg" 데이터 타입을 가진다는 것이다.

Response 데이터로는 1가지 데이터 형식만을 보낼 수 있으므로 text/html과 image/jpeg 파일을 동시에 보낼 수 없다.

이 때문에 먼저 HTML 파일을 Respond Message Body에 넣어 데이터로 보내준 뒤 cat.jpg 파일에 대해서 다시 Request를 보내야 하는 것이다.

3번 Request Message

GET /cat.jpg HTTP/1.1
Accept : */*
Referer : http://www.sample.com/sample.html
Accept-Language : ko
Accept-Encoding : gzip, deflate
User-Agent : Mozilla/4.0(compatible; ~)
Host: www.sample.com
Connection: Keep-Alive
Referer이 추가되었음을 볼 수 있다.

cat.jpg에 대한 요청은 sample.html에서 보낸 요청이므로 Referer가 추가된 것이다.

4번 Respond Message

HTTP/1.1 200 OK
Date : THU, 2 MAR 2023 00:25:30 GMT
Server: Apache
Last-Modified : THU, 2 FEB 2023 00:25:14 GMT
Content-Type: image/jpeg
Connection: close
Content-Length : 632

[cat.jpg Binary 데이터]

먼저 Content-Type이 "image/jpeg"로 설정되어 있는 것을 볼 수 있다.

또한 Respond Message Body에는 cat.jpg에 대한 데이터가 저장되어 브라우저 쪽에 전달될 것이다.

profile
혹시 틀린 내용이 있다면 언제든 말씀해주세요!

0개의 댓글