comparison src/http/modules/proxy/ngx_http_event_proxy_handler.c @ 75:869b10be682f

nginx-0.0.1-2003-04-14-21:04:58 import
author Igor Sysoev <igor@sysoev.ru>
date Mon, 14 Apr 2003 17:04:58 +0000
parents 17ab1af8c3dd
children 6127d7075471
comparison
equal deleted inserted replaced
74:17ab1af8c3dd 75:869b10be682f
5 #include <ngx_file.h> 5 #include <ngx_file.h>
6 #include <ngx_hunk.h> 6 #include <ngx_hunk.h>
7 #include <ngx_inet.h> 7 #include <ngx_inet.h>
8 #include <ngx_conf_file.h> 8 #include <ngx_conf_file.h>
9 #include <ngx_event_write.h> 9 #include <ngx_event_write.h>
10 #include <ngx_event_proxy.h>
10 11
11 #include <ngx_http.h> 12 #include <ngx_http.h>
12 #include <ngx_http_config.h> 13 #include <ngx_http_config.h>
13 #include <ngx_http_core_module.h> 14 #include <ngx_http_core_module.h>
14 #include <ngx_http_output_filter.h> 15 #include <ngx_http_output_filter.h>
15 #include <ngx_http_event_proxy_handler.h> 16 #include <ngx_http_event_proxy_handler.h>
16 17
18
19 /* STUB */
20 typedef struct {
21 int dummy;
22 } ngx_cache_header_t;
17 23
18 static int ngx_http_proxy_handler(ngx_http_request_t *r); 24 static int ngx_http_proxy_handler(ngx_http_request_t *r);
19 25
20 static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_proxy_ctx_t *p); 26 static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_proxy_ctx_t *p);
21 static int ngx_http_proxy_process_upstream(ngx_http_proxy_ctx_t *p, 27 static int ngx_http_proxy_process_upstream(ngx_http_proxy_ctx_t *p,
28 34
29 static int ngx_http_proxy_process_upstream_status_line(ngx_http_proxy_ctx_t *p); 35 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); 36 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); 37 static int ngx_http_proxy_process_upstream_header_line(ngx_http_proxy_ctx_t *p);
32 38
33 39 static int ngx_http_proxy_read_upstream_body(ngx_http_proxy_ctx_t *p);
34 static int ngx_http_proxy_write_upstream_body(ngx_event_t *wev); 40 static int ngx_http_proxy_write_upstream_body(ngx_http_proxy_ctx_t *p);
35 41
36 42
37 static int ngx_http_proxy_read_response_body(ngx_event_t *ev); 43 static int ngx_http_proxy_read_response_body(ngx_event_t *ev);
38 static int ngx_http_proxy_write_to_client(ngx_event_t *ev); 44 static int ngx_http_proxy_write_to_client(ngx_event_t *ev);
39 45
713 ngx_http_request_t *r; 719 ngx_http_request_t *r;
714 720
715 r = p->request; 721 r = p->request;
716 722
717 ngx_test_null(p->header_in, 723 ngx_test_null(p->header_in,
718 ngx_create_temp_hunk(r->pool, p->lcf->header_size, 0, 0), 724 ngx_create_temp_hunk(r->pool,
725 p->lcf->header_size
726 - sizeof(ngx_cache_header_t),
727 sizeof(ngx_cache_header_t),
728 0),
719 NGX_ERROR); 729 NGX_ERROR);
720 730
721 p->header_in->type = NGX_HUNK_MEMORY|NGX_HUNK_IN_MEMORY; 731 p->header_in->type = NGX_HUNK_MEMORY|NGX_HUNK_IN_MEMORY;
722 732
723 #if 0 733 #if 0
746 static int ngx_http_proxy_read_upstream_header(ngx_http_proxy_ctx_t *p) 756 static int ngx_http_proxy_read_upstream_header(ngx_http_proxy_ctx_t *p)
747 { 757 {
748 int i, n, rc; 758 int i, n, rc;
749 ngx_event_t *rev; 759 ngx_event_t *rev;
750 ngx_table_elt_t *ch, *ph; 760 ngx_table_elt_t *ch, *ph;
761 ngx_event_proxy_t *ep;
751 ngx_http_request_t *r; 762 ngx_http_request_t *r;
763 ngx_http_proxy_log_ctx_t *lcx;
752 764
753 rev = p->connection->read; 765 rev = p->connection->read;
754 766
755 do { 767 do {
756 n = ngx_event_recv(p->connection, p->header_in->last, 768 n = ngx_event_recv(p->connection, p->header_in->last,
831 843
832 r->headers_out.status = p->status; 844 r->headers_out.status = p->status;
833 845
834 rc = ngx_http_send_header(r); 846 rc = ngx_http_send_header(r);
835 847
848 #if 1
849 rc = ngx_http_output_filter(r, p->header_in);
850
851 ngx_test_null(ep, ngx_pcalloc(r->pool, sizeof(ngx_event_proxy_t)),
852 NGX_ERROR);
853
854 ep->output_filter = (ngx_event_proxy_output_filter_pt)
855 ngx_http_output_filter;
856 ep->output_data = r;
857 ep->block_size = p->lcf->block_size;
858 ep->max_block_size = p->lcf->max_block_size;
859 ep->file_block_size = p->lcf->file_block_size;
860 ep->upstream = p->connection;
861 ep->client = r->connection;
862 ep->pool = r->pool;
863 ep->log = p->log;
864 ep->temp_path = p->lcf->temp_path;
865
866 ngx_test_null(ep->temp_file, ngx_palloc(r->pool, sizeof(ngx_file_t)),
867 NGX_ERROR);
868 ep->temp_file->fd = NGX_INVALID_FILE;
869 ep->temp_file->log = p->log;
870
871 ep->number = 10;
872 ep->random = 5;
873
874 ep->max_temp_size = 6000;
875 ep->temp_file_warn = "an upstream response is buffered "
876 "to a temporary file";
877
878 p->event_proxy = ep;
879
880 lcx = p->log->data;
881 lcx->action = "reading an upstream";
882
883 p->state_read_upstream_handler = ngx_http_proxy_read_upstream_body;
884 p->state_write_upstream_handler = ngx_http_proxy_write_upstream_body;
885
886 ngx_http_proxy_read_upstream_body(p);
887 #endif
888
889 #if 0
836 /* STUB */ 890 /* STUB */
837 p->header_in->type |= NGX_HUNK_LAST; 891 p->header_in->type |= NGX_HUNK_LAST;
838 rc = ngx_http_output_filter(r, p->header_in); 892 rc = ngx_http_output_filter(r, p->header_in);
839 ngx_http_proxy_finalize_request(p, NGX_OK); 893 ngx_http_proxy_finalize_request(p, NGX_OK);
894 #endif
840 895
841 /* STUB */ return NGX_DONE; 896 /* STUB */ return NGX_DONE;
842 } 897 }
843 898
844 if (rc > NGX_OK) { 899 if (rc > NGX_OK) {
1028 1083
1029 return NGX_OK; 1084 return NGX_OK;
1030 } 1085 }
1031 1086
1032 1087
1088 static int ngx_http_proxy_read_upstream_body(ngx_http_proxy_ctx_t *p)
1089 {
1090 int rc;
1091
1092 rc = ngx_event_proxy_read_upstream(p->event_proxy);
1093 if (rc == NGX_OK) {
1094 rc = ngx_event_close_connection(p->connection->read);
1095 }
1096
1097 return rc;
1098 }
1099
1100
1101 static int ngx_http_proxy_write_upstream_body(ngx_http_proxy_ctx_t *p)
1102 {
1103 return ngx_event_proxy_write_to_client(p->event_proxy);
1104 }
1105
1106
1107 #if 0
1033 static int ngx_http_proxy_read_upstream_body(ngx_event_t *rev) 1108 static int ngx_http_proxy_read_upstream_body(ngx_event_t *rev)
1034 { 1109 {
1035 int rc, n, size; 1110 int rc, n, size, eof;
1036 ngx_hunk_t *h; 1111 ngx_hunk_t *h;
1037 ngx_chain_t *chain, chain_entry, *ce, *te; 1112 ngx_chain_t *chain, *ce, *tce;
1113 ngx_event_t *wev;
1038 ngx_connection_t *c; 1114 ngx_connection_t *c;
1039 ngx_http_request_t *r; 1115 ngx_http_request_t *r;
1040 ngx_http_proxy_ctx_t *p; 1116 ngx_http_proxy_ctx_t *p;
1041 1117
1042 c = (ngx_connection_t *) rev->data; 1118 c = (ngx_connection_t *) rev->data;
1043 r = (ngx_http_request_t *) c->data; 1119 r = (ngx_http_request_t *) c->data;
1044 p = (ngx_http_proxy_ctx_t *) 1120 p = (ngx_http_proxy_ctx_t *)
1045 ngx_http_get_module_ctx(r, ngx_http_proxy_module_ctx); 1121 ngx_http_get_module_ctx(r, ngx_http_proxy_module_ctx);
1046 1122
1047 chain_entry.next = NULL; 1123 eof = 0;
1048 1124
1049 for ( ;; ) { 1125 for ( ;; ) {
1050 1126
1051 #if (USE_KQUEUE) 1127 #if (USE_KQUEUE)
1052 1128
1053 if (ev->eof && ev->available == 0) { 1129 if (ev->eof && ev->available == 0) {
1130 eof = 1;
1054 break; 1131 break;
1055 } 1132 }
1056 1133
1057 #elif (HAVE_KQUEUE0) 1134 #elif (HAVE_KQUEUE0)
1058 1135
1059 if (ngx_event_type == NGX_HAVE_KQUEUE_EVENT 1136 if (ngx_event_type == NGX_HAVE_KQUEUE_EVENT
1060 && ev->eof && ev->available == 0) 1137 && ev->eof && ev->available == 0)
1061 { 1138 {
1139 eof = 1;
1062 break; 1140 break;
1063 } 1141 }
1064 1142
1065 #endif 1143 #endif
1144
1145 /* use the free hunks if they exist */
1066 1146
1067 if (p->free_hunks) { 1147 if (p->free_hunks) {
1068 chain = p->free_hunks; 1148 chain = p->free_hunks;
1069 p->free_hunks = NULL; 1149 p->free_hunks = NULL;
1150
1151 /* allocate a new hunk if it's still allowed */
1070 1152
1071 } else if (p->allocated < p->lcf->max_block_size) { 1153 } else if (p->allocated < p->lcf->max_block_size) {
1072 ngx_test_null(h, 1154 ngx_test_null(h,
1073 ngx_create_temp_hunk(r->pool, p->block_size, 50, 50), 1155 ngx_create_temp_hunk(r->pool, p->block_size, 50, 50),
1074 NGX_ERROR); 1156 NGX_ERROR);
1075 1157
1076 p->allocated += p->block_size; 1158 p->allocated += p->block_size;
1077 chain_entry.hunk = h; 1159
1078 chain = &chain_entry; 1160 ngx_test_null(tce, ngx_create_chain_entry(r->pool), NGX_ERROR);
1161 tce->hunk = h;
1162 tce->next = NULL;
1163 chain = tce;
1164
1165 /* use the shadow hunks if they exist */
1166
1167 } else if (p->shadow_hunks) {
1168 chain = p->shadow_hunks;
1169 p->shadow_hunks = NULL;
1170
1171 /* write all the incoming hunks or the first hunk only
1172 to a temporary file and convert them to the shadow hunks */
1079 1173
1080 } else { 1174 } else {
1081 if (p->temp_file->fd == NGX_INVALID_FILE) { 1175 if (r->cachable) {
1082 rc = ngx_create_temp_file(p->temp_file, p->lcf->temp_path, 1176 rc = ngx_http_proxy_write_chain_to_temp_file(p);
1083 r->pool, 0, 2, r->cachable);
1084
1085 if (rc != NGX_OK) { 1177 if (rc != NGX_OK) {
1086 return rc; 1178 return rc;
1087 } 1179 }
1088 1180
1089 if (p->lcf->temp_file_warn) { 1181 } else {
1090 ngx_log_error(NGX_LOG_WARN, p->log, 0, 1182 tce = p->in_hunks->next;
1091 "an upstream response is buffered " 1183 p->in_hunks->next = NULL;
1092 "to a temporary file"); 1184
1185 rc = ngx_http_proxy_write_chain_to_temp_file(p);
1186 if (rc != NGX_OK) {
1187 p->in_hunks = tce;
1188 return rc;
1093 } 1189 }
1094 } 1190
1095 1191 p->in_hunks = tce;
1096 n = ngx_write_chain_to_file(p->temp_file, p->in_hunks,
1097 p->temp_offset, r->pool);
1098
1099 if (n == NGX_ERROR) {
1100 return NGX_ERROR;
1101 }
1102
1103 for (ce = p->in_hunks; ce; ce = ce->next) {
1104 ngx_test_null(h, ngx_pcalloc(r->pool, sizeof(ngx_hunk_t)),
1105 NGX_ERROR);
1106
1107 h->type = NGX_HUNK_FILE
1108 |NGX_HUNK_TEMP|NGX_HUNK_IN_MEMORY|NGX_HUNK_RECYCLED;
1109
1110 ce->hunk->shadow = h;
1111 h->shadow = ce->hunk;
1112
1113 h->file_pos = p->temp_offset;
1114 p->temp_offset += ce->hunk->last - ce->hunk->pos;
1115 h->file_last = p->temp_offset;
1116
1117 h->file->fd = p->temp_file->fd;
1118 h->file->log = p->log;
1119
1120 h->pos = ce->hunk->pos;
1121 h->last = ce->hunk->last;
1122 h->start = ce->hunk->start;
1123 h->end = ce->hunk->end;
1124 h->pre_start = ce->hunk->pre_start;
1125 h->post_end = ce->hunk->post_end;
1126
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 } 1192 }
1139 } 1193 }
1140 1194
1141 n = ngx_recv_chain(c, chain); 1195 n = ngx_recv_chain(c, chain);
1142 1196
1147 if (n == NGX_AGAIN) { 1201 if (n == NGX_AGAIN) {
1148 return NGX_AGAIN; 1202 return NGX_AGAIN;
1149 } 1203 }
1150 1204
1151 if (n == 0) { 1205 if (n == 0) {
1206 eof = 1;
1152 break; 1207 break;
1153 } 1208 }
1154 1209
1155 for (ce = chain; ce && n > 0; ce = ce->next) { 1210 for (ce = chain; ce && n > 0; ce = ce->next) {
1156 ngx_test_null(te, ngx_create_chain_entry(r->pool), NGX_ERROR); 1211 ngx_test_null(tce, ngx_create_chain_entry(r->pool), NGX_ERROR);
1157 te->hunk = ce->hunk; 1212 tce->hunk = ce->hunk;
1158 te->next = NULL; 1213 tce->next = NULL;
1159 1214
1160 if (p->last_in_hunk) { 1215 if (p->last_in_hunk) {
1161 p->last_in_hunk->next = te; 1216 p->last_in_hunk->next = tce;
1162 p->last_in_hunk = te; 1217 p->last_in_hunk = tce;
1163 1218
1164 } else { 1219 } else {
1165 p->last_in_hunk = te; 1220 p->last_in_hunk = tce;
1166 } 1221 }
1167 1222
1168 size = ce->hunk->end - ce->hunk->last; 1223 size = ce->hunk->end - ce->hunk->last;
1169 1224
1170 if (n >= size) { 1225 if (n >= size) {
1194 1249
1195 if (ce) { 1250 if (ce) {
1196 ce->next = p->free_hunks; 1251 ce->next = p->free_hunks;
1197 p->free_hunks = ce; 1252 p->free_hunks = ce;
1198 break; 1253 break;
1199 1254 }
1200 return NGX_OK; 1255 }
1201 } 1256
1202 } 1257 wev = p->request->connection->write;
1203 1258
1204 if (p->out_hunks && p->request->connection->write->ready) { 1259 if (r->cachable) {
1205 return 1260 if (p->in_hunks) {
1206 ngx_http_proxy_write_upstream_body(p->request->connection->write); 1261 rc = ngx_http_proxy_write_chain_to_temp_file(p);
1262 if (rc != NGX_OK) {
1263 return rc;
1264 }
1265 }
1266
1267 if (p->out_hunks && wev->ready) {
1268 return ngx_http_proxy_write_upstream_body(wev);
1269 }
1270
1271 } else {
1272 if ((p->out_hunks || p->in_hunks) && wev->ready) {
1273 return ngx_http_proxy_write_upstream_body(wev);
1274 }
1207 } 1275 }
1208 1276
1209 return NGX_OK; 1277 return NGX_OK;
1210 } 1278 }
1211 1279
1280
1281 static int ngx_http_proxy_write_chain_to_temp_file(ngx_http_proxy_ctx_t *p)
1282 {
1283 int i, rc;
1284 ngx_hunk_t *h;
1285 ngx_chain_t *ce, *tce;
1286
1287 if (p->temp_file->fd == NGX_INVALID_FILE) {
1288 rc = ngx_create_temp_file(p->temp_file, p->lcf->temp_path,
1289 p->request->pool,
1290 0, 2,
1291 p->request->cachable);
1292
1293 if (rc != NGX_OK) {
1294 return rc;
1295 }
1296
1297 if (p->lcf->temp_file_warn) {
1298 ngx_log_error(NGX_LOG_WARN, p->log, 0,
1299 "an upstream response is buffered "
1300 "to a temporary file");
1301 }
1302 }
1303
1304 if (ngx_write_chain_to_file(p->temp_file, p->in_hunks,
1305 p->temp_offset, p->request->pool) == NGX_ERROR) {
1306 return NGX_ERROR;
1307 }
1308
1309 for (ce = p->in_hunks; ce; ce = ce->next) {
1310 ngx_test_null(h, ngx_pcalloc(p->request->pool, sizeof(ngx_hunk_t)),
1311 NGX_ERROR);
1312
1313 h->type = NGX_HUNK_FILE
1314 |NGX_HUNK_TEMP|NGX_HUNK_IN_MEMORY|NGX_HUNK_RECYCLED;
1315
1316 ce->hunk->shadow = h;
1317 h->shadow = ce->hunk;
1318
1319 h->file_pos = p->temp_offset;
1320 p->temp_offset += ce->hunk->last - ce->hunk->pos;
1321 h->file_last = p->temp_offset;
1322
1323 h->file->fd = p->temp_file->fd;
1324 h->file->log = p->log;
1325
1326 h->pos = ce->hunk->pos;
1327 h->last = ce->hunk->last;
1328 h->start = ce->hunk->start;
1329 h->end = ce->hunk->end;
1330 h->pre_start = ce->hunk->pre_start;
1331 h->post_end = ce->hunk->post_end;
1332
1333 ngx_test_null(tce, ngx_create_chain_entry(p->request->pool), NGX_ERROR);
1334 tce->hunk = h;
1335 tce->next = NULL;
1336
1337 if (p->last_out_hunk) {
1338 p->last_out_hunk->next = tce;
1339 p->last_out_hunk = tce;
1340
1341 } else {
1342 p->last_out_hunk = tce;
1343 }
1344 }
1345
1346 return NGX_OK;
1347 }
1212 1348
1213 static int ngx_http_proxy_write_upstream_body(ngx_event_t *wev) 1349 static int ngx_http_proxy_write_upstream_body(ngx_event_t *wev)
1214 { 1350 {
1215 int rc; 1351 int rc;
1216 ngx_hunk_t *h, *sh; 1352 ngx_hunk_t *h, *sh;
1254 1390
1255 return NGX_OK; 1391 return NGX_OK;
1256 } 1392 }
1257 1393
1258 1394
1259 1395 #endif
1260 1396
1261 1397
1262 1398
1263 1399
1264 static int ngx_http_proxy_read_response_body(ngx_event_t *ev) 1400 static int ngx_http_proxy_read_response_body(ngx_event_t *ev)
1626 conf->connect_timeout = 10000; 1762 conf->connect_timeout = 10000;
1627 conf->send_timeout = 10000; 1763 conf->send_timeout = 10000;
1628 conf->read_timeout = 10000; 1764 conf->read_timeout = 10000;
1629 conf->header_size = 1024; 1765 conf->header_size = 1024;
1630 conf->block_size = 4096; 1766 conf->block_size = 4096;
1631 conf->max_block_size = 32768; 1767 conf->max_block_size = 4096 * 3;
1768 conf->file_block_size = 4096;
1632 1769
1633 ngx_test_null(conf->temp_path, ngx_pcalloc(pool, sizeof(ngx_path_t)), NULL); 1770 ngx_test_null(conf->temp_path, ngx_pcalloc(pool, sizeof(ngx_path_t)), NULL);
1634 1771
1635 conf->temp_path->name.data = "temp"; 1772 conf->temp_path->name.data = "temp";
1636 conf->temp_path->name.len = 4; 1773 conf->temp_path->name.len = 4;