Upstream with multiple request reply

Bertrand Paquet bpaquet at octo.com
Tue Jan 17 10:29:00 UTC 2012


Hi all,

Finally, I do not use subrequest, I write the following code, inspired from
upstream module.
I call ngx_http_upstream_send_another_request from process_header. It's
working fine.

Feel free to comment my code, if you think I can have problem, memory
allocation, segfault or others.

Regards,

Bertrand


static void
ngx_http_upstream_send_another_request_dummy_handler(ngx_http_request_t *r,
ngx_http_upstream_t *u)
{
    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "http upstream send another request dummy handler");
}

static ngx_int_t
ngx_http_upstream_send_another_request(ngx_http_request_t *r,
ngx_http_upstream_t *u);

static void
ngx_http_upstream_send_another_request_handler(ngx_http_request_t *r,
ngx_http_upstream_t *u)
{
    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "http upstream send another request handler");

    ngx_http_upstream_send_another_request(r, u);
}

static ngx_int_t
ngx_http_upstream_send_another_request(ngx_http_request_t *r,
ngx_http_upstream_t *u)
{
    ngx_int_t          rc;
    ngx_connection_t  *c;

    c = u->peer.connection;

    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
                   "http upstream send another request");
    //
    // if (!u->request_sent && ngx_http_upstream_test_connect(c) != NGX_OK)
{
    //     ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
    //     return;
    // }

    c->log->action = "sending request to upstream";

    rc = ngx_output_chain(&u->output, u->request_sent ? NULL :
u->request_bufs);

    u->request_sent = 1;

    if (rc == NGX_ERROR) {
        return rc;
    }

    if (c->write->timer_set) {
        ngx_del_timer(c->write);
    }

    if (rc == NGX_AGAIN) {
       ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
                       "ngx_output_chain return NGX_AGAIN");

        u->write_event_handler =
ngx_http_upstream_send_another_request_handler;

        ngx_add_timer(c->write, u->conf->send_timeout);

        if (ngx_handle_write_event(c->write, u->conf->send_lowat) !=
NGX_OK) {
          return NGX_ERROR;
        }

        return NGX_AGAIN;
    }

    /* rc == NGX_OK */

    if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) {
        if (ngx_tcp_push(c->fd) == NGX_ERROR) {
            ngx_log_error(NGX_LOG_CRIT, c->log, ngx_socket_errno,
                          ngx_tcp_push_n " failed");
            return NGX_ERROR;
        }

        c->tcp_nopush = NGX_TCP_NOPUSH_UNSET;
    }

    ngx_add_timer(c->read, u->conf->read_timeout);

// #if 1
//     if (c->read->ready) {
//
//         /* post aio operation */
//
//         /*
//          * TODO comment
//          * although we can post aio operation just in the end
//          * of ngx_http_upstream_connect() CHECK IT !!!
//          * it's better to do here because we postpone header buffer
allocation
//          */
//
//          return u->process_header(r);
//     }
// #endif

    u->write_event_handler =
ngx_http_upstream_send_another_request_dummy_handler;

    if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
        return NGX_ERROR;
    }

    return NGX_AGAIN;
}

On Tue, Jan 17, 2012 at 04:14, bigplum <nginx-forum at nginx.us> wrote:

> Hi,
>
> This demo maybe helpful.
> https://github.com/bigplum/nginx-http-nphase-module
>
> Posted at Nginx Forum:
> http://forum.nginx.org/read.php?2,221329,221339#msg-221339
>
> _______________________________________________
> nginx mailing list
> nginx at nginx.org
> http://mailman.nginx.org/mailman/listinfo/nginx
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.nginx.org/pipermail/nginx/attachments/20120117/07d6e411/attachment-0001.html>


More information about the nginx mailing list