Skip to content

Commit d1ff206

Browse files
committed
Unzip filter configuration merging
1 parent 4688700 commit d1ff206

File tree

2 files changed

+87
-63
lines changed

2 files changed

+87
-63
lines changed

ngx_http_upload_module.c

+9-4
Original file line numberDiff line numberDiff line change
@@ -1548,7 +1548,7 @@ ngx_http_upload_add_filter(ngx_http_upload_loc_conf_t *ulcf,
15481548
static char * /* {{{ ngx_http_upload_filter_block */
15491549
ngx_http_upload_filter_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
15501550
{
1551-
ngx_http_upload_loc_conf_t *ulcf, *pulcf;
1551+
ngx_http_upload_loc_conf_t *ulcf, *pulcf = conf;
15521552

15531553
char *rv;
15541554
void *mconf;
@@ -1557,9 +1557,7 @@ ngx_http_upload_filter_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
15571557
ngx_conf_t save;
15581558
ngx_http_module_t *module;
15591559
ngx_http_conf_ctx_t *ctx, *pctx;
1560-
ngx_http_core_loc_conf_t *clcf, *pclcf = conf;
1561-
1562-
pulcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_upload_module);
1560+
ngx_http_core_loc_conf_t *clcf, *pclcf;
15631561

15641562
value = cf->args->elts;
15651563

@@ -1607,9 +1605,16 @@ ngx_http_upload_filter_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
16071605
}
16081606
}
16091607

1608+
pclcf = pctx->loc_conf[ngx_http_core_module.ctx_index];
1609+
16101610
clcf = ctx->loc_conf[ngx_http_core_module.ctx_index];
16111611
clcf->loc_conf = ctx->loc_conf;
16121612
clcf->name = pclcf->name;
1613+
clcf->noname = 1;
1614+
1615+
if (ngx_http_add_location(cf, &pclcf->locations, clcf) != NGX_OK) {
1616+
return NGX_CONF_ERROR;
1617+
}
16131618

16141619
save = *cf;
16151620
cf->ctx = ctx;

ngx_upload_unzip_filter_module.c

+78-59
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,9 @@ typedef struct {
6262

6363
typedef struct {
6464
ngx_bufs_t bufs;
65-
ssize_t wbits;
66-
ssize_t max_file_name_len;
67-
unsigned int recursive:1;
68-
} ngx_unzip_conf_t;
65+
size_t wbits, memlevel;
66+
size_t max_file_name_len;
67+
} ngx_unzip_loc_conf_t;
6968

7069
typedef enum {
7170
unzip_state_signature,
@@ -95,10 +94,10 @@ typedef struct {
9594
uint16_t last_mod_time;
9695
uint16_t last_mod_date;
9796
uint32_t crc32;
98-
ssize_t compressed_size;
99-
ssize_t uncompressed_size;
100-
ssize_t file_name_len;
101-
ssize_t extra_field_len;
97+
size_t compressed_size;
98+
size_t uncompressed_size;
99+
size_t file_name_len;
100+
size_t extra_field_len;
102101
} ngx_unzip_local_data_header_t;
103102

104103
typedef struct {
@@ -209,6 +208,8 @@ void ngx_http_unzip_chain_advance(ngx_chain_t *chain, ngx_chain_t *copy);
209208

210209
static char * ngx_upload_unzip_command(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
211210
static void *ngx_upload_unzip_create_loc_conf(ngx_conf_t *cf);
211+
static char *ngx_upload_unzip_merge_loc_conf(ngx_conf_t *cf,
212+
void *parent, void *child);
212213

213214
static ngx_int_t ngx_http_unzip_start_handler(ngx_http_upload_ctx_t *u);
214215
static void ngx_http_unzip_finish_handler(ngx_http_upload_ctx_t *u);
@@ -227,6 +228,7 @@ static void ngx_http_unzip_inflate_abort(ngx_unzip_ctx_t *ctx);
227228
static ngx_int_t ngx_http_unzip_inflate_process_chain(ngx_unzip_ctx_t *ctx, ngx_chain_t *chain);
228229

229230
static char *ngx_http_unzip_window(ngx_conf_t *cf, void *post, void *data);
231+
static char *ngx_http_unzip_hash(ngx_conf_t *cf, void *post, void *data);
230232

231233
static ngx_int_t
232234
ngx_http_unzip_set_decompression_method(ngx_unzip_ctx_t *ctx, uint16_t compression_method_number);
@@ -259,14 +261,15 @@ ngx_http_unzip_content_filter = {
259261
} /* }}} */;
260262

261263
static ngx_conf_post_handler_pt ngx_http_unzip_window_p = ngx_http_unzip_window;
264+
static ngx_conf_post_handler_pt ngx_http_unzip_hash_p = ngx_http_unzip_hash;
262265

263266
static ngx_command_t ngx_upload_unzip_filter_commands[] = { /* {{{ */
264267

265268
/*
266269
* Enables unzipping of uploaded file
267270
*/
268271
{ ngx_string("upload_unzip"),
269-
NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
272+
NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS|NGX_CONF_TAKE1,
270273
ngx_upload_unzip_command,
271274
NGX_HTTP_LOC_CONF_OFFSET,
272275
0,
@@ -276,52 +279,37 @@ static ngx_command_t ngx_upload_unzip_filter_commands[] = { /* {{{ */
276279
* Specifies size and number of buffers to use for decompressing
277280
*/
278281
{ ngx_string("upload_unzip_buffers"),
279-
NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
282+
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
280283
ngx_conf_set_bufs_slot,
281284
NGX_HTTP_LOC_CONF_OFFSET,
282-
offsetof(ngx_unzip_conf_t, bufs),
285+
offsetof(ngx_unzip_loc_conf_t, bufs),
283286
NULL },
284287

285288
/*
286-
* Specifies size window to use for decompressing
289+
* Specifies window size to use for decompressing
287290
*/
288291
{ ngx_string("upload_unzip_window"),
289-
NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
292+
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
290293
ngx_conf_set_size_slot,
291294
NGX_HTTP_LOC_CONF_OFFSET,
292-
offsetof(ngx_unzip_conf_t, wbits),
295+
offsetof(ngx_unzip_loc_conf_t, wbits),
293296
&ngx_http_unzip_window_p },
294297

295-
/*
296-
* Specifies a form field with a special content to generate
297-
* in output form
298-
*/
299-
{ ngx_string("upload_unzip_set_form_field"),
300-
NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
301-
ngx_conf_set_size_slot,
302-
NGX_HTTP_LOC_CONF_OFFSET,
303-
offsetof(ngx_unzip_conf_t, wbits),
304-
NULL },
305-
306-
/*
307-
* Specifies a form field with a special aggregate content to generate
308-
* in output form
309-
*/
310-
{ ngx_string("upload_unzip_aggregate_form_field"),
311-
NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
298+
{ ngx_string("upload_unzip_hash"),
299+
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
312300
ngx_conf_set_size_slot,
313-
NGX_HTTP_LOC_CONF_OFFSET,
314-
offsetof(ngx_unzip_conf_t, wbits),
315-
NULL },
301+
NGX_HTTP_LOC_CONF_OFFSET,
302+
offsetof(ngx_unzip_loc_conf_t, memlevel),
303+
&ngx_http_unzip_hash_p },
316304

317305
/*
318-
* Specifies the maximal length of a file name in archive
306+
* Specifies maximal allowed length of file in ZIP archive
319307
*/
320308
{ ngx_string("upload_unzip_max_file_name_len"),
321-
NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
309+
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
322310
ngx_conf_set_size_slot,
323311
NGX_HTTP_LOC_CONF_OFFSET,
324-
offsetof(ngx_unzip_conf_t, max_file_name_len),
312+
offsetof(ngx_unzip_loc_conf_t, max_file_name_len),
325313
NULL },
326314

327315
ngx_null_command
@@ -338,7 +326,7 @@ ngx_http_module_t ngx_upload_unzip_filter_module_ctx = { /* {{{ */
338326
NULL, /* merge server configuration */
339327

340328
ngx_upload_unzip_create_loc_conf, /* create location configuration */
341-
NULL /* merge location configuration */
329+
ngx_upload_unzip_merge_loc_conf /* merge location configuration */
342330
}; /* }}} */
343331

344332
ngx_module_t ngx_upload_unzip_filter_module = { /* {{{ */
@@ -359,21 +347,10 @@ ngx_module_t ngx_upload_unzip_filter_module = { /* {{{ */
359347
static char * /* {{{ ngx_upload_unzip_command */
360348
ngx_upload_unzip_command(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
361349
{
362-
ngx_unzip_conf_t *uzcf = conf;
363350
ngx_http_upload_loc_conf_t *ulcf;
364351

365-
ngx_str_t *value;
366-
367352
ulcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_upload_module);
368353

369-
value = cf->args->elts;
370-
371-
if(cf->args->nelts > 1) {
372-
if(ngx_strcmp(value[1].data, "recursive") == 0) {
373-
uzcf->recursive = 1;
374-
}
375-
}
376-
377354
if(ngx_http_upload_add_filter(ulcf, &ngx_http_unzip_content_filter, cf->pool) != NGX_OK) {
378355
return NGX_CONF_ERROR;
379356
}
@@ -385,7 +362,7 @@ static ngx_int_t /* {{{ ngx_http_unzip_process_chain */
385362
ngx_http_unzip_process_chain(ngx_unzip_ctx_t *ctx, ngx_chain_t *chain) {
386363
ngx_int_t result;
387364
ngx_buf_t *buf;
388-
ngx_unzip_conf_t *uzcf;
365+
ngx_unzip_loc_conf_t *uzcf;
389366

390367
uzcf = ngx_http_get_module_loc_conf(ctx->upload_ctx->request, ngx_upload_unzip_filter_module);
391368

@@ -855,7 +832,7 @@ ngx_http_unzip_process_chain(ngx_unzip_ctx_t *ctx, ngx_chain_t *chain) {
855832

856833
static ngx_int_t /* {{{ ngx_http_unzip_start_handler */
857834
ngx_http_unzip_start_handler(ngx_http_upload_ctx_t *u) {
858-
ngx_unzip_conf_t *uzcf;
835+
ngx_unzip_loc_conf_t *uzcf;
859836
ngx_unzip_ctx_t *ctx, *parent;
860837
ngx_http_upload_loc_conf_t *ulcf;
861838

@@ -954,16 +931,16 @@ ngx_http_unzip_data_handler(ngx_http_upload_ctx_t *u, ngx_chain_t *chain) {
954931
static void * /* {{{ ngx_upload_unzip_create_loc_conf */
955932
ngx_upload_unzip_create_loc_conf(ngx_conf_t *cf)
956933
{
957-
ngx_unzip_conf_t *conf;
934+
ngx_unzip_loc_conf_t *conf;
958935

959-
conf = ngx_pcalloc(cf->pool, sizeof(ngx_unzip_conf_t));
936+
conf = ngx_pcalloc(cf->pool, sizeof(ngx_unzip_loc_conf_t));
960937
if (conf == NULL) {
961938
return NGX_CONF_ERROR;
962939
}
963940

964-
conf->wbits = 15;
965-
conf->bufs.num = 4;
966-
conf->bufs.size = ngx_pagesize;
941+
conf->wbits = NGX_CONF_UNSET_SIZE;
942+
conf->memlevel = NGX_CONF_UNSET_SIZE;
943+
conf->max_file_name_len = NGX_CONF_UNSET_SIZE;
967944

968945
/*
969946
* conf->bufs
@@ -973,6 +950,25 @@ ngx_upload_unzip_create_loc_conf(ngx_conf_t *cf)
973950
return conf;
974951
} /* }}} */
975952

953+
static char * /* {{{ ngx_upload_unzip_merge_loc_conf */
954+
ngx_upload_unzip_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
955+
{
956+
ngx_unzip_loc_conf_t *prev = parent;
957+
ngx_unzip_loc_conf_t *conf = child;
958+
959+
ngx_conf_merge_bufs_value(conf->bufs, prev->bufs, 4, ngx_pagesize);
960+
961+
ngx_conf_merge_size_value(conf->wbits, prev->wbits, MAX_WBITS);
962+
ngx_conf_merge_size_value(conf->memlevel, prev->memlevel,
963+
MAX_MEM_LEVEL - 1);
964+
965+
ngx_conf_merge_size_value(conf->max_file_name_len,
966+
prev->max_file_name_len,
967+
(size_t) 256);
968+
969+
return NGX_CONF_OK;
970+
} /* }}} */
971+
976972
static char * /* {{{ ngx_http_unzip_window */
977973
ngx_http_unzip_window(ngx_conf_t *cf, void *post, void *data)
978974
{
@@ -996,6 +992,29 @@ ngx_http_unzip_window(ngx_conf_t *cf, void *post, void *data)
996992
return "must be 512, 1k, 2k, 4k, 8k, 16k, or 32k";
997993
} /* }}} */
998994

995+
static char * /* {{{ ngx_http_unzip_hash */
996+
ngx_http_unzip_hash(ngx_conf_t *cf, void *post, void *data)
997+
{
998+
int *np = data;
999+
1000+
int memlevel, hsize;
1001+
1002+
memlevel = 9;
1003+
1004+
for (hsize = 128 * 1024; hsize > 256; hsize >>= 1) {
1005+
1006+
if (hsize == *np) {
1007+
*np = memlevel;
1008+
1009+
return NGX_CONF_OK;
1010+
}
1011+
1012+
memlevel--;
1013+
}
1014+
1015+
return "must be 512, 1k, 2k, 4k, 8k, 16k, 32k, 64k, or 128k";
1016+
} /* }}} */
1017+
9991018
static ngx_int_t /* {{{ ngx_http_unzip_set_decompression_method */
10001019
ngx_http_unzip_set_decompression_method(ngx_unzip_ctx_t *ctx, uint16_t compression_method)
10011020
{
@@ -1019,8 +1038,8 @@ ngx_http_unzip_set_decompression_method(ngx_unzip_ctx_t *ctx, uint16_t compressi
10191038
static ngx_int_t /* {{{ ngx_http_unzip_inflate_start */
10201039
ngx_http_unzip_inflate_start(ngx_unzip_ctx_t *ctx) {
10211040
ngx_int_t rc;
1022-
ngx_unzip_conf_t *uzcf;
1023-
unsigned int wbits, memlevel;
1041+
ngx_unzip_loc_conf_t *uzcf;
1042+
int wbits, memlevel;
10241043

10251044
ctx->stream.zalloc = ngx_http_unzip_filter_alloc;
10261045
ctx->stream.zfree = ngx_http_unzip_filter_free;
@@ -1057,7 +1076,7 @@ ngx_http_unzip_inflate_start(ngx_unzip_ctx_t *ctx) {
10571076

10581077
/* the actual zlib window size is smaller by 262 bytes */
10591078

1060-
while (ctx->local_data_header.uncompressed_size < ((1 << (wbits - 1)) - 262)) {
1079+
while ((off_t)ctx->local_data_header.uncompressed_size < ((1 << (wbits - 1)) - 262)) {
10611080
wbits--;
10621081
memlevel--;
10631082
}

0 commit comments

Comments
 (0)