comparison src/http/modules/ngx_http_proxy_module.c @ 5908:f8e80f8c7fc7

Upstream: moved header lists to separate structures. No functional changes.
author Roman Arutyunyan <arut@nginx.com>
date Wed, 19 Nov 2014 17:33:22 +0300
parents 195561ef367f
children 8d0cf26ce071
comparison
equal deleted inserted replaced
5907:195561ef367f 5908:f8e80f8c7fc7
38 ngx_str_t uri; 38 ngx_str_t uri;
39 } ngx_http_proxy_vars_t; 39 } ngx_http_proxy_vars_t;
40 40
41 41
42 typedef struct { 42 typedef struct {
43 ngx_array_t *flushes;
44 ngx_array_t *lengths;
45 ngx_array_t *values;
46 ngx_hash_t hash;
47 } ngx_http_proxy_headers_t;
48
49
50 typedef struct {
43 ngx_http_upstream_conf_t upstream; 51 ngx_http_upstream_conf_t upstream;
44 52
45 ngx_array_t *flushes; 53 ngx_array_t *body_flushes;
46 ngx_array_t *body_set_len; 54 ngx_array_t *body_set_len;
47 ngx_array_t *body_set; 55 ngx_array_t *body_set;
48 ngx_array_t *headers_set_len; 56
49 ngx_array_t *headers_set; 57 ngx_http_proxy_headers_t headers;
50 ngx_hash_t headers_set_hash;
51
52 ngx_array_t *headers_source; 58 ngx_array_t *headers_source;
53 59
54 ngx_array_t *proxy_lengths; 60 ngx_array_t *proxy_lengths;
55 ngx_array_t *proxy_values; 61 ngx_array_t *proxy_values;
56 62
145 static ngx_int_t ngx_http_proxy_add_variables(ngx_conf_t *cf); 151 static ngx_int_t ngx_http_proxy_add_variables(ngx_conf_t *cf);
146 static void *ngx_http_proxy_create_loc_conf(ngx_conf_t *cf); 152 static void *ngx_http_proxy_create_loc_conf(ngx_conf_t *cf);
147 static char *ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, 153 static char *ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf,
148 void *parent, void *child); 154 void *parent, void *child);
149 static ngx_int_t ngx_http_proxy_init_headers(ngx_conf_t *cf, 155 static ngx_int_t ngx_http_proxy_init_headers(ngx_conf_t *cf,
150 ngx_http_proxy_loc_conf_t *conf); 156 ngx_http_proxy_loc_conf_t *conf, ngx_http_proxy_headers_t *headers);
151 157
152 static char *ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, 158 static char *ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd,
153 void *conf); 159 void *conf);
154 static char *ngx_http_proxy_redirect(ngx_conf_t *cf, ngx_command_t *cmd, 160 static char *ngx_http_proxy_redirect(ngx_conf_t *cf, ngx_command_t *cmd,
155 void *conf); 161 void *conf);
1078 ngx_list_part_t *part; 1084 ngx_list_part_t *part;
1079 ngx_table_elt_t *header; 1085 ngx_table_elt_t *header;
1080 ngx_http_upstream_t *u; 1086 ngx_http_upstream_t *u;
1081 ngx_http_proxy_ctx_t *ctx; 1087 ngx_http_proxy_ctx_t *ctx;
1082 ngx_http_script_code_pt code; 1088 ngx_http_script_code_pt code;
1089 ngx_http_proxy_headers_t *headers;
1083 ngx_http_script_engine_t e, le; 1090 ngx_http_script_engine_t e, le;
1084 ngx_http_proxy_loc_conf_t *plcf; 1091 ngx_http_proxy_loc_conf_t *plcf;
1085 ngx_http_script_len_code_pt lcode; 1092 ngx_http_script_len_code_pt lcode;
1086 1093
1087 u = r->upstream; 1094 u = r->upstream;
1088 1095
1089 plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module); 1096 plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module);
1097
1098 headers = &plcf->headers;
1090 1099
1091 if (u->method.len) { 1100 if (u->method.len) {
1092 /* HEAD was changed to GET to cache response */ 1101 /* HEAD was changed to GET to cache response */
1093 method = u->method; 1102 method = u->method;
1094 method.len++; 1103 method.len++;
1144 1153
1145 len += uri_len; 1154 len += uri_len;
1146 1155
1147 ngx_memzero(&le, sizeof(ngx_http_script_engine_t)); 1156 ngx_memzero(&le, sizeof(ngx_http_script_engine_t));
1148 1157
1149 ngx_http_script_flush_no_cacheable_variables(r, plcf->flushes); 1158 ngx_http_script_flush_no_cacheable_variables(r, plcf->body_flushes);
1159 ngx_http_script_flush_no_cacheable_variables(r, headers->flushes);
1150 1160
1151 if (plcf->body_set_len) { 1161 if (plcf->body_set_len) {
1152 le.ip = plcf->body_set_len->elts; 1162 le.ip = plcf->body_set_len->elts;
1153 le.request = r; 1163 le.request = r;
1154 le.flushed = 1; 1164 le.flushed = 1;
1164 1174
1165 } else { 1175 } else {
1166 ctx->internal_body_length = r->headers_in.content_length_n; 1176 ctx->internal_body_length = r->headers_in.content_length_n;
1167 } 1177 }
1168 1178
1169 le.ip = plcf->headers_set_len->elts; 1179 le.ip = headers->lengths->elts;
1170 le.request = r; 1180 le.request = r;
1171 le.flushed = 1; 1181 le.flushed = 1;
1172 1182
1173 while (*(uintptr_t *) le.ip) { 1183 while (*(uintptr_t *) le.ip) {
1174 while (*(uintptr_t *) le.ip) { 1184 while (*(uintptr_t *) le.ip) {
1193 part = part->next; 1203 part = part->next;
1194 header = part->elts; 1204 header = part->elts;
1195 i = 0; 1205 i = 0;
1196 } 1206 }
1197 1207
1198 if (ngx_hash_find(&plcf->headers_set_hash, header[i].hash, 1208 if (ngx_hash_find(&headers->hash, header[i].hash,
1199 header[i].lowcase_key, header[i].key.len)) 1209 header[i].lowcase_key, header[i].key.len))
1200 { 1210 {
1201 continue; 1211 continue;
1202 } 1212 }
1203 1213
1264 sizeof(ngx_http_proxy_version) - 1); 1274 sizeof(ngx_http_proxy_version) - 1);
1265 } 1275 }
1266 1276
1267 ngx_memzero(&e, sizeof(ngx_http_script_engine_t)); 1277 ngx_memzero(&e, sizeof(ngx_http_script_engine_t));
1268 1278
1269 e.ip = plcf->headers_set->elts; 1279 e.ip = headers->values->elts;
1270 e.pos = b->last; 1280 e.pos = b->last;
1271 e.request = r; 1281 e.request = r;
1272 e.flushed = 1; 1282 e.flushed = 1;
1273 1283
1274 le.ip = plcf->headers_set_len->elts; 1284 le.ip = headers->lengths->elts;
1275 1285
1276 while (*(uintptr_t *) le.ip) { 1286 while (*(uintptr_t *) le.ip) {
1277 lcode = *(ngx_http_script_len_code_pt *) le.ip; 1287 lcode = *(ngx_http_script_len_code_pt *) le.ip;
1278 1288
1279 /* skip the header line name length */ 1289 /* skip the header line name length */
1317 part = part->next; 1327 part = part->next;
1318 header = part->elts; 1328 header = part->elts;
1319 i = 0; 1329 i = 0;
1320 } 1330 }
1321 1331
1322 if (ngx_hash_find(&plcf->headers_set_hash, header[i].hash, 1332 if (ngx_hash_find(&headers->hash, header[i].hash,
1323 header[i].lowcase_key, header[i].key.len)) 1333 header[i].lowcase_key, header[i].key.len))
1324 { 1334 {
1325 continue; 1335 continue;
1326 } 1336 }
1327 1337
2500 * conf->upstream.store_values = NULL; 2510 * conf->upstream.store_values = NULL;
2501 * conf->upstream.ssl_name = NULL; 2511 * conf->upstream.ssl_name = NULL;
2502 * 2512 *
2503 * conf->method = { 0, NULL }; 2513 * conf->method = { 0, NULL };
2504 * conf->headers_source = NULL; 2514 * conf->headers_source = NULL;
2505 * conf->headers_set_len = NULL; 2515 * conf->headers.lengths = NULL;
2506 * conf->headers_set = NULL; 2516 * conf->headers.values = NULL;
2507 * conf->headers_set_hash = NULL; 2517 * conf->headers.hash = { NULL, 0 };
2508 * conf->body_set_len = NULL; 2518 * conf->body_set_len = NULL;
2509 * conf->body_set = NULL; 2519 * conf->body_set = NULL;
2510 * conf->body_source = { 0, NULL }; 2520 * conf->body_source = { 0, NULL };
2511 * conf->redirects = NULL; 2521 * conf->redirects = NULL;
2512 * conf->ssl = 0; 2522 * conf->ssl = 0;
2991 conf->location = prev->location; 3001 conf->location = prev->location;
2992 } 3002 }
2993 } 3003 }
2994 3004
2995 if (conf->body_source.data == NULL) { 3005 if (conf->body_source.data == NULL) {
3006 conf->body_flushes = prev->body_flushes;
2996 conf->body_source = prev->body_source; 3007 conf->body_source = prev->body_source;
2997 conf->body_set_len = prev->body_set_len; 3008 conf->body_set_len = prev->body_set_len;
2998 conf->body_set = prev->body_set; 3009 conf->body_set = prev->body_set;
2999 } 3010 }
3000 3011
3002 3013
3003 ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); 3014 ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
3004 3015
3005 sc.cf = cf; 3016 sc.cf = cf;
3006 sc.source = &conf->body_source; 3017 sc.source = &conf->body_source;
3007 sc.flushes = &conf->flushes; 3018 sc.flushes = &conf->body_flushes;
3008 sc.lengths = &conf->body_set_len; 3019 sc.lengths = &conf->body_set_len;
3009 sc.values = &conf->body_set; 3020 sc.values = &conf->body_set;
3010 sc.complete_lengths = 1; 3021 sc.complete_lengths = 1;
3011 sc.complete_values = 1; 3022 sc.complete_values = 1;
3012 3023
3014 return NGX_CONF_ERROR; 3025 return NGX_CONF_ERROR;
3015 } 3026 }
3016 } 3027 }
3017 3028
3018 if (conf->headers_source == NULL) { 3029 if (conf->headers_source == NULL) {
3019 conf->flushes = prev->flushes; 3030 conf->headers = prev->headers;
3020 conf->headers_set_len = prev->headers_set_len;
3021 conf->headers_set = prev->headers_set;
3022 conf->headers_set_hash = prev->headers_set_hash;
3023 conf->headers_source = prev->headers_source; 3031 conf->headers_source = prev->headers_source;
3024 } 3032 }
3025 3033
3026 #if (NGX_HTTP_CACHE) 3034 #if (NGX_HTTP_CACHE)
3027 if ((conf->upstream.cache == NULL) != (prev->upstream.cache == NULL)) { 3035 if ((conf->upstream.cache == NULL) != (prev->upstream.cache == NULL)) {
3028 conf->headers_set_hash.buckets = NULL; 3036 conf->headers.hash.buckets = NULL;
3029 } 3037 }
3030 #endif 3038 #endif
3031 3039
3032 if (ngx_http_proxy_init_headers(cf, conf) != NGX_OK) { 3040 if (ngx_http_proxy_init_headers(cf, conf, &conf->headers) != NGX_OK) {
3033 return NGX_CONF_ERROR; 3041 return NGX_CONF_ERROR;
3034 } 3042 }
3035 3043
3036 return NGX_CONF_OK; 3044 return NGX_CONF_OK;
3037 } 3045 }
3038 3046
3039 3047
3040 static ngx_int_t 3048 static ngx_int_t
3041 ngx_http_proxy_init_headers(ngx_conf_t *cf, ngx_http_proxy_loc_conf_t *conf) 3049 ngx_http_proxy_init_headers(ngx_conf_t *cf, ngx_http_proxy_loc_conf_t *conf,
3050 ngx_http_proxy_headers_t *headers)
3042 { 3051 {
3043 u_char *p; 3052 u_char *p;
3044 size_t size; 3053 size_t size;
3045 uintptr_t *code; 3054 uintptr_t *code;
3046 ngx_uint_t i; 3055 ngx_uint_t i;
3049 ngx_hash_key_t *hk; 3058 ngx_hash_key_t *hk;
3050 ngx_hash_init_t hash; 3059 ngx_hash_init_t hash;
3051 ngx_http_script_compile_t sc; 3060 ngx_http_script_compile_t sc;
3052 ngx_http_script_copy_code_t *copy; 3061 ngx_http_script_copy_code_t *copy;
3053 3062
3054 if (conf->headers_set_hash.buckets) { 3063 if (headers->hash.buckets) {
3055 return NGX_OK; 3064 return NGX_OK;
3056 } 3065 }
3057 3066
3058 if (ngx_array_init(&headers_names, cf->temp_pool, 4, sizeof(ngx_hash_key_t)) 3067 if (ngx_array_init(&headers_names, cf->temp_pool, 4, sizeof(ngx_hash_key_t))
3059 != NGX_OK) 3068 != NGX_OK)
3073 if (conf->headers_source == NULL) { 3082 if (conf->headers_source == NULL) {
3074 return NGX_ERROR; 3083 return NGX_ERROR;
3075 } 3084 }
3076 } 3085 }
3077 3086
3078 conf->headers_set_len = ngx_array_create(cf->pool, 64, 1); 3087 headers->lengths = ngx_array_create(cf->pool, 64, 1);
3079 if (conf->headers_set_len == NULL) { 3088 if (headers->lengths == NULL) {
3080 return NGX_ERROR; 3089 return NGX_ERROR;
3081 } 3090 }
3082 3091
3083 conf->headers_set = ngx_array_create(cf->pool, 512, 1); 3092 headers->values = ngx_array_create(cf->pool, 512, 1);
3084 if (conf->headers_set == NULL) { 3093 if (headers->values == NULL) {
3085 return NGX_ERROR; 3094 return NGX_ERROR;
3086 } 3095 }
3087 3096
3088 3097
3089 #if (NGX_HTTP_CACHE) 3098 #if (NGX_HTTP_CACHE)
3144 if (src[i].value.len == 0) { 3153 if (src[i].value.len == 0) {
3145 continue; 3154 continue;
3146 } 3155 }
3147 3156
3148 if (ngx_http_script_variables_count(&src[i].value) == 0) { 3157 if (ngx_http_script_variables_count(&src[i].value) == 0) {
3149 copy = ngx_array_push_n(conf->headers_set_len, 3158 copy = ngx_array_push_n(headers->lengths,
3150 sizeof(ngx_http_script_copy_code_t)); 3159 sizeof(ngx_http_script_copy_code_t));
3151 if (copy == NULL) { 3160 if (copy == NULL) {
3152 return NGX_ERROR; 3161 return NGX_ERROR;
3153 } 3162 }
3154 3163
3162 + src[i].key.len + sizeof(": ") - 1 3171 + src[i].key.len + sizeof(": ") - 1
3163 + src[i].value.len + sizeof(CRLF) - 1 3172 + src[i].value.len + sizeof(CRLF) - 1
3164 + sizeof(uintptr_t) - 1) 3173 + sizeof(uintptr_t) - 1)
3165 & ~(sizeof(uintptr_t) - 1); 3174 & ~(sizeof(uintptr_t) - 1);
3166 3175
3167 copy = ngx_array_push_n(conf->headers_set, size); 3176 copy = ngx_array_push_n(headers->values, size);
3168 if (copy == NULL) { 3177 if (copy == NULL) {
3169 return NGX_ERROR; 3178 return NGX_ERROR;
3170 } 3179 }
3171 3180
3172 copy->code = ngx_http_script_copy_code; 3181 copy->code = ngx_http_script_copy_code;
3179 *p++ = ':'; *p++ = ' '; 3188 *p++ = ':'; *p++ = ' ';
3180 p = ngx_cpymem(p, src[i].value.data, src[i].value.len); 3189 p = ngx_cpymem(p, src[i].value.data, src[i].value.len);
3181 *p++ = CR; *p = LF; 3190 *p++ = CR; *p = LF;
3182 3191
3183 } else { 3192 } else {
3184 copy = ngx_array_push_n(conf->headers_set_len, 3193 copy = ngx_array_push_n(headers->lengths,
3185 sizeof(ngx_http_script_copy_code_t)); 3194 sizeof(ngx_http_script_copy_code_t));
3186 if (copy == NULL) { 3195 if (copy == NULL) {
3187 return NGX_ERROR; 3196 return NGX_ERROR;
3188 } 3197 }
3189 3198
3194 3203
3195 size = (sizeof(ngx_http_script_copy_code_t) 3204 size = (sizeof(ngx_http_script_copy_code_t)
3196 + src[i].key.len + sizeof(": ") - 1 + sizeof(uintptr_t) - 1) 3205 + src[i].key.len + sizeof(": ") - 1 + sizeof(uintptr_t) - 1)
3197 & ~(sizeof(uintptr_t) - 1); 3206 & ~(sizeof(uintptr_t) - 1);
3198 3207
3199 copy = ngx_array_push_n(conf->headers_set, size); 3208 copy = ngx_array_push_n(headers->values, size);
3200 if (copy == NULL) { 3209 if (copy == NULL) {
3201 return NGX_ERROR; 3210 return NGX_ERROR;
3202 } 3211 }
3203 3212
3204 copy->code = ngx_http_script_copy_code; 3213 copy->code = ngx_http_script_copy_code;
3211 3220
3212 ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); 3221 ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
3213 3222
3214 sc.cf = cf; 3223 sc.cf = cf;
3215 sc.source = &src[i].value; 3224 sc.source = &src[i].value;
3216 sc.flushes = &conf->flushes; 3225 sc.flushes = &headers->flushes;
3217 sc.lengths = &conf->headers_set_len; 3226 sc.lengths = &headers->lengths;
3218 sc.values = &conf->headers_set; 3227 sc.values = &headers->values;
3219 3228
3220 if (ngx_http_script_compile(&sc) != NGX_OK) { 3229 if (ngx_http_script_compile(&sc) != NGX_OK) {
3221 return NGX_ERROR; 3230 return NGX_ERROR;
3222 } 3231 }
3223 3232
3224 3233
3225 copy = ngx_array_push_n(conf->headers_set_len, 3234 copy = ngx_array_push_n(headers->lengths,
3226 sizeof(ngx_http_script_copy_code_t)); 3235 sizeof(ngx_http_script_copy_code_t));
3227 if (copy == NULL) { 3236 if (copy == NULL) {
3228 return NGX_ERROR; 3237 return NGX_ERROR;
3229 } 3238 }
3230 3239
3235 3244
3236 size = (sizeof(ngx_http_script_copy_code_t) 3245 size = (sizeof(ngx_http_script_copy_code_t)
3237 + sizeof(CRLF) - 1 + sizeof(uintptr_t) - 1) 3246 + sizeof(CRLF) - 1 + sizeof(uintptr_t) - 1)
3238 & ~(sizeof(uintptr_t) - 1); 3247 & ~(sizeof(uintptr_t) - 1);
3239 3248
3240 copy = ngx_array_push_n(conf->headers_set, size); 3249 copy = ngx_array_push_n(headers->values, size);
3241 if (copy == NULL) { 3250 if (copy == NULL) {
3242 return NGX_ERROR; 3251 return NGX_ERROR;
3243 } 3252 }
3244 3253
3245 copy->code = ngx_http_script_copy_code; 3254 copy->code = ngx_http_script_copy_code;
3247 3256
3248 p = (u_char *) copy + sizeof(ngx_http_script_copy_code_t); 3257 p = (u_char *) copy + sizeof(ngx_http_script_copy_code_t);
3249 *p++ = CR; *p = LF; 3258 *p++ = CR; *p = LF;
3250 } 3259 }
3251 3260
3252 code = ngx_array_push_n(conf->headers_set_len, sizeof(uintptr_t)); 3261 code = ngx_array_push_n(headers->lengths, sizeof(uintptr_t));
3253 if (code == NULL) { 3262 if (code == NULL) {
3254 return NGX_ERROR; 3263 return NGX_ERROR;
3255 } 3264 }
3256 3265
3257 *code = (uintptr_t) NULL; 3266 *code = (uintptr_t) NULL;
3258 3267
3259 code = ngx_array_push_n(conf->headers_set, sizeof(uintptr_t)); 3268 code = ngx_array_push_n(headers->values, sizeof(uintptr_t));
3260 if (code == NULL) { 3269 if (code == NULL) {
3261 return NGX_ERROR; 3270 return NGX_ERROR;
3262 } 3271 }
3263 3272
3264 *code = (uintptr_t) NULL; 3273 *code = (uintptr_t) NULL;
3265 } 3274 }
3266 3275
3267 code = ngx_array_push_n(conf->headers_set_len, sizeof(uintptr_t)); 3276 code = ngx_array_push_n(headers->lengths, sizeof(uintptr_t));
3268 if (code == NULL) { 3277 if (code == NULL) {
3269 return NGX_ERROR; 3278 return NGX_ERROR;
3270 } 3279 }
3271 3280
3272 *code = (uintptr_t) NULL; 3281 *code = (uintptr_t) NULL;
3273 3282
3274 3283
3275 hash.hash = &conf->headers_set_hash; 3284 hash.hash = &headers->hash;
3276 hash.key = ngx_hash_key_lc; 3285 hash.key = ngx_hash_key_lc;
3277 hash.max_size = conf->headers_hash_max_size; 3286 hash.max_size = conf->headers_hash_max_size;
3278 hash.bucket_size = conf->headers_hash_bucket_size; 3287 hash.bucket_size = conf->headers_hash_bucket_size;
3279 hash.name = "proxy_headers_hash"; 3288 hash.name = "proxy_headers_hash";
3280 hash.pool = cf->pool; 3289 hash.pool = cf->pool;