ngx_http_request.c

来自「Nginx是一个高性能的HTTP和反向代理服务器」· C语言 代码 · 共 2,528 行 · 第 1/5 页

C
2,528
字号
                              " failed: %d on \"%V\" using \"%V\"",                              n, &name, &sn[i].name);                return;            }            /* match */            cscf = sn[i].core_srv_conf;            goto found;        }    }#endif    return;found:    r->srv_conf = cscf->ctx->srv_conf;    r->loc_conf = cscf->ctx->loc_conf;    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);    r->connection->log->file = clcf->err_log->file;    if (!(r->connection->log->log_level & NGX_LOG_DEBUG_CONNECTION)) {        r->connection->log->log_level = clcf->err_log->log_level;    }    return;}static voidngx_http_request_handler(ngx_event_t *ev){    ngx_connection_t    *c;    ngx_http_request_t  *r;    ngx_http_log_ctx_t  *ctx;    c = ev->data;    r = c->data;    ctx = c->log->data;    ctx->current_request = r;    if (ev->write) {        r->write_event_handler(r);    } else {        r->read_event_handler(r);    }}voidngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc){    ngx_connection_t          *c;    ngx_http_request_t        *pr;    ngx_http_log_ctx_t        *ctx;    ngx_http_core_loc_conf_t  *clcf;    if (rc == NGX_DONE) {        /* the request pool may be already destroyed */        return;    }    c = r->connection;    ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,                   "http finalize request: %d, \"%V?%V\"",                   rc, &r->uri, &r->args);    if (rc == NGX_DECLINED) {        r->content_handler = NULL;        r->write_event_handler = ngx_http_core_run_phases;        ngx_http_core_run_phases(r);        return;    }    if (r != r->main && r->post_subrequest) {        rc = r->post_subrequest->handler(r, r->post_subrequest->data, rc);    }    if (rc == NGX_ERROR        || rc == NGX_HTTP_REQUEST_TIME_OUT        || rc == NGX_HTTP_CLIENT_CLOSED_REQUEST        || c->error)    {        if (rc > 0 && r->headers_out.status == 0) {            r->headers_out.status = rc;        }        if (ngx_http_post_action(r) == NGX_OK) {            return;        }        ngx_http_close_request(r, 0);        return;    }    if (rc >= NGX_HTTP_SPECIAL_RESPONSE        || rc == NGX_HTTP_CREATED        || rc == NGX_HTTP_NO_CONTENT)    {        if (rc == NGX_HTTP_CLOSE) {            ngx_http_close_request(r, rc);            return;        }        if (r == r->main) {            if (c->read->timer_set) {                ngx_del_timer(c->read);            }            if (c->write->timer_set) {                ngx_del_timer(c->write);            }        }        ngx_http_finalize_request(r, ngx_http_special_response_handler(r, rc));        return;    }    if (r != r->main || rc == NGX_AGAIN) {        if (ngx_http_set_write_handler(r) != NGX_OK) {            return;        }    }    r->done = 1;    if (r != c->data) {        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,                       "http finalize non-active request: \"%V?%V\"",                       &r->uri, &r->args);        return;    }    if (r != r->main) {        pr = r->parent;        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,                       "http parent request: \"%V?%V\"", &pr->uri, &pr->args);        if (rc != NGX_AGAIN) {            c->data = pr;        }        ctx = c->log->data;        ctx->current_request = pr;        if (pr->postponed) {            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,                           "http request: \"%V?%V\" has postponed",                           &pr->uri, &pr->args);            if (rc != NGX_AGAIN && pr->postponed->request == r) {                pr->postponed = pr->postponed->next;            }            if (r->fast_subrequest) {                if (rc == NGX_AGAIN) {                    r->fast_subrequest = 0;                }                ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,                               "http fast subrequest: \"%V?%V\" done",                               &r->uri, &r->args);                return;            }            if (rc != NGX_AGAIN) {                ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,                               "http wake parent request: \"%V?%V\"",                               &pr->uri, &pr->args);                pr->write_event_handler(pr);            }        }        return;    }    if (rc == NGX_AGAIN) {        return;    }    if (c->buffered) {        (void) ngx_http_set_write_handler(r);        return;    }    if (!r->post_action) {        r->request_complete = 1;    }    if (ngx_http_post_action(r) == NGX_OK) {        return;    }    if (c->read->timer_set) {        ngx_del_timer(c->read);    }    if (c->write->timer_set) {        c->write->delayed = 0;        ngx_del_timer(c->write);    }    if (c->destroyed) {        return;    }    if (c->read->eof) {        ngx_http_close_request(r, 0);        return;    }    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);    if (!ngx_terminate         && !ngx_exiting         && r->keepalive != 0         && clcf->keepalive_timeout > 0)    {        ngx_http_set_keepalive(r);        return;    } else if (r->lingering_close && clcf->lingering_timeout > 0) {        ngx_http_set_lingering_close(r);        return;    }    ngx_http_close_request(r, 0);}static ngx_int_tngx_http_set_write_handler(ngx_http_request_t *r){    ngx_event_t               *wev;    ngx_http_core_loc_conf_t  *clcf;    r->http_state = NGX_HTTP_WRITING_REQUEST_STATE;    r->read_event_handler = ngx_http_test_reading;    r->write_event_handler = ngx_http_writer;    wev = r->connection->write;    if (wev->ready && wev->delayed) {        return NGX_OK;    }    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);    if (!wev->delayed) {        ngx_add_timer(wev, clcf->send_timeout);    }    if (ngx_handle_write_event(wev, clcf->send_lowat) == NGX_ERROR) {        ngx_http_close_request(r, 0);        return NGX_ERROR;    }    return NGX_OK;}static voidngx_http_writer(ngx_http_request_t *r){    int                        rc;    ngx_event_t               *wev;    ngx_connection_t          *c;    ngx_http_core_loc_conf_t  *clcf;    c = r->connection;    wev = c->write;    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, wev->log, 0,                   "http writer handler: \"%V?%V\"", &r->uri, &r->args);    if (wev->timedout) {        if (!wev->delayed) {            ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT,                          "client timed out");            c->timedout = 1;            ngx_http_finalize_request(r, NGX_HTTP_REQUEST_TIME_OUT);            return;        }        wev->timedout = 0;        wev->delayed = 0;        if (!wev->ready) {            clcf = ngx_http_get_module_loc_conf(r->main, ngx_http_core_module);            ngx_add_timer(wev, clcf->send_timeout);            if (ngx_handle_write_event(wev, clcf->send_lowat) == NGX_ERROR) {                ngx_http_close_request(r, 0);            }            return;        }    } else {        if (wev->delayed) {            ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0,                           "http writer delayed");            clcf = ngx_http_get_module_loc_conf(r->main, ngx_http_core_module);            if (ngx_handle_write_event(wev, clcf->send_lowat) == NGX_ERROR) {                ngx_http_close_request(r, 0);            }            return;        }    }    rc = ngx_http_output_filter(r, NULL);    if (c->destroyed) {        return;    }    ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,                   "http writer output filter: %d, \"%V?%V\"",                   rc, &r->uri, &r->args);    if (rc == NGX_AGAIN) {        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);        }        if (ngx_handle_write_event(wev, clcf->send_lowat) == NGX_ERROR) {            ngx_http_close_request(r, 0);        }        if (r == r->main || r->buffered) {            return;        }        rc = NGX_OK;    }    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, wev->log, 0,                   "http writer done: \"%V?%V\"", &r->uri, &r->args);    ngx_http_finalize_request(r, rc);}voidngx_http_block_reading(ngx_http_request_t *r){    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,                   "http reading blocked");    /* aio does not call this handler */    if ((ngx_event_flags & NGX_USE_LEVEL_EVENT)        && r->connection->read->active)    {        if (ngx_del_event(r->connection->read, NGX_READ_EVENT, 0)            == NGX_ERROR)        {            ngx_http_close_request(r, 0);        }    }}static voidngx_http_test_reading(ngx_http_request_t *r){    int                n;    char               buf[1];    ngx_err_t          err;    ngx_event_t       *rev;    ngx_connection_t  *c;    c = r->connection;    rev = c->read;    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http test reading");#if (NGX_HAVE_KQUEUE)    if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {        if (!rev->pending_eof) {            return;        }        rev->eof = 1;        c->error = 1;        err = rev->kq_errno;        goto closed;    }#endif    n = recv(c->fd, buf, 1, MSG_PEEK);    if (n == 0) {        rev->eof = 1;        c->error = 1;        err = 0;        goto closed;    } else if (n == -1) {        err = ngx_socket_errno;        if (err != NGX_EAGAIN) {            rev->eof = 1;            c->error = 1;            goto closed;        }    }    /* aio does not call this handler */    if ((ngx_event_flags & NGX_USE_LEVEL_EVENT) && rev->active) {        if (ngx_del_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {            ngx_http_close_request(r, 0);        }    }    return;closed:    if (err) {        rev->error = 1;    }    ngx_log_error(NGX_LOG_INFO, c->log, err,                  "client closed prematurely connection");    ngx_http_finalize_request(r, 0);}static voidngx_http_set_keepalive(ngx_http_request_t *r){    int                        tcp_nodelay;    ngx_int_t                  i;    ngx_buf_t                 *b, *f;    ngx_event_t               *rev, *wev;    ngx_connection_t          *c;    ngx_http_connection_t     *hc;    ngx_http_core_srv_conf_t  *cscf;    ngx_http_core_loc_conf_t  *clcf;    c = r->connection;    rev = c->read;    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "set http keepalive handler");    if (r->discard_body) {        r->lingering_time = ngx_time() + (time_t) (clcf->lingering_time / 1000);        ngx_add_timer(rev, clcf->lingering_timeout);        return;    }    c->log->action = "closing request";    hc = r->http_connection;    b = r->header_in;    if (b->pos < b->last) {        /* the pipelined request */        if (b != c->buffer) {            /*             * If the large header buffers were allocated while the previous             * request processing then we do not use c->buffer for             * the pipelined request (see ngx_http_init_request()).             *             * Now we would move the large header buffers to the free list.             */            cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);            if (hc->free == NULL) {                hc->free = ngx_palloc(c->pool,                  cscf->large_client_header_buffers.num * sizeof(ngx_buf_t *));                if (hc->free == NULL) {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?