본문으로 건너뛰기

HTTP/1.0의 신택스: 기본이 되는 네가지 요소

지금 보면 HTTP 는 엄청난 사전같다. 처음부터 그랬던건 아니다. 초창기를 생각해보자

4가지 기본 요소가 있었아

  • method & path
  • header
  • body
  • status code

1.1 HTTP의 역사​

1.2 HTTP/0.9로 할 수 있는 것을 시험​

현재는 0.9 를 사용할 수 없음 현재 버전의 프로토콜에서는 0.9와 호환되지 않음

기존에 0.9에 기본 스펙이 정의되었음

0.9에서는 바디 수신과 경로 정도의 기능만 가지고 있었음

1.3 HTTP/0.9에서 1.0으로​

0.9는 프로토콜이라고 하기 어려움

  • 하나의 문서를 전송하는 기능만 가지고 있음
  • 통신되는 모든 내용은 HTML로 가정함. 콘텐츠 형식을 서버가 전달할 수 단이 없음
  • 클라이언트쪽에서 검색 이외의 요청이 없음
  • 새로운 문장을 전송하거나 갱신 삭제가 불가능

그 외에도 서버가 올바르게 응답했는지 알 수 없음

1.0에서는 다음과 같은 기능이 추가됨

  • 메서드 추가
  • HTTP 버전 추가
  • 헤더 추가 (Host, User-Agent, Accept)
  • 응답에 HTTP 버전과 3행의 status code가 포함됨
  • 요청과 같은 형식의 헤더가 포함

1.4 HTTP의 조상, 전자메일​

Header는 request / response 에 모두 포함됨 Key-Value 쌍으로 본문 앞에 존재함 Header의 이름은 대소문자 구분 안함

많이 사용되는 Headers Request (Client -> Server)

  • User-Agent
  • Referer
  • Authorization

Response (Server -> Client)

  • Content-Type
  • Content-Length
  • Content-Encoding
  • Date

이 외에도 X-*** 가 붙은 다양한 헤더도 있음

1.4.1 헤터의 전송​

curl --http1.0 -H "X-Test: Hello" http://localhost:18888

위와같이 명령어를 보내면 User-Agent와 Accept 헤더가 강제로 들어감

같은 헤더를 여러번 보낼 수 있음 받는쪽에선 , 로 이어서 받던지, 배열로 받을 수 있음 언어나 프레임워크에 따라 다르니 정리해두면 도움이 될수도 있을듯 하다

1.4.2 헤더의 수신​

Request header와 거의 비슷하지만 헤더 이름은 서로 상이함

1.4.3 MIME 타입​

MIME 타입은 파일의 종류를 구별하는 문자열

1.4.4 Content-Type 과 보안​

파일 종류를 특정할떄 Content-Type 를 사용함 확장자가 전송되지 않은 경우 브라우저에 따라서 스스로 해석하고 실행하는 경우가 있었음

이런 동작을 Content sniffing 이라고 함 현재는 다음과 같은 헤더를 추가하여 브라우저가 추측하지 않도록 하는것이 일반적임

X-Content-Type-Options: nosniff

1.4.5 전자메일과의 차이​

기본 동작은 동일하게 동작함 HTTP는 고속으로 전자메일이 왕복하는것과 비슷함

1.5 HTTP의 조상 - 뉴스그룹​

뉴스그룹은 Master/slave 구조로 필요한 정보를 가져와 전달하는 역할을 수행했음 그중 스토리지 문제로 인해 오래된 데이터는 삭제함 NNTP (Network News Transfer Protocol) 을 사용했음

NNTP에 착안하여 HTTP는 method와 status code를 가져옴

1.5.1 메서드​

NNTP 에는 LIST, HEAD, Body, POST 가 있었음 HTTP는 다음을 정의함

  • GET

  • HEAD

  • POST

  • PUT

  • DELETE

PUT과 DELETE는 1.0에서는 필수가 아니였으나 이후 Js에서 XML HttpRequest 가 지원된 후 살아남음 이외에 다음 Method 는 삭제됨

  • LINK: 문서간 링크를 만듬
  • UNLINK:
  • CHECKOUT
  • CHECKIN
  • SHOWMETHOD
  • TEXTSEARCH
  • SEARCHJIMP
  • SEARCH:

1.5.2 status code​

크게 5가지 카테고리로 나뉨

100번대:

  • 처리가 계속됨을 의미
  • 특수한 용도로 사용함

200번대

  • 성공

300번대

  • 서버에서 클라이언트로의 명령. 오류가 아니라 정상 처리의 범주.
  • redirect나 cache 이용을 지시함

400번대

  • 클라이언트가 보낸 요청에 오류가 있음

500번대:

  • 서버 내부에서 오류가 발생

1.6 리디렉트​

300번대 status 는 서버가 브라우저에게 리다이렉트 하도록 지시하는 코드

메서드 변경 여부, 영구/일시적, 캐시 여부 등에 따라 5가지 종류가 있음 // TODO: 표로 정리하자. 53p

클라이언트는 Location 헤더값을 보고 다시 요청함. 재요청시 헤더등도 다시 보내고, Methods를 바꿀지 여부도 결정함 (일반적으론 GET으로 함. 307과 308은 변경 가능)

redurect 횟수도 기본 50번까지지만 --max-redirs 옵션으로 변경 가능

redirect 하는곳이 외부라면 TCP 세션 접속, HTTP 송수신으로 두번 왕복하는 통신이 발생함

1.7 URL​

모든 URL과 URN은 URI이다.

URL은 접근 가능한 리소스의 경로, URN은 접근과 무관한 리소스의 고유 이름, URI는 이 둘을 포괄하는 식별자 전체 개념입니다.

항목약어의미예시
URLUniform Resource Locator리소스의 "위치(location)"를 지정함https://example.com/index.html
URIUniform Resource Identifier리소스를 고유하게 "식별(identifier)"함 (URL 포함 더 포괄적 개념)https://example.com/index.html, urn:isbn:0451450523
URNUniform Resource Name리소스의 "이름(name)"을 지정함 (위치는 명시하지 않음)urn:isbn:0451450523
  • 공식 표기는 URI 이고, URL은 관용적인 표현인듯 함

1.7.1 URL 구조​

일반적으로 보는 URL의 구조는 다음과 같음

스키마://사용자:패스워드@호스트명:포트/경로#프래그먼트?쿼리

스키마는 http, https, ftp, file, mailto 등 다양함 스키마의 해석은 브라우저의 책임 스키마를 보고 어떻게 표시할지 결정함

호스트는 실제 통신하는 곳

...

URL은 사용자가 읽는 문장이기도 함 읽기 쉬운 구조를 짜는것도 중요함 따라서 보안적인 부분도 신경써야함

URL은 최근에 decode 되어서 보이긴 함 길이의 제한은 없지만 인터넷 익스플로러가 2083자여서 대략 2000자로 제한이 있다고 알려짐 하지만 HTTP/2 에서 너무 길면 414 (URI Too Long) 응답을 받을 수 있음

1.7.2 URL과 국제와​

다양한 문자로 호스트명을 지정할 수 있음

퓨니코드 로 지정함 앞에 xn-- 을 반드시 붙임

1.8 바디​

HTTP/0.9 에서는 데이터를 포함할 수 없었음 헤더 끝에 빈줄을 넣으면 그 이후는 모두 바디

헤더1: 헤더 값 1
헤더2: 헤더 값 2
Content-Length: {바디의 바이트 수}

여기부터 지정된 바이트 수만큼 바디가 포함됨

응답의 바디는 단순함. 한번 응답할 때 마다 한 파일만 반환 읽어올 바디의 수는 Content-Length 헤더로 지정함

속도를 위해 압축하는 경우가 있음 Content-Encoding 에서 지정된 압축 알고리즘을 사용함 Content-Length 는 압축된 이후의 값을 사용함

HEAD methods 로 보내도 Content-length는 보내야함

1.8.1 GET 요청시 바디​

HTTP 메서드중 Body를 기대하지 않는 메서드가 GET, HEAD 메서드임 보낼 수 있긴 하지만 추천하지 않는 방법

RFC 2616 에서는'서버는 메시지 바디를 읽어올 수 있어야 하지만, 요청된 메서드가 바디의 시맨틱스를 정하지 않은 경우는 요청을 처리할 때 메시지 바디는 무시돼야 한다.'

https://stackoverflow.com/questions/978061/http-get-with-request-body

OPTIONS와 CONNECT 메서드도 바디를 가질 수 있긴 하지만 구현에 따라서 무시되는 경우도 있음

1.9 마치며​

ㅇㅇ