2011-12-08 7 views
6

非常に単純なnginxハンドラを書きましたが、何らかのテキスト(サイズ100B〜10KB)を出力しました。私のカスタムハンドラではNginx gzipフィルタが動作しません

コードは(1.0.6のver)nginxので正常に動作する

が、私はgzipのフィルタは、ハンドラでは動作しないことができました。

nginx.conf(httpセクションの下)で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 *が存在し、値のいずれかが非ゼロ長
  • Tを有していなければならないでなければなりません彼はnull以外を返す必要ngx_http_test_content_type
  • 設定ファイルで有効である必要がありcontent_length_n(ない-1)よりも大きいか、指定gzip_min_length値と同じでなければなりません例えば、有効なコンテキストタイプ
  • 要求が持っている必要がありますヘッダーと本文

Nginxモジュール、フィラー、ハンドラーの開発に関する詳細は、hereを参照してください。

1

遅すぎることがなければ、私のフィルタモジュールで同じ問題がありました。

問題は、レスポンスContent-typeを変更したことに関連しています。 Gzipはcontent_type_lenとcontent_type_lowcaseのContent-Typeをチェックして、応答がGzipedである必要があるかどうかを判断します。このコードは動作するはずです:

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; 

このコードの動作は、あなたがGzipでフィルタが応答にGZIPを有効にするには、最初の方法のngx_http_test_content_typeで呼び出すことを考慮しなければならない理由を理解するために。ここでソースを見ることができます: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設定オプションで設定できます。リストに「*」が含まれている場合は、コンテンツタイプがまったく含まれていなくてもOKです。
  • バージョン1.7.10のとおり

を圧縮するために、いくつかの体が存在しなければならない、上記returnが「オフデーモン」の設定ライン257上で、GDBとb ngx_http_gzip_filter_module.c:257の下で実行すると、あなたが見ることができるようになります正確にするときとどのようにチェックが失敗しているか。 (もしあなたがこれを試しているのなら、おそらくソースからコンパイルするべきです...)

関連する問題