Mercurial > hg > nginx
comparison src/http/modules/proxy/ngx_http_proxy_handler.c @ 148:5afee0074707
nginx-0.0.1-2003-10-17-00:19:16 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Thu, 16 Oct 2003 20:19:16 +0000 |
parents | ef8c87afcfc5 |
children | ad5f382c9e7d |
comparison
equal
deleted
inserted
replaced
147:be71fca7f9d7 | 148:5afee0074707 |
---|---|
15 static void ngx_http_proxy_send_request(ngx_http_proxy_ctx_t *p); | 15 static void ngx_http_proxy_send_request(ngx_http_proxy_ctx_t *p); |
16 static void ngx_http_proxy_process_upstream_status_line(ngx_event_t *rev); | 16 static void ngx_http_proxy_process_upstream_status_line(ngx_event_t *rev); |
17 static void ngx_http_proxy_process_upstream_headers(ngx_event_t *rev); | 17 static void ngx_http_proxy_process_upstream_headers(ngx_event_t *rev); |
18 static ssize_t ngx_http_proxy_read_upstream_header(ngx_http_proxy_ctx_t *); | 18 static ssize_t ngx_http_proxy_read_upstream_header(ngx_http_proxy_ctx_t *); |
19 static void ngx_http_proxy_send_response(ngx_http_proxy_ctx_t *p); | 19 static void ngx_http_proxy_send_response(ngx_http_proxy_ctx_t *p); |
20 static void ngx_http_proxy_process_upstream_body(ngx_event_t *rev); | 20 static void ngx_http_proxy_process_upstream(ngx_event_t *rev); |
21 static void ngx_http_proxy_process_downstream(ngx_event_t *wev); | |
21 | 22 |
22 static int ngx_http_proxy_parse_status_line(ngx_http_proxy_ctx_t *p); | 23 static int ngx_http_proxy_parse_status_line(ngx_http_proxy_ctx_t *p); |
23 static void ngx_http_proxy_next_upstream(ngx_http_proxy_ctx_t *p); | 24 static void ngx_http_proxy_next_upstream(ngx_http_proxy_ctx_t *p); |
24 static void ngx_http_proxy_finalize_request(ngx_http_proxy_ctx_t *p, int rc); | 25 static void ngx_http_proxy_finalize_request(ngx_http_proxy_ctx_t *p, int rc); |
25 static void ngx_http_proxy_close_connection(ngx_connection_t *c); | 26 static void ngx_http_proxy_close_connection(ngx_connection_t *c); |
26 | 27 |
27 static int ngx_http_proxy_init(ngx_cycle_t *cycle); | 28 static int ngx_http_proxy_init(ngx_cycle_t *cycle); |
28 static void *ngx_http_proxy_create_loc_conf(ngx_conf_t *cf); | 29 static void *ngx_http_proxy_create_loc_conf(ngx_conf_t *cf); |
29 | 30 |
31 static char *ngx_http_proxy_set_pass(ngx_conf_t *cf, ngx_command_t *cmd, | |
32 void *conf); | |
33 static char *ngx_http_proxy_parse_upstream(ngx_str_t *url, | |
34 ngx_http_proxy_upstream_t *u); | |
35 | |
30 | 36 |
31 static ngx_command_t ngx_http_proxy_commands[] = { | 37 static ngx_command_t ngx_http_proxy_commands[] = { |
38 | |
39 {ngx_string("proxy_pass"), | |
40 NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
41 ngx_http_proxy_set_pass, | |
42 NGX_HTTP_LOC_CONF_OFFSET, | |
43 0, | |
44 NULL}, | |
45 | |
32 ngx_null_command | 46 ngx_null_command |
33 }; | 47 }; |
34 | 48 |
35 | 49 |
36 ngx_http_module_t ngx_http_proxy_module_ctx = { | 50 ngx_http_module_t ngx_http_proxy_module_ctx = { |
52 ngx_module_t ngx_http_proxy_module = { | 66 ngx_module_t ngx_http_proxy_module = { |
53 NGX_MODULE, | 67 NGX_MODULE, |
54 &ngx_http_proxy_module_ctx, /* module context */ | 68 &ngx_http_proxy_module_ctx, /* module context */ |
55 ngx_http_proxy_commands, /* module directives */ | 69 ngx_http_proxy_commands, /* module directives */ |
56 NGX_HTTP_MODULE, /* module type */ | 70 NGX_HTTP_MODULE, /* module type */ |
57 ngx_http_proxy_init, /* init module */ | 71 NULL, /* init module */ |
58 NULL /* init child */ | 72 NULL /* init child */ |
59 }; | 73 }; |
60 | 74 |
61 | 75 |
62 static ngx_str_t http_methods[] = { | 76 static ngx_str_t http_methods[] = { |
97 static char host_header[] = "Host: "; | 111 static char host_header[] = "Host: "; |
98 static char conn_close_header[] = "Connection: close" CRLF; | 112 static char conn_close_header[] = "Connection: close" CRLF; |
99 | 113 |
100 | 114 |
101 | 115 |
102 static int ngx_http_proxy_translate_handler(ngx_http_request_t *r) | |
103 { | |
104 #if 0 | |
105 r->handler = ngx_http_proxy_handler; | |
106 return NGX_OK; | |
107 #else | |
108 return NGX_DECLINED; | |
109 #endif | |
110 } | |
111 | |
112 | |
113 static int ngx_http_proxy_handler(ngx_http_request_t *r) | 116 static int ngx_http_proxy_handler(ngx_http_request_t *r) |
114 { | 117 { |
115 int rc; | 118 ngx_http_proxy_ctx_t *p; |
116 ngx_http_proxy_ctx_t *p; | |
117 ngx_http_proxy_loc_conf_t *lcf; | |
118 | 119 |
119 ngx_http_create_ctx(r, p, ngx_http_proxy_module, | 120 ngx_http_create_ctx(r, p, ngx_http_proxy_module, |
120 sizeof(ngx_http_proxy_ctx_t), | 121 sizeof(ngx_http_proxy_ctx_t), |
121 NGX_HTTP_INTERNAL_SERVER_ERROR); | 122 NGX_HTTP_INTERNAL_SERVER_ERROR); |
122 | 123 |
124 p->upstream.peers = p->lcf->peers; | 125 p->upstream.peers = p->lcf->peers; |
125 p->upstream.tries = p->lcf->peers->number; | 126 p->upstream.tries = p->lcf->peers->number; |
126 | 127 |
127 p->request = r; | 128 p->request = r; |
128 p->method = r->method; | 129 p->method = r->method; |
130 | |
131 /* TODO: from lcf->upstream */ | |
129 p->uri.data = "/"; | 132 p->uri.data = "/"; |
130 p->uri.len = 1; | 133 p->uri.len = 1; |
131 p->location_len = 1; | 134 p->location_len = 1; |
132 | 135 |
133 /* STUB */ p->accel = 1; | 136 /* STUB */ p->accel = 1; |
142 /* TODO: log->data would be changed, how to restore log->data ? */ | 145 /* TODO: log->data would be changed, how to restore log->data ? */ |
143 p->upstream.log = r->connection->log; | 146 p->upstream.log = r->connection->log; |
144 | 147 |
145 ngx_http_proxy_send_request(p); | 148 ngx_http_proxy_send_request(p); |
146 | 149 |
147 return NGX_OK; | 150 return NGX_DONE; |
148 } | 151 } |
149 | 152 |
150 | 153 |
151 static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_proxy_ctx_t *p) | 154 static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_proxy_ctx_t *p) |
152 { | 155 { |
578 } | 581 } |
579 | 582 |
580 | 583 |
581 static ssize_t ngx_http_proxy_read_upstream_header(ngx_http_proxy_ctx_t *p) | 584 static ssize_t ngx_http_proxy_read_upstream_header(ngx_http_proxy_ctx_t *p) |
582 { | 585 { |
583 int event; | |
584 ssize_t n; | 586 ssize_t n; |
585 ngx_event_t *rev; | 587 ngx_event_t *rev; |
586 | 588 |
587 rev = p->upstream.connection->read; | 589 rev = p->upstream.connection->read; |
588 | 590 |
589 n = p->header_in->last - p->header_in->pos; | 591 n = p->header_in->last - p->header_in->pos; |
590 | 592 |
591 if (n > 0) { | 593 if (n > 0) { |
594 #if 0 | |
595 /* TODO THINK */ | |
592 rev->ready = 0; | 596 rev->ready = 0; |
597 #endif | |
593 return n; | 598 return n; |
594 } | 599 } |
595 | 600 |
596 n = ngx_recv(p->upstream.connection, p->header_in->last, | 601 n = ngx_recv(p->upstream.connection, p->header_in->last, |
597 p->header_in->end - p->header_in->last); | 602 p->header_in->end - p->header_in->last); |
698 if (ep == NULL) { | 703 if (ep == NULL) { |
699 ngx_http_proxy_finalize_request(p, 0); | 704 ngx_http_proxy_finalize_request(p, 0); |
700 return; | 705 return; |
701 } | 706 } |
702 | 707 |
708 ep->input_filter = ngx_event_proxy_copy_input_filter; | |
703 ep->output_filter = (ngx_event_proxy_output_filter_pt) | 709 ep->output_filter = (ngx_event_proxy_output_filter_pt) |
704 ngx_http_output_filter; | 710 ngx_http_output_filter; |
705 ep->output_data = r; | 711 ep->output_ctx = r; |
706 ep->block_size = p->lcf->block_size; | 712 ep->bufs = p->lcf->bufs; |
707 ep->max_block_size = p->lcf->max_block_size; | 713 ep->max_busy_len = p->lcf->max_busy_len; |
708 ep->upstream = p->upstream.connection; | 714 ep->upstream = p->upstream.connection; |
709 ep->downstream = r->connection; | 715 ep->downstream = r->connection; |
710 ep->pool = r->pool; | 716 ep->pool = r->pool; |
711 ep->log = r->connection->log; | 717 ep->log = r->connection->log; |
712 ep->temp_path = p->lcf->temp_path; | 718 ep->temp_path = p->lcf->temp_path; |
740 #if 0 | 746 #if 0 |
741 lcx = p->log->data; | 747 lcx = p->log->data; |
742 lcx->action = "reading an upstream"; | 748 lcx->action = "reading an upstream"; |
743 #endif | 749 #endif |
744 | 750 |
745 ngx_event_proxy_read_upstream(ep); | |
746 | |
747 p->upstream.connection->read->event_handler = | 751 p->upstream.connection->read->event_handler = |
748 ngx_http_proxy_process_upstream_body; | 752 ngx_http_proxy_process_upstream; |
753 r->connection->write->event_handler = | |
754 ngx_http_proxy_process_downstream; | |
755 | |
756 ngx_http_proxy_process_upstream(p->upstream.connection->read); | |
749 | 757 |
750 return; | 758 return; |
751 } | 759 } |
752 | 760 |
753 | 761 |
754 static void ngx_http_proxy_process_upstream_body(ngx_event_t *rev) | 762 static void ngx_http_proxy_process_upstream(ngx_event_t *rev) |
755 { | 763 { |
756 ngx_connection_t *c; | 764 ngx_connection_t *c; |
757 ngx_http_proxy_ctx_t *p; | 765 ngx_http_proxy_ctx_t *p; |
758 | 766 |
759 c = rev->data; | 767 c = rev->data; |
760 p = c->data; | 768 p = c->data; |
761 | 769 |
762 ngx_log_debug(rev->log, "http proxy process upstream body"); | 770 ngx_log_debug(rev->log, "http proxy process upstream"); |
763 | 771 |
764 if (rev->timedout) { | 772 if (rev->timedout) { |
765 ngx_http_proxy_close_connection(p->upstream.connection); | 773 ngx_http_proxy_close_connection(c); |
766 p->upstream.connection = NULL; | 774 p->upstream.connection = NULL; |
767 return; | 775 return; |
768 } | 776 } |
769 | 777 |
770 ngx_event_proxy_read_upstream(p->event_proxy); | 778 if (ngx_event_proxy_read_upstream(p->event_proxy) == NGX_ABORT) { |
771 | 779 ngx_http_proxy_finalize_request(p, 0); |
772 if (p->event_proxy->upstream_eof) { | 780 return; |
773 ngx_http_proxy_close_connection(p->upstream.connection); | 781 } |
774 p->upstream.connection = NULL; | 782 |
775 return; | 783 if (p->event_proxy->upstream_eof |
776 } | 784 || p->event_proxy->upstream_error |
777 | 785 || p->event_proxy->upstream_done) |
778 if (p->event_proxy->upstream_error) { | 786 { |
779 ngx_http_proxy_close_connection(p->upstream.connection); | 787 ngx_http_proxy_finalize_request(p, ngx_http_send_last(p->request)); |
780 p->upstream.connection = NULL; | 788 return; |
789 } | |
790 | |
791 return; | |
792 } | |
793 | |
794 | |
795 static void ngx_http_proxy_process_downstream(ngx_event_t *wev) | |
796 { | |
797 ngx_connection_t *c; | |
798 ngx_http_proxy_ctx_t *p; | |
799 | |
800 c = wev->data; | |
801 p = c->data; | |
802 | |
803 ngx_log_debug(wev->log, "http proxy process downstream"); | |
804 | |
805 if (wev->timedout) { | |
806 ngx_http_close_connection(c); | |
807 return; | |
808 } | |
809 | |
810 if (ngx_event_proxy_write_to_downstream(p->event_proxy) == NGX_ABORT) { | |
811 ngx_http_proxy_finalize_request(p, 0); | |
812 return; | |
813 } | |
814 | |
815 if (p->event_proxy->downstream_done) { | |
816 ngx_http_proxy_finalize_request(p, 0); | |
817 return; | |
818 } | |
819 | |
820 if (p->event_proxy->downstream_error) { | |
821 ngx_http_close_connection(c); | |
781 return; | 822 return; |
782 } | 823 } |
783 | 824 |
784 return; | 825 return; |
785 } | 826 } |
1074 p->request->connection->addr_text.data, | 1115 p->request->connection->addr_text.data, |
1075 p->request->unparsed_uri.data); | 1116 p->request->unparsed_uri.data); |
1076 } | 1117 } |
1077 | 1118 |
1078 | 1119 |
1079 static int ngx_http_proxy_init(ngx_cycle_t *cycle) | |
1080 { | |
1081 ngx_http_handler_pt *h; | |
1082 ngx_http_conf_ctx_t *ctx; | |
1083 ngx_http_core_main_conf_t *cmcf; | |
1084 | |
1085 ctx = (ngx_http_conf_ctx_t *) cycle->conf_ctx[ngx_http_module.index]; | |
1086 cmcf = ctx->main_conf[ngx_http_core_module.ctx_index]; | |
1087 | |
1088 ngx_test_null(h, ngx_push_array( | |
1089 &cmcf->phases[NGX_HTTP_TRANSLATE_PHASE].handlers), | |
1090 NGX_ERROR); | |
1091 | |
1092 *h = ngx_http_proxy_translate_handler; | |
1093 | |
1094 return NGX_OK; | |
1095 } | |
1096 | |
1097 | |
1098 static void *ngx_http_proxy_create_loc_conf(ngx_conf_t *cf) | 1120 static void *ngx_http_proxy_create_loc_conf(ngx_conf_t *cf) |
1099 { | 1121 { |
1100 int i; | 1122 int i; |
1101 ngx_http_proxy_loc_conf_t *conf; | 1123 ngx_http_proxy_loc_conf_t *conf; |
1102 | 1124 |
1119 conf->connect_timeout = 30000; | 1141 conf->connect_timeout = 30000; |
1120 conf->send_timeout = 30000; | 1142 conf->send_timeout = 30000; |
1121 conf->header_size = 4096; | 1143 conf->header_size = 4096; |
1122 conf->read_timeout = 30000; | 1144 conf->read_timeout = 30000; |
1123 | 1145 |
1124 conf->block_size = 4096; | 1146 conf->bufs.num = 10; |
1125 conf->max_block_size = 4096 * 3; | 1147 conf->bufs.size = 4096; |
1148 conf->max_busy_len = 8192 + 4096; | |
1126 conf->max_temp_file_size = 4096 * 5; | 1149 conf->max_temp_file_size = 4096 * 5; |
1127 conf->temp_file_write_size = 4096 * 2; | 1150 conf->temp_file_write_size = 4096 * 2; |
1128 | 1151 |
1129 ngx_test_null(conf->temp_path, ngx_pcalloc(cf->pool, sizeof(ngx_path_t)), | 1152 ngx_test_null(conf->temp_path, ngx_pcalloc(cf->pool, sizeof(ngx_path_t)), |
1130 NULL); | 1153 NULL); |
1145 | 1168 |
1146 /* */ | 1169 /* */ |
1147 | 1170 |
1148 return conf; | 1171 return conf; |
1149 } | 1172 } |
1173 | |
1174 | |
1175 static char *ngx_http_proxy_set_pass(ngx_conf_t *cf, ngx_command_t *cmd, | |
1176 void *conf) | |
1177 { | |
1178 ngx_http_proxy_loc_conf_t *lcf = conf; | |
1179 | |
1180 int i, len; | |
1181 char *err, *host; | |
1182 ngx_str_t *value; | |
1183 struct hostent *h; | |
1184 u_int32_t addr; | |
1185 ngx_http_conf_ctx_t *ctx; | |
1186 ngx_http_core_loc_conf_t *clcf; | |
1187 | |
1188 | |
1189 value = cf->args->elts; | |
1190 | |
1191 if (ngx_strncasecmp(value[1].data, "http://", 7) != 0) { | |
1192 return "invalid URL prefix"; | |
1193 } | |
1194 | |
1195 ngx_test_null(lcf->upstream, | |
1196 ngx_pcalloc(cf->pool, sizeof(ngx_http_proxy_upstream_t)), | |
1197 NGX_CONF_ERROR); | |
1198 | |
1199 value[1].data += 7; | |
1200 value[1].len -= 7; | |
1201 | |
1202 err = ngx_http_proxy_parse_upstream(&value[1], lcf->upstream); | |
1203 | |
1204 if (err) { | |
1205 return err; | |
1206 } | |
1207 | |
1208 ngx_test_null(host, ngx_palloc(cf->pool, lcf->upstream->host.len + 1), | |
1209 NGX_CONF_ERROR); | |
1210 ngx_cpystrn(host, lcf->upstream->host.data, lcf->upstream->host.len + 1); | |
1211 | |
1212 addr = inet_addr(host); | |
1213 | |
1214 if (addr == INADDR_NONE) { | |
1215 h = gethostbyname(host); | |
1216 | |
1217 if (h == NULL || h->h_addr_list[0] == NULL) { | |
1218 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "host %s not found", host); | |
1219 return NGX_CONF_ERROR; | |
1220 } | |
1221 | |
1222 for (i = 0; h->h_addr_list[i] != NULL; i++) { /* void */ } | |
1223 | |
1224 /* MP: ngx_shared_palloc() */ | |
1225 | |
1226 ngx_test_null(lcf->peers, | |
1227 ngx_pcalloc(cf->pool, | |
1228 sizeof(ngx_peers_t) | |
1229 + sizeof(ngx_peer_t) * (i - 1)), | |
1230 NGX_CONF_ERROR); | |
1231 | |
1232 lcf->peers->number = i; | |
1233 | |
1234 for (i = 0; h->h_addr_list[i] != NULL; i++) { | |
1235 lcf->peers->peers[i].host.data = host; | |
1236 lcf->peers->peers[i].host.len = lcf->upstream->host.len; | |
1237 lcf->peers->peers[i].addr = *(u_int32_t *)(h->h_addr_list[i]); | |
1238 lcf->peers->peers[i].port = lcf->upstream->port; | |
1239 | |
1240 len = INET_ADDRSTRLEN + lcf->upstream->port_text.len + 1; | |
1241 ngx_test_null(lcf->peers->peers[i].addr_port_text.data, | |
1242 ngx_palloc(cf->pool, len), | |
1243 NGX_CONF_ERROR); | |
1244 | |
1245 len = ngx_inet_ntop(AF_INET, | |
1246 (char *) &lcf->peers->peers[i].addr, | |
1247 lcf->peers->peers[i].addr_port_text.data, | |
1248 len); | |
1249 | |
1250 lcf->peers->peers[i].addr_port_text.data[len++] = ':'; | |
1251 | |
1252 ngx_cpystrn(lcf->peers->peers[i].addr_port_text.data + len, | |
1253 lcf->upstream->port_text.data, | |
1254 lcf->upstream->port_text.len + 1); | |
1255 | |
1256 lcf->peers->peers[i].addr_port_text.len = | |
1257 len + lcf->upstream->port_text.len + 1; | |
1258 } | |
1259 | |
1260 } else { | |
1261 | |
1262 /* MP: ngx_shared_palloc() */ | |
1263 | |
1264 ngx_test_null(lcf->peers, ngx_pcalloc(cf->pool, sizeof(ngx_peers_t)), | |
1265 NGX_CONF_ERROR); | |
1266 | |
1267 lcf->peers->number = 1; | |
1268 | |
1269 lcf->peers->peers[0].host.data = host; | |
1270 lcf->peers->peers[0].host.len = lcf->upstream->host.len; | |
1271 lcf->peers->peers[0].addr = addr; | |
1272 lcf->peers->peers[0].port = lcf->upstream->port; | |
1273 | |
1274 len = lcf->upstream->host.len + lcf->upstream->port_text.len + 1; | |
1275 | |
1276 ngx_test_null(lcf->peers->peers[0].addr_port_text.data, | |
1277 ngx_palloc(cf->pool, len + 1), | |
1278 NGX_CONF_ERROR); | |
1279 | |
1280 len = lcf->upstream->host.len; | |
1281 | |
1282 ngx_memcpy(lcf->peers->peers[0].addr_port_text.data, | |
1283 lcf->upstream->host.data, len); | |
1284 | |
1285 lcf->peers->peers[0].addr_port_text.data[len++] = ':'; | |
1286 | |
1287 ngx_cpystrn(lcf->peers->peers[0].addr_port_text.data + len, | |
1288 lcf->upstream->port_text.data, | |
1289 lcf->upstream->port_text.len + 1); | |
1290 } | |
1291 | |
1292 ctx = cf->ctx; | |
1293 clcf = ctx->loc_conf[ngx_http_core_module.ctx_index]; | |
1294 lcf->upstream->location = &clcf->name; | |
1295 clcf->handler = ngx_http_proxy_handler; | |
1296 | |
1297 return NULL; | |
1298 } | |
1299 | |
1300 static char *ngx_http_proxy_parse_upstream(ngx_str_t *url, | |
1301 ngx_http_proxy_upstream_t *u) | |
1302 { | |
1303 size_t i; | |
1304 | |
1305 if (url->data[0] == ':' || url->data[0] == '/') { | |
1306 return "invalid upstream URL"; | |
1307 } | |
1308 | |
1309 u->host.data = url->data; | |
1310 u->host_header.data = url->data; | |
1311 | |
1312 for (i = 1; i < url->len; i++) { | |
1313 if (url->data[i] == ':') { | |
1314 u->port_text.data = &url->data[i] + 1; | |
1315 u->host.len = i; | |
1316 } | |
1317 | |
1318 if (url->data[i] == '/') { | |
1319 u->uri.data = &url->data[i]; | |
1320 u->uri.len = url->len - i; | |
1321 u->host_header.len = i; | |
1322 | |
1323 if (u->host.len == 0) { | |
1324 u->host.len = i; | |
1325 } | |
1326 | |
1327 if (u->port_text.data == NULL) { | |
1328 u->port = htons(80); | |
1329 u->port_text.len = 2; | |
1330 u->port_text.data = "80"; | |
1331 return NULL; | |
1332 } | |
1333 | |
1334 u->port_text.len = &url->data[i] - u->port_text.data; | |
1335 | |
1336 if (u->port_text.len > 0) { | |
1337 u->port = ngx_atoi(u->port_text.data, u->port_text.len); | |
1338 if (u->port > 0) { | |
1339 u->port = htons((u_short) u->port); | |
1340 return NULL; | |
1341 } | |
1342 } | |
1343 | |
1344 return "invalid port in upstream URL"; | |
1345 } | |
1346 } | |
1347 | |
1348 if (u->host.len == 0) { | |
1349 u->host.len = i; | |
1350 } | |
1351 | |
1352 u->host_header.len = i; | |
1353 | |
1354 u->uri.data = "/"; | |
1355 u->uri.len = 1; | |
1356 | |
1357 if (u->port_text.data == NULL) { | |
1358 u->port = htons(80); | |
1359 u->port_text.len = 2; | |
1360 u->port_text.data = "80"; | |
1361 return NULL; | |
1362 } | |
1363 | |
1364 u->port_text.len = &url->data[i] - u->port_text.data; | |
1365 | |
1366 if (u->port_text.len > 0) { | |
1367 u->port = ngx_atoi(u->port_text.data, u->port_text.len); | |
1368 if (u->port > 0) { | |
1369 u->port = htons((u_short) u->port); | |
1370 return NULL; | |
1371 } | |
1372 } | |
1373 | |
1374 return "invalid port in upstream URL"; | |
1375 } |