for ( ;; ) {
- /* use the free hunks if they exist */
+ /* use the pre-read hunks if they exist */
- if (p->free_hunks) {
- chain = p->free_hunks;
- p->free_hunks = NULL;
+ if (p->preread_hunks) {
+ chain = p->preread_hunks;
+ p->preread_hunks = NULL;
+ n = p->preread_size;
+
+ } else {
+
+ /* use the free hunks if they exist */
+
+ if (p->free_hunks) {
+ chain = p->free_hunks;
+ p->free_hunks = NULL;
ngx_log_debug(p->log, "free hunk: %08X:%d" _ chain->hunk _
chain->hunk->end - chain->hunk->last);
- /* allocate a new hunk if it's still allowed */
+ /* allocate a new hunk if it's still allowed */
- } else if (p->allocated < p->max_block_size) {
- ngx_test_null(h,
- ngx_create_temp_hunk(p->pool, p->block_size, 20, 20),
- NGX_ERROR);
+ } else if (p->allocated < p->max_block_size) {
+ ngx_test_null(h,
+ ngx_create_temp_hunk(p->pool,
+ p->block_size, 20, 20),
+ NGX_ERROR);
- p->allocated += p->block_size;
+ p->allocated += p->block_size;
- ngx_test_null(temp, ngx_alloc_chain_entry(p->pool), NGX_ERROR);
- temp->hunk = h;
- temp->next = NULL;
- chain = temp;
+ ngx_test_null(temp, ngx_alloc_chain_entry(p->pool), NGX_ERROR);
+ temp->hunk = h;
+ temp->next = NULL;
+ chain = temp;
ngx_log_debug(p->log, "new hunk: %08X" _ chain->hunk);
- /* use the shadow hunks if they exist */
+ /* use the shadow hunks if they exist */
- } else if (p->shadow_hunks) {
- chain = p->shadow_hunks;
- p->shadow_hunks = NULL;
+ } else if (p->shadow_hunks) {
+ chain = p->shadow_hunks;
+ p->shadow_hunks = NULL;
ngx_log_debug(p->log, "shadow hunk: %08X" _ chain->hunk _
chain->hunk->end - chain->hunk->last);
- /* if it's allowed then save the incoming hunks to a temporary file,
- move the saved hunks to a shadow chain,
- and add the file hunks to an outgoing chain */
+ /* if the hunks is not needed to be saved in a cache and
+ a downstream is ready then write the hunks to a downstream */
- } else if (p->temp_offset < p->max_temp_size) {
- rc = ngx_event_proxy_write_chain_to_temp_file(p);
+ } else if (p->cachable == 0 && p->downstream->write->ready) {
+
+ rc = ngx_event_proxy_write_to_downstream(p);
+
+ continue;
+
+ /* if it's allowed then save the incoming hunks
+ to a temporary file, move the saved hunks to a shadow chain,
+ and add the file hunks to an outgoing chain */
+
+ } else if (p->temp_offset < p->max_temp_file_size) {
+ rc = ngx_event_proxy_write_chain_to_temp_file(p);
ngx_log_debug(p->log, "temp offset: %d" _ p->temp_offset);
- if (rc != NGX_OK) {
- return rc;
- }
+ if (rc != NGX_OK) {
+ return rc;
+ }
- chain = p->shadow_hunks;
- p->shadow_hunks = NULL;
+ chain = p->shadow_hunks;
+ p->shadow_hunks = NULL;
ngx_log_debug(p->log, "new shadow hunk: %08X:%d" _ chain->hunk _
chain->hunk->end - chain->hunk->last);
- /* if there're no hunks to read in then disable a level event */
+ /* if there're no hunks to read in then disable a level event */
- } else {
- if (ngx_event_flags & NGX_USE_LEVEL_EVENT) {
- p->block_upstream = 1;
+ } else {
+ if (ngx_event_flags & NGX_USE_LEVEL_EVENT) {
+ p->block_upstream = 1;
+ }
+
+ break;
}
- break;
- }
+ n = ngx_recv_chain(p->upstream, chain);
- n = ngx_recv_chain(p->upstream, chain);
+ }
ngx_log_debug(p->log, "recv_chain: %d" _ n);
p->upstream->read->blocked = 0;
}
- return NGX_AGAIN;
+ break;
}
if (n == 0) {
ngx_test_null(h, ngx_alloc_hunk(p->pool), NGX_ERROR);
ngx_memcpy(h, entry->hunk, sizeof(ngx_hunk_t));
h->shadow = entry->hunk;
- h->type |= NGX_HUNK_LAST_SHADOW;
+ h->type |= NGX_HUNK_LAST_SHADOW|NGX_HUNK_RECYCLED;
entry->hunk->shadow = h;
ngx_test_null(temp, ngx_alloc_chain_entry(p->pool),
}
}
- if (p->out_hunks && p->client->write->ready) {
- rc = ngx_event_proxy_write_to_client(p);
+ if (p->out_hunks && p->downstream->write->ready) {
+ rc = ngx_event_proxy_write_to_downstream(p);
}
- } else if ((p->out_hunks || p->in_hunks) && p->client->write->ready) {
- rc = ngx_event_proxy_write_to_client(p);
+ } else if ((p->out_hunks || p->in_hunks) && p->downstream->write->ready) {
+ rc = ngx_event_proxy_write_to_downstream(p);
}
p->level--;
}
-int ngx_event_proxy_write_to_client(ngx_event_proxy_t *p)
+int ngx_event_proxy_write_to_downstream(ngx_event_proxy_t *p)
{
int rc;
ngx_hunk_t *h;
ngx_chain_t *entry;
-ngx_log_debug(p->log, "write to client");
+ngx_log_debug(p->log, "write to downstream");
h = p->busy_hunk;
do {
size += entry->hunk->last - entry->hunk->pos;
- if (size >= p->file_block_size) {
+ if (size >= p->temp_file_write_size) {
break;
}
entry = entry->next;
ngx_log_debug(p->log, "event proxy file hunk: %08X:%08X" _ h _ h->shadow);
if (h->type & NGX_HUNK_LAST_SHADOW) {
+#if 0
h->shadow->last = h->shadow->pos;
+#else
+ h->shadow->last = h->shadow->pos = h->shadow->start;
+#endif
}
if (p->out_hunks) {
ngx_test_null(h, ngx_alloc_hunk(p->pool), NGX_ERROR);
ngx_memcpy(h, entry->hunk, sizeof(ngx_hunk_t));
h->shadow = entry->hunk;
- h->type |= NGX_HUNK_LAST_SHADOW;
+ h->type |= NGX_HUNK_LAST_SHADOW|NGX_HUNK_RECYCLED;
entry->hunk->shadow = h;
ngx_test_null(temp, ngx_alloc_chain_entry(p->pool), NGX_ERROR);
struct ngx_event_proxy_s {
ngx_chain_t *read_hunks;
ngx_chain_t *last_read_hunk;
+
+ ngx_chain_t *shadow_hunks;
+
ngx_chain_t *in_hunks;
ngx_chain_t *last_in_hunk;
- ngx_chain_t *shadow_hunks;
+
ngx_chain_t *out_hunks;
ngx_chain_t *last_out_hunk;
+
ngx_chain_t *free_hunks;
+#if 0
+ ngx_chain_t *last_free_hunk;
+#endif
+
ngx_hunk_t *busy_hunk;
ngx_event_proxy_input_filter_pt input_filter;
unsigned block_upstream:1;
unsigned upstream_eof:1;
unsigned upstream_error:1;
- unsigned client_eof:1;
- unsigned client_error:1;
+ unsigned downstream_eof:1;
+ unsigned downstream_error:1;
int level;
int max_block_size;
off_t temp_offset;
- off_t max_temp_size;
- int file_block_size;
+ off_t max_temp_file_size;
+ int temp_file_write_size;
ngx_connection_t *upstream;
- ngx_connection_t *client;
+ ngx_connection_t *downstream;
ngx_pool_t *pool;
ngx_log_t *log;
+ ngx_chain_t *preread_hunks;
+#if 0
+ ngx_chain_t *last_preread_hunk;
+#endif
+ int preread_size;
+
ngx_file_t *temp_file;
ngx_path_t *temp_path;
int number;
int ngx_event_proxy_read_upstream(ngx_event_proxy_t *p);
-int ngx_event_proxy_write_to_client(ngx_event_proxy_t *p);
+int ngx_event_proxy_write_to_downstream(ngx_event_proxy_t *p);
int ngx_event_proxy_write_chain_to_temp_file(ngx_event_proxy_t *p);
r = p->request;
+ ngx_test_null(p->header_in,
+ ngx_create_temp_hunk(r->pool, p->lcf->header_size, 0, 0),
+ NGX_ERROR);
+
+#if 0
ngx_test_null(p->header_in,
ngx_create_temp_hunk(r->pool,
p->lcf->header_size
NGX_ERROR);
p->header_in->type = NGX_HUNK_MEMORY|NGX_HUNK_IN_MEMORY;
+#endif
#if 0
ngx_test_null(p->headers_in,
{
int i, n, rc;
ngx_event_t *rev;
+ ngx_chain_t *temp;
ngx_table_elt_t *ch, *ph;
ngx_event_proxy_t *ep;
ngx_http_request_t *r;
rc = ngx_http_send_header(r);
#if 1
+#if 0
rc = ngx_http_output_filter(r, p->header_in);
+#endif
ngx_test_null(ep, ngx_pcalloc(r->pool, sizeof(ngx_event_proxy_t)),
NGX_ERROR);
ep->output_data = r;
ep->block_size = p->lcf->block_size;
ep->max_block_size = p->lcf->max_block_size;
- ep->file_block_size = p->lcf->file_block_size;
ep->upstream = p->connection;
- ep->client = r->connection;
+ ep->downstream = r->connection;
ep->pool = r->pool;
ep->log = p->log;
ep->temp_path = p->lcf->temp_path;
ep->number = 10;
ep->random = 5;
- ep->max_temp_size = p->lcf->max_temp_file_size;
+ ep->max_temp_file_size = p->lcf->max_temp_file_size;
+ ep->temp_file_write_size = p->lcf->temp_file_write_size;
ep->temp_file_warn = "an upstream response is buffered "
"to a temporary file";
+ ngx_test_null(ep->preread_hunks, ngx_alloc_chain_entry(r->pool),
+ NGX_ERROR);
+ ep->preread_hunks->hunk = p->header_in;
+ ep->preread_hunks->next = NULL;
+#if 0
+ ep->last_preread_hunk = ep->preread_hunks;
+#endif
+
+ ep->preread_size = p->header_in->last - p->header_in->pos;
+
p->event_proxy = ep;
lcx = p->log->data;
static int ngx_http_proxy_write_upstream_body(ngx_http_proxy_ctx_t *p)
{
- return ngx_event_proxy_write_to_client(p->event_proxy);
+ return ngx_event_proxy_write_to_downstream(p->event_proxy);
}
conf->connect_timeout = 10000;
conf->send_timeout = 10000;
conf->read_timeout = 10000;
- conf->header_size = 1024;
+ conf->header_size = 2048;
-#if 0
+#if 1
conf->block_size = 4096;
conf->max_block_size = 4096 * 3;
conf->max_temp_file_size = 4096 * 5;
- conf->file_block_size = 4096 * 2;
+ conf->temp_file_write_size = 4096 * 2;
#else
conf->block_size = 2048;
conf->max_block_size = 4096 * 6;
conf->max_temp_file_size = 4096 * 5;
- conf->file_block_size = 4096 * 5;
+ conf->temp_file_write_size = 4096 * 5;
#endif
ngx_test_null(conf->temp_path, ngx_pcalloc(pool, sizeof(ngx_path_t)), NULL);