2011-12-08 2 views
6

아주 간단한 nginx 처리기를 작성하여 일부 텍스트 (크기 100B에서 10KB) 만 출력했습니다.Nginx gzip 필터가 내 사용자 정의 처리기에서 작동하지 않습니다.

코드 (1.0.6 버전)의 nginx 제대로 작동

하지만 난 gzip을 필터 핸들러와 함께 작동하지 않을 수 있습니다 발견했다.

(http 섹션에서) nginx.conf에서 gzip을 켜면 gzip은 정적 HTML 파일로 파일을 작동합니다.

하지만 핸들러의 응답은 gzip으로 압축되지 않습니다.

많은 검색 작업 후에도 여전히 답변을 찾을 수 없습니다.

댓글? 고마워. :-)

//my code : 
static ngx_int_t ngx_http_test_handler(ngx_http_request_t *r){ 

    ngx_chain_t out; 
    ngx_buf_t *b; 

    b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); 

    ...... 
    //writing text to buffer 
    ...... 
    r->headers_out.status = NGX_HTTP_OK; 
    r->headers_out.content_length_n = len; 
    r->headers_out.content_type.len = sizeof("text/html")-1; 
    r->headers_out.content_type.data = (u_char *) "text/html"; 

    out.buf = b; 
    out.next = NULL; 
    return ngx_http_output_filter(r, &out); 
} 

답변

0

첫째 곳 ngx_http_send_header(r);에 전화 무엇입니까?

ngx_buf_t *b의 회원을 초기화 하시겠습니까?

요청에 대한 콘텐츠 인코딩이 설정되어 있습니까?

처리기에서 오류가 발생합니까? 그렇다면 필터가 호출되지 않습니까? 핸들러에 의해 호출하면 (오히려 무시되는 것이 아니라) gzip을 필터 실행을 보장하기 위해 충족해야

다른 제약

    Gzip으로는 nginx를 구성 파일에서 활성화해야합니다
  • 참조 포함 here
  • 전송 헤더 상태는 어느 NGX_HTTP_OK, NGX_HTTP_FORBIDDEN 또는 NGX_HTTP_NOT_FOUND
  • 컨텐츠 인코딩은 ngx_table_elt_t *에 존재한다 (설정되어야하고있는 값이 0이 아닌 길이
  • T를 가지고 있어야한다 그 유효 (되지 -1)이어야 content_length_n 비 널 예
  • 요청이 있어야 유효한 콘텍스트 타입을 반환해야 ngx_http_test_content_type 구성 파일
  • 지정된 gzip_min_length 값 이상이어야 머리글 및 본문

Nginx 모듈, 채우기 및 처리기 개발에 대한 자세한 내용은 here을 참조하십시오.

1

너무 늦지 않았다면 필자의 필터 모듈에도 동일한 문제가있었습니다.

문제는 응답 Content-type을 변경한다는 것과 관련이 있습니다. Gzip은 content_type_len 및 content_type_lowcase에서 Content-Type을 확인하여 응답을 Gziped해야하는지 결정합니다. 이 코드는 작동합니다 : 코드가 작동, 당신은 Gzip으로 필터 응답에 GZIP을 사용하려면 먼저 방법 ngx_http_test_content_type에서 호출하는 고려해야 할 이유

r->headers_out.content_type_len = strlen("text/html"); 
r->headers_out.content_type.len = strlen("text/html"); 
r->headers_out.content_type.data = (u_char *) "text/html"; 
r->headers_out.content_type_lowcase = NULL; 

는 이해하기. 여기에 소스를 볼 수 있습니다 : http://lxr.evanmiller.org/http/source/http/ngx_http_core_module.c#L1659

0

위의 대답은 ... 정확하지 않은 것 같습니다.

이 또는 src/http/modules/ngx_http_gzip_filter_module.c 라인 (250) 주변에 위치한 확인하고 읽는 코드 : 내가 제대로 읽고 있어요 경우

if (!conf->enable 
    || (r->headers_out.status != NGX_HTTP_OK 
     && r->headers_out.status != NGX_HTTP_FORBIDDEN 
     && r->headers_out.status != 207 
     && r->headers_out.status != NGX_HTTP_NOT_FOUND) 
    || (r->headers_out.content_encoding 
     && r->headers_out.content_encoding->value.len) 
    || (r->headers_out.content_length_n != -1 
     && r->headers_out.content_length_n < conf->min_length) 
    || ngx_http_test_content_type(r, &conf->types) == NULL 
    || r->header_only) 
{ 
    return ngx_http_next_header_filter(r); <-- this is the line you want to breakpoint! 
} 

, 조건은 다음과 같습니다

  • HTTP 상태는 200이어야합니다 , 403 또는 404입니다.
  • content_encoding은 이 아니고이되어야합니다 (gzipping은 콘텐츠 인코딩을 "gzip"으로 설정 함)
  • content_length_n이 설정되면 최소 길이 (기본값 20)보다 커야합니다. 콘텐츠 길이를 설정하지 않아도됩니다.
  • content_type은 유효한 목록에 있어야합니다. 기본적으로 "text/html"만 허용되지만 다른 유형은 gzip_types 구성 옵션으로 설정할 수 있습니다. 목록에 "*"가 포함되어 있으면 아무 것도 포함하지 않은 모든 콘텐츠 유형이 정상입니다.
  • return 위, "오프 디먼에"GDB에서 실행하고 b ngx_http_gzip_filter_module.c:257 당신이 정확하게 볼 수있게됩니다 라인 257 설정에 일부 몸이 버전 1.7.10의로

를 압축이 있어야합니다 때 수표가 어떻게 실패했는지. (아마이 소스 코드를 컴파일하려고한다면 ...)

관련 문제