Mercurial > hg > nginx-quic
changeset 152:fb48bf4fea1c
nginx-0.0.1-2003-10-21-11:47:21 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Tue, 21 Oct 2003 07:47:21 +0000 |
parents | 2d9e4a8b6d11 |
children | c71aeb75c071 |
files | src/event/ngx_event_proxy.c src/event/ngx_event_proxy.h src/http/modules/proxy/ngx_http_proxy_handler.c src/http/ngx_http_core_module.c src/http/ngx_http_request.c src/os/unix/ngx_freebsd_init.c src/os/unix/ngx_freebsd_sendfile_chain.c |
diffstat | 7 files changed, 193 insertions(+), 70 deletions(-) [+] |
line wrap: on
line diff
--- a/src/event/ngx_event_proxy.c +++ b/src/event/ngx_event_proxy.c @@ -10,6 +10,7 @@ ngx_inline static void ngx_remove_shadow ngx_hunk_t *h); ngx_inline static void ngx_add_after_partially_filled_hunk(ngx_chain_t **chain, ngx_chain_t *ce); +static int ngx_drain_chains(ngx_event_proxy_t *p); int ngx_event_proxy(ngx_event_proxy_t *p, int do_write) @@ -53,11 +54,22 @@ int ngx_event_proxy_read_upstream(ngx_ev ngx_hunk_t *h; ngx_chain_t *chain, *ce, *te; + if (p->upstream_eof || p->upstream_error || p->upstream_done) { + return NGX_OK; + } + ngx_log_debug(p->log, "read upstream: %d" _ p->upstream->read->ready); - while (p->preread_hunks - || (p->upstream->read->ready && !p->upstream_done)) - { + for ( ;; ) { + + if (p->upstream_eof || p->upstream_error || p->upstream_done) { + break; + } + + if (p->preread_hunks == NULL && !p->upstream->read->ready) { + break; + } + if (p->preread_hunks) { /* use the pre-read hunks if they exist */ @@ -184,14 +196,12 @@ ngx_log_debug(p->log, "FREE: %08X:%d" _ break; } - /* TODO THINK about eof */ p->read = 1; if (n == 0) { p->upstream_eof = 1; break; } - } ce = chain; @@ -244,13 +254,16 @@ ngx_log_debug(p->log, "PART: %08X:%d" _ int ngx_event_proxy_write_to_downstream(ngx_event_proxy_t *p) { - int rc; + size_t busy_len; ngx_hunk_t *h; ngx_chain_t *out, *ce, *te; ngx_log_debug(p->log, "write downstream: %d" _ p->downstream->write->ready); for ( ;; ) { + if (p->downstream_error) { + return ngx_drain_chains(p); + } if ((p->upstream_eof || p->upstream_error || p->upstream_done) && p->out == NULL && p->in == NULL) @@ -263,10 +276,22 @@ int ngx_event_proxy_write_to_downstream( break; } + busy_len = 0; + + if (!(p->upstream_eof || p->upstream_error || p->upstream_done)) { + /* calculate p->busy_len */ + for (ce = p->busy; ce; ce = ce->next) { + busy_len += ngx_hunk_size(ce->hunk); + } + } + + if (p->out) { out = p->out; - if (p->busy_len + ngx_hunk_size(out->hunk) > p->max_busy_len) { + if (!(p->upstream_eof || p->upstream_error || p->upstream_done) + && (busy_len + ngx_hunk_size(out->hunk) > p->max_busy_len)) + { break; } @@ -277,7 +302,7 @@ int ngx_event_proxy_write_to_downstream( out = p->in; if (!(p->upstream_eof || p->upstream_error || p->upstream_done) - && (p->busy_len + ngx_hunk_size(out->hunk) > p->max_busy_len)) + && (busy_len + ngx_hunk_size(out->hunk) > p->max_busy_len)) { break; } @@ -290,22 +315,14 @@ int ngx_event_proxy_write_to_downstream( out->next = NULL; - rc = p->output_filter(p->output_ctx, out->hunk); - if (rc == NGX_ERROR) { + if (p->output_filter(p->output_ctx, out->hunk) == NGX_ERROR) { p->downstream_error = 1; - return NGX_ERROR; + continue; } ngx_chain_update_chains(&p->free, &p->busy, &out); - /* calculate p->busy_len */ - - p->busy_len = 0; - for (ce = p->busy; ce; ce = ce->next) { - p->busy_len += ngx_hunk_size(ce->hunk); - } - /* add the free shadow raw hunks to p->free_raw_hunks */ for (ce = p->free; ce; ce = ce->next) { @@ -323,13 +340,6 @@ ngx_log_debug(p->log, "RAW %08X" _ h->po } ce->hunk->shadow = NULL; } - -#if 0 /* TODO THINK p->read_priority ??? */ - if (p->upstream->read->ready) { - return; - } -#endif - } ngx_log_debug(p->log, "STATE %d:%d:%d:%X:%X" _ @@ -340,21 +350,15 @@ ngx_log_debug(p->log, "RAW %08X" _ h->po p->out ); - if ((p->upstream_eof || p->upstream_error || p->upstream_done) - && p->in == NULL && p->out == NULL) - { - p->downstream_done = 1; - } - return NGX_OK; } static int ngx_event_proxy_write_chain_to_temp_file(ngx_event_proxy_t *p) { - int rc, size; + int rc, size, hunk_size; ngx_hunk_t *h; - ngx_chain_t *ce, *te, *next, *in, **last, **last_free; + ngx_chain_t *ce, *te, *next, *in, **le, **last_free; ngx_log_debug(p->log, "write to file"); @@ -379,31 +383,41 @@ static int ngx_event_proxy_write_chain_t size = 0; ce = p->in; + le = NULL; + +ngx_log_debug(p->log, "offset: %d" _ p->temp_offset); do { - if (size + ce->hunk->last - ce->hunk->pos - >= p->temp_file_write_size) + hunk_size = ce->hunk->last - ce->hunk->pos; + +ngx_log_debug(p->log, "hunk size: %d" _ hunk_size); + + if ((size + hunk_size > p->temp_file_write_size) + || (p->temp_offset + hunk_size > p->max_temp_file_size)) { break; } - size += ce->hunk->last - ce->hunk->pos; + + size += hunk_size; + le = &ce->next; ce = ce->next; } while (ce); +ngx_log_debug(p->log, "size: %d" _ size); + if (ce) { - in = ce->next; - last = &ce->next; - ce->next = NULL; + in = ce; + *le = NULL; } else { in = NULL; - last = &p->in; + p->last_in = &p->in; } } else { in = NULL; - last = &p->in; + p->last_in = &p->in; } if (ngx_write_chain_to_file(p->temp_file, p->in, p->temp_offset, @@ -413,7 +427,7 @@ static int ngx_event_proxy_write_chain_t for (last_free = &p->free_raw_hunks; *last_free != NULL; - last_free = &(*last)->next) + last_free = &(*last_free)->next) { /* void */ } @@ -440,7 +454,6 @@ static int ngx_event_proxy_write_chain_t } p->in = in; - p->last_in = last; return NGX_OK; } @@ -552,3 +565,43 @@ ngx_inline static void ngx_add_after_par (*chain) = ce; } } + + +static int ngx_drain_chains(ngx_event_proxy_t *p) +{ + ngx_hunk_t *h; + ngx_chain_t *ce, *te; + + for ( ;; ) { + if (p->busy) { + ce = p->busy; + + } else if (p->out) { + ce = p->out; + + } else if (p->in) { + ce = p->in; + + } else { + return NGX_OK; + } + + while (ce) { + 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, h, p->pool, NGX_ABORT); + ngx_add_after_partially_filled_hunk(&p->free_raw_hunks, te); + + ce->hunk->type &= ~NGX_HUNK_LAST_SHADOW; + } + + ce->hunk->shadow = NULL; + te = ce->next; + ce->next = p->free; + p->free = ce; + ce = te; + } + } +}
--- a/src/event/ngx_event_proxy.h +++ b/src/event/ngx_event_proxy.h @@ -47,7 +47,6 @@ struct ngx_event_proxy_s { int hunks; ngx_bufs_t bufs; - size_t busy_len; size_t max_busy_len; off_t temp_offset;
--- a/src/http/modules/proxy/ngx_http_proxy_handler.c +++ b/src/http/modules/proxy/ngx_http_proxy_handler.c @@ -742,6 +742,12 @@ static void ngx_http_proxy_send_response ep->preread_size = p->header_in->last - p->header_in->pos; + /* + * event_proxy would do p->header_in->last += ep->preread_size + * as these bytes were read. + */ + p->header_in->last = p->header_in->pos; + /* STUB */ ep->cachable = 0; p->event_proxy = ep; @@ -806,7 +812,7 @@ static void ngx_http_proxy_process_body( } if (ep->upstream_done || ep->upstream_eof || ep->upstream_error) { - ngx_http_proxy_close_connection(c); + ngx_http_proxy_close_connection(p->upstream.connection); p->upstream.connection = NULL; } } @@ -819,7 +825,7 @@ static void ngx_http_proxy_process_body( if (ep->downstream_error) { if (!p->cachable && p->upstream.connection) { - ngx_http_proxy_close_connection(c); + ngx_http_proxy_close_connection(p->upstream.connection); p->upstream.connection = NULL; } @@ -1052,7 +1058,9 @@ static void ngx_http_proxy_finalize_requ p->upstream.connection = NULL; } - if (p->header_sent) { + if (p->header_sent + && (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE)) + { rc = 0; } @@ -1152,7 +1160,12 @@ static void *ngx_http_proxy_create_loc_c conf->bufs.num = 10; conf->bufs.size = 4096; conf->max_busy_len = 8192 + 4096; + + + /* CHECK in _init conf->max_temp_size >= conf->bufs.size !!! */ 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)),
--- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -207,13 +207,31 @@ void ngx_http_handler(ngx_http_request_t lcx = r->connection->log->data; lcx->action = NULL; + /* STUB */ r->keepalive = 1; + if (r->headers_in.connection) { + if (r->headers_in.connection->value.len == 5 + && ngx_strcasecmp(r->headers_in.connection->value.data, "close") + == 0) + { + r->keepalive = 0; + } + } + +#if 0 + /* TEST STUB */ r->keepalive = 0; +#endif if (r->headers_in.content_length_n > 0) { r->lingering_close = 1; + + } else { + r->lingering_close = 0; } +#if 0 /* TEST STUB */ r->lingering_close = 1; +#endif r->connection->write->event_handler = ngx_http_phase_event_handler; @@ -258,6 +276,11 @@ static void ngx_http_run_phases(ngx_http { rc = h[r->phase_handler](r); + if (rc == NGX_DONE) { + return; + } + + /* TODO THINK: is it dupliate NGX_DONE ??? */ if (r->closed) { return; } @@ -435,7 +458,7 @@ int ngx_http_internal_redirect(ngx_http_ ngx_http_handler(r); - return NGX_OK; + return NGX_DONE; }
--- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -583,6 +583,7 @@ static void ngx_http_process_request_hea if (ngx_strcasecmp(headers_in[i].name.data, h->key.data) == 0) { *((ngx_table_elt_t **) ((char *) &r->headers_in + headers_in[i].offset)) = h; + break; } }
--- a/src/os/unix/ngx_freebsd_init.c +++ b/src/os/unix/ngx_freebsd_init.c @@ -100,7 +100,7 @@ int ngx_os_init(ngx_log_t *log) /* * The determination of the sendfile() nbytes bug is complex enough. - * There're two sendfile() syscalls: a new 393 has no bug while + * There are two sendfile() syscalls: a new 393 has no bug while * an old 336 has the bug in some versions and has not in others. * Besides libc_r wrapper also emulates the bug in some versions. * There's no way to say exactly if a given FreeBSD version has the bug.
--- a/src/os/unix/ngx_freebsd_sendfile_chain.c +++ b/src/os/unix/ngx_freebsd_sendfile_chain.c @@ -14,8 +14,8 @@ * and the first part of the file in one packet but also sends 4K pages * in the full packets. * - * Until FreeBSD 4.5 the turning TCP_NOPUSH off does not flush - * the pending data that less than MSS so the data is sent with 5 second delay. + * Until FreeBSD 4.5 the turning TCP_NOPUSH off does not flush the pending + * data that less than MSS so the data can be sent with 5 second delay. * We do not use TCP_NOPUSH on FreeBSD prior to 4.5 although it can be used * for non-keepalive HTTP connections. */ @@ -23,10 +23,10 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in) { - int rc, eintr; + int rc, eintr, eagain; char *prev; - ssize_t hsize, size; - off_t sent; + ssize_t hsize, fsize, size; + off_t sent, fprev; struct iovec *iov; struct sf_hdtr hdtr; ngx_err_t err; @@ -41,8 +41,10 @@ ngx_chain_t *ngx_freebsd_sendfile_chain( do { ce = in; file = NULL; + fsize = 0; hsize = 0; eintr = 0; + eagain = 0; ngx_init_array(header, c->pool, 10, sizeof(struct iovec), NGX_CHAIN_ERROR); @@ -77,11 +79,27 @@ ngx_chain_t *ngx_freebsd_sendfile_chain( hsize += ce->hunk->last - ce->hunk->pos; } - /* TODO: coalesce the neighbouring file hunks */ + /* get the file hunk */ if (ce && (ce->hunk->type & NGX_HUNK_FILE)) { file = ce->hunk; ce = ce->next; + fsize = (size_t) (file->file_last - file->file_pos); + fprev = file->file_last; + + /* coalesce the neighbouring file hunks */ + + while (ce && (ce->hunk->type & NGX_HUNK_FILE)) { + if (file->file->fd != ce->hunk->file->fd + || fprev != ce->hunk->file_pos) + { + break; + } + + fsize += (size_t) (ce->hunk->file_last - ce->hunk->file_pos); + fprev = ce->hunk->file_last; + ce = ce->next; + } } /* create the iovec and coalesce the neighbouring chain entries */ @@ -110,6 +128,11 @@ ngx_chain_t *ngx_freebsd_sendfile_chain( } } + /* + * the tail is the rest of the chain that exceeded + * a single sendfile() capability + */ + tail = ce; if (file) { @@ -136,8 +159,7 @@ ngx_log_debug(c->log, "NOPUSH"); } rc = sendfile(file->file->fd, c->fd, file->file_pos, - (size_t) (file->file_last - file->file_pos) + hsize, - &hdtr, &sent, 0); + fsize + hsize, &hdtr, &sent, 0); if (rc == -1) { err = ngx_errno; @@ -146,6 +168,10 @@ ngx_log_debug(c->log, "NOPUSH"); eintr = 1; } + if (err == NGX_EAGAIN) { + eagain = 1; + } + if (err == NGX_EAGAIN || err == NGX_EINTR) { ngx_log_error(NGX_LOG_INFO, c->log, err, "sendfile() sent only %qd bytes", sent); @@ -159,8 +185,7 @@ ngx_log_debug(c->log, "NOPUSH"); #if (NGX_DEBUG_WRITE_CHAIN) ngx_log_debug(c->log, "sendfile: %d, @%qd %qd:%d" _ - rc _ file->file_pos _ sent _ - (size_t) (file->file_last - file->file_pos) + hsize); + rc _ file->file_pos _ sent _ fsize + hsize); #endif } else { @@ -169,6 +194,7 @@ ngx_log_debug(c->log, "NOPUSH"); if (rc == -1) { err = ngx_errno; if (err == NGX_EAGAIN) { + eagain = 1; ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EAGAIN"); } else if (err == NGX_EINTR) { @@ -190,14 +216,18 @@ ngx_log_debug(c->log, "NOPUSH"); c->sent += sent; - for (ce = in; ce && sent > 0; ce = ce->next) { + for (ce = in; ce; ce = ce->next) { + + if (ngx_hunk_special(ce->hunk)) { + continue; + } - if (ce->hunk->type & NGX_HUNK_IN_MEMORY) { - size = ce->hunk->last - ce->hunk->pos; - } else { - size = ce->hunk->file_last - ce->hunk->file_pos; + if (sent == 0) { + break; } + size = ngx_hunk_size(ce->hunk); + if (sent >= size) { sent -= size; @@ -223,16 +253,20 @@ ngx_log_debug(c->log, "NOPUSH"); break; } - ngx_destroy_array(&trailer); - ngx_destroy_array(&header); - in = ce; - } while ((tail && tail == ce) || eintr); + if (eagain) { + c->write->ready = 0; + break; + } - if (ce) { + /* "tail == in" means that a single sendfile() is complete */ + + } while ((tail && tail == in) || eintr); + + if (in) { c->write->ready = 0; } - return ce; + return in; }