Skip to content

Commit 1059c24

Browse files
committed
Added support for archive element paths
1 parent aaa500a commit 1059c24

6 files changed

+313
-83
lines changed

config

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
USE_MD5=YES
22
USE_SHA1=YES
33
ngx_addon_name=ngx_http_upload_module
4-
HTTP_MODULES="$HTTP_MODULES ngx_http_upload_module ngx_http_unzip_filter_module"
5-
NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_upload_module.c $ngx_addon_dir/ngx_http_unzip_filter_module.c"
4+
HTTP_MODULES="$HTTP_MODULES ngx_http_upload_module ngx_http_unzip_filter_module ngx_upload_discard_filter_module"
5+
NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_upload_module.c $ngx_addon_dir/ngx_http_unzip_filter_module.c $ngx_addon_dir/ngx_upload_discard_filter_module.c"
66
HTTP_INCS="$HTTP_INCS $ngx_addon_dir"

nginx.conf

+4
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ http {
3939
upload_aggregate_form_field "${upload_field_name}_size" $upload_file_size;
4040

4141
upload_pass_form_field "^submit$|^description$";
42+
43+
upload_filter "application/zip" {
44+
unzip on;
45+
}
4246
}
4347

4448
# Pass altered request body to a backend

ngx_http_unzip_filter_module.c

+97-24
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2006, 2008 Valery Kholodkov
2+
* Copyright (C) 2008 Valery Kholodkov
33
*/
44
#include <ngx_config.h>
55
#include <ngx_core.h>
@@ -169,8 +169,13 @@ typedef struct ngx_unzip_ctx_s {
169169
ngx_unzip_extra_data_record_t extra_data_record;
170170
};
171171

172+
ngx_str_t archive_name;
172173
ngx_str_t file_name;
173174

175+
ngx_str_t prev_elm, current_elm;
176+
ngx_str_t prev_archive_path, current_archive_path;
177+
ngx_int_t entry_no;
178+
174179
void *preallocated;
175180
char *free_mem;
176181
ngx_uint_t allocated;
@@ -260,7 +265,7 @@ static ngx_command_t ngx_http_unzip_filter_commands[] = { /* {{{ */
260265
/*
261266
* Enables unzipping of uploaded file
262267
*/
263-
{ ngx_string("unzip"),
268+
{ ngx_string("upload_unzip"),
264269
NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
265270
ngx_http_unzip_command,
266271
NGX_HTTP_LOC_CONF_OFFSET,
@@ -270,7 +275,7 @@ static ngx_command_t ngx_http_unzip_filter_commands[] = { /* {{{ */
270275
/*
271276
* Specifies size and number of buffers to use for decompressing
272277
*/
273-
{ ngx_string("unzip_buffers"),
278+
{ ngx_string("upload_unzip_buffers"),
274279
NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
275280
ngx_conf_set_bufs_slot,
276281
NGX_HTTP_LOC_CONF_OFFSET,
@@ -280,7 +285,7 @@ static ngx_command_t ngx_http_unzip_filter_commands[] = { /* {{{ */
280285
/*
281286
* Specifies size window to use for decompressing
282287
*/
283-
{ ngx_string("unzip_window"),
288+
{ ngx_string("upload_unzip_window"),
284289
NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
285290
ngx_conf_set_size_slot,
286291
NGX_HTTP_LOC_CONF_OFFSET,
@@ -291,7 +296,7 @@ static ngx_command_t ngx_http_unzip_filter_commands[] = { /* {{{ */
291296
* Specifies a form field with a special content to generate
292297
* in output form
293298
*/
294-
{ ngx_string("unzip_set_form_field"),
299+
{ ngx_string("upload_unzip_set_form_field"),
295300
NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
296301
ngx_conf_set_size_slot,
297302
NGX_HTTP_LOC_CONF_OFFSET,
@@ -302,7 +307,7 @@ static ngx_command_t ngx_http_unzip_filter_commands[] = { /* {{{ */
302307
* Specifies a form field with a special aggregate content to generate
303308
* in output form
304309
*/
305-
{ ngx_string("unzip_aggregate_form_field"),
310+
{ ngx_string("upload_unzip_aggregate_form_field"),
306311
NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
307312
ngx_conf_set_size_slot,
308313
NGX_HTTP_LOC_CONF_OFFSET,
@@ -312,7 +317,7 @@ static ngx_command_t ngx_http_unzip_filter_commands[] = { /* {{{ */
312317
/*
313318
* Specifies the maximal length of a file name in archive
314319
*/
315-
{ ngx_string("unzip_max_file_name_len"),
320+
{ ngx_string("upload_unzip_max_file_name_len"),
316321
NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
317322
ngx_conf_set_size_slot,
318323
NGX_HTTP_LOC_CONF_OFFSET,
@@ -852,8 +857,10 @@ static ngx_int_t /* {{{ ngx_http_unzip_start_handler */
852857
ngx_http_unzip_start_handler(ngx_http_upload_ctx_t *u) {
853858
ngx_unzip_conf_t *uzcf;
854859
ngx_unzip_ctx_t *ctx, *parent;
860+
ngx_http_upload_loc_conf_t *ulcf;
855861

856862
uzcf = ngx_http_get_module_loc_conf(u->request, ngx_http_unzip_filter_module);
863+
ulcf = ngx_http_get_module_loc_conf(u->request, ngx_http_upload_module);
857864

858865
ctx = ngx_http_get_module_ctx(u->request, ngx_http_unzip_filter_module);
859866

@@ -875,12 +882,27 @@ ngx_http_unzip_start_handler(ngx_http_upload_ctx_t *u) {
875882

876883
ctx->state = unzip_state_signature;
877884
ctx->upload_ctx = u;
878-
ctx->next_field_filter = ngx_upload_get_next_field_filter(u);
879-
ctx->next_content_filter = ngx_upload_get_next_content_filter(u);
880885

881886
ctx->pool = u->request->pool;
882887
ctx->log = u->log;
883888

889+
ctx->next_field_filter = ngx_upload_get_next_field_filter(u);
890+
ctx->next_content_filter = ngx_upload_get_next_content_filter(u);
891+
892+
ngx_upload_get_archive_elm(u, &ctx->prev_elm);
893+
894+
ngx_upload_get_archive_path(u, &ctx->prev_archive_path);
895+
896+
ngx_upload_get_file_name(u, &ctx->archive_name);
897+
898+
ctx->entry_no = 0;
899+
900+
ctx->current_elm.len = ctx->prev_elm.len + ulcf->archive_elm_separator.len + NGX_OFF_T_LEN;
901+
ctx->current_elm.data = ngx_palloc(ctx->pool, ctx->current_elm.len);
902+
903+
if(ctx->current_elm.data == NULL)
904+
return NGX_UPLOAD_NOMEM;
905+
884906
return NGX_OK;
885907
} /* }}} */
886908

@@ -895,6 +917,10 @@ ngx_http_unzip_finish_handler(ngx_http_upload_ctx_t *u) {
895917
ctx->decompression_method->abort(ctx);
896918
}
897919

920+
ngx_upload_set_archive_elm(u, &ctx->prev_elm);
921+
922+
ngx_upload_set_archive_path(u, &ctx->prev_archive_path);
923+
898924
ngx_http_set_ctx(u->request, ctx->parent, ngx_http_unzip_filter_module);
899925
} /* }}} */
900926

@@ -909,6 +935,10 @@ ngx_http_unzip_abort_handler(ngx_http_upload_ctx_t *u) {
909935
ctx->decompression_method->abort(ctx);
910936
}
911937

938+
ngx_upload_set_archive_elm(u, &ctx->prev_elm);
939+
940+
ngx_upload_set_archive_path(u, &ctx->prev_archive_path);
941+
912942
ngx_http_set_ctx(u->request, ctx->parent, ngx_http_unzip_filter_module);
913943
} /* }}} */
914944

@@ -1118,22 +1148,40 @@ static ngx_int_t /* {{{ ngx_http_unzip_inflate_process_chain */
11181148
ngx_http_unzip_inflate_process_chain(ngx_unzip_ctx_t *ctx, ngx_chain_t *chain) {
11191149
int rc;
11201150
size_t remaining;
1151+
int flush;
11211152

11221153
while(chain != NULL && !chain->buf->last_in_chain) {
11231154
remaining = chain->buf->last - chain->buf->pos;
11241155

1125-
if(ctx->current_field_len - ctx->current_field_pos > remaining)
1156+
if(ctx->current_field_len - ctx->current_field_pos > remaining) {
11261157
ctx->stream.avail_in = remaining;
1127-
else
1158+
flush = Z_NO_FLUSH;
1159+
}else{
11281160
ctx->stream.avail_in = ctx->current_field_len - ctx->current_field_pos;
1161+
flush = Z_SYNC_FLUSH;
1162+
}
11291163

11301164
ctx->stream.next_in = chain->buf->pos;
11311165

11321166
do{
11331167
ctx->stream.avail_out = ctx->output_buffer->end - ctx->output_buffer->start;
11341168
ctx->stream.next_out = ctx->output_buffer->pos = ctx->output_buffer->start;
11351169

1136-
rc = inflate(&ctx->stream, Z_NO_FLUSH);
1170+
ngx_log_debug5(NGX_LOG_DEBUG_HTTP, ctx->log, 0,
1171+
"inflate in: ai:%ud ni:%p ao:%ud no:%p fl:%d",
1172+
ctx->stream.avail_in, ctx->stream.next_in,
1173+
ctx->stream.avail_out, ctx->stream.next_out,
1174+
flush
1175+
);
1176+
1177+
rc = inflate(&ctx->stream, flush);
1178+
1179+
ngx_log_debug5(NGX_LOG_DEBUG_HTTP, ctx->log, 0,
1180+
"inflate out: ai:%ud ni:%p ao:%ud no:%p rc:%d",
1181+
ctx->stream.avail_in, ctx->stream.next_in,
1182+
ctx->stream.avail_out, ctx->stream.next_out,
1183+
rc
1184+
);
11371185

11381186
if(rc == Z_OK || rc == Z_STREAM_END) {
11391187
ctx->output_buffer->last = ctx->stream.next_out;
@@ -1155,7 +1203,7 @@ ngx_http_unzip_inflate_process_chain(ngx_unzip_ctx_t *ctx, ngx_chain_t *chain) {
11551203
"inflate() failed: %d", rc);
11561204
return NGX_ERROR;
11571205
}
1158-
}while(ctx->stream.avail_out == 0 && rc == Z_OK);
1206+
}while(ctx->stream.avail_out == 0 && ctx->stream.avail_in > 0 && rc == Z_OK);
11591207

11601208
ctx->current_field_pos += (ctx->stream.next_in - chain->buf->pos);
11611209

@@ -1229,6 +1277,37 @@ ngx_http_unzip_extract_process_chain(ngx_unzip_ctx_t *ctx, ngx_chain_t *chain) {
12291277
return NGX_OK;
12301278
} /* }}} */
12311279

1280+
static void /* {{{ ngx_http_unzip_set_archive_elm */
1281+
ngx_http_unzip_set_archive_elm(ngx_unzip_ctx_t *ctx, off_t elm_id) {
1282+
ngx_http_upload_loc_conf_t *ulcf;
1283+
1284+
ulcf = ngx_http_get_module_loc_conf(ctx->upload_ctx->request, ngx_http_upload_module);
1285+
1286+
ctx->current_elm.len = ngx_sprintf(ctx->current_elm.data, "%V%V%O", &ctx->prev_elm, &ulcf->archive_elm_separator, elm_id) - ctx->current_elm.data;
1287+
1288+
ngx_upload_set_archive_elm(ctx->upload_ctx, &ctx->current_elm);
1289+
} /* }}} */
1290+
1291+
static ngx_int_t /* {{{ ngx_http_unzip_set_archive_path */
1292+
ngx_http_unzip_set_archive_path(ngx_unzip_ctx_t *ctx, ngx_str_t *file_name, ngx_str_t *path) {
1293+
ngx_http_upload_loc_conf_t *ulcf;
1294+
1295+
ulcf = ngx_http_get_module_loc_conf(ctx->upload_ctx->request, ngx_http_upload_module);
1296+
1297+
ctx->current_archive_path.len = ctx->prev_archive_path.len + file_name->len + ulcf->archive_path_separator.len + path->len;
1298+
1299+
ctx->current_archive_path.data = ngx_palloc(ctx->pool, ctx->current_archive_path.len);
1300+
1301+
if(ctx->current_archive_path.data == NULL)
1302+
return NGX_UPLOAD_NOMEM;
1303+
1304+
ctx->current_archive_path.len = ngx_sprintf(ctx->current_archive_path.data, "%V%V%V%V", &ctx->prev_archive_path, file_name, &ulcf->archive_path_separator, path) - ctx->current_archive_path.data;
1305+
1306+
ngx_upload_set_archive_path(ctx->upload_ctx, &ctx->current_archive_path);
1307+
1308+
return NGX_OK;
1309+
} /* }}} */
1310+
12321311
static ngx_int_t /* {{{ ngx_http_unzip_parse_file_name */
12331312
ngx_http_unzip_parse_file_name(ngx_unzip_ctx_t *ctx, ngx_str_t *file_name) {
12341313
u_char *p;
@@ -1251,11 +1330,7 @@ ngx_http_unzip_parse_file_name(ngx_unzip_ctx_t *ctx, ngx_str_t *file_name) {
12511330
archive_path.len = 0;
12521331

12531332
set:
1254-
rc = ngx_upload_set_file_name(ctx->upload_ctx, &element_name);
1255-
1256-
if(rc != NGX_OK) {
1257-
return rc;
1258-
}
1333+
ngx_upload_set_file_name(ctx->upload_ctx, &element_name);
12591334

12601335
rc = ngx_upload_set_exten(ctx->upload_ctx, &element_name, &exten);
12611336

@@ -1269,18 +1344,16 @@ ngx_http_unzip_parse_file_name(ngx_unzip_ctx_t *ctx, ngx_str_t *file_name) {
12691344
return rc;
12701345
}
12711346

1272-
rc = ngx_upload_set_content_type(ctx->upload_ctx, &content_type);
1347+
ngx_upload_set_content_type(ctx->upload_ctx, &content_type);
12731348

1274-
if(rc != NGX_OK) {
1275-
return rc;
1276-
}
1277-
1278-
rc = ngx_upload_set_archive_path(ctx->upload_ctx, &archive_path);
1349+
rc = ngx_http_unzip_set_archive_path(ctx, &ctx->archive_name, &archive_path);
12791350

12801351
if(rc != NGX_OK) {
12811352
return rc;
12821353
}
12831354

1355+
ngx_http_unzip_set_archive_elm(ctx, ctx->entry_no++);
1356+
12841357
return NGX_OK;
12851358
} /* }}} */
12861359

ngx_http_upload.h

+52-3
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,9 @@ typedef struct ngx_http_upload_loc_conf_s {
128128
ngx_array_t *content_filters;
129129
ngx_array_t *content_type_map;
130130

131+
ngx_str_t archive_elm_separator;
132+
ngx_str_t archive_path_separator;
133+
131134
unsigned int md5:1;
132135
unsigned int sha1:1;
133136
unsigned int crc32:1;
@@ -160,6 +163,7 @@ typedef struct ngx_http_upload_ctx_s {
160163
ngx_str_t field_name;
161164
ngx_str_t file_name;
162165
ngx_str_t content_type;
166+
ngx_str_t archive_elm;
163167
ngx_str_t archive_path;
164168

165169
ngx_buf_t *output_buffer;
@@ -197,9 +201,54 @@ ngx_module_t ngx_http_upload_module;
197201

198202
ngx_int_t ngx_upload_set_exten(ngx_http_upload_ctx_t *u, ngx_str_t *file_name, ngx_str_t *exten);
199203
ngx_int_t ngx_upload_resolve_content_type(ngx_http_upload_ctx_t *u, ngx_str_t *exten, ngx_str_t *content_type);
200-
ngx_int_t ngx_upload_set_file_name(ngx_http_upload_ctx_t *ctx, ngx_str_t *file_name);
201-
ngx_int_t ngx_upload_set_content_type(ngx_http_upload_ctx_t *ctx, ngx_str_t *content_type);
202-
ngx_int_t ngx_upload_set_archive_path(ngx_http_upload_ctx_t *ctx, ngx_str_t *archive_path);
204+
205+
#define ngx_upload_set_file_name(ctx, fn) \
206+
do{ \
207+
(ctx)->file_name.data = (fn)->data; \
208+
(ctx)->file_name.len = (fn)->len; \
209+
}while(0); \
210+
211+
#define ngx_upload_get_file_name(ctx, fn) \
212+
do{ \
213+
(fn)->data = (ctx)->file_name.data; \
214+
(fn)->len = (ctx)->file_name.len; \
215+
}while(0); \
216+
217+
#define ngx_upload_set_content_type(ctx, ct) \
218+
do{ \
219+
(ctx)->content_type.data = (ct)->data; \
220+
(ctx)->content_type.len = (ct)->len; \
221+
}while(0); \
222+
223+
#define ngx_upload_get_content_type(ctx, ct) \
224+
do{ \
225+
(ct)->data = (ctx)->content_type.data; \
226+
(ct)->len = (ctx)->content_type.len; \
227+
}while(0); \
228+
229+
#define ngx_upload_set_archive_elm(ctx, ae) \
230+
do{ \
231+
(ctx)->archive_elm.data = (ae)->data; \
232+
(ctx)->archive_elm.len = (ae)->len; \
233+
}while(0); \
234+
235+
#define ngx_upload_get_archive_elm(ctx, ae) \
236+
do{ \
237+
(ae)->data = (ctx)->archive_elm.data; \
238+
(ae)->len = (ctx)->archive_elm.len; \
239+
}while(0); \
240+
241+
#define ngx_upload_set_archive_path(ctx, ap) \
242+
do{ \
243+
(ctx)->archive_path.data = (ap)->data; \
244+
(ctx)->archive_path.len = (ap)->len; \
245+
}while(0); \
246+
247+
#define ngx_upload_get_archive_path(ctx, ap) \
248+
do{ \
249+
(ap)->data = (ctx)->archive_path.data; \
250+
(ap)->len = (ctx)->archive_path.len; \
251+
}while(0); \
203252

204253
ngx_upload_field_filter_t*
205254
ngx_upload_get_next_field_filter(ngx_http_upload_ctx_t *ctx);

0 commit comments

Comments
 (0)