2011-12-08 10 views
6

Ho scritto un gestore nginx molto semplice, ho appena emesso del testo (dimensioni da 100B a 10KB).Il filtro gzip Nginx non funziona con il mio gestore personalizzato

il codice funziona correttamente con nginx (ver 1.0.6)

ma ho trovato il filtro gzip non può funzionare con il gestore.

quando accendo gzip in nginx.conf (nella sezione http), gzip funziona con file html statici.

ma, la risposta del gestore non è compressa con gzip.

dopo un lungo lavoro di ricerca, non riesco ancora a trovare la risposta.

eventuali commenti? molte grazie. :-)

//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); 
} 

risposta

0

In primo luogo dove è la vostra chiamata a ngx_http_send_header(r);?

Stai inizializzando i membri di ngx_buf_t *b?

La codifica del contenuto per il set di richieste è?

Il gestore genera un errore? Se è così, nessun filtro sarà chiamato?

Altri vincoli che devono essere soddisfare per garantire le corse del filtro gzip (invece di essere bypassato) quando viene chiamato dal vostro gestore includono

  • Gzip deve essere abilitato nel file di configurazione di nginx vedere here
  • Il Situazione intestazione inviata dovrebbe essere sia NGX_HTTP_OK, NGX_HTTP_FORBIDDEN o NGX_HTTP_NOT_FOUND
  • la codifica contenuto deve essere impostato (il ngx_table_elt_t * deve esistere e il valore dovrebbe essere avere una lunghezza nulla non
  • T egli content_length_n dovrebbe essere valido (non -1) e deve essere maggiore o uguale al valore gzip_min_length specificato nel file di configurazione
  • ngx_http_test_content_type deve restituire esempio non nulla, un tipo di contesto valido
  • La richiesta deve avere un intestazione e corpo

Vedere here per ulteriori informazioni sullo sviluppo di Nginx Module, Fillter e Handler.

1

Se non è troppo tardi, ho avuto lo stesso problema con il mio modulo filtro.

Il problema è legato al fatto che si modifica la risposta Tipo di contenuto. Gzip controlla il Content-Type su content_type_len e content_type_lowcase per decidere se la risposta deve essere Gzip. Questo codice dovrebbe funzionare:

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; 

Per comprendere il motivo per cui questo lavoro di codice, è necessario considerare che il filtro Gzip chiama in un primo momento il metodo ngx_http_test_content_type per consentire gzip sulla risposta. Puoi vedere la fonte qui: http://lxr.evanmiller.org/http/source/http/ngx_http_core_module.c#L1659

0

La risposta di cui sopra sembra ... imprecisa.

Il codice che controlla questo si trova in corrispondenza o attorno alla riga 250 di src/http/modules/ngx_http_gzip_filter_module.c e legge:

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! 
} 

Se sto leggendo correttamente, le condizioni sono:

  • stato HTTP deve essere 200 , 403 o 404.
  • content_encoding deve non essere impostato (che ha senso: gzipping imposta la codifica del contenuto su "gzip")
  • content_length_n, se impostato, deve essere maggiore della lunghezza minima (valore predefinito 20). Non è possibile impostare una lunghezza del contenuto accettabile.
  • content_type deve essere nell'elenco valido. Per impostazione predefinita, solo "text/html" è accettato, ma altri tipi possono essere impostati con l'opzione di configurazione gzip_types. Se l'elenco include "*", qualsiasi tipo di contenuto, incluso nessuno, è OK.
  • ci deve essere qualche corpo a comprimere

A partire dalla versione 1.7.10, il return sopra è on line 257. Setting "Daemon off", in esecuzione sotto gdb e b ngx_http_gzip_filter_module.c:257 vi permetterà di vedere con precisione quando e come i controlli stanno fallendo. (Probabilmente dovresti compilare dal sorgente se stai provando questo ...)

Problemi correlati