Skip to content

Commit f12d506

Browse files
committed
Merge branch '2.2-merge' into 2.2
2 parents cd4c631 + 4a9d8b5 commit f12d506

File tree

1 file changed

+241
-30
lines changed

1 file changed

+241
-30
lines changed

ngx_http_upload_module.c

Lines changed: 241 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,12 @@ typedef struct {
114114
#endif
115115
} ngx_http_upload_field_filter_t;
116116

117+
typedef struct {
118+
ngx_path_t *path;
119+
ngx_http_complex_value_t dynamic;
120+
unsigned is_dynamic:1;
121+
} ngx_http_upload_path_t;
122+
117123
/*
118124
* Upload cleanup record
119125
*/
@@ -132,8 +138,8 @@ typedef struct ngx_http_upload_cleanup_s {
132138
typedef struct {
133139
ngx_str_t url;
134140
ngx_http_complex_value_t *url_cv;
135-
ngx_path_t *state_store_path;
136-
ngx_path_t *store_path;
141+
ngx_http_upload_path_t *state_store_path;
142+
ngx_http_upload_path_t *store_path;
137143
ngx_uint_t store_access;
138144
size_t buffer_size;
139145
size_t merge_buffer_size;
@@ -245,6 +251,8 @@ typedef struct ngx_http_upload_ctx_s {
245251
ngx_http_upload_sha256_ctx_t *sha256_ctx;
246252
ngx_http_upload_sha512_ctx_t *sha512_ctx;
247253
uint32_t crc32;
254+
ngx_path_t *store_path;
255+
ngx_path_t *state_store_path;
248256

249257
unsigned int first_part:1;
250258
unsigned int discard_data:1;
@@ -313,8 +321,14 @@ static char *ngx_http_upload_set_form_field(ngx_conf_t *cf, ngx_command_t *cmd,
313321
void *conf);
314322
static char *ngx_http_upload_add_header(ngx_conf_t *cf, ngx_command_t *cmd,
315323
void *conf);
324+
static ngx_int_t ngx_http_upload_eval_path(ngx_http_request_t *r);
325+
static ngx_int_t ngx_http_upload_eval_state_path(ngx_http_request_t *r);
316326
static char *ngx_http_upload_pass_form_field(ngx_conf_t *cf, ngx_command_t *cmd,
317327
void *conf);
328+
static char *ngx_http_upload_set_path_slot(ngx_conf_t *cf, ngx_command_t *cmd,
329+
void *conf);
330+
static char *ngx_http_upload_merge_path_value(ngx_conf_t *cf, ngx_http_upload_path_t **path, ngx_http_upload_path_t *prev,
331+
ngx_path_init_t *init);
318332
static char *ngx_http_upload_cleanup(ngx_conf_t *cf, ngx_command_t *cmd,
319333
void *conf);
320334
static void ngx_upload_cleanup_handler(void *data);
@@ -425,7 +439,7 @@ static ngx_command_t ngx_http_upload_commands[] = { /* {{{ */
425439
{ ngx_string("upload_store"),
426440
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF|NGX_HTTP_LIF_CONF
427441
|NGX_CONF_TAKE1234,
428-
ngx_conf_set_path_slot,
442+
ngx_http_upload_set_path_slot,
429443
NGX_HTTP_LOC_CONF_OFFSET,
430444
offsetof(ngx_http_upload_loc_conf_t, store_path),
431445
NULL },
@@ -435,7 +449,7 @@ static ngx_command_t ngx_http_upload_commands[] = { /* {{{ */
435449
*/
436450
{ ngx_string("upload_state_store"),
437451
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234,
438-
ngx_conf_set_path_slot,
452+
ngx_http_upload_set_path_slot,
439453
NGX_HTTP_LOC_CONF_OFFSET,
440454
offsetof(ngx_http_upload_loc_conf_t, state_store_path),
441455
NULL },
@@ -841,6 +855,20 @@ ngx_http_upload_handler(ngx_http_request_t *r)
841855
return rc;
842856
}
843857

858+
rc = ngx_http_upload_eval_path(r);
859+
860+
if(rc != NGX_OK) {
861+
upload_shutdown_ctx(u);
862+
return rc;
863+
}
864+
865+
rc = ngx_http_upload_eval_state_path(r);
866+
867+
if(rc != NGX_OK) {
868+
upload_shutdown_ctx(u);
869+
return rc;
870+
}
871+
844872
if (ngx_http_upload_test_expect(r) != NGX_OK) {
845873
upload_shutdown_ctx(u);
846874
return NGX_HTTP_INTERNAL_SERVER_ERROR;
@@ -896,6 +924,68 @@ static ngx_int_t ngx_http_upload_add_headers(ngx_http_request_t *r, ngx_http_upl
896924
return NGX_OK;
897925
} /* }}} */
898926

927+
static ngx_int_t /* {{{ */
928+
ngx_http_upload_eval_path(ngx_http_request_t *r) {
929+
ngx_http_upload_ctx_t *u;
930+
ngx_http_upload_loc_conf_t *ulcf;
931+
ngx_str_t value;
932+
933+
ulcf = ngx_http_get_module_loc_conf(r, ngx_http_upload_module);
934+
u = ngx_http_get_module_ctx(r, ngx_http_upload_module);
935+
936+
if(ulcf->store_path->is_dynamic) {
937+
u->store_path = ngx_pcalloc(r->pool, sizeof(ngx_path_t));
938+
if(u->store_path == NULL) {
939+
return NGX_ERROR;
940+
}
941+
942+
ngx_memcpy(u->store_path, ulcf->store_path->path, sizeof(ngx_path_t));
943+
944+
if(ngx_http_complex_value(r, &ulcf->store_path->dynamic, &value) != NGX_OK) {
945+
return NGX_ERROR;
946+
}
947+
948+
u->store_path->name.data = value.data;
949+
u->store_path->name.len = value.len;
950+
}
951+
else{
952+
u->store_path = ulcf->store_path->path;
953+
}
954+
955+
return NGX_OK;
956+
} /* }}} */
957+
958+
static ngx_int_t /* {{{ */
959+
ngx_http_upload_eval_state_path(ngx_http_request_t *r) {
960+
ngx_http_upload_ctx_t *u;
961+
ngx_http_upload_loc_conf_t *ulcf;
962+
ngx_str_t value;
963+
964+
ulcf = ngx_http_get_module_loc_conf(r, ngx_http_upload_module);
965+
u = ngx_http_get_module_ctx(r, ngx_http_upload_module);
966+
967+
if(ulcf->state_store_path->is_dynamic) {
968+
u->state_store_path = ngx_pcalloc(r->pool, sizeof(ngx_path_t));
969+
if(u->store_path == NULL) {
970+
return NGX_ERROR;
971+
}
972+
973+
ngx_memcpy(u->state_store_path, ulcf->state_store_path->path, sizeof(ngx_path_t));
974+
975+
if(ngx_http_complex_value(r, &ulcf->state_store_path->dynamic, &value) != NGX_OK) {
976+
return NGX_ERROR;
977+
}
978+
979+
u->state_store_path->name.data = value.data;
980+
u->state_store_path->name.len = value.len;
981+
}
982+
else{
983+
u->state_store_path = ulcf->state_store_path->path;
984+
}
985+
986+
return NGX_OK;
987+
} /* }}} */
988+
899989
static ngx_int_t ngx_http_upload_options_handler(ngx_http_request_t *r) { /* {{{ */
900990
ngx_http_upload_loc_conf_t *ulcf;
901991

@@ -1112,7 +1202,8 @@ static ngx_int_t ngx_http_upload_start_handler(ngx_http_upload_ctx_t *u) { /* {{
11121202
ngx_http_upload_loc_conf_t *ulcf = ngx_http_get_module_loc_conf(r, ngx_http_upload_module);
11131203

11141204
ngx_file_t *file = &u->output_file;
1115-
ngx_path_t *path = ulcf->store_path;
1205+
ngx_path_t *path = u->store_path;
1206+
ngx_path_t *state_path = u->state_store_path;
11161207
uint32_t n;
11171208
ngx_uint_t i;
11181209
ngx_int_t rc;
@@ -1152,28 +1243,28 @@ static ngx_int_t ngx_http_upload_start_handler(ngx_http_upload_ctx_t *u) { /* {{
11521243
"hashed path: %s", file->name.data);
11531244

11541245
if(u->partial_content) {
1246+
ngx_file_t *state_file = &u->state_file;
11551247
if(u->merge_buffer == NULL) {
11561248
u->merge_buffer = ngx_palloc(r->pool, ulcf->merge_buffer_size);
11571249

11581250
if(u->merge_buffer == NULL)
11591251
return NGX_UPLOAD_NOMEM;
11601252
}
11611253

1162-
u->state_file.name.len = file->name.len + sizeof(".state") - 1;
1163-
u->state_file.name.data = ngx_palloc(u->request->pool, u->state_file.name.len + 1);
1254+
state_file->name.len = state_path->name.len + 1 + state_path->len + u->session_id.len + sizeof(".state");
1255+
state_file->name.data = ngx_palloc(u->request->pool, state_file->name.len + 1);
11641256

1165-
if(u->state_file.name.data == NULL)
1257+
if(state_file->name.data == NULL)
11661258
return NGX_UPLOAD_NOMEM;
11671259

1168-
ngx_memcpy(u->state_file.name.data, file->name.data, file->name.len);
1260+
ngx_memcpy(state_file->name.data, state_path->name.data, state_path->name.len);
1261+
(void) ngx_sprintf(state_file->name.data + state_path->name.len + 1 + state_path->len,
1262+
"%V.state%Z", &u->session_id);
11691263

1170-
/*
1171-
* NOTE: we add terminating zero for system calls
1172-
*/
1173-
ngx_memcpy(u->state_file.name.data + file->name.len, ".state", sizeof(".state") - 1 + 1);
1264+
ngx_create_hashed_filename(state_path, state_file->name.data, state_file->name.len);
11741265

11751266
ngx_log_debug1(NGX_LOG_DEBUG_CORE, file->log, 0,
1176-
"hashed path of state file: %s", u->state_file.name.data);
1267+
"hashed path of state file: %s", state_file->name.data);
11771268
}
11781269

11791270
file->fd = ngx_open_file(file->name.data, NGX_FILE_WRONLY, NGX_FILE_CREATE_OR_OPEN, ulcf->store_access);
@@ -2013,27 +2104,15 @@ ngx_http_upload_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
20132104
}
20142105

20152106
if(conf->url.len != 0) {
2016-
#if defined nginx_version && nginx_version >= 7052
2017-
ngx_conf_merge_path_value(cf,
2107+
ngx_http_upload_merge_path_value(cf,
20182108
&conf->store_path,
20192109
prev->store_path,
20202110
&ngx_http_upload_temp_path);
20212111

2022-
ngx_conf_merge_path_value(cf,
2112+
ngx_http_upload_merge_path_value(cf,
20232113
&conf->state_store_path,
20242114
prev->state_store_path,
20252115
&ngx_http_upload_temp_path);
2026-
#else
2027-
ngx_conf_merge_path_value(conf->store_path,
2028-
prev->store_path,
2029-
NGX_HTTP_PROXY_TEMP_PATH, 1, 2, 0,
2030-
ngx_garbage_collector_temp_handler, cf);
2031-
2032-
ngx_conf_merge_path_value(conf->state_store_path,
2033-
prev->state_store_path,
2034-
NGX_HTTP_PROXY_TEMP_PATH, 1, 2, 0,
2035-
ngx_garbage_collector_temp_handler, cf);
2036-
#endif
20372116
}
20382117

20392118
ngx_conf_merge_uint_value(conf->store_access,
@@ -2874,6 +2953,138 @@ ngx_http_upload_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
28742953
return NGX_CONF_OK;
28752954
} /* }}} */
28762955

2956+
static char * /* {{{ ngx_http_upload_set_path_slot */
2957+
ngx_http_upload_set_path_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2958+
{
2959+
char *p = conf;
2960+
2961+
ssize_t level;
2962+
ngx_str_t *value;
2963+
ngx_uint_t i, n;
2964+
ngx_http_upload_path_t *path, **slot;
2965+
ngx_http_compile_complex_value_t ccv;
2966+
2967+
slot = (ngx_http_upload_path_t **) (p + cmd->offset);
2968+
2969+
if (*slot) {
2970+
return "is duplicate";
2971+
}
2972+
2973+
path = ngx_pcalloc(cf->pool, sizeof(ngx_http_upload_path_t));
2974+
if (path == NULL) {
2975+
return NGX_CONF_ERROR;
2976+
}
2977+
2978+
path->path = ngx_pcalloc(cf->pool, sizeof(ngx_path_t));
2979+
if (path->path == NULL) {
2980+
return NGX_CONF_ERROR;
2981+
}
2982+
2983+
value = cf->args->elts;
2984+
2985+
path->path->name = value[1];
2986+
2987+
if (path->path->name.data[path->path->name.len - 1] == '/') {
2988+
path->path->name.len--;
2989+
}
2990+
2991+
if (ngx_conf_full_name(cf->cycle, &path->path->name, 0) != NGX_OK) {
2992+
return NULL;
2993+
}
2994+
2995+
path->path->len = 0;
2996+
path->path->manager = NULL;
2997+
path->path->loader = NULL;
2998+
path->path->conf_file = cf->conf_file->file.name.data;
2999+
path->path->line = cf->conf_file->line;
3000+
3001+
for (i = 0, n = 2; n < cf->args->nelts; i++, n++) {
3002+
level = ngx_atoi(value[n].data, value[n].len);
3003+
if (level == NGX_ERROR || level == 0) {
3004+
return "invalid value";
3005+
}
3006+
3007+
path->path->level[i] = level;
3008+
path->path->len += level + 1;
3009+
}
3010+
3011+
while (i < 3) {
3012+
path->path->level[i++] = 0;
3013+
}
3014+
3015+
*slot = path;
3016+
3017+
if(ngx_http_script_variables_count(&value[1])) {
3018+
ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
3019+
3020+
ccv.cf = cf;
3021+
ccv.value = &value[1];
3022+
ccv.complex_value = &path->dynamic;
3023+
3024+
if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
3025+
return NGX_CONF_ERROR;
3026+
}
3027+
3028+
path->is_dynamic = 1;
3029+
}
3030+
else {
3031+
if (ngx_add_path(cf, &path->path) == NGX_ERROR) {
3032+
return NGX_CONF_ERROR;
3033+
}
3034+
}
3035+
3036+
return NGX_CONF_OK;
3037+
} /* }}} */
3038+
3039+
3040+
static char * /* {{{ ngx_http_upload_merge_path_value */
3041+
ngx_http_upload_merge_path_value(ngx_conf_t *cf, ngx_http_upload_path_t **path, ngx_http_upload_path_t *prev,
3042+
ngx_path_init_t *init)
3043+
{
3044+
if (*path) {
3045+
return NGX_CONF_OK;
3046+
}
3047+
3048+
if (prev) {
3049+
*path = prev;
3050+
return NGX_CONF_OK;
3051+
}
3052+
3053+
*path = ngx_palloc(cf->pool, sizeof(ngx_http_upload_path_t));
3054+
if(*path == NULL) {
3055+
return NGX_CONF_ERROR;
3056+
}
3057+
3058+
(*path)->path = ngx_pcalloc(cf->pool, sizeof(ngx_path_t));
3059+
if((*path)->path == NULL) {
3060+
return NGX_CONF_ERROR;
3061+
}
3062+
3063+
(*path)->path->name = init->name;
3064+
3065+
if(ngx_conf_full_name(cf->cycle, &(*path)->path->name, 0) != NGX_OK) {
3066+
return NGX_CONF_ERROR;
3067+
}
3068+
3069+
(*path)->path->level[0] = init->level[0];
3070+
(*path)->path->level[1] = init->level[1];
3071+
(*path)->path->level[2] = init->level[2];
3072+
3073+
(*path)->path->len = init->level[0] + (init->level[0] ? 1 : 0)
3074+
+ init->level[1] + (init->level[1] ? 1 : 0)
3075+
+ init->level[2] + (init->level[2] ? 1 : 0);
3076+
3077+
(*path)->path->manager = NULL;
3078+
(*path)->path->loader = NULL;
3079+
(*path)->path->conf_file = NULL;
3080+
3081+
if(ngx_add_path(cf, &(*path)->path) != NGX_OK) {
3082+
return NGX_CONF_ERROR;
3083+
}
3084+
3085+
return NGX_CONF_OK;
3086+
} /* }}} */
3087+
28773088
ngx_int_t /* {{{ ngx_http_read_upload_client_request_body */
28783089
ngx_http_read_upload_client_request_body(ngx_http_request_t *r) {
28793090
ssize_t size, preread;
@@ -3795,8 +4006,8 @@ ngx_http_upload_parse_range(ngx_str_t *range, ngx_http_upload_range_t *range_n)
37954006
return NGX_ERROR;
37964007
}
37974008

3798-
if(range_n->start >= range_n->end || range_n->start >= range_n->total
3799-
|| range_n->end > range_n->total)
4009+
if(range_n->start > range_n->end || range_n->start >= range_n->total
4010+
|| range_n->end >= range_n->total)
38004011
{
38014012
return NGX_ERROR;
38024013
}

0 commit comments

Comments
 (0)