# 17. TIL

이지훈·2021년 5월 28일
1

TIL

목록 보기
17/33
post-thumbnail

1. HTTP message

HTTP 메시지는 ASCII로 인코딩된 텍스트 정보이며 여러 줄로 되어 있습니다.

이 HTTP 메시지는 소프트웨어, 브라우저, 프록시, 또는 웹 서버가 작성해서 설정파일, API, 인터페이스를 통해 제공됩니다.

1-1. HTTP Request와 Response

HTTP 요청과 응답은 비슷한 구조입니다.

1. 시작줄(Start-line)에 실행되어야하는 요청이나 요청 수행에 대한 결과가 기록되어있습니다.
2. 옵션으로 HTTP Header 세트가 들어가는데, 이는 요청에 대한 부가적인 설명 혹은 메시지 본문 설명이 기록됩니다.
3. 요청에 대한 모든 meta 정보가 전송되었음을 Blank line(empty line) 삽입으로 알립니다.
4. 요청과 관련된 내용이 옵션으로 들어가거나, 응답과 관련된 문서가 기록됩니다.

HTTP 메시지의 시작 줄과 HTTP 헤더를 묶어서 요청 헤드(head)라고 부릅니다.
이와 반대로 HTTP 메시지의 페이로드는 본문(body)이라고 합니다.

1-2. HTTP Request 구조

HTTP Request는 시작 줄, 헤더, 본문으로 구성되어있습니다.

1-2-1. 시작 줄

1. HTTP 메서드

GET, PUT,POST 혹은 HEAD, OPTIONS를 사용해 서버가 수행해야 할 동작을 나타냅니다.

2. 두번째는 요청 타겟 포맷입니다.

origin 형식: 끝에 '?'와 쿼리 문자열이 붙는 절대 경로입니다.

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 http://developer.mozilla.org/en-US/docs/Web/HTTP/Messages HTTP/1.1

authority 형식: 도메인 이름 및 옵션 포트(':'가 앞에 붙음)로 이루어진 URL의 authority component 입니다

CONNECT developer.mozilla.org:80 HTTP/1.1

asterisk 형식: OPTIONS와 함께 별표('*') 하나로 간단하게 서버 전체를 나타냅니다.

OPTIONS * HTTP/1.1

3. 마지막으로 HTTP 버전이 들어갑니다.
응답 메시지에서 써야 할 HTTP 버전을 알려주는 역할을 합니다.

1-2-2. 헤더

요청에 들어가는 HTTP 헤더는 HTTP 헤더의 기본 구조를 따릅니다.

헤더는 다음과 같은 종류가 있습니다.

General: Via와 같은 헤더는 메시지 전체에 적용됩니다.

Request: User-Agent, Accept-Type와 같은 헤더는 요청의 내용을 좀 더 구체화 시키고(Accept-Language), 컨텍스를 제공하기도 하며(Referer), 조건에 따른 제약 사항을 가하기도 하면서(If-None) 요청 내용을 수정합니다.

Entity: Content-Length와 같은 헤더는 요청 본문에 적용됩니다. 당연히 요청 내에 본문이 없는 경우 entity 헤더는 전송되지 않습니다.!

1-2-3. 본문

본문은 Request의 마지막에 들어가지만 필수적이지는 않습니다.

  1. GET, HEAD, DELETE , OPTIONS처럼 리소스를 가져오는 요청은 보통 본문이 필요가 없습니다.

single-resource bodies: 헤더 두 개(Content-Type와 Content-Length)로 정의된 단일 파일로 구성됩니다.

  1. POST 요청과 같이 HTML 폼과 관련된 요청은 업데이트를 하기 위해 서버에 데이터를 전송합니다.

multiple-resource bodies: 멀티파트 본문으로 구성되는 다중 리소스 본문에서는 파트마다 다른 정보를 지니게 됩니다. 보통 HTML 폼과 관련이 있습니다.

1-3. HTTP Response의 구조

시작 줄, 헤더, 본문의 구조로 이루어집니다.

1-3-1. 시작 줄(=상태 줄)

HTTP 응답의 status line은 다음과 같은 정보를 가집니다.

일반적으로 HTTP/1.1 404 Not Found. 와 같은 모습을 보입니다.

  1. 프로토콜 버전

보통 HTTP/1.1입니다.

  1. 상태 코드

요청의 성공 여부를 나타냅니다. 200, 404 혹은 302입니다.

  1. 상태 텍스트

상태 코드에 대해 간략하게 설명한 글입니다. Not Found.

1-3-2. Header

응답에 들어가는 HTTP 헤더는 대소문자를 구분하지 않는 문자열 다음에 콜론(':')이 오며, 그 뒤에 오는 값은 구조가 헤더에 따라 달라집니다.

헤더는 Request와 같은 종류의 헤더가 있습니다.

General 헤더

Via와 같은 헤더는 메시지 전체에 적용

Response 헤더

VaryAccept-Ranges와 같은 헤더는 상태 줄에 미처 들어가지 못했던 서버에 대한 추가 정보를 제공

Entity 헤더

Content-Length와 같은 헤더는 요청 본문에 적용됩니다.

1-3-3. 본문

본문은 Response의 마지막에 들어가나 필수적인 것은 아닙니다. (ex. 201, 204)

본문도 3가지로 나뉩니다.

1. 길이를 아는 single-resource bodies

헤더 두개(Content-TypeContent-Length)로 정의 합니다.

2. 길이를 모르는 single-resource bodies

Transfer-Encodingchunked로 설정되어 있으며, 파일은 청크로 나뉘어 인코딩 되어 있습니다.

3. multiple-resource bodies

서로 다른 정보를 담고 있는 멀티파트로 이루어진 본문

MDN

1-3-4. Client error Response

HTTP 상태 코드는 200 = 성공, 400 = 클라이언트가 요청 잘못함, 500 = 서버가 잘못함과 같이 각 상황에 맞는 코드가 표준으로 정해져있으며 자세한 내용은 이곳에 자세히 기록되어 있습니다.

  • 1xx(Information) : 요청을 받았으며 프로세스 진행
  • 2xx(Successful) : 요청한 작업을 서버가 성공적으로 수행함.
  • 3xx(Redirection) : 요청 완료를 위한 추가적 조치 필요
  • 4xx(Client Error) : 요청의 문법이 잘못됐거나 그 밖의 이유로 요청을 처리할 수 없음
  • 5xx(Server Error) : 서버의 문제로 유효한 요청에 대한 충족에 실패함

저는 백엔드 위주로 상태 코드를 알아보겠습니다.
더 자세한 정보는 여기를 참고하세요.

1-3-4-1. 200 번대

만약 클라이언트 쪽에서 디테일한 상태를 요구한다면, 이 200번대의 상태 코드를 적극적으로 사용하여 클라이언트에게 더 자세한 정보를 알려줄 수 있음

200: ok

요청이 백엔드 서버에서 성공적으로 이루어지고 난 뒤 오는 응답코드 🤗

201: Created

POST 메소드의 요청에 따라 백엔드 서버에 데이터가 성공적으로 생성 또는 수정되었을 때 보내는 코드 😘

204: No Content

요청이 정상적으로 수행되었고, 이 요청과 관련되었던 컨텐츠 또한 더 이상 깔끔하게 존재하지 않음을 의미하나, 이 상태 코드는 클라이언트가 서버에게 요청을 보내서 뭔가를 삭제해야하는 응답으로 사용될 수도 있다. 😕

1-3-4-2. 300 번대

정상적인 방법으로 해당 리소스에 접근할 수 없고 URL을 통해 리소스에 접근해야할 때, 서버에서 해당 리소스의 정보 상태를 알려주는 코드이다.

301: Moved Permanetly

브라우저는 자신의 대한 요청의 응답으로 301을 받으면 HTTP 헤더에 들어있는 Location 필드를 찾아보고, 해당 필드가 존재할 경우 Location 필드에 담긴 URL로 자동으로 리다이렉션한다.

일반적으로 301은 HTTP 프로토콜로 접속한 사용자를 HTTPS 프로토콜을 사용해야만 접근 가능한 포트로 보내버릴 때 많이 사용한다.

304: Not Modified

클라이언트가 요청한 리소스가 이전 요청떄와 비교해보았을 때 전혀 달라진 점이 없다는 것을 의미한다. 즉, 말 그대로 Not Modified, 수정되지 않음이다.

서버가 응답으로 이 상태 코드를 보내주면 클라이언트는 굳이 서버에게 리소스를 재전송받아야할 필요가 없기에 자신이 캐싱해놓았던 리소스를 사용하게되며, 이 과정에서 불필요한 통신 페이로드의 낭비를 줄일 수 있다.

브라우저 역시 이 응답을 위한 자체 캐싱 기능을 가지고 있으며, 만약 304 상태 코드를 응답으로 받았는데 캐싱된 리소스(Cached Resource)가 없는 경우에는 빈 화면을 띄우거나 에러 화면이 노출된다.

1-3-4-3. 400 번대

400 번대는 클라이언트가 서버에게 보낸 요청이 잘못된 경우를 의미한다. 프론트엔드에게 결투를 신청하자 👊

400: Bad Request

클라이언트가 요청 잘못 날림을 의미한다.
HTTP Response body를 보거나 백엔드 어플리케이션의 로그를 까봐야한다.

401: Unauthorized

인증되지 않은 사용자가 인증이 필요한 리소스를 요청하는 경우에 인증이 필요하다라고 알려주는 상태 코드이다.

403: Forbidden

401과 다르게 403은 이 리소스를 요청하는 것은 무조건 금지라고 말하고 있는 것이다.
HTTPS와 HTTP 프로토콜을 잘 구별해서 사용해야한다.

404: Not Found

요청한 리소스가 존재하지 않다는 것

405: Method Not Allowed

백엔드 프레임워크의 경우 특정 컨트롤러에 해당 메소드를 사용하는 로직이 없다면 현재 리소스에 맞지않는 메소드를 사용했음을 의미한다.

406: No Acceptable

어떤 컨텐츠 타입의 리소스를 응답으로 내려줄 것인지는 전적으로 서버가 결정하게 되는데 이 과정을 서버 주도 컨텐츠 협상이라고 한다.

만약 클라이언트가 요청한 컨텐츠 타입을 모두 탐색했는데도 불구하고 알맞은 리소스가 없을 경우 서버는 406 상태 코드와 함께 찾는 컨텐츠 타입과 맞는 리소스가 없다는 응답을 주는 것이다.

408: Request Timeout

HTTP 프로토콜을 사용하여 통신을 할 때는 반드시 클라이언트와 서버 간의 연결을 생성하고, 그 이후에 요청 본문에 해당하는 데이터를 전송하게 된다.

연결은 되었지만, 서버가 클라이언트의 요청 본문을 받지 못할 때 발생한다.

429: Too Many Requests

클라이언트가 서버에 짧은 시간동안 요청을 빠르게 보내는 경우에 발생하거나 유로 API 사용중이라면 사용 횟수를 초과해서 발생한다.

1-3-4-4. 500 번대

500 번대는 서버에서 문제가 일어난 경우인데, 멱살 잡힐 준비를 하자... 😵

500: Internal Server Error

백엔드 어플리케이션 내에서 알 수 없는 에러가 발생했다는 의미다. 💀

이 경우 제대로 핸들링되지 않은 에러가 발생한 경우가 많다. 보안 사고의 우려가 많으므로, 서버 로그를 까보거나 SentryBugsnag과 같은 에러 모니터링 솔루션을 적극 활용해야한다.

502: Bad Gateway

주로 백엔드 어플리케이션이 죽은 상황에 발생한다.

연산이 필요한 요청이 아닌, 파일을 찾아서 보내주기만 하는 간단한 요청 같은 경우는 굳이 안 그래도 바쁜 백엔드 어플리케이션에게 시킬 필요가 없으므로 이런 서버 엔진이 대신 처리한다.

그래서 백엔드에서는 앞 단에 아예 프록시 서버를 두어서 문지기 역할을 시킨다. 이때 이 프록시 서버와 백엔드 어플리케이션 간의 연결된 추상적인 통로를게이트웨이라고 부른다. 백엔드 어플리케이션이 죽어버릴 경우 앞 단의 문지기인 프록시 서버는 백엔드 어플리케이션에게 아무런 응답을 받지 못하게 되고, 클라이언트에게 502 Bad Gateway라는 응답을 보낸다.

503: Service Unavailable

서버가 요청을 처리할 준비가 되지 않았음을 의미한다.

502와 비교해서 503일시적으로 서버에 부하가 심해서 현재 요청을 핸들링 할 수 있는 여유가 없는 경우에 많이 사용된다.

AWS Lambda에서는 요청을 처리할 때 컨테이너의 동시 실행 갯수를 초과할 정도의 리소스가 필요하거나 어떤 작업의 처리 시간이 Lambda에 설정된 컨테이너의 최대 수명 시간을 초과했을 경우에 발생하기도 한다.

429 Too Many Requests와 동일하게 응답 헤더의 Retry-After 필드를 사용하여 잠시 후에 다시 시도하라는 의미를 클라이언트에게 전달해줄 수 있다.

504: Gateway Timeout

백엔드 아키텍처 내부에서 서버끼리 주고받는 요청에서의 타임아웃을 의미한다. ⌚

백엔드의 아키텍처는 단순히 백엔드 어플리케이션 하나로만 구성된 것이 아니기 때문에, 클라이언트의 요청이 서버에 닿은 뒤에도 백엔드 어플리케이션끼리의 통신이 발생하게 된다.

만약 프록시 서버 역할을 맡은 Nginx가 백엔드 어플리케이션에 클라이언트의 요청을 전달했는데, 백엔드 어플리케이션이 일정 시간 동안 응답을 하지 않는 경우 Nginx는 클라이언트에게 504 Geteway Timeout을 내려주게 되는 것이다.

505: HTTP Version Not Supported

1.0 이하의 HTTP 프로토콜을 사용할 경우 지원되지 않는 프로토콜이므로 발생한다.

506: Variant Also Negotiates

서버 내부 구성(값)에 오류가 있어 반환되는 값에 컨텐츠 협상이 순환 참조로 이루어져 있다는걸 알려주는 코드

507: Insufficient Storage

서버 내부 구성(값)에 오류가 있어 선택된 가변 리소스는 투명한 콘텐츠 협상에 참여하도록 구성되므로 협상 과정에서 적절한 끝점이 아님을 알려주는 코드

508: Loop Detected

서버가 요청을 처리하는 동안 무한 루프를 감지한 경우 발생

510: Not Extended

서버가 요청을 이행하려면 요청에 대한 추가 확장이 필요함

511: Network Authentication Required

사용자가 네트워크 엑세스 권한이 필요한 경우 뜨는 응답코드. 보통 네트워크에 엑세스할 때 로그인이 필요한 경우 주로 뜬다.

더 자세히 아시고 싶으시면 나무위키를 참고해주세요.

profile
꾸준하게 🐌

0개의 댓글