static void ngx_http_tfs_timeout_handler(ngx_event_t *event) { ngx_int_t rc; ngx_pool_t *pool; ngx_http_tfs_t *t; ngx_connection_t *dummy; ngx_http_request_t *r; ngx_http_tfs_timers_data_t *data; dummy = event->data; data = dummy->data; if (ngx_shmtx_trylock(&data->lock->ngx_http_tfs_kp_mutex)) { if (ngx_queue_empty(&data->upstream->rc_ctx->sh->kp_queue)) { ngx_log_debug0(NGX_LOG_DEBUG_EVENT, event->log, 0, "empty rc keepalive queue"); ngx_shmtx_unlock(&data->lock->ngx_http_tfs_kp_mutex); ngx_add_timer(event, data->upstream->rcs_interval); return; } pool = ngx_create_pool(8192, event->log); if (pool == NULL) { ngx_shmtx_unlock(&data->lock->ngx_http_tfs_kp_mutex); return; } /* fake ngx_http_request_t */ r = ngx_pcalloc(pool, sizeof(ngx_http_request_t)); if (r == NULL) { ngx_shmtx_unlock(&data->lock->ngx_http_tfs_kp_mutex); return; } r->pool = pool; r->connection = ngx_pcalloc(pool, sizeof(ngx_connection_t)); if (r->connection == NULL) { ngx_destroy_pool(pool); ngx_shmtx_unlock(&data->lock->ngx_http_tfs_kp_mutex); return; } r->connection->log = event->log; /* in order to return from ngx_http_run_posted_requests() */ r->connection->destroyed = 1; t = ngx_pcalloc(pool, sizeof(ngx_http_tfs_t)); if (t == NULL) { ngx_destroy_pool(pool); ngx_shmtx_unlock(&data->lock->ngx_http_tfs_kp_mutex); return; } t->pool = pool; t->data = r; t->log = event->log; t->finalize_request = ngx_http_tfs_timers_finalize_request_handler; t->finalize_data = event; t->r_ctx.action.code = NGX_HTTP_TFS_ACTION_KEEPALIVE; t->r_ctx.version = 1; t->loc_conf = ngx_pcalloc(pool, sizeof(ngx_http_tfs_loc_conf_t)); if (t->loc_conf == NULL) { ngx_destroy_pool(pool); ngx_shmtx_unlock(&data->lock->ngx_http_tfs_kp_mutex); return; } t->loc_conf->upstream = data->upstream; t->main_conf = data->main_conf; rc = ngx_http_tfs_init(t); if (rc == NGX_ERROR) { ngx_destroy_pool(pool); ngx_shmtx_unlock(&data->lock->ngx_http_tfs_kp_mutex); return; } } else { ngx_log_debug0(NGX_LOG_DEBUG_EVENT, event->log, 0, "tfs kp mutex lock failed"); } }
static void ngx_http_tfs_read_body_handler(ngx_http_request_t *r) { ngx_int_t rc; ngx_http_tfs_t *t; ngx_connection_t *c; c = r->connection; t = ngx_http_get_module_ctx(r, ngx_http_tfs_module); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "http init tfs, client timer: %d", c->read->timer_set); if (c->read->timer_set) { ngx_del_timer(c->read); } if (ngx_event_flags & NGX_USE_CLEAR_EVENT) { if (!c->write->active) { if (ngx_add_event(c->write, NGX_WRITE_EVENT, NGX_CLEAR_EVENT) == NGX_ERROR) { ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } } } if (t->r_ctx.large_file || t->r_ctx.fsname.file_type == NGX_HTTP_TFS_LARGE_FILE_TYPE) { t->is_large_file = NGX_HTTP_TFS_YES; } if (r->request_body) { t->send_body = r->request_body->bufs; if (t->send_body == NULL) { ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); return; } if (r->headers_in.content_length_n > NGX_HTTP_TFS_USE_LARGE_FILE_SIZE && t->r_ctx.version == 1) { t->is_large_file = NGX_HTTP_TFS_YES; } /* save large file data len here */ if (t->is_large_file) { t->r_ctx.size = r->headers_in.content_length_n; } } rc = ngx_http_tfs_init(t); if (rc != NGX_OK) { switch (rc) { case NGX_HTTP_SPECIAL_RESPONSE ... NGX_HTTP_INTERNAL_SERVER_ERROR: ngx_http_finalize_request(r, rc); break; default: ngx_log_error(NGX_LOG_ERR, t->log, 0, "ngx_http_tfs_init failed"); ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); } } }