2. Semantics of Http/1.0
Timeless, 4-core components of HTTP
Method, URL(domain + path)
Header
Body
Status code
2.1. Simple form transfer (x-www-form-urlencoded)
form encode request:
#!/bin/sh curl --http1.0 --data-urlencode title="Head First PHP & MySQL" \ --data-urlencode author="Lynn Beighley, Michael Morrison" \ http://$1 --verboseoutput:
Content-Length: 71 Content-Type: application/x-www-form-urlencoded User-Agent: curl/7.82.0 title=Head+First+PHP+%26+MySQL&author=Lynn+Beighley%2C+Michael+Morrison
- URL encoding (wikipedia)
- Percent-encoding은 URL encoding이라고도 알려져 있으며,형식적인 데이터를 US-ASCII만을 허용하는 URI로 encode하는 방법이다.일반적으로 주류 URI셋에서 사용되는데,
application/x-www-form-urlencoded
의 Media type 데이터의 준비작업에 사용되며 HTML form에 사용된다.
2.2. File transfer using form (multipart/form-data)
<form action="POST" enctype="multipart/form-data></form>
Content-Type: multipart/form-data; boundary=-----WebkitFromBoundaryy0YfbccgoID172j7
Note
헤더에 Content-Disposition 항목이 포함됩니다.
2.2.1. Multipart form test
Request
#!/bin/sh curl --http1.0 -F "file2<test.txt;type=text/html" -F "file1@test.txt;type=text/html" http://$1 --verbose
Client
POST / HTTP/1.0 > Host: 127.0.0.1:18888 > User-Agent: curl/7.82.0 > Accept: */* > Content-Length: 354 > Content-Type: multipart/form-data; boundary=------------------------8eef5e797ff1fda2 > * We are completely uploaded and fine * Mark bundle as not supporting multiuse * HTTP 1.0, assume close after body < HTTP/1.0 200 OK < Date: Wed, 13 Apr 2022 12:27:39 GMT < Content-Length: 32 < Content-Type: text/html; charset=utf-8
Server
POST / HTTP/1.0 Host: 127.0.0.1:18888 Connection: close Accept: */* Content-Length: 333 Content-Type: multipart/form-data; boundary=------------------------8eef5e797ff1fda2 User-Agent: curl/7.82.0 --------------------------8eef5e797ff1fda2 Content-Disposition: form-data; name="file2" Content-Type: text/html simple string --------------------------8eef5e797ff1fda2 Content-Disposition: form-data; name="file1"; filename="test.txt" Content-Type: text/html simple string --------------------------8eef5e797ff1fda2--
Note
text/plain
form의 encoding type은 기본적으로 www-form-urlencoded, 파일을 전송하고 싶을 때: multipart/form-data.
text/plain은 개행을 통해 각 값을 구분해 전송합니다.
`
title=The Art of community
author=john bacon
`
서비스쪽이 보안이 약할 때 문제를 일으키는 경우가 있다고 합니다.
2.3. Content negotiation
서버와 클라이언트간 통신을 최적화 하고자 하나의 요청에서 최고의 설정을 공유하는 시스템
Request Header |
Response Header |
negotiation target |
---|---|---|
Accept |
Content-Type |
MIME Type |
Accept-Language |
Content-Type / html tag |
language |
Accept-Charset |
Content-Type |
character set |
Accept-Encoding |
Content-Encoding |
compression type |
2.3.1. File type 결정
Accept: text/html,application/xml;q=0.9,image/webp,*/*;p=0.8
image/webp
*/*;q=0.8
quality value는 0~1 사이의 수치로, 기본 1.0일 경우에는 명시하지 않습니다.
0.9의 우선순위로 webp를 요청하고, 그렇지 않으면 다른 포맷(0.8)을 다음으로 두고 있는 표현입니다.
2.3.2. Charset 결정
Accept-Charset: window-949,utf-8;q=0.7,*;q=0.3
브라우저가 모든 charest-encoder를 내장하고 있기 때문에, 협상이 필요없어 졌습니다.
Content-Type: text/html; charset=UTF-8
HTML의 경우 문서 안에 쓸 수도 있습니다.
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8>
<meta charset="UTF-8">
2.3.3. 압축을 이용한 통신속도 향상
통신에 걸리는 시간보다 압축과 해체가 짧은 시간에 이루어지므로, 압축을 함으로써 웹페이지를 표시할 때 걸리는 전체적인 처리시간을 줄일 수 있습니다.
PROS:
- 전력소비 감소
- 데이터 사용 비용 절감
압축에 대한 negotiation은 header안에서 명시합니다.
Accept-Encoding: deflate, gzip
#!/bin/sh
curl --http1.0 --compressed -H "Accept-Encoding: gzip, br" http://$1 --verbose
> GET / HTTP/1.0
> Host: 127.0.0.1:18888
> User-Agent: curl/7.82.0
> Accept: */*
> Accept-Encoding: gzip, br
>
* Mark bundle as not supporting multiuse
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Date: Fri, 15 Apr 2022 11:34:53 GMT
< Content-Length: 32
< Content-Type: text/html; charset=utf-8
서버가 압축 content를 지원하지 않기 떄문에 차이가 발생하지 않았을 뿐 요청을 정상적으로 처리되었습니다.
서버가 gzip을 지원했을 경우, 아래와 같은 응답을 반환합니다.
< Content-Encoding: gzip < Content-Length: (zipped size of bytes)
gzip보다 효율이 좋은 Brotil는 구글의 proposal로 등장하였습니다
HTTP헤더를 사용해 1왕복을 데이터 교환 단계에서 하위 호환성을 유지하면서도, 서로 최적의 통신을 할 수 있게 시스템이 정비되었습니다.
See also
sdch(Shared Dictionary Compressing for HTTP), 는 IANA비등록 압축알고리즘이며, 중복되는 문구를 공유 사전으로 사용하여 통신량을 대폭 줄일 수 있는 알고리즘입니다. 이런 공유 방식은 HTTP/2의 헤더부분 압축에도 사용됩니다.
2.6. Proxy
2.6.1. wikipedia.Proxy
Proxy 서버는 client request와 server providing resource 중간에서 전달자 역할을 합니다. 직접 서버에 요청을 연결하는 대신에 프록시 서버에게 연결하도록 하여, request를 분석하고, 요구되는 네트워크 transaction을 수행합니다.
아래와 같은 효과를 가질 수 있습니다.
request의 복잡성을 조절하는 역할
로드 밸런싱, 보안 등의 이점
Proxies는 분산 시스템에 encapsulation과 구조를 더하는 것으로 소개되었습니다.
따라서 중간의 자리에서, 암시적으로 request의 원형을 masking하는 효과를 가집니다.
프록시는 HTTP/1.0 규격에서 부터 언급되었습니다.
GET /helloworld
Host: localhost:18888
GET https://example.com/helloworld
Host: example.com
2.6.2. HEADER.Proxy-Authenticate
프록시 서버가 악용되지 않도록 인증을 이용해 프록시 서버를 보호하는 경우도 있습니다.
중계되는 프록시는 중간의 호스트 IP주소를 특정 Header에 기록해 갑니다.
X-Forwarded-For: client, proxy1, proxy2
(RFC 7239)
$ curl --http1.0 --proxy http://proxy1.com -U user:pass http://server/helloworld
HTTPS통신의 프록시 지원은 HTTP1.1에 추가된 CONNECT method를 사용합니다.
2.7. Cache
Note
GET, HEAD메서드 이외에는 ‘기본적으로’ 캐시되지 않습니다.
2.7.1. 갱신 일자에 따른 캐시
HTTP/1.0 당시에는 정적 컨텐츠 위주여서 파일의 timestamp가 변경되었는지 비교하는 것으로 데이터 전송여부를 결정할 수 있었습니다.
- Response Header
Last-Modified: Wed, 08 Jun 2016 15:23:45 GMT
웹 브라우저가 캐시된 URL을 다시 읽을 때에 서버에서 반환된 일시를 그대로 넣어 요청합니다.
- REQUEST HEADER
If-Modified-Since: Wed, 08 Jun 2016 15:23:45 GMT
위 요청에 따라 데이터가 변경되었다면,
200 OK, 데이터가 변경되어 정상적으로 응답
304 Not Modified, 데이터가 변경되지 않았으니 캐시를 사용하라는 응답
2.7.2. Expires
갱신일시를 이용하는 캐시의 경우 명백히 시간이 너무 오래 지났는데 캐시의 유효성을 확인하기 위해 불필요한 통신이 발생하는 경우가 있습니다.
이 캐시 자체에 유효시간을 두어 fresh를 체크하는 Expires 헤더가 http/1.0에 도입되었습니다.
2.7.3. ETag
날짜와 시간을 이용한 캐시 비교만으로 해결할 수 없을 때가 있습니다.
사용자의 정보나 상태에 따라 부분적인 변경이 한 주소에 동적으로 일어나는 경우가 늘어나거나 하는 등의 경우에, 날짜와 시간을 근거로 캐시의 신선함을 판단하기가 어려워 집니다.
이럴 때 사용할 수 있는 것이 HTTP/1.1에서 추가된 ETag(Entity tag)입니다.
- Wikipedia.ETag
파일의 데이터로 비교하여 캐시의 유효성을 검증하는 매커니즘
클라이언트가 조건적인 요청을 전달하는 것을 가능하게 합니다.
대상 URL에 대한 자원이 변경되면 새로운 Etag가 생성되고 전달됩니다.
ETag는 서버가 자유롭게 결정해서 반환할 수 있습니다.
아마존 S3의 경우 컨텐츠 파일의 해시 값이 사용되는 것으로 추정됩니다.
2.7.4. Cache-Control
ETag와 같이 HTTP/1.1에 추가된 Cache-Control
아래와 같은 값을 가질 수 있습니다.
public: 같은 컴퓨터를 사용하는 사용자간 캐시 재사용을 허가
private: 같은 컴퓨터라도 다른 사용자라면 캐시를 재사용 하지 않음(유저 별로 컨텐츠가 변경되는 경우)
max-age=n: 캐시의 fresh를 초단위로 설정.
n == 86400
이면 하루동안 캐시가 유효하고 시간동안 서버에 문의 없이 캐시사용s-maxage=n: max-age와 같으나 공유 캐시에 대한 설정 값
no-cache: 캐시가 유효한지 매번 ETAG를 포함하도록 요청
no-store: 캐시하지 않도록 요청
Todo
cache-Control(2) header for Proxy server manages
2.7.5. Vary
같은 URL이라도 클라이언트에 따라 반환결과가 다름을 나타내는 헤더 Vary
Vary: User-Agent, Accept-Language
캐시데이터가 있고 신선하며, 그럴 경우 캐시를 사용하도록 권유하더라도 해당 데이터가 모바일 네트워크 요청이었고 현재는 그렇지 않다면 다른 결과를 기대할 수 있다.
이래서 반응형이 짱이다.
2.7.6. Referer
개인정보가 GET 파라메터로 표시되게 만들면 안됩니다. referer를 통해 외부 서비스로 전송되므로 유출과 직결됩니다.
방어적인 용도로 이미지에 직접 링크되는 것을 막고자, 이미지 다운로드 시 referer가 설정되지 않은 요청은 거절하는 경우도 있었습니다.
referer 헤더에 대해서는 아래에 대한 옵션이 존재합니다.
no-referer: 전송하지 않음
no-referer-when-downgrade: HTTPS -> HTTP 일때는 전송하지 않음
same-origin: 동일 도메인 내의 링크에 대해서 전송
origin: index페이지에서 링크된 것으로 해 도메인 이름만 전송한다.
strict-origin: origin + downgrade시 비전송
origin-when-crossorigin: 같은 도메인 내에서는 온전한 referer, 다른 도메인에서는 도메인 이름만 전송
strict-origin-when-crossorigin: 위와 같으나 HTTPS -> HTTP에서는 전송하지 않는다.
unsafe-url: 항상 전송한다.