Skip to content
This repository

Merge wd-2.2 to master and fix #11 - make upload_state_path working #37

Merged
merged 4 commits into from over 1 year ago

2 participants

Sokolov Yura Valery Kholodkov
Sokolov Yura

wd-2.2 branch (commit 9406333 ) is very useful, please merge it to a 2.2 branch before next version release. I wish to use it for load balancing between several hard drives of the same upload server.

Last commit fixes upload_state_path to make it workable (so that fix issue #11). It is absolutely necessary cause high load on upload disk cause some misbehavior for state files when they are written to the same disk. So that, it is necessary for upload_state_path to point to other physical storage disk.

I've copied infrastructure from upload_path to upload_state_path, so that upload_state_path expanded with variables as well. I doubt it will be very usefull (I will not use this expansion), but I think, that things should behaves similar.

Valery Kholodkov vkholodkov merged commit d106b92 into from September 05, 2012
Valery Kholodkov vkholodkov closed this September 05, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.

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

  1. 267  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;
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.