[HTTP] HTTP 기본적인 개념 및 헤더 종류
HTTP가 무엇일까? 웹 개발자들이 http가 중요하다 라고 많이 말을 한다. 그런데 왜 난 (그리고 이 글을 보는 넌) 잘 모를까? 그건 http 작업을 하면서 문제가 발생하지 않았기 때문이다. 사람은 문제가 발생해야지만 공부를 하는 것 같다. 필자도 http 관련 문제가 발생하였고 이번 기회에 공부를 해보았다. 공부를 하면서 이 재밌는 것을 왜 이제 했나 싶었다. 기초적인 수준을 공부하였지만 얻은 게 많이 있었다.
HTTP ?
HTTP가 무엇일까? 인터넷에 검색을 하면 Hyper Text Transfer Protocol 이라고 나온다. Hyper Text가 뭔지는 몰라도 Hyper Text를 전송하는 protocol 인 것을 알 수 있다. 즉 hyper text를 전송하기 위한 약속이 http라는 것이다. 필자는 이 약속을 지키지 않고 사용하여 문제가 발생하였다. 간단하게 말하자면 사과를 줄꺼면 사과를 준다고 말을 해야하는데 사과를 준다고 해놓고 배를 준 것이다. 따라서 서버는 사과를 기대했는데 배가 오니 작업을 진행할 수 없었다.
이러한 약속을 알고 지키기 위해서는 header와 body를 알아야 한다. 우선 header의 종류에 대해 알아보자.
- ● General Headerex) Date, Cache-Control, Connection, ...
- HTTP 요청/응답에 사용되지만 Body 데이터와는 무관한 정보.
- ● Request Headerex) Accept, Cookie, Referer, ...
- HTTP 요청에 사용되지만 Body 데이터와는 무관한 정보
- ● Response Headerex) Age, Location, ...
- HTTP 응답에 사용되지만 Body 데이터와는 무관한 정보.
- ● Entity Headerex) Content-Length, Content-Language, ...
- HTTP body에 관한 정보
HTTP header의 종류는 위 4가지가 있습니다. 그러나 어떤 헤더가 어떤 종류에 포함되는 지는 별로 중요하지 않다고 생각됩니다. 그럼 뭐가 중요하냐? 각각의 header가 의미하는 내용이 중요합니다. 그럼 http header에 대해 더 자세히 알아보겠습니다.
HTTP header
- ● Date
- HTTP packet이 생성된 시간
- ● Cache-Controlno-cache : 캐시 사용 전 서버에게 확인private : 개인 환경 캐시 사용 (ex, 브라우저)
- max-age= seconds : 해당 시간동은 유지 (304 - 값 변화 없음 인 경우 캐시 사용)
- public : 공유 캐시 사용
- no-store : 캐시 사용 X
- ● Expires
- 응답 컨텐츠 만료 기간 (cache-control에 max-age가 있는 경우 무시)
- ● Etag
- 콘텐츠가 변경된 경우 같이 변하는 값
- ● If-Modified-Since조건부 헤더변경되지 않으면 304
- 해당 시간을 기준으로 값이 변경되면 200 + 콘텐츠
- If-modified-since: <day-name>, <day> <month> <year> <hour>:<minute>:<second> GMT
- ● If-None-Match
- If-None-match: ETag 값
Etag 실습
etag와 if-none-match 값이 실제로 변하는 지 궁금하여 간단한 client, server를 만들어 테스트를 해보았습니다. 기존 값은 변경전, 변경 이후의 값은 변경후 입니다. etag 값을 확인하기 위해 변경전을 그대로 한번 더 return 하고 그 이후 변경후를 return 하였습니다.
그 결과 header에 정의된 설명대로 etag 값과 if-none-match는 처음에는 변경되지 않았고 값이 변경된 후에 변경된 것을 확인할 수 있었습니다.
- ● content-typeex) application/json, multipart/form-data, ...
- 콘텐츠 타입
- ● content-length
- 본문의 길이
- ● Connectionex) Keep-alive: timeout=n1, max=n2n2 : 연결 시 전송될 수 있는 최대 요청 수
- ex) close
- n1 : 연결 되어있어야 하는 최소한의 시간
- Client-Server 간의 연결 방식 설정
- ● Host
- Host: <host>:<port> - 서버 도메인:포트번호
- ● User-Agent
- 요청하는 클라이언트의 정보 (ex, 접속한 브라우저 종류)
- ● Accept<MIME_type>/<MIME_subtype>
- 서버에게 전송 바라는 콘텐츠 타입
- ● AuthorizationAuthorization: 인증타입 credentials
- 인증 토큰을 서버로 전송할 때 사용
- ● Refererex) 네이버 -> 네이버 지식in
- 요청한 페이지의 주소 (링크 타고 넘어온 경우 링크의 주소)
- ● Origin
- POST 요청이 시작되는 주소
- ● Access-Control-Allow-Origin
- 요청을 허용하는 주소
이 정도 header 종류를 이해했습니다. 사실 이해만 한거지 실제로 사용할 때는 기억나지 않아 다시 찾아볼 것입니다. 그리고 Web 개발하면 1번은 꼭 거치는 문제가 있습니다. 바로 cors 에러 입니다. cors에 에러는 왜 나는 것일까요? 그리고 cors 에러는 무엇일까요? 한번 알아보겠습니다.
CORS, SOP
CORS(Cross-Origin Resource Sharing) - 교차 출처 리소스 공유입니다. 그럼 SOP는 뭘까요? SOP(Same Origin Policy) - 동일 출처 정책 입니다. 2개 문장에서 공통적으로 나오는 단어가 있습니다. 출처. 출처가 뭘까요?
출처 : protocol + host + port 입니다. (ex, https://172.26.50.13:3000) 즉, 브라우저에서는 보안을 위해 동일한 출처인 경우만 정보를 주고 받을 수 있도록 되어있습니다. 그런데 대부분 웹 사이트는 Client, Server의 출처가 다를 것입니다. 따라서 서로 데이터를 주고 받을 수 없습니다. 이러한 이유로 인해 cors 에러가 발생하는 것입니다. 그럼 어떻게 해결할 수 있을까요? 여러 방법이 있지만 대표적으로 Access-Control-Allow-Origin Header를 통해 허용하고자 하는 도메인을 작성하여 데이터를 주고 받을 수 있게 허락하는 것입니다. 이해가 되었을까요?
HTTP header에 따른 body
필자가 잘못하여 공부하게 된 부분입니다. 위에서 header를 알아볼 때 content-type이 있었습니다. 말 그대로 content의 type을 의미합니다. 본문 내용에 따라 이것은 달라지고 맞추어 주어야 합니다.
- 본문 데이터 : json -> application/json
- 본문 데이터 : binary 없는 form data -> application/x-www-form-urlencoded
- 본문 데이터 : image / file ... -> multipart/form-data
- ...
위와 같이 본문에 따라 content-type을 다르게 적어주어야 합니다. 아니면 제대로 동작한다는 보장을 할 수 없습니다. 아래 필자가 구현한 client, server가 데이터를 주고 받은 것을 확인해봅시다.
위 이미지를 보면 알 수 있듯이 body data와 맞지 않은 content-type을 보낸 경우 server에서 제대로 parsing 하지 못 하였습니다. 이러한 이유 때문에 content-type을 정확히 입력해주어야 합니다.
HTTP packet 구조
HTTP packet을 확인해보면 아래와 같이 되어있습니다.
첫 번째 줄은 start line, 두 번째는 header들로 되어 있습니다. 본문이 있는 경우 한칸 띄우고 나타납니다. 아래 이미지를 확인해봅시다.
TCP 3, 4 way handshake
HTTP packet을 언제 보낼까요? 그냥 툭 던지면 받을 수 있을까요? 그렇지 않습니다. 서로 packet을 주고 받을 준비가 되어 있는 지 확인을 해야합니다. 주고 받기 전 확인하는 작업을 3 way handshake, 모든 데이터 송수신 완료 후 끊기 위한 작업을 4 way handshake 라고 합니다. 한번 간단하게만 알아봅시다.
3 way handshake
데이터를 주고 받기 전 사전 작업입니다. ack의 경우 받은 seq + 1이 됩니다.
위 작업이 이루어 지고 나면 이제 서로 데이터를 주고 받습니다. 아래 이미지는 실제 packet을 주고 받을 때 해당 동작을 하는 지 확인한 이미지입니다.
4 way handshake
데이터를 주고 받은 후 연결을 종료하는 작업입니다. (서버가 데이터를 다 보냈다고 판단 후 먼저 끊을 수도 있음)
해당 이미지는 캡처하지 않았습니다. wireshark로 직접 해보는 것도 좋을 것 같습니다.
정리
하나의 게시글을 많은 내용이 있었습니다. 따라서 해당 게시글로 모든 개념을 습득하기는 매우 부족합니다. 이 게시글에서 얻어갈 것은 딱 2개라고 볼 수 있습니다.
1. header는 여러 종류가 있다. 그리고 각각의 의미를 알면 좋다.
2. content-type은 body data에 꼭 알맞게 작성해주자.
위 2가지를 꼭 알아가셨으면 좋겠습니다.
참고자료
마지막
해당 내용은 틀릴 수도 있다는 것을 감안하여 봐주세요. 틀린 내용 및 오탈자 수정 요청 환영입니다.
'공유 > 기타' 카테고리의 다른 글
[REST API / GRAPHQL] REST API로 graphql 서버에 요청 보내기 (0) | 2022.09.19 |
---|---|
[VSCode] Organize Imports / import 정리하기 (0) | 2022.01.14 |
[Minio] prefix로 object 삭제하기 (0) | 2021.12.14 |
[AWS] node에서 aws-sdk 사용하기 (0) | 2021.10.31 |
[C#] DLL 만들기 - 2 / dll에서 winForm 사용하기 (0) | 2021.09.01 |