Skip to content
This repository
Browse code

Merge pull request #37 from funny-falcon/dyn_upload_store

Merge wd-2.2 to 2.2 and fix #11 - make upload_state_path working
  • Loading branch information...
commit d106b92525a46faf9b1ccb8d07fe004eb48423a4 2 parents fb66c11 + 11e0a39
Valery Kholodkov authored

Showing 1 changed file with 239 additions and 28 deletions. Show diff stats Hide diff stats

  1. +239 28 ngx_http_upload_module.c
267 ngx_http_upload_module.c
@@ -114,6 +114,12 @@ typedef struct {
114 114 #endif
115 115 } ngx_http_upload_field_filter_t;
116 116
  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 +
117 123 /*
118 124 * Upload cleanup record
119 125 */
@@ -132,8 +138,8 @@ typedef struct ngx_http_upload_cleanup_s {
132 138 typedef struct {
133 139 ngx_str_t url;
134 140 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;
137 143 ngx_uint_t store_access;
138 144 size_t buffer_size;
139 145 size_t merge_buffer_size;
@@ -244,6 +250,8 @@ typedef struct ngx_http_upload_ctx_s {
244 250 ngx_http_upload_sha256_ctx_t *sha256_ctx;
245 251 ngx_http_upload_sha512_ctx_t *sha512_ctx;
246 252 uint32_t crc32;
  253 + ngx_path_t *store_path;
  254 + ngx_path_t *state_store_path;
247 255
248 256 unsigned int first_part:1;
249 257 unsigned int discard_data:1;
@@ -312,8 +320,14 @@ static char *ngx_http_upload_set_form_field(ngx_conf_t *cf, ngx_command_t *cmd,
312 320 void *conf);
313 321 static char *ngx_http_upload_add_header(ngx_conf_t *cf, ngx_command_t *cmd,
314 322 void *conf);
  323 +static ngx_int_t ngx_http_upload_eval_path(ngx_http_request_t *r);
  324 +static ngx_int_t ngx_http_upload_eval_state_path(ngx_http_request_t *r);
315 325 static char *ngx_http_upload_pass_form_field(ngx_conf_t *cf, ngx_command_t *cmd,
316 326 void *conf);
  327 +static char *ngx_http_upload_set_path_slot(ngx_conf_t *cf, ngx_command_t *cmd,
  328 + void *conf);
  329 +static char *ngx_http_upload_merge_path_value(ngx_conf_t *cf, ngx_http_upload_path_t **path, ngx_http_upload_path_t *prev,
  330 + ngx_path_init_t *init);
317 331 static char *ngx_http_upload_cleanup(ngx_conf_t *cf, ngx_command_t *cmd,
318 332 void *conf);
319 333 static void ngx_upload_cleanup_handler(void *data);
@@ -424,7 +438,7 @@ static ngx_command_t ngx_http_upload_commands[] = { /* {{{ */
424 438 { ngx_string("upload_store"),
425 439 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF|NGX_HTTP_LIF_CONF
426 440 |NGX_CONF_TAKE1234,
427   - ngx_conf_set_path_slot,
  441 + ngx_http_upload_set_path_slot,
428 442 NGX_HTTP_LOC_CONF_OFFSET,
429 443 offsetof(ngx_http_upload_loc_conf_t, store_path),
430 444 NULL },
@@ -434,7 +448,7 @@ static ngx_command_t ngx_http_upload_commands[] = { /* {{{ */
434 448 */
435 449 { ngx_string("upload_state_store"),
436 450 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234,
437   - ngx_conf_set_path_slot,
  451 + ngx_http_upload_set_path_slot,
438 452 NGX_HTTP_LOC_CONF_OFFSET,
439 453 offsetof(ngx_http_upload_loc_conf_t, state_store_path),
440 454 NULL },
@@ -840,6 +854,20 @@ ngx_http_upload_handler(ngx_http_request_t *r)
840 854 return rc;
841 855 }
842 856
  857 + rc = ngx_http_upload_eval_path(r);
  858 +
  859 + if(rc != NGX_OK) {
  860 + upload_shutdown_ctx(u);
  861 + return rc;
  862 + }
  863 +
  864 + rc = ngx_http_upload_eval_state_path(r);
  865 +
  866 + if(rc != NGX_OK) {
  867 + upload_shutdown_ctx(u);
  868 + return rc;
  869 + }
  870 +
843 871 if (ngx_http_upload_test_expect(r) != NGX_OK) {
844 872 upload_shutdown_ctx(u);
845 873 return NGX_HTTP_INTERNAL_SERVER_ERROR;
@@ -895,6 +923,68 @@ static ngx_int_t ngx_http_upload_add_headers(ngx_http_request_t *r, ngx_http_upl
895 923 return NGX_OK;
896 924 } /* }}} */
897 925
  926 +static ngx_int_t /* {{{ */
  927 +ngx_http_upload_eval_path(ngx_http_request_t *r) {
  928 + ngx_http_upload_ctx_t *u;
  929 + ngx_http_upload_loc_conf_t *ulcf;
  930 + ngx_str_t value;
  931 +
  932 + ulcf = ngx_http_get_module_loc_conf(r, ngx_http_upload_module);
  933 + u = ngx_http_get_module_ctx(r, ngx_http_upload_module);
  934 +
  935 + if(ulcf->store_path->is_dynamic) {
  936 + u->store_path = ngx_pcalloc(r->pool, sizeof(ngx_path_t));
  937 + if(u->store_path == NULL) {
  938 + return NGX_ERROR;
  939 + }
  940 +
  941 + ngx_memcpy(u->store_path, ulcf->store_path->path, sizeof(ngx_path_t));
  942 +
  943 + if(ngx_http_complex_value(r, &ulcf->store_path->dynamic, &value) != NGX_OK) {
  944 + return NGX_ERROR;
  945 + }
  946 +
  947 + u->store_path->name.data = value.data;
  948 + u->store_path->name.len = value.len;
  949 + }
  950 + else{
  951 + u->store_path = ulcf->store_path->path;
  952 + }
  953 +
  954 + return NGX_OK;
  955 +} /* }}} */
  956 +
  957 +static ngx_int_t /* {{{ */
  958 +ngx_http_upload_eval_state_path(ngx_http_request_t *r) {
  959 + ngx_http_upload_ctx_t *u;
  960 + ngx_http_upload_loc_conf_t *ulcf;
  961 + ngx_str_t value;
  962 +
  963 + ulcf = ngx_http_get_module_loc_conf(r, ngx_http_upload_module);
  964 + u = ngx_http_get_module_ctx(r, ngx_http_upload_module);
  965 +
  966 + if(ulcf->state_store_path->is_dynamic) {
  967 + u->state_store_path = ngx_pcalloc(r->pool, sizeof(ngx_path_t));
  968 + if(u->store_path == NULL) {
  969 + return NGX_ERROR;
  970 + }
  971 +
  972 + ngx_memcpy(u->state_store_path, ulcf->state_store_path->path, sizeof(ngx_path_t));
  973 +
  974 + if(ngx_http_complex_value(r, &ulcf->state_store_path->dynamic, &value) != NGX_OK) {
  975 + return NGX_ERROR;
  976 + }
  977 +
  978 + u->state_store_path->name.data = value.data;
  979 + u->state_store_path->name.len = value.len;
  980 + }
  981 + else{
  982 + u->state_store_path = ulcf->state_store_path->path;
  983 + }
  984 +
  985 + return NGX_OK;
  986 +} /* }}} */
  987 +
898 988 static ngx_int_t ngx_http_upload_options_handler(ngx_http_request_t *r) { /* {{{ */
899 989 ngx_http_upload_loc_conf_t *ulcf;
900 990
@@ -1111,7 +1201,8 @@ static ngx_int_t ngx_http_upload_start_handler(ngx_http_upload_ctx_t *u) { /* {{
1111 1201 ngx_http_upload_loc_conf_t *ulcf = ngx_http_get_module_loc_conf(r, ngx_http_upload_module);
1112 1202
1113 1203 ngx_file_t *file = &u->output_file;
1114   - ngx_path_t *path = ulcf->store_path;
  1204 + ngx_path_t *path = u->store_path;
  1205 + ngx_path_t *state_path = u->state_store_path;
1115 1206 uint32_t n;
1116 1207 ngx_uint_t i;
1117 1208 ngx_int_t rc;
@@ -1151,6 +1242,7 @@ static ngx_int_t ngx_http_upload_start_handler(ngx_http_upload_ctx_t *u) { /* {{
1151 1242 "hashed path: %s", file->name.data);
1152 1243
1153 1244 if(u->partial_content) {
  1245 + ngx_file_t *state_file = &u->state_file;
1154 1246 if(u->merge_buffer == NULL) {
1155 1247 u->merge_buffer = ngx_palloc(r->pool, ulcf->merge_buffer_size);
1156 1248
@@ -1158,21 +1250,20 @@ static ngx_int_t ngx_http_upload_start_handler(ngx_http_upload_ctx_t *u) { /* {{
1158 1250 return NGX_UPLOAD_NOMEM;
1159 1251 }
1160 1252
1161   - u->state_file.name.len = file->name.len + sizeof(".state") - 1;
1162   - u->state_file.name.data = ngx_palloc(u->request->pool, u->state_file.name.len + 1);
  1253 + state_file->name.len = state_path->name.len + 1 + state_path->len + u->session_id.len + sizeof(".state");
  1254 + state_file->name.data = ngx_palloc(u->request->pool, state_file->name.len + 1);
1163 1255
1164   - if(u->state_file.name.data == NULL)
  1256 + if(state_file->name.data == NULL)
1165 1257 return NGX_UPLOAD_NOMEM;
1166 1258
1167   - ngx_memcpy(u->state_file.name.data, file->name.data, file->name.len);
  1259 + ngx_memcpy(state_file->name.data, state_path->name.data, state_path->name.len);
  1260 + (void) ngx_sprintf(state_file->name.data + state_path->name.len + 1 + state_path->len,
  1261 + "%V.state%Z", &u->session_id);
1168 1262
1169   - /*
1170   - * NOTE: we add terminating zero for system calls
1171   - */
1172   - ngx_memcpy(u->state_file.name.data + file->name.len, ".state", sizeof(".state") - 1 + 1);
  1263 + ngx_create_hashed_filename(state_path, state_file->name.data, state_file->name.len);
1173 1264
1174 1265 ngx_log_debug1(NGX_LOG_DEBUG_CORE, file->log, 0,
1175   - "hashed path of state file: %s", u->state_file.name.data);
  1266 + "hashed path of state file: %s", state_file->name.data);
1176 1267 }
1177 1268
1178 1269 file->fd = ngx_open_file(file->name.data, NGX_FILE_WRONLY, NGX_FILE_CREATE_OR_OPEN, ulcf->store_access);
@@ -2012,27 +2103,15 @@ ngx_http_upload_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
2012 2103 }
2013 2104
2014 2105 if(conf->url.len != 0) {
2015   -#if defined nginx_version && nginx_version >= 7052
2016   - ngx_conf_merge_path_value(cf,
  2106 + ngx_http_upload_merge_path_value(cf,
2017 2107 &conf->store_path,
2018 2108 prev->store_path,
2019 2109 &ngx_http_upload_temp_path);
2020 2110
2021   - ngx_conf_merge_path_value(cf,
  2111 + ngx_http_upload_merge_path_value(cf,
2022 2112 &conf->state_store_path,
2023 2113 prev->state_store_path,
2024 2114 &ngx_http_upload_temp_path);
2025   -#else
2026   - ngx_conf_merge_path_value(conf->store_path,
2027   - prev->store_path,
2028   - NGX_HTTP_PROXY_TEMP_PATH, 1, 2, 0,
2029   - ngx_garbage_collector_temp_handler, cf);
2030   -
2031   - ngx_conf_merge_path_value(conf->state_store_path,
2032   - prev->state_store_path,
2033   - NGX_HTTP_PROXY_TEMP_PATH, 1, 2, 0,
2034   - ngx_garbage_collector_temp_handler, cf);
2035   -#endif
2036 2115 }
2037 2116
2038 2117 ngx_conf_merge_uint_value(conf->store_access,
@@ -2873,6 +2952,138 @@ ngx_http_upload_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2873 2952 return NGX_CONF_OK;
2874 2953 } /* }}} */
2875 2954
  2955 +static char * /* {{{ ngx_http_upload_set_path_slot */
  2956 +ngx_http_upload_set_path_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  2957 +{
  2958 + char *p = conf;
  2959 +
  2960 + ssize_t level;
  2961 + ngx_str_t *value;
  2962 + ngx_uint_t i, n;
  2963 + ngx_http_upload_path_t *path, **slot;
  2964 + ngx_http_compile_complex_value_t ccv;
  2965 +
  2966 + slot = (ngx_http_upload_path_t **) (p + cmd->offset);
  2967 +
  2968 + if (*slot) {
  2969 + return "is duplicate";
  2970 + }
  2971 +
  2972 + path = ngx_pcalloc(cf->pool, sizeof(ngx_http_upload_path_t));
  2973 + if (path == NULL) {
  2974 + return NGX_CONF_ERROR;
  2975 + }
  2976 +
  2977 + path->path = ngx_pcalloc(cf->pool, sizeof(ngx_path_t));
  2978 + if (path->path == NULL) {
  2979 + return NGX_CONF_ERROR;
  2980 + }
  2981 +
  2982 + value = cf->args->elts;
  2983 +
  2984 + path->path->name = value[1];
  2985 +
  2986 + if (path->path->name.data[path->path->name.len - 1] == '/') {
  2987 + path->path->name.len--;
  2988 + }
  2989 +
  2990 + if (ngx_conf_full_name(cf->cycle, &path->path->name, 0) != NGX_OK) {
  2991 + return NULL;
  2992 + }
  2993 +
  2994 + path->path->len = 0;
  2995 + path->path->manager = NULL;
  2996 + path->path->loader = NULL;
  2997 + path->path->conf_file = cf->conf_file->file.name.data;
  2998 + path->path->line = cf->conf_file->line;
  2999 +
  3000 + for (i = 0, n = 2; n < cf->args->nelts; i++, n++) {
  3001 + level = ngx_atoi(value[n].data, value[n].len);
  3002 + if (level == NGX_ERROR || level == 0) {
  3003 + return "invalid value";
  3004 + }
  3005 +
  3006 + path->path->level[i] = level;
  3007 + path->path->len += level + 1;
  3008 + }
  3009 +
  3010 + while (i < 3) {
  3011 + path->path->level[i++] = 0;
  3012 + }
  3013 +
  3014 + *slot = path;
  3015 +
  3016 + if(ngx_http_script_variables_count(&value[1])) {
  3017 + ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
  3018 +
  3019 + ccv.cf = cf;
  3020 + ccv.value = &value[1];
  3021 + ccv.complex_value = &path->dynamic;
  3022 +
  3023 + if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
  3024 + return NGX_CONF_ERROR;
  3025 + }
  3026 +
  3027 + path->is_dynamic = 1;
  3028 + }
  3029 + else {
  3030 + if (ngx_add_path(cf, &path->path) == NGX_ERROR) {
  3031 + return NGX_CONF_ERROR;
  3032 + }
  3033 + }
  3034 +
  3035 + return NGX_CONF_OK;
  3036 +} /* }}} */
  3037 +
  3038 +
  3039 +static char * /* {{{ ngx_http_upload_merge_path_value */
  3040 +ngx_http_upload_merge_path_value(ngx_conf_t *cf, ngx_http_upload_path_t **path, ngx_http_upload_path_t *prev,
  3041 + ngx_path_init_t *init)
  3042 +{
  3043 + if (*path) {
  3044 + return NGX_CONF_OK;
  3045 + }
  3046 +
  3047 + if (prev) {
  3048 + *path = prev;
  3049 + return NGX_CONF_OK;
  3050 + }
  3051 +
  3052 + *path = ngx_palloc(cf->pool, sizeof(ngx_http_upload_path_t));
  3053 + if(*path == NULL) {
  3054 + return NGX_CONF_ERROR;
  3055 + }
  3056 +
  3057 + (*path)->path = ngx_pcalloc(cf->pool, sizeof(ngx_path_t));
  3058 + if((*path)->path == NULL) {
  3059 + return NGX_CONF_ERROR;
  3060 + }
  3061 +
  3062 + (*path)->path->name = init->name;
  3063 +
  3064 + if(ngx_conf_full_name(cf->cycle, &(*path)->path->name, 0) != NGX_OK) {
  3065 + return NGX_CONF_ERROR;
  3066 + }
  3067 +
  3068 + (*path)->path->level[0] = init->level[0];
  3069 + (*path)->path->level[1] = init->level[1];
  3070 + (*path)->path->level[2] = init->level[2];
  3071 +
  3072 + (*path)->path->len = init->level[0] + (init->level[0] ? 1 : 0)
  3073 + + init->level[1] + (init->level[1] ? 1 : 0)
  3074 + + init->level[2] + (init->level[2] ? 1 : 0);
  3075 +
  3076 + (*path)->path->manager = NULL;
  3077 + (*path)->path->loader = NULL;
  3078 + (*path)->path->conf_file = NULL;
  3079 +
  3080 + if(ngx_add_path(cf, &(*path)->path) != NGX_OK) {
  3081 + return NGX_CONF_ERROR;
  3082 + }
  3083 +
  3084 + return NGX_CONF_OK;
  3085 +} /* }}} */
  3086 +
2876 3087 ngx_int_t /* {{{ ngx_http_read_upload_client_request_body */
2877 3088 ngx_http_read_upload_client_request_body(ngx_http_request_t *r) {
2878 3089 ssize_t size, preread;

0 comments on commit d106b92

Please sign in to comment.
Something went wrong with that request. Please try again.