Hyper Text Transfer Protocol

Hyper Text Transfer Protocol은 인터넷 상에서 데이터(주로 HTML파일)을 주고 받기 위한 네트워크 전송 규약이다. 버전은 1.0과 1.1그리고 2.0이 있다. 주로 사용되는 서버 포트는 80번이다. 간단하게 인터넷 주소에 http://이 붙은 것은 이것으로 데이터를 받는 것이라고 생각하면 된다.

최근 대부분의 프로그래밍 언어나 게임엔진에서는 HTTP라이브러리가 있어서 실시간 네트워크 게임이 아닌 경우 HTTP를 이용하여 서버와 통신하는 경우가 많다.

전송방식

HTTP는 기본적으로 클라이언트가 서버에게 데이터를 요청한 뒤, 서버에서 데이터를 받으면 서버와의 연결을 끊는 방식이다. 전화로 따지자면, 한 번 전화를 걸어서 계속 이야기를 하는 방식이 아니라, 이야기할 게 있을 때마다 걸고, 이야기가 끝나면 전화을 끊는 방식이다.

URL인코딩

프로토콜로 데이터를 전송할 때 특수문자나 알파벳이 아닌 다른 문자가 들어갈 경우 옛날에 제작된 HTTP서버의 경우 해석에 에러가 생길 수 있다. 이 때문에 URL에 들어가는 특수문자나 알파벳이 아닌 다른 문자의 경우 특수한 처리를 거쳐 보내게 된다. 이 방법은, 알파벳이나, /,?,&가 아닌 다른 문자를 %이 붙은 헥사코드로 변환하여 전송한다.

예시로서 "리브레위키"의 경우 UTF-8로 할 경우

  1. 리->0xEB 0xA6 0xAC
  2. 브->0xEB 0xB8 0x8C
  3. 레->0xEB 0xA0 0x88
  4. 위->0xEC 0x9C 0x84
  5. 키->0xED 0x82 0xA4

라는 바이트로 저장되는데, 이를 텍스트로 하여 https://librewiki.net/wiki/%EB%A6%AC%EB%B8%8C%EB%A0%88%EC%9C%84%ED%82%A4로 전송을 한다.

요청(Request)

클라이언트에서 서버로 "이런이런 데이터를 주세요"라고 요청할 때 양식에 맞춰서 말을 걸어야 한다. 양식은 다음과 같다.

[메소드] 요청할데이터 HTTP/[HTTP버전]\r\n
HEADER1키 : 값\r\n
HEADER2키 : 값\r\n
...
HEADERn키 : 값\r\n
\r\n
  • 메소드(method)
    요청이 어떤 방식으로 해달라는 건지에 대한 것이다. 다음과 같은 것이 있다.
    • GET
      가장 기본적인 요청이다. 서버쪽의 데이터의 변경이 아닌, 그냥 달라고만 하는 것이다.
    • POST
      가장 기본적인 요청이다. 그저 데이터를 달라는 것이 아닌, 서버쪽으로 데이터를 전송하겠다는 의미이다.
    • PUT
    • DELETE
    • OPTION
    • UPDATE
      위 4개의 메소드는 웹브라우저에는 지원하지 않는 요청방식으로 주로 Rest API라는 데서 사용하는 메소드다.
  • HTTP버전
    1.0, 1.1, 2.0이 있으며, HTTP/버전 으로 보낸다.
  • HEADER
    기본적인 요청데이터의 경로 외에, 기타 서버측에 보낼 데이터가 이곳에 들어간다. 대표적으로 다음과 같은 헤더가 있다.
    • host
      1.1이후에서는 꼭 보내야 하는 헤더로 해당 사이트의 도메인이 들어가야 한다.
    • referer
      주로 웹브라우저에서 링크를 눌러 다른 페이지로 이동할 때, 서버에 "이 페이지에서 넘어왔어요"라고 알려 주기 위한 헤더다. 이것으로 다른 사이트에서 이미지를 그냥 복붙한 걸 차단하기도 한다.
    • user-agent
      클라이언트(유저)가 무엇인지를 설명하기 위해 넘겨주는 데이터다. 웹브라우저나 검색봇에 따라서 다른 데이터를 주기 위해서 사용한다.
    • cookie
      쿠키(서버측에서 사용자 별로 따로 저장하는 데이터)를 다시 서버로 보내기 위한 헤버이다.

데이터 전달

헤더는 주로 웹브라우저나 프로그램 자체적으로 서버로 보내기 위해 사용하는 것으로, 서버측의 프로그램에서 필요한 데이터를 정할 수 없다. 그럴 때, 필요한 것이 Get과 Post를 통해 데이터를 전달한다.

GET

경로 뒤에 ?를 붙인 뒤에 "키=값"식으로 데이터를 전달한다.

GET /index.php?title=리브레_위키:현관 HTTP/1.1\r\n
host: librewiki.net\r\n
\r\n

전달할 데이터가 많으면 &를 이용하여 연결한다.

GET /index.php?title=리브레_위키:현관&action=edit HTTP/1.1\r\n
host: librewiki.net\r\n
\r\n

POST

응답(Response)

클라이언트에게서 요청을 받으면 서버에서는 그 요청에 따른 대응을 하여 응답을 보낸다.

HTTP/[HTTP버전] [응답코드] [응답메시지]\r\n
응답헤더1:값\r\n
응답헤더2:값\r\n
...
응답헤더n:값\r\n
\r\n
[데이터]

응답코드/응답메시지

이 응답 코드와 메시지는 다음과 같은 게 있다.

  • 200/OK
    정상적으로 요청을 받았다는 의미다.
  • 400/Bad Request
    옳바르지 않은 요청이라는 뜻이다.
  • 403/Forbidden
    해당 요청을 받고 서버가 처리하다 오류가 났다는 뜻이다.
  • 404/Not Found
    해당 요청에 해당하는 파일이나, 데이터를 찾을 수 없다는 뜻이다.

그 외에도 많지만 여기서는 대표적인 4가지만 설명한다.

요청에 따른 응답 데이터

데이터를 클라이언트(웹브라우저나 프로그램)에게 보낼 때 두 가지 방식이 있다.

Chunked방식

응답 헤더 transfer-encoding이 chunked라는 값이 들어있으면 chunked방식으로 데이터를 보낸다는 뜻이다.

[다음에 전송될 데이터의 사이즈]
\r\n
[데이터]
\r\n
[다음에 전송될 데이터의 사이즈]
\r\n
[데이터]
\r\n
...
0
\r\n
\r\n

이런 방식으로 데이터를 보내며, 마지막에 데이터를 다 보냈다는 의미로 0\r\n\r\n를 보냅으로서 끝난다. 주로 응답 데이터가 항상 일정하지 않은 데이터를 전송할 때 사용된다.

Content-Length

응답 헤더 content-length에 응답 데이터의 크기가 들어있으면 content-length방식으로 데이터를 보낸다. 따로 데이터를 가공하지 않고, content-length로 들어온 데이터 크기만큼을 읽으면 된다. 주로 사진이나 동영상같은 서버에 저장된 파일을 전송할 때 사용된다.

각주