Mercurial > hg > nginx-quic
diff src/http/modules/ngx_http_event_proxy_handler.c @ 67:5a7d1aaa1618
nginx-0.0.1-2003-03-11-23:38:13 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Tue, 11 Mar 2003 20:38:13 +0000 |
parents | 50186b49f2ad |
children | e43f406e4525 |
line wrap: on
line diff
--- a/src/http/modules/ngx_http_event_proxy_handler.c +++ b/src/http/modules/ngx_http_event_proxy_handler.c @@ -4,12 +4,53 @@ #include <ngx_string.h> #include <ngx_file.h> #include <ngx_hunk.h> +#include <ngx_conf_file.h> #include <ngx_event_write.h> + #include <ngx_http.h> +#include <ngx_http_config.h> +#include <ngx_http_core_module.h> #include <ngx_http_output_filter.h> #include <ngx_http_event_proxy_handler.h> -ngx_http_module_t ngx_http_proxy_module_ctx; + +static ngx_command_t ngx_http_proxy_commands[] = { + + {ngx_string("proxy_large_header"), + NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_flag_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_proxy_loc_conf_t, large_header)}, + + {ngx_null_string, 0, NULL, 0, 0} +}; + + +static ngx_http_module_t ngx_http_proxy_module_ctx = { + NGX_HTTP_MODULE, + + NULL, /* create server config */ + NULL, /* init server config */ + NULL, /* create location config */ + NULL, /* merge location config */ + + NULL, /* translate handler */ + + NULL, /* output header filter */ + NULL, /* next output header filter */ + NULL, /* output body filter */ + NULL /* next output body filter */ +}; + + +ngx_module_t ngx_http_proxy_module = { + 0, /* module index */ + &ngx_http_proxy_module_ctx, /* module context */ + ngx_http_proxy_commands, /* module directives */ + NGX_HTTP_MODULE_TYPE, /* module type */ + NULL /* init module */ +}; + static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_request_t *r); @@ -18,6 +59,7 @@ static int ngx_http_proxy_connect(ngx_ht char *addr_text); static int ngx_http_proxy_send_request(ngx_event_t *ev); +static int ngx_http_proxy_init_response(ngx_event_t *ev); static int ngx_http_proxy_read_response_header(ngx_event_t *ev); static int ngx_http_proxy_process_status_line(ngx_http_request_t *r, ngx_http_proxy_ctx_t *p); @@ -45,12 +87,13 @@ int ngx_http_proxy_handler(ngx_http_requ if (p == NULL) { ngx_http_create_ctx(r, p, ngx_http_proxy_module_ctx, - sizeof(ngx_http_proxy_ctx_t)); + sizeof(ngx_http_proxy_ctx_t), + NGX_HTTP_INTERNAL_SERVER_ERROR); } chain = ngx_http_proxy_create_request(r); if (chain == NULL) { - return NGX_ERROR; + return NGX_HTTP_INTERNAL_SERVER_ERROR; } p->out = chain; @@ -74,8 +117,13 @@ static ngx_chain_t *ngx_http_proxy_creat /* 2 is for "\r\n" after request line and 2 is for "\r\n" at the header end */ + + /* STUB: "method p->url HTTP/1.0" length */ + len = r->request_line.len + 2 + 2; + /* TODO: Host length */ + /* "Connection: close\r\n" */ len += sizeof(conn_close) - 1; @@ -98,12 +146,16 @@ static ngx_chain_t *ngx_http_proxy_creat ngx_test_null(hunk, ngx_create_temp_hunk(r->pool, len, 0, 0), NULL); ngx_add_hunk_to_chain(chain, hunk, r->pool, NULL); - ngx_memcpy(hunk->last.mem, r->request_line.data, r->request_line.len); - hunk->last.mem += r->request_line.len; - *(hunk->last.mem++) = CR; *(hunk->last.mem++) = LF; + /* STUB: "method p->url HTTP/1.0" */ - ngx_memcpy(hunk->last.mem, conn_close, sizeof(conn_close) - 1); - hunk->last.mem += sizeof(conn_close) - 1; + ngx_memcpy(hunk->last, r->request_line.data, r->request_line.len); + hunk->last += r->request_line.len; + *(hunk->last++) = CR; *(hunk->last++) = LF; + + /* TODO: Host header */ + + ngx_memcpy(hunk->last, conn_close, sizeof(conn_close) - 1); + hunk->last += sizeof(conn_close) - 1; for (i = 0; i < r->headers_in.headers->nelts; i++) { if (&header[i] == r->headers_in.host) { @@ -114,25 +166,25 @@ static ngx_chain_t *ngx_http_proxy_creat continue; } - ngx_memcpy(hunk->last.mem, header[i].key.data, header[i].key.len); - hunk->last.mem += header[i].key.len; + ngx_memcpy(hunk->last, header[i].key.data, header[i].key.len); + hunk->last += header[i].key.len; - *(hunk->last.mem++) = ':'; *(hunk->last.mem++) = ' '; + *(hunk->last++) = ':'; *(hunk->last++) = ' '; - ngx_memcpy(hunk->last.mem, header[i].value.data, header[i].value.len); - hunk->last.mem += header[i].value.len; + ngx_memcpy(hunk->last, header[i].value.data, header[i].value.len); + hunk->last += header[i].value.len; - *(hunk->last.mem++) = CR; *(hunk->last.mem++) = LF; + *(hunk->last++) = CR; *(hunk->last++) = LF; ngx_log_debug(r->connection->log, "proxy: '%s: %s'" _ header[i].key.data _ header[i].value.data); } /* add "\r\n" at the header end */ - *(hunk->last.mem++) = CR; *(hunk->last.mem++) = LF; + *(hunk->last++) = CR; *(hunk->last++) = LF; - /* STUB */ *(hunk->last.mem++) = '\0'; - ngx_log_debug(r->connection->log, "PROXY:\n'%s'" _ hunk->pos.mem); + /* STUB */ *(hunk->last++) = '\0'; + ngx_log_debug(r->connection->log, "PROXY:\n'%s'" _ hunk->pos); return chain; } @@ -142,7 +194,7 @@ static int ngx_http_proxy_connect(ngx_ht struct sockaddr_in *addr, char *addr_text) { - int rc; + int rc, event; ngx_err_t err; ngx_socket_t s; ngx_event_t *rev, *wev; @@ -157,7 +209,7 @@ static int ngx_http_proxy_connect(ngx_ht if (s == -1) { ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno, ngx_socket_n " failed"); - return NGX_ERROR; + return NGX_HTTP_INTERNAL_SERVER_ERROR; } #if 0 @@ -172,7 +224,7 @@ static int ngx_http_proxy_connect(ngx_ht ngx_close_socket_n " failed"); } - return NGX_ERROR; + return NGX_HTTP_INTERNAL_SERVER_ERROR; } } #endif @@ -186,7 +238,7 @@ static int ngx_http_proxy_connect(ngx_ht ngx_close_socket_n " failed"); } - return NGX_ERROR; + return NGX_HTTP_INTERNAL_SERVER_ERROR; } rc = connect(s, (struct sockaddr *) addr, sizeof(struct sockaddr_in)); @@ -201,7 +253,7 @@ static int ngx_http_proxy_connect(ngx_ht ngx_close_socket_n " failed"); } - return NGX_ERROR; + return NGX_HTTP_INTERNAL_SERVER_ERROR; } } @@ -226,21 +278,48 @@ static int ngx_http_proxy_connect(ngx_ht ngx_test_null(pc->pool, ngx_create_pool(/* STUB */ 1024 /**/, pc->log), - NGX_ERROR); + NGX_HTTP_INTERNAL_SERVER_ERROR); wev->event_handler = ngx_http_proxy_send_request; - rev->event_handler = ngx_http_proxy_read_response_header; + rev->event_handler = ngx_http_proxy_init_response; -#if (HAVE_CLEAR_EVENT) +#if (USE_KQUEUE) + if (ngx_add_event(rev, NGX_READ_EVENT, NGX_CLEAR_EVENT) != NGX_OK) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + #else - if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT) != NGX_OK) { -#endif - return NGX_ERROR; + +#if (HAVE_CLEAR_EVENT) /* kqueue */ + + if (ngx_event_flags & NGX_HAVE_CLEAR_EVENT) { + event = NGX_CLEAR_EVENT; + + } else { + event = NGX_LEVEL_EVENT; } +#else /* select, poll, /dev/poll */ + + event = NGX_LEVEL_EVENT; + +#endif + + if (ngx_add_event(rev, NGX_READ_EVENT, event) != NGX_OK) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + +#endif /* USE_KQUEUE */ + + /* TODO: aio, iocp */ + + /* The connection is in a progress */ if (rc == -1) { - return ngx_add_event(wev, NGX_WRITE_EVENT, NGX_ONESHOT_EVENT); + /* TODO: oneshot */ + if (ngx_add_event(wev, NGX_WRITE_EVENT, NGX_ONESHOT_EVENT) != NGX_OK) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } } wev->write = 1; @@ -262,7 +341,7 @@ static int ngx_http_proxy_send_request(n p = (ngx_http_proxy_ctx_t *) ngx_http_get_module_ctx(r, ngx_http_proxy_module_ctx); - chain = ngx_event_write(c, p->out, 0); + chain = ngx_write_chain(c, p->out, 0); if (chain == (ngx_chain_t *) -1) { return NGX_ERROR; } @@ -273,7 +352,7 @@ static int ngx_http_proxy_send_request(n } -static int ngx_http_proxy_read_response_header(ngx_event_t *ev) +static int ngx_http_proxy_init_response(ngx_event_t *ev) { int n; ngx_hunk_t **ph; @@ -281,48 +360,126 @@ static int ngx_http_proxy_read_response_ ngx_http_request_t *r; ngx_http_proxy_ctx_t *p; + c = (ngx_connection_t *) ev->data; + r = (ngx_http_request_t *) c->data; + if (ev->timedout) { - return NGX_ERROR; + return ngx_http_proxy_error(r, p, NGX_HTTP_GATEWAY_TIME_OUT); } + p = (ngx_http_proxy_ctx_t *) + ngx_http_get_module_ctx(r, ngx_http_proxy_module_ctx); + + ngx_test_null(p->header_in, + ngx_create_temp_hunk(r->pool, + /* STUB */ 1024 /**/, 0, 0), + ngx_http_proxy_error(r, p, NGX_HTTP_INTERNAL_SERVER_ERROR)); + + p->header_in->type = NGX_HUNK_MEMORY|NGX_HUNK_IN_MEMORY; + + ngx_test_null(p->headers_in, + ngx_palloc(r->pool, sizeof(ngx_http_proxy_headers_in_t)), + ngx_http_proxy_error(r, p, NGX_HTTP_INTERNAL_SERVER_ERROR)); + + ngx_init_array(p->hunks, r->pool, + /* STUB */ 10 /**/, + sizeof(ngx_hunk_t *), + ngx_http_proxy_error(r, p, NGX_HTTP_INTERNAL_SERVER_ERROR)); + + ngx_test_null(ph, ngx_push_array(&p->hunks), NGX_ERROR); + *ph = p->header_in; + + p->state_handler = ngx_http_proxy_process_status_line; + + return ngx_http_proxy_read_response_header(ev); +} + + +static int ngx_http_proxy_read_response_header(ngx_event_t *ev) +{ + int n; + ngx_hunk_t **ph; + ngx_connection_t *c; + ngx_http_request_t *r; + ngx_http_proxy_ctx_t *p; + ngx_http_proxy_loc_conf_t *lcf; + c = (ngx_connection_t *) ev->data; r = (ngx_http_request_t *) c->data; p = (ngx_http_proxy_ctx_t *) - ngx_http_get_module_ctx(r, ngx_http_proxy_module_ctx); - - if (p->header_in == NULL) { - ngx_test_null(p->header_in, - ngx_create_temp_hunk(r->pool, - /* STUB */ 1024 /**/, 0, 0), - NGX_ERROR); - - p->header_in->type = NGX_HUNK_MEMORY; + ngx_http_get_module_ctx(r, ngx_http_proxy_module); - ngx_test_null(p->headers_in, - ngx_palloc(r->pool, sizeof(ngx_http_proxy_headers_in_t)), - NGX_ERROR); - - ngx_init_array(p->hunks, r->pool, - /* STUB */ 10 /**/, - sizeof(ngx_hunk_t *), - NGX_ERROR); - - ngx_test_null(ph, ngx_push_array(&p->hunks), NGX_ERROR); - *ph = p->header_in; - - p->state_handler = ngx_http_proxy_process_status_line; + if (ev->timedout) { + return ngx_http_proxy_error(r, p, NGX_HTTP_GATEWAY_TIME_OUT); } - n = ngx_event_recv(c, p->header_in->last.mem, - p->header_in->end - p->header_in->last.mem); + lcf = (ngx_http_proxy_loc_conf_t *) + ngx_http_get_module_loc_conf(r, ngx_http_proxy_module); + + +#if 0 + + do { + n = ngx_event_recv(c, p->header_in->last, + p->header_in->end - p->header_in->last; + + if (n == NGX_AGAIN) { + if (ev->timer_set) { + ngx_del_timer(ev); + } else { + ev->timer_set = 1; + } + + ngx_add_timer(ev, lcf->timeout); + return NGX_AGAIN; + } + + if (n == NGX_ERROR) { + ngx_http_proxy_close_request(r, p); + return ngx_http_error(r, NGX_HTTP_BAD_GATEWAY); + } + + ngx_log_debug(c->log, "http proxy read %d" _ n); + + if (n == 0) { + ngx_log_error(NGX_LOG_INFO, c->log, 0, + "client has prematurely closed connection"); + ngx_http_proxy_close_request(r, p); + } + + p->header_in->last += n; + + if (lcf->large_header && p->header_in->end == p->header_in->last) { + again = 1; + } else { + again = 0; + } + + + + +#if (HAVE_AIO_EVENT) /* aio, iocp */ + + if (ngx_event_flags & NGX_HAVE_AIO_EVENT) { + again = 1; + } + +#endif + + } while (rc == NGX_AGAIN && again); + +#endif + + n = ngx_event_recv(c, p->header_in->last, + p->header_in->end - p->header_in->last); ngx_log_debug(c->log, "READ:%d" _ n); - p->header_in->last.mem += n; + p->header_in->last += n; /* STUB */ - *p->header_in->last.mem = '\0'; - ngx_log_debug(c->log, "PROXY:\n'%s'" _ p->header_in->pos.mem); + *p->header_in->last = '\0'; + ngx_log_debug(c->log, "PROXY:\n'%s'" _ p->header_in->pos); /**/ if (n == 0) { @@ -355,13 +512,14 @@ static int ngx_http_proxy_read_response_ #endif ev->event_handler = ngx_http_proxy_read_response_body; - if (p->header_in->end - p->header_in->last.mem == 0) { + if (p->header_in->end - p->header_in->last == 0) { return ngx_http_proxy_read_response_body(ev); } return NGX_WAITING; } + static int ngx_http_proxy_process_status_line(ngx_http_request_t *r, ngx_http_proxy_ctx_t *p) { @@ -380,7 +538,7 @@ static int ngx_http_proxy_process_status p->state_handler = NULL; } - if (p->header_in->last.mem >= p->header_in->end) { + if (p->header_in->last >= p->header_in->end) { rc = NGX_HTTP_PARSE_TOO_LONG_STATUS_LINE; } else if (rc == NGX_AGAIN) { @@ -390,6 +548,7 @@ static int ngx_http_proxy_process_status /* STUB */ return NGX_ERROR; } + #if 0 static int ngx_http_proxy_process_response_header(ngx_http_request_t *r, ngx_http_proxy_ctx_t *p) @@ -398,6 +557,7 @@ static int ngx_http_proxy_process_respon } #endif + static int ngx_http_proxy_read_response_body(ngx_event_t *ev) { int n; @@ -419,7 +579,7 @@ static int ngx_http_proxy_read_response_ if (p->hunks.nelts > 0) { h = ((ngx_hunk_t **) p->hunks.elts)[p->hunks.nelts - 1]; - left = h->end - h->last.mem; + left = h->end - h->last; } else { h = NULL; @@ -453,13 +613,13 @@ static int ngx_http_proxy_read_response_ /* STUB */ 4096 /**/, 0, 0), NGX_ERROR); - h->type = NGX_HUNK_MEMORY; + h->type = NGX_HUNK_MEMORY|NGX_HUNK_IN_MEMORY; *ph = h; } if (h != NULL) { - buf = h->last.mem; - size = h->end - h->last.mem; + buf = h->last; + size = h->end - h->last; } else { buf = (char *) &buf; @@ -478,12 +638,12 @@ static int ngx_http_proxy_read_response_ return NGX_ERROR; } - h->last.mem += n; - left = h->end - h->last.mem; + h->last += n; + left = h->end - h->last; /* STUB */ - *h->last.mem = '\0'; - ngx_log_debug(c->log, "PROXY:\n'%s'" _ h->pos.mem); + *h->last = '\0'; + ngx_log_debug(c->log, "PROXY:\n'%s'" _ h->pos); /**/ } while (n > 0 && left == 0); @@ -503,6 +663,7 @@ static int ngx_http_proxy_read_response_ /* STUB */ return NGX_WAITING; } + static int ngx_http_proxy_write_to_client(ngx_event_t *ev) { int rc; @@ -536,6 +697,15 @@ static int ngx_http_proxy_write_to_clien } +static int ngx_http_proxy_error(ngx_http_request_t *r, ngx_http_proxy_ctx_t *p, + int error) +{ + ngx_event_close_connection(p->connection->read); + + return ngx_http_error(r, error); +} + + static int ngx_read_http_proxy_status_line(ngx_http_proxy_ctx_t *ctx) { char ch; @@ -554,21 +724,16 @@ static int ngx_read_http_proxy_status_li } state; state = ctx->state; - p = ctx->header_in->pos.mem; - - while (p < ctx->header_in->last.mem && state < sw_done) { - ch = *p++; + p = ctx->header_in->pos; -#if 0 -fprintf(stderr, "state: %d, pos: %x, end: %x, char: '%c', status: %d\n", - state, p, ctx->header_in->last.mem, ch, ctx->status); -#endif + while (p < ctx->header_in->last && state < sw_done) { + ch = *p++; switch (state) { /* "HTTP/" */ case sw_start: - if (p + 3 >= ctx->header_in->last.mem) { + if (p + 3 >= ctx->header_in->last) { return NGX_AGAIN; } @@ -684,7 +849,7 @@ fprintf(stderr, "state: %d, pos: %x, end } } - ctx->header_in->pos.mem = p; + ctx->header_in->pos = p; if (state == sw_done) { if (ctx->request_end == NULL) {