My generic nginx patches

Hello!

The following patch series consists of various generic patches for nginx
not yet imported by Igor. Most of them was already posted somewhere.

Posting them here in hope it would be easier to review / test / import
them.

Maxim D.

HG changeset patch

User Maxim D. [email protected]

Date 1223802906 -14400

Node ID 83ba5ad4985f08c8acbffe694fa365a2dff571bf

Parent 2a993b1413bab4435a9dfe88bd0889d74b90c3da

Upstream: unbreak intercept_404 used by memcached.

We should honor intercept_404 even if no not_found specified in
memcached_next_upstream directive.

diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
— a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -1376,11 +1376,6 @@ ngx_http_upstream_test_next(ngx_http_req
return NGX_OK;
}

  •    if (status == NGX_HTTP_NOT_FOUND && u->conf->intercept_404) {
    
  •        ngx_http_upstream_finalize_request(r, u, 
    

NGX_HTTP_NOT_FOUND);

  •        return NGX_OK;
    
  •    }
    

#if (NGX_HTTP_CACHE)

     if (u->peer.tries == 0 && u->stale && (u->conf->use_stale & 

un->mask)) {
@@ -1406,6 +1401,13 @@ ngx_http_upstream_intercept_errors(ngx_h
ngx_http_err_page_t *err_page;
ngx_http_core_loc_conf_t *clcf;

  • status = u->headers_in.status_n;
  • if (status == NGX_HTTP_NOT_FOUND && u->conf->intercept_404) {
  •    ngx_http_upstream_finalize_request(r, u, NGX_HTTP_NOT_FOUND);
    
  •    return NGX_OK;
    
  • }
  • if (!u->conf->intercept_errors) {
    return NGX_DECLINED;
    }
    @@ -1415,8 +1417,6 @@ ngx_http_upstream_intercept_errors(ngx_h
    if (clcf->error_pages == NULL) {
    return NGX_DECLINED;
    }
  • status = u->headers_in.status_n;

    err_page = clcf->error_pages->elts;
    for (i = 0; i < clcf->error_pages->nelts; i++) {

HG changeset patch

User Maxim D. [email protected]

Date 1225109046 -10800

Node ID 9a6bf5cfcd63433a28dc00064af195a91b628d64

Parent aa6cd5a06ccc2037064686bcb183c71d8c65f44a

Upstream: don’t wait for upstream close if we know length.

This change basically deligates right to control how many bytes may be
buffered by ngx_event_pipe to input filter by means of changing
p->length.

Currently p->length is set to NGX_MAX_OFF_T_VALUE if content length
isn’t
known (and thus input must be terminated by upstream connection close),
or
to content length if it’s known.

Futher improvement may involve correct parsing of chunked transfer
encoding -
by setting p->length in input filter as approprate. E.g. set it to 2 if
you
just parsed chunk end and expect other chunk to start (chunk takes at
least
3 bytes, “0” CRLF, but RFC 2616 recomends to be tolerant and recognize
bare
LF too).

diff --git a/src/event/ngx_event_pipe.c b/src/event/ngx_event_pipe.c
— a/src/event/ngx_event_pipe.c
+++ b/src/event/ngx_event_pipe.c
@@ -328,22 +328,26 @@ ngx_event_pipe_read_upstream(ngx_event_p

         if (n >= size) {
             cl->buf->last = cl->buf->end;
  •            /* STUB */ cl->buf->num = p->num++;
    
  •            if (p->input_filter(p, cl->buf) == NGX_ERROR) {
    
  •                return NGX_ABORT;
    
  •            }
    
  •            n -= size;
    
  •            ln = cl;
    
  •            cl = cl->next;
    
  •            ngx_free_chain(p->pool, ln);
    
           } else {
               cl->buf->last += n;
               n = 0;
    
  •            if (cl->buf->last - cl->buf->pos < p->length) {
    
  •                continue;
    
  •            }
           }
    
  •        /* STUB */ cl->buf->num = p->num++;
    
  •        if (p->input_filter(p, cl->buf) == NGX_ERROR) {
    
  •            return NGX_ABORT;
    
  •        }
    
  •        ln = cl;
    
  •        cl = cl->next;
    
  •        ngx_free_chain(p->pool, ln);
       }
    
       if (cl) {
    

@@ -409,6 +413,9 @@ flush:
cl->buf->file_pos,
cl->buf->file_last - cl->buf->file_pos);
}
+

  • ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0,
  •               "pipe length: %O", p->length);
    

#endif

@@ -856,6 +863,16 @@ ngx_event_pipe_copy_input_filter(ngx_eve
}
p->last_in = &cl->next;

  • if (p->length == NGX_MAX_OFF_T_VALUE) {
  •    return NGX_OK;
    
  • }
  • p->length -= b->last - b->pos;
  • if (p->length <= 0) {
  •    p->upstream_done = 1;
    
  • }
  • return NGX_OK;
    }

diff --git a/src/event/ngx_event_pipe.h b/src/event/ngx_event_pipe.h
— a/src/event/ngx_event_pipe.h
+++ b/src/event/ngx_event_pipe.h
@@ -65,6 +65,7 @@ struct ngx_event_pipe_s {
ssize_t busy_size;

 off_t              read_length;
  • off_t length;

    off_t max_temp_file_size;
    ssize_t temp_file_write_size;
    diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
    — a/src/http/ngx_http_upstream.c
    +++ b/src/http/ngx_http_upstream.c
    @@ -1710,6 +1710,13 @@ ngx_http_upstream_send_response(ngx_http
    p->pool = r->pool;
    p->log = c->log;

  • if (r->headers_out.content_length_n != -1) {

  •    p->length = r->headers_out.content_length_n;
    
  • } else {

  •    p->length = NGX_MAX_OFF_T_VALUE;
    
  • }

  • p->cacheable = u->cacheable || u->store;

    p->temp_file = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t));

HG changeset patch

User Maxim D. [email protected]

Date 1225108949 -10800

Node ID 824321c85af87f85f9a3e56b0dd69d0a84c8d54f

Parent 5410f1e19796ccfcc08cf3d1c996537328a4fb42

Core: recall write handler if subrequest changed.

If complex reply was buffered after postpone filter (e.g. in gzip filter
module), and this happened just after switching to next postponed
subrequest,
the copy filter has no chance to reclaim freed buffers and send more
data.

To resolve this, just post an additional write event in
ngx_http_writer()
if we got NGX_AGAIN and subrequest has been changed.

diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
— a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -1981,6 +1981,11 @@ ngx_http_writer(ngx_http_request_t *r)
rc, &r->uri, &r->args);

 if (rc == NGX_AGAIN) {
  •    if (r != c->data) {
    
  •        ngx_post_event(wev, &ngx_posted_events);
    
  •        return;
    
  •    }
    
  •    clcf = ngx_http_get_module_loc_conf(r->main, 
    

ngx_http_core_module);
if (!wev->ready && !wev->delayed) {
ngx_add_timer(wev, clcf->send_timeout);

That’s just I’m looking for. Thanks.

2008-10-28

nbubingo

发件人: Benjamin
发送时间: 2008-10-28 05:31:04
收件人: nginx
抄送:
主题: Re: [PATCH 0 of 6] my generic nginx patches

Thanks for all your works !

On Mon, Oct 27, 2008 at 3:53 PM, Maxim D. [email protected]
wrote:

Hello!

The following patch series consists of various generic patches for nginx
not yet imported by Igor. Most of them was already posted somewhere.

Posting them here in hope it would be easier to review / test / import
them.

Maxim D.

Thanks for all your works !