Annotation of embedaddon/nginx/src/http/modules/ngx_http_uwsgi_module.c, revision 1.1
1.1 ! misho 1:
! 2: /*
! 3: * Copyright (C) Unbit S.a.s. 2009-2010
! 4: * Copyright (C) 2008 Manlio Perillo (manlio.perillo@gmail.com)
! 5: * Copyright (C) Igor Sysoev
! 6: * Copyright (C) Nginx, Inc.
! 7: */
! 8:
! 9:
! 10: #include <ngx_config.h>
! 11: #include <ngx_core.h>
! 12: #include <ngx_http.h>
! 13:
! 14:
! 15: typedef struct {
! 16: ngx_http_upstream_conf_t upstream;
! 17:
! 18: ngx_array_t *flushes;
! 19: ngx_array_t *params_len;
! 20: ngx_array_t *params;
! 21: ngx_array_t *params_source;
! 22:
! 23: ngx_hash_t headers_hash;
! 24: ngx_uint_t header_params;
! 25:
! 26: ngx_array_t *uwsgi_lengths;
! 27: ngx_array_t *uwsgi_values;
! 28:
! 29: #if (NGX_HTTP_CACHE)
! 30: ngx_http_complex_value_t cache_key;
! 31: #endif
! 32:
! 33: ngx_str_t uwsgi_string;
! 34:
! 35: ngx_uint_t modifier1;
! 36: ngx_uint_t modifier2;
! 37: } ngx_http_uwsgi_loc_conf_t;
! 38:
! 39:
! 40: static ngx_int_t ngx_http_uwsgi_eval(ngx_http_request_t *r,
! 41: ngx_http_uwsgi_loc_conf_t *uwcf);
! 42: static ngx_int_t ngx_http_uwsgi_create_request(ngx_http_request_t *r);
! 43: static ngx_int_t ngx_http_uwsgi_reinit_request(ngx_http_request_t *r);
! 44: static ngx_int_t ngx_http_uwsgi_process_status_line(ngx_http_request_t *r);
! 45: static ngx_int_t ngx_http_uwsgi_process_header(ngx_http_request_t *r);
! 46: static void ngx_http_uwsgi_abort_request(ngx_http_request_t *r);
! 47: static void ngx_http_uwsgi_finalize_request(ngx_http_request_t *r,
! 48: ngx_int_t rc);
! 49:
! 50: static void *ngx_http_uwsgi_create_loc_conf(ngx_conf_t *cf);
! 51: static char *ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent,
! 52: void *child);
! 53: static ngx_int_t ngx_http_uwsgi_merge_params(ngx_conf_t *cf,
! 54: ngx_http_uwsgi_loc_conf_t *conf, ngx_http_uwsgi_loc_conf_t *prev);
! 55:
! 56: static char *ngx_http_uwsgi_pass(ngx_conf_t *cf, ngx_command_t *cmd,
! 57: void *conf);
! 58: static char *ngx_http_uwsgi_store(ngx_conf_t *cf, ngx_command_t *cmd,
! 59: void *conf);
! 60:
! 61: #if (NGX_HTTP_CACHE)
! 62: static ngx_int_t ngx_http_uwsgi_create_key(ngx_http_request_t *r);
! 63: static char *ngx_http_uwsgi_cache(ngx_conf_t *cf, ngx_command_t *cmd,
! 64: void *conf);
! 65: static char *ngx_http_uwsgi_cache_key(ngx_conf_t *cf, ngx_command_t *cmd,
! 66: void *conf);
! 67: #endif
! 68:
! 69:
! 70: static ngx_conf_num_bounds_t ngx_http_uwsgi_modifier_bounds = {
! 71: ngx_conf_check_num_bounds, 0, 255
! 72: };
! 73:
! 74:
! 75: static ngx_conf_bitmask_t ngx_http_uwsgi_next_upstream_masks[] = {
! 76: { ngx_string("error"), NGX_HTTP_UPSTREAM_FT_ERROR },
! 77: { ngx_string("timeout"), NGX_HTTP_UPSTREAM_FT_TIMEOUT },
! 78: { ngx_string("invalid_header"), NGX_HTTP_UPSTREAM_FT_INVALID_HEADER },
! 79: { ngx_string("http_500"), NGX_HTTP_UPSTREAM_FT_HTTP_500 },
! 80: { ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 },
! 81: { ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 },
! 82: { ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING },
! 83: { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF },
! 84: { ngx_null_string, 0 }
! 85: };
! 86:
! 87:
! 88: ngx_module_t ngx_http_uwsgi_module;
! 89:
! 90:
! 91: static ngx_command_t ngx_http_uwsgi_commands[] = {
! 92:
! 93: { ngx_string("uwsgi_pass"),
! 94: NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1,
! 95: ngx_http_uwsgi_pass,
! 96: NGX_HTTP_LOC_CONF_OFFSET,
! 97: 0,
! 98: NULL },
! 99:
! 100: { ngx_string("uwsgi_modifier1"),
! 101: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
! 102: ngx_conf_set_num_slot,
! 103: NGX_HTTP_LOC_CONF_OFFSET,
! 104: offsetof(ngx_http_uwsgi_loc_conf_t, modifier1),
! 105: &ngx_http_uwsgi_modifier_bounds },
! 106:
! 107: { ngx_string("uwsgi_modifier2"),
! 108: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
! 109: ngx_conf_set_num_slot,
! 110: NGX_HTTP_LOC_CONF_OFFSET,
! 111: offsetof(ngx_http_uwsgi_loc_conf_t, modifier2),
! 112: &ngx_http_uwsgi_modifier_bounds },
! 113:
! 114: { ngx_string("uwsgi_store"),
! 115: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
! 116: ngx_http_uwsgi_store,
! 117: NGX_HTTP_LOC_CONF_OFFSET,
! 118: 0,
! 119: NULL },
! 120:
! 121: { ngx_string("uwsgi_store_access"),
! 122: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE123,
! 123: ngx_conf_set_access_slot,
! 124: NGX_HTTP_LOC_CONF_OFFSET,
! 125: offsetof(ngx_http_uwsgi_loc_conf_t, upstream.store_access),
! 126: NULL },
! 127:
! 128: { ngx_string("uwsgi_buffering"),
! 129: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
! 130: ngx_conf_set_flag_slot,
! 131: NGX_HTTP_LOC_CONF_OFFSET,
! 132: offsetof(ngx_http_uwsgi_loc_conf_t, upstream.buffering),
! 133: NULL },
! 134:
! 135: { ngx_string("uwsgi_ignore_client_abort"),
! 136: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
! 137: ngx_conf_set_flag_slot,
! 138: NGX_HTTP_LOC_CONF_OFFSET,
! 139: offsetof(ngx_http_uwsgi_loc_conf_t, upstream.ignore_client_abort),
! 140: NULL },
! 141:
! 142: { ngx_string("uwsgi_bind"),
! 143: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
! 144: ngx_http_upstream_bind_set_slot,
! 145: NGX_HTTP_LOC_CONF_OFFSET,
! 146: offsetof(ngx_http_uwsgi_loc_conf_t, upstream.local),
! 147: NULL },
! 148:
! 149: { ngx_string("uwsgi_connect_timeout"),
! 150: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
! 151: ngx_conf_set_msec_slot,
! 152: NGX_HTTP_LOC_CONF_OFFSET,
! 153: offsetof(ngx_http_uwsgi_loc_conf_t, upstream.connect_timeout),
! 154: NULL },
! 155:
! 156: { ngx_string("uwsgi_send_timeout"),
! 157: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
! 158: ngx_conf_set_msec_slot,
! 159: NGX_HTTP_LOC_CONF_OFFSET,
! 160: offsetof(ngx_http_uwsgi_loc_conf_t, upstream.send_timeout),
! 161: NULL },
! 162:
! 163: { ngx_string("uwsgi_buffer_size"),
! 164: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
! 165: ngx_conf_set_size_slot,
! 166: NGX_HTTP_LOC_CONF_OFFSET,
! 167: offsetof(ngx_http_uwsgi_loc_conf_t, upstream.buffer_size),
! 168: NULL },
! 169:
! 170: { ngx_string("uwsgi_pass_request_headers"),
! 171: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
! 172: ngx_conf_set_flag_slot,
! 173: NGX_HTTP_LOC_CONF_OFFSET,
! 174: offsetof(ngx_http_uwsgi_loc_conf_t, upstream.pass_request_headers),
! 175: NULL },
! 176:
! 177: { ngx_string("uwsgi_pass_request_body"),
! 178: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
! 179: ngx_conf_set_flag_slot,
! 180: NGX_HTTP_LOC_CONF_OFFSET,
! 181: offsetof(ngx_http_uwsgi_loc_conf_t, upstream.pass_request_body),
! 182: NULL },
! 183:
! 184: { ngx_string("uwsgi_intercept_errors"),
! 185: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
! 186: ngx_conf_set_flag_slot,
! 187: NGX_HTTP_LOC_CONF_OFFSET,
! 188: offsetof(ngx_http_uwsgi_loc_conf_t, upstream.intercept_errors),
! 189: NULL },
! 190:
! 191: { ngx_string("uwsgi_read_timeout"),
! 192: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
! 193: ngx_conf_set_msec_slot,
! 194: NGX_HTTP_LOC_CONF_OFFSET,
! 195: offsetof(ngx_http_uwsgi_loc_conf_t, upstream.read_timeout),
! 196: NULL },
! 197:
! 198: { ngx_string("uwsgi_buffers"),
! 199: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
! 200: ngx_conf_set_bufs_slot,
! 201: NGX_HTTP_LOC_CONF_OFFSET,
! 202: offsetof(ngx_http_uwsgi_loc_conf_t, upstream.bufs),
! 203: NULL },
! 204:
! 205: { ngx_string("uwsgi_busy_buffers_size"),
! 206: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
! 207: ngx_conf_set_size_slot,
! 208: NGX_HTTP_LOC_CONF_OFFSET,
! 209: offsetof(ngx_http_uwsgi_loc_conf_t, upstream.busy_buffers_size_conf),
! 210: NULL },
! 211:
! 212: #if (NGX_HTTP_CACHE)
! 213:
! 214: { ngx_string("uwsgi_cache"),
! 215: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
! 216: ngx_http_uwsgi_cache,
! 217: NGX_HTTP_LOC_CONF_OFFSET,
! 218: 0,
! 219: NULL },
! 220:
! 221: { ngx_string("uwsgi_cache_key"),
! 222: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
! 223: ngx_http_uwsgi_cache_key,
! 224: NGX_HTTP_LOC_CONF_OFFSET,
! 225: 0,
! 226: NULL },
! 227:
! 228: { ngx_string("uwsgi_cache_path"),
! 229: NGX_HTTP_MAIN_CONF|NGX_CONF_2MORE,
! 230: ngx_http_file_cache_set_slot,
! 231: 0,
! 232: 0,
! 233: &ngx_http_uwsgi_module },
! 234:
! 235: { ngx_string("uwsgi_cache_bypass"),
! 236: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
! 237: ngx_http_set_predicate_slot,
! 238: NGX_HTTP_LOC_CONF_OFFSET,
! 239: offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_bypass),
! 240: NULL },
! 241:
! 242: { ngx_string("uwsgi_no_cache"),
! 243: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
! 244: ngx_http_set_predicate_slot,
! 245: NGX_HTTP_LOC_CONF_OFFSET,
! 246: offsetof(ngx_http_uwsgi_loc_conf_t, upstream.no_cache),
! 247: NULL },
! 248:
! 249: { ngx_string("uwsgi_cache_valid"),
! 250: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
! 251: ngx_http_file_cache_valid_set_slot,
! 252: NGX_HTTP_LOC_CONF_OFFSET,
! 253: offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_valid),
! 254: NULL },
! 255:
! 256: { ngx_string("uwsgi_cache_min_uses"),
! 257: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
! 258: ngx_conf_set_num_slot,
! 259: NGX_HTTP_LOC_CONF_OFFSET,
! 260: offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_min_uses),
! 261: NULL },
! 262:
! 263: { ngx_string("uwsgi_cache_use_stale"),
! 264: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
! 265: ngx_conf_set_bitmask_slot,
! 266: NGX_HTTP_LOC_CONF_OFFSET,
! 267: offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_use_stale),
! 268: &ngx_http_uwsgi_next_upstream_masks },
! 269:
! 270: { ngx_string("uwsgi_cache_methods"),
! 271: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
! 272: ngx_conf_set_bitmask_slot,
! 273: NGX_HTTP_LOC_CONF_OFFSET,
! 274: offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_methods),
! 275: &ngx_http_upstream_cache_method_mask },
! 276:
! 277: { ngx_string("uwsgi_cache_lock"),
! 278: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
! 279: ngx_conf_set_flag_slot,
! 280: NGX_HTTP_LOC_CONF_OFFSET,
! 281: offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_lock),
! 282: NULL },
! 283:
! 284: { ngx_string("uwsgi_cache_lock_timeout"),
! 285: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
! 286: ngx_conf_set_msec_slot,
! 287: NGX_HTTP_LOC_CONF_OFFSET,
! 288: offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_lock_timeout),
! 289: NULL },
! 290:
! 291: #endif
! 292:
! 293: { ngx_string("uwsgi_temp_path"),
! 294: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234,
! 295: ngx_conf_set_path_slot,
! 296: NGX_HTTP_LOC_CONF_OFFSET,
! 297: offsetof(ngx_http_uwsgi_loc_conf_t, upstream.temp_path),
! 298: NULL },
! 299:
! 300: { ngx_string("uwsgi_max_temp_file_size"),
! 301: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
! 302: ngx_conf_set_size_slot,
! 303: NGX_HTTP_LOC_CONF_OFFSET,
! 304: offsetof(ngx_http_uwsgi_loc_conf_t, upstream.max_temp_file_size_conf),
! 305: NULL },
! 306:
! 307: { ngx_string("uwsgi_temp_file_write_size"),
! 308: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
! 309: ngx_conf_set_size_slot,
! 310: NGX_HTTP_LOC_CONF_OFFSET,
! 311: offsetof(ngx_http_uwsgi_loc_conf_t, upstream.temp_file_write_size_conf),
! 312: NULL },
! 313:
! 314: { ngx_string("uwsgi_next_upstream"),
! 315: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
! 316: ngx_conf_set_bitmask_slot,
! 317: NGX_HTTP_LOC_CONF_OFFSET,
! 318: offsetof(ngx_http_uwsgi_loc_conf_t, upstream.next_upstream),
! 319: &ngx_http_uwsgi_next_upstream_masks },
! 320:
! 321: { ngx_string("uwsgi_param"),
! 322: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE23,
! 323: ngx_http_upstream_param_set_slot,
! 324: NGX_HTTP_LOC_CONF_OFFSET,
! 325: offsetof(ngx_http_uwsgi_loc_conf_t, params_source),
! 326: NULL },
! 327:
! 328: { ngx_string("uwsgi_string"),
! 329: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
! 330: ngx_conf_set_str_slot,
! 331: NGX_HTTP_LOC_CONF_OFFSET,
! 332: offsetof(ngx_http_uwsgi_loc_conf_t, uwsgi_string),
! 333: NULL },
! 334:
! 335: { ngx_string("uwsgi_pass_header"),
! 336: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
! 337: ngx_conf_set_str_array_slot,
! 338: NGX_HTTP_LOC_CONF_OFFSET,
! 339: offsetof(ngx_http_uwsgi_loc_conf_t, upstream.pass_headers),
! 340: NULL },
! 341:
! 342: { ngx_string("uwsgi_hide_header"),
! 343: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
! 344: ngx_conf_set_str_array_slot,
! 345: NGX_HTTP_LOC_CONF_OFFSET,
! 346: offsetof(ngx_http_uwsgi_loc_conf_t, upstream.hide_headers),
! 347: NULL },
! 348:
! 349: { ngx_string("uwsgi_ignore_headers"),
! 350: NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
! 351: ngx_conf_set_bitmask_slot,
! 352: NGX_HTTP_LOC_CONF_OFFSET,
! 353: offsetof(ngx_http_uwsgi_loc_conf_t, upstream.ignore_headers),
! 354: &ngx_http_upstream_ignore_headers_masks },
! 355:
! 356: ngx_null_command
! 357: };
! 358:
! 359:
! 360: static ngx_http_module_t ngx_http_uwsgi_module_ctx = {
! 361: NULL, /* preconfiguration */
! 362: NULL, /* postconfiguration */
! 363:
! 364: NULL, /* create main configuration */
! 365: NULL, /* init main configuration */
! 366:
! 367: NULL, /* create server configuration */
! 368: NULL, /* merge server configuration */
! 369:
! 370: ngx_http_uwsgi_create_loc_conf, /* create location configuration */
! 371: ngx_http_uwsgi_merge_loc_conf /* merge location configuration */
! 372: };
! 373:
! 374:
! 375: ngx_module_t ngx_http_uwsgi_module = {
! 376: NGX_MODULE_V1,
! 377: &ngx_http_uwsgi_module_ctx, /* module context */
! 378: ngx_http_uwsgi_commands, /* module directives */
! 379: NGX_HTTP_MODULE, /* module type */
! 380: NULL, /* init master */
! 381: NULL, /* init module */
! 382: NULL, /* init process */
! 383: NULL, /* init thread */
! 384: NULL, /* exit thread */
! 385: NULL, /* exit process */
! 386: NULL, /* exit master */
! 387: NGX_MODULE_V1_PADDING
! 388: };
! 389:
! 390:
! 391: static ngx_str_t ngx_http_uwsgi_hide_headers[] = {
! 392: ngx_string("X-Accel-Expires"),
! 393: ngx_string("X-Accel-Redirect"),
! 394: ngx_string("X-Accel-Limit-Rate"),
! 395: ngx_string("X-Accel-Buffering"),
! 396: ngx_string("X-Accel-Charset"),
! 397: ngx_null_string
! 398: };
! 399:
! 400:
! 401: #if (NGX_HTTP_CACHE)
! 402:
! 403: static ngx_keyval_t ngx_http_uwsgi_cache_headers[] = {
! 404: { ngx_string("HTTP_IF_MODIFIED_SINCE"), ngx_string("") },
! 405: { ngx_string("HTTP_IF_UNMODIFIED_SINCE"), ngx_string("") },
! 406: { ngx_string("HTTP_IF_NONE_MATCH"), ngx_string("") },
! 407: { ngx_string("HTTP_IF_MATCH"), ngx_string("") },
! 408: { ngx_string("HTTP_RANGE"), ngx_string("") },
! 409: { ngx_string("HTTP_IF_RANGE"), ngx_string("") },
! 410: { ngx_null_string, ngx_null_string }
! 411: };
! 412:
! 413: #endif
! 414:
! 415:
! 416: static ngx_path_init_t ngx_http_uwsgi_temp_path = {
! 417: ngx_string(NGX_HTTP_UWSGI_TEMP_PATH), { 1, 2, 0 }
! 418: };
! 419:
! 420:
! 421: static ngx_int_t
! 422: ngx_http_uwsgi_handler(ngx_http_request_t *r)
! 423: {
! 424: ngx_int_t rc;
! 425: ngx_http_status_t *status;
! 426: ngx_http_upstream_t *u;
! 427: ngx_http_uwsgi_loc_conf_t *uwcf;
! 428:
! 429: if (r->subrequest_in_memory) {
! 430: ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
! 431: "ngx_http_uwsgi_module does not support "
! 432: "subrequests in memory");
! 433: return NGX_HTTP_INTERNAL_SERVER_ERROR;
! 434: }
! 435:
! 436: if (ngx_http_upstream_create(r) != NGX_OK) {
! 437: return NGX_HTTP_INTERNAL_SERVER_ERROR;
! 438: }
! 439:
! 440: status = ngx_pcalloc(r->pool, sizeof(ngx_http_status_t));
! 441: if (status == NULL) {
! 442: return NGX_HTTP_INTERNAL_SERVER_ERROR;
! 443: }
! 444:
! 445: ngx_http_set_ctx(r, status, ngx_http_uwsgi_module);
! 446:
! 447: uwcf = ngx_http_get_module_loc_conf(r, ngx_http_uwsgi_module);
! 448:
! 449: if (uwcf->uwsgi_lengths) {
! 450: if (ngx_http_uwsgi_eval(r, uwcf) != NGX_OK) {
! 451: return NGX_HTTP_INTERNAL_SERVER_ERROR;
! 452: }
! 453: }
! 454:
! 455: u = r->upstream;
! 456:
! 457: ngx_str_set(&u->schema, "uwsgi://");
! 458: u->output.tag = (ngx_buf_tag_t) &ngx_http_uwsgi_module;
! 459:
! 460: u->conf = &uwcf->upstream;
! 461:
! 462: #if (NGX_HTTP_CACHE)
! 463: u->create_key = ngx_http_uwsgi_create_key;
! 464: #endif
! 465: u->create_request = ngx_http_uwsgi_create_request;
! 466: u->reinit_request = ngx_http_uwsgi_reinit_request;
! 467: u->process_header = ngx_http_uwsgi_process_status_line;
! 468: u->abort_request = ngx_http_uwsgi_abort_request;
! 469: u->finalize_request = ngx_http_uwsgi_finalize_request;
! 470: r->state = 0;
! 471:
! 472: u->buffering = uwcf->upstream.buffering;
! 473:
! 474: u->pipe = ngx_pcalloc(r->pool, sizeof(ngx_event_pipe_t));
! 475: if (u->pipe == NULL) {
! 476: return NGX_HTTP_INTERNAL_SERVER_ERROR;
! 477: }
! 478:
! 479: u->pipe->input_filter = ngx_event_pipe_copy_input_filter;
! 480: u->pipe->input_ctx = r;
! 481:
! 482: rc = ngx_http_read_client_request_body(r, ngx_http_upstream_init);
! 483:
! 484: if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
! 485: return rc;
! 486: }
! 487:
! 488: return NGX_DONE;
! 489: }
! 490:
! 491:
! 492: static ngx_int_t
! 493: ngx_http_uwsgi_eval(ngx_http_request_t *r, ngx_http_uwsgi_loc_conf_t * uwcf)
! 494: {
! 495: ngx_url_t url;
! 496: ngx_http_upstream_t *u;
! 497:
! 498: ngx_memzero(&url, sizeof(ngx_url_t));
! 499:
! 500: if (ngx_http_script_run(r, &url.url, uwcf->uwsgi_lengths->elts, 0,
! 501: uwcf->uwsgi_values->elts)
! 502: == NULL)
! 503: {
! 504: return NGX_ERROR;
! 505: }
! 506:
! 507: url.no_resolve = 1;
! 508:
! 509: if (ngx_parse_url(r->pool, &url) != NGX_OK) {
! 510: if (url.err) {
! 511: ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
! 512: "%s in upstream \"%V\"", url.err, &url.url);
! 513: }
! 514:
! 515: return NGX_ERROR;
! 516: }
! 517:
! 518: u = r->upstream;
! 519:
! 520: u->resolved = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_resolved_t));
! 521: if (u->resolved == NULL) {
! 522: return NGX_ERROR;
! 523: }
! 524:
! 525: if (url.addrs && url.addrs[0].sockaddr) {
! 526: u->resolved->sockaddr = url.addrs[0].sockaddr;
! 527: u->resolved->socklen = url.addrs[0].socklen;
! 528: u->resolved->naddrs = 1;
! 529: u->resolved->host = url.addrs[0].name;
! 530:
! 531: } else {
! 532: u->resolved->host = url.host;
! 533: u->resolved->port = url.port;
! 534: u->resolved->no_port = url.no_port;
! 535: }
! 536:
! 537: return NGX_OK;
! 538: }
! 539:
! 540:
! 541: #if (NGX_HTTP_CACHE)
! 542:
! 543: static ngx_int_t
! 544: ngx_http_uwsgi_create_key(ngx_http_request_t *r)
! 545: {
! 546: ngx_str_t *key;
! 547: ngx_http_uwsgi_loc_conf_t *uwcf;
! 548:
! 549: key = ngx_array_push(&r->cache->keys);
! 550: if (key == NULL) {
! 551: return NGX_ERROR;
! 552: }
! 553:
! 554: uwcf = ngx_http_get_module_loc_conf(r, ngx_http_uwsgi_module);
! 555:
! 556: if (ngx_http_complex_value(r, &uwcf->cache_key, key) != NGX_OK) {
! 557: return NGX_ERROR;
! 558: }
! 559:
! 560: return NGX_OK;
! 561: }
! 562:
! 563: #endif
! 564:
! 565:
! 566: static ngx_int_t
! 567: ngx_http_uwsgi_create_request(ngx_http_request_t *r)
! 568: {
! 569: u_char ch, *lowcase_key;
! 570: size_t key_len, val_len, len, allocated;
! 571: ngx_uint_t i, n, hash, skip_empty, header_params;
! 572: ngx_buf_t *b;
! 573: ngx_chain_t *cl, *body;
! 574: ngx_list_part_t *part;
! 575: ngx_table_elt_t *header, **ignored;
! 576: ngx_http_script_code_pt code;
! 577: ngx_http_script_engine_t e, le;
! 578: ngx_http_uwsgi_loc_conf_t *uwcf;
! 579: ngx_http_script_len_code_pt lcode;
! 580:
! 581: len = 0;
! 582: header_params = 0;
! 583: ignored = NULL;
! 584:
! 585: uwcf = ngx_http_get_module_loc_conf(r, ngx_http_uwsgi_module);
! 586:
! 587: if (uwcf->params_len) {
! 588: ngx_memzero(&le, sizeof(ngx_http_script_engine_t));
! 589:
! 590: ngx_http_script_flush_no_cacheable_variables(r, uwcf->flushes);
! 591: le.flushed = 1;
! 592:
! 593: le.ip = uwcf->params_len->elts;
! 594: le.request = r;
! 595:
! 596: while (*(uintptr_t *) le.ip) {
! 597:
! 598: lcode = *(ngx_http_script_len_code_pt *) le.ip;
! 599: key_len = lcode(&le);
! 600:
! 601: lcode = *(ngx_http_script_len_code_pt *) le.ip;
! 602: skip_empty = lcode(&le);
! 603:
! 604: for (val_len = 0; *(uintptr_t *) le.ip; val_len += lcode (&le)) {
! 605: lcode = *(ngx_http_script_len_code_pt *) le.ip;
! 606: }
! 607: le.ip += sizeof(uintptr_t);
! 608:
! 609: if (skip_empty && val_len == 0) {
! 610: continue;
! 611: }
! 612:
! 613: len += 2 + key_len + 2 + val_len;
! 614: }
! 615: }
! 616:
! 617: if (uwcf->upstream.pass_request_headers) {
! 618:
! 619: allocated = 0;
! 620: lowcase_key = NULL;
! 621:
! 622: if (uwcf->header_params) {
! 623: n = 0;
! 624: part = &r->headers_in.headers.part;
! 625:
! 626: while (part) {
! 627: n += part->nelts;
! 628: part = part->next;
! 629: }
! 630:
! 631: ignored = ngx_palloc(r->pool, n * sizeof(void *));
! 632: if (ignored == NULL) {
! 633: return NGX_ERROR;
! 634: }
! 635: }
! 636:
! 637: part = &r->headers_in.headers.part;
! 638: header = part->elts;
! 639:
! 640: for (i = 0; /* void */ ; i++) {
! 641:
! 642: if (i >= part->nelts) {
! 643: if (part->next == NULL) {
! 644: break;
! 645: }
! 646:
! 647: part = part->next;
! 648: header = part->elts;
! 649: i = 0;
! 650: }
! 651:
! 652: if (uwcf->header_params) {
! 653: if (allocated < header[i].key.len) {
! 654: allocated = header[i].key.len + 16;
! 655: lowcase_key = ngx_pnalloc(r->pool, allocated);
! 656: if (lowcase_key == NULL) {
! 657: return NGX_ERROR;
! 658: }
! 659: }
! 660:
! 661: hash = 0;
! 662:
! 663: for (n = 0; n < header[i].key.len; n++) {
! 664: ch = header[i].key.data[n];
! 665:
! 666: if (ch >= 'A' && ch <= 'Z') {
! 667: ch |= 0x20;
! 668:
! 669: } else if (ch == '-') {
! 670: ch = '_';
! 671: }
! 672:
! 673: hash = ngx_hash(hash, ch);
! 674: lowcase_key[n] = ch;
! 675: }
! 676:
! 677: if (ngx_hash_find(&uwcf->headers_hash, hash, lowcase_key, n)) {
! 678: ignored[header_params++] = &header[i];
! 679: continue;
! 680: }
! 681: }
! 682:
! 683: len += 2 + sizeof("HTTP_") - 1 + header[i].key.len
! 684: + 2 + header[i].value.len;
! 685: }
! 686: }
! 687:
! 688: len += uwcf->uwsgi_string.len;
! 689:
! 690: #if 0
! 691: /* allow custom uwsgi packet */
! 692: if (len > 0 && len < 2) {
! 693: ngx_log_error (NGX_LOG_ALERT, r->connection->log, 0,
! 694: "uwsgi request is too little: %uz", len);
! 695: return NGX_ERROR;
! 696: }
! 697: #endif
! 698:
! 699: b = ngx_create_temp_buf(r->pool, len + 4);
! 700: if (b == NULL) {
! 701: return NGX_ERROR;
! 702: }
! 703:
! 704: cl = ngx_alloc_chain_link(r->pool);
! 705: if (cl == NULL) {
! 706: return NGX_ERROR;
! 707: }
! 708:
! 709: cl->buf = b;
! 710:
! 711: *b->last++ = (u_char) uwcf->modifier1;
! 712: *b->last++ = (u_char) (len & 0xff);
! 713: *b->last++ = (u_char) ((len >> 8) & 0xff);
! 714: *b->last++ = (u_char) uwcf->modifier2;
! 715:
! 716: if (uwcf->params_len) {
! 717: ngx_memzero(&e, sizeof(ngx_http_script_engine_t));
! 718:
! 719: e.ip = uwcf->params->elts;
! 720: e.pos = b->last;
! 721: e.request = r;
! 722: e.flushed = 1;
! 723:
! 724: le.ip = uwcf->params_len->elts;
! 725:
! 726: while (*(uintptr_t *) le.ip) {
! 727:
! 728: lcode = *(ngx_http_script_len_code_pt *) le.ip;
! 729: key_len = (u_char) lcode (&le);
! 730:
! 731: lcode = *(ngx_http_script_len_code_pt *) le.ip;
! 732: skip_empty = lcode(&le);
! 733:
! 734: for (val_len = 0; *(uintptr_t *) le.ip; val_len += lcode(&le)) {
! 735: lcode = *(ngx_http_script_len_code_pt *) le.ip;
! 736: }
! 737: le.ip += sizeof(uintptr_t);
! 738:
! 739: if (skip_empty && val_len == 0) {
! 740: e.skip = 1;
! 741:
! 742: while (*(uintptr_t *) e.ip) {
! 743: code = *(ngx_http_script_code_pt *) e.ip;
! 744: code((ngx_http_script_engine_t *) &e);
! 745: }
! 746: e.ip += sizeof(uintptr_t);
! 747:
! 748: e.skip = 0;
! 749:
! 750: continue;
! 751: }
! 752:
! 753: *e.pos++ = (u_char) (key_len & 0xff);
! 754: *e.pos++ = (u_char) ((key_len >> 8) & 0xff);
! 755:
! 756: code = *(ngx_http_script_code_pt *) e.ip;
! 757: code((ngx_http_script_engine_t *) & e);
! 758:
! 759: *e.pos++ = (u_char) (val_len & 0xff);
! 760: *e.pos++ = (u_char) ((val_len >> 8) & 0xff);
! 761:
! 762: while (*(uintptr_t *) e.ip) {
! 763: code = *(ngx_http_script_code_pt *) e.ip;
! 764: code((ngx_http_script_engine_t *) & e);
! 765: }
! 766:
! 767: e.ip += sizeof(uintptr_t);
! 768:
! 769: ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
! 770: "uwsgi param: \"%*s: %*s\"",
! 771: key_len, e.pos - (key_len + 2 + val_len),
! 772: val_len, e.pos - val_len);
! 773: }
! 774:
! 775: b->last = e.pos;
! 776: }
! 777:
! 778: if (uwcf->upstream.pass_request_headers) {
! 779:
! 780: part = &r->headers_in.headers.part;
! 781: header = part->elts;
! 782:
! 783: for (i = 0; /* void */ ; i++) {
! 784:
! 785: if (i >= part->nelts) {
! 786: if (part->next == NULL) {
! 787: break;
! 788: }
! 789:
! 790: part = part->next;
! 791: header = part->elts;
! 792: i = 0;
! 793: }
! 794:
! 795: for (n = 0; n < header_params; n++) {
! 796: if (&header[i] == ignored[n]) {
! 797: goto next;
! 798: }
! 799: }
! 800:
! 801: key_len = sizeof("HTTP_") - 1 + header[i].key.len;
! 802: *b->last++ = (u_char) (key_len & 0xff);
! 803: *b->last++ = (u_char) ((key_len >> 8) & 0xff);
! 804:
! 805: b->last = ngx_cpymem(b->last, "HTTP_", sizeof("HTTP_") - 1);
! 806: for (n = 0; n < header[i].key.len; n++) {
! 807: ch = header[i].key.data[n];
! 808:
! 809: if (ch >= 'a' && ch <= 'z') {
! 810: ch &= ~0x20;
! 811:
! 812: } else if (ch == '-') {
! 813: ch = '_';
! 814: }
! 815:
! 816: *b->last++ = ch;
! 817: }
! 818:
! 819: val_len = header[i].value.len;
! 820: *b->last++ = (u_char) (val_len & 0xff);
! 821: *b->last++ = (u_char) ((val_len >> 8) & 0xff);
! 822: b->last = ngx_copy(b->last, header[i].value.data, val_len);
! 823:
! 824: ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
! 825: "uwsgi param: \"%*s: %*s\"",
! 826: key_len, b->last - (key_len + 2 + val_len),
! 827: val_len, b->last - val_len);
! 828: next:
! 829:
! 830: continue;
! 831: }
! 832: }
! 833:
! 834: b->last = ngx_copy(b->last, uwcf->uwsgi_string.data,
! 835: uwcf->uwsgi_string.len);
! 836:
! 837: if (uwcf->upstream.pass_request_body) {
! 838: body = r->upstream->request_bufs;
! 839: r->upstream->request_bufs = cl;
! 840:
! 841: while (body) {
! 842: b = ngx_alloc_buf(r->pool);
! 843: if (b == NULL) {
! 844: return NGX_ERROR;
! 845: }
! 846:
! 847: ngx_memcpy(b, body->buf, sizeof(ngx_buf_t));
! 848:
! 849: cl->next = ngx_alloc_chain_link(r->pool);
! 850: if (cl->next == NULL) {
! 851: return NGX_ERROR;
! 852: }
! 853:
! 854: cl = cl->next;
! 855: cl->buf = b;
! 856:
! 857: body = body->next;
! 858: }
! 859:
! 860: } else {
! 861: r->upstream->request_bufs = cl;
! 862: }
! 863:
! 864: cl->next = NULL;
! 865:
! 866: return NGX_OK;
! 867: }
! 868:
! 869:
! 870: static ngx_int_t
! 871: ngx_http_uwsgi_reinit_request(ngx_http_request_t *r)
! 872: {
! 873: ngx_http_status_t *status;
! 874:
! 875: status = ngx_http_get_module_ctx(r, ngx_http_uwsgi_module);
! 876:
! 877: if (status == NULL) {
! 878: return NGX_OK;
! 879: }
! 880:
! 881: status->code = 0;
! 882: status->count = 0;
! 883: status->start = NULL;
! 884: status->end = NULL;
! 885:
! 886: r->upstream->process_header = ngx_http_uwsgi_process_status_line;
! 887: r->state = 0;
! 888:
! 889: return NGX_OK;
! 890: }
! 891:
! 892:
! 893: static ngx_int_t
! 894: ngx_http_uwsgi_process_status_line(ngx_http_request_t *r)
! 895: {
! 896: size_t len;
! 897: ngx_int_t rc;
! 898: ngx_http_status_t *status;
! 899: ngx_http_upstream_t *u;
! 900:
! 901: status = ngx_http_get_module_ctx(r, ngx_http_uwsgi_module);
! 902:
! 903: if (status == NULL) {
! 904: return NGX_ERROR;
! 905: }
! 906:
! 907: u = r->upstream;
! 908:
! 909: rc = ngx_http_parse_status_line(r, &u->buffer, status);
! 910:
! 911: if (rc == NGX_AGAIN) {
! 912: return rc;
! 913: }
! 914:
! 915: if (rc == NGX_ERROR) {
! 916: u->process_header = ngx_http_uwsgi_process_header;
! 917: return ngx_http_uwsgi_process_header(r);
! 918: }
! 919:
! 920: if (u->state) {
! 921: u->state->status = status->code;
! 922: }
! 923:
! 924: u->headers_in.status_n = status->code;
! 925:
! 926: len = status->end - status->start;
! 927: u->headers_in.status_line.len = len;
! 928:
! 929: u->headers_in.status_line.data = ngx_pnalloc(r->pool, len);
! 930: if (u->headers_in.status_line.data == NULL) {
! 931: return NGX_ERROR;
! 932: }
! 933:
! 934: ngx_memcpy(u->headers_in.status_line.data, status->start, len);
! 935:
! 936: ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
! 937: "http uwsgi status %ui \"%V\"",
! 938: u->headers_in.status_n, &u->headers_in.status_line);
! 939:
! 940: u->process_header = ngx_http_uwsgi_process_header;
! 941:
! 942: return ngx_http_uwsgi_process_header(r);
! 943: }
! 944:
! 945:
! 946: static ngx_int_t
! 947: ngx_http_uwsgi_process_header(ngx_http_request_t *r)
! 948: {
! 949: ngx_str_t *status_line;
! 950: ngx_int_t rc, status;
! 951: ngx_table_elt_t *h;
! 952: ngx_http_upstream_t *u;
! 953: ngx_http_upstream_header_t *hh;
! 954: ngx_http_upstream_main_conf_t *umcf;
! 955:
! 956: umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module);
! 957:
! 958: for ( ;; ) {
! 959:
! 960: rc = ngx_http_parse_header_line(r, &r->upstream->buffer, 1);
! 961:
! 962: if (rc == NGX_OK) {
! 963:
! 964: /* a header line has been parsed successfully */
! 965:
! 966: h = ngx_list_push(&r->upstream->headers_in.headers);
! 967: if (h == NULL) {
! 968: return NGX_ERROR;
! 969: }
! 970:
! 971: h->hash = r->header_hash;
! 972:
! 973: h->key.len = r->header_name_end - r->header_name_start;
! 974: h->value.len = r->header_end - r->header_start;
! 975:
! 976: h->key.data = ngx_pnalloc(r->pool,
! 977: h->key.len + 1 + h->value.len + 1
! 978: + h->key.len);
! 979: if (h->key.data == NULL) {
! 980: return NGX_ERROR;
! 981: }
! 982:
! 983: h->value.data = h->key.data + h->key.len + 1;
! 984: h->lowcase_key = h->key.data + h->key.len + 1 + h->value.len + 1;
! 985:
! 986: ngx_memcpy(h->key.data, r->header_name_start, h->key.len);
! 987: h->key.data[h->key.len] = '\0';
! 988: ngx_memcpy(h->value.data, r->header_start, h->value.len);
! 989: h->value.data[h->value.len] = '\0';
! 990:
! 991: if (h->key.len == r->lowcase_index) {
! 992: ngx_memcpy(h->lowcase_key, r->lowcase_header, h->key.len);
! 993:
! 994: } else {
! 995: ngx_strlow(h->lowcase_key, h->key.data, h->key.len);
! 996: }
! 997:
! 998: hh = ngx_hash_find(&umcf->headers_in_hash, h->hash,
! 999: h->lowcase_key, h->key.len);
! 1000:
! 1001: if (hh && hh->handler(r, h, hh->offset) != NGX_OK) {
! 1002: return NGX_ERROR;
! 1003: }
! 1004:
! 1005: ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
! 1006: "http uwsgi header: \"%V: %V\"", &h->key, &h->value);
! 1007:
! 1008: continue;
! 1009: }
! 1010:
! 1011: if (rc == NGX_HTTP_PARSE_HEADER_DONE) {
! 1012:
! 1013: /* a whole header has been parsed successfully */
! 1014:
! 1015: ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
! 1016: "http uwsgi header done");
! 1017:
! 1018: u = r->upstream;
! 1019:
! 1020: if (u->headers_in.status_n) {
! 1021: goto done;
! 1022: }
! 1023:
! 1024: if (u->headers_in.status) {
! 1025: status_line = &u->headers_in.status->value;
! 1026:
! 1027: status = ngx_atoi(status_line->data, 3);
! 1028: if (status == NGX_ERROR) {
! 1029: ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
! 1030: "upstream sent invalid status \"%V\"",
! 1031: status_line);
! 1032: return NGX_HTTP_UPSTREAM_INVALID_HEADER;
! 1033: }
! 1034:
! 1035: u->headers_in.status_n = status;
! 1036: u->headers_in.status_line = *status_line;
! 1037:
! 1038: } else if (u->headers_in.location) {
! 1039: u->headers_in.status_n = 302;
! 1040: ngx_str_set(&u->headers_in.status_line,
! 1041: "302 Moved Temporarily");
! 1042:
! 1043: } else {
! 1044: u->headers_in.status_n = 200;
! 1045: ngx_str_set(&u->headers_in.status_line, "200 OK");
! 1046: }
! 1047:
! 1048: if (u->state) {
! 1049: u->state->status = u->headers_in.status_n;
! 1050: }
! 1051:
! 1052: done:
! 1053:
! 1054: if (u->headers_in.status_n == NGX_HTTP_SWITCHING_PROTOCOLS
! 1055: && r->headers_in.upgrade)
! 1056: {
! 1057: u->upgrade = 1;
! 1058: }
! 1059:
! 1060: return NGX_OK;
! 1061: }
! 1062:
! 1063: if (rc == NGX_AGAIN) {
! 1064: return NGX_AGAIN;
! 1065: }
! 1066:
! 1067: /* there was error while a header line parsing */
! 1068:
! 1069: ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
! 1070: "upstream sent invalid header");
! 1071:
! 1072: return NGX_HTTP_UPSTREAM_INVALID_HEADER;
! 1073: }
! 1074: }
! 1075:
! 1076:
! 1077: static void
! 1078: ngx_http_uwsgi_abort_request(ngx_http_request_t *r)
! 1079: {
! 1080: ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
! 1081: "abort http uwsgi request");
! 1082:
! 1083: return;
! 1084: }
! 1085:
! 1086:
! 1087: static void
! 1088: ngx_http_uwsgi_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
! 1089: {
! 1090: ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
! 1091: "finalize http uwsgi request");
! 1092:
! 1093: return;
! 1094: }
! 1095:
! 1096:
! 1097: static void *
! 1098: ngx_http_uwsgi_create_loc_conf(ngx_conf_t *cf)
! 1099: {
! 1100: ngx_http_uwsgi_loc_conf_t *conf;
! 1101:
! 1102: conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_uwsgi_loc_conf_t));
! 1103: if (conf == NULL) {
! 1104: return NULL;
! 1105: }
! 1106:
! 1107: conf->modifier1 = NGX_CONF_UNSET_UINT;
! 1108: conf->modifier2 = NGX_CONF_UNSET_UINT;
! 1109:
! 1110: conf->upstream.store = NGX_CONF_UNSET;
! 1111: conf->upstream.store_access = NGX_CONF_UNSET_UINT;
! 1112: conf->upstream.buffering = NGX_CONF_UNSET;
! 1113: conf->upstream.ignore_client_abort = NGX_CONF_UNSET;
! 1114:
! 1115: conf->upstream.local = NGX_CONF_UNSET_PTR;
! 1116:
! 1117: conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC;
! 1118: conf->upstream.send_timeout = NGX_CONF_UNSET_MSEC;
! 1119: conf->upstream.read_timeout = NGX_CONF_UNSET_MSEC;
! 1120:
! 1121: conf->upstream.send_lowat = NGX_CONF_UNSET_SIZE;
! 1122: conf->upstream.buffer_size = NGX_CONF_UNSET_SIZE;
! 1123:
! 1124: conf->upstream.busy_buffers_size_conf = NGX_CONF_UNSET_SIZE;
! 1125: conf->upstream.max_temp_file_size_conf = NGX_CONF_UNSET_SIZE;
! 1126: conf->upstream.temp_file_write_size_conf = NGX_CONF_UNSET_SIZE;
! 1127:
! 1128: conf->upstream.pass_request_headers = NGX_CONF_UNSET;
! 1129: conf->upstream.pass_request_body = NGX_CONF_UNSET;
! 1130:
! 1131: #if (NGX_HTTP_CACHE)
! 1132: conf->upstream.cache = NGX_CONF_UNSET_PTR;
! 1133: conf->upstream.cache_min_uses = NGX_CONF_UNSET_UINT;
! 1134: conf->upstream.cache_bypass = NGX_CONF_UNSET_PTR;
! 1135: conf->upstream.no_cache = NGX_CONF_UNSET_PTR;
! 1136: conf->upstream.cache_valid = NGX_CONF_UNSET_PTR;
! 1137: conf->upstream.cache_lock = NGX_CONF_UNSET;
! 1138: conf->upstream.cache_lock_timeout = NGX_CONF_UNSET_MSEC;
! 1139: #endif
! 1140:
! 1141: conf->upstream.hide_headers = NGX_CONF_UNSET_PTR;
! 1142: conf->upstream.pass_headers = NGX_CONF_UNSET_PTR;
! 1143:
! 1144: conf->upstream.intercept_errors = NGX_CONF_UNSET;
! 1145:
! 1146: /* "uwsgi_cyclic_temp_file" is disabled */
! 1147: conf->upstream.cyclic_temp_file = 0;
! 1148:
! 1149: conf->upstream.change_buffering = 1;
! 1150:
! 1151: ngx_str_set(&conf->upstream.module, "uwsgi");
! 1152:
! 1153: return conf;
! 1154: }
! 1155:
! 1156:
! 1157: static char *
! 1158: ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
! 1159: {
! 1160: ngx_http_uwsgi_loc_conf_t *prev = parent;
! 1161: ngx_http_uwsgi_loc_conf_t *conf = child;
! 1162:
! 1163: size_t size;
! 1164: ngx_hash_init_t hash;
! 1165: ngx_http_core_loc_conf_t *clcf;
! 1166:
! 1167: if (conf->upstream.store != 0) {
! 1168: ngx_conf_merge_value(conf->upstream.store, prev->upstream.store, 0);
! 1169:
! 1170: if (conf->upstream.store_lengths == NULL) {
! 1171: conf->upstream.store_lengths = prev->upstream.store_lengths;
! 1172: conf->upstream.store_values = prev->upstream.store_values;
! 1173: }
! 1174: }
! 1175:
! 1176: ngx_conf_merge_uint_value(conf->upstream.store_access,
! 1177: prev->upstream.store_access, 0600);
! 1178:
! 1179: ngx_conf_merge_value(conf->upstream.buffering,
! 1180: prev->upstream.buffering, 1);
! 1181:
! 1182: ngx_conf_merge_value(conf->upstream.ignore_client_abort,
! 1183: prev->upstream.ignore_client_abort, 0);
! 1184:
! 1185: ngx_conf_merge_ptr_value(conf->upstream.local,
! 1186: prev->upstream.local, NULL);
! 1187:
! 1188: ngx_conf_merge_msec_value(conf->upstream.connect_timeout,
! 1189: prev->upstream.connect_timeout, 60000);
! 1190:
! 1191: ngx_conf_merge_msec_value(conf->upstream.send_timeout,
! 1192: prev->upstream.send_timeout, 60000);
! 1193:
! 1194: ngx_conf_merge_msec_value(conf->upstream.read_timeout,
! 1195: prev->upstream.read_timeout, 60000);
! 1196:
! 1197: ngx_conf_merge_size_value(conf->upstream.send_lowat,
! 1198: prev->upstream.send_lowat, 0);
! 1199:
! 1200: ngx_conf_merge_size_value(conf->upstream.buffer_size,
! 1201: prev->upstream.buffer_size,
! 1202: (size_t) ngx_pagesize);
! 1203:
! 1204:
! 1205: ngx_conf_merge_bufs_value(conf->upstream.bufs, prev->upstream.bufs,
! 1206: 8, ngx_pagesize);
! 1207:
! 1208: if (conf->upstream.bufs.num < 2) {
! 1209: ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
! 1210: "there must be at least 2 \"uwsgi_buffers\"");
! 1211: return NGX_CONF_ERROR;
! 1212: }
! 1213:
! 1214:
! 1215: size = conf->upstream.buffer_size;
! 1216: if (size < conf->upstream.bufs.size) {
! 1217: size = conf->upstream.bufs.size;
! 1218: }
! 1219:
! 1220:
! 1221: ngx_conf_merge_size_value(conf->upstream.busy_buffers_size_conf,
! 1222: prev->upstream.busy_buffers_size_conf,
! 1223: NGX_CONF_UNSET_SIZE);
! 1224:
! 1225: if (conf->upstream.busy_buffers_size_conf == NGX_CONF_UNSET_SIZE) {
! 1226: conf->upstream.busy_buffers_size = 2 * size;
! 1227: } else {
! 1228: conf->upstream.busy_buffers_size =
! 1229: conf->upstream.busy_buffers_size_conf;
! 1230: }
! 1231:
! 1232: if (conf->upstream.busy_buffers_size < size) {
! 1233: ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
! 1234: "\"uwsgi_busy_buffers_size\" must be equal to or greater "
! 1235: "than the maximum of the value of \"uwsgi_buffer_size\" and "
! 1236: "one of the \"uwsgi_buffers\"");
! 1237:
! 1238: return NGX_CONF_ERROR;
! 1239: }
! 1240:
! 1241: if (conf->upstream.busy_buffers_size
! 1242: > (conf->upstream.bufs.num - 1) * conf->upstream.bufs.size)
! 1243: {
! 1244: ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
! 1245: "\"uwsgi_busy_buffers_size\" must be less than "
! 1246: "the size of all \"uwsgi_buffers\" minus one buffer");
! 1247:
! 1248: return NGX_CONF_ERROR;
! 1249: }
! 1250:
! 1251:
! 1252: ngx_conf_merge_size_value(conf->upstream.temp_file_write_size_conf,
! 1253: prev->upstream.temp_file_write_size_conf,
! 1254: NGX_CONF_UNSET_SIZE);
! 1255:
! 1256: if (conf->upstream.temp_file_write_size_conf == NGX_CONF_UNSET_SIZE) {
! 1257: conf->upstream.temp_file_write_size = 2 * size;
! 1258: } else {
! 1259: conf->upstream.temp_file_write_size =
! 1260: conf->upstream.temp_file_write_size_conf;
! 1261: }
! 1262:
! 1263: if (conf->upstream.temp_file_write_size < size) {
! 1264: ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
! 1265: "\"uwsgi_temp_file_write_size\" must be equal to or greater than "
! 1266: "the maximum of the value of \"uwsgi_buffer_size\" and "
! 1267: "one of the \"uwsgi_buffers\"");
! 1268:
! 1269: return NGX_CONF_ERROR;
! 1270: }
! 1271:
! 1272:
! 1273: ngx_conf_merge_size_value(conf->upstream.max_temp_file_size_conf,
! 1274: prev->upstream.max_temp_file_size_conf,
! 1275: NGX_CONF_UNSET_SIZE);
! 1276:
! 1277: if (conf->upstream.max_temp_file_size_conf == NGX_CONF_UNSET_SIZE) {
! 1278: conf->upstream.max_temp_file_size = 1024 * 1024 * 1024;
! 1279: } else {
! 1280: conf->upstream.max_temp_file_size =
! 1281: conf->upstream.max_temp_file_size_conf;
! 1282: }
! 1283:
! 1284: if (conf->upstream.max_temp_file_size != 0
! 1285: && conf->upstream.max_temp_file_size < size) {
! 1286: ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
! 1287: "\"uwsgi_max_temp_file_size\" must be equal to zero to disable "
! 1288: "temporary files usage or must be equal to or greater than "
! 1289: "the maximum of the value of \"uwsgi_buffer_size\" and "
! 1290: "one of the \"uwsgi_buffers\"");
! 1291:
! 1292: return NGX_CONF_ERROR;
! 1293: }
! 1294:
! 1295:
! 1296: ngx_conf_merge_bitmask_value(conf->upstream.ignore_headers,
! 1297: prev->upstream.ignore_headers,
! 1298: NGX_CONF_BITMASK_SET);
! 1299:
! 1300:
! 1301: ngx_conf_merge_bitmask_value(conf->upstream.next_upstream,
! 1302: prev->upstream.next_upstream,
! 1303: (NGX_CONF_BITMASK_SET
! 1304: |NGX_HTTP_UPSTREAM_FT_ERROR
! 1305: |NGX_HTTP_UPSTREAM_FT_TIMEOUT));
! 1306:
! 1307: if (conf->upstream.next_upstream & NGX_HTTP_UPSTREAM_FT_OFF) {
! 1308: conf->upstream.next_upstream = NGX_CONF_BITMASK_SET
! 1309: |NGX_HTTP_UPSTREAM_FT_OFF;
! 1310: }
! 1311:
! 1312: if (ngx_conf_merge_path_value(cf, &conf->upstream.temp_path,
! 1313: prev->upstream.temp_path,
! 1314: &ngx_http_uwsgi_temp_path)
! 1315: != NGX_OK)
! 1316: {
! 1317: return NGX_CONF_ERROR;
! 1318: }
! 1319:
! 1320: #if (NGX_HTTP_CACHE)
! 1321:
! 1322: ngx_conf_merge_ptr_value(conf->upstream.cache,
! 1323: prev->upstream.cache, NULL);
! 1324:
! 1325: if (conf->upstream.cache && conf->upstream.cache->data == NULL) {
! 1326: ngx_shm_zone_t *shm_zone;
! 1327:
! 1328: shm_zone = conf->upstream.cache;
! 1329:
! 1330: ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
! 1331: "\"uwsgi_cache\" zone \"%V\" is unknown",
! 1332: &shm_zone->shm.name);
! 1333:
! 1334: return NGX_CONF_ERROR;
! 1335: }
! 1336:
! 1337: ngx_conf_merge_uint_value(conf->upstream.cache_min_uses,
! 1338: prev->upstream.cache_min_uses, 1);
! 1339:
! 1340: ngx_conf_merge_bitmask_value(conf->upstream.cache_use_stale,
! 1341: prev->upstream.cache_use_stale,
! 1342: (NGX_CONF_BITMASK_SET
! 1343: |NGX_HTTP_UPSTREAM_FT_OFF));
! 1344:
! 1345: if (conf->upstream.cache_use_stale & NGX_HTTP_UPSTREAM_FT_OFF) {
! 1346: conf->upstream.cache_use_stale = NGX_CONF_BITMASK_SET
! 1347: |NGX_HTTP_UPSTREAM_FT_OFF;
! 1348: }
! 1349:
! 1350: if (conf->upstream.cache_use_stale & NGX_HTTP_UPSTREAM_FT_ERROR) {
! 1351: conf->upstream.cache_use_stale |= NGX_HTTP_UPSTREAM_FT_NOLIVE;
! 1352: }
! 1353:
! 1354: if (conf->upstream.cache_methods == 0) {
! 1355: conf->upstream.cache_methods = prev->upstream.cache_methods;
! 1356: }
! 1357:
! 1358: conf->upstream.cache_methods |= NGX_HTTP_GET|NGX_HTTP_HEAD;
! 1359:
! 1360: ngx_conf_merge_ptr_value(conf->upstream.cache_bypass,
! 1361: prev->upstream.cache_bypass, NULL);
! 1362:
! 1363: ngx_conf_merge_ptr_value(conf->upstream.no_cache,
! 1364: prev->upstream.no_cache, NULL);
! 1365:
! 1366: ngx_conf_merge_ptr_value(conf->upstream.cache_valid,
! 1367: prev->upstream.cache_valid, NULL);
! 1368:
! 1369: if (conf->cache_key.value.data == NULL) {
! 1370: conf->cache_key = prev->cache_key;
! 1371: }
! 1372:
! 1373: ngx_conf_merge_value(conf->upstream.cache_lock,
! 1374: prev->upstream.cache_lock, 0);
! 1375:
! 1376: ngx_conf_merge_msec_value(conf->upstream.cache_lock_timeout,
! 1377: prev->upstream.cache_lock_timeout, 5000);
! 1378:
! 1379: #endif
! 1380:
! 1381: ngx_conf_merge_value(conf->upstream.pass_request_headers,
! 1382: prev->upstream.pass_request_headers, 1);
! 1383: ngx_conf_merge_value(conf->upstream.pass_request_body,
! 1384: prev->upstream.pass_request_body, 1);
! 1385:
! 1386: ngx_conf_merge_value(conf->upstream.intercept_errors,
! 1387: prev->upstream.intercept_errors, 0);
! 1388:
! 1389: ngx_conf_merge_str_value(conf->uwsgi_string, prev->uwsgi_string, "");
! 1390:
! 1391: hash.max_size = 512;
! 1392: hash.bucket_size = ngx_align(64, ngx_cacheline_size);
! 1393: hash.name = "uwsgi_hide_headers_hash";
! 1394:
! 1395: if (ngx_http_upstream_hide_headers_hash(cf, &conf->upstream,
! 1396: &prev->upstream, ngx_http_uwsgi_hide_headers, &hash)
! 1397: != NGX_OK)
! 1398: {
! 1399: return NGX_CONF_ERROR;
! 1400: }
! 1401:
! 1402: if (conf->upstream.upstream == NULL) {
! 1403: conf->upstream.upstream = prev->upstream.upstream;
! 1404: }
! 1405:
! 1406: if (conf->uwsgi_lengths == NULL) {
! 1407: conf->uwsgi_lengths = prev->uwsgi_lengths;
! 1408: conf->uwsgi_values = prev->uwsgi_values;
! 1409: }
! 1410:
! 1411: if (conf->upstream.upstream || conf->uwsgi_lengths) {
! 1412: clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
! 1413: if (clcf->handler == NULL && clcf->lmt_excpt) {
! 1414: clcf->handler = ngx_http_uwsgi_handler;
! 1415: }
! 1416: }
! 1417:
! 1418: ngx_conf_merge_uint_value(conf->modifier1, prev->modifier1, 0);
! 1419: ngx_conf_merge_uint_value(conf->modifier2, prev->modifier2, 0);
! 1420:
! 1421: if (ngx_http_uwsgi_merge_params(cf, conf, prev) != NGX_OK) {
! 1422: return NGX_CONF_ERROR;
! 1423: }
! 1424:
! 1425: return NGX_CONF_OK;
! 1426: }
! 1427:
! 1428:
! 1429: static ngx_int_t
! 1430: ngx_http_uwsgi_merge_params(ngx_conf_t *cf, ngx_http_uwsgi_loc_conf_t *conf,
! 1431: ngx_http_uwsgi_loc_conf_t *prev)
! 1432: {
! 1433: u_char *p;
! 1434: size_t size;
! 1435: uintptr_t *code;
! 1436: ngx_uint_t i, nsrc;
! 1437: ngx_array_t headers_names;
! 1438: #if (NGX_HTTP_CACHE)
! 1439: ngx_array_t params_merged;
! 1440: #endif
! 1441: ngx_hash_key_t *hk;
! 1442: ngx_hash_init_t hash;
! 1443: ngx_http_upstream_param_t *src;
! 1444: ngx_http_script_compile_t sc;
! 1445: ngx_http_script_copy_code_t *copy;
! 1446:
! 1447: if (conf->params_source == NULL) {
! 1448: conf->params_source = prev->params_source;
! 1449:
! 1450: if (prev->headers_hash.buckets
! 1451: #if (NGX_HTTP_CACHE)
! 1452: && ((conf->upstream.cache == NULL)
! 1453: == (prev->upstream.cache == NULL))
! 1454: #endif
! 1455: )
! 1456: {
! 1457: conf->flushes = prev->flushes;
! 1458: conf->params_len = prev->params_len;
! 1459: conf->params = prev->params;
! 1460: conf->headers_hash = prev->headers_hash;
! 1461: conf->header_params = prev->header_params;
! 1462:
! 1463: return NGX_OK;
! 1464: }
! 1465: }
! 1466:
! 1467: if (conf->params_source == NULL
! 1468: #if (NGX_HTTP_CACHE)
! 1469: && (conf->upstream.cache == NULL)
! 1470: #endif
! 1471: )
! 1472: {
! 1473: conf->headers_hash.buckets = (void *) 1;
! 1474: return NGX_OK;
! 1475: }
! 1476:
! 1477: conf->params_len = ngx_array_create(cf->pool, 64, 1);
! 1478: if (conf->params_len == NULL) {
! 1479: return NGX_ERROR;
! 1480: }
! 1481:
! 1482: conf->params = ngx_array_create(cf->pool, 512, 1);
! 1483: if (conf->params == NULL) {
! 1484: return NGX_ERROR;
! 1485: }
! 1486:
! 1487: if (ngx_array_init(&headers_names, cf->temp_pool, 4, sizeof(ngx_hash_key_t))
! 1488: != NGX_OK)
! 1489: {
! 1490: return NGX_ERROR;
! 1491: }
! 1492:
! 1493: if (conf->params_source) {
! 1494: src = conf->params_source->elts;
! 1495: nsrc = conf->params_source->nelts;
! 1496:
! 1497: } else {
! 1498: src = NULL;
! 1499: nsrc = 0;
! 1500: }
! 1501:
! 1502: #if (NGX_HTTP_CACHE)
! 1503:
! 1504: if (conf->upstream.cache) {
! 1505: ngx_keyval_t *h;
! 1506: ngx_http_upstream_param_t *s;
! 1507:
! 1508: if (ngx_array_init(¶ms_merged, cf->temp_pool, 4,
! 1509: sizeof(ngx_http_upstream_param_t))
! 1510: != NGX_OK)
! 1511: {
! 1512: return NGX_ERROR;
! 1513: }
! 1514:
! 1515: for (i = 0; i < nsrc; i++) {
! 1516:
! 1517: s = ngx_array_push(¶ms_merged);
! 1518: if (s == NULL) {
! 1519: return NGX_ERROR;
! 1520: }
! 1521:
! 1522: *s = src[i];
! 1523: }
! 1524:
! 1525: h = ngx_http_uwsgi_cache_headers;
! 1526:
! 1527: while (h->key.len) {
! 1528:
! 1529: src = params_merged.elts;
! 1530: nsrc = params_merged.nelts;
! 1531:
! 1532: for (i = 0; i < nsrc; i++) {
! 1533: if (ngx_strcasecmp(h->key.data, src[i].key.data) == 0) {
! 1534: goto next;
! 1535: }
! 1536: }
! 1537:
! 1538: s = ngx_array_push(¶ms_merged);
! 1539: if (s == NULL) {
! 1540: return NGX_ERROR;
! 1541: }
! 1542:
! 1543: s->key = h->key;
! 1544: s->value = h->value;
! 1545: s->skip_empty = 0;
! 1546:
! 1547: next:
! 1548:
! 1549: h++;
! 1550: }
! 1551:
! 1552: src = params_merged.elts;
! 1553: nsrc = params_merged.nelts;
! 1554: }
! 1555:
! 1556: #endif
! 1557:
! 1558: for (i = 0; i < nsrc; i++) {
! 1559:
! 1560: if (src[i].key.len > sizeof("HTTP_") - 1
! 1561: && ngx_strncmp(src[i].key.data, "HTTP_", sizeof("HTTP_") - 1) == 0)
! 1562: {
! 1563: hk = ngx_array_push(&headers_names);
! 1564: if (hk == NULL) {
! 1565: return NGX_ERROR;
! 1566: }
! 1567:
! 1568: hk->key.len = src[i].key.len - 5;
! 1569: hk->key.data = src[i].key.data + 5;
! 1570: hk->key_hash = ngx_hash_key_lc(hk->key.data, hk->key.len);
! 1571: hk->value = (void *) 1;
! 1572:
! 1573: if (src[i].value.len == 0) {
! 1574: continue;
! 1575: }
! 1576: }
! 1577:
! 1578: copy = ngx_array_push_n(conf->params_len,
! 1579: sizeof(ngx_http_script_copy_code_t));
! 1580: if (copy == NULL) {
! 1581: return NGX_ERROR;
! 1582: }
! 1583:
! 1584: copy->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code;
! 1585: copy->len = src[i].key.len;
! 1586:
! 1587: copy = ngx_array_push_n(conf->params_len,
! 1588: sizeof(ngx_http_script_copy_code_t));
! 1589: if (copy == NULL) {
! 1590: return NGX_ERROR;
! 1591: }
! 1592:
! 1593: copy->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code;
! 1594: copy->len = src[i].skip_empty;
! 1595:
! 1596:
! 1597: size = (sizeof(ngx_http_script_copy_code_t)
! 1598: + src[i].key.len + sizeof(uintptr_t) - 1)
! 1599: & ~(sizeof(uintptr_t) - 1);
! 1600:
! 1601: copy = ngx_array_push_n(conf->params, size);
! 1602: if (copy == NULL) {
! 1603: return NGX_ERROR;
! 1604: }
! 1605:
! 1606: copy->code = ngx_http_script_copy_code;
! 1607: copy->len = src[i].key.len;
! 1608:
! 1609: p = (u_char *) copy + sizeof(ngx_http_script_copy_code_t);
! 1610: ngx_memcpy(p, src[i].key.data, src[i].key.len);
! 1611:
! 1612:
! 1613: ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
! 1614:
! 1615: sc.cf = cf;
! 1616: sc.source = &src[i].value;
! 1617: sc.flushes = &conf->flushes;
! 1618: sc.lengths = &conf->params_len;
! 1619: sc.values = &conf->params;
! 1620:
! 1621: if (ngx_http_script_compile(&sc) != NGX_OK) {
! 1622: return NGX_ERROR;
! 1623: }
! 1624:
! 1625: code = ngx_array_push_n(conf->params_len, sizeof(uintptr_t));
! 1626: if (code == NULL) {
! 1627: return NGX_ERROR;
! 1628: }
! 1629:
! 1630: *code = (uintptr_t) NULL;
! 1631:
! 1632:
! 1633: code = ngx_array_push_n(conf->params, sizeof(uintptr_t));
! 1634: if (code == NULL) {
! 1635: return NGX_ERROR;
! 1636: }
! 1637:
! 1638: *code = (uintptr_t) NULL;
! 1639: }
! 1640:
! 1641: code = ngx_array_push_n(conf->params_len, sizeof(uintptr_t));
! 1642: if (code == NULL) {
! 1643: return NGX_ERROR;
! 1644: }
! 1645:
! 1646: *code = (uintptr_t) NULL;
! 1647:
! 1648: conf->header_params = headers_names.nelts;
! 1649:
! 1650: hash.hash = &conf->headers_hash;
! 1651: hash.key = ngx_hash_key_lc;
! 1652: hash.max_size = 512;
! 1653: hash.bucket_size = 64;
! 1654: hash.name = "uwsgi_params_hash";
! 1655: hash.pool = cf->pool;
! 1656: hash.temp_pool = NULL;
! 1657:
! 1658: return ngx_hash_init(&hash, headers_names.elts, headers_names.nelts);
! 1659: }
! 1660:
! 1661:
! 1662: static char *
! 1663: ngx_http_uwsgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
! 1664: {
! 1665: ngx_http_uwsgi_loc_conf_t *uwcf = conf;
! 1666:
! 1667: ngx_url_t u;
! 1668: ngx_str_t *value, *url;
! 1669: ngx_uint_t n;
! 1670: ngx_http_core_loc_conf_t *clcf;
! 1671: ngx_http_script_compile_t sc;
! 1672:
! 1673: if (uwcf->upstream.upstream || uwcf->uwsgi_lengths) {
! 1674: return "is duplicate";
! 1675: }
! 1676:
! 1677: clcf = ngx_http_conf_get_module_loc_conf (cf, ngx_http_core_module);
! 1678: clcf->handler = ngx_http_uwsgi_handler;
! 1679:
! 1680: value = cf->args->elts;
! 1681:
! 1682: url = &value[1];
! 1683:
! 1684: n = ngx_http_script_variables_count(url);
! 1685:
! 1686: if (n) {
! 1687:
! 1688: ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
! 1689:
! 1690: sc.cf = cf;
! 1691: sc.source = url;
! 1692: sc.lengths = &uwcf->uwsgi_lengths;
! 1693: sc.values = &uwcf->uwsgi_values;
! 1694: sc.variables = n;
! 1695: sc.complete_lengths = 1;
! 1696: sc.complete_values = 1;
! 1697:
! 1698: if (ngx_http_script_compile(&sc) != NGX_OK) {
! 1699: return NGX_CONF_ERROR;
! 1700: }
! 1701:
! 1702: return NGX_CONF_OK;
! 1703: }
! 1704:
! 1705: ngx_memzero(&u, sizeof(ngx_url_t));
! 1706:
! 1707: u.url = value[1];
! 1708: u.no_resolve = 1;
! 1709:
! 1710: uwcf->upstream.upstream = ngx_http_upstream_add(cf, &u, 0);
! 1711: if (uwcf->upstream.upstream == NULL) {
! 1712: return NGX_CONF_ERROR;
! 1713: }
! 1714:
! 1715: if (clcf->name.data[clcf->name.len - 1] == '/') {
! 1716: clcf->auto_redirect = 1;
! 1717: }
! 1718:
! 1719: return NGX_CONF_OK;
! 1720: }
! 1721:
! 1722:
! 1723: static char *
! 1724: ngx_http_uwsgi_store(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
! 1725: {
! 1726: ngx_http_uwsgi_loc_conf_t *uwcf = conf;
! 1727:
! 1728: ngx_str_t *value;
! 1729: ngx_http_script_compile_t sc;
! 1730:
! 1731: if (uwcf->upstream.store != NGX_CONF_UNSET || uwcf->upstream.store_lengths)
! 1732: {
! 1733: return "is duplicate";
! 1734: }
! 1735:
! 1736: value = cf->args->elts;
! 1737:
! 1738: if (ngx_strcmp(value[1].data, "off") == 0) {
! 1739: uwcf->upstream.store = 0;
! 1740: return NGX_CONF_OK;
! 1741: }
! 1742:
! 1743: #if (NGX_HTTP_CACHE)
! 1744:
! 1745: if (uwcf->upstream.cache != NGX_CONF_UNSET_PTR
! 1746: && uwcf->upstream.cache != NULL)
! 1747: {
! 1748: return "is incompatible with \"uwsgi_cache\"";
! 1749: }
! 1750:
! 1751: #endif
! 1752:
! 1753: if (ngx_strcmp(value[1].data, "on") == 0) {
! 1754: uwcf->upstream.store = 1;
! 1755: return NGX_CONF_OK;
! 1756: }
! 1757:
! 1758: /* include the terminating '\0' into script */
! 1759: value[1].len++;
! 1760:
! 1761: ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
! 1762:
! 1763: sc.cf = cf;
! 1764: sc.source = &value[1];
! 1765: sc.lengths = &uwcf->upstream.store_lengths;
! 1766: sc.values = &uwcf->upstream.store_values;
! 1767: sc.variables = ngx_http_script_variables_count(&value[1]);;
! 1768: sc.complete_lengths = 1;
! 1769: sc.complete_values = 1;
! 1770:
! 1771: if (ngx_http_script_compile(&sc) != NGX_OK) {
! 1772: return NGX_CONF_ERROR;
! 1773: }
! 1774:
! 1775: return NGX_CONF_OK;
! 1776: }
! 1777:
! 1778:
! 1779: #if (NGX_HTTP_CACHE)
! 1780:
! 1781: static char *
! 1782: ngx_http_uwsgi_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
! 1783: {
! 1784: ngx_http_uwsgi_loc_conf_t *uwcf = conf;
! 1785:
! 1786: ngx_str_t *value;
! 1787:
! 1788: value = cf->args->elts;
! 1789:
! 1790: if (uwcf->upstream.cache != NGX_CONF_UNSET_PTR) {
! 1791: return "is duplicate";
! 1792: }
! 1793:
! 1794: if (ngx_strcmp(value[1].data, "off") == 0) {
! 1795: uwcf->upstream.cache = NULL;
! 1796: return NGX_CONF_OK;
! 1797: }
! 1798:
! 1799: if (uwcf->upstream.store > 0 || uwcf->upstream.store_lengths) {
! 1800: return "is incompatible with \"uwsgi_store\"";
! 1801: }
! 1802:
! 1803: uwcf->upstream.cache = ngx_shared_memory_add(cf, &value[1], 0,
! 1804: &ngx_http_uwsgi_module);
! 1805: if (uwcf->upstream.cache == NULL) {
! 1806: return NGX_CONF_ERROR;
! 1807: }
! 1808:
! 1809: return NGX_CONF_OK;
! 1810: }
! 1811:
! 1812:
! 1813: static char *
! 1814: ngx_http_uwsgi_cache_key(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
! 1815: {
! 1816: ngx_http_uwsgi_loc_conf_t *uwcf = conf;
! 1817:
! 1818: ngx_str_t *value;
! 1819: ngx_http_compile_complex_value_t ccv;
! 1820:
! 1821: value = cf->args->elts;
! 1822:
! 1823: if (uwcf->cache_key.value.data) {
! 1824: return "is duplicate";
! 1825: }
! 1826:
! 1827: ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
! 1828:
! 1829: ccv.cf = cf;
! 1830: ccv.value = &value[1];
! 1831: ccv.complex_value = &uwcf->cache_key;
! 1832:
! 1833: if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
! 1834: return NGX_CONF_ERROR;
! 1835: }
! 1836:
! 1837: return NGX_CONF_OK;
! 1838: }
! 1839:
! 1840: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>