httpd content-encoding 헤더 누락 문제

# nginx proxy -> apache httpd 웹서버 구성에서
# apache httpd 2.4 버전업과 brotli(br) 압축을 적용했다.
# 다음과 같이 nginx 에 br 인코딩 헤더로 요청을 준다.
# 참고로 -I 로 헤더만 보는경우 curl 은 HEAD method 로 요청하기 때문에
# 실제 GET 요청에서 응답받는 헤더를 보려면 GET method 로 지정해야 한다.
curl 'http://ysoftman-nginx/test?param=ysoftman'-H 'accept-encoding:br' -I -X GET

# 다음과 같이 content-encoding: br 응답헤더를 볼 수 있다.
HTTP/2 200
date: Thu, 03 Oct 2019 13:13:34 GMT
content-type: text/html; charset=utf-8
vary: Accept-Encoding
content-encoding: br
server: ysoftman-nginx
cache-control: private, no-cache, max-age=0
expires: -1

# gzip 요청도 테스트 해보면
curl 'http://ysoftman-nginx/test?param=ysoftman'-H 'accept-encoding:gzip' -I -X GET

# 다음과 같이 content-encoding: gzip 응답헤더를 볼 수 있다.
HTTP/2 200
date: Thu, 03 Oct 2019 13:09:34 GMT
content-type: text/html; charset=utf-8
vary: Accept-Encoding
content-encoding: gzip
server: ysoftman-nginx
cache-control: private, no-cache, max-age=0
expires: -1

# 문제
# nginx 에서 packetbeat 을 설치해 httpd 의 응답 헤더를 수집해 elasticsearch(es) 보냈다.
# kibana 로 content-encoding 헤더가 br 또는 gzip 을 카운트 하려는데
# http.response.headers.content-encoding 헤더 자체가 없는 로그가 있다.
# "accept-encoding" 요청이 없으면 plain text 로 헤더가 없는게 맞지만
# "accept-encoding: gzip" 요청은 있어야 한다.
# http.response.headers.content-encoding: br 은 잘 남고 있었다.
# 원인
# curl 이나 실제 브라우저에서 테스트 해보면
# content-encoding: br 또는 gzip 응답이 확인된다.
# 하지만 nginx 가 아닌 httpd 로 요청하면
# gzip 요청에 대해선 content-encoding 응답헤더가 없었다.
curl 'http://ysoftman-httpd/test?param=ysoftman'-H 'accept-encoding:gzip' -I -X GET

# gzip 처리를 nginx 가 해줘 nginx 의 packetbeat 은
# httpd 로 부터의 응답에서 "content-encoding: gzip" 찾을 수 없었던 것이다.
# 찾아보니 httpd.conf 에서 응답 필터 처리시
# 다음과 같이 brotli 만 응답 필터링한게 문제였다.
SetOutputFilter BROTLI_COMPRESS

# 해결
# SetOutputFilter 는 주석처리하고
# 다음과 같이 AddOutputFilterByType 로
# deflate(gizp에서 사용하는 무손실 압축 알고리즘), brotli 둘다 사용할 수 있게 했다.
# 먼저 추가한 필터가 우선순위를 가져 br 먼저 설정해야 한다.
AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/xml text/css text/javascript application/x-javascript application/javascript application/json application/x-font-ttf application/vnd.ms-fontobject image/x-icon

AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/x-javascript application/javascript application/json application/x-font-ttf application/vnd.ms-fontobject image/x-icon

# 그리고 AddOutputFilterByType 사용하려면 filter 모듈을 추가해야 한다.
LoadModule filter_module modules/mod_filter.so

# 이제 httpd 요청시에도 "content-encoding: gzip" 헤더를 받을 수 있고,
# packetbeat 에서도 잘 수집돼 -> es -> kibana 로 content-encoding 값을 구분 할 수 있다.

# 참고
https://httpd.apache.org/docs/current/mod/mod_filter.html#AddOutputFilterByType
https://www.tunetheweb.com/performance/brotli/

comments:

댓글 쓰기