ngx_chain_t *ce);
-
int ngx_event_proxy(ngx_event_proxy_t *p, int do_write)
{
for ( ;; ) {
chain = p->free_raw_hunks;
p->free_raw_hunks = NULL;
+ngx_log_debug(p->log, "FREE: %08X:%d" _ chain->hunk->pos _ chain->hunk->end - chain->hunk->last);
} else if (p->hunks < p->bufs.num) {
ngx_log_debug(p->log, "recv_chain: %d" _ n);
+ p->free_raw_hunks = chain;
+
if (n == NGX_ERROR) {
p->upstream_error = 1;
return NGX_ERROR;
p->read = 1;
if (n == 0) {
- p->free_raw_hunks = chain;
p->upstream_eof = 1;
-
break;
}
}
- for (ce = chain; ce && n > 0; ce = ce->next) {
+ ce = chain;
+
+ while (ce && n > 0) {
ngx_remove_shadow_links(ce->hunk);
}
n -= size;
-
- chain = ce->next;
+ ce = ce->next;
} else {
+ngx_log_debug(p->log, "PART: %08X:%d:%d" _ ce->hunk->pos _ ce->hunk->last - ce->hunk->pos _ n);
ce->hunk->last += n;
+ngx_log_debug(p->log, "PART: %08X:%d" _ ce->hunk->pos _ ce->hunk->end - ce->hunk->last);
n = 0;
}
}
- p->free_raw_hunks = chain;
+ p->free_raw_hunks = ce;
}
if ((p->upstream_eof || p->upstream_error) && p->free_raw_hunks) {
rc = p->output_filter(p->output_ctx, out->hunk);
if (rc == NGX_ERROR) {
- /* TODO */
+ p->downstream_error = 1;
+ return NGX_ERROR;
}
ngx_chain_update_chains(&p->free, &p->busy, &out);
/* add the free shadow raw hunks to p->free_raw_hunks */
for (ce = p->free; ce; ce = ce->next) {
+ngx_log_debug(p->log, "SHADOW %08X" _ ce->hunk->shadow);
if (ce->hunk->type & NGX_HUNK_LAST_SHADOW) {
h = ce->hunk->shadow;
/* THINK NEEDED ??? */ h->pos = h->last = h->start;
h->shadow = NULL;
- ngx_alloc_ce_and_set_hunk(te, ce->hunk->shadow, p->pool,
- NGX_ABORT);
+ ngx_alloc_ce_and_set_hunk(te, h, p->pool, NGX_ABORT);
ngx_add_after_partially_filled_hunk(&p->free_raw_hunks, te);
+ngx_log_debug(p->log, "RAW %08X" _ h->pos);
+
ce->hunk->type &= ~NGX_HUNK_LAST_SHADOW;
}
ce->hunk->shadow = NULL;
}
- if (p->upstream_done && p->in == NULL && p->out == NULL) {
+ ngx_log_debug(p->log, "STATE %d:%d:%d:%X:%X" _
+ p->upstream_eof _
+ p->upstream_error _
+ p->upstream_done _
+ p->in _
+ p->out
+ );
+
+ if ((p->upstream_eof || p->upstream_error || p->upstream_done)
+ && p->in == NULL && p->out == NULL)
+ {
p->downstream_done = 1;
}
ce = p->in;
do {
- size += ce->hunk->last - ce->hunk->pos;
- if (size >= p->temp_file_write_size) {
+ if (size + ce->hunk->last - ce->hunk->pos
+ >= p->temp_file_write_size)
+ {
break;
}
+ size += ce->hunk->last - ce->hunk->pos;
ce = ce->next;
} while (ce);
- in = ce->next;
- last = &ce->next;
- ce->next = NULL;
+ if (ce) {
+ in = ce->next;
+ last = &ce->next;
+ ce->next = NULL;
+
+ } else {
+ in = NULL;
+ last = &p->in;
+ }
} else {
in = NULL;
static void ngx_http_proxy_process_upstream_headers(ngx_event_t *rev);
static ssize_t ngx_http_proxy_read_upstream_header(ngx_http_proxy_ctx_t *);
static void ngx_http_proxy_send_response(ngx_http_proxy_ctx_t *p);
-static void ngx_http_proxy_process_upstream(ngx_event_t *rev);
-static void ngx_http_proxy_process_downstream(ngx_event_t *wev);
+static void ngx_http_proxy_process_body(ngx_event_t *ev);
static int ngx_http_proxy_parse_status_line(ngx_http_proxy_ctx_t *p);
static void ngx_http_proxy_next_upstream(ngx_http_proxy_ctx_t *p);
continue;
}
- /* TODO: delete "Keep-Alive" header */
+ if (&header[i] == r->headers_in.keep_alive) {
+ continue;
+ }
h->last = ngx_cpymem(h->last, header[i].key.data, header[i].key.len);
ep->preread_size = p->header_in->last - p->header_in->pos;
+ /* STUB */ ep->cachable = 0;
+
p->event_proxy = ep;
#if 0
lcx->action = "reading an upstream";
#endif
- p->upstream.connection->read->event_handler =
- ngx_http_proxy_process_upstream;
- r->connection->write->event_handler =
- ngx_http_proxy_process_downstream;
+ p->upstream.connection->read->event_handler = ngx_http_proxy_process_body;
+ r->connection->write->event_handler = ngx_http_proxy_process_body;
- ngx_http_proxy_process_upstream(p->upstream.connection->read);
+ ngx_http_proxy_process_body(p->upstream.connection->read);
return;
}
-static void ngx_http_proxy_process_upstream(ngx_event_t *rev)
+static void ngx_http_proxy_process_body(ngx_event_t *ev)
{
ngx_connection_t *c;
+ ngx_http_request_t *r;
ngx_http_proxy_ctx_t *p;
+ ngx_event_proxy_t *ep;
- c = rev->data;
- p = c->data;
+ c = ev->data;
- ngx_log_debug(rev->log, "http proxy process upstream");
-
- if (rev->timedout) {
- ngx_http_proxy_close_connection(c);
- p->upstream.connection = NULL;
- return;
- }
+ if (ev->write) {
+ ngx_log_debug(ev->log, "http proxy process downstream");
+ r = c->data;
+ p = ngx_http_get_module_ctx(r, ngx_http_proxy_module);
- if (ngx_event_proxy(p->event_proxy, 0) == NGX_ABORT) {
- ngx_http_proxy_finalize_request(p, 0);
- return;
+ } else {
+ ngx_log_debug(ev->log, "http proxy process upstream");
+ p = c->data;
+ r = p->request;
}
- if (p->event_proxy->upstream_eof
- || p->event_proxy->upstream_error
- || p->event_proxy->upstream_done)
- {
- ngx_http_proxy_close_connection(c);
- p->upstream.connection = NULL;
- return;
- }
+ ep = p->event_proxy;
- return;
-}
+ if (ev->timedout) {
+ if (ev->write) {
+ ep->downstream_error = 1;
+ } else {
+ ep->upstream_error = 1;
+ }
-static void ngx_http_proxy_process_downstream(ngx_event_t *wev)
-{
- ngx_connection_t *c;
- ngx_http_request_t *r;
- ngx_http_proxy_ctx_t *p;
+ } else {
+ if (ngx_event_proxy(ep, ev->write) == NGX_ABORT) {
+ ngx_http_proxy_finalize_request(p, 0);
+ return;
+ }
+ }
- c = wev->data;
- r = c->data;
- p = ngx_http_get_module_ctx(r, ngx_http_proxy_module);
-
- ngx_log_debug(wev->log, "http proxy process downstream");
+ if (p->upstream.connection) {
+ if (ep->upstream_done) {
+ /* TODO: update cache */
- if (wev->timedout) {
- ngx_http_close_connection(c);
- return;
- }
+ } else if (ep->upstream_eof) {
+ /* TODO: check length & update cache */
+ }
- if (ngx_event_proxy(p->event_proxy, 1) == NGX_ABORT) {
- ngx_http_proxy_finalize_request(p, 0);
- return;
+ if (ep->upstream_done || ep->upstream_eof || ep->upstream_error) {
+ ngx_http_proxy_close_connection(c);
+ p->upstream.connection = NULL;
+ }
}
- if (p->event_proxy->downstream_done) {
-ngx_log_debug(wev->log, "http proxy downstream done");
- ngx_http_proxy_finalize_request(p, r->main ? 0:
- ngx_http_send_last(p->request));
+ if (ep->downstream_done) {
+ ngx_log_debug(ev->log, "http proxy downstream done");
+ ngx_http_proxy_finalize_request(p, r->main ? 0 : ngx_http_send_last(r));
return;
}
- if (p->event_proxy->downstream_error) {
- ngx_http_close_connection(c);
- return;
+ if (ep->downstream_error) {
+ if (!p->cachable && p->upstream.connection) {
+ ngx_http_proxy_close_connection(c);
+ p->upstream.connection = NULL;
+ }
+
+ if (p->upstream.connection == NULL) {
+ ngx_http_close_connection(c);
+ }
}
return;
conf->bufs.num = 10;
conf->bufs.size = 4096;
conf->max_busy_len = 8192 + 4096;
- conf->max_temp_file_size = 4096 * 5;
+ conf->max_temp_file_size = 4096 * 6;
conf->temp_file_write_size = 4096 * 2;
ngx_test_null(conf->temp_path, ngx_pcalloc(cf->pool, sizeof(ngx_path_t)),