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