2011-12-08 24 views
6

Escribí un controlador nginx muy simple, solo imprimí un texto (tamaño 100B a 10KB).El filtro gzip de Nginx no funciona con mi controlador personalizado

el código funciona correctamente con Nginx (ver 1.0.6)

pero he encontrado filtro gzip no puede trabajar con el controlador.

cuando enciendo gzip en nginx.conf (en la sección http), el archivo gzip funciona con archivos html estáticos.

pero, la respuesta del controlador no está comprimida con gzip.

después de un montón de trabajo de búsqueda, todavía no puedo encontrar la respuesta.

¿Algún comentario? muchas gracias. :-)

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

Respuesta

0

En primer lugar, donde es su llamada a ngx_http_send_header(r);?

¿Está inicializando los miembros de ngx_buf_t *b?

¿Está su codificación de contenido para el conjunto de solicitudes?

¿Su controlador produce un error? Si es así, ¿no se llamará a ningún filtro?

Otras limitaciones que se deben cumplir para garantizar las carreras de filtración gzip (en lugar de ser pasado por alto) cuando se le llama por su manejador incluyen

  • Gzip debe estar habilitado en el archivo de configuración de nginx ver here
  • El estado encabezado enviado debe ser ya sea NGX_HTTP_OK, NGX_HTTP_FORBIDDEN o NGX_HTTP_NOT_FOUND
  • la codificación de contenido debe ajustarse (debe existir la ngx_table_elt_t * y el valor en debería ser tener una longitud no cero
  • T él content_length_n debe ser válida (no -1) y debe ser mayor que o igual al valor gzip_min_length especificado en el archivo de configuración
  • ngx_http_test_content_type necesita volver por ejemplo no nulo, un tipo de contexto válido
  • La solicitud tiene que tener una encabezado y cuerpo

Consulte here para obtener más información sobre el desarrollo del módulo Nginx, el llenado y el manipulador.

1

Si no es demasiado tarde, tuve el mismo problema con mi módulo de filtro.

El problema está relacionado con el hecho de que cambia la respuesta Content-type. Gzip verifica Content-Type en content_type_len y content_type_lowcase para decidir si la respuesta debe ser Gziped. Este código debería funcionar:

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; 

Para entender por qué funciona este código, usted tiene que considerar que el filtro gzip llama al principio el ngx_http_test_content_type método para permitir gzip en la respuesta. Puede ver la fuente aquí: http://lxr.evanmiller.org/http/source/http/ngx_http_core_module.c#L1659

0

La respuesta anterior parece ... imprecisa.

El código que comprueba esto se encuentra en o alrededor de la línea 250 de src/http/modules/ngx_http_gzip_filter_module.c y lee:

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

Si estoy leyendo correctamente, las condiciones son:

  • estado HTTP debe ser 200 , debe no ajustarse 403 o 404.
  • content_encoding (que tiene sentido: gzipping coloca la codificación de contenido a "gzip")
  • content_length_n, si está configurado, debe ser mayor que la longitud mínima (valor predeterminado 20). No establecer una longitud de contenido es aceptable.
  • content_type debe estar en la lista válida. De forma predeterminada, solo se acepta "text/html", pero se pueden establecer otros tipos con la opción de configuración gzip_types. Si la lista incluye "*", cualquier tipo de contenido, incluido ninguno, está bien.
  • Debe haber algún cuerpo para comprimir

partir de la versión 1.7.10, la return anterior es en la línea 257. Ajuste "Daemon off", que corre bajo el BGF y b ngx_http_gzip_filter_module.c:257 le permitirá ver exactamente cuándo y cómo están fallando los cheques. (Probablemente deberías compilar desde la fuente si estás intentando esto ...)

Cuestiones relacionadas