/* Handler function that processes incoming requests destined for the Mobwrite daemon */ static ngx_int_t ngx_http_mobwrite_handler(ngx_http_request_t *r) { ngx_int_t rc; ngx_http_upstream_t *upstream; ngx_http_mobwrite_loc_conf_t *mobwrite_conf; /* Create an "upstream" object that tells nginx how to call the Mobwrite daemon */ if ((rc = ngx_http_upstream_create(r)) != NGX_OK) { return rc; } upstream = r->upstream; upstream->schema.len = sizeof("mobwrite://") - 1; upstream->schema.data = (u_char *)"mobwrite://"; upstream->output.tag = (ngx_buf_tag_t)&ngx_http_mobwrite_module; mobwrite_conf = (ngx_http_mobwrite_loc_conf_t *)ngx_http_get_module_loc_conf(r, ngx_http_mobwrite_module); upstream->conf = &(mobwrite_conf->upstream); /* These callbacks will do the actual work of sending a request to the Mobwrite daemon and processing the reponse */ upstream->create_request = ngx_http_mobwrite_create_request; upstream->reinit_request = ngx_http_mobwrite_reinit_request; upstream->process_header = ngx_http_mobwrite_process_response_header; upstream->abort_request = ngx_http_mobwrite_abort_request; upstream->finalize_request = ngx_http_mobwrite_finalize_request; /* Ask the nginx core to call our callbacks after the full POST body arrives. */ rc = ngx_http_read_client_request_body(r, ngx_http_upstream_init); if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { return rc; } return NGX_DONE; }
static ngx_int_t ngx_http_memcached_handler(ngx_http_request_t *r) { ngx_int_t rc; ngx_http_upstream_t *u; ngx_http_memcached_ctx_t *ctx; ngx_http_memcached_loc_conf_t *mlcf; if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) { return NGX_HTTP_NOT_ALLOWED; } rc = ngx_http_discard_request_body(r); if (rc != NGX_OK) { return rc; } if (ngx_http_set_content_type(r) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } if (ngx_http_upstream_create(r) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } u = r->upstream; ngx_str_set(&u->schema, "memcached://"); u->output.tag = (ngx_buf_tag_t) &ngx_http_memcached_module; mlcf = ngx_http_get_module_loc_conf(r, ngx_http_memcached_module); u->conf = &mlcf->upstream; u->create_request = ngx_http_memcached_create_request; u->reinit_request = ngx_http_memcached_reinit_request; u->process_header = ngx_http_memcached_process_header; u->abort_request = ngx_http_memcached_abort_request; u->finalize_request = ngx_http_memcached_finalize_request; ctx = ngx_palloc(r->pool, sizeof(ngx_http_memcached_ctx_t)); if (ctx == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } ctx->request = r; ngx_http_set_ctx(r, ctx, ngx_http_memcached_module); u->input_filter_init = ngx_http_memcached_filter_init; u->input_filter = ngx_http_memcached_filter; u->input_filter_ctx = ctx; r->main->count++; ngx_http_upstream_init(r); return NGX_DONE; }
static ngx_int_t ngx_lcb_handler(ngx_http_request_t *r) { ngx_int_t rc; ngx_http_upstream_t *u; ngx_lcb_loc_conf_t *llcf; llcf = ngx_http_get_module_loc_conf(r, ngx_http_couchbase_module); if (ngx_http_upstream_create(r) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } u = r->upstream; u->conf = &llcf->upstream; u->schema.len = sizeof("couchbase://") - 1; u->schema.data = (u_char *) "couchbase://"; u->output.tag = (ngx_buf_tag_t) &ngx_http_couchbase_module; u->create_request = ngx_lcb_create_request; u->reinit_request = ngx_lcb_reinit_request; u->process_header = ngx_lcb_process_header; u->abort_request = ngx_lcb_abort_request; u->finalize_request = ngx_lcb_finalize_request; u->input_filter_init = ngx_lcb_input_filter_init; u->input_filter = ngx_lcb_input_filter; u->input_filter_ctx = NULL; rc = ngx_http_read_client_request_body(r, ngx_lcb_upstream_init); if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { ngx_http_finalize_request(r, rc); } return NGX_DONE; }
static ngx_int_t ngx_http_mytest_handler(ngx_http_request_t *r) { //首先建立http上下文结构体ngx_http_mytest_ctx_t ngx_http_mytest_ctx_t *myctx = ngx_http_get_module_ctx(r,ngx_http_mytest_module); if(myctx == NULL){ myctx = ngx_palloc(r->pool,sizeof(ngx_http_mytest_ctx_t)); if(myctx == NULL){ return NGX_ERROR; } //将新建的上下文与请求关联起来 ngx_http_set_ctx(r,myctx,ngx_http_mytest_module); } if(ngx_http_upstream_create(r) != NGX_OK){ ngx_log_error(NGX_LOG_ERR,r->connection->log,0,"ngx_http_upstream_create() failed"); return NGX_ERROR; } //得到配置结构体ngx_http_mytest_conf_t ngx_http_mytest_conf_t *mycf = (ngx_http_mytest_conf_t*)ngx_http_get_module_loc_conf(r,ngx_http_mytest_module); ngx_http_upstream_t *u = r->upstream; //这里用配置文件中的结构体来赋给r->upstream->conf成员 u->conf = &mycf->upstream; u->buffering = mycf->upstream.buffering; //初始化resolved结构体,用来保存上游服务器的地址 u->resolved = (ngx_http_upstream_resolved_t*)ngx_pcalloc(r->pool,sizeof(ngx_http_upstream_resolved_t)); if(u->resolved == NULL){ ngx_log_error(NGX_LOG_ERR,r->connection->log,0,"ngx_pcalloc resolved error. %s.",strerror(errno)); return NGX_ERROR; } static struct sockaddr_in backendSockAddr; struct hostent *pHost = gethostbyname((char*)"www.mmkuaipai.com"); if(pHost == NULL) { ngx_log_error(NGX_LOG_ERR,r->connection->log,0,"gethostbyname fail. %s",strerror(errno)); return NGX_ERROR; } backendSockAddr.sin_family = AF_INET; backendSockAddr.sin_port = htons((in_port_t)80); char* pDmsIP = inet_ntoa(*(struct in_addr*)(pHost->h_addr_list[0])); backendSockAddr.sin_addr.s_addr = inet_addr(pDmsIP); //myctx->backendServer.data = (u_char*)pDmsIP; //myctx->backendServer.len = strlen(pDmsIP); u->resolved->sockaddr = (struct sockaddr*)&backendSockAddr; u->resolved->socklen = sizeof(struct sockaddr_in); u->resolved->naddrs = 1; u->create_request = mytest_upstream_create_request; u->process_header = mytest_process_status_line; u->finalize_request = mytest_upstream_finalize_request; r->main->count++; ngx_http_upstream_init(r); return NGX_DONE; }
static ngx_int_t ngx_http_mytest_handler(ngx_http_request_t *r) { //全局变量 ngx_http_mytest_ctx_t* myctx = ngx_http_get_module_ctx(r, ngx_http_mytest_module); if (myctx == NULL) { myctx = ngx_palloc(r->pool, sizeof(ngx_http_mytest_ctx_t)); if (myctx == NULL) return NGX_ERROR; ngx_http_set_ctx(r, myctx, ngx_http_mytest_module); } //创建upstream结构 if (ngx_http_upstream_create(r) != NGX_OK) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "[jseanj] ngx_http_upstream_create() failed"); return NGX_ERROR; } //获得conf ngx_http_mytest_conf_t *mycf = (ngx_http_mytest_conf_t *) ngx_http_get_module_loc_conf(r, ngx_http_mytest_module); ngx_http_upstream_t *u = r->upstream; u->conf = &mycf->upstream; //conf指定了upstream的运行方式,其中的配置都很重要,它们会影响访问上游服务器的方式 u->buffering = mycf->upstream.buffering; u->resolved = (ngx_http_upstream_resolved_t*) ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_resolved_t)); if (u->resolved == NULL) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "[jseanj] ngx_pcalloc resolved error. %s.", strerror(errno)); return NGX_ERROR; } static struct sockaddr_in backendSockAddr; //struct hostent *pHost = gethostbyname((char*)"www.google.com"); struct hostent *pHost = gethostbyname((char*) "www.baidu.com"); if (pHost == NULL) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "[jseanj] gethostbyname fail. %s.", strerror(errno)); return NGX_ERROR; } backendSockAddr.sin_family = AF_INET; backendSockAddr.sin_port = htons((in_port_t) 80); char* pDmsIP = inet_ntoa(*(struct in_addr*) (pHost->h_addr_list[0])); backendSockAddr.sin_addr.s_addr = inet_addr(pDmsIP); //myctx->backendServer.data = (u_char*)pDmsIP; //myctx->backendServer.len = strlen(pDmsIP); u->resolved->sockaddr = (struct sockaddr *) &backendSockAddr; u->resolved->socklen = sizeof(struct sockaddr_in); u->resolved->naddrs = 1; u->create_request = mytest_upstream_create_request; u->process_header = mytest_process_status_line; u->finalize_request = mytest_upstream_finalize_request; r->main->count++; ngx_http_upstream_init(r); return NGX_DONE; }
static ngx_int_t ngx_http_tnt_handler(ngx_http_request_t *r) { ngx_int_t rc; ngx_http_upstream_t *u; ngx_http_tnt_loc_conf_t *tlcf; tlcf = ngx_http_get_module_loc_conf(r, ngx_http_tnt_module); if (!(r->method & ngx_http_tnt_allowed_methods) || (r->method & tlcf->http_rest_methods && !tlcf->method.len && r->uri.len <= 1 /* i.e '/' */)) { return NGX_HTTP_NOT_ALLOWED; } if (ngx_http_set_content_type(r) != NGX_OK || ngx_http_upstream_create(r) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } u = r->upstream; ngx_str_set(&u->schema, "tnt://"); u->output.tag = (ngx_buf_tag_t) &ngx_http_tnt_module; u->conf = &tlcf->upstream; rc = ngx_http_tnt_init_handlers(r, u, tlcf); if (rc != NGX_OK){ return rc; } u->input_filter_init = ngx_http_tnt_filter_init; u->input_filter = ngx_http_tnt_filter; u->input_filter_ctx = r; u->length = 0; u->state = 0; rc = ngx_http_read_client_request_body(r, ngx_http_upstream_init); if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { return rc; } return NGX_DONE; }
static ngx_int_t ngx_zmx_handler(ngx_http_request_t *r) { ngx_int_t rc; ngx_http_upstream_t *u; ngx_zmx_ctx_t *ctx; ngx_http_proxy_loc_conf_t *plcf; if (ngx_http_upstream_create(r) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } ctx = ngx_pcalloc(r->pool, sizeof(ngx_zmx_ctx_t)); if (ctx == NULL) { return NGX_ERROR; } ngx_http_set_ctx(r, ctx, ngx_zmx_module); /* plcf = ngx_http_get_module_loc_conf(r, ngx_zmx_module); */ u = r->upstream; u->output.tag = (ngx_buf_tag_t) &ngx_zmx_module; u->conf = &plcf->upstream; u->create_request = ngx_http_proxy_create_request; u->reinit_request = ngx_http_proxy_reinit_request; u->process_header = ngx_http_proxy_process_status_line; u->abort_request = ngx_http_proxy_abort_request; u->finalize_request = ngx_http_proxy_finalize_request; r->state = 0; u->buffering = plcf->upstream.buffering; /* u->pipe = ngx_pcalloc(r->pool, sizeof(ngx_event_pipe_t)); */ /* if (u->pipe == NULL) { */ /* return NGX_HTTP_INTERNAL_SERVER_ERROR; */ /* } */ /* u->accel = 1; */ rc = ngx_http_read_client_request_body(r, ngx_http_upstream_init); return NGX_DONE; }
static ngx_int_t ngx_http_mcset_module_init_cache_request( ngx_http_request_t *r ) { ngx_http_mcset_module_conf_t* mscf; ngx_http_upstream_t *u; ngx_mcset_module_ctx_t* ctx; mscf = ngx_http_get_module_loc_conf( r, ngx_http_mcset_module ); ctx = ngx_http_get_module_ctx( r, ngx_http_mcset_module ); if ( ctx == NULL ) { ctx = ngx_pcalloc( r->pool, sizeof( ngx_mcset_module_ctx_t ) ); if ( ctx == NULL ) { return NGX_ERROR; } ctx->cache_id.len = 32; ctx->cache_id.data = ngx_pcalloc( r->pool, ctx->cache_id.len ); ctx->r = r; ngx_http_set_ctx( r, ctx, ngx_http_mcset_module ); } if ( ngx_http_upstream_create( r ) != NGX_OK ) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } u = r->upstream; ngx_str_set( &u->schema, "memcached://" ); u->conf = &mscf->upstream; u->create_request = ngx_http_mcset_cache_create_request; u->reinit_request = ngx_http_mcset_cache_reinit_request; u->process_header = ngx_http_mcset_cache_process_header; u->abort_request = ngx_http_mcset_cache_abort_request; u->finalize_request = ngx_http_mcset_cache_finalize_request; u->input_filter_init = ngx_http_mcset_module_filter_init; u->input_filter = ngx_http_mcset_module_filter; u->input_filter_ctx = ctx; r->subrequest_in_memory = 1; r->main->count++; ngx_http_upstream_init( r ); return NGX_OK; }
static ngx_int_t ngx_http_proxy_connect_upstream(ngx_http_request_t *r) { ngx_http_upstream_t *u; ngx_http_proxy_connect_ctx_t *ctx; ngx_http_proxy_connect_loc_conf_t *mlcf; if (ngx_http_upstream_create(r) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } mlcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_connect_module); ctx = ngx_http_get_module_ctx(r,ngx_http_proxy_connect_module); if (ngx_http_proxy_connect_eval(r, ctx, mlcf) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } ctx->request = r; u = r->upstream; ngx_str_set(&u->schema, "proxy_connect://"); u->output.tag = (ngx_buf_tag_t) &ngx_http_proxy_connect_module; mlcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_connect_module); u->conf = &mlcf->upstream; u->create_request = ngx_http_proxy_connect_create_request; u->reinit_request = ngx_http_proxy_connect_reinit_request; u->process_header = ngx_http_proxy_connect_process_header; u->abort_request = ngx_http_proxy_connect_abort_request; u->finalize_request = ngx_http_proxy_connect_finalize_request; u->input_filter_init = NULL; u->input_filter = NULL; u->input_filter_ctx = ctx; ngx_http_upstream_init(r); return NGX_DONE; }
ngx_int_t passenger_content_handler(ngx_http_request_t *r) { ngx_int_t rc; ngx_http_upstream_t *u; passenger_loc_conf_t *slcf; ngx_str_t path, base_uri; u_char *path_last, *end; u_char root_path_str[NGX_MAX_PATH + 1]; ngx_str_t root_path; size_t root_len, len; u_char page_cache_file_str[NGX_MAX_PATH + 1]; ngx_str_t page_cache_file; passenger_context_t *context; PP_Error error; if (passenger_main_conf.root_dir.len == 0) { return NGX_DECLINED; } slcf = ngx_http_get_module_loc_conf(r, ngx_http_passenger_module); /* Let the next content handler take care of this request if Phusion * Passenger is disabled for this URL. */ if (!slcf->enabled) { return NGX_DECLINED; } /* Let the next content handler take care of this request if this URL * maps to an existing file. */ path_last = ngx_http_map_uri_to_path(r, &path, &root_len, 0); if (path_last != NULL && file_exists(path.data, 0)) { return NGX_DECLINED; } /* Create a string containing the root path. This path already * contains a trailing slash. */ end = ngx_copy(root_path_str, path.data, root_len); *end = '\0'; root_path.data = root_path_str; root_path.len = root_len; context = ngx_pcalloc(r->pool, sizeof(passenger_context_t)); if (context == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } ngx_http_set_ctx(r, context, ngx_http_passenger_module); /* Find the base URI for this web application, if any. */ if (find_base_uri(r, slcf, &base_uri)) { /* Store the found base URI into context->public_dir. We infer that * the 'public' directory of the web app equals document root + base URI. */ if (slcf->document_root.data != NULL) { len = slcf->document_root.len + 1; context->public_dir.data = ngx_palloc(r->pool, sizeof(u_char) * len); end = ngx_copy(context->public_dir.data, slcf->document_root.data, slcf->document_root.len); } else { len = root_path.len + base_uri.len + 1; context->public_dir.data = ngx_palloc(r->pool, sizeof(u_char) * len); end = ngx_copy(context->public_dir.data, root_path.data, root_path.len); end = ngx_copy(end, base_uri.data, base_uri.len); } *end = '\0'; context->public_dir.len = len - 1; context->base_uri = base_uri; } else { /* No base URI directives are applicable for this request. So assume that * the web application's public directory is the document root. * context->base_uri is now a NULL string. */ len = sizeof(u_char *) * (root_path.len + 1); context->public_dir.data = ngx_palloc(r->pool, len); end = ngx_copy(context->public_dir.data, root_path.data, root_path.len); *end = '\0'; context->public_dir.len = root_path.len; } /* If there's a corresponding page cache file for this URL, then serve that * file instead. */ page_cache_file.data = page_cache_file_str; page_cache_file.len = sizeof(page_cache_file_str); if (map_uri_to_page_cache_file(r, &context->public_dir, path.data, path_last - path.data, &page_cache_file)) { return passenger_static_content_handler(r, &page_cache_file); } if (slcf->app_type.data == NULL) { pp_error_init(&error); if (slcf->app_root.data == NULL) { context->app_type = pp_app_type_detector_check_document_root( pp_app_type_detector, (const char *) context->public_dir.data, context->public_dir.len, context->base_uri.len != 0, &error); } else { context->app_type = pp_app_type_detector_check_app_root( pp_app_type_detector, (const char *) slcf->app_root.data, slcf->app_root.len, &error); } if (context->app_type == PAT_NONE) { return NGX_DECLINED; } else if (context->app_type == PAT_ERROR) { if (error.errnoCode == EACCES) { ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, "%s; This error means that the Nginx worker process (PID %d, " "running as UID %d) does not have permission to access this file. " "Please read the manual to learn how to fix this problem: " "section 'Troubleshooting' -> 'Upon accessing the web app, Nginx " "reports a \"Permission denied\" error'; Extra info", error.message, (int) getpid(), (int) getuid()); } else { ngx_log_error(NGX_LOG_ALERT, r->connection->log, (error.errnoCode == PP_NO_ERRNO) ? 0 : error.errnoCode, "%s", error.message); } pp_error_destroy(&error); return NGX_HTTP_INTERNAL_SERVER_ERROR; } } else { context->app_type = pp_get_app_type2((const char *) slcf->app_type.data, slcf->app_type.len); if (context->app_type == PAT_NONE) { return NGX_DECLINED; } } /* Setup upstream stuff and prepare sending the request to the Passenger core. */ if (ngx_http_upstream_create(r) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } u = r->upstream; u->schema = pp_schema_string; u->output.tag = (ngx_buf_tag_t) &ngx_http_passenger_module; set_upstream_server_address(u, &slcf->upstream_config); u->conf = &slcf->upstream_config; #if (NGX_HTTP_CACHE) u->create_key = create_key; #endif u->create_request = create_request; u->reinit_request = reinit_request; u->process_header = process_status_line; u->abort_request = abort_request; u->finalize_request = finalize_request; r->state = 0; u->buffering = slcf->upstream_config.buffering; u->pipe = ngx_pcalloc(r->pool, sizeof(ngx_event_pipe_t)); if (u->pipe == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } u->pipe->input_filter = ngx_event_pipe_copy_input_filter; u->pipe->input_ctx = r; rc = ngx_http_read_client_request_body(r, ngx_http_upstream_init); fix_peer_address(r); if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { return rc; } return NGX_DONE; }
static ngx_int_t ngx_http_upstreamTest_handler(ngx_http_request_t *r) { static ngx_int_t visited_times = 0; ngx_http_upstreamTest_ctx_t *upstreamctx = ngx_http_get_module_ctx(r,ngx_http_upstreamTest_module); if(upstreamctx == NULL) { upstreamctx = ngx_pcalloc(r->pool,sizeof(ngx_http_upstreamTest_ctx_t)); if(upstreamctx == NULL) { return NGX_ERROR; } ngx_http_set_ctx(r,upstreamctx,ngx_http_upstream_module); } if(ngx_http_upstream_create(r) != NGX_OK) { ngx_log_error(NGX_LOG_ERR,r->connection->log,0,"ngx_http_upstream_create() failed"); return NGX_ERROR; } ngx_http_upstreamTest_conf_t *upstreamconf = (ngx_http_upstreamTest_conf_t *)ngx_http_get_module_loc_conf(r,ngx_http_upstreamTest_module); ngx_http_upstream_t *u = r->upstream; u->conf = &upstreamconf->upstream; u->buffering = upstreamconf->upstream.buffering; u->resolved = (ngx_http_upstream_resolved_t*)ngx_pcalloc(r->pool,sizeof(ngx_http_upstream_resolved_t)); if(u->resolved == NULL) { ngx_log_error(NGX_LOG_ERR,r->connection->log,0,"ngx_pcalloc resolved error. %s",strerror(errno)); return NGX_ERROR; } // static struct sockaddr_in backendSockAddr; // backendSockAddr.sin_family = AF_INET; // backendSockAddr.sin_port = htons((in_port_t)7777); // backendSockAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); // u->resolved->sockaddr = (struct sockaddr *)&backendSockAddr; // u->resolved->socklen = sizeof(struct sockaddr_in); // u->resolved->naddrs = 1; u->create_request = ngx_http_upstreamTest_create_request; u->process_header = ngx_http_upstreamTest_process_status_line; u->finalize_request = ngx_http_upstreamTest_finalize_request; // r->main->count++; // ngx_http_upstream_init(r); if(!(r->method & (NGX_HTTP_GET | NGX_HTTP_HEAD))) return NGX_HTTP_NOT_ALLOWED; u_char ngx_upstream_string[1024]; ngx_sprintf(ngx_upstream_string,"Visited times: %d",++visited_times); ngx_log_error(NGX_LOG_EMERG,r->connection->log,0,"ngx_upstream_string: %s",ngx_upstream_string); ngx_uint_t content_length = ngx_strlen(ngx_upstream_string); ngx_int_t rc; if(!(r->method & (NGX_HTTP_GET | NGX_HTTP_HEAD))) return NGX_HTTP_NOT_ALLOWED; rc = ngx_http_discard_request_body(r); if(rc != NGX_OK) { ngx_log_error(NGX_LOG_EMERG,r->connection->log,0,"discard requst_body failed!"); return rc; } ngx_str_set(&r->headers_out.content_type,"text/html"); if(r->method == NGX_HTTP_HEAD) { r->headers_out.status = NGX_HTTP_OK; r->headers_out.content_length_n = content_length; ngx_log_error(NGX_LOG_EMERG,r->connection->log,0,"send respond head!"); return ngx_http_send_header(r); } ngx_buf_t *b; b = ngx_pcalloc(r->pool,sizeof(ngx_buf_t)); if(b == NULL) return NGX_HTTP_INTERNAL_SERVER_ERROR; ngx_chain_t out; out.buf = b; out.next = NULL; b->pos = ngx_upstream_string; b->last = ngx_upstream_string + content_length; b->memory = 1; b->last_buf = 1; r->headers_out.status = NGX_HTTP_OK; r->headers_out.content_length_n = content_length; rc = ngx_http_send_header(r); if(rc == NGX_ERROR || rc > NGX_OK || r->header_only) return rc; ngx_http_output_filter(r,&out); r->main->count++; ngx_http_upstream_init(r); return NGX_OK; }
//在ngx_http_mytest_handler方法中启动upstream static ngx_int_t ngx_http_mytest_handler(ngx_http_request_t *r) { //首先建立HTTP上下文结构体 ngx_http_mytest_ctx_t *myctx = ngx_http_get_module_ctx(r, ngx_http_mytest_module); if(myctx == NULL){ myctx = ngx_palloc(r->pool, sizeof(ngx_http_mytest_ctx_t)); if(myctx == NULL){ return NGX_ERROR; } //将新建的上下文与请求联系起来 ngx_http_set_ctx(r, myctx, ngx_http_mytest_module); } //对每一个要使用upstream的请求,必须调用且只能调用一次ngx_http_upstream_create方法, //它会初始化r->upstream成员 if(ngx_http_upstream_create(r) != NGX_OK){ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "ngx_http_upstream_create() failed"); return NGX_ERROR; } //得到配置结构体ngx_http_mytest_conf_t ngx_http_mytest_conf_t *mycf = (ngx_http_mytest_conf_t *) ngx_http_get_module_loc_conf(r, ngx_http_mytest_module); ngx_http_upstream_t *u = r->upstream; //这里用配置文件中的结构体来赋值给r->upstream->conf成员 u->conf = &mycf->upstream; u->buffering = mycf->upstream.buffering; //以下代码开始初始化resolved结构体,用来保存上游服务器的地址 u->resolved = (ngx_http_upstream_resolved_t *)ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_resolved_t)); if(u->resolved == NULL){ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "ngx_pcalloc resolved error. %s.", strerror(errno)); return NGX_ERROR; } //这里的上游服务器是www.bing.com static struct sockaddr_in backendSockAddr; struct hostent *pHost = gethostbyname((char*)"bing.com"); if(pHost == NULL){ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "gethostbyname fail. %s.", strerror(errno)); return NGX_ERROR; } //访问上游服务器的80端口 backendSockAddr.sin_family = AF_INET; backendSockAddr.sin_port = htons((in_port_t)80); char *pDmsIP = inet_ntoa(*(struct in_addr*)(pHost->h_addr_list[0])); backendSockAddr.sin_addr.s_addr = inet_addr(pDmsIP); //myctx->backendServer.data = (u_char*)pDmsIP; //myctx->backendServer.len = strlen(pDmsIP); //将地址设置到resolved成员中 u->resolved->sockaddr = (struct sockaddr *)&backendSockAddr; u->resolved->socklen = sizeof(struct sockaddr_in); u->resolved->naddrs = 1; //设置三个必须实现的回调方法 u->create_request = mytest_upstream_create_request; u->process_header = mytest_process_status_line; u->finalize_request = mytest_upstream_finalize_request; //这里必须将count成员加1 r->main->count++; //启动upstream ngx_http_upstream_init(r); //必须返回NGX_DONE return NGX_DONE; }
static ngx_int_t ngx_http_scgi_handler(ngx_http_request_t *r) { ngx_int_t rc; ngx_http_status_t *status; ngx_http_upstream_t *u; ngx_http_scgi_loc_conf_t *scf; if (r->subrequest_in_memory) { ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, "ngx_http_scgi_module does not support " "subrequests in memory"); return NGX_HTTP_INTERNAL_SERVER_ERROR; } if (ngx_http_upstream_create(r) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } status = ngx_pcalloc(r->pool, sizeof(ngx_http_status_t)); if (status == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } ngx_http_set_ctx(r, status, ngx_http_scgi_module); scf = ngx_http_get_module_loc_conf(r, ngx_http_scgi_module); if (scf->scgi_lengths) { if (ngx_http_scgi_eval(r, scf) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } } u = r->upstream; ngx_str_set(&u->schema, "scgi://"); u->output.tag = (ngx_buf_tag_t) &ngx_http_scgi_module; u->conf = &scf->upstream; #if (NGX_HTTP_CACHE) u->create_key = ngx_http_scgi_create_key; #endif u->create_request = ngx_http_scgi_create_request; u->reinit_request = ngx_http_scgi_reinit_request; u->process_header = ngx_http_scgi_process_status_line; u->abort_request = ngx_http_scgi_abort_request; u->finalize_request = ngx_http_scgi_finalize_request; u->buffering = 1; u->pipe = ngx_pcalloc(r->pool, sizeof(ngx_event_pipe_t)); if (u->pipe == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } u->pipe->input_filter = ngx_event_pipe_copy_input_filter; u->pipe->input_ctx = r; rc = ngx_http_read_client_request_body(r, ngx_http_upstream_init); if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { return rc; } return NGX_DONE; }
ngx_int_t ngx_http_drizzle_handler(ngx_http_request_t *r) { ngx_http_upstream_t *u; ngx_http_drizzle_loc_conf_t *dlcf; #if defined(nginx_version) && nginx_version < 8017 ngx_http_drizzle_ctx_t *dctx; #endif ngx_http_core_loc_conf_t *clcf; ngx_str_t target; ngx_url_t url; ngx_connection_t *c; dd("request: %p", r); dd("subrequest in memory: %d", (int) r->subrequest_in_memory); dd("connection: %p", r->connection); dd("connection log: %p", r->connection->log); if (r->subrequest_in_memory) { /* TODO: add support for subrequest in memory by * emitting output into u->buffer instead */ ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, "ngx_http_drizzle_module does not support " "subrequest in memory"); return NGX_HTTP_INTERNAL_SERVER_ERROR; } dlcf = ngx_http_get_module_loc_conf(r, ngx_http_drizzle_module); if ((dlcf->default_query == NULL) && !(dlcf->methods_set & r->method)) { if (dlcf->methods_set != 0) { return NGX_HTTP_NOT_ALLOWED; } clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "drizzle: missing \"drizzle_query\" in location \"%V\"", &clcf->name); return NGX_HTTP_INTERNAL_SERVER_ERROR; } dd("XXX upstream already exists? %p", r->upstream); #if defined(nginx_version) && \ ((nginx_version >= 7063 && nginx_version < 8000) \ || nginx_version >= 8007) dd("creating upstream......."); if (ngx_http_upstream_create(r) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } u = r->upstream; #else /* 0.7.x < 0.7.63, 0.8.x < 0.8.7 */ dd("XXX create upstream"); u = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_t)); if (u == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } u->peer.log = r->connection->log; u->peer.log_error = NGX_ERROR_ERR; # if (NGX_THREADS) u->peer.lock = &r->connection->lock; # endif r->upstream = u; #endif if (dlcf->complex_target) { /* variables used in the drizzle_pass directive */ if (ngx_http_complex_value(r, dlcf->complex_target, &target) != NGX_OK) { dd("failed to compile"); return NGX_ERROR; } if (target.len == 0) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "drizzle: handler: empty \"drizzle_pass\" target"); return NGX_HTTP_INTERNAL_SERVER_ERROR; } url.host = target; url.port = 0; url.no_resolve = 1; dlcf->upstream.upstream = ngx_http_upstream_drizzle_add(r, &url); if (dlcf->upstream.upstream == NULL) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "drizzle: upstream \"%V\" not found", &target); return NGX_HTTP_INTERNAL_SERVER_ERROR; } } #if defined(nginx_version) && nginx_version < 8017 dctx = ngx_pcalloc(r->pool, sizeof(ngx_http_drizzle_ctx_t)); if (dctx == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } ngx_http_set_ctx(r, dctx, ngx_http_drizzle_module); #endif u->schema.len = sizeof("drizzle://") - 1; u->schema.data = (u_char *) "drizzle://"; u->output.tag = (ngx_buf_tag_t) &ngx_http_drizzle_module; dd("drizzle tag: %p", (void *) u->output.tag); u->conf = &dlcf->upstream; u->create_request = ngx_http_drizzle_create_request; u->reinit_request = ngx_http_drizzle_reinit_request; u->process_header = ngx_http_drizzle_process_header; u->abort_request = ngx_http_drizzle_abort_request; u->finalize_request = ngx_http_drizzle_finalize_request; /* we bypass the upstream input filter mechanism in * ngx_http_upstream_process_headers */ u->input_filter_init = ngx_http_drizzle_input_filter_init; u->input_filter = ngx_http_drizzle_input_filter; u->input_filter_ctx = NULL; #if defined(nginx_version) && nginx_version >= 8011 r->main->count++; #endif dd("XXX connect timeout: %d", (int) dlcf->upstream.connect_timeout); ngx_http_upstream_dbd_init(r); /* override the read/write event handler to our own */ u->write_event_handler = ngx_http_drizzle_wev_handler; u->read_event_handler = ngx_http_drizzle_rev_handler; /* a bit hack-ish way to return error response (clean-up part) */ if ((u->peer.connection) && (u->peer.connection->fd == 0)) { c = u->peer.connection; u->peer.connection = NULL; if (c->write->timer_set) { ngx_del_timer(c->write); } ngx_free_connection(c); ngx_http_upstream_drizzle_finalize_request(r, u, #if defined(nginx_version) && (nginx_version >= 8017) NGX_HTTP_SERVICE_UNAVAILABLE); #else dctx->status ? dctx->status : NGX_HTTP_INTERNAL_SERVER_ERROR); #endif }
ngx_int_t ngx_http_redis2_handler(ngx_http_request_t *r) { ngx_int_t rc; ngx_http_upstream_t *u; ngx_http_redis2_ctx_t *ctx; ngx_http_redis2_loc_conf_t *rlcf; ngx_str_t target; ngx_url_t url; rc = ngx_http_discard_request_body(r); if (rc != NGX_OK) { return rc; } if (ngx_http_set_content_type(r) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } if (ngx_http_upstream_create(r) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } u = r->upstream; rlcf = ngx_http_get_module_loc_conf(r, ngx_http_redis2_module); if (rlcf->complex_target) { /* variables used in the redis2_pass directive */ if (ngx_http_complex_value(r, rlcf->complex_target, &target) != NGX_OK) { return NGX_ERROR; } if (target.len == 0) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "handler: empty \"redis2_pass\" target"); return NGX_HTTP_INTERNAL_SERVER_ERROR; } url.host = target; url.port = 0; url.no_resolve = 1; rlcf->upstream.upstream = ngx_http_redis2_upstream_add(r, &url); if (rlcf->upstream.upstream == NULL) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "redis2: upstream \"%V\" not found", &target); return NGX_HTTP_INTERNAL_SERVER_ERROR; } } ngx_str_set(&u->schema, "redis2://"); u->output.tag = (ngx_buf_tag_t) &ngx_http_redis2_module; u->conf = &rlcf->upstream; u->create_request = ngx_http_redis2_create_request; u->reinit_request = ngx_http_redis2_reinit_request; u->process_header = ngx_http_redis2_process_header; u->abort_request = ngx_http_redis2_abort_request; u->finalize_request = ngx_http_redis2_finalize_request; ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_redis2_ctx_t)); if (ctx == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } ctx->request = r; ctx->state = NGX_ERROR; ngx_http_set_ctx(r, ctx, ngx_http_redis2_module); u->input_filter_init = ngx_http_redis2_filter_init; u->input_filter = ngx_http_redis2_filter; u->input_filter_ctx = ctx; r->main->count++; ngx_http_upstream_init(r); return NGX_DONE; }
ngx_int_t passenger_content_handler(ngx_http_request_t *r) { ngx_int_t rc; ngx_http_upstream_t *u; passenger_loc_conf_t *slcf; ngx_str_t path, base_uri; u_char *path_last, *end; u_char root_path_str[NGX_MAX_PATH + 1]; ngx_str_t root_path; size_t root, len; u_char page_cache_file_str[NGX_MAX_PATH + 1]; ngx_str_t page_cache_file; passenger_context_t *context; if (passenger_main_conf.root_dir.len == 0) { return NGX_DECLINED; } else if (r->subrequest_in_memory) { ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, "ngx_http_passenger_module does not support " "subrequest in memory"); return NGX_HTTP_INTERNAL_SERVER_ERROR; } slcf = ngx_http_get_module_loc_conf(r, ngx_http_passenger_module); /* Let the next content handler take care of this request if Phusion * Passenger is disabled for this URL. */ if (!slcf->enabled) { return NGX_DECLINED; } /* Let the next content handler take care of this request if this URL * maps to an existing file. */ path_last = ngx_http_map_uri_to_path(r, &path, &root, 0); if (path_last != NULL && file_exists(path.data, 0)) { return NGX_DECLINED; } /* Create a string containing the root path. This path already * contains a trailing slash. */ end = ngx_copy(root_path_str, path.data, root); *end = '\0'; root_path.data = root_path_str; root_path.len = root; context = ngx_pcalloc(r->pool, sizeof(passenger_context_t)); if (context == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } ngx_http_set_ctx(r, context, ngx_http_passenger_module); /* Find the base URI for this web application, if any. */ if (find_base_uri(r, slcf, &base_uri)) { /* Store the found base URI in context->public_dir. We infer that the 'public' * directory of the web application is document root + base URI. */ len = root_path.len + base_uri.len + 1; context->public_dir.data = ngx_palloc(r->pool, sizeof(u_char) * len); end = ngx_copy(context->public_dir.data, root_path.data, root_path.len); end = ngx_copy(end, base_uri.data, base_uri.len); *end = '\0'; context->public_dir.len = len - 1; context->base_uri = base_uri; } else { /* No base URI directives are applicable for this request. So assume that * the web application's public directory is the document root. * context->base_uri is now a NULL string. */ len = sizeof(u_char *) * (root_path.len + 1); context->public_dir.data = ngx_palloc(r->pool, len); end = ngx_copy(context->public_dir.data, root_path.data, root_path.len); *end = '\0'; context->public_dir.len = root_path.len; } /* If there's a corresponding page cache file for this URL, then serve that * file instead. */ page_cache_file.data = page_cache_file_str; page_cache_file.len = sizeof(page_cache_file_str); if (map_uri_to_page_cache_file(r, &context->public_dir, path.data, path_last - path.data, &page_cache_file)) { return passenger_static_content_handler(r, &page_cache_file); } context->app_type = detect_application_type(&context->public_dir); if (context->app_type == AP_NONE) { return NGX_DECLINED; } /* Setup upstream stuff and prepare sending the request to the backend. */ if (ngx_http_upstream_create(r) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } u = r->upstream; u->schema = passenger_schema_string; u->output.tag = (ngx_buf_tag_t) &ngx_http_passenger_module; set_upstream_server_address(u, &slcf->upstream_config); u->conf = &slcf->upstream_config; #if (NGX_HTTP_CACHE) u->create_key = create_key; #endif u->create_request = create_request; u->reinit_request = reinit_request; u->process_header = process_status_line; u->abort_request = abort_request; u->finalize_request = finalize_request; u->buffering = slcf->upstream_config.buffering; u->pipe = ngx_pcalloc(r->pool, sizeof(ngx_event_pipe_t)); if (u->pipe == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } u->pipe->input_filter = ngx_event_pipe_copy_input_filter; u->pipe->input_ctx = r; rc = ngx_http_read_client_request_body(r, ngx_http_upstream_init); if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { return rc; } return NGX_DONE; }
static ngx_int_t ngx_http_redis_handler(ngx_http_request_t *r) { ngx_int_t rc; ngx_http_upstream_t *u; ngx_http_redis_ctx_t *ctx; ngx_http_redis_loc_conf_t *rlcf; if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) { return NGX_HTTP_NOT_ALLOWED; } rc = ngx_http_discard_request_body(r); if (rc != NGX_OK) { return rc; } if (ngx_http_set_content_type(r) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } #if defined nginx_version && nginx_version >= 8011 if (ngx_http_upstream_create(r) != NGX_OK) { #else rlcf = ngx_http_get_module_loc_conf(r, ngx_http_redis_module); u = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_t)); if (u == NULL) { #endif return NGX_HTTP_INTERNAL_SERVER_ERROR; } #if defined nginx_version && nginx_version >= 8011 u = r->upstream; #endif #if defined nginx_version && nginx_version >= 8037 ngx_str_set(&u->schema, "redis://"); #else u->schema.len = sizeof("redis://") - 1; u->schema.data = (u_char *) "redis://"; #endif #if defined nginx_version && nginx_version >= 8011 u->output.tag = (ngx_buf_tag_t) &ngx_http_redis_module; #else u->peer.log = r->connection->log; u->peer.log_error = NGX_ERROR_ERR; #endif #if defined nginx_version && nginx_version >= 8011 rlcf = ngx_http_get_module_loc_conf(r, ngx_http_redis_module); #else u->output.tag = (ngx_buf_tag_t) &ngx_http_redis_module; #endif u->conf = &rlcf->upstream; u->create_request = ngx_http_redis_create_request; u->reinit_request = ngx_http_redis_reinit_request; u->process_header = ngx_http_redis_process_header; u->abort_request = ngx_http_redis_abort_request; u->finalize_request = ngx_http_redis_finalize_request; #if defined nginx_version && nginx_version < 8011 r->upstream = u; #endif ctx = ngx_palloc(r->pool, sizeof(ngx_http_redis_ctx_t)); if (ctx == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } ctx->rest = NGX_HTTP_REDIS_END; ctx->request = r; ngx_http_set_ctx(r, ctx, ngx_http_redis_module); u->input_filter_init = ngx_http_redis_filter_init; u->input_filter = ngx_http_redis_filter; u->input_filter_ctx = ctx; #if defined nginx_version && nginx_version >= 8011 r->main->count++; #endif ngx_http_upstream_init(r); return NGX_DONE; } static ngx_int_t ngx_http_redis_create_request(ngx_http_request_t *r) { size_t len, i; ngx_buf_t *b; ngx_chain_t *cl; ngx_http_redis_ctx_t *ctx; ngx_http_variable_value_t *vv[2]; ngx_http_redis_loc_conf_t *rlcf; //The start of the unified protocol GET request const char *get_request_start = "*2\r\n$3\r\nGET\r\n$"; //Buffer to store the char version of the key - max size char key_len_buf[8]; //Bad code //TODO: use ngx_get_num_size( to remove the need for this const char* key_len_ptr = &key_len_buf[0]; int key_len; rlcf = ngx_http_get_module_loc_conf(r, ngx_http_redis_module); vv[0] = ngx_http_get_indexed_variable(r, ngx_http_redis_db_index); /* * If user do not select redis database in nginx.conf by redis_db * variable, just add size of "select 0" to request. This is add * some overhead in talk with redis, but this way simplify parsing * the redis answer in ngx_http_redis_process_header(). */ if (vv[0] == NULL || vv[0]->not_found || vv[0]->len == 0) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "select 0 redis database" ); len = sizeof("select 0") - 1; } else { len = sizeof("select ") - 1 + vv[0]->len; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "select %s redis database", vv[0]->data); } len += sizeof(CRLF) - 1; vv[1] = ngx_http_get_indexed_variable(r, rlcf->index); /* If nginx.conf have no redis_key return error. */ if (vv[1] == NULL || vv[1]->not_found || vv[1]->len == 0) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "the \"$redis_key\" variable is not set"); return NGX_ERROR; } key_len = sprintf(key_len_buf,"%d",vv[1]->len); //Work out how long the request is going to be //14 = length of request_start len += 14 + key_len + sizeof(CRLF) - 1 + vv[1]->len + sizeof(CRLF) - 1; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "redis request length: %d", len); /* Create temporary buffer for request with size len. */ b = ngx_create_temp_buf(r->pool, len); if (b == NULL) { return NGX_ERROR; } cl = ngx_alloc_chain_link(r->pool); if (cl == NULL) { return NGX_ERROR; } cl->buf = b; cl->next = NULL; r->upstream->request_bufs = cl; /* Add "select " for request. */ *b->last++ = 's'; *b->last++ = 'e'; *b->last++ = 'l'; *b->last++ = 'e'; *b->last++ = 'c'; *b->last++ = 't'; *b->last++ = ' '; /* Get context redis_db from configuration file. */ ctx = ngx_http_get_module_ctx(r, ngx_http_redis_module); ctx->key.data = b->last; /* * Add "0" as redis number db to request if redis_db undefined, * othervise add real number from context. */ if (vv[0] == NULL || vv[0]->not_found || vv[0]->len == 0) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "select 0 redis database" ); *b->last++ = '0'; } else { b->last = ngx_copy(b->last, vv[0]->data, vv[0]->len); ctx->key.len = b->last - ctx->key.data; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "select %V redis database", &ctx->key); } /* Add "\r\n". */ *b->last++ = CR; *b->last++ = LF; /* Add "get" command with space. */ for(i=0;i<14;i++){ *b->last++ = get_request_start[i]; } /* Add length */ while(key_len != 0){ *b->last++ = *key_len_ptr; key_len--; key_len_ptr ++; } /* Add one more "\r\n". */ *b->last++ = CR; *b->last++ = LF; /* Get context redis_key from nginx.conf. */ ctx = ngx_http_get_module_ctx(r, ngx_http_redis_module); ctx->key.data = b->last; /* Copy the key into the request buffer */ b->last = ngx_copy(b->last, vv[1]->data, vv[1]->len); ctx->key.len = b->last - ctx->key.data; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http redis request: \"%V\"", &ctx->key); /* Add one more "\r\n". */ *b->last++ = CR; *b->last++ = LF; /* * Summary, the request looks like this: * "select $redis_db\r\nget $redis_key\r\n", where * $redis_db and $redis_key are variable's values. */ return NGX_OK; }
/* XXX extermely evil and not working yet */ ngx_int_t ngx_http_echo_exec_abort_parent(ngx_http_request_t *r, ngx_http_echo_ctx_t *ctx) { #if 0 ngx_http_postponed_request_t *pr, *ppr; ngx_http_request_t *saved_data = NULL; ngx_chain_t *out = NULL; /* ngx_int_t rc; */ dd("aborting parent..."); if (r == r->main || r->parent == NULL) { return NGX_OK; } if (r->parent->postponed) { dd("Found parent->postponed..."); saved_data = r->connection->data; ppr = NULL; for (pr = r->parent->postponed; pr->next; pr = pr->next) { if (pr->request == NULL) { continue; } if (pr->request == r) { /* r->parent->postponed->next = pr; */ dd("found the current subrequest"); out = pr->out; continue; } /* r->connection->data = pr->request; */ dd("finalizing the subrequest..."); ngx_http_upstream_create(pr->request); pr->request->upstream = NULL; if (ppr == NULL) { r->parent->postponed = pr->next; ppr = pr->next; } else { ppr->next = pr->next; ppr = pr->next; } } } r->parent->postponed->next = NULL; /* r->connection->data = r->parent; r->connection->buffered = 0; if (out != NULL) { dd("trying to send more stuffs for the parent"); ngx_http_output_filter(r->parent, out); } */ /* ngx_http_send_special(r->parent, NGX_HTTP_LAST); */ if (saved_data) { r->connection->data = saved_data; } dd("terminating the parent request"); return ngx_http_echo_send_chain_link(r, ctx, NULL /* indicate LAST */); /* ngx_http_upstream_create(r); */ /* ngx_http_finalize_request(r->parent, NGX_ERROR); */ #endif return NGX_OK; }
static ngx_int_t ngx_http_redis_handler(ngx_http_request_t *r) { ngx_int_t rc; ngx_http_upstream_t *u; ngx_http_redis_ctx_t *ctx; ngx_http_redis_loc_conf_t *rlcf; if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) { return NGX_HTTP_NOT_ALLOWED; } rc = ngx_http_discard_request_body(r); if (rc != NGX_OK) { return rc; } if (ngx_http_set_content_type(r) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } #if defined nginx_version && nginx_version >= 8011 if (ngx_http_upstream_create(r) != NGX_OK) { #else rlcf = ngx_http_get_module_loc_conf(r, ngx_http_redis_module); u = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_t)); if (u == NULL) { #endif return NGX_HTTP_INTERNAL_SERVER_ERROR; } #if defined nginx_version && nginx_version >= 8011 u = r->upstream; #endif #if defined nginx_version && nginx_version >= 8037 ngx_str_set(&u->schema, "redis://"); #else u->schema.len = sizeof("redis://") - 1; u->schema.data = (u_char *) "redis://"; #endif #if defined nginx_version && nginx_version >= 8011 u->output.tag = (ngx_buf_tag_t) &ngx_http_redis_module; #else u->peer.log = r->connection->log; u->peer.log_error = NGX_ERROR_ERR; #endif #if defined nginx_version && nginx_version >= 8011 rlcf = ngx_http_get_module_loc_conf(r, ngx_http_redis_module); #else u->output.tag = (ngx_buf_tag_t) &ngx_http_redis_module; #endif u->conf = &rlcf->upstream; u->create_request = ngx_http_redis_create_request; u->reinit_request = ngx_http_redis_reinit_request; u->process_header = ngx_http_redis_process_header; u->abort_request = ngx_http_redis_abort_request; u->finalize_request = ngx_http_redis_finalize_request; #if defined nginx_version && nginx_version < 8011 r->upstream = u; #endif ctx = ngx_palloc(r->pool, sizeof(ngx_http_redis_ctx_t)); if (ctx == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } ctx->rest = NGX_HTTP_REDIS_END; ctx->request = r; ngx_http_set_ctx(r, ctx, ngx_http_redis_module); u->input_filter_init = ngx_http_redis_filter_init; u->input_filter = ngx_http_redis_filter; u->input_filter_ctx = ctx; #if defined nginx_version && nginx_version >= 8011 r->main->count++; #endif ngx_http_upstream_init(r); return NGX_DONE; } static ngx_int_t ngx_http_redis_create_request(ngx_http_request_t *r) { size_t len; uintptr_t escape; ngx_buf_t *b; ngx_chain_t *cl; ngx_http_redis_ctx_t *ctx; ngx_http_variable_value_t *vv[2]; ngx_http_redis_loc_conf_t *rlcf; rlcf = ngx_http_get_module_loc_conf(r, ngx_http_redis_module); vv[0] = ngx_http_get_indexed_variable(r, ngx_http_redis_db_index); /* * If user do not select redis database in nginx.conf by redis_db * variable, just add size of "select 0" to request. This is add * some overhead in talk with redis, but this way simplify parsing * the redis answer in ngx_http_redis_process_header(). */ if (vv[0] == NULL || vv[0]->not_found || vv[0]->len == 0) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "select 0 redis database" ); len = sizeof("select 0") - 1; } else { len = sizeof("select ") - 1 + vv[0]->len; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "select %s redis database", vv[0]->data); } len += sizeof(CRLF) - 1; vv[1] = ngx_http_get_indexed_variable(r, rlcf->index); /* If nginx.conf have no redis_key return error. */ if (vv[1] == NULL || vv[1]->not_found || vv[1]->len == 0) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "the \"$redis_key\" variable is not set"); return NGX_ERROR; } /* Count have space required escape symbols. */ escape = 2 * ngx_escape_uri(NULL, vv[1]->data, vv[1]->len, NGX_ESCAPE_REDIS); len += sizeof("get ") - 1 + vv[1]->len + escape + sizeof(CRLF) - 1; /* Create temporary buffer for request with size len. */ b = ngx_create_temp_buf(r->pool, len); if (b == NULL) { return NGX_ERROR; } cl = ngx_alloc_chain_link(r->pool); if (cl == NULL) { return NGX_ERROR; } cl->buf = b; cl->next = NULL; r->upstream->request_bufs = cl; /* Add "select " for request. */ *b->last++ = 's'; *b->last++ = 'e'; *b->last++ = 'l'; *b->last++ = 'e'; *b->last++ = 'c'; *b->last++ = 't'; *b->last++ = ' '; /* Get context redis_db from configuration file. */ ctx = ngx_http_get_module_ctx(r, ngx_http_redis_module); ctx->key.data = b->last; /* * Add "0" as redis number db to request if redis_db undefined, * othervise add real number from context. */ if (vv[0] == NULL || vv[0]->not_found || vv[0]->len == 0) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "select 0 redis database" ); *b->last++ = '0'; } else { b->last = ngx_copy(b->last, vv[0]->data, vv[0]->len); ctx->key.len = b->last - ctx->key.data; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "select %V redis database", &ctx->key); } /* Add "\r\n". */ *b->last++ = CR; *b->last++ = LF; /* Add "get" command with space. */ *b->last++ = 'g'; *b->last++ = 'e'; *b->last++ = 't'; *b->last++ = ' '; /* Get context redis_key from nginx.conf. */ ctx = ngx_http_get_module_ctx(r, ngx_http_redis_module); ctx->key.data = b->last; /* * If no escape symbols then copy data as is, othervise use * escape-copy function. */ if (escape == 0) { b->last = ngx_copy(b->last, vv[1]->data, vv[1]->len); } else { b->last = (u_char *) ngx_escape_uri(b->last, vv[1]->data, vv[1]->len, NGX_ESCAPE_REDIS); } ctx->key.len = b->last - ctx->key.data; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http redis request: \"%V\"", &ctx->key); /* Add one more "\r\n". */ *b->last++ = CR; *b->last++ = LF; /* * Summary, the request looks like this: * "select $redis_db\r\nget $redis_key\r\n", where * $redis_db and $redis_key are variable's values. */ return NGX_OK; }
static ngx_int_t ngx_http_redis_handler(ngx_http_request_t *r) { ngx_int_t rc; ngx_http_upstream_t *u; ngx_http_redis_ctx_t *ctx; ngx_http_redis_loc_conf_t *rlcf; if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) { return NGX_HTTP_NOT_ALLOWED; } rc = ngx_http_discard_request_body(r); if (rc != NGX_OK) { return rc; } if (ngx_http_set_content_type(r) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } #if defined nginx_version && nginx_version >= 8011 if (ngx_http_upstream_create(r) != NGX_OK) { #else rlcf = ngx_http_get_module_loc_conf(r, ngx_http_redis_module); u = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_t)); if (u == NULL) { #endif return NGX_HTTP_INTERNAL_SERVER_ERROR; } #if defined nginx_version && nginx_version >= 8011 u = r->upstream; #endif u->schema.len = sizeof("redis://") - 1; u->schema.data = (u_char *) "redis://"; #if defined nginx_version && nginx_version >= 8011 u->output.tag = (ngx_buf_tag_t) &ngx_http_redis_module; #else u->peer.log = r->connection->log; u->peer.log_error = NGX_ERROR_ERR; #endif #if defined nginx_version && nginx_version >= 8011 rlcf = ngx_http_get_module_loc_conf(r, ngx_http_redis_module); #else u->output.tag = (ngx_buf_tag_t) &ngx_http_redis_module; #endif u->conf = &rlcf->upstream; u->create_request = ngx_http_redis_create_request; u->reinit_request = ngx_http_redis_reinit_request; u->process_header = ngx_http_redis_process_header; u->abort_request = ngx_http_redis_abort_request; u->finalize_request = ngx_http_redis_finalize_request; #if defined nginx_version && nginx_version < 8011 r->upstream = u; #endif ctx = ngx_palloc(r->pool, sizeof(ngx_http_redis_ctx_t)); if (ctx == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } ctx->rest = NGX_HTTP_REDIS_END; ctx->request = r; ngx_http_set_ctx(r, ctx, ngx_http_redis_module); u->input_filter_init = ngx_http_redis_filter_init; u->input_filter = ngx_http_redis_filter; u->input_filter_ctx = ctx; #if defined nginx_version && nginx_version >= 8011 r->main->count++; #endif ngx_http_upstream_init(r); return NGX_DONE; } static ngx_int_t ngx_http_redis_create_request(ngx_http_request_t *r) { size_t len; uintptr_t escape; ngx_buf_t *b; ngx_chain_t *cl; ngx_http_redis_ctx_t *ctx; ngx_http_variable_value_t *vv[2]; ngx_http_redis_loc_conf_t *rlcf; rlcf = ngx_http_get_module_loc_conf(r, ngx_http_redis_module); vv[0] = ngx_http_get_indexed_variable(r, rlcf->db); if (vv[0] == NULL || vv[0]->not_found || vv[0]->len == 0) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "select 0 redis database" ); len = sizeof("select 0") - 1; } else { len = sizeof("select ") - 1 + vv[0]->len; } len += sizeof(CRLF) - 1; vv[1] = ngx_http_get_indexed_variable(r, rlcf->index); if (vv[1] == NULL || vv[1]->not_found || vv[1]->len == 0) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "the \"$redis_key\" variable is not set"); return NGX_ERROR; } escape = 2 * ngx_escape_uri(NULL, vv[1]->data, vv[1]->len, NGX_ESCAPE_REDIS); len += sizeof("get ") - 1 + vv[1]->len + escape + sizeof(CRLF) - 1; b = ngx_create_temp_buf(r->pool, len); if (b == NULL) { return NGX_ERROR; } cl = ngx_alloc_chain_link(r->pool); if (cl == NULL) { return NGX_ERROR; } cl->buf = b; cl->next = NULL; r->upstream->request_bufs = cl; *b->last++ = 's'; *b->last++ = 'e'; *b->last++ = 'l'; *b->last++ = 'e'; *b->last++ = 'c'; *b->last++ = 't'; *b->last++ = ' '; ctx = ngx_http_get_module_ctx(r, ngx_http_redis_module); ctx->key.data = b->last; if (vv[0] == NULL || vv[0]->not_found || vv[0]->len == 0) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "select 0 redis database" ); *b->last++ = '0'; } else { b->last = ngx_copy(b->last, vv[0]->data, vv[0]->len); ctx->key.len = b->last - ctx->key.data; } *b->last++ = CR; *b->last++ = LF; *b->last++ = 'g'; *b->last++ = 'e'; *b->last++ = 't'; *b->last++ = ' '; ctx = ngx_http_get_module_ctx(r, ngx_http_redis_module); ctx->key.data = b->last; if (escape == 0) { b->last = ngx_copy(b->last, vv[1]->data, vv[1]->len); } else { b->last = (u_char *) ngx_escape_uri(b->last, vv[1]->data, vv[1]->len, NGX_ESCAPE_REDIS); } ctx->key.len = b->last - ctx->key.data; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http redis request: \"%V\"", &ctx->key); *b->last++ = CR; *b->last++ = LF; return NGX_OK; }
static ngx_int_t ngx_http_memcached_handler(ngx_http_request_t *r) { ngx_int_t rc; ngx_http_upstream_t *u; ngx_http_memcached_ctx_t *ctx; ngx_http_memcached_loc_conf_t *mlcf; u_char *cmd; ngx_int_t type; /* GET for get/delete */ /* POST for set/add/replace */ if (r->method & (NGX_HTTP_GET | NGX_HTTP_HEAD)) { if (NGX_OK != (rc = ngx_http_discard_request_body(r))) return rc; } else if (!(r->method & NGX_HTTP_POST)) return NGX_HTTP_NOT_ALLOWED; /* last unit of uri is command of memcache */ for (cmd = r->uri.data + r->uri.len; r->uri.data < cmd;) if (*--cmd == '/') break; if (cmd == r->uri.data) return NGX_HTTP_BAD_REQUEST; ++cmd; if (!(ngx_memcmp(cmd, "get", sizeof("get") - 1) && ngx_memcmp(cmd, "gets", sizeof("gets") - 1))) type = NGX_HTTP_MEMCACHED_GET; else if (!(ngx_memcmp(cmd, "set", sizeof("set") - 1) && ngx_memcmp(cmd, "add", sizeof("add") - 1) && ngx_memcmp(cmd, "replace", sizeof("replace") - 1))) type = NGX_HTTP_MEMCACHED_SET; else if (!ngx_memcmp(cmd, "delete", sizeof("delete") - 1)) type = NGX_HTTP_MEMCACHED_DEL; else if (!ngx_memcmp(cmd, "cas", sizeof("cas") - 1)) type = NGX_HTTP_MEMCACHED_CAS; else return NGX_HTTP_BAD_REQUEST; if (NGX_OK != ngx_http_set_content_type(r)) return NGX_HTTP_INTERNAL_SERVER_ERROR; if (NGX_OK != ngx_http_upstream_create(r)) return NGX_HTTP_INTERNAL_SERVER_ERROR; u = r->upstream; ngx_str_set(&u->schema, "memcached://"); u->output.tag = (ngx_buf_tag_t)&ngx_http_memcached_module; mlcf = ngx_http_get_module_loc_conf(r, ngx_http_memcached_module); u->conf = &mlcf->upstream; u->create_request = ngx_http_memcached_create_request; u->reinit_request = ngx_http_memcached_reinit_request; u->process_header = ngx_http_memcached_process_header; u->abort_request = ngx_http_memcached_abort_request; u->finalize_request = ngx_http_memcached_finalize_request; /* context */ if (!(ctx = ngx_palloc(r->pool, sizeof(ngx_http_memcached_ctx_t)))) return NGX_HTTP_INTERNAL_SERVER_ERROR; ctx->request = r; ctx->cmd.data = cmd; ctx->cmd.len = r->uri.len - (ctx->cmd.data - r->uri.data); ctx->type = type; ngx_http_set_ctx(r, ctx, ngx_http_memcached_module); u->input_filter_init = ngx_http_memcached_filter_init; u->input_filter = ngx_http_memcached_filter; u->input_filter_ctx = ctx; if (r->method & NGX_HTTP_POST) { /* POST */ if (NGX_HTTP_SPECIAL_RESPONSE <= (rc = ngx_http_read_client_request_body(r, ngx_http_upstream_init))) return rc; } else { /* GET */ ++r->main->count; ngx_http_upstream_init(r); } return NGX_DONE; }
static ngx_int_t ngx_http_tcp_proxy_handler(ngx_http_request_t *r) { ngx_http_upstream_t *u = NULL; ngx_http_downstream_t *d = NULL; ngx_http_tcp_proxy_loc_conf_t *tlcf = NULL; if (!(r->method & (NGX_HTTP_CONNECT))) { return NGX_HTTP_NOT_ALLOWED; } tlcf = ngx_http_get_module_loc_conf(r, ngx_http_tcp_proxy_module); if (ngx_http_upstream_create(r) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } u = r->upstream; if (ngx_http_dyconfig_enabled(r)){ if(ngx_http_proxy_switch_set_upstream_srv_conf(r, u) != NGX_OK){ return NGX_HTTP_INTERNAL_SERVER_ERROR; } if (u->uscf->domain == 1){ if (ngx_http_proxy_switch_eval(r, tlcf->proxy_lengths, tlcf->proxy_values) != NGX_OK){ return NGX_HTTP_INTERNAL_SERVER_ERROR; } } }else{ if (ngx_http_proxy_switch_eval(r, tlcf->proxy_lengths, tlcf->proxy_values) != NGX_OK){ return NGX_HTTP_INTERNAL_SERVER_ERROR; } } u->output.tag = (ngx_buf_tag_t) &ngx_http_tcp_proxy_module; u->conf = &tlcf->upstream; u->create_established_response = ngx_http_tcp_proxy_create_established_response; u->create_request = ngx_http_tcp_proxy_create_request; u->reinit_request = ngx_http_tcp_proxy_reinit_request; u->process_header = ngx_http_tcp_proxy_process_header; u->abort_request = ngx_http_tcp_proxy_abort_request; u->finalize_request = ngx_http_tcp_proxy_finalize_request; r->state = 0; if( ngx_http_downstream_create(r,u) != NGX_OK){ return NGX_HTTP_INTERNAL_SERVER_ERROR; } d = u->downstream; d->output.tag = (ngx_buf_tag_t) &ngx_http_tcp_proxy_module; d->process_header = ngx_http_tcp_proxy_downstream_process_header; d->input_filter = NULL; return ngx_http_proxy_switch_start(r); }
ngx_int_t ngx_http_ajp_handler(ngx_http_request_t *r) { ngx_int_t rc; ngx_http_upstream_t *u; ngx_http_ajp_ctx_t *a; ngx_http_ajp_loc_conf_t *alcf; if (r->subrequest_in_memory) { ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, "ngx_ajp_module does not support " "subrequest in memory"); return NGX_HTTP_INTERNAL_SERVER_ERROR; } if (ngx_http_upstream_create(r) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } a = ngx_pcalloc(r->pool, sizeof(ngx_http_ajp_ctx_t)); if (a == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } a->state = ngx_http_ajp_st_init_state; a->pstate = ngx_http_ajp_pst_init_state; ngx_http_set_ctx(r, a, ngx_http_ajp_module); alcf = ngx_http_get_module_loc_conf(r, ngx_http_ajp_module); if (alcf->ajp_lengths) { if (ngx_http_ajp_eval(r, alcf) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } } u = r->upstream; u->schema.len = sizeof("ajp://") - 1; u->schema.data = (u_char *) "ajp://"; u->output.tag = (ngx_buf_tag_t) &ngx_http_ajp_module; u->conf = &alcf->upstream; #if (NGX_HTTP_CACHE) u->create_key = ngx_http_ajp_create_key; #endif u->create_request = ngx_http_ajp_create_request; u->reinit_request = ngx_http_ajp_reinit_request; u->process_header = ngx_http_ajp_process_header; u->abort_request = ngx_http_ajp_abort_request; u->finalize_request = ngx_http_ajp_finalize_request; u->buffering = 1; u->pipe = ngx_pcalloc(r->pool, sizeof(ngx_event_pipe_t)); if (u->pipe == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } u->pipe->input_filter = ngx_http_ajp_input_filter; u->pipe->input_ctx = r; u->input_filter_init = ngx_http_ajp_input_filter_init; rc = ngx_http_read_client_request_body(r, ngx_http_upstream_init); if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { return rc; } return NGX_DONE; }
static ngx_int_t ngx_http_redis_handler(ngx_http_request_t *r) { ngx_int_t rc; ngx_http_upstream_t *u; ngx_http_redis_ctx_t *ctx; ngx_http_redis_loc_conf_t *mlcf; if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD|NGX_HTTP_POST))) { return NGX_HTTP_NOT_ALLOWED; } if (ngx_http_set_content_type(r) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } if (ngx_http_upstream_create(r) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } u = r->upstream; ngx_str_set(&u->schema, "redis://"); u->output.tag = (ngx_buf_tag_t) &ngx_http_redis_module; mlcf = ngx_http_get_module_loc_conf(r, ngx_http_redis_module); u->conf = &mlcf->upstream; u->create_request = ngx_http_redis_create_request; u->reinit_request = ngx_http_redis_reinit_request; u->process_header = ngx_http_redis_process_header; u->abort_request = ngx_http_redis_abort_request; u->finalize_request = ngx_http_redis_finalize_request; ctx = ngx_palloc(r->pool, sizeof(ngx_http_redis_ctx_t)); if (ctx == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } ctx->rest = NGX_HTTP_REDIS_END; ctx->request = r; ctx->command_hash = mlcf->command_hash; ngx_http_set_ctx(r, ctx, ngx_http_redis_module); u->input_filter_init = ngx_http_redis_filter_init; u->input_filter = ngx_http_redis_filter; u->input_filter_ctx = ctx; r->main->count++; //ngx_http_upstream_init(r); rc = ngx_http_read_client_request_body(r, ngx_http_upstream_init); if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { return rc; } return NGX_DONE; }
static ngx_int_t ngx_http_cwinux_handler(ngx_http_request_t *r) { ngx_int_t rc; ngx_http_upstream_t *u; ngx_http_cwinux_ctx_t *ctx; ngx_http_cwinux_loc_conf_t *mlcf; if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_POST))){ ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, "ngx_cwinux: method %V doesn't support ", &r->method_name); return NGX_HTTP_BAD_REQUEST; } mlcf = ngx_http_get_module_loc_conf(r, ngx_http_cwinux_module); if (ngx_http_set_content_type(r) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } #if defined(nginx_version) && \ ((nginx_version >= 7063 && nginx_version < 8000) \ || nginx_version >= 8007) if (ngx_http_upstream_create(r) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } u = r->upstream; #else /* 0.7.x < 0.7.63, 0.8.x < 0.8.7 */ u = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_t)); if (u == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } u->peer.log = r->connection->log; u->peer.log_error = NGX_ERROR_ERR; # if (NGX_THREADS) u->peer.lock = &r->connection->lock; # endif r->upstream = u; #endif u->schema.len = sizeof("cwinux://") - 1; u->schema.data = (u_char *) "cwinux://"; u->output.tag = (ngx_buf_tag_t) &ngx_http_cwinux_module; u->conf = &mlcf->upstream; ctx = ngx_palloc(r->pool, sizeof(ngx_http_cwinux_ctx_t)); if (ctx == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } ngx_gettimeofday(&ctx->start_time); ctx->header = false; ctx->finish = false; ctx->request = r; ngx_http_set_ctx(r, ctx, ngx_http_cwinux_module); u->create_request = ngx_http_cwinux_create_request; u->process_header = ngx_http_cwinux_process_header; u->input_filter_init = ngx_http_cwinux_empty_filter_init; u->input_filter = ngx_http_cwinux_empty_filter; u->reinit_request = ngx_http_cwinux_reinit_request; u->abort_request = ngx_http_cwinux_abort_request; u->finalize_request = ngx_http_cwinux_finalize_request; u->input_filter_ctx = ctx; if (NGX_HTTP_POST == r->method){ rc = ngx_http_read_client_request_body(r, ngx_http_upstream_init); if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { return rc; } return NGX_DONE; } rc = ngx_http_discard_request_body(r); if (rc != NGX_OK) { return rc; } #if defined(nginx_version) && nginx_version >= 8011 r->main->count++; #endif ngx_http_upstream_init(r); return NGX_DONE; }
static ngx_http_request_t * ngx_http_poller_request(ngx_http_poller_t *poller) { ngx_connection_t *c; ngx_http_request_t *r; ngx_http_upstream_t *u; ngx_log_t *log; ngx_http_log_ctx_t *ctx; ngx_http_core_main_conf_t *cmcf; ngx_http_conf_ctx_t *cctx; ngx_pool_t *cpool = NULL; ngx_pool_t *rpool = NULL; ngx_time_t *tp; struct sockaddr_in *sin; log = &poller->log; log->log_level = NGX_LOG_DEBUG_CONNECTION | NGX_LOG_DEBUG_ALL; /* using connection_pool_size default */ cpool = ngx_create_pool(256, log); if (cpool == NULL) { return ngx_http_poller_destroy_pools(cpool, rpool); } c = ngx_pcalloc(poller->pool, sizeof(ngx_connection_t)); if (c == NULL) { return ngx_http_poller_destroy_pools(cpool, rpool); } c->read = ngx_pcalloc(cpool, sizeof(ngx_event_t)); if (c->read == NULL) { return ngx_http_poller_destroy_pools(cpool, rpool); } c->write = ngx_pcalloc(cpool, sizeof(ngx_event_t)); if (c->write == NULL) { return ngx_http_poller_destroy_pools(cpool, rpool); } c->local_sockaddr = ngx_pcalloc(cpool, sizeof(struct sockaddr_in)); if (c->local_sockaddr == NULL) { return ngx_http_poller_destroy_pools(cpool, rpool); } c->pool = cpool; c->log = log; c->local_sockaddr->sa_family = AF_INET; sin = (struct sockaddr_in *)c->local_sockaddr; sin->sin_addr.s_addr = 0x0100007f; c->read->log = log; c->write->log = log; c->log->log_level = NGX_LOG_DEBUG_CONNECTION | NGX_LOG_DEBUG_ALL; c->requests++; /* using request_pool_size default */ rpool = ngx_create_pool(4096, log); if (rpool == NULL) { return ngx_http_poller_destroy_pools(cpool, rpool); } r = ngx_pcalloc(rpool, sizeof(ngx_http_request_t)); if (r == NULL) { return ngx_http_poller_destroy_pools(cpool, rpool); } r->pool = rpool; r->connection = c; cctx = (ngx_http_conf_ctx_t *)ngx_cycle->conf_ctx[ngx_http_module.index]; r->main_conf = cctx->main_conf; r->srv_conf = cctx->srv_conf; r->loc_conf = cctx->loc_conf; if (ngx_list_init(&r->headers_out.headers, r->pool, 20, sizeof(ngx_table_elt_t)) != NGX_OK) { return ngx_http_poller_destroy_pools(cpool, rpool); } r->ctx = ngx_pcalloc(r->pool, sizeof(void *) * ngx_http_max_module); if (r->ctx == NULL) { return ngx_http_poller_destroy_pools(cpool, rpool); } cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); r->variables = ngx_pcalloc(r->pool, cmcf->variables.nelts * sizeof(ngx_http_variable_value_t)); if (r->variables == NULL) { return ngx_http_poller_destroy_pools(cpool, rpool); } r->main = r; r->count = 1; tp = ngx_timeofday(); r->start_sec = tp->sec; r->start_msec = tp->msec; ctx = ngx_palloc(c->pool, sizeof(ngx_http_log_ctx_t)); if (ctx == NULL) { return ngx_http_poller_destroy_pools(cpool, rpool); } ctx->connection = c; ctx->request = r; ctx->current_request = r; c->log->data = ctx; c->log->action = "polling"; c->log_error = NGX_ERROR_INFO; c->write->active = 1; c->fd = -1; c->data = r; if (ngx_http_upstream_create(r) != NGX_OK) { return ngx_http_poller_destroy_pools(cpool, rpool); } ngx_http_set_ctx(r, poller, ngx_http_poller_module); u = r->upstream; #if (NGX_HTTP_SSL) if (conf->upstream.ssl != NULL) { u->ssl = 1; } #endif u->output.tag = (ngx_buf_tag_t)&ngx_http_poller_module; u->headers_in.content_length_n = -1; u->conf = &poller->upstream; ngx_memzero(&poller->status, sizeof(ngx_http_status_t)); u->create_request = ngx_http_poller_create_request; u->reinit_request = ngx_http_poller_reinit_request; u->process_header = ngx_http_poller_process_status_line; u->abort_request = ngx_http_poller_abort_request; u->finalize_request = ngx_http_poller_finalize_request; u->buffering = 1; u->input_filter_init = ngx_http_poller_filter_init; u->input_filter = ngx_http_poller_filter; u->input_filter_ctx = r; return r; }
static ngx_int_t ngx_http_mytest_upstream_handler(ngx_http_request_t *r) { //首先建立http上下文结构体ngx_http_mytest_ctx_t ngx_http_mytest_upstream_ctx_t* myctx = ngx_http_get_module_ctx(r, ngx_http_mytest_upstream_module); if (myctx == NULL) { myctx = ngx_palloc(r->pool, sizeof(ngx_http_mytest_upstream_ctx_t)); if (myctx == NULL) { return NGX_ERROR; } //将新建的上下文与请求关联起来 ngx_http_set_ctx(r, myctx, ngx_http_mytest_upstream_module); } //对每1个要使用upstream的请求,必须调用且只能调用1次 //ngx_http_upstream_create方法,它会初始化r->upstream成员 if (ngx_http_upstream_create(r) != NGX_OK) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "ngx_http_upstream_create() failed"); return NGX_ERROR; } //得到配置结构体ngx_http_mytest_conf_t ngx_http_mytest_upstream_conf_t *mycf = (ngx_http_mytest_upstream_conf_t *) ngx_http_get_module_loc_conf(r, ngx_http_mytest_upstream_module); ngx_http_upstream_t *u = r->upstream; //这里用配置文件中的结构体来赋给r->upstream->conf成员 u->conf = &mycf->upstream;//把我们设置好的upstream配置信息赋值给ngx_http_request_t->upstream->conf //决定转发包体时使用的缓冲区 u->buffering = mycf->upstream.buffering; //以下代码开始初始化resolved结构体,用来保存上游服务器的地址 u->resolved = (ngx_http_upstream_resolved_t*) ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_resolved_t)); if (u->resolved == NULL) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "ngx_pcalloc resolved error. %s.", strerror(errno)); return NGX_ERROR; } //这里的上游服务器就是www.google.com static struct sockaddr_in backendSockAddr; struct hostent *pHost = gethostbyname((char*) "www.sina.com"); if (pHost == NULL) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "gethostbyname fail. %s", strerror(errno)); ngx_log_debugall(r->connection->log, 0, "yang test ############################MYTEST upstream gethostbyname error\n"); return NGX_ERROR; } //访问上游服务器的80端口 backendSockAddr.sin_family = AF_INET; backendSockAddr.sin_port = htons((in_port_t) 80); char* pDmsIP = inet_ntoa(*(struct in_addr*) (pHost->h_addr_list[0])); //char* pDmsIP = inet_ntoa(*(struct in_addr*) ("10.10.0.2")); backendSockAddr.sin_addr.s_addr = inet_addr(pDmsIP); myctx->backendServer.data = (u_char*)pDmsIP; myctx->backendServer.len = strlen(pDmsIP); ngx_log_debugall(r->connection->log, 0, "yang test ############################MYTEST upstream gethostbyname OK, addr:%s\n", pDmsIP); //将地址设置到resolved成员中 u->resolved->sockaddr = (struct sockaddr *)&backendSockAddr; u->resolved->socklen = sizeof(struct sockaddr_in); u->resolved->naddrs = 1; //设置三个必须实现的回调方法,也就是5.3.3节至5.3.5节中实现的3个方法 u->create_request = mytest_upstream_create_request; //构造http请求行和头部行 u->process_header = mytest_process_status_line; u->finalize_request = mytest_upstream_finalize_request; //这里必须将count成员加1,理由见5.1.5节 /* 这里还需要执行r->main->count++,这是在告诉HTTP框架将当前请求的引用计数加1,即告诉ngx_http_mytest_handler方法暂时不要销 毁请求,因为HTTP框架只有在引用计数为0时才能真正地销毁请求。这样的话,upstream机制接下来才能接管请求的处理工作。 */ r->main->count++; //启动upstream ngx_http_upstream_init(r); //必须返回NGX_DONE return NGX_DONE; //这时要通过返回NGX DONE告诉HTTP框架暂停执行请求的下一个阶段 }