comparison src/http/modules/proxy/ngx_http_proxy_handler.c @ 28:7ca9bdc82b3f NGINX_0_1_14

nginx 0.1.14 *) Feature: the autoconfiguration directives: --http-client-body-temp-path=PATH, --http-proxy-temp-path=PATH, and --http-fastcgi-temp-path=PATH *) Change: the directory name for the temporary files with the client request body is specified by directive client_body_temp_path, by default it is <prefix>/client_body_temp. *) Feature: the ngx_http_fastcgi_module and the directives: fastcgi_pass, fastcgi_root, fastcgi_index, fastcgi_params, fastcgi_connect_timeout, fastcgi_send_timeout, fastcgi_read_timeout, fastcgi_send_lowat, fastcgi_header_buffer_size, fastcgi_buffers, fastcgi_busy_buffers_size, fastcgi_temp_path, fastcgi_max_temp_file_size, fastcgi_temp_file_write_size, fastcgi_next_upstream, and fastcgi_x_powered_by. *) Bugfix: the "[alert] zero size buf" error; bug appeared in 0.1.3. *) Change: the URI must be specified after the host name in the proxy_pass directive. *) Change: the %3F symbol in the URI was considered as the argument string start. *) Feature: the unix domain sockets support in the ngx_http_proxy_module. *) Feature: the ssl_engine and ssl_ciphers directives. Thanks to Sergey Skvortsov for SSL-accelerator.
author Igor Sysoev <http://sysoev.ru>
date Tue, 18 Jan 2005 00:00:00 +0300
parents 45fe5b98a9de
children e1ada20fc595
comparison
equal deleted inserted replaced
27:66901c2556fd 28:7ca9bdc82b3f
11 11
12 12
13 static ngx_int_t ngx_http_proxy_handler(ngx_http_request_t *r); 13 static ngx_int_t ngx_http_proxy_handler(ngx_http_request_t *r);
14 static ngx_int_t ngx_http_proxy_cache_get(ngx_http_proxy_ctx_t *p); 14 static ngx_int_t ngx_http_proxy_cache_get(ngx_http_proxy_ctx_t *p);
15 15
16 static size_t ngx_http_proxy_log_proxy_state_getlen(ngx_http_request_t *r,
17 uintptr_t data);
16 static u_char *ngx_http_proxy_log_proxy_state(ngx_http_request_t *r, 18 static u_char *ngx_http_proxy_log_proxy_state(ngx_http_request_t *r,
17 u_char *buf, uintptr_t data); 19 u_char *buf,
20 ngx_http_log_op_t *op);
21
22 #if 0
18 static u_char *ngx_http_proxy_log_cache_state(ngx_http_request_t *r, 23 static u_char *ngx_http_proxy_log_cache_state(ngx_http_request_t *r,
19 u_char *buf, uintptr_t data); 24 u_char *buf, uintptr_t data);
20 static u_char *ngx_http_proxy_log_reason(ngx_http_request_t *r, u_char *buf, 25 static u_char *ngx_http_proxy_log_reason(ngx_http_request_t *r, u_char *buf,
21 uintptr_t data); 26 uintptr_t data);
22 27 #endif
23 static ngx_int_t ngx_http_proxy_pre_conf(ngx_conf_t *cf); 28
29 static ngx_int_t ngx_http_proxy_add_log_formats(ngx_conf_t *cf);
24 static void *ngx_http_proxy_create_loc_conf(ngx_conf_t *cf); 30 static void *ngx_http_proxy_create_loc_conf(ngx_conf_t *cf);
25 static char *ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, 31 static char *ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf,
26 void *parent, void *child); 32 void *parent, void *child);
27 33
28 static char *ngx_http_proxy_set_pass(ngx_conf_t *cf, ngx_command_t *cmd, 34 static char *ngx_http_proxy_set_pass(ngx_conf_t *cf, ngx_command_t *cmd,
229 ngx_conf_set_sec_slot, 235 ngx_conf_set_sec_slot,
230 NGX_HTTP_LOC_CONF_OFFSET, 236 NGX_HTTP_LOC_CONF_OFFSET,
231 offsetof(ngx_http_proxy_loc_conf_t, default_expires), 237 offsetof(ngx_http_proxy_loc_conf_t, default_expires),
232 NULL }, 238 NULL },
233 239
234
235 { ngx_string("proxy_next_upstream"), 240 { ngx_string("proxy_next_upstream"),
236 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_ANY, 241 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_ANY,
237 ngx_conf_set_bitmask_slot, 242 ngx_conf_set_bitmask_slot,
238 NGX_HTTP_LOC_CONF_OFFSET, 243 NGX_HTTP_LOC_CONF_OFFSET,
239 offsetof(ngx_http_proxy_loc_conf_t, next_upstream), 244 offsetof(ngx_http_proxy_loc_conf_t, next_upstream),
249 ngx_null_command 254 ngx_null_command
250 }; 255 };
251 256
252 257
253 ngx_http_module_t ngx_http_proxy_module_ctx = { 258 ngx_http_module_t ngx_http_proxy_module_ctx = {
254 ngx_http_proxy_pre_conf, /* pre conf */ 259 ngx_http_proxy_add_log_formats, /* pre conf */
255 260
256 NULL, /* create main configuration */ 261 NULL, /* create main configuration */
257 NULL, /* init main configuration */ 262 NULL, /* init main configuration */
258 263
259 NULL, /* create server configuration */ 264 NULL, /* create server configuration */
268 NGX_MODULE, 273 NGX_MODULE,
269 &ngx_http_proxy_module_ctx, /* module context */ 274 &ngx_http_proxy_module_ctx, /* module context */
270 ngx_http_proxy_commands, /* module directives */ 275 ngx_http_proxy_commands, /* module directives */
271 NGX_HTTP_MODULE, /* module type */ 276 NGX_HTTP_MODULE, /* module type */
272 NULL, /* init module */ 277 NULL, /* init module */
273 NULL /* init child */ 278 NULL /* init process */
274 }; 279 };
275 280
276 281
277 282
278 static ngx_http_log_op_name_t ngx_http_proxy_log_fmt_ops[] = { 283 static ngx_http_log_op_name_t ngx_http_proxy_log_fmt_ops[] = {
279 { ngx_string("proxy"), 0, ngx_http_proxy_log_proxy_state }, 284 { ngx_string("proxy"), 0, NULL,
285 ngx_http_proxy_log_proxy_state_getlen,
286 ngx_http_proxy_log_proxy_state },
287
288 #if 0
280 { ngx_string("proxy_cache_state"), 0, ngx_http_proxy_log_cache_state }, 289 { ngx_string("proxy_cache_state"), 0, ngx_http_proxy_log_cache_state },
281 { ngx_string("proxy_reason"), 0, ngx_http_proxy_log_reason }, 290 { ngx_string("proxy_reason"), 0, ngx_http_proxy_log_reason },
282 { ngx_null_string, 0, NULL } 291 #endif
292
293 { ngx_null_string, 0, NULL, NULL, NULL }
283 }; 294 };
284 295
285 296
286 297
287 ngx_http_header_t ngx_http_proxy_headers_in[] = { 298 ngx_http_header_t ngx_http_proxy_headers_in[] = {
299 offsetof(ngx_http_proxy_headers_in_t, connection) }, 310 offsetof(ngx_http_proxy_headers_in_t, connection) },
300 { ngx_string("Content-Type"), 311 { ngx_string("Content-Type"),
301 offsetof(ngx_http_proxy_headers_in_t, content_type) }, 312 offsetof(ngx_http_proxy_headers_in_t, content_type) },
302 { ngx_string("Content-Length"), 313 { ngx_string("Content-Length"),
303 offsetof(ngx_http_proxy_headers_in_t, content_length) }, 314 offsetof(ngx_http_proxy_headers_in_t, content_length) },
315
316 #if (NGX_HTTP_GZIP)
304 { ngx_string("Content-Encoding"), 317 { ngx_string("Content-Encoding"),
305 offsetof(ngx_http_proxy_headers_in_t, content_encoding) }, 318 offsetof(ngx_http_proxy_headers_in_t, content_encoding) },
319 #endif
320
306 { ngx_string("Last-Modified"), 321 { ngx_string("Last-Modified"),
307 offsetof(ngx_http_proxy_headers_in_t, last_modified) }, 322 offsetof(ngx_http_proxy_headers_in_t, last_modified) },
308 { ngx_string("Location"), 323 { ngx_string("Location"),
309 offsetof(ngx_http_proxy_headers_in_t, location) }, 324 offsetof(ngx_http_proxy_headers_in_t, location) },
310 { ngx_string("Accept-Ranges"), 325 { ngx_string("Accept-Ranges"),
777 r = ctx->proxy->request; 792 r = ctx->proxy->request;
778 uc = ctx->proxy->lcf->upstream; 793 uc = ctx->proxy->lcf->upstream;
779 peer = &ctx->proxy->upstream->peer; 794 peer = &ctx->proxy->upstream->peer;
780 795
781 p = ngx_snprintf(buf, len, 796 p = ngx_snprintf(buf, len,
782 " while %s, client: %V, URL: %V, upstream: %V%V", 797 " while %s, client: %V, URL: %V, upstream: http://%V%s%V",
783 ctx->proxy->action, 798 ctx->proxy->action,
784 &r->connection->addr_text, 799 &r->connection->addr_text,
785 &r->unparsed_uri, 800 &r->unparsed_uri,
786 &peer->peers->peers[peer->cur_peer].addr_port_text, 801 &peer->peers->peer[peer->cur_peer].name,
802 ctx->proxy->lcf->upstream->uri_separator,
787 &ctx->proxy->lcf->upstream->uri); 803 &ctx->proxy->lcf->upstream->uri);
788 len -= p - buf; 804 len -= p - buf;
789 buf = p; 805 buf = p;
790 806
791 if (r->quoted_uri) { 807 if (r->quoted_uri) {
833 return ngx_snprintf(buf, len, "%V%s%V", 849 return ngx_snprintf(buf, len, "%V%s%V",
834 &uri, r->args.len ? "?" : "", &r->args); 850 &uri, r->args.len ? "?" : "", &r->args);
835 } 851 }
836 852
837 853
854 static size_t ngx_http_proxy_log_proxy_state_getlen(ngx_http_request_t *r,
855 uintptr_t data)
856 {
857 ngx_http_proxy_ctx_t *p;
858
859 p = ngx_http_get_module_err_ctx(r, ngx_http_proxy_module);
860
861 if (p == NULL) {
862 return 1;
863 }
864
865 return p->states.nelts * /* STUB */ 100;
866 }
867
868
838 static u_char *ngx_http_proxy_log_proxy_state(ngx_http_request_t *r, 869 static u_char *ngx_http_proxy_log_proxy_state(ngx_http_request_t *r,
839 u_char *buf, uintptr_t data) 870 u_char *buf,
871 ngx_http_log_op_t *op)
840 { 872 {
841 ngx_uint_t i; 873 ngx_uint_t i;
842 ngx_http_proxy_ctx_t *p; 874 ngx_http_proxy_ctx_t *p;
843 ngx_http_proxy_state_t *state; 875 ngx_http_proxy_state_t *state;
844 876
845 p = ngx_http_get_module_err_ctx(r, ngx_http_proxy_module); 877 p = ngx_http_get_module_err_ctx(r, ngx_http_proxy_module);
846 878
847 if (p == NULL) { 879 if (p == NULL) {
848 if (buf == NULL) {
849 return (u_char *) 1;
850 }
851
852 *buf = '-'; 880 *buf = '-';
853 return buf + 1; 881 return buf + 1;
854 } 882 }
855
856
857 if (buf == NULL) {
858 /* find the request line length */
859 return (u_char *) (uintptr_t) (p->states.nelts * /* STUB */ 100);
860 }
861
862 883
863 i = 0; 884 i = 0;
864 state = p->states.elts; 885 state = p->states.elts;
865 886
866 for ( ;; ) { 887 for ( ;; ) {
933 *buf++ = ' '; 954 *buf++ = ' ';
934 } 955 }
935 } 956 }
936 957
937 958
959 #if 0
960
938 static u_char *ngx_http_proxy_log_cache_state(ngx_http_request_t *r, 961 static u_char *ngx_http_proxy_log_cache_state(ngx_http_request_t *r,
939 u_char *buf, uintptr_t data) 962 u_char *buf, uintptr_t data)
940 { 963 {
941 ngx_uint_t i; 964 ngx_uint_t i;
942 ngx_http_proxy_ctx_t *p; 965 ngx_http_proxy_ctx_t *p;
1012 *buf++ = ','; 1035 *buf++ = ',';
1013 *buf++ = ' '; 1036 *buf++ = ' ';
1014 } 1037 }
1015 } 1038 }
1016 1039
1017 1040 #endif
1018 static ngx_int_t ngx_http_proxy_pre_conf(ngx_conf_t *cf) 1041
1042
1043 static ngx_int_t ngx_http_proxy_add_log_formats(ngx_conf_t *cf)
1019 { 1044 {
1020 ngx_http_log_op_name_t *op; 1045 ngx_http_log_op_name_t *op;
1021 1046
1022 for (op = ngx_http_proxy_log_fmt_ops; op->name.len; op++) { /* void */ } 1047 for (op = ngx_http_proxy_log_fmt_ops; op->name.len; op++) { /* void */ }
1023 op->op = NULL; 1048 op->run = NULL;
1024 1049
1025 op = ngx_http_log_fmt_ops; 1050 for (op = ngx_http_log_fmt_ops; op->run; op++) {
1026
1027 for (op = ngx_http_log_fmt_ops; op->op; op++) {
1028 if (op->name.len == 0) { 1051 if (op->name.len == 0) {
1029 op = (ngx_http_log_op_name_t *) op->op; 1052 op = (ngx_http_log_op_name_t *) op->run;
1030 } 1053 }
1031 } 1054 }
1032 1055
1033 op->op = (ngx_http_log_op_pt) ngx_http_proxy_log_fmt_ops; 1056 op->run = (ngx_http_log_op_run_pt) ngx_http_proxy_log_fmt_ops;
1034 1057
1035 return NGX_OK; 1058 return NGX_OK;
1036 } 1059 }
1037 1060
1038 1061
1042 1065
1043 ngx_test_null(conf, 1066 ngx_test_null(conf,
1044 ngx_pcalloc(cf->pool, sizeof(ngx_http_proxy_loc_conf_t)), 1067 ngx_pcalloc(cf->pool, sizeof(ngx_http_proxy_loc_conf_t)),
1045 NGX_CONF_ERROR); 1068 NGX_CONF_ERROR);
1046 1069
1047 /* set by ngx_pcalloc(): 1070 /*
1048 1071 * set by ngx_pcalloc():
1049 conf->bufs.num = 0; 1072 *
1050 1073 * conf->bufs.num = 0;
1051 conf->path = NULL; 1074 * conf->path = NULL;
1052 1075 * conf->next_upstream = 0;
1053 conf->next_upstream = 0; 1076 * conf->use_stale = 0;
1054 conf->use_stale = 0; 1077 * conf->upstreams = NULL;
1055 1078 * conf->peers = NULL;
1056 conf->upstreams = NULL; 1079 * conf->cache_path = NULL;
1057 conf->peers = NULL; 1080 * conf->temp_path = NULL;
1058 1081 * conf->busy_lock = NULL;
1059 conf->cache_path = NULL; 1082 */
1060 conf->temp_path = NULL;
1061
1062 conf->busy_lock = NULL;
1063
1064 */
1065 1083
1066 conf->connect_timeout = NGX_CONF_UNSET_MSEC; 1084 conf->connect_timeout = NGX_CONF_UNSET_MSEC;
1067 conf->send_timeout = NGX_CONF_UNSET_MSEC; 1085 conf->send_timeout = NGX_CONF_UNSET_MSEC;
1068 conf->send_lowat = NGX_CONF_UNSET_SIZE; 1086 conf->send_lowat = NGX_CONF_UNSET_SIZE;
1069 1087
1208 |NGX_HTTP_PROXY_FT_TIMEOUT)); 1226 |NGX_HTTP_PROXY_FT_TIMEOUT));
1209 1227
1210 ngx_conf_merge_bitmask_value(conf->use_stale, prev->use_stale, 1228 ngx_conf_merge_bitmask_value(conf->use_stale, prev->use_stale,
1211 NGX_CONF_BITMASK_SET); 1229 NGX_CONF_BITMASK_SET);
1212 1230
1231 #if 0
1213 ngx_conf_merge_path_value(conf->cache_path, prev->cache_path, 1232 ngx_conf_merge_path_value(conf->cache_path, prev->cache_path,
1214 "cache", 1, 2, 0, cf->pool); 1233 NGX_HTTP_PROXY_CACHE_PATH, 1, 2, 0,
1234 ngx_garbage_collector_temp_handler, cf);
1235 #endif
1215 1236
1216 ngx_conf_merge_path_value(conf->temp_path, prev->temp_path, 1237 ngx_conf_merge_path_value(conf->temp_path, prev->temp_path,
1217 "temp", 1, 2, 0, cf->pool); 1238 NGX_HTTP_PROXY_TEMP_PATH, 1, 2, 0,
1239 ngx_garbage_collector_temp_handler, cf);
1218 1240
1219 ngx_conf_merge_value(conf->cache, prev->cache, 0); 1241 ngx_conf_merge_value(conf->cache, prev->cache, 0);
1220 1242
1221 1243
1222 /* conf->cache must be merged */ 1244 /* conf->cache must be merged */
1254 1276
1255 return NULL; 1277 return NULL;
1256 } 1278 }
1257 1279
1258 1280
1259
1260 static char *ngx_http_proxy_set_pass(ngx_conf_t *cf, ngx_command_t *cmd, 1281 static char *ngx_http_proxy_set_pass(ngx_conf_t *cf, ngx_command_t *cmd,
1261 void *conf) 1282 void *conf)
1262 { 1283 {
1263 ngx_http_proxy_loc_conf_t *lcf = conf; 1284 ngx_http_proxy_loc_conf_t *lcf = conf;
1264 1285
1265 ngx_uint_t i, len; 1286 ngx_str_t *value, *url;
1266 char *err; 1287 ngx_inet_upstream_t inet_upstream;
1267 u_char *host; 1288 ngx_http_core_loc_conf_t *clcf;
1268 in_addr_t addr; 1289 #if (NGX_HAVE_UNIX_DOMAIN)
1269 ngx_str_t *value; 1290 ngx_unix_domain_upstream_t unix_upstream;
1270 struct hostent *h; 1291 #endif
1271 ngx_http_core_loc_conf_t *clcf;
1272
1273 1292
1274 value = cf->args->elts; 1293 value = cf->args->elts;
1275 1294
1276 if (ngx_strncasecmp(value[1].data, "http://", 7) != 0) { 1295 url = &value[1];
1296
1297 if (ngx_strncasecmp(url->data, "http://", 7) != 0) {
1277 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid URL prefix"); 1298 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid URL prefix");
1278 return NGX_CONF_ERROR; 1299 return NGX_CONF_ERROR;
1279 } 1300 }
1280 1301
1281 lcf->upstream = ngx_pcalloc(cf->pool, 1302 lcf->upstream = ngx_pcalloc(cf->pool,
1282 sizeof(ngx_http_proxy_upstream_conf_t)); 1303 sizeof(ngx_http_proxy_upstream_conf_t));
1283 if (lcf->upstream == NULL) { 1304 if (lcf->upstream == NULL) {
1284 return NGX_CONF_ERROR; 1305 return NGX_CONF_ERROR;
1285 } 1306 }
1286 1307
1287 lcf->upstream->url.len = value[1].len; 1308 if (ngx_strncasecmp(url->data + 7, "unix:", 5) == 0) {
1288 if (!(lcf->upstream->url.data = ngx_palloc(cf->pool, value[1].len + 1))) { 1309
1310 #if (NGX_HAVE_UNIX_DOMAIN)
1311
1312 ngx_memzero(&unix_upstream, sizeof(ngx_unix_domain_upstream_t));
1313
1314 unix_upstream.name = *url;
1315 unix_upstream.url.len = url->len - 7;
1316 unix_upstream.url.data = url->data + 7;
1317 unix_upstream.uri_part = 1;
1318
1319 if (!(lcf->peers = ngx_unix_upstream_parse(cf, &unix_upstream))) {
1320 return NGX_CONF_ERROR;
1321 }
1322
1323 lcf->upstream->host_header.len = sizeof("localhost") - 1;
1324 lcf->upstream->host_header.data = (u_char *) "localhost";
1325 lcf->upstream->uri = unix_upstream.uri;
1326 lcf->upstream->uri_separator = ":";
1327 lcf->upstream->default_port = 1;
1328
1329 #else
1330 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1331 "the unix domain sockets are not supported "
1332 "on this platform");
1289 return NGX_CONF_ERROR; 1333 return NGX_CONF_ERROR;
1290 } 1334
1291 1335 #endif
1292 ngx_cpystrn(lcf->upstream->url.data, value[1].data, value[1].len + 1); 1336
1293 1337 } else {
1294 value[1].data += 7; 1338 ngx_memzero(&inet_upstream, sizeof(ngx_inet_upstream_t));
1295 value[1].len -= 7; 1339
1296 1340 inet_upstream.name = *url;
1297 err = ngx_http_proxy_parse_upstream(&value[1], lcf->upstream); 1341 inet_upstream.url.len = url->len - 7;
1298 1342 inet_upstream.url.data = url->data + 7;
1299 if (err) { 1343 inet_upstream.default_port_value = 80;
1300 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, err); 1344 inet_upstream.uri_part = 1;
1301 return NGX_CONF_ERROR; 1345
1302 } 1346 if (!(lcf->peers = ngx_inet_upstream_parse(cf, &inet_upstream))) {
1303
1304 if (!(host = ngx_palloc(cf->pool, lcf->upstream->host.len + 1))) {
1305 return NGX_CONF_ERROR;
1306 }
1307
1308 ngx_cpystrn(host, lcf->upstream->host.data, lcf->upstream->host.len + 1);
1309
1310 /* AF_INET only */
1311
1312 addr = inet_addr((char *) host);
1313
1314 if (addr == INADDR_NONE) {
1315 h = gethostbyname((char *) host);
1316
1317 if (h == NULL || h->h_addr_list[0] == NULL) {
1318 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "host %s not found", host);
1319 return NGX_CONF_ERROR; 1347 return NGX_CONF_ERROR;
1320 } 1348 }
1321 1349
1322 for (i = 0; h->h_addr_list[i] != NULL; i++) { /* void */ } 1350 lcf->upstream->host_header = inet_upstream.host_header;
1323 1351 lcf->upstream->port_text = inet_upstream.port_text;
1324 /* MP: ngx_shared_palloc() */ 1352 lcf->upstream->uri = inet_upstream.uri;
1325 1353 lcf->upstream->uri_separator = "";
1326 lcf->peers = ngx_pcalloc(cf->pool,
1327 sizeof(ngx_peers_t) + sizeof(ngx_peer_t) * (i - 1));
1328
1329 if (lcf->peers == NULL) {
1330 return NGX_CONF_ERROR;
1331 }
1332
1333 lcf->peers->number = i;
1334
1335 /* STUB */
1336 lcf->peers->max_fails = 1;
1337 lcf->peers->fail_timeout = 60;
1338
1339 for (i = 0; h->h_addr_list[i] != NULL; i++) {
1340 lcf->peers->peers[i].host.data = host;
1341 lcf->peers->peers[i].host.len = lcf->upstream->host.len;
1342 lcf->peers->peers[i].addr = *(in_addr_t *)(h->h_addr_list[i]);
1343 lcf->peers->peers[i].port = lcf->upstream->port;
1344
1345 len = INET_ADDRSTRLEN - 1 + 1 + lcf->upstream->port_text.len;
1346
1347 lcf->peers->peers[i].addr_port_text.data =
1348 ngx_palloc(cf->pool, len);
1349 if (lcf->peers->peers[i].addr_port_text.data == NULL) {
1350 return NGX_CONF_ERROR;
1351 }
1352
1353 len = ngx_inet_ntop(AF_INET,
1354 &lcf->peers->peers[i].addr,
1355 lcf->peers->peers[i].addr_port_text.data,
1356 len);
1357
1358 lcf->peers->peers[i].addr_port_text.data[len++] = ':';
1359
1360 ngx_memcpy(lcf->peers->peers[i].addr_port_text.data + len,
1361 lcf->upstream->port_text.data,
1362 lcf->upstream->port_text.len);
1363
1364 lcf->peers->peers[i].addr_port_text.len =
1365 len + lcf->upstream->port_text.len;
1366 }
1367
1368 } else {
1369
1370 /* MP: ngx_shared_palloc() */
1371
1372 if (!(lcf->peers = ngx_pcalloc(cf->pool, sizeof(ngx_peers_t)))) {
1373 return NGX_CONF_ERROR;
1374 }
1375
1376 lcf->peers->number = 1;
1377
1378 lcf->peers->peers[0].host.data = host;
1379 lcf->peers->peers[0].host.len = lcf->upstream->host.len;
1380 lcf->peers->peers[0].addr = addr;
1381 lcf->peers->peers[0].port = lcf->upstream->port;
1382
1383 len = lcf->upstream->host.len + 1 + lcf->upstream->port_text.len;
1384
1385 lcf->peers->peers[0].addr_port_text.len = len;
1386
1387 lcf->peers->peers[0].addr_port_text.data = ngx_palloc(cf->pool, len);
1388 if (lcf->peers->peers[0].addr_port_text.data == NULL) {
1389 return NGX_CONF_ERROR;
1390 }
1391
1392 len = lcf->upstream->host.len;
1393
1394 ngx_memcpy(lcf->peers->peers[0].addr_port_text.data,
1395 lcf->upstream->host.data, len);
1396
1397 lcf->peers->peers[0].addr_port_text.data[len++] = ':';
1398
1399 ngx_memcpy(lcf->peers->peers[0].addr_port_text.data + len,
1400 lcf->upstream->port_text.data,
1401 lcf->upstream->port_text.len);
1402 } 1354 }
1403 1355
1404 clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); 1356 clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
1405 1357
1406 lcf->upstream->location = &clcf->name; 1358 lcf->upstream->location = &clcf->name;
1408 1360
1409 if (clcf->name.data[clcf->name.len - 1] == '/') { 1361 if (clcf->name.data[clcf->name.len - 1] == '/') {
1410 clcf->auto_redirect = 1; 1362 clcf->auto_redirect = 1;
1411 } 1363 }
1412 1364
1413 return NULL; 1365 return NGX_CONF_OK;
1414 }
1415
1416
1417 static char *ngx_http_proxy_parse_upstream(ngx_str_t *url,
1418 ngx_http_proxy_upstream_conf_t *u)
1419 {
1420 size_t i;
1421
1422 if (url->data[0] == ':' || url->data[0] == '/') {
1423 return "invalid upstream URL";
1424 }
1425
1426 u->host.data = url->data;
1427 u->host_header.data = url->data;
1428
1429 for (i = 1; i < url->len; i++) {
1430 if (url->data[i] == ':') {
1431 u->port_text.data = &url->data[i] + 1;
1432 u->host.len = i;
1433 }
1434
1435 if (url->data[i] == '/') {
1436 u->uri.data = &url->data[i];
1437 u->uri.len = url->len - i;
1438 u->host_header.len = i;
1439
1440 if (u->host.len == 0) {
1441 u->host.len = i;
1442 }
1443
1444 if (u->port_text.data == NULL) {
1445 u->default_port = 1;
1446 u->port = htons(80);
1447 u->port_text.len = 2;
1448 u->port_text.data = (u_char *) "80";
1449 return NULL;
1450 }
1451
1452 u->port_text.len = &url->data[i] - u->port_text.data;
1453
1454 if (u->port_text.len > 0) {
1455 u->port = (in_port_t) ngx_atoi(u->port_text.data,
1456 u->port_text.len);
1457 if (u->port > 0) {
1458
1459 if (u->port == 80) {
1460 u->default_port = 1;
1461 }
1462
1463 u->port = htons(u->port);
1464 return NULL;
1465 }
1466 }
1467
1468 return "invalid port in upstream URL";
1469 }
1470 }
1471
1472 if (u->host.len == 0) {
1473 u->host.len = i;
1474 }
1475
1476 u->host_header.len = i;
1477
1478 u->uri.data = (u_char *) "/";
1479 u->uri.len = 1;
1480
1481 if (u->port_text.data == NULL) {
1482 u->default_port = 1;
1483 u->port = htons(80);
1484 u->port_text.len = 2;
1485 u->port_text.data = (u_char *) "80";
1486 return NULL;
1487 }
1488
1489 u->port_text.len = &url->data[i] - u->port_text.data;
1490
1491 if (u->port_text.len > 0) {
1492 u->port = (in_port_t) ngx_atoi(u->port_text.data, u->port_text.len);
1493 if (u->port > 0) {
1494 u->port = htons(u->port);
1495 return NULL;
1496 }
1497 }
1498
1499 return "invalid port in upstream URL";
1500 } 1366 }
1501 1367
1502 1368
1503 static char *ngx_http_proxy_lowat_check(ngx_conf_t *cf, void *post, void *data) 1369 static char *ngx_http_proxy_lowat_check(ngx_conf_t *cf, void *post, void *data)
1504 { 1370 {