Skip to content

Commit 5f295b9

Browse files
iii-idna2github
authored andcommitted
Gzip: use zlib to write header and trailer.
When nginx is used with zlib patched with [1], which provides integration with the future IBM Z hardware deflate acceleration, it ends up computing CRC32 twice: one time in hardware, which always does this, and one time in software by explicitly calling crc32(). crc32() calls were added in changesets 133:b27548f540ad ("nginx-0.0.1- 2003-09-24-23:51:12 import") and 134:d57c6835225c ("nginx-0.0.1- 2003-09-26-09:45:21 import") as part of gzip wrapping feature - back then zlib did not support it. However, since then gzip wrapping was implemented in zlib v1.2.0.4, and it's already being used by nginx for log compression. This patch replaces hand-written gzip wrapping with the one provided by zlib. It simplifies the code, and makes it avoid computing CRC32 twice when using hardware acceleration. [1] madler/zlib#410
1 parent 2ea526b commit 5f295b9

File tree

1 file changed

+7
-117
lines changed

1 file changed

+7
-117
lines changed

src/http/modules/ngx_http_gzip_filter_module.c

Lines changed: 7 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -55,44 +55,23 @@ typedef struct {
5555
unsigned redo:1;
5656
unsigned done:1;
5757
unsigned nomem:1;
58-
unsigned gzheader:1;
5958
unsigned buffering:1;
6059
unsigned intel:1;
6160

6261
size_t zin;
6362
size_t zout;
6463

65-
uint32_t crc32;
6664
z_stream zstream;
6765
ngx_http_request_t *request;
6866
} ngx_http_gzip_ctx_t;
6967

7068

71-
#if (NGX_HAVE_LITTLE_ENDIAN && NGX_HAVE_NONALIGNED)
72-
73-
struct gztrailer {
74-
uint32_t crc32;
75-
uint32_t zlen;
76-
};
77-
78-
#else /* NGX_HAVE_BIG_ENDIAN || !NGX_HAVE_NONALIGNED */
79-
80-
struct gztrailer {
81-
u_char crc32[4];
82-
u_char zlen[4];
83-
};
84-
85-
#endif
86-
87-
8869
static void ngx_http_gzip_filter_memory(ngx_http_request_t *r,
8970
ngx_http_gzip_ctx_t *ctx);
9071
static ngx_int_t ngx_http_gzip_filter_buffer(ngx_http_gzip_ctx_t *ctx,
9172
ngx_chain_t *in);
9273
static ngx_int_t ngx_http_gzip_filter_deflate_start(ngx_http_request_t *r,
9374
ngx_http_gzip_ctx_t *ctx);
94-
static ngx_int_t ngx_http_gzip_filter_gzheader(ngx_http_request_t *r,
95-
ngx_http_gzip_ctx_t *ctx);
9675
static ngx_int_t ngx_http_gzip_filter_add_data(ngx_http_request_t *r,
9776
ngx_http_gzip_ctx_t *ctx);
9877
static ngx_int_t ngx_http_gzip_filter_get_buf(ngx_http_request_t *r,
@@ -446,12 +425,6 @@ ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
446425
return ctx->busy ? NGX_AGAIN : NGX_OK;
447426
}
448427

449-
if (!ctx->gzheader) {
450-
if (ngx_http_gzip_filter_gzheader(r, ctx) != NGX_OK) {
451-
goto failed;
452-
}
453-
}
454-
455428
rc = ngx_http_next_body_filter(r, ctx->out);
456429

457430
if (rc == NGX_ERROR) {
@@ -643,7 +616,7 @@ ngx_http_gzip_filter_deflate_start(ngx_http_request_t *r,
643616
ctx->zstream.opaque = ctx;
644617

645618
rc = deflateInit2(&ctx->zstream, (int) conf->level, Z_DEFLATED,
646-
- ctx->wbits, ctx->memlevel, Z_DEFAULT_STRATEGY);
619+
ctx->wbits + 16, ctx->memlevel, Z_DEFAULT_STRATEGY);
647620

648621
if (rc != Z_OK) {
649622
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
@@ -652,45 +625,12 @@ ngx_http_gzip_filter_deflate_start(ngx_http_request_t *r,
652625
}
653626

654627
ctx->last_out = &ctx->out;
655-
ctx->crc32 = crc32(0L, Z_NULL, 0);
656628
ctx->flush = Z_NO_FLUSH;
657629

658630
return NGX_OK;
659631
}
660632

661633

662-
static ngx_int_t
663-
ngx_http_gzip_filter_gzheader(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx)
664-
{
665-
ngx_buf_t *b;
666-
ngx_chain_t *cl;
667-
static u_char gzheader[10] =
668-
{ 0x1f, 0x8b, Z_DEFLATED, 0, 0, 0, 0, 0, 0, 3 };
669-
670-
b = ngx_calloc_buf(r->pool);
671-
if (b == NULL) {
672-
return NGX_ERROR;
673-
}
674-
675-
b->memory = 1;
676-
b->pos = gzheader;
677-
b->last = b->pos + 10;
678-
679-
cl = ngx_alloc_chain_link(r->pool);
680-
if (cl == NULL) {
681-
return NGX_ERROR;
682-
}
683-
684-
cl->buf = b;
685-
cl->next = ctx->out;
686-
ctx->out = cl;
687-
688-
ctx->gzheader = 1;
689-
690-
return NGX_OK;
691-
}
692-
693-
694634
static ngx_int_t
695635
ngx_http_gzip_filter_add_data(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx)
696636
{
@@ -743,14 +683,9 @@ ngx_http_gzip_filter_add_data(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx)
743683

744684
} else if (ctx->in_buf->flush) {
745685
ctx->flush = Z_SYNC_FLUSH;
746-
}
747-
748-
if (ctx->zstream.avail_in) {
749686

750-
ctx->crc32 = crc32(ctx->crc32, ctx->zstream.next_in,
751-
ctx->zstream.avail_in);
752-
753-
} else if (ctx->flush == Z_NO_FLUSH) {
687+
} else if (ctx->zstream.avail_in == 0) {
688+
/* ctx->flush == Z_NO_FLUSH */
754689
return NGX_AGAIN;
755690
}
756691

@@ -932,13 +867,11 @@ static ngx_int_t
932867
ngx_http_gzip_filter_deflate_end(ngx_http_request_t *r,
933868
ngx_http_gzip_ctx_t *ctx)
934869
{
935-
int rc;
936-
ngx_buf_t *b;
937-
ngx_chain_t *cl;
938-
struct gztrailer *trailer;
870+
int rc;
871+
ngx_chain_t *cl;
939872

940873
ctx->zin = ctx->zstream.total_in;
941-
ctx->zout = 10 + ctx->zstream.total_out + 8;
874+
ctx->zout = ctx->zstream.total_out;
942875

943876
rc = deflateEnd(&ctx->zstream);
944877

@@ -960,50 +893,7 @@ ngx_http_gzip_filter_deflate_end(ngx_http_request_t *r,
960893
*ctx->last_out = cl;
961894
ctx->last_out = &cl->next;
962895

963-
if (ctx->zstream.avail_out >= 8) {
964-
trailer = (struct gztrailer *) ctx->out_buf->last;
965-
ctx->out_buf->last += 8;
966-
ctx->out_buf->last_buf = 1;
967-
968-
} else {
969-
b = ngx_create_temp_buf(r->pool, 8);
970-
if (b == NULL) {
971-
return NGX_ERROR;
972-
}
973-
974-
b->last_buf = 1;
975-
976-
cl = ngx_alloc_chain_link(r->pool);
977-
if (cl == NULL) {
978-
return NGX_ERROR;
979-
}
980-
981-
cl->buf = b;
982-
cl->next = NULL;
983-
*ctx->last_out = cl;
984-
ctx->last_out = &cl->next;
985-
trailer = (struct gztrailer *) b->pos;
986-
b->last += 8;
987-
}
988-
989-
#if (NGX_HAVE_LITTLE_ENDIAN && NGX_HAVE_NONALIGNED)
990-
991-
trailer->crc32 = ctx->crc32;
992-
trailer->zlen = ctx->zin;
993-
994-
#else
995-
996-
trailer->crc32[0] = (u_char) (ctx->crc32 & 0xff);
997-
trailer->crc32[1] = (u_char) ((ctx->crc32 >> 8) & 0xff);
998-
trailer->crc32[2] = (u_char) ((ctx->crc32 >> 16) & 0xff);
999-
trailer->crc32[3] = (u_char) ((ctx->crc32 >> 24) & 0xff);
1000-
1001-
trailer->zlen[0] = (u_char) (ctx->zin & 0xff);
1002-
trailer->zlen[1] = (u_char) ((ctx->zin >> 8) & 0xff);
1003-
trailer->zlen[2] = (u_char) ((ctx->zin >> 16) & 0xff);
1004-
trailer->zlen[3] = (u_char) ((ctx->zin >> 24) & 0xff);
1005-
1006-
#endif
896+
ctx->out_buf->last_buf = 1;
1007897

1008898
ctx->zstream.avail_in = 0;
1009899
ctx->zstream.avail_out = 0;

0 commit comments

Comments
 (0)