ngx_http_request.c
来自「Nginx是一个高性能的HTTP和反向代理服务器」· C语言 代码 · 共 2,528 行 · 第 1/5 页
C
2,528 行
ngx_http_close_request(r, 0); return; } } for (i = 0; i < hc->nbusy - 1; i++) { f = hc->busy[i]; hc->free[hc->nfree++] = f; f->pos = f->start; f->last = f->start; } hc->busy[0] = b; hc->nbusy = 1; } } ngx_http_request_done(r, 0); c->data = hc; ngx_add_timer(rev, clcf->keepalive_timeout); if (ngx_handle_read_event(rev, 0) == NGX_ERROR) { ngx_http_close_connection(c); return; } wev = c->write; wev->handler = ngx_http_empty_handler; if (b->pos < b->last) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "pipelined request");#if (NGX_STAT_STUB) ngx_atomic_fetch_add(ngx_stat_reading, 1);#endif hc->pipeline = 1; c->log->action = "reading client pipelined request line"; ngx_http_init_request(rev); return; } hc->pipeline = 0; /* * To keep a memory footprint as small as possible for an idle * keepalive connection we try to free the ngx_http_request_t and * c->buffer's memory if they were allocated outside the c->pool. * The large header buffers are always allocated outside the c->pool and * are freed too. */ if (ngx_pfree(c->pool, r) == NGX_OK) { hc->request = NULL; } b = c->buffer; if (ngx_pfree(c->pool, b->start) == NGX_OK) { /* * the special note for ngx_http_keepalive_handler() that * c->buffer's memory was freed */ b->pos = NULL; } else { b->pos = b->start; b->last = b->start; } ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "hc free: %p %d", hc->free, hc->nfree); if (hc->free) { for (i = 0; i < hc->nfree; i++) { ngx_pfree(c->pool, hc->free[i]->start); hc->free[i] = NULL; } hc->nfree = 0; } ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "hc busy: %p %d", hc->busy, hc->nbusy); if (hc->busy) { for (i = 0; i < hc->nbusy; i++) { ngx_pfree(c->pool, hc->busy[i]->start); hc->busy[i] = NULL; } hc->nbusy = 0; }#if (NGX_HTTP_SSL) if (c->ssl) { ngx_ssl_free_buffer(c); }#endif rev->handler = ngx_http_keepalive_handler; if (wev->active && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) { if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) == NGX_ERROR) { ngx_http_close_connection(c); return; } } c->log->action = "keepalive"; if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) { if (ngx_tcp_push(c->fd) == -1) { ngx_connection_error(c, ngx_socket_errno, ngx_tcp_push_n " failed"); ngx_http_close_connection(c); return; } c->tcp_nopush = NGX_TCP_NOPUSH_UNSET; tcp_nodelay = ngx_tcp_nodelay_and_tcp_nopush ? 1 : 0; } else { tcp_nodelay = 1; } if (tcp_nodelay && clcf->tcp_nodelay && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay"); if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, (const void *) &tcp_nodelay, sizeof(int)) == -1) { ngx_connection_error(c, ngx_socket_errno, "setsockopt(TCP_NODELAY) failed"); ngx_http_close_connection(c); return; } c->tcp_nodelay = NGX_TCP_NODELAY_SET; }#if 0 /* if ngx_http_request_t was freed then we need some other place */ r->http_state = NGX_HTTP_KEEPALIVE_STATE;#endif c->idle = 1; if (rev->ready) { ngx_http_keepalive_handler(rev); }}static voidngx_http_keepalive_handler(ngx_event_t *rev){ size_t size; ssize_t n; ngx_buf_t *b; ngx_connection_t *c; c = rev->data; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http keepalive handler"); if (rev->timedout || c->close) { ngx_http_close_connection(c); return; }#if (NGX_HAVE_KQUEUE) if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { if (rev->pending_eof) { c->log->handler = NULL; ngx_log_error(NGX_LOG_INFO, c->log, rev->kq_errno, "kevent() reported that client %V closed " "keepalive connection", &c->addr_text);#if (NGX_HTTP_SSL) if (c->ssl) { c->ssl->no_send_shutdown = 1; }#endif ngx_http_close_connection(c); return; } }#endif b = c->buffer; size = b->end - b->start; if (b->pos == NULL) { /* * The c->buffer's memory was freed by ngx_http_set_keepalive(). * However, the c->buffer->start and c->buffer->end were not changed * to keep the buffer size. */ b->pos = ngx_palloc(c->pool, size); if (b->pos == NULL) { ngx_http_close_connection(c); return; } b->start = b->pos; b->last = b->pos; b->end = b->pos + size; } /* * MSIE closes a keepalive connection with RST flag * so we ignore ECONNRESET here. */ c->log_error = NGX_ERROR_IGNORE_ECONNRESET; ngx_set_socket_errno(0); n = c->recv(c, b->last, size); c->log_error = NGX_ERROR_INFO; if (n == NGX_AGAIN) { if (ngx_handle_read_event(rev, 0) == NGX_ERROR) { ngx_http_close_connection(c); } return; } if (n == NGX_ERROR) { ngx_http_close_connection(c); return; } c->log->handler = NULL; if (n == 0) { ngx_log_error(NGX_LOG_INFO, c->log, ngx_socket_errno, "client %V closed keepalive connection", &c->addr_text); ngx_http_close_connection(c); return; } b->last += n;#if (NGX_STAT_STUB) ngx_atomic_fetch_add(ngx_stat_reading, 1);#endif c->log->handler = ngx_http_log_error; c->log->action = "reading client request line"; c->idle = 0; ngx_http_init_request(rev);}static voidngx_http_set_lingering_close(ngx_http_request_t *r){ ngx_event_t *rev, *wev; ngx_connection_t *c; ngx_http_core_loc_conf_t *clcf; c = r->connection; clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); rev = c->read; rev->handler = ngx_http_lingering_close_handler; r->lingering_time = ngx_time() + (time_t) (clcf->lingering_time / 1000); ngx_add_timer(rev, clcf->lingering_timeout); if (ngx_handle_read_event(rev, 0) == NGX_ERROR) { ngx_http_close_request(r, 0); return; } wev = c->write; wev->handler = ngx_http_empty_handler; if (wev->active && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) { if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) == NGX_ERROR) { ngx_http_close_request(r, 0); return; } } if (ngx_shutdown_socket(c->fd, NGX_WRITE_SHUTDOWN) == -1) { ngx_connection_error(c, ngx_socket_errno, ngx_shutdown_socket_n " failed"); ngx_http_close_request(r, 0); return; } if (rev->ready) { ngx_http_lingering_close_handler(rev); }}static voidngx_http_lingering_close_handler(ngx_event_t *rev){ ssize_t n; ngx_msec_t timer; ngx_connection_t *c; ngx_http_request_t *r; ngx_http_core_loc_conf_t *clcf; u_char buffer[NGX_HTTP_LINGERING_BUFFER_SIZE]; c = rev->data; r = c->data; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http lingering close handler"); if (rev->timedout) { c->timedout = 1; ngx_http_close_request(r, 0); return; } timer = (ngx_msec_t) (r->lingering_time - ngx_time()); if (timer <= 0) { ngx_http_close_request(r, 0); return; } do { n = c->recv(c, buffer, NGX_HTTP_LINGERING_BUFFER_SIZE); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "lingering read: %d", n); if (n == NGX_ERROR || n == 0) { ngx_http_close_request(r, 0); return; } } while (rev->ready); if (ngx_handle_read_event(rev, 0) == NGX_ERROR) { ngx_http_close_request(r, 0); return; } clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); timer *= 1000; if (timer > clcf->lingering_timeout) { timer = clcf->lingering_timeout; } ngx_add_timer(rev, timer);}voidngx_http_empty_handler(ngx_event_t *wev){ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0, "http empty handler"); return;}voidngx_http_request_empty_handler(ngx_http_request_t *r){ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http request empty handler"); return;}ngx_int_tngx_http_send_special(ngx_http_request_t *r, ngx_uint_t flags){ ngx_buf_t *b; ngx_chain_t out; b = ngx_calloc_buf(r->pool); if (b == NULL) { return NGX_ERROR; } if (flags & NGX_HTTP_LAST) { b->last_buf = 1; } if (flags & NGX_HTTP_FLUSH) { b->flush = 1; } out.buf = b; out.next = NULL; return ngx_http_output_filter(r, &out);}static ngx_int_tngx_http_post_action(ngx_http_request_t *r){ ngx_http_core_loc_conf_t *clcf; clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); if (clcf->post_action.data == NULL) { return NGX_DECLINED; } ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "post action: \"%V\"", &clcf->post_action); r->http_version = NGX_HTTP_VERSION_9; r->header_only = 1; r->post_action = 1; r->read_event_handler = ngx_http_block_reading; if (clcf->post_action.data[0] == '/') { ngx_http_internal_redirect(r, &clcf->post_action, NULL); } else { ngx_http_named_location(r, &clcf->post_action); } return NGX_OK;}static voidngx_http_close_request(ngx_http_request_t *r, ngx_int_t error){ ngx_connection_t *c; c = r->connection; ngx_http_request_done(r->main, error); ngx_http_close_connection(c);}static voidngx_http_request_done(ngx_http_request_t *r, ngx_int_t error){ ngx_log_t *log; ngx_uint_t i, n; struct linger linger; ngx_http_cleanup_t *cln; ngx_http_log_ctx_t *ctx; ngx_http_handler_pt *log_handler; ngx_http_core_loc_conf_t *clcf; ngx_http_core_main_conf_t *cmcf; log = r->connection->log; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, log, 0, "http close request"); if (r->pool == NULL) { ngx_log_error(NGX_LOG_ALERT, log, 0, "http request already closed"); return; } for (cln = r->cleanup; cln; cln = cln->next) { if (cln->handler) { cln->handler(cln->data); } }#if (NGX_STAT_STUB) if (r->stat_reading) { ngx_atomic_fetch_add(ngx_stat_reading, -1); } if (r->stat_writing) { ngx_atomic_fetch_add(ngx_stat_writing, -1); }#endif if (error && r->headers_out.status == 0) { r->headers_out.status = error; } c
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?