Mercurial > hg > nginx-quic
comparison src/http/modules/proxy/ngx_http_event_proxy_handler.c @ 74:17ab1af8c3dd
nginx-0.0.1-2003-04-11-20:01:14 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Fri, 11 Apr 2003 16:01:14 +0000 |
parents | 4534060fde92 |
children | 869b10be682f |
comparison
equal
deleted
inserted
replaced
73:4534060fde92 | 74:17ab1af8c3dd |
---|---|
29 static int ngx_http_proxy_process_upstream_status_line(ngx_http_proxy_ctx_t *p); | 29 static int ngx_http_proxy_process_upstream_status_line(ngx_http_proxy_ctx_t *p); |
30 static int ngx_http_proxy_process_upstream_headers(ngx_http_proxy_ctx_t *p); | 30 static int ngx_http_proxy_process_upstream_headers(ngx_http_proxy_ctx_t *p); |
31 static int ngx_http_proxy_process_upstream_header_line(ngx_http_proxy_ctx_t *p); | 31 static int ngx_http_proxy_process_upstream_header_line(ngx_http_proxy_ctx_t *p); |
32 | 32 |
33 | 33 |
34 static int ngx_http_proxy_write_upstream_body(ngx_event_t *wev); | |
35 | |
36 | |
34 static int ngx_http_proxy_read_response_body(ngx_event_t *ev); | 37 static int ngx_http_proxy_read_response_body(ngx_event_t *ev); |
35 static int ngx_http_proxy_write_to_client(ngx_event_t *ev); | 38 static int ngx_http_proxy_write_to_client(ngx_event_t *ev); |
36 | 39 |
37 static int ngx_read_http_proxy_status_line(ngx_http_proxy_ctx_t *ctx); | 40 static int ngx_read_http_proxy_status_line(ngx_http_proxy_ctx_t *ctx); |
38 | 41 |
39 static int ngx_http_proxy_finalize_request(ngx_http_proxy_ctx_t *p, int error); | 42 static int ngx_http_proxy_finalize_request(ngx_http_proxy_ctx_t *p, int error); |
40 static size_t ngx_http_proxy_log_error(void *data, char *buf, size_t len); | 43 static size_t ngx_http_proxy_log_error(void *data, char *buf, size_t len); |
41 | 44 |
45 static int ngx_http_proxy_init(ngx_pool_t *pool); | |
42 static void *ngx_http_proxy_create_loc_conf(ngx_pool_t *pool); | 46 static void *ngx_http_proxy_create_loc_conf(ngx_pool_t *pool); |
43 | 47 |
44 static char *ngx_http_proxy_set_pass(ngx_conf_t *cf, ngx_command_t *cmd, | 48 static char *ngx_http_proxy_set_pass(ngx_conf_t *cf, ngx_command_t *cmd, |
45 char *conf); | 49 char *conf); |
46 | 50 |
80 ngx_module_t ngx_http_proxy_module = { | 84 ngx_module_t ngx_http_proxy_module = { |
81 0, /* module index */ | 85 0, /* module index */ |
82 &ngx_http_proxy_module_ctx, /* module context */ | 86 &ngx_http_proxy_module_ctx, /* module context */ |
83 ngx_http_proxy_commands, /* module directives */ | 87 ngx_http_proxy_commands, /* module directives */ |
84 NGX_HTTP_MODULE_TYPE, /* module type */ | 88 NGX_HTTP_MODULE_TYPE, /* module type */ |
85 NULL /* init module */ | 89 ngx_http_proxy_init /* init module */ |
86 }; | 90 }; |
87 | 91 |
88 | 92 |
89 static ngx_str_t http_methods[] = { | 93 static ngx_str_t http_methods[] = { |
90 ngx_string("GET "), | 94 ngx_string("GET "), |
177 if (chain == NULL) { | 181 if (chain == NULL) { |
178 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 182 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
179 } | 183 } |
180 | 184 |
181 /* TODO: duplicate the hunks and chain if there is backend farm */ | 185 /* TODO: duplicate the hunks and chain if there is backend farm */ |
182 p->out = chain; | 186 p->request_hunks = chain; |
183 | 187 |
184 p->last_error = NGX_HTTP_BAD_GATEWAY; | 188 p->last_error = NGX_HTTP_BAD_GATEWAY; |
185 ngx_http_proxy_process_upstream(p, NULL); | 189 ngx_http_proxy_process_upstream(p, NULL); |
186 | 190 |
187 /* On an error ngx_http_proxy_process_upstream() calls | 191 /* On an error ngx_http_proxy_process_upstream() calls |
677 static int ngx_http_proxy_send_request(ngx_http_proxy_ctx_t *p) | 681 static int ngx_http_proxy_send_request(ngx_http_proxy_ctx_t *p) |
678 { | 682 { |
679 ngx_chain_t *chain; | 683 ngx_chain_t *chain; |
680 ngx_event_t *wev; | 684 ngx_event_t *wev; |
681 | 685 |
682 chain = ngx_write_chain(p->connection, p->out, 0); | 686 chain = ngx_write_chain(p->connection, p->request_hunks, 0); |
683 if (chain == (ngx_chain_t *) -1) { | 687 if (chain == (ngx_chain_t *) -1) { |
684 return NGX_ERROR; | 688 return NGX_ERROR; |
685 } | 689 } |
686 | 690 |
687 p->out = chain; | 691 p->request_hunks = chain; |
688 | 692 |
689 wev = p->connection->write; | 693 wev = p->connection->write; |
690 | 694 |
691 ngx_del_timer(wev); | 695 ngx_del_timer(wev); |
692 | 696 |
1024 | 1028 |
1025 return NGX_OK; | 1029 return NGX_OK; |
1026 } | 1030 } |
1027 | 1031 |
1028 | 1032 |
1029 #if 0 | |
1030 | |
1031 static int ngx_http_proxy_read_upstream_body(ngx_event_t *rev) | 1033 static int ngx_http_proxy_read_upstream_body(ngx_event_t *rev) |
1032 { | 1034 { |
1035 int rc, n, size; | |
1033 ngx_hunk_t *h; | 1036 ngx_hunk_t *h; |
1034 ngx_chain_t *chain, ce; | 1037 ngx_chain_t *chain, chain_entry, *ce, *te; |
1035 ngx_connection_t *c; | 1038 ngx_connection_t *c; |
1036 ngx_http_request_t *r; | 1039 ngx_http_request_t *r; |
1037 ngx_http_proxy_ctx_t *p; | 1040 ngx_http_proxy_ctx_t *p; |
1038 | 1041 |
1039 c = (ngx_connection_t *) rev->data; | 1042 c = (ngx_connection_t *) rev->data; |
1040 r = (ngx_http_request_t *) c->data; | 1043 r = (ngx_http_request_t *) c->data; |
1041 p = (ngx_http_proxy_ctx_t *) | 1044 p = (ngx_http_proxy_ctx_t *) |
1042 ngx_http_get_module_ctx(r, ngx_http_proxy_module_ctx); | 1045 ngx_http_get_module_ctx(r, ngx_http_proxy_module_ctx); |
1043 | 1046 |
1044 ce.next = NULL; | 1047 chain_entry.next = NULL; |
1045 | 1048 |
1046 do { | 1049 for ( ;; ) { |
1047 | 1050 |
1048 #if (USE_KQUEUE) | 1051 #if (USE_KQUEUE) |
1049 | 1052 |
1050 if (ev->eof && ev->available == 0) { | 1053 if (ev->eof && ev->available == 0) { |
1051 break; | 1054 break; |
1052 } | 1055 } |
1053 | 1056 |
1054 #elif (HAVE_KQUEUE) | 1057 #elif (HAVE_KQUEUE0) |
1055 | 1058 |
1056 if (ngx_event_type == NGX_HAVE_KQUEUE_EVENT | 1059 if (ngx_event_type == NGX_HAVE_KQUEUE_EVENT |
1057 && ev->eof && ev->available == 0) | 1060 && ev->eof && ev->available == 0) |
1058 { | 1061 { |
1059 break; | 1062 break; |
1061 | 1064 |
1062 #endif | 1065 #endif |
1063 | 1066 |
1064 if (p->free_hunks) { | 1067 if (p->free_hunks) { |
1065 chain = p->free_hunks; | 1068 chain = p->free_hunks; |
1069 p->free_hunks = NULL; | |
1066 | 1070 |
1067 } else if (p->allocated < p->lcf->max_block_size) { | 1071 } else if (p->allocated < p->lcf->max_block_size) { |
1068 ngx_test_null(h, | 1072 ngx_test_null(h, |
1069 ngx_create_temp_hunk(r->pool, p->block_size, 50, 50), | 1073 ngx_create_temp_hunk(r->pool, p->block_size, 50, 50), |
1070 NGX_ERROR); | 1074 NGX_ERROR); |
1071 | 1075 |
1072 p->allocated += p->block_size; | 1076 p->allocated += p->block_size; |
1073 ce.hunk = h; | 1077 chain_entry.hunk = h; |
1074 chain = &ce; | 1078 chain = &chain_entry; |
1075 | 1079 |
1076 } else { | 1080 } else { |
1077 if (p->temp_fd == NGX_INVALID_FILE) { | 1081 if (p->temp_file->fd == NGX_INVALID_FILE) { |
1078 rc = ngx_create_temp_file(p->temp_file, r->cachable); | 1082 rc = ngx_create_temp_file(p->temp_file, p->lcf->temp_path, |
1083 r->pool, 0, 2, r->cachable); | |
1079 | 1084 |
1080 if (rc != NGX_OK) { | 1085 if (rc != NGX_OK) { |
1081 return rc; | 1086 return rc; |
1082 } | 1087 } |
1083 | 1088 |
1087 "to a temporary file"); | 1092 "to a temporary file"); |
1088 } | 1093 } |
1089 } | 1094 } |
1090 | 1095 |
1091 n = ngx_write_chain_to_file(p->temp_file, p->in_hunks, | 1096 n = ngx_write_chain_to_file(p->temp_file, p->in_hunks, |
1092 p->temp_offset); | 1097 p->temp_offset, r->pool); |
1093 | 1098 |
1094 if (n == NGX_ERROR) { | 1099 if (n == NGX_ERROR) { |
1095 return NGX_ERROR; | 1100 return NGX_ERROR; |
1096 } | 1101 } |
1097 | 1102 |
1098 ngx_test_null(h, ngx_pcalloc(r->pool, sizeof(ngx_hunk_t)), | 1103 for (ce = p->in_hunks; ce; ce = ce->next) { |
1099 NGX_ERROR); | 1104 ngx_test_null(h, ngx_pcalloc(r->pool, sizeof(ngx_hunk_t)), |
1100 | 1105 NGX_ERROR); |
1101 h->type = NGX_HUNK_FILE | 1106 |
1102 |NGX_HUNK_IN_MEMORY|NGX_HUNK_TEMP|NGX_HUNK_RECYCLED; | 1107 h->type = NGX_HUNK_FILE |
1103 | 1108 |NGX_HUNK_TEMP|NGX_HUNK_IN_MEMORY|NGX_HUNK_RECYCLED; |
1104 h->file_pos = p->temp_offset; | 1109 |
1105 p->temp_offset += n; | 1110 ce->hunk->shadow = h; |
1106 h->file_last = p->temp_offset; | 1111 h->shadow = ce->hunk; |
1107 | 1112 |
1108 h->file->fd = p->temp_file.fd; | 1113 h->file_pos = p->temp_offset; |
1109 h->file->log = p->log; | 1114 p->temp_offset += ce->hunk->last - ce->hunk->pos; |
1110 | 1115 h->file_last = p->temp_offset; |
1111 h->pos = p->in_hunks->hunk->pos; | 1116 |
1112 h->last = p->in_hunks->hunk->last; | 1117 h->file->fd = p->temp_file->fd; |
1113 h->start = p->in_hunks->hunk->start; | 1118 h->file->log = p->log; |
1114 h->end = p->in_hunks->hunk->end; | 1119 |
1115 h->pre_start = p->in_hunks->hunk->pre_start; | 1120 h->pos = ce->hunk->pos; |
1116 h->post_end = p->in_hunks->hunk->post_end; | 1121 h->last = ce->hunk->last; |
1117 | 1122 h->start = ce->hunk->start; |
1118 ngx_add_hunk_to_chain(p->last_out_hunk, h, r->pool, NGX_ERROR); | 1123 h->end = ce->hunk->end; |
1119 | 1124 h->pre_start = ce->hunk->pre_start; |
1120 ce.hunk = p->in_hunks->next; | 1125 h->post_end = ce->hunk->post_end; |
1121 p->in_hunks = p->in_hunks->next; | 1126 |
1122 chain = &ce; | 1127 ngx_test_null(te, ngx_create_chain_entry(r->pool), NGX_ERROR); |
1128 te->hunk = h; | |
1129 te->next = NULL; | |
1130 | |
1131 if (p->last_out_hunk) { | |
1132 p->last_out_hunk->next = te; | |
1133 p->last_out_hunk = te; | |
1134 | |
1135 } else { | |
1136 p->last_out_hunk = te; | |
1137 } | |
1138 } | |
1123 } | 1139 } |
1124 | 1140 |
1125 n = ngx_recv_chain(c, chain); | 1141 n = ngx_recv_chain(c, chain); |
1126 | 1142 |
1127 h->last += n; | 1143 if (n == NGX_ERROR) { |
1128 left = hunk->end - hunk->last; | 1144 return NGX_ERROR; |
1129 | 1145 } |
1130 } while (n > 0 && left == 0); | 1146 |
1147 if (n == NGX_AGAIN) { | |
1148 return NGX_AGAIN; | |
1149 } | |
1150 | |
1151 if (n == 0) { | |
1152 break; | |
1153 } | |
1154 | |
1155 for (ce = chain; ce && n > 0; ce = ce->next) { | |
1156 ngx_test_null(te, ngx_create_chain_entry(r->pool), NGX_ERROR); | |
1157 te->hunk = ce->hunk; | |
1158 te->next = NULL; | |
1159 | |
1160 if (p->last_in_hunk) { | |
1161 p->last_in_hunk->next = te; | |
1162 p->last_in_hunk = te; | |
1163 | |
1164 } else { | |
1165 p->last_in_hunk = te; | |
1166 } | |
1167 | |
1168 size = ce->hunk->end - ce->hunk->last; | |
1169 | |
1170 if (n >= size) { | |
1171 n -= size; | |
1172 ce->hunk->last = ce->hunk->end; | |
1173 if (ce->hunk->shadow) { | |
1174 ce->hunk->shadow->type &= ~(NGX_HUNK_TEMP | |
1175 |NGX_HUNK_IN_MEMORY | |
1176 |NGX_HUNK_RECYCLED); | |
1177 ce->hunk->shadow->shadow = NULL; | |
1178 | |
1179 } | |
1180 | |
1181 continue; | |
1182 } | |
1183 | |
1184 ce->hunk->last += n; | |
1185 if (ce->hunk->shadow) { | |
1186 ce->hunk->shadow->type &= ~(NGX_HUNK_TEMP | |
1187 |NGX_HUNK_IN_MEMORY | |
1188 |NGX_HUNK_RECYCLED); | |
1189 ce->hunk->shadow->shadow = NULL; | |
1190 } | |
1191 | |
1192 break; | |
1193 } | |
1194 | |
1195 if (ce) { | |
1196 ce->next = p->free_hunks; | |
1197 p->free_hunks = ce; | |
1198 break; | |
1199 | |
1200 return NGX_OK; | |
1201 } | |
1202 } | |
1131 | 1203 |
1132 if (p->out_hunks && p->request->connection->write->ready) { | 1204 if (p->out_hunks && p->request->connection->write->ready) { |
1133 ngx_http_proxy_write_upstream_body(p->request->connection->write); | 1205 return |
1134 } | 1206 ngx_http_proxy_write_upstream_body(p->request->connection->write); |
1207 } | |
1208 | |
1209 return NGX_OK; | |
1135 } | 1210 } |
1136 | 1211 |
1137 | 1212 |
1138 static int ngx_http_proxy_write_upstream_body(ngx_event_t *wev) | 1213 static int ngx_http_proxy_write_upstream_body(ngx_event_t *wev) |
1139 { | 1214 { |
1140 while (out) { | 1215 int rc; |
1141 output_filter(r, hunk); | 1216 ngx_hunk_t *h, *sh; |
1142 if (again) | 1217 ngx_chain_t *ce; |
1143 return | 1218 ngx_connection_t *c; |
1144 | 1219 ngx_http_request_t *r; |
1145 if (hunk done) | 1220 ngx_http_proxy_ctx_t *p; |
1146 remove from out | 1221 |
1147 if (hunk is memory) | 1222 c = (ngx_connection_t *) wev->data; |
1148 add it to free | 1223 r = (ngx_http_request_t *) c->data; |
1149 } | 1224 p = (ngx_http_proxy_ctx_t *) |
1150 } | 1225 ngx_http_get_module_ctx(r, ngx_http_proxy_module_ctx); |
1151 | 1226 |
1152 | 1227 while (p->out_hunks) { |
1153 | 1228 h = p->out_hunks->hunk; |
1154 #endif | 1229 rc = ngx_http_output_filter(r, h); |
1230 | |
1231 if (rc == NGX_ERROR) { | |
1232 return NGX_ERROR; | |
1233 } | |
1234 | |
1235 if (rc == NGX_AGAIN || h->pos < h->last) { | |
1236 return NGX_AGAIN; | |
1237 } | |
1238 | |
1239 p->out_hunks = p->out_hunks->next; | |
1240 | |
1241 /* if the complete hunk has a shadow hunk | |
1242 then add a shadow hunk to p->free_hunks chain */ | |
1243 | |
1244 sh = h->shadow; | |
1245 | |
1246 if (sh) { | |
1247 sh->pos = sh->last = sh->start; | |
1248 ngx_test_null(ce, ngx_create_chain_entry(r->pool), NGX_ERROR); | |
1249 ce->hunk = sh; | |
1250 ce->next = p->free_hunks; | |
1251 p->free_hunks = ce; | |
1252 } | |
1253 } | |
1254 | |
1255 return NGX_OK; | |
1256 } | |
1257 | |
1258 | |
1155 | 1259 |
1156 | 1260 |
1157 | 1261 |
1158 | 1262 |
1159 | 1263 |
1480 return NGX_AGAIN; | 1584 return NGX_AGAIN; |
1481 } | 1585 } |
1482 } | 1586 } |
1483 | 1587 |
1484 | 1588 |
1589 static int ngx_http_proxy_init(ngx_pool_t *pool) | |
1590 { | |
1591 int i; | |
1592 ngx_file_t file; | |
1593 ngx_path_t path; | |
1594 | |
1595 file.log = pool->log; | |
1596 | |
1597 path.name.data = "temp"; | |
1598 path.name.len = 4; | |
1599 path.level[0] = 1; | |
1600 path.level[1] = 2; | |
1601 path.level[2] = 3; | |
1602 path.len = 0; | |
1603 | |
1604 for (i = 0; i < 3; i++) { | |
1605 if (path.level[i] == 0) { | |
1606 break; | |
1607 } | |
1608 path.len += path.level[i] + 1; | |
1609 } | |
1610 | |
1611 return ngx_create_temp_file(&file, &path, pool, 123456789, 2, 0); | |
1612 } | |
1613 | |
1614 | |
1485 static void *ngx_http_proxy_create_loc_conf(ngx_pool_t *pool) | 1615 static void *ngx_http_proxy_create_loc_conf(ngx_pool_t *pool) |
1486 { | 1616 { |
1487 ngx_http_proxy_loc_conf_t *conf; | 1617 int i; |
1618 ngx_http_proxy_loc_conf_t *conf; | |
1488 | 1619 |
1489 ngx_test_null(conf, | 1620 ngx_test_null(conf, |
1490 ngx_pcalloc(pool, sizeof(ngx_http_proxy_loc_conf_t)), | 1621 ngx_pcalloc(pool, sizeof(ngx_http_proxy_loc_conf_t)), |
1491 NULL); | 1622 NULL); |
1492 | 1623 |
1496 conf->send_timeout = 10000; | 1627 conf->send_timeout = 10000; |
1497 conf->read_timeout = 10000; | 1628 conf->read_timeout = 10000; |
1498 conf->header_size = 1024; | 1629 conf->header_size = 1024; |
1499 conf->block_size = 4096; | 1630 conf->block_size = 4096; |
1500 conf->max_block_size = 32768; | 1631 conf->max_block_size = 32768; |
1632 | |
1633 ngx_test_null(conf->temp_path, ngx_pcalloc(pool, sizeof(ngx_path_t)), NULL); | |
1634 | |
1635 conf->temp_path->name.data = "temp"; | |
1636 conf->temp_path->name.len = 4; | |
1637 conf->temp_path->level[0] = 1; | |
1638 conf->temp_path->level[1] = 2; | |
1639 conf->temp_path->level[2] = 3; | |
1640 conf->temp_path->len = 0; | |
1641 | |
1642 for (i = 0; i < 3; i++) { | |
1643 if (conf->temp_path->level[i] == 0) { | |
1644 break; | |
1645 } | |
1646 conf->temp_path->len += conf->temp_path->level[i] + 1; | |
1647 } | |
1501 /**/ | 1648 /**/ |
1502 | 1649 |
1503 return conf; | 1650 return conf; |
1504 } | 1651 } |
1505 | 1652 |