static void ngx_http_parallel_wev_handler(ngx_http_request_t *r) { ngx_http_parallel_fiber_ctx_t* fiber; ngx_http_parallel_ctx_t *ctx; ngx_int_t rc; ctx = ngx_http_get_module_ctx(r, ngx_http_parallel_module); // restore the write event handler r->write_event_handler = ctx->original_write_event_handler; ctx->original_write_event_handler = NULL; // get the fiber fiber = ctx->completed_fiber; ctx->completed_fiber = NULL; if (fiber == NULL) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "ngx_http_parallel_wev_handler: unexpected, fiber is null"); return; } // code taken from echo-nginx-module to work around nginx subrequest issues if (r == r->connection->data && r->postponed) { if (r->postponed->request) { r->connection->data = r->postponed->request; #if defined(nginx_version) && nginx_version >= 8012 ngx_http_post_request(r->postponed->request, NULL); #else ngx_http_post_request(r->postponed->request); #endif } else { ngx_http_output_filter(r, NULL); } } rc = ngx_http_parallel_handle_request_complete(ctx, fiber->sr, fiber); if (rc != NGX_OK && ctx->error_code == NGX_AGAIN) { ctx->error_code = rc; } if (ctx->error_code != NGX_AGAIN && ctx->active_fibers == 0) { ngx_http_finalize_request(r, ctx->error_code); } }
static ngx_int_t ngx_http_lua_sleep_resume(ngx_http_request_t *r) { ngx_connection_t *c; ngx_int_t rc; ngx_http_lua_ctx_t *ctx; ngx_http_lua_main_conf_t *lmcf; ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); if (ctx == NULL) { return NGX_ERROR; } ctx->resume_handler = ngx_http_lua_wev_handler; lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module); c = r->connection; rc = ngx_http_lua_run_thread(lmcf->lua, r, ctx, 0); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua run thread returned %d", rc); if (rc == NGX_AGAIN) { return ngx_http_lua_run_posted_threads(c, lmcf->lua, r, ctx); } if (rc == NGX_DONE) { ngx_http_finalize_request(r, NGX_DONE); return ngx_http_lua_run_posted_threads(c, lmcf->lua, r, ctx); } if (ctx->entered_content_phase) { ngx_http_finalize_request(r, rc); return NGX_DONE; } return rc; }
static void mytest_post_handler(ngx_http_request_t * r) { //如果没有返回200则直接把错误码发回用户 if (r->headers_out.status != NGX_HTTP_OK) { ngx_http_finalize_request(r, r->headers_out.status); return; } //当前请求是父请求,直接取其上下文 ngx_http_mytest_ctx_t* myctx = ngx_http_get_module_ctx(r, ngx_http_mytest_module); //定义发给用户的http包体内容,格式为: //stock[…],Today current price: …, volumn: … ngx_str_t output_format = ngx_string("stock[%V],Today current price: %V, volumn: %V"); //计算待发送包体的长度 int bodylen = output_format.len + myctx->stock[0].len + myctx->stock[1].len + myctx->stock[4].len - 6; r->headers_out.content_length_n = bodylen; //在内存池上分配内存保存将要发送的包体 ngx_buf_t* b = ngx_create_temp_buf(r->pool, bodylen); ngx_snprintf(b->pos, bodylen, (char*)output_format.data, &myctx->stock[0], &myctx->stock[1], &myctx->stock[4]); b->last = b->pos + bodylen; b->last_buf = 1; ngx_chain_t out; out.buf = b; out.next = NULL; //设置Content-Type,注意汉字编码新浪服务器使用了GBK static ngx_str_t type = ngx_string("text/plain; charset=GBK"); r->headers_out.content_type = type; r->headers_out.status = NGX_HTTP_OK; r->connection->buffered |= NGX_HTTP_WRITE_BUFFERED; ngx_int_t ret = ngx_http_send_header(r); ret = ngx_http_output_filter(r, &out); //注意,这里发送完响应后必须手动调用ngx_http_finalize_request //结束请求,因为这时http框架不会再帮忙调用它 ngx_http_finalize_request(r, ret); }
static void ngx_http_mysql_auth(ngx_mysql_t *m) { ngx_http_request_t *r; r = m->data; if (m->state != NGX_OK) { ngx_http_finalize_request(r, NGX_HTTP_NO_CONTENT); return; } m->query.len = NGX_MYSQL_CMDPKT_LEN + ngx_mysql_command_query.len; m->query.data = ngx_pnalloc(r->pool, m->query.len); if (m->query.data == NULL) { ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } ngx_memcpy(m->query.data + NGX_MYSQL_CMDPKT_LEN, ngx_mysql_command_query.data, ngx_mysql_command_query.len); m->handler = ngx_http_mysql_done; ngx_mysql_query(m); }
void ngx_http_foo_post_handler(ngx_http_request_t *r){ // 请求全部读完后从这里入口, 可以产生响应 /*ngx_http_finalize_request(r, NGX_HTTP_OK);*/ int result = get_route_id(r); ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "get_route_id result:%d", result); if (result < 0) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "get_route_id fail, result:%d", result); result = DFT_ROUTE_ID; } ngx_http_finalize_request(r, result); }
// 读取请求体的handler // 首先检查超时,实际功能在ngx_http_do_read_client_request_body static void ngx_http_read_client_request_body_handler(ngx_http_request_t *r) { ngx_int_t rc; // 首先检查超时 if (r->connection->read->timedout) { r->connection->timedout = 1; // 读取body超时错误,返回408 ngx_http_finalize_request(r, NGX_HTTP_REQUEST_TIME_OUT); return; } // 实际功能在ngx_http_do_read_client_request_body rc = ngx_http_do_read_client_request_body(r); // 出错直接结束请求 if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { ngx_http_finalize_request(r, rc); } }
static void ngx_http_mytest_body_handler(ngx_http_request_t *r) { /*打印包体内容*/ ngx_log_error(NGX_LOG_EMERG, r->connection->log, 0, "HTTP BODAY:%s\n", r->request_body->buf->pos); /*报文头中包体的长度*/ ngx_log_error(NGX_LOG_EMERG, r->connection->log, 0, "HTTP BODAYlength:%d\n", r->headers_in.content_length_n); /*计算真实的包体长度*/ ngx_log_error(NGX_LOG_EMERG, r->connection->log, 0, "HTTP BODAYle:%d\n", r->request_body->buf->last - r->request_body->buf->pos); ngx_http_finalize_request(r, ngx_http_send_header(r)); return; }
void ngx_http_cache_viewer_handler(ngx_http_request_t *r) { ngx_int_t rc; if (r->uri.data[r->uri.len - 1] == '/') { ngx_http_finalize_request(r, ngx_http_cache_viewer_send_response(r, 0)); return; } # if (NGX_HAVE_FILE_AIO) if (r->aio) { return; } # endif rc = ngx_http_file_cache_viewer(r); ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http file cache viewer: %i, \"%s\"", rc, r->cache->file.name.data); switch (rc) { case NGX_OK: r->write_event_handler = ngx_http_request_empty_handler; ngx_http_finalize_request(r, ngx_http_cache_viewer_send_response(r, 1)); return; case NGX_DECLINED: ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND); return; # if (NGX_HAVE_FILE_AIO) case NGX_AGAIN: r->write_event_handler = ngx_http_cache_viewer_handler; return; # endif default: ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); } }
static ngx_int_t publish_callback(ngx_int_t status, void *rptr, ngx_http_request_t *r) { nchan_channel_t *ch = rptr; nchan_request_ctx_t *ctx = ngx_http_get_module_ctx(r, nchan_module); static nchan_msg_id_t empty_msgid = {0}; //DBG("publish_callback %V owner %i status %i", ch_id, memstore_channel_owner(ch_id), status); switch(status) { case NCHAN_MESSAGE_QUEUED: //message was queued successfully, but there were no subscribers to receive it. ctx->prev_msg_id = ctx->msg_id; ctx->msg_id = ch != NULL ? ch->last_published_msg_id : empty_msgid; ngx_http_finalize_request(r, nchan_response_channel_ptr_info(ch, r, NGX_HTTP_ACCEPTED)); return NGX_OK; case NCHAN_MESSAGE_RECEIVED: //message was queued successfully, and it was already sent to at least one subscriber ctx->prev_msg_id = ctx->msg_id; ctx->msg_id = ch != NULL ? ch->last_published_msg_id : empty_msgid; ngx_http_finalize_request(r, nchan_response_channel_ptr_info(ch, r, NGX_HTTP_CREATED)); return NGX_OK; case NGX_ERROR: case NGX_HTTP_INTERNAL_SERVER_ERROR: //WTF? ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "nchan: error publishing message"); ctx->prev_msg_id = empty_msgid;; ctx->msg_id = empty_msgid; ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return NGX_ERROR; default: //for debugging, mostly. I don't expect this branch to behit during regular operation ctx->prev_msg_id = empty_msgid;; ctx->msg_id = empty_msgid; ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "nchan: TOTALLY UNEXPECTED error publishing message, status code %i", status); ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return NGX_ERROR; } }
/* 在接收较大的包体时,无法在一次调度中完成。通俗地讲,就是接收包体不是调用一次ngx_http_read_client_request_body方法就能完成的。 但是HTTP框架希望对于它的用户,也就是HTTP模块而言,接收包体时只需要调用一次ngx_http_read_client_request_body方法就好, 这时就需要有另一个方法在ngx_http_read_client_request_body没接收到完整的包体时,如果连接上再次接收到包体就被调用(触发ngx_http_request_handler), 这个方 法就是ngx_http_read_client_request_body_handler。通过ngx_http_request_handler执行这里的handler */ static void ngx_http_read_client_request_body_handler(ngx_http_request_t *r) { ngx_int_t rc; /* 首先检查连接上读事件的timeout标志位,如果为1,则表示接收HTTP包体超时, 这时把连接ngx_connection_t结构体上的timeout标志位也置为1, 同时调用ngx_http_finalize_request方法结束请求,并发送408超时错误码 */ if (r->connection->read->timedout) { r->connection->timedout = 1; ngx_http_finalize_request(r, NGX_HTTP_REQUEST_TIME_OUT); return; } rc = ngx_http_do_read_client_request_body(r); //检测这个方法的返回值,如果它大于300,那么一定表示希望返回错误码 if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { ngx_http_finalize_request(r, rc); } }
static ngx_int_t ngx_http_js_content_handler(ngx_http_request_t *r) { #if defined(nginx_version) && (nginx_version >= 8011) r->main->count++; #endif ngx_http_finalize_request(r, ngx_http_js__glue__content_handler(r)); // return implies ngx_http_finalize_request() // which in turn implies count-- // for the first count = 1 from ngx_http_init_request() return NGX_DONE; }
static void ngx_http_zm_sso_finalize_request(ngx_http_request_t *r, ngx_int_t rc) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "finalize http zm sso request: %i", rc); if (rc == NGX_DECLINED) { return; } r->connection->log->action = "sending to client"; ngx_http_finalize_request(r, rc); }
static void ngx_http_mogilefs_body_handler(ngx_http_request_t *r) { ngx_int_t rc; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "mogilefs body handler"); rc = ngx_http_mogilefs_put_handler(r); if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { ngx_http_finalize_request(r, rc); } }
static void ngx_http_dyups_send_response(ngx_http_request_t *r, ngx_int_t status, ngx_str_t *content) { ngx_int_t rc; ngx_buf_t *b; ngx_chain_t out; r->headers_out.status = status; r->headers_out.content_length_n = content->len; rc = ngx_http_send_header(r); if (rc == NGX_ERROR || rc > NGX_OK) { ngx_http_finalize_request(r, rc); return; } if (content->len == 0) { ngx_http_finalize_request(r, ngx_http_send_special(r, NGX_HTTP_FLUSH)); return; } b = ngx_create_temp_buf(r->pool, content->len); if (b == NULL) { ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } b->pos = content->data; b->last = content->data + content->len; b->last_buf = 1; out.buf = b; out.next = NULL; ngx_http_finalize_request(r, ngx_http_output_filter(r, &out)); }
static ngx_int_t ngx_http_sysguard_do_redirect(ngx_http_request_t *r, ngx_str_t *path) { if (path->len == 0) { return NGX_HTTP_SERVICE_UNAVAILABLE; } else if (path->data[0] == '@') { (void) ngx_http_named_location(r, path); } else { (void) ngx_http_internal_redirect(r, path, &r->args); } ngx_http_finalize_request(r, NGX_DONE); return NGX_DONE; }
static void resolver_handler_finalize(ngx_http_request_t * r, ngx_http_rdns_ctx_t * ctx) { if (r == NULL || ctx == NULL) { return; } ctx->resolved = 1; /* * Reset request handling pipeline to make new variable 'rdns_result' * visible by other rewrite phase modules */ r->uri_changed = 1; ngx_http_finalize_request(r, NGX_DECLINED); }
void ngx_http_finalize_request_failed(ngx_http_oauth_keepalive_peer_data_t *mkp) { ngx_buf_t *b = NULL; ngx_http_request_t *r; ngx_http_oauth_service_ctx_t *ctx; if (mkp->check_timeout_ev.timer_set) { ngx_del_timer(&mkp->check_timeout_ev); } r = mkp->request; ngx_log_debug0(NGX_LOG_DEBUG, r->connection->log, 0, "finalize_request_failed"); ctx = ngx_http_get_module_ctx(r, ngx_http_oauth_service_module); if (ctx->sub_signed_flag == 1) { r->headers_out.content_length_n = ngx_strlen(sub_signed); b = ngx_create_temp_buf(r->pool, ngx_strlen(sub_signed)); b->pos = (u_char *)sub_signed; b->last = b->pos + ngx_strlen(sub_signed); } else { r->headers_out.content_length_n = ngx_strlen(sub_failed); b = ngx_create_temp_buf(r->pool, ngx_strlen(sub_failed)); b->pos = (u_char *)sub_failed; b->last = b->pos + ngx_strlen(sub_failed); } b->last_buf = 1; ngx_chain_t out; out.buf = b; out.next = NULL; r->headers_out.status = NGX_HTTP_UNAUTHORIZED; r->headers_out.content_length_n = b->last - b->pos; ngx_str_set(&r->headers_out.content_type, "text/plain"); r->connection->buffered |= NGX_HTTP_WRITE_BUFFERED; ngx_int_t ret = ngx_http_send_header(r); ret = ngx_http_output_filter(r, &out); ngx_http_finalize_request(r, ret); return; }
void ngx_http_push_clean_timeouted_subscriber(ngx_event_t *ev) { ngx_http_push_subscriber_t *subscriber = NULL; ngx_http_request_t *r = NULL; subscriber = ev->data; r = subscriber->request; if (r->connection->destroyed) { return; } ngx_int_t rc = ngx_http_push_respond_status_only(r, NGX_HTTP_NOT_MODIFIED, NULL); ngx_http_finalize_request(r, rc); //the subscriber and channel counter will be freed by the pool cleanup callback }
static void ngx_http_limit_req_delay(ngx_http_request_t *r) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "limit_req delay"); if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) { ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } r->read_event_handler = ngx_http_block_reading; r->write_event_handler = ngx_http_core_run_phases; ngx_http_core_run_phases(r); }
void ngx_http_finalize_request_success(ngx_http_oauth_keepalive_peer_data_t *mkp) { ngx_int_t len; ngx_buf_t *b = NULL; ngx_http_request_t *r; ngx_http_variable_value_t *oauth; ngx_http_oauth_service_ctx_t *ctx; if (mkp->check_timeout_ev.timer_set) { ngx_del_timer(&mkp->check_timeout_ev); } r = mkp->request; ctx = ngx_http_get_module_ctx(r, ngx_http_oauth_service_module); ngx_log_debug0(NGX_LOG_DEBUG, r->connection->log, 0, "finalize_request_success"); oauth = ngx_http_get_indexed_variable(r, oauth_index); oauth->data = ngx_palloc(r->pool, ngx_strlen("oauth_succeed")); ngx_sprintf(oauth->data, "oauth_succeed"); r->headers_out.content_length_n = ctx->uid.len; len = ngx_strlen("{\"uid\":\"\"}") + ctx->uid.len; b = ngx_create_temp_buf(r->pool, ctx->uid.len); b->pos = ngx_pcalloc(r->pool, len); b->last = ngx_sprintf(b->pos, "{\"uid\":\"%V\"}", &ctx->uid); b->last_buf = 1; ngx_chain_t out; out.buf = b; out.next = NULL; r->headers_out.status = NGX_HTTP_OK; r->headers_out.content_length_n = len; ngx_str_set(&r->headers_out.content_type, "text/plain"); r->connection->buffered |= NGX_HTTP_WRITE_BUFFERED; ngx_int_t ret = ngx_http_send_header(r); ret = ngx_http_output_filter(r, &out); ngx_http_finalize_request(r, ret); return; }
ngx_int_t nchan_respond_string(ngx_http_request_t *r, ngx_int_t status_code, const ngx_str_t *content_type, const ngx_str_t *body, ngx_int_t finalize) { ngx_int_t rc = NGX_OK; ngx_buf_t *b = REQUEST_PCALLOC(r, b); ngx_chain_t *chain = REQUEST_PALLOC(r, chain); //assume both were alloc'd fine r->headers_out.status=status_code; r->headers_out.content_length_n = body->len; if(content_type) { r->headers_out.content_type.len = content_type->len; r->headers_out.content_type.data = content_type->data; } nchan_include_access_control_if_needed(r, NULL); if ((!b) || (!chain)) { ERR("Couldn't allocate ngx buf or chain."); r->headers_out.status=NGX_HTTP_INTERNAL_SERVER_ERROR; r->headers_out.content_length_n = 0; r->header_only = 1; ngx_http_send_header(r); rc=NGX_ERROR; } else { chain->buf=b; chain->next=NULL; b->last_buf = 1; b->last_in_chain = 1; b->flush = 1; //flush just to be sure, although I should perhaps rethink this b->memory = 1; b->start = body->data; b->pos = body->data; b->end = body->data + body->len; b->last = b->end; ngx_http_send_header(r); rc= nchan_output_filter(r, chain); } if(finalize) { ngx_http_finalize_request(r, rc); } return rc; }
/* post read callback for the content phase */ static void ngx_http_lua_content_phase_post_read(ngx_http_request_t *r) { ngx_http_lua_ctx_t *ctx; ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); ctx->read_body_done = 1; if (ctx->waiting_more_body) { ctx->waiting_more_body = 0; ngx_http_finalize_request(r, ngx_http_lua_content_handler(r)); } else { r->main->count--; } }
void ngx_http_echo_sleep_event_handler(ngx_event_t *ev) { ngx_connection_t *c; ngx_http_request_t *r; ngx_http_log_ctx_t *ctx; r = ev->data; c = r->connection; if (c->destroyed) { return; } if (c->error) { ngx_http_finalize_request(r, NGX_ERROR); return; } ctx = c->log->data; ctx->current_request = r; /* XXX when r->done == 1 we should do cleaning immediately * and delete our timer and then quit. */ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "echo sleep handler: \"%V?%V\"", &r->uri, &r->args); /* if (r->done) { return; } */ ngx_http_echo_post_sleep(r); #if defined(nginx_version) dd("before run posted requests"); ngx_http_run_posted_requests(c); dd("after run posted requests"); #endif }
static ngx_int_t ngx_http_echo_post_subrequest(ngx_http_request_t *r, void *data, ngx_int_t rc) { ngx_http_echo_ctx_t *ctx; ngx_int_t parent_rc; ctx = data; ctx->next_handler_cmd++; parent_rc = ngx_http_echo_handler(r->parent); if (parent_rc != NGX_DONE) { ngx_http_finalize_request(r->parent, parent_rc); } return rc; }
static void ngx_http_authen_post_handler(ngx_http_request_t *r) { ngx_http_authen_conf_t *authencf; authencf = (ngx_http_authen_conf_t *)ngx_http_get_module_loc_conf(r, ngx_http_authen_module); ngx_log_stderr(NGX_OK, "Authen request from: %V", &(r->connection->addr_text)); ngx_http_authen_pass(authencf, r); r->headers_out.status = NGX_HTTP_OK; r->headers_out.content_length_n = 0; r->header_only = 1; ngx_http_finalize_request(r, ngx_http_send_header(r)); return; }
static ngx_int_t ngx_http_methods_filter_send_header(ngx_http_request_t *r, size_t len, ngx_uint_t status) { ngx_int_t rc; r->headers_out.status = status; r->headers_out.content_length_n = len; r->header_only = len ? 0 : 1; r->keepalive = 0; ngx_str_set(&r->headers_out.content_type, "text/plain"); rc = ngx_http_send_header(r); if (r->header_only) { ngx_http_finalize_request(r, NGX_DONE); } return rc; }
void ngx_http_perl_sleep_handler(ngx_http_request_t *r) { ngx_event_t *wev; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "perl sleep handler"); wev = r->connection->write; if (wev->timedout) { wev->timedout = 0; ngx_http_perl_handle_request(r); return; } if (ngx_handle_write_event(wev, 0) != NGX_OK) { ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); } }
static void ngx_http_groonga_handler_post(ngx_http_request_t *r) { ngx_int_t rc; ngx_str_t command_path; ngx_http_groonga_handler_data_t *data; rc = ngx_http_groonga_extract_command_path(r, &command_path); if (rc == NGX_OK) { rc = ngx_http_groonga_handler_create_data(r, &data); } if (rc == NGX_OK) { rc = ngx_http_groonga_handler_process_load(r, &command_path, data); } ngx_http_groonga_handler_send_response(r, data); ngx_http_finalize_request(r, rc); }
ngx_int_t nchan_respond_status(ngx_http_request_t *r, ngx_int_t status_code, const ngx_str_t *status_line, ngx_int_t finalize) { ngx_int_t rc = NGX_OK; r->headers_out.status=status_code; if(status_line!=NULL) { r->headers_out.status_line.len =status_line->len; r->headers_out.status_line.data=status_line->data; } r->headers_out.content_length_n = 0; r->header_only = 1; nchan_include_access_control_if_needed(r, NULL); rc= ngx_http_send_header(r); if(finalize) { ngx_http_finalize_request(r, rc); } return rc; }
/* post read callback for the content phase */ static void ngx_http_lua_content_phase_post_read(ngx_http_request_t *r) { ngx_http_lua_ctx_t *ctx; ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); ctx->read_body_done = 1; if (ctx->waiting_more_body) { ctx->waiting_more_body = 0; ngx_http_finalize_request(r, ngx_http_lua_content_handler(r)); } else { #if defined(nginx_version) && nginx_version >= 8011 r->main->count--; #endif } }