HTTP 메시지는 ASCII로 인코딩된 텍스트 정보이며 여러 줄로 되어 있습니다.
이 HTTP 메시지는 소프트웨어, 브라우저, 프록시, 또는 웹 서버가 작성해서 설정파일, API, 인터페이스를 통해 제공됩니다.
HTTP 요청과 응답은 비슷한 구조입니다.
1. 시작줄(Start-line)에 실행되어야하는 요청이나 요청 수행에 대한 결과가 기록되어있습니다.
2. 옵션으로 HTTP Header 세트가 들어가는데, 이는 요청에 대한 부가적인 설명 혹은 메시지 본문 설명이 기록됩니다.
3. 요청에 대한 모든 meta 정보가 전송되었음을 Blank line(empty line) 삽입으로 알립니다.
4. 요청과 관련된 내용이 옵션으로 들어가거나, 응답과 관련된 문서가 기록됩니다.
HTTP 메시지의 시작 줄과 HTTP 헤더를 묶어서 요청 헤드(head)라고 부릅니다.
이와 반대로 HTTP 메시지의 페이로드는 본문(body)이라고 합니다.
HTTP Request는 시작 줄, 헤더, 본문으로 구성되어있습니다.
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 버전을 알려주는 역할을 합니다.
요청에 들어가는 HTTP 헤더는 HTTP 헤더의 기본 구조를 따릅니다.
헤더는 다음과 같은 종류가 있습니다.
General
: Via와 같은 헤더는 메시지 전체에 적용됩니다.
Request
: User-Agent, Accept-Type와 같은 헤더는 요청의 내용을 좀 더 구체화 시키고(Accept-Language), 컨텍스를 제공하기도 하며(Referer), 조건에 따른 제약 사항을 가하기도 하면서(If-None) 요청 내용을 수정합니다.
Entity
: Content-Length와 같은 헤더는 요청 본문에 적용됩니다. 당연히 요청 내에 본문이 없는 경우 entity 헤더는 전송되지 않습니다.!
본문은 Request의 마지막에 들어가지만 필수적이지는 않습니다.
GET
, HEAD
, DELETE
, OPTIONS
처럼 리소스를 가져오는 요청은 보통 본문이 필요가 없습니다.
single-resource bodies
: 헤더 두 개(Content-Type와 Content-Length)로 정의된 단일 파일로 구성됩니다.
POST
요청과 같이 HTML 폼과 관련된 요청은 업데이트를 하기 위해 서버에 데이터를 전송합니다.
multiple-resource bodies
: 멀티파트 본문으로 구성되는 다중 리소스 본문에서는 파트마다 다른 정보를 지니게 됩니다. 보통 HTML 폼과 관련이 있습니다.
시작 줄, 헤더, 본문의 구조로 이루어집니다.
HTTP 응답의 status line은 다음과 같은 정보를 가집니다.
일반적으로 HTTP/1.1 404 Not Found.
와 같은 모습을 보입니다.
보통
HTTP/1.1
입니다.
요청의 성공 여부를 나타냅니다.
200
,404
혹은302
입니다.
상태 코드에 대해 간략하게 설명한 글입니다.
Not Found.
응답에 들어가는 HTTP 헤더는 대소문자를 구분하지 않는 문자열 다음에 콜론(':')
이 오며, 그 뒤에 오는 값은 구조가 헤더에 따라 달라집니다.
헤더는 Request와 같은 종류의 헤더가 있습니다.
General 헤더
Via
와 같은 헤더는 메시지 전체에 적용
Response 헤더
Vary
와Accept-Ranges
와 같은 헤더는 상태 줄에 미처 들어가지 못했던 서버에 대한 추가 정보를 제공
Entity 헤더
Content-Length와 같은 헤더는 요청 본문에 적용됩니다.
본문은 Response의 마지막에 들어가나 필수적인 것은 아닙니다. (ex. 201
, 204
)
본문도 3가지로 나뉩니다.
1. 길이를 아는 single-resource bodies
헤더 두개(
Content-Type
와Content-Length
)로 정의 합니다.
2. 길이를 모르는 single-resource bodies
Transfer-Encoding
가chunked
로 설정되어 있으며, 파일은 청크로 나뉘어 인코딩 되어 있습니다.
3. multiple-resource bodies
서로 다른 정보를 담고 있는 멀티파트로 이루어진 본문
HTTP 상태 코드는 200 = 성공
, 400 = 클라이언트가 요청 잘못함
, 500 = 서버가 잘못함
과 같이 각 상황에 맞는 코드가 표준으로 정해져있으며 자세한 내용은 이곳에 자세히 기록되어 있습니다.
저는 백엔드 위주로 상태 코드를 알아보겠습니다.
더 자세한 정보는 여기를 참고하세요.
만약 클라이언트 쪽에서 디테일한 상태를 요구한다면, 이 200번대의 상태 코드를 적극적으로 사용하여 클라이언트에게 더 자세한 정보를 알려줄 수 있음
요청이 백엔드 서버에서 성공적으로 이루어지고 난 뒤 오는 응답코드 🤗
POST 메소드의 요청에 따라 백엔드 서버에 데이터가 성공적으로 생성 또는 수정되었을 때 보내는 코드 😘
요청이 정상적으로 수행되었고, 이 요청과 관련되었던 컨텐츠 또한 더 이상 깔끔하게 존재하지 않음을 의미하나, 이 상태 코드는 클라이언트가 서버에게 요청을 보내서 뭔가를 삭제해야하는 응답으로 사용될 수도 있다. 😕
정상적인 방법으로 해당 리소스에 접근할 수 없고 URL을 통해 리소스에 접근해야할 때, 서버에서 해당 리소스의 정보 상태를 알려주는 코드이다.
브라우저는 자신의 대한 요청의 응답으로 301을 받으면 HTTP 헤더에 들어있는 Location 필드를 찾아보고, 해당 필드가 존재할 경우 Location 필드에 담긴 URL로 자동으로 리다이렉션한다.
일반적으로 301
은 HTTP 프로토콜로 접속한 사용자를 HTTPS 프로토콜을 사용해야만 접근 가능한 포트로 보내버릴 때 많이 사용한다.
클라이언트가 요청한 리소스가 이전 요청떄와 비교해보았을 때 전혀 달라진 점이 없다는 것을 의미한다. 즉, 말 그대로 Not Modified
, 수정되지 않음이다.
서버가 응답으로 이 상태 코드를 보내주면 클라이언트는 굳이 서버에게 리소스를 재전송받아야할 필요가 없기에 자신이 캐싱해놓았던 리소스를 사용하게되며, 이 과정에서 불필요한 통신 페이로드의 낭비를 줄일 수 있다.
브라우저 역시 이 응답을 위한 자체 캐싱 기능을 가지고 있으며, 만약 304 상태 코드를 응답으로 받았는데 캐싱된 리소스(Cached Resource)가 없는 경우에는 빈 화면을 띄우거나 에러 화면이 노출된다.
400
번대는 클라이언트가 서버에게 보낸 요청이 잘못된 경우를 의미한다. 프론트엔드에게 결투를 신청하자 👊
클라이언트가 요청 잘못 날림을 의미한다.
HTTP Response body를 보거나 백엔드 어플리케이션의 로그를 까봐야한다.
인증되지 않은 사용자가 인증이 필요한 리소스를 요청하는 경우에 인증이 필요하다라고 알려주는 상태 코드이다.
401
과 다르게 403
은 이 리소스를 요청하는 것은 무조건 금지라고 말하고 있는 것이다.
HTTPS와 HTTP 프로토콜을 잘 구별해서 사용해야한다.
요청한 리소스가 존재하지 않다는 것
백엔드 프레임워크의 경우 특정 컨트롤러에 해당 메소드를 사용하는 로직이 없다면 현재 리소스에 맞지않는 메소드
를 사용했음을 의미한다.
어떤 컨텐츠 타입의 리소스를 응답으로 내려줄 것인지는 전적으로 서버가 결정하게 되는데 이 과정을 서버 주도 컨텐츠 협상
이라고 한다.
만약 클라이언트가 요청한 컨텐츠 타입을 모두 탐색했는데도 불구하고 알맞은 리소스가 없을 경우 서버는 406
상태 코드와 함께 찾는 컨텐츠 타입과 맞는 리소스가 없다는 응답을 주는 것이다.
HTTP 프로토콜을 사용하여 통신을 할 때는 반드시 클라이언트와 서버 간의 연결을 생성하고, 그 이후에 요청 본문에 해당하는 데이터를 전송하게 된다.
연결은 되었지만, 서버가 클라이언트의 요청 본문을 받지 못할 때 발생한다.
클라이언트가 서버에 짧은 시간동안 요청을 빠르게 보내는 경우에 발생하거나 유로 API 사용중이라면 사용 횟수를 초과해서 발생한다.
500
번대는 서버에서 문제가 일어난 경우인데, 멱살 잡힐 준비를 하자... 😵
백엔드 어플리케이션 내에서 알 수 없는 에러가 발생했다는 의미다. 💀
이 경우 제대로 핸들링되지 않은 에러가 발생한 경우가 많다. 보안 사고의 우려가 많으므로, 서버 로그를 까보거나 Sentry
나 Bugsnag
과 같은 에러 모니터링 솔루션을 적극 활용해야한다.
주로 백엔드 어플리케이션이 죽은 상황에 발생한다.
연산이 필요한 요청이 아닌, 파일을 찾아서 보내주기만 하는 간단한 요청 같은 경우는 굳이 안 그래도 바쁜 백엔드 어플리케이션에게 시킬 필요가 없으므로 이런 서버 엔진이 대신 처리한다.
그래서 백엔드에서는 앞 단에 아예 프록시 서버를 두어서 문지기 역할을 시킨다. 이때 이 프록시 서버와 백엔드 어플리케이션 간의 연결된 추상적인 통로를게이트웨이
라고 부른다. 백엔드 어플리케이션이 죽어버릴 경우 앞 단의 문지기인 프록시 서버는 백엔드 어플리케이션에게 아무런 응답을 받지 못하게 되고, 클라이언트에게 502 Bad Gateway
라는 응답을 보낸다.
서버가 요청을 처리할 준비가 되지 않았음을 의미한다.
502
와 비교해서 503
은 일시적
으로 서버에 부하가 심해서 현재 요청을 핸들링 할 수 있는 여유가 없는 경우에 많이 사용된다.
AWS Lambda
에서는 요청을 처리할 때 컨테이너
의 동시 실행 갯수를 초과할 정도의 리소스가 필요하거나 어떤 작업의 처리 시간이 Lambda
에 설정된 컨테이너
의 최대 수명 시간을 초과했을 경우에 발생하기도 한다.
429 Too Many Requests
와 동일하게 응답 헤더의 Retry-After
필드를 사용하여 잠시 후에 다시 시도하라는 의미를 클라이언트에게 전달해줄 수 있다.
백엔드 아키텍처 내부에서 서버끼리 주고받는 요청에서의 타임아웃을 의미한다. ⌚
백엔드의 아키텍처는 단순히 백엔드 어플리케이션 하나로만 구성된 것이 아니기 때문에, 클라이언트의 요청이 서버에 닿은 뒤에도 백엔드 어플리케이션끼리의 통신이 발생하게 된다.
만약 프록시 서버 역할을 맡은 Nginx
가 백엔드 어플리케이션에 클라이언트의 요청을 전달했는데, 백엔드 어플리케이션이 일정 시간 동안 응답을 하지 않는 경우 Nginx
는 클라이언트에게 504 Geteway Timeout
을 내려주게 되는 것이다.
1.0 이하의 HTTP 프로토콜을 사용할 경우 지원되지 않는 프로토콜이므로 발생한다.
서버 내부 구성(값)에 오류가 있어 반환되는 값에 컨텐츠 협상
이 순환 참조로 이루어져 있다는걸 알려주는 코드
서버 내부 구성(값)에 오류가 있어 선택된 가변 리소스는 투명한 콘텐츠 협상에 참여하도록 구성되므로 협상 과정에서 적절한 끝점이 아님을 알려주는 코드
서버가 요청을 처리하는 동안 무한 루프를 감지한 경우 발생
서버가 요청을 이행하려면 요청에 대한 추가 확장이 필요함
사용자가 네트워크 엑세스 권한이 필요한 경우 뜨는 응답코드. 보통 네트워크에 엑세스할 때 로그인이 필요한 경우 주로 뜬다.
더 자세히 아시고 싶으시면 나무위키를 참고해주세요.