완벽한 다음 행보는 없다.

HTTP란 무엇인가? - 특징, 구조, 메서드, 헤더, 응답코드 본문

네트워크

HTTP란 무엇인가? - 특징, 구조, 메서드, 헤더, 응답코드

We On Fire 2023. 8. 20. 21:28

HTTP란 무엇인가

HTTP(Hypertext Transfer Protocol)는 웹 브라우저와 웹 서버 사이에서 데이터를 주고받는 데 사용되는 프로토콜입니다. HTTP는 클라이언트와 서버 간의 통신을 관리하며, 웹 페이지를 요청하고 전달하는 데 사용됩니다.

특징

1. 클라이언트-서버 모델

HTTP는 클라이언트(웹 브라우저 등)와 서버(웹 서버) 간의 통신을 위한 모델을 제공합니다. 클라이언트는 서버에 요청(Request)을 보내고, 서버는 클라이언트에 응답(Response)을 보냅니다.

2. 무상태(Stateless)

HTTP는 기본적으로 무상태 프로토콜입니다. 즉, 각각의 요청과 응답은 이전 요청과 응답과는 독립적으로 처리됩니다. 서버는 각 요청을 별개의 요청으로 처리하며, 클라이언트의 상태 정보를 서버에 유지하지 않습니다.

3. 요청 메서드

HTTP는 다양한 요청 메서드를 제공하여 서버에 어떤 동작을 수행할지 지정할 수 있습니다. 주요 요청 메서드로는 GET(리소스 조회), POST(리소스 생성), PUT(리소스 수정), DELETE(리소스 삭제) 등이 있습니다.

4. 상태 코드

서버는 요청에 대한 응답으로 상태 코드를 반환합니다. 상태 코드는 요청이 성공했는지 또는 어떤 종류의 에러가 발생했는지를 나타내는 숫자로 구성됩니다. 예를 들어, 200은 성공, 404는 찾을 수 없음, 500은 서버 내부 오류 등을 나타냅니다

5. 헤더와 본문

HTTP 요청과 응답은 헤더(Header)와 본문(Body)으로 구성됩니다. 헤더는 요청 또는 응답의 메타데이터를 포함하며, 본문은 실제 데이터를 포함합니다. 헤더는 요청의 세부 정보나 응답의 속성을 설정하는 데 사용됩니다.

구조

HTTP 요청과 응답은 각각의 메시지로 구성되며, 이 메시지는 여러 부분으로 나누어져 있습니다.

요청구조

1. 메서드(Method)

요청의 목적을 나타내는 HTTP 메서드(GET, POST, PUT, DELETE 등)가 포함됩니다.

2. URL(Path)

요청하는 리소스의 경로가 포함됩니다.

3. 헤더(Headers)

요청의 부가 정보를 담고 있는 헤더가 포함됩니다. 헤더는 키-값 쌍으로 이루어져 있으며, 요청의 속성이나 메타데이터를 포함합니다.

4. 요청 본문(Request Body)

POST, PUT 등의 메서드에서 사용되며, 클라이언트가 서버로 보내는 데이터가 담겨있습니다.

GET <https://naver.com> HTTP/1.1

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...

Upgrade-Insecure-Requests: 1

 

응답 구조

1. 상태 코드(Status Code)

서버의 응답 상태를 나타내는 세 자리 숫자로 이루어진 코드가 포함됩니다. 예를 들어, 200은 성공, 404는 찾을 수 없음, 500은 서버 내부 오류를 나타냅니다.

2. 헤더(Headers)

응답의 부가 정보를 담고 있는 헤더가 포함됩니다. 요청 헤더와 마찬가지로 키-값 쌍으로 이루어져 있으며, 응답의 속성이나 메타데이터를 포함합니다.

3. 응답 본문(Response Body)

서버가 클라이언트에게 보내는 데이터가 담겨있습니다. 주로 HTML, JSON, XML 등의 형식으로 데이터가 전달됩니다.

HTTP/1.1 200 OK
Connection: keep-alive
Content-Encoding: gzip
Content-Length: 35653
Content-Type: text/html;
//한줄 띄우고 응답 바디
<!DOCTYPE html><html lang="ko" data-reactroot=""><head><title...

메서드

HTTP 메서드는 클라이언트와 서버 간의 통신에서 어떤 동작을 수행할 것인지를 지정하는 방법입니다. 각 메서드는 특정한 의미와 역할을 가지며, 서버는 클라이언트의 요청에 따라 해당 메서드에 맞는 작업을 수행합니다. 아래는 주요한 HTTP 메서드들과 그 역할에 대한 설명입니다:

  1. GET: 서버에서 리소스를 요청하는 메서드로, 주로 데이터 조회나 읽기 작업에 사용됩니다. 요청의 매개변수는 URL에 포함되어 전달됩니다. get 요청은 캐시가 됩니다. 그리고 브라우저에 기록됩니다.
  2. POST: 서버로 데이터를 전송하여 리소스를 생성하거나 변경하는 메서드입니다. 주로 데이터의 생성 또는 수정 작업에 사용됩니다. 요청 데이터는 요청 본문에 담겨서 전달됩니다.
  3. PUT: 서버에 리소스를 생성하거나 업데이트하는 메서드로, 주로 데이터의 수정 작업에 사용됩니다. 요청 데이터는 요청 본문에 담겨서 전달됩니다.
  4. DELETE: 서버에서 리소스를 삭제하는 메서드로, 주로 데이터 삭제 작업에 사용됩니다.
  5. PATCH: 서버에 리소스를 일부만 수정하는 메서드입니다. PUT과 비슷하지만, PATCH는 변경할 데이터만 요청 본문에 담아서 보내고, 나머지 데이터는 변경하지 않습니다.
  6. HEAD: GET과 비슷하지만, 실제 데이터를 요청하지 않고 응답 헤더만 가져오는 메서드입니다. 주로 리소스의 메타데이터나 상태 정보를 확인할 때 사용됩니다.
  7. OPTIONS: 서버가 지원하는 메서드나 리소스에 대한 정보를 요청하는 메서드입니다. 주로 CORS (Cross-Origin Resource Sharing) 관련 요청에서 사용됩니다.

HTTP 메서드는 RESTful API 구현 등에서 중요한 역할을 하며, 클라이언트와 서버 간의 효율적인 통신을 위해 적절하게 선택되고 사용되어야 합니다. 주소를 자원이라고 보고, 메서드를 동사라고 보는 개발 방식이 바로 REST 입니다.

HTTP 헤더

공통 헤더

요청과 응답에 모두 사용되는 헤더입니다. 이 중에서 Content 시리즈는 엔티티 헤더라고 불립니다.

Date

HTTP 메시지가 만들어진 시각입니다. 자동으로 만들어집니다.

Date: Thu, 12 Jul 2018 03:12:27 GMT

Cache-Control

캐싱 정책을 제어하기 위해 사용되며, 클라이언트나 프록시 서버에 캐싱 관련 정보를 제공합니다.

Content-Length

요청과 응답 메시지의 본문 크기를 바이트 단위로 표시해줍니다. 메시지 크기에 따라 자동으로 만들어집니다.

Content-Length: 52

Content-Type

Content-Type: text/html; charset=utf-8

컨텐츠의 타입(MIME)과 문자열 인코딩(utf-8 등등)을 명시할 수 있습니다. 조금 뒤에 나오는 Accept 헤더, Accept-Charset 헤더와 대응됩니다. 위에 예시로 든 헤더는 현재 메시지 내용이 text/html 타입이고 문자열은 utf-8 문자열임을 알려줍니다.

프런트엔드에서 서버로 데이터를 보낼 때는 text/html 이런 것 대신 www-url-form-encoded나 multipart/form-data같은 게 Content-Type이 됩니다.

Content-Language

사용자의 언어를 뜻합니다. 요청이나 응답이 무슨 언어인지와는 관련 없습니다. 예를 들어 한국 사람한테 일본어를 가르치는 사이트일 경우, 페이지 언어는 일본어더라도 Content-Language는 ko-KR일 수 있습니다.

Content-Encoding

Content-Encoding: gzip, deflate

Content-Encoding은 컨텐츠 압축된 방식입니다. 응ㅇ답 컨텐츠를 br, gzip, deflate 등의 알고리즘으로 압축해서 보내면, 브라우저가 알아서 해제해서 사용합니다. 이 외에도 다양한 압축 알고리즘이 존재합니다. 컨텐츠 용량이 줄어들기 때문에 압축을 권장합니다. 요청이나 응답 전송 속도도 빨라지고, 데이터 소모량도 줄어들기 때문에 가능하면 압축해두세요.

요청헤더

Host

서버의 도메인 네임이 나타나는 부분입니다(포트 포함).

Host: www.naver.com

Host 헤더는 반드시 하나가 존재해야 합니다.

User-Agent

Host보다 더 유명한 헤더는 User-Agent입니다. 현재 사용자가 어떤 클라이언트를 이용해 요청을 보냈는지 나옵니다.

User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36

헤더가 변경 가능하긴 하지만 대부분의 사람들이 유저 에이전트를 조작하지 않고 그대로 보내기 때문에, 유저 에이전트 헤더를 활용해서 접속자 통계 등을 내곤 합니다. 또한 이를 활용해서 IE로 접속한 사람들을 찾아낸 후, IE는 지원하지 않으니 크롬으로 접속해주세요와 같은 메시지를 표시하기도 하고요.

Accept

Accept 시리즈를 알아봅시다. Accept 헤더는 요청을 보낼 때 서버에 이런 타입(MIME)의 데이터를 보내줬으면 좋겠다고 명시할 때 사용합니다. 예를 들어 요청의 헤더로

Accept: text/html

를 보내면 HTML 형식인 응답을 처리하겠다는 뜻입니다.

Accept: image/png, image/gif

콤마로 여러 타입을 동시에 적어줄 수도 있고, *(와일드카드)로 "텍스트이기만 하면 돼"라고 적어줄 수도 있습니다.

Accept 시리즈라고 한 이유는 Accept-Encoding, Accept-Charset, Accept-Language 등도 있기 때문인데요. 공통 헤더의 Content 시리즈와 대응됩니다. Accept로 원하는 형식을 보내면, 서버가 그에 맞춰 보내주면서 응답 헤더의 Content를 알맞게 설정하겠죠.

Accept-Charset: utf-8

Charset은 문자 인코딩(UTF-8 등)을 명시하는 부분이고, Language는 원하는 언어, Encoding은 원하는 컨텐츠 압축 방식입니다.

뭘 적어야할지 모르겠다면 *(와일드카드)를 적거나, 그냥 브라우저가 알아서 설정해서 보내는 Accept를 사용하면 됩니다.

Authorization

Authorization 헤더는 인증 토큰(JWT, Bearer 토큰)을 서버로 보낼 때 사용하는 헤더입니다. API 요청같은 것을 할 때 토큰이 없으면 거절당하기 때문에 이 때, Authorization을 사용하면 됩니다.

Authorization: Bearer XXXXXXXXXXXXX

보통 Basic이나 Bearer같은 토큰의 종류를 먼저 알리고 그 다음에 실제 토큰 문자를 적어 보냅니다.

Origin

POST같은 요청을 보낼 때, 요청이 어느 주소에서 시작되었는지를 나타냅니다. 여기서 요청을 보낸 주소와 받는 주소가 다르면 CORS 문제가 발생하기도 합니다.

Referer

Referer: https://www.naver.com/news/Weather

이 페이지 이전의 페이지 주소가 담겨 있습니다. 이 헤더를 사용하면 어떤 페이지에서 지금 페이지로 들어왔는지 알 수 있기 때문에 애널리틱스같은 데 많이 사용됩니다.

응답 헤더

Access-Control-Allow-Origin

요청을 보내는 프론트 주소와 받는 백엔드 주소가 다르면 CORS 에러가 발생합니다. 이 때 서버에서 응답 메시지 Access-Control-Allow-Origin 헤더에 프론트 주소를 적어주어야 에러가 나지 않습니다.

Access-Control-Allow-Origin: www.naver.com

프로토콜, 서브도메인, 도메인, 포트 중 하나만 달라도 CORS 에러가 발생합니다. *을 사용하면 모든 주소에 CORS 요청을 허용하면 가능합니다. 단 그만큼 보안이 취약해집니다.

유사한 헤더로 Access-Control-Request-Method, Access-Control-Request-Headers, Access-Control-Allow-Methods, Access-Control-Allow-Headers 등이 있습니다. Request랑 Allow에서 Method 단수 복수 주의하세요!

CORS 요청 시에는 미리 OPTIONS 주소로 서버가 CORS를 허용하는지 물어봅니다. 이 때 Access-Control-Request-Method로 실제로 보내고자 하는 메서드를 알리고, Access-Control-Request-Headers로 실제로 보내고자 하는 헤더들을 알립니다. Allow 친구들은 Request에 대응되는 애들로, 서버가 허용하는 메서드와 헤더를 응답하는데 사용됩니다. Request랑 Allow가 일치하면 CORS 요청이 이루어지는 것이죠.

Allow

Allow 헤더는 Access-Control-Allow-Methods랑 비슷하지만, CORS 요청 외에도 적용된다는 데에 차이가 있습니다. 즉 GET www.naver.com은 되고, POST www.naver.com은 허용하지 않는 경우, 405 Method Not Allowed 에러를 응답하면서 헤더로

Allow: GET

를 같이 보내면 됩니다. GET 요청만 받겠다는 뜻입니다.

Content-Disposition

응답 본문을 브라우저가 어떻게 표시해야 할지 알려주는 헤더입니다. inline인 경우 웹페이지 화면에 표시되고, attachment인 경우 다운로드됩니다.

Content-Disposition: inline

다운로드되길 원하는 파일은 attachment로 값을 설정하고, filename 옵션으로 파일명까지 지정해줄 수 있습니다. 파일용 서버인 경우 이 태그를 자주 사용하게 될 것입니다.

Location

300번대 응답이나 201 Created 응답일 때 어느 페이지로 이동할지를 알려주는 헤더입니다.

HTTP/1.1 302 Found

이런 응답이 왔다면 브라우저는 / 주소로 리다이렉트합니다.

Content-Security-Policy

다른 외부 파일들을 불러오는 경우, 차단할 소스와 불러올 소스를 여기에 명시할 수 있습니다. 하나의 웹 페이지는 다양한 외부 소스들을 불러옵니다. 이미지도 불러오고 script 태그로 자바스크립트 파일들도 불러옵니다. 해커들에 의해 원하지 않는 파일을 불러오게 될 수도 있습니다. XSS 공격 같은 것이 하나의 예시입니다. 이럴 때 Content-Security-Policy로 허용할 외부 소스만 지정할 수 있습니다.

Content-Security-Policy: default-src 'self'

self로 지정하면 자신의 도메인의 파일들만 가져올 수 있습니다. www.naver.com에서는 www.naver.com/logo.jpg를 가져올 수 있지만, www.nero.com/logo.jpg는 못 가져오는 것이죠. https:로 지정하면 https를 통해서만 파일을 가져올 수 있게 됩니다. 'none'으로 지정하면 가져올 수 없습니다. 

 

쿠키, 세션 헤더

웹 자원을 효율적으로 사용하기 위해 캐싱이 중요합니다. 똑같은 데이터를 계속 받을 필요는 없습니다. 쿠키는 클라이언트와 서버간 데이터를 주고 받는 가장 간단한 방법 중 하나입니다. 쿠키에 대한 설정은 헤더를 통해 할 수 있습니다.

캐시

브라우저에 응답으로 온 HTML이나 JSON같은 데이터가 저장되어 나중에 서버에 요청을 보내지 않아도 브라우저에 저장된 응답을 사용할 수 있습니다. 캐싱은 보통 GET 메소드에만 합니다. 가져온 데이터를 저장해두고 재사용합니다. 일반적으로 200(요청 성공), 301(다른 주소로 이동 후 가져옴), 404(경로가 잘못됨) 상태로 온 응답을 캐싱할 수 있습니다.

Cache-Control

먼저 아무것도 캐싱하지 않으려면 no-store옵션을 사용하면 됩니다.

Cache-Control: no-store

no-cache 옵션은 캐시를 쓰지 않겠다는 뜻이 아니고 모든 캐시를 쓰기 전에 서버에 이 캐시를 사용해도 되냐고 물어보라는 옵션입니다.

Cache-Control: no-cache

must-revalidate는 만료된 캐시만 서버에 확인을 받도록 하는 겁니다.

Cache-Control: must-revalidate

public이면 공유 캐시(또는 중개 서버)에 저장해도 된다는 뜻이고 private이면 브라우저같은 특정 사용자 환경에만 저장하라는 뜻입니다.

Cache-Control: public 또는 private

max-age로 캐시 유효시간을 줄 수 있습니다. 초 단위이므로 위 예제에서는 1시간입니다. 1시간이 지나면 이 응답 캐시는 만료된 것으로 여겨집니다.

Cache-Control: public, max-age=3600

참고로 위의 옵션들은 혼합해서 쓸 수 있습니다. no-store, no-cache, must-revalidate처럼 콤마로만 구분하면 되고요.

Cache-Control을 응답 헤더라고 생각하실 수도 있는데, 요청 헤더로도 사용할 수 있습니다. 프론트 - 중개 서버 - 진짜 서버와 같은 구조인 경우에 중개 서버에 있는 캐시를 가져오지 않도록 하려면 요청 시부터 Cache-Control을 헤더로 넣어주곤 합니다.

Age

Age 헤더는 캐시 응답 때 나타나는데, max-age 시간 내에서 얼마나 흘렀는지 초 단위로 알려줍니다. 위 예제에서 max-age= 3600을 설정한 경우, 1분이 지나면

Age: 60

이 캐시 응답 헤더에 포함됩니다.

Expires

Cache-Control과 별개로 응답에 Expires라는 헤더를 줄 수도 있습니다.

Expires: Thu, 26 Jul 2018 07:28:00 GMT

응답 컨텐츠가 언제 만료되는지를 나타내며, Cache-Control의 max-age가 있는 경우 이 헤더는 무시됩니다.

ETag

HTTP 컨텐츠가 바뀌었는지를 검사할 수 있는 태그입니다. 같은 주소의 자원이더라도 컨텐츠가 달라졌다면 ETag가 다릅니다. 예를 하나 들어봅시다.

GET www.naver.com의 응답 본문이 안녕이고 ETag 헤더 값이 12345라 칩시다. 만약 서버 컨텐츠(응답 본문)가 동일하다면 매번 GET www.zerocho.com을 할 때마다 ETag는 12345입니다. 그런데 안녕에서 이태그로 컨텐츠가 바뀌었다면 ETag 헤더 값도 34567로 바뀝니다. 그러면 서버가 클라이언트의 응답 내용이 달라졌구나를 깨닫게 되어 캐시를 지우고 새로 컨텐츠를 내려받을 수 있게 됩니다.

Etag: W/"3bf2-wdj3VvN8/CvXVgafkI30/TyczHk"

If-None-Match

서버보고 ETag가 달라졌는 지 검사해서 ETag가 다를 경우에만 컨텐츠를 새로 내려주라는 뜻입니다.

If-None-Match: W/"3bf2-wdj3VvN8/CvXVgafkI30/TyczHk"

만약 ETag가 같다면 서버는 304 Not Modified를 응답해서 캐시를 그대로 사용하게 합니다.

쿠키

쿠키는 브라우저에 저장되는 작은 데이터 조각으로, 임시 데이터 보관 또는 웹페이지 개인화 등에 사용됩니다.

Set-Cookie

서버에서 클라이언트(브라우저)한테 이런 이런 쿠키를 저장하라고 명령하는 응답 헤더입니다.

Set-Cookie: 키=값; 옵션들

Set-Cookie: hello=zero면 hello라는 키에 값을 zero로 해서 보낼 수 있는거죠. 옵션들도 몇 개 알려드리겠습니다.

  • Expires: 쿠키 만료 날짜를 알려줄 수 있습니다.
  • Max-Age: 쿠키 수명을 알려줄 수 있습니다. Expires는 무시됩니다.
  • Secure: https에서만 쿠키가 전송됩니다.
  • HttpOnly: 자바스크립트에서 쿠키에 접근할 수 없습니다. XSS 요청을 막으려면 활성화해두는 것이 좋습니다.
  • Domain: 도메인을 적어주면 도메인이 일치하는 요청에서만 쿠키가 전송됩니다. 가끔 도메인이 다른 쿠키들이 있는데, 이런 쿠키들은 써드 파티 쿠키로 여러분을 추적하고 있는 쿠키입니다. 구글이나 페이스북같은 곳이 써드 파티 쿠키를 적극적으로 사용합니다.
  • Path: 패스를 적어주면 이 패스와 일치하는 요청 요청에서만 쿠키가 전송됩니다.

예를 들면 다음과 같이 가능합니다.

Set-Cookie: hellp=zero; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly

쿠키는 XSS 공격과 CSRF 공격 등에 취약하기 때문에 HttpOnly 옵션을 켜두고, 쿠키를 사용하는 요청은 서버 단에서 검증하는 로직을 꼭 마련해두는 것이 좋습니다.

Cookie

반대로 클라이언트가 서버한테 쿠키를 보내줄 때는 이 요청 헤더에 담아 보냅니다.

Cookie: 키=값; 키=값;

서버는 이 쿠키 헤더를 파싱해서 사용하게 됩니다. 아까도 말했듯 CSRF 공격같은 것을 막기 위해서 반드시 서버는 쿠키가 제대로 된 상황에서 온 것인지 확인하는 로직을 갖춰야 합니다.

이렇게 캐시와 쿠키에 관련된 헤더를 알아봤습니다. 보통은 서버가 알아서 세팅하는 캐시와 쿠키를 사용하지만, 수정이 필요할 때 참고하면 좋습니다.

 

응답코드

HTTP 응답 코드(HTTP Response Status Codes)는 서버가 클라이언트의 요청에 대한 처리 결과를 전달하는 데 사용되는 숫자 코드입니다. 각 응답 코드는 해당 요청의 처리 상태를 나타내며, 클라이언트와 서버 간의 통신을 원활하게 만드는 데 도움이 됩니다. 아래는 몇 가지 주요한 HTTP 응답 코드와 그 의미입니다:

  • 1xx (Informational): 요청이 수신되었고 처리 중임을 나타냅니다.
    • 100 (Continue): 클라이언트가 요청을 계속해서 보낼 수 있음을 나타냅니다.
  • 2xx (Successful): 요청이 성공적으로 처리되었음을 나타냅니다.
    • 200 (OK): 요청이 성공적으로 처리되었음을 나타냅니다.
    • 201 (Created): 새 리소스가 생성되었음을 나타냅니다.
    • 204 (No Content): 응답 본문이 없음을 나타냅니다.
  • 3xx (Redirection): 요청 완료를 위해 추가 작업 조치가 필요합니다.
    • 301 (Moved Permanently): 리소스의 위치가 변경되었음을 나타냅니다.
    • 302 (Found): 임시적으로 리소스의 위치가 변경되었음을 나타냅니다.
    • 304 (Not Modified): 클라이언트의 캐시가 최신 상태임을 나타냅니다.
  • 4xx (Client Error): 클라이언트 측에서 발생한 오류를 나타냅니다.
    • 400 (Bad Request): 잘못된 요청을 나타냅니다.
    • 401 (Unauthorized): 인증이 필요함을 나타냅니다.
    • 403 (Forbidden): 접근이 금지되었음을 나타냅니다.
    • 404 (Not Found): 요청한 리소스를 찾을 수 없음을 나타냅니다.
  • 5xx (Server Error): 서버 측에서 발생한 오류를 나타냅니다.
    • 500 (Internal Server Error): 서버 내부 오류를 나타냅니다.
    • 502 (Bad Gateway): 게이트웨이 서버에서 잘못된 응답을 받았음을 나타냅니다.
    • 503 (Service Unavailable): 서비스를 사용할 수 없음을 나타냅니다.

참조

https://velog.io/@surim014/HTTP란-무엇인가

https://www.zerocho.com/category/HTTP/post/5b344f3af94472001b17f2da

Comments