http¶
클라이언트/원본과 진행하는 HTTP 트랜잭션을 설정한다.
/usr/local/m2/setting.json
다음 영역에 대해 기술한다.
{
"functions": {
"network": {
"http": {
...
}
}
}
}
frontEnd¶
HTTP 클라이언트 세션과 요청을 처리하는 방식에 대해 설명한다.
{
"functions": {
"network": {
"http": {
"frontEnd": {
...
}
}
}
}
}
session¶
클라이언트 세션과 아무런 통신이 없는 상태로 설정된 시간이 경과하면 세션을 종료한다. 시간을 너무 길게 설정하면 통신을 하지 않는 세션이 지나치게 많아진다. 너무 많은 세션을 유지하는 것만으로도 시스템엔 부하가 된다.
"session": {
"keepAliveSec": 10
}
keepAliveSec (기본: 10초)
HTTP 통신이 없는 상태로 세션을 유지하는 시간(초)
headers¶
{
"functions": {
"network": {
"http": {
"frontEnd": {
"headers": {
...
}
}
}
}
}
}
via¶
클라이언트에게 보내는 HTTP응답에 Via 헤더 명시여부를 설정한다.
"via": {
"enable": true
}
enable (기본: true)
Via 헤더를
M2Live/{version}
로 명시한다.
etag¶
클라이언트에게 보내는 HTTP응답에 ETag 헤더 명시여부를 설정한다.
"etag": {
"enable": true
}
enable (기본: true)
ETag 헤더를 명시한다.
age¶
Age헤더는 캐싱된 순간부터 경과시간(초)을 의미하며 RFC2616 - 13.2.3 Age Calculations 에 의하여 계산된다.
"age": {
"enable": false
}
enable (기본: false)
true
라면 Age헤더를 명시한다.
expires¶
Expires 헤더를 재설정한다. Expires조건은 Apache의 mod_expires 와 동일하게 동작한다. 특정 조건(URL이나 MIME Type)에 해당하는 콘텐츠의 Expires헤더와 Cache-Control 값을 설정할 수 있다. Cache-Control의 max-age값은 설정된 Expires시간에서 요청한 시간을 뺀 값이 된다.
"expires": {
"enable": false,
"base": "access",
"matchingList": [
{
"pattern": "$URL[/test.jpg]",
"time": "86400"
},
{
"pattern": "$MIME[application/octet-stream]",
"time": "#ORG_MAXAGE",
"base": "modification"
}
]
}
enable (기본: false)
false (기본)
원본서버에서 응답한 Expires헤더를 클라이언트에게 명시한다. 원본서버에서 Expires헤더가 생략되었다면 클라이언트 응답에도 Expires헤더가 생략된다.
true
Expires조건을 반영하여 Expires헤더를 명시한다. 조건에 해당하지 않는 콘텐츠는OFF
설정과 동일하게 동작한다.
base (기본: access)
Expires만료시간의 기준시점(
access
또는modification
)을 설정한다.access
현재 시간을 기준으로 한다. 다음은 MIME Type이 image/gif인 파일에 대하여 접근시간으로부터 1일 12시간 후로 Expires헤더 조건을 설정하는 예제이다.
{ "pattern": "$MIME[image/gif]", "time": "1 day 12 hours", "base": "access" }
modification
원본서버에서 보낸 Last-Modified를 기준으로 한다. 다음은 모든 jpg파일에 대하여 Last-Modified로부터 30분 뒤를 Expires값으로 설정하는 예제이다.
{ "pattern": "*.jpg", "time": "30min", "base": "modification" }
modification
의 경우 계산된 Expires값이 현재시간보다 과거의 시간일 경우 현재시간을 명시한다. 만약 원본서버에서 Last-Modified헤더를 제공하지 않는다면 Expires헤더를 보내지 않는다.
matchingList
매칭리스트
pattern
URL과 MIME Type 2가지로 설정이 가능하다. URL일 경우
$URL[...]
로, MIME Type일 경우$MIME[...]
으로 표기한다. 패턴표현이 가능하며 $표현이 생략된 경우 URL로 인식한다.time (단위: 초)
Expires만료시간을 설정한다. 시간단위 표현을 지원하며 단위를 명시하지 않을 경우 초로 계산된다.
{number}
- Expires만료시간#ORG_MAXAGE
- 원본서버가 응답한 Max-Age 값#TTL_LEFT
- 콘텐츠가 만료되는 시간
base
변경모드 -
access
,modification
Note
#ORG_MAXAGE
키워드를 통해 원본서버가 응답한 Max-Age 값을 Expire 시간으로 사용할 수 있다.
"expires": {
"enable": true,
"matchingList": [
{
"pattern": "/stat.jpg",
"time": "#ORG_MAXAGE"
},
{
"pattern": "/pds/*.dat",
"time": "#ORG_MAXAGE",
"base": "modification"
},
{
"pattern": "$MIME[application/shockwave]",
"time": "#ORG_MAXAGE"
},
{
"pattern": "$MIME[application/octet-stream]",
"time": "#ORG_MAXAGE",
"base": "modification"
},
{
"pattern": "$MIME[image/gif]",
"time": "#ORG_MAXAGE",
"base": "modification"
}
]
}
#TTL_LEFT
키워드를 통해 콘텐츠가 만료되는 시간을 Expires 헤더의 값으로 명시한다.
기준 설정이 access
인 경우에만 동작한다.
{
"pattern": "/*",
"time": "#TTL_LEFT",
"base": "access"
}
원본서버가 보낸 Max-Age
헤더가 없거나, 값이 0인 경우 Expire헤더를 붙이지 않는다.
server¶
클라이언트에게 보내는 HTTP응답에 Server 헤더 명시여부를 설정한다.
"server": {
"enable": true
}
enable (기본: true)
원본서버의 Server헤더를 명시한다.
connection¶
클라이언트에게 보내는 HTTP응답의 Connection헤더( keep-alive
또는 close
)를 설정한다.
"connection": {
"directive": "keep-alive"
}
directive (기본: keep-alive)
keep-alive
또는close
lastModified¶
클라이언트가 보내는 요청의 If-Modified-Since
헤더 처리정책을 설정한다.
"lastModified": {
"rule": "orlater"
}
rule (기본: orlater)
orlater (기본)
요청 대상의 Last-Modified 시간보다 일치하거나 큰 경우304 Not Modified
응답한다.
exact
요청 대상의 Last-Modified 시간과 일치하는 경우에만304 Not Modified
로 응답한다.
cacheFreshness¶
캐싱된 콘텐츠에 대한 304 Not Modified
응답판단을 설정한다.
"cacheFreshness": {
"rule": "both"
}
rule (기본: both)
both (기본)
클라이언트가 전송한If-Modified-Since
또는ETag
헤더 중 하나라도 같다면 동일 콘텐츠로 판단한다.
lmt
클라이언트가 전송한If-Modified-Since
만으로 동일 콘텐츠로 판단한다.
etag
클라이언트가 전송한ETag
만으로 동일 콘텐츠로 판단한다.
ifRange¶
클라이언트가 보내는 Range요청의 If-Range
헤더를 인식하여 처리한다.
Note
2 Tier구성이라면 Parent Layer에서 반드시 활성화해주어야 무결성이 보장된다.
"ifRange": {
"enable": true,
"purge": false
}
enable (기본: true)
true (기본)
If-Range헤더를 인식하여 Range 요청을 처리한다. 값이 유효하다면206 Partial Content
로 응답한다. 아니라면200 OK
로 응답한다.
false
If-Range헤더를 무시한다.
purge (기본: false)
활성화되면 클라이언트가 보낸
Last-Modified
시간이 더 최근일 경우 캐싱된 컨텐츠를 Purge 한다.
keepAlive¶
클라이언트에게 보내는 HTTP응답의 Keep-Alive 헤더를 설정한다.
"keepAlive": {
"enable": true,
"max": 0
}
enable (기본: true)
true (기본)
HTTP응답에 Keep-Alive헤더를 명시한다.
false
HTTP응답에 Keep-Alive헤더를 생략한다.
max (기본: 0)
0보다 크게 설정하면
Keep-Alive
헤더의 값으로max
값이 명시된다. 이후 HTTP 트랜잭션이 발생할때마다 1씩 차감된다.
modify¶
클라이언트 HTTP요청과 응답헤더를 특정 조건에 따라 변경한다.
"modify": {
"enable": false,
"matchFirstOnly": false,
"defaultCaseSensitive": true,
"matchingList": [
{
"pattern": "/*.mp4",
"header": "$RES[Access-Control-Allow-Origin: example1.com]",
"caseSensitive": false,
"mode": "set"
}
]
}
enable (기본: false)
헤더 수정 활성화
matchFirstOnly (기본: false)
최초 조건에만 변경을 원할 경우 속성을 true 로 설정한다. 서로 다른 조건이 같은 헤더를 변경하는 경우
set
에 의해 Last-Win이 된다. 또는 명시적으로put
,append
또는rewrite
할 수 있다.
defaultCaseSensitive (기본: true)
true (기본)
헤더를 제외한 값의 대소문자를 구분한다. (헤더는 대소문자 미구분이 스펙이다.)
false
대소문자를 구분하지 않는다.
matchingList
매칭리스트
pattern
패턴은 다음 조건을 지원한다.
조건
표현
설명
IP
$IP[...]
클라이언트 IP, IP Range, Bitmask, Subnet 네 가지 형식을 지원한다.
GeoIP
$IP[...]
클라이언트 국가코드. 반드시 geoip 가 설정되어 있어야 한다. 국가코드는 ISO 3166-1 alpha-2 와 ISO 3166-1 alpha-3 를 지원한다.
요청헤더
$HEADER[Key : Value]
클라이언트 요청헤더 패턴을 검사하며, Value는 명확한 표현과 패턴을 지원한다.
Value가 생략된 경우에는 Key에 해당하는 헤더의 존재유무를 조건으로 판단한다.
응답헤더
$RESHEADER[Key : Value]
클라이언트 응답헤더 패턴을 검사하며 그 외 동작은 요청헤더와 동일하다.
URL
$URL[...]
명확한 표현과 패턴을 인식한다.
URL 정규표현식
$URLMATCH[ ]
HTTP 요청 URL을 정규표현식으로 검사한다. 부정표현을 지원한다. ( $URL[...] 과 $URLMATCH[...] 차이 참조)
Method
$METHOD[...]
GET
,POST
,HEAD
,OPTIONS
중 하나만 명시적으로 지정한다.응답코드
$CODE[...]
클라이언트 응답코드.
200
,404
등 구체적인 코드외에2xx
,3xx
,4xx
,5xx
표현이 가능하다.Warning
위 조건 중 응답헤더
$RESHEADER[...]
와 응답코드$CODE[...]
표현은 응답헤더 변조$RES[...]
설정에서만 사용 가능하다."matchingList": [ { ... "pattern": "$URL[/*.mp4]", "header": "$RES[...]", ... } ]
개별
$
, 부정!
, 결합&
표현을 지원한다.# 특정 IP만 지정한 경우 $IP[10.10.10.10] # 국가코드 AP에 해당하며 referer헤더가 없는 경우 $IP[AP] & !HEADER[referer] # POST메소드로 /api/* 경로에 접근한 경우 $METHOD[POST] & $URL[/api/*] # cookie헤더에 login= 필드가 없는 경우 !HEADER[cookie: *login=*] # referer, user-agent, host 헤더가 모두 없는 경우 !HEADER[referer] & !HEADER[user-agent] & !HEADER[host] # /downloads/* 디렉토리 접근시 4xx응답이 발생한 경우 $URL[/downloads/*] & $CODE[4xx]
header
$REQ[...]
와$RES[...]
문법으로 헤더변경 방법을 설정한다.set
put
append
set_if_not_exist
의 경우{Key: Value}
로 설정하며, Value가 입력되지 않은 경우""
으로 간주한다.unset
의 경우{Key}
만 입력한다.caseSensitive
아이템의 대소문자 구분여부. 값이 없다면
defaultCaseSensitive (기본: true)
를 사용한다.
mode
값
설명
set
요청/응답 헤더에 설정되어 있는 Key와 Value를 헤더에 추가한다. 이미 같은 Key가 존재한다면 이전 값을 덮어쓴다.
set_if_not_exist
헤더가 존재하지 않는 경우에만
set
과 같이 동작한다.put
(
set
과 유사하나) 같은 Key가 존재하면, 덮어쓰지 않고 새로운 라인으로 붙여 넣는다.append
(
set
과 유사하나) 같은 Key가 존재하면, 기존의 Value와 설정된 Value사이에 콤마,
로 구분하여 값을 결합한다.unset
요청/응답 헤더에 설정되어 있는 Key에 해당하는 헤더를 삭제한다.
rewrite
정규표현식을 이용하여 헤더 값을 변경한다.
클라이언트가 보낸 헤더의 값은 $REQ.{헤더명}
로 참조한다.
이를 이용해 클라이언트가 보낸 헤더 값을 응답 헤더와 원본 요청 헤더에 명시할 수 있다.
"modify": {
"enable": true,
"matchFirstOnly": false,
"matchingList": [
{
# 클라이언트가 보낸 요청의 Origin헤더 값을 응답의 Access-Control-Allow-Origin 헤더 값으로 설정한다.
"pattern": "$URL[*.html]",
"header": "$RES[Access-Control-Allow-Origin: $REQ.Origin]",
"mode": "set"
},
{
# 클라이언트가 보낸 요청의 여러 헤더 값을 응답의 X-Cookie 헤더 값으로 설정한다.
"pattern": "$URL[*.json]",
"header": "$RES[X-Cookie: $REQ.[User-Agent, Host]]",
"mode": "set"
}
}
}
요청헤더 설정 예제는 다음과 같다.
"modify": {
"enable": true,
"matchFirstOnly": false,
"matchingList": [
{
"pattern": "$IP[192.168.1.1]",
"header": "$REQ[SOAPAction]",
"mode": "unset"
},
{
"pattern": "$IP[192.168.2.1-255]",
"header": "$REQ[accept-encoding: gzip]",
"mode": "set"
},
{
"pattern": "$IP[192.168.3.0/24]",
"header": "$REQ[cache-control: no-cache]",
"mode": "append"
},
{
"pattern": "$IP[192.168.4.0/255.255.255.0]",
"header": "$REQ[x-custom-header]",
"mode": "unset"
},
{
"pattern": "$IP[AP]",
"header": "$REQ[X-Forwarded-For]",
"mode": "unset"
},
{
"pattern": "$HEADER[user-agent: *IE6*]",
"header": "$REQ[accept-encoding]",
"mode": "unset"
},
{
"pattern": "$HEADER[via]",
"header": "$REQ[via]",
"mode": "unset"
},
{
"pattern": "$URL[/source/*.zip]",
"header": "$REQ[accept-encoding: deflate]",
"mode": "set"
},
{
"pattern": "$METHOD[POST]",
"header": "$REQ[host: sub.example.com]",
"mode": "set"
}
]
}
응답헤더 설정 예제는 다음과 같다.
resCode
설정을 통해 특정 응답코드에 한하여 헤더를 변경할 수 있지만 필수는 아니다.
"modify": {
"enable": true,
"matchFirstOnly": false,
"matchingList": [
{
"pattern": "$IP[192.168.1.1]",
"header": "$RES[via: STON for CDN]",
"mode": "set"
},
{
"pattern": "$IP[192.168.2.1-255]",
"header": "$RES[X-Cache]",
"mode": "unset"
},
{
"pattern": "$IP[192.168.3.0/24]",
"header": "$RES[cache-control: no-cache, private]",
"mode": "append"
},
{
"pattern": "$IP[192.168.4.0/255.255.255.0]",
"header": "$RES[x-custom-header]",
"mode": "unset"
},
{
"pattern": "$HEADER[user-agent: *IE6*]",
"header": "$RES[vary]",
"mode": "unset"
},
{
"pattern": "$HEADER[x-custom-header]",
"header": "$RES[cache-control: no-cache, private]",
"mode": "append"
},
{
"pattern": "$URL[/source/*]",
"header": "$RES[cache-control: no-cache]",
"mode": "set_if_not_exist"
},
{
"pattern": "/secure/*.dat",
"header": "$RES[x-custom]",
"mode": "unset"
},
{
"pattern": "/*.mp4",
"header": "$RES[Access-Control-Allow-Origin: example1.com]",
"mode": "set"
},
{
"pattern": "/*.mp4",
"header": "$RES[Access-Control-Allow-Origin: example2.com]",
"mode": "put"
}
]
}
그 밖에 특수 목적의 예약어를 지원한다.
예약어 |
설명 |
---|---|
|
클라이언트가 요청한 프로토콜. |
|
클라이언트가 접속한 포트. |
|
히트율 의 상세코드 |
|
access.log 의 |
|
access.log 의 |
|
호스트 이름 |
|
|
"modify": {
"enable": true,
"matchFirstOnly": false,
"matchingList": [
{
"pattern": "$URL[/download/*.pdf]",
"header": "$RES[Content-Disposition: #1]",
"mode": "set"
},
{
"pattern": "$URL[*]",
"header": "$REQ[X-Forwarded-Proto: #PROTOCOL]",
"mode": "set"
},
{
"pattern": "$URL[*]",
"header": "$REQ[X-Forwarded-Port: #PORT]",
"mode": "set"
},
{
"pattern": "$URL[*]",
"header": "$ORGREQ[X-Client-Forwarded-Port: #PORT]",
"mode": "set"
},
{
"pattern": "$URL[*]",
"header": "$RES[X-Cache-Result: #CACHEHIT]",
"mode": "set"
},
{
"pattern": "$URL[*]",
"header": "$RES[X-Cache-Sessionid: #SESSIONID]",
"mode": "set"
},
{
"pattern": "$URL[*]",
"header": "$RES[X-Cache-Hostname: #HOSTNAME]",
"mode": "set"
},
{
# rewrite의 경우 header 필드의 값으로 헤더명만 입력한다.
"pattern": "$URL[*]",
"header": "$RES[Location]",
"mode": "rewrite",
"rewrites": [
{
"pattern": "([^/]+)/(.*)]",
"replace": "www.example.com/#2"
},
{
"pattern": "bar.com/(.*)?cache=on",
"replace": "cache.example.com/#1"
}
]
}
]
}
debug¶
"debug": {
"enableContentProcessing": false
}
enableContentProcessing (기본: false)
undocumented
accessControl¶
가상호스트별로 서비스 허용, 차단, Redirect를 설정한다.
"accessControl": {
"enable": false,
"defaultAction": "allow",
"defaultCaseSensitive": true,
"matchingList": [
{
"pattern": "!HEADER[referer] & !HEADER[user-agent] & !HEADER[host]",
"action": "deny"
},
{
"pattern": "$URL[/source/public.zip]",
"caseSensitive": false,
"action": "allow",
"denialCode": 404
}
]
}
enable (기본: false)
false (기본)
ACL이 활성화되지 않는다. 모든 클라이언트 요청을 허가한다.
true
ACL이 활성화된다.차단된 요청에 대해서는
denialCode
속성에 설정된 응답코드로 응답한다.
defaultAction (기본: allow)
matchingList
에 해당하지 않거나action
이 정의되지 않은 조건에 대한 기본 행위
defaultCaseSensitive (기본: true)
true (기본)
헤더를 제외한 값의 대소문자를 구분한다. (헤더는 대소문자 미구분이 스펙이다.)
false
대소문자를 구분하지 않는다.
denialCode (기본: 401)
차단된 요청에 대한 응답코드
matchingList
접근제어 목록
pattern
매칭 패턴
caseSensitive
아이템의 대소문자 구분여부. 값이 없다면
defaultCaseSensitive (기본: true)
를 사용한다.action (기본: deny)
deny
또는allow
denialCode
차단된 요청에 대한 응답코드
allow/deny¶
모든 클라이언트 HTTP요청에 대하여 허용/거부 여부를 설정한다.
deny
된 요청은 access.log 에 TCP_DENY
로 기록된다.
각 조건마다 별도로 응답코드를 설정할 수 있다.
"accessControl": {
"enable": true,
"defaultAction": "deny",
"denialCode": 401,
"matchingList": [
{
"pattern": "$IP[192.168.1.1]",
"action": "allow"
},
{
"pattern": "$IP[192.168.2.1-255]"
},
{
"pattern": "$IP[192.168.3.0/24]",
"action": "deny"
},
{
"pattern": "$IP[192.168.4.0/255.255.255.0]"
},
{
"pattern": "$IP[AP] & !HEADER[referer]",
"action": "allow"
},
{
"pattern": "$HEADER[cookie: *ILLEGAL*]",
"action": "deny",
"action": 404
},
{
"pattern": "$HEADER[via: Apache]"
},
{
"pattern": "$HEADER[x-custom-header]"
},
{
"pattern": "!HEADER[referer] & !HEADER[user-agent] & !HEADER[host]",
"action": "deny"
},
{
"pattern": "$URL[/source/public.zip]",
"action": "allow"
},
{
"pattern": "$URL[/source/*]"
},
{
"pattern": "/profile.zip",
"action": "deny",
"denialCode": 500
{
"pattern": "/secure/*.dat"
}
]
}
허용/차단 조건은 IP, GeoIP, Header, URL, Protocol 5가지로 설정이 가능하다.
IP
$IP[...]
로 표기하며 IP, IP Range, Bitmask, Subnet 네 가지 형식을 지원한다.GEOIP
$IP[...]
로 표기하며 반드시 GeoIP설정이 되어 있어야 동작한다.HEADER
$HEADER[Key : Value]
로 표기한다. Value는 명확한 표현과 패턴을 인식한다.$HEADER[Key:]
처럼 구분자는 있지만 Value가 빈 문자열이라면 요청 헤더의 값이 비어 있는 경우를 의미한다.$HEADER[Key]
처럼 구분자 없이 Key만 명시되어 있다면 Key에 해당하는 헤더의 존재유무를 조건으로 판단한다.URL
$URL[...]
로 표기하며 생략이 가능하다. 명확한 표현과 패턴을 인식한다.PROTOCOL
$PROTOCOL[...]
로 표기한다.$PROTOCOL[http]
요청이HTTP
이다.$PROTOCOL[https]
요청이HTTPS
이다.$PROTOCOL[http2]
요청이HTTP2
이다.
Note
$
는 “조건에 맞다면 ~ 한다”를 의미하며, !
는 “조건에 맞지 않는다면 ~ 한다”를 의미한다.
다음과 같이 부정조건으로 지원한다.
"matchingList": [
{
# 국가가 KOR이 아니라면 deny한다.
"pattern": "!IP[KOR]",
"action": "deny"
},
{
# referer헤더가 존재하지 않는다면 deny한다.
"pattern": "!HEADER[referer]",
"action": "deny"
},
{
# /secure/ 경로 하위가 아니라면 allow한다.
"pattern": "!URL[/secure/*]",
"action": "allow"
}
]
redirect¶
모든 클라이언트 HTTP요청에 대하여 Redirect 여부를 설정한다.
Redirect된 요청은 302 Moved temporarily 로 응답하며 denialCode
로 설정이 가능하다.
"matchingList": [
{
"pattern": "$IP[GIN]",
"action": "redirect",
"location": "/page/illegal_access.html"
},
{
"pattern": "$HEADER[referer:]",
"action": "redirect",
"location": "http://another-site.com",
"denialCode": 307
},
{
"pattern": "!HEADER[referer]",
"action": "redirect",
"location": "http://example.com#URL"
}
]
Warning
POST
요청을 사용 중이라면 307 Temporary Redirect 를 권장한다.Chrome/103
버전의 테스트 결과는 다음과 같다.
응답코드 |
|
---|---|
|
|
|
|
|
|
|
|
Redirect 시점에 지원되는 예약어는 다음과 같다.
예약어 |
설명 |
---|---|
|
클라이언트 요청의 Note
Host: example.com:8080
위와 같이 요청된 경우 |
|
클라이언트 요청 URL |
|
|
설정 예제는 다음과 같다.
"matchingList": [
{
# HTTP 요청이라면 HTTPS로 강제하도록 redirect시킨다.
"pattern": "$PROTOCOL[HTTP]",
"action": "redirect",
"location": "https://example.com#URL"
},
{
# 모든 요청에 대해 8080 포트로 리다이렉트 시킨다.
"pattern": "$URL[/*]",
"action": "redirect",
"location": "http://#HOST:8080#URL"
},
{
# 문자열을 추출하여 리다이렉트 시킨다.
"pattern": "$URL[/domain/*/url/*]",
"action": "redirect",
"location": "https://#1/#2"
}
]
optionsMethod¶
"optionsMethod": {
"enable": true
}
enable (기본: true)
OPTIONS 메소드 처리.
false
인 경우 501 Not Implemented
,true
인 경우200 OK
응답
Note
extraMethods 에 OPTIONS
메소드가 설정되었다면 이 설정은 무시된다.
bypass¶
클라이언트 요청처리를 원본서버에게 위임하는 바이패스에 대해 설정한다. 바이패스는 캐싱정책보다 우선한다.
{
"functions": {
"network": {
"http": {
"frontEnd": {
"bypass": {
...
}
}
}
}
}
}
session¶
바이패스는 원본서버에서 동적으로 처리한 결과를 응답하는 경우가 많다. 이로 인해 처리 속도가 정적인 콘텐츠보다 느린 경우가 많다. 바이패스 전용 Timeout을 설정하여 섣부른 장애판단이 되지 않도록 한다.
"session": {
"connectTimeout": 5,
"receiveTimeout": 300
}
connectTimeout (기본: 5)
바이패스를 위해 n초 이내에 원본서버와 접속이 이루어지지 않는 경우 접속실패로 처리한다.
receiveTimeout (기본: 300)
바이패스 중 원본서버의 응답이 n초 동안 없다면 전송실패로 처리한다.
stickiness¶
항상 같은 서버로 바이패스되도록 다양한 옵션을 제공한다.
See also
"stickiness": {
"enable": false,
"mode": "net_route"
}
enable (기본: false)
stickiness 활성화
mode (기본: net_route)
stickiness 모드
none
session.balanceMode
로 동작한다.net_route
클라이언트 세션별로 바이패스된 원본 IP를 기억하여 동일 원본 IP로 라우팅한다. 최초 바이패스는 Round-Robin으로 선택한다.net_clientip
클라이언트 IP를 해쉬하여 원본 IP를 선택한다. 원본 IP가 증설, 감축되면 다른 원본 IP로 라우팅될 수 있다.app_cookie_route
바이패스된 원본서버의 힌트를Set-Cookie
로 설정한다. 최초 바이패스는 Round-Robin으로 선택한다.Set-Cookie: M2_BYPASS_TOKEN=<서버힌트>; path=/;
예제와 같이 옵션이 없는 Session Cookie로 동작하기 떄문에 현재 세션동안만 유효하다.
Set-Cookie
헤더의 키는app_cookie_route.name
으로 설정한다.# functions.network.http.frontEnd.bypass.stickiness "stickiness": { "enable": true, "mode": "app_cookie_route", "cookieHint": "M2_BYPASS_TOKEN", "cookiePath": "/" }
cookiePath
속성을null
로 설정하면 아래와 같이 명기하지 않는다.Set-Cookie: M2_BYPASS_TOKEN=<서버힌트>;
Warning
path
가 생략된다면 크롬에서는 아래와 같이 수신한 URL Path를 Path로 지정한다.같은
Name
이라도Path
가 다르면Cookie
헤더에 동일한Name
과 다른 값이 중복될 수 있어 의도치 않은 결과를 초래할 수 있다.app_cookie_origin
바이패스된 원본서버에서Set-Cookie
특정 키를 지정할 때에만 원본서버의 힌트를Set-Cookie
로 설정한다. 최초 또는Set-Cookie
특정 키가 없는 경우 Round-Robin으로 동작한다.# functions.network.http.frontEnd.bypass.stickiness "stickiness": { "enable": true, "mode": "app_cookie_origin", "cookieHint": "M2_BYPASS_TOKEN" "cookieOrigin": "JSESSIONID" }
위 설정은 원본서버에서
Set-Cookie
로JSESSIONID
값을 설정할 때 서버힌트를 삽입한다.Set-Cookie: JSESSIONID=DB926DF0772BAE3CB361E0BE1A9A7DE7; Expires=Thu, 21 Oct 2022 07:28:00 GMT; Secure; HttpOnly Set-Cookie: M2_BYPASS_TOKEN=<서버힌트>; Expires=Thu, 21 Oct 2022 07:28:00 GMT; Secure; HttpOnly
이 모드는 예제와 같이 원본의 Cookie 설정옵션을 모두 승계하며
cookiePath
설정등은 무시한다. 따라서 Persistent Cookie로 동작할 수 있다.
Note
서버힌트와 일치하는 서버를 찾을 수 없는 경우 초기화된다. Round Robin으로 원본 IP가 재선택되고 이후 설정된 절차를 따른다.
matchingList¶
accessControl 과 동일한 조건을 모두 지원한다.
"matchingList": [
{
"pattern": "$IP[192.168.2.1-255]"
},
{
"pattern": "/index.html"
}
]
matchingList
조건 리스트
pattern
매칭 패턴
action
cache
캐싱한다.bypass
바이패스한다.instant
instant 모드 상세 참고
action
을 명확하게 명시하지 않은 경우 기본설정과 반대로 동작한다.
예를 들어 getMethod 설정을 바이패스하도록 설정하면 예외조건은 캐싱목록이 된다.
혼란스럽다면 항상 action
을 명시하자.
"matchingList": [
{
# 항상 캐싱한다.
"pattern": "$HEADER[cookie: *ILLEGAL*]",
"action": "cache"
},
{
# 기본 설정에 따라 다름
"pattern": "!HEADER[referer:]",
"action": "cache"
},
{
# 항상 바이패스
"pattern": "!HEADER[referer] & !HEADER[user-agent]",
"action": "bypass"
},
{
# 기본 설정에 따라 다름
"pattern": "$URL[/source/public.zip]"
}
}
Note
정리하면 우선순위는 다음과 같다.
No-Cache 바이패스
matchingList
에"action": "bypass"
라고 명시된 경우matchingList
에서 인식하는 기본 설정
함수체인 등 많은 HTTP/콘텐츠 가공기능은 cache
엔진을 기반으로 한다.
때문에 bypass
는 HTTP/콘텐츠 가공기능을 사용하지 못한다.
bypass
되어야 하는 트래픽을 HTTP/콘텐츠 가공처리하고 싶을 때 instant
모드를 사용한다.
"matchingList": [
{
# login 된 요청을 instant모드로 지정하면 캐싱엔진을 통해 가공할 수 있다.
"pattern": "$HEADER[cookie: *login=yes*] && $URL[/search/*]",
"action": "instant"
}
}
instant
모드 상세¶
instant
모드의 장점은 bypass
처럼 개인화 트래픽에도 활용할 수 있음과 동시에 cache
엔진의 강력한 기능을 활용할 수 있다는 점이다.
기능 |
|
|
|
---|---|---|---|
콘텐츠 캐싱 |
X |
O |
O |
콘텐츠 재가공 |
X |
O |
O |
X |
O |
O |
|
콘텐츠 개인화 |
O |
X |
O |
메모리/디스크 사용 |
X |
O |
△ |
Warning
instant
를 함수체인과 같이 사용할 경우 각별히 주의해야 한다.
특히 비디오, 이미지등 고용량 콘텐츠가 HIT
되지 않기 때문에 캐싱엔진의 메모리 사용량이 요청수만큼 순식간에 폭증될 우려가 있기 때문이다.
자원(메모리/디스크) 사용량 관점에서 전송 메커니즘을 비교하면 동작 방식과 주의사항을 쉽게 이해할 수 있다. 아래는 3개의 메모리 블록으로 이루어진 콘텐츠를 전송하는 과정을 비교한 것이다.
bypass
- 캐싱없이 전송 수신된 메모리를 중계만 한다.클라이언트 <------■------ BYPASS[] <------■------ 원본
cache
- 캐싱하며 전송한다. 트랜잭션이 종료되어도 콘텐츠는 유지된다.클라이언트 <------■ ■ ■------- CACHE[■ ■ ■] <-------■ ■ ■------ 원본 클라이언트 CACHE[■ ■ ■] 원본
instant
- 함수체인이 사용되지 않는다면 전송 중인 메모리 블럭만을 캐싱하며, 완료되면 소거된다.# 1. 전송 중인 메모리 블럭만 캐싱하며 전송한다. 클라이언트 <-------■------ CACHE[■ □ □] <-------■------ 원본 클라이언트 <-------■------ CACHE[□ ■ □] <-------■------ 원본 클라이언트 <-------■------ CACHE[□ □ ■] <-------■------ 원본 # 2. 트랜잭션이 종료되면 콘텐츠는 소거된다. 클라이언트 CACHE[] 원본
instant + 함수체인
- 함수체인이 사용된다면HIT
만 되지 않을 뿐 콘텐츠 생성과정은cache
와 동일하게 동작한다. 중간 처리과정이 모두 캐싱되며 더 이상 접근이 없는 경우라면 모든 메모리가 소거된다.# 원본비디오 ---> 트랜스코더 이미지 추출 ---> DIMS 인 경우 중간 과정이 모두 캐싱된다. 클라이언트 <------ CACHE[■ ■ ■] <------ DIMS[■ ■ ■] <------ TRANSCODER[■ ■ ■] <------ 원본 # 트랜잭션이 종료되어도 최대 3초간 콘텐츠는 유지된다. 클라이언트 CACHE[■ ■ ■] DIMS[■ ■ ■] TRANSCODER[■ ■ ■] 원본 # 이후 모든 메모리는 소거된다. 클라이언트 CACHE[] DIMS[] TRANSCODER[] 원본
Note
instant
모드는 캐싱엔진을 사용하지만 바이패스의 성격을 가지고 있기 때문에 cookie
관련헤더 또는 커스텀헤더 등이 모두 캐싱된다.
단, 아래 표준 헤더들은 캐싱엔진에서 콘텐츠 처리와 연관되어 재해석된다.
Cache-Control
Content-Disposition
Content-Encoding
Content-Length
Content-Type
Expire
Transfer-Encoding
Server
Date
Keep-Alive
Connection
ETag
Last-Modified
Accept-Ranges
noCacheRequest¶
클라이언트가 no-cache요청을 보냈다면 바이패스한다.
GET / HTTP/1.1
cache-control: no-cache 또는 cache-control:max-age=0
pragma: no-cache
"noCacheRequest": {
"enable": false
}
enable (기본: false)
true
로 설정하면 클라이언트가 no-cache요청을 보냈을 때 바이패스한다.
Note
이 설정은 클라이언트 동작(아마도 ctrl
+ F5
)에 의해 판단된다.
그러므로 대량의 바이패스가 원본에 부담을 줄 가능성이 있다.
getMethod¶
바이패스가 GET요청의 기본동작이 되도록 설정한다.
"getMethod": {
"enable": false
}
enable (기본: false)
기본 동작은 캐싱이다.
true
로 설정하면GET
요청을 원본서버로 바이패스한다.
postMethod¶
바이패스가 POST요청의 기본동작이 되도록 설정한다.
"postMethod": {
"enable": true
}
enable (기본: true)
기본 동작은 원본 바이패스이다.
false
로 설정하면POST
요청을 캐싱한다.
extraMethods¶
HEAD, GET, POST
제외한 HTTP method 요청에 대한 기본 응답은 처리할 수 없기에 501 Not Implemented
이다.
특정 메소드를 원본서버가 처리할 수 있다면 설정 리스트에 추가하여 바이패스 시킨다.
"extraMethods": [
]
extraMethods
원본으로 바이패스할 메소드 리스트
설정가능 -
PUT
,DELETE
,PATCH
,OPTIONS
,TRACE
,PATCH
# PUT, OPTIONS 메소드만 바이패스한다. "extraMethods": [ "PUT", "OPTIONS" ]
설정불가 -
CONNECT
,HEAD
,GET
,POST
, 기타 비표준 문자열# 등록불가하거나 알 수 없는 메소드는 무시된다. "extraMethods": [ "CONNECT", "HEAD", "LIKE" ]
Note
이 설정은 OPTIONS
메소드에 대해 optionsMethod 보다 우선한다.
따라서 OPTIONS
메소드가 등록되면 원본으로 바이패스된다.
compression¶
원본 콘텐츠를 압축하여 전송한다.
Note
압축은 캐싱엔진을 경유할 때만 동작한다.
"compression": {
"enable": false,
"useOriginEncoding": false,
"method": "gzip",
"minSrcSize": 2,
"maxSrcSize": 2048,
"matchingList": [
{
"pattern": "$URL[/*.css]",
},
{
"pattern": "$URL[/*.js]",
}
]
}
enable (기본: false)
압축 활성화
useOriginEncoding (기본: false)
원본
Content-Encoding
응답에 따라 조건부 압축을 진행한다.false (기본)
항상 솔루션에서 압축하도록, 원본에Accept-Encoding
헤더를 보내지 않는다.true
원본에Accept-Encoding
헤더를 보내고, 원본에서 압축하지 않았을 때 (=Content-Encoding
을 명시하지 않았을 때)만 압축한다.
method (기본: gzip)
우선 압축 알고리즘 (
gzip
또는br
). 클라이언트와 호환되지 않는다면 자동 선택되거나 압축하지 않는다.minSrcSize (기본: 2KB)
최소 압축크기
maxSrcSize (기본: 2048KB)
최대 압축크기
matchingList
매칭리스트. 압축할 대상 URL을 결정한다.
gzip¶
gzip 압축정책을 설정한다.
"gzip": {
"level": 6
}
level (기본: 6)
gzip 압축 레벨 (범위: 1~9)
brotli¶
brotli 압축정책을 설정한다.
"brotli": {
"window": 22
"quality": 11
}
window (기본: 22)
LZ77 window size (범위: 10~24)
quality (기본: 11)
압축 레벨 (범위: 0~11)
customErrorPage¶
원본통신 장애등으로 인해 정상적인 서비스가 불가능한 경우 미리 정의된 에러페이지를 제공한다.
"customErrorPage": {
"resCode": 0,
"path": "/error.html"
}
responseCode (기본: 0)
에러페이지의 HTTP 응답코드. 0인 경우 STON의 에러코드가 제공된다.
path
원본장애 발생시 제공할 에러페이지 경로/URL
backEnd¶
M2와 원본서버 사이의 HTTP 트랜잭션에 대해 설정한다.
{
"functions": {
"network": {
"http": {
"backEnd": {
...
}
}
}
}
}
urlRewrites¶
캐싱을 목적으로 원본으로 보내는 HTTP요청의 URL을 변경한다.
"urlRewrites" : [
{
# /download/1.3.4 -> /1.3.4
"pattern": "/download/(.*)",
"replace": "/#1"
},
{
# /img/image.jpg?date=20140326 -> /image.jpg?date=20140326/m2/composite/watermark1
"pattern": "/img/(.*\.(jpg|png).*)",
"replace": "/#1/m2/composite/watermark1"
}
]
pattern
변경대상의 정규식 패턴
replace
정규식 패턴
urlRewrites 와 같은 표현을 사용하지만 가상호스트마다 독립적으로 설정하기 때문에 가상호스트명을 입력하지 않는다.
Note
바이패스되는 HTTP요청의 URL은 변경할 수 없다. wholeClientRequest 보다 우선한다.
session¶
원본서버 연결 및 요청 유입정책을 설정한다.
"session":{
"connectTimeout": 3,
"receiveTimeout": 10,
"reuseTimeout": 60,
"balanceMode": "roundrobin",
"maxUnknownSize": 32,
"authEndpoint": null
}
connectTimeout (기본: 3)
n초 이내에 원본서버와 접속이 이루어지지 않는 경우 접속실패로 간주한다.
receiveTimeout (기본: 10)
정상적인 HTTP요청에도 불구하고 원본서버가 HTTP응답을 n초 동안 보내지 않는 경우 전송실패로 간주한다.
reuseTimeout (기본: 60)
일정 시간동안 사용되지 않은 원본세션은 종료한다. 0으로 설정하면 원본서버 세션을 재사용하지 않는다.
balanceMode (기본: roundrobin)
원본서버 주소가 멀티(2개 이상)로 구성되어 있을 때 원본서버 선택정책을 설정한다.
roundrobin
- 모든 원본서버가 균등하게 요청을 받도록 Round-Robin으로 동작한다. 연결된 Idle세션은 해당 서버로 요청이 필요할 때만 사용한다.session
- 재사용할 수 있는 세션이 있다면 우선 사용한다. 신규 세션이 필요하면 Round-Robin으로 할당한다.hash
- 컨텐츠를 Consistent Hashing 알고리즘에 따라 원본서버로 분산하여 요청한다. 서버가 선택되면 이미 연결된 세션을 재사용하며 없다면 신규로 접속한다.
maxUnknownSize (기본: 32MB)
크기를 알 수 없는 원본 콘텐츠 최대 버퍼링 크기. 아래 2가지 상황을 모두 만족해야
maxUnknownSize
버퍼링이 이루어진다.localCacheStorage 가 구성되어 있지 않은 경우 (=메모리 모드)
원본에서
Content-Length
헤더를 제공하지 않는 경우 (예.Transfer-Encoding: Chunked
)
Note
이 경우 응답코드는
507 Insufficient Storage
이다. 이 응답이 발생할 경우 가급적 버퍼를 늘리는 것보다 다음 방안을 검토하는 것을 권장한다.해당 URL을 바이패스한다.
원본에서
Content-Length
를 부여한다.
authEndpoint
인증이 필요한 백엔드와 연결할 경우
{endpoint}@{function}
형식으로 설정한다. 예를 들어 AWS S3를 연결한다면 aws_s3 에 엔드포인트를 먼저 구성한 뒤, 해당 구성을 사용하는 방식이다.# aws_s3에 설정된 mystorage라는 endpoint를 사용한다. "authEndpoint": "mystorage@aws_s3"
Note
인증만 참조할 뿐 origin 설정은 그대로 사용한다.
hash¶
"balanceMode": "hash"
일 때 분산정책을 설정한다.
"hash":{
"urlIgnoreList": [
"/dims/",
"?start="
]
}
urlIgnoreList (기본: null)
효율화를 위해 URL 중 매칭되는 영역부터 Hash 정책에서 무시하도록 설정한다.
dns¶
원본주소를 Domain으로 설정하면 Resolving해서 IP를 얻어야 한다. ( dns.log 에 기록된다.) IP 목록은 동적으로 변경될 수 있으며 모든 IP는 TTL(Time To Live)동안만 유효하다.
Domain은 주기적으로(1~10초) Resolving한다.
Resolving을 통해 사용할 IP테이블을 구성한다.
모든 IP는 TTL만큼만 유효하며 TTL이 만료되면 사용하지 않는다.
같은 IP가 다시 Resolving되면 TTL을 갱신한다.
IP테이블은 비어서는 안된다. (TTL이 만료되었더라도) 마지막 IP들은 삭제되지 않는다.
IP의 TTL이 너무 길 경우 지나치게 많은 IP를 사용하게 되어 의도치 않은 결과를 만들 수 있다. 이를 방지하기 위해 IP의 최대 TTL을 제한할 수 있다.
"dns": {
"ttlMin": 0,
"ttlMax": 0
}
ttlMin (기본: 0)
Resolved TTL 값이 적다면
ttlMin
값으로 보정한다.ttlMax (기본: 0)
Resolved TTL 값이 크다면
ttlMax
값으로 보정한다.
간혹 너무 TTL이 짧은 경우 ttlMin
설정을 통해 최소 값을 보정할 수 있다.
예를 들어 ttlMin: 30
이라면 TTL이 30초 미만인 경우 30초로 보정된다.
Note
원본주소를 Domain으로 설정하여도 장애/복구는 IP기반으로 동작한다. Domain주소 장애/복구 정책은 다음과 같다.
(Domain에 대해) 알고 있는 모든 IP주소가 배제(Inactive)되면 해당 Domain주소가 배제된다.
신규 IP가 Resolving되더라도 Domain이 배제되어 있다면 IP주소는 처음부터 배제된다.
모든 IP가 TTL 만료되더라도 배제된 Domain상태는 풀리지 않는다.
배제된 Domain에 속한 IP주소가 하나라도 복구되어야 해당 Domain은 다시 활성화된다.
다소 복잡한 내용이므로 원본상태 모니터링 API API 결과 값의 상태변화를 서비스 동작상태에 대해 이해도를 높이는 것이 좋다.
health¶
원본서버 장애/복구 정책에 대해 설정한다.
{
"functions": {
"network": {
"http": {
"backEnd": {
"health": {
...
}
}
}
}
}
}
exclusion¶
캐싱과정 중 원본서버에 장애가 발생하면 자동배제한다.
"exclusion": {
"count": 3,
"events": {
"serverClosed": false
}
}
exclusion (기본: 3)
원본서버에서 연속적으로 n번 장애상황이 발생하면 해당 서버를 유효 원본서버 목록에서 배제한다. 배제 전 정상적인 통신이 이루어진다면 이 값은 다시 0으로 초기화된다.
Note
"count": 0
으로 설정하면 원본서버를 배제하지 않는다.events
기본 장애상황인
connectTimeout
,receiveTimeout
외에 장애상황을 추가한다.serverClosed (기본: false)
서버에서 트랜잭션 완료 전 연결을 먼저 종료하는 경우를 장애로 간주한다.
recovery¶
배제된 원본서버가 다시 안정화됐다고 판단하면 서비스에 투입한다.
"recovery": {
"cycle": 10,
"count": 5,
"responseCode": 0,
"url": "/",
"log": true,
"host": null
}
cycle (기본: 10초)
복구주기
Note
"cycle": 0
으로 설정하면 배제된 원본서버를 복구하지 않는다.
count (기본: 5)
복구허용 연속횟수
responseCode (기본: 0)
정상응답으로 처리할 응답코드. 0인 경우 응답코드와 상관없이 응답이 오면 성공으로 간주한다. 200으로 설정하면 응답코드가 반드시 200이어야 정상응답으로 처리한다. 콤마(,)를 사용하여 유효한 응답코드를 멀티로 설정한다. 200, 206, 404로 설정하면 응답코드가 이 중 하나인 경우 정상응답으로 처리한다.
url (기본: /)
요청을 보낼 url
log (기본: true)
복구를 위해 사용된 HTTP Transaction을 Origin 로그 에 기록한다.
host (기본: null)
복구 세션에서 사용할
Host
헤더를 설정한다.null
또는""
- 가상호스트 명을 사용한다.문자열
- 설정된 문자열을Host
헤더와SNI
필드로 사용한다.
cycle
마다 url
로 요청하여 원본서버가 responseCode
로 연속적으로 count
만큼 응답하면 해당 서버를 복구한다.
health-checkers¶
exclusion 과 recovery 는 캐싱과정 중 발생하는 장애에 대응한다. recovery 는 응답코드를 받는 즉시 HTTP 트랜잭션을 종료한다. 하지만 Health-Checker는 HTTP 트랜잭션이 성공함까지 주기적으로 확인하여 원본서버 배제여부를 결정한다.
"checkers": [
{
"resCode": [0],
"timeout": 10,
"cycle": 10,
"exclusion": 3,
"recovery": 5,
"log": true,
"url": "/",
"host": null
},
{
"resCode": [200, 404],
"timeout": 10,
"cycle": 10,
"exclusion": 3,
"recovery": 5,
"log": true,
"url": "/alive.html",
"host": null
}
]
resCode (기본: 0)
올바른 응답코드 (배열로 멀티 구성가능)
timeout (기본: 10초)
소켓연결부터 HTTP 트랜잭션이 완료될 때까지 유효시간
cycle (기본: 10초)
실행주기
exclusion (기본: 3회)
연속 n회 실패 시 해당서버 배제
recovery (기본: 5회)
연속 n회 성공 시 해당서버 재투입
log (기본: true)
HTTP 트랜잭션을 origin.log 에 기록한다.
url
요청 url
host (기본: null)
헬쓰체커에서 사용할
Host
헤더를 설정한다.null
또는""
- 가상호스트 명을 사용한다.문자열
- 설정된 문자열을Host
헤더와SNI
필드로 사용한다.
Health-Checker는 멀티로 구성할 수 있으며 클라이언트 요청과 상관없이 독립적으로 수행되며, 각각의 기준으로 배제와 투입을 결정한다.
headers¶
{
"functions": {
"network": {
"http": {
"backEnd": {
"headers": {
...
}
}
}
}
}
}
cacheOriginal¶
성능과 보안상의 이유로 원본서버가 보내는 헤더 중 캐싱과 관련된 표준 헤더만을 선별적으로 캐싱한다.
Note
어떠한 경우라도 다음 헤더는 캐싱할 수 없다.
cookie
set-cookie
set-cookie2
원본이 응답하는 헤더를 캐싱하기 위해서는 추가 설정이 필요하다.
"cacheOriginal": {
"enable": false,
"standard": false
}
enable (기본: false)
false (기본)
다음 헤더만을 캐싱한다.Cache-Control Content-Disposition Content-Encoding Content-Length Content-Type Expire Transfer-Encoding Server
true
위 목록 이외의 헤더를 캐싱한다.
"standard": false (기본)
비표준 헤더만을 캐싱한다.
"standard": true
비표준 헤더와 다음 목록의 헤더를 추가로 캐싱한다.:Content-Language Content-Location Content-MD5 Proxy-Authenticate Retry-After TE Trailer Warning WWW-Authenticate
host¶
원본서버로 보내는 HTTP요청의 Host
헤더를 설정한다.
별도로 설정하지 않은 경우 가상호스트 이름이 명시된다.
"host": {
"enable": false,
"value": null
}
enable (기본: false)
false (기본)
- 가상호스트 이름
true
-value
를 host 헤더의 값으로 설정한다. 클라이언트가 보낸 Host헤더를 원본으로 보내고 싶은 경우*
로 설정한다.
value
host 헤더 값
Note
원본서버에서 80포트 이외의 포트로 서비스하고 있다면 반드시 포트 번호를 명시해야 한다.
"host": {
"enable": true,
"value": "www.example2.com:8080"
}
userAgent¶
원본서버로 보내는 HTTP요청의 User-Agent
헤더를 설정한다.
"userAgent": {
"enable": false,
"value": null
}
enable (기본: false)
false
- 기본 User-Agent 헤더
true
-value
를 User-Agent 헤더의 값으로 설정한다.
value
host 헤더 값. 클라이언트가 보낸 User-Agent헤더를 원본으로 보내고 싶은 경우
*
로 설정한다.
xff¶
클라이언트와 원본서버 사이에 M2를 위치하면 원본서버는 클라이언트 IP를 얻을 수 없다.
때문에 M2는 원본서버로 보내는 모든 HTTP요청에 X-Forwarded-For
헤더를 명시한다.
"xff": {
"appendProxy": true
}
appendProxy (기본: true)
true
XFF헤더의 첫번째 주소만을 원본서버로 전송한다.X-Forwarded-For: 220.61.7.150
false
클라이언트(IP: 128.134.9.1)가 보낸 XFF헤더에 클라이언트 IP를 추가한다.클라이언트가 XFF헤더를 보내지 않았다면 클라이언트 IP만 명시된다.
X-Forwarded-For: 220.61.7.150, 61.1.9.100, 128.134.9.1
ifRange¶
원본에 Range요청을 보낼 때 If-Range헤더를 추가하여 요청한다.
"ifRange": {
"enable": false
}
enable (기본: false)
false
- Range요청 시 If-Range헤더를 추가하지 않는다.
true
- Range요청 시 If-Range헤더를 추가한다.
Note
If-Range 헤더에 의해 원본서버가 206 Partial Content
가 아닌 200 OK
응답을 주는 경우 다음과 같이 전개된다.
클라이언트가 요청한 파일은 무효화 처리
해당 클라이언트 요청은 실패
동일한 파일이 요청될 때 신규 캐싱 서비스
wholeClientRequest¶
원본에 요청할 때 클라이언트가 보낸 요청을 유지하도록 설정한다.
"wholeClientRequest": {
"enable": false
}
wholeClientRequest (기본: false)
false (기본)
캐싱엔진이 사용하는 캐싱키를 원본에 요청할 URL로 사용한다.
true
클라이언트가 요청한 URL로 원본에 요청한다.
originalEtag¶
원본서버에서 응답하는 ETag인식여부를 설정한다.
"originalEtag": {
"enable": false
}
originalEtag (기본: false)
false (기본)
ETag
헤더를 무시한다.
true
ETag
헤더를 인식하며 컨텐츠 갱신시If-None-Match
헤더를 추가한다.
limitMaxRange¶
한번에 다운로드 받는 컨텐츠 크기를 설정한다. 동영상처럼 앞 부분만이 주로 소비되는 컨텐츠의 경우 다운로드 크기를 제한하면 불필요한 원본 트래픽을 줄일 수 있다.
"limitMaxRange": {
"enable": false,
"size": 1
}
enable (기본: false)
기능 활성화
size (단위: MB)
0보다 크면 클라이언트가 요청한 지점부터 설정크기(MB) 만큼 Range요청으로 다운로드 한다.
limitMaxRange
를 사용하는 또 다른 이유는 디스크 공간을 절약하기 위함이다.
기본설정으로 M2는 원본크기의 파일을 디스크에 생성한다.
하지만 size
가 0이 아니라면 다운로드 되는만큼만 파일을 분할하여 저장한다.
예를 들어 1시간짜리 영상(600MB)을 1분(10MB)만 시청한 경우에 디스크 공간을 10MB만 사용한다. 공간을 절약하는 장점은 있지만 파일이 분할되어 저장되기 때문에 디스크 부하가 조금 높아진다.
Note
최초 콘텐츠를 다운로드할 때 Content-Length를 알 수 없으므로 Range요청을 할 수 없다.
때문에 size
가 설정되어 있다면 설정크기만큼만 다운로드 받고 연결을 종료한다.
initByFullRange¶
일반적으로 원본서버로부터 처음 파일을 다운로드 할 때나 갱신확인 할 때는 다음과 같이 단순한 형태의 GET 요청을 보낸다.
GET /file.dat HTTP/1.1
하지만 원본서버가 일반적인 GET요청에 대하여 항상 파일을 변조하도록 설정되어 있다면 원본파일 그대로를 Caching할 수 없어서 문제가 될 수 있다.
가장 대표적인 예는 Apache 웹서버가 mod_h.264_streaming같은 외부모듈과 같이 구동되는 경우이다. Apache 웹서버는 GET요청에 대해서 항상 mod_h.264_streaming모듈을 통해서 응답한다. 클라이언트(이 경우에는 M2)는 원본파일 그대로가 아닌 모듈에 의해 변조된 파일을 서비스 받는다.
Range요청을 사용하면 모듈을 우회하여 원본을 다운로드할 수 있다.
"initByFullRange": {
"enable": false,
"method": "get"
}
initByFullRange (기본: false)
true
- 0부터 시작하는 Range요청을 보낸다. Apache의 경우 Range헤더가 명시되면 모듈을 우회한다.GET /file.dat HTTP/1.1 Range: bytes=0-
최초로 파일 Caching할 때는 컨텐츠의 Range를 알지 못하므로 Full-Range(=0부터 시작하는)를 요청한다. 원본서버가 Range요청에 대해 정상적으로 응답(206 OK)하는지 반드시 확인해야 한다.
method (기본: get)
head
로 설정할 경우HEAD
메소드로 최초 요청을 보낸다.HEAD /file.dat HTTP/1.1
콘텐츠를 갱신할 때는 다음과 같이 If-Modified-Since
헤더가 같이 명시된다.
원본서버가 올바르게 304 Not Modified
로 응답해야 한다.
GET /file.dat HTTP/1.1
Range: bytes=0-
If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT
Note
initByFullRange
가 정상동작함을 확인한 웹서버들 목록.
Microsoft-IIS/7.5
nginx/1.4.2
lighttpd/1.4.32
Apache/2.2.22
modify¶
원본 HTTP요청과 응답헤더를 조건에 따라 변경한다.
"modify": {
"enable": false,
"matchFirstOnly": false,
"defaultCaseSensitive": true,
"matchingList": [
{
"pattern": "$URL[/*.mp4]",
"header": "$ORGREQ[x-media-type: video/mp4]",
"caseSensitive": false,
"mode": "set"
},
{
"pattern": "$URL[/images/private/*]",
"header": "$ORGRES[Server: m2server]",
"mode": "set_if_not_exist"
},
{
"pattern": "$IP[1.1.1.1]",
"header": "$ORGREQ[user-agent: media_probe]",
"mode": "put"
},
{
"pattern": "*",
"header": "$ORGREQ[If-Modified-Since]",
"mode": "unset"
},
{
# #PROTOCOL 키워드를 통해 클라이언트가 요청한 프로토콜을 헤더에 추가한다.
"pattern": "$URL[*]",
"header": "$ORGREQ[X-Forwarded-Proto: #PROTOCOL]",
"mode": "set"
},
{
# $REQ.header-name을 이용해 클라이언트 요청을 원본으로 보낼 수 있다.
"pattern": "$URL[/account/]",
"header": "$ORGREQ[cookie: $REQ.Cookie]",
"mode": "set"
},
{
# #HOSTNAME 키워드를 통해 요청을 보내는 호스트(서버) 이름을 헤더에 추가한다.
"pattern": "$URL[*]",
"header": "$ORGREQ[X-Req-Hostname: #HOSTNAME]",
"mode": "set"
}
]
}
$ORGREQ
$ORGRES
키워드를 사용한다는 것만 제외하면 modify 와 동일하다.
Note
If-Modified-Since
헤더와 If-None-Match
헤더를 unset
하면 TTL이 만료된 컨텐츠는 항상 다시 다운로드 한다.
forwardContextId¶
클라이언트 HTTP 트랜잭션의 UUID(로그의 x-ctx-id
필드)를 원본서버로 전달한다.
"forwardContextId": {
"enable": false,
"header": "X-M2X-Forwarded-Context-Id"
}
enable (기본: false)
기능 활성화
header (기본: X-M2X-Forwarded-Context-Id)
헤더 이름
See also
redirectionTrace¶
원본서버에서 Redirect계열(301, 302, 303, 307)로 응답하는 경우 Location
헤더를 추적하여 콘텐츠를 요청한다.
"redirectionTrace": {
"enable": false,
"max": 3,
"responseCode": ["3xx", "302", "307"],
"url": [ "*.ts", "*.mp4" ]
}
enable (기본: false)
true
로 설정하면 Location헤더에 명시된 주소에서 콘텐츠를 다운로드 한다.형식에 맞지 않거나 Location헤더가 없는 경우에는 동작하지 않는다. 무한히 Redirect되는 경우를 방지하기 위하여 1회만 추적한다.
max (기본: 3)
최대 redirect 동작 회수.
0
이라면enable
이false
인 것과 동일하다.responseCode
처리할 응답코드 목록
url": [ "*.ts", "*.mp4" ]
URL패턴을 설정하면 추적할 Location 대상을 지정할 수 있다.