ngx_int_t ngx_http_lua_complex_value(ngx_http_request_t *r, ngx_str_t *subj, size_t offset, ngx_int_t count, int *cap, ngx_http_lua_complex_value_t *val, luaL_Buffer *luabuf) { size_t len; u_char *p; ngx_http_lua_script_code_pt code; ngx_http_lua_script_len_code_pt lcode; ngx_http_lua_script_engine_t e; if (val->lengths == NULL) { luaL_addlstring(luabuf, (char *) &subj->data[offset], cap[0] - offset); luaL_addlstring(luabuf, (char *) val->value.data, val->value.len); return NGX_OK; } ngx_memzero(&e, sizeof(ngx_http_lua_script_engine_t)); e.request = r; e.ncaptures = count * 2; e.captures = cap; e.captures_data = subj->data; e.ip = val->lengths; len = 0; while (*(uintptr_t *) e.ip) { lcode = *(ngx_http_lua_script_len_code_pt *) e.ip; len += lcode(&e); } p = ngx_pnalloc(r->pool, len); if (p == NULL) { return NGX_ERROR; } e.ip = val->values; e.pos = p; while (*(uintptr_t *) e.ip) { code = *(ngx_http_lua_script_code_pt *) e.ip; code((ngx_http_lua_script_engine_t *) &e); } luaL_addlstring(luabuf, (char *) &subj->data[offset], cap[0] - offset); luaL_addlstring(luabuf, (char *) p, len); ngx_pfree(r->pool, p); return NGX_OK; }
void Codes::MakeCode(const Node *root, uint32_t prefix, uint8_t len) { assert(len<=30); if(root!=NULL) { if(!root->getLabel().empty()) valToCode.insert(Map::value_type(trie.insert(root->getLabel()), prefix)); uint32_t lcode(prefix); uint32_t rcode(prefix|(1<<len)); MakeCode(root->getLeft(),lcode,len+1); MakeCode(root->getRight(),rcode,len+1); } }
ngx_int_t ngx_http_replace_complex_value(ngx_http_request_t *r, ngx_chain_t *captured, sre_uint_t ncaps, sre_int_t *cap, ngx_http_replace_complex_value_t *val, ngx_str_t *value) { size_t len; ngx_http_replace_script_code_pt code; ngx_http_replace_script_len_code_pt lcode; ngx_http_replace_script_engine_t e; if (val->lengths == NULL) { *value = val->value; return NGX_OK; } ngx_memzero(&e, sizeof(ngx_http_replace_script_engine_t)); e.request = r; e.ncaptures = (ncaps + 1) * 2; e.captures_data = captured; e.captures = cap; e.ip = val->lengths; len = 0; while (*(uintptr_t *) e.ip) { lcode = *(ngx_http_replace_script_len_code_pt *) e.ip; len += lcode(&e); } value->len = len; value->data = ngx_pnalloc(r->pool, len); if (value->data == NULL) { return NGX_ERROR; } e.ip = val->values; e.pos = value->data; while (*(uintptr_t *) e.ip) { code = *(ngx_http_replace_script_code_pt *) e.ip; code((ngx_http_replace_script_engine_t *) &e); } return NGX_OK; }
static ngx_uint_t construct_request_buffer(ngx_http_request_t *r, passenger_loc_conf_t *slcf, passenger_context_t *context, buffer_construction_state *state, ngx_buf_t *b) { #define PUSH_STATIC_STR(str) \ do { \ if (b != NULL) { \ b->last = ngx_copy(b->last, (const u_char *) str, \ sizeof(str) - 1); \ } \ total_size += sizeof(str) - 1; \ } while (0) ngx_uint_t total_size = 0; ngx_str_t *union_station_filters; ngx_uint_t i; ngx_list_part_t *part; ngx_table_elt_t *header; size_t len; ngx_http_script_len_code_pt lcode; ngx_http_script_code_pt code; ngx_http_script_engine_t e, le; if (b != NULL) { b->last = ngx_copy(b->last, state->method.data, state->method.len); } total_size += state->method.len; if (b != NULL) { b->last = ngx_copy(b->last, state->escaped_uri.data, state->escaped_uri.len); } total_size += state->escaped_uri.len; if (r->args.len > 0) { if (b != NULL) { b->last = ngx_copy(b->last, "?", 1); b->last = ngx_copy(b->last, r->args.data, r->args.len); } total_size += r->args.len + 1; } PUSH_STATIC_STR(" HTTP/1.1\r\nConnection: close\r\n"); part = &r->headers_in.headers.part; header = part->elts; for (i = 0; /* void */; i++) { if (i >= part->nelts) { if (part->next == NULL) { break; } part = part->next; header = part->elts; i = 0; } if (ngx_hash_find(&slcf->headers_set_hash, header[i].hash, header[i].lowcase_key, header[i].key.len) || header_is_transfer_encoding(&header[i].key)) { continue; } if (b != NULL) { b->last = ngx_copy(b->last, header[i].key.data, header[i].key.len); b->last = ngx_copy(b->last, ": ", 2); b->last = ngx_copy(b->last, header[i].value.data, header[i].value.len); b->last = ngx_copy(b->last, "\r\n", 2); } total_size += header[i].key.len + header[i].value.len + 4; } if (r->headers_in.chunked) { PUSH_STATIC_STR("Content-Length: "); if (b != NULL) { b->last = ngx_copy(b->last, state->content_length.data, state->content_length.len); } total_size += state->content_length.len; PUSH_STATIC_STR("\r\n"); } if (slcf->headers_set_len) { ngx_memzero(&le, sizeof(ngx_http_script_engine_t)); ngx_http_script_flush_no_cacheable_variables(r, slcf->flushes); le.ip = slcf->headers_set_len->elts; le.request = r; le.flushed = 1; while (*(uintptr_t *) le.ip) { while (*(uintptr_t *) le.ip) { lcode = *(ngx_http_script_len_code_pt *) le.ip; total_size += lcode(&le); } le.ip += sizeof(uintptr_t); } if (b != NULL) { ngx_memzero(&e, sizeof(ngx_http_script_engine_t)); e.ip = slcf->headers_set->elts; e.pos = b->last; e.request = r; e.flushed = 1; le.ip = slcf->headers_set_len->elts; while (*(uintptr_t *) le.ip) { lcode = *(ngx_http_script_len_code_pt *) le.ip; /* skip the header line name length */ (void) lcode(&le); if (*(ngx_http_script_len_code_pt *) le.ip) { for (len = 0; *(uintptr_t *) le.ip; len += lcode(&le)) { lcode = *(ngx_http_script_len_code_pt *) le.ip; } e.skip = (len == sizeof("\r\n") - 1) ? 1 : 0; } else { e.skip = 0; } le.ip += sizeof(uintptr_t); while (*(uintptr_t *) e.ip) { code = *(ngx_http_script_code_pt *) e.ip; code((ngx_http_script_engine_t *) &e); } e.ip += sizeof(uintptr_t); } b->last = e.pos; } } if (b != NULL) { b->last = ngx_copy(b->last, "!~: ", sizeof("!~: ") - 1); b->last = ngx_copy(b->last, state->core_password.data, state->core_password.len); b->last = ngx_copy(b->last, "\r\n", sizeof("\r\n") - 1); } total_size += (sizeof("!~: \r\n") - 1) + state->core_password.len; PUSH_STATIC_STR("!~DOCUMENT_ROOT: "); if (b != NULL) { b->last = ngx_copy(b->last, context->public_dir.data, context->public_dir.len); } total_size += context->public_dir.len; PUSH_STATIC_STR("\r\n"); if (context->base_uri.len > 0) { PUSH_STATIC_STR("!~SCRIPT_NAME: "); if (b != NULL) { b->last = ngx_copy(b->last, context->base_uri.data, context->base_uri.len); } total_size += context->base_uri.len; PUSH_STATIC_STR("\r\n"); } PUSH_STATIC_STR("!~REMOTE_ADDR: "); if (b != NULL) { b->last = ngx_copy(b->last, r->connection->addr_text.data, r->connection->addr_text.len); } total_size += r->connection->addr_text.len; PUSH_STATIC_STR("\r\n"); PUSH_STATIC_STR("!~REMOTE_PORT: "); if (b != NULL) { b->last = ngx_copy(b->last, state->remote_port.data, state->remote_port.len); } total_size += state->remote_port.len; PUSH_STATIC_STR("\r\n"); if (r->headers_in.user.len > 0) { PUSH_STATIC_STR("!~REMOTE_USER: "******"\r\n"); } if (slcf->app_group_name.data == NULL) { PUSH_STATIC_STR("!~PASSENGER_APP_GROUP_NAME: "); if (b != NULL) { b->last = ngx_copy(b->last, context->public_dir.data, context->public_dir.len); } total_size += context->public_dir.len; if (slcf->environment.data != NULL) { if (b != NULL) { b->last = ngx_copy(b->last, " (", 2); b->last = ngx_copy(b->last, slcf->environment.data, slcf->environment.len); b->last = ngx_copy(b->last, ")", 1); } total_size += (sizeof(" (") - 1) + slcf->environment.len + (sizeof(")") - 1); } PUSH_STATIC_STR("\r\n"); } PUSH_STATIC_STR("!~PASSENGER_APP_TYPE: "); if (b != NULL) { b->last = ngx_copy(b->last, state->app_type.data, state->app_type.len); } total_size += state->app_type.len; PUSH_STATIC_STR("\r\n"); if (slcf->union_station_filters != NGX_CONF_UNSET_PTR && slcf->union_station_filters->nelts > 0) { union_station_filters = (ngx_str_t *) slcf->union_station_filters->elts; for (i = 0; i < slcf->union_station_filters->nelts; i++) { PUSH_STATIC_STR("!~UNION_STATION_FILTERS: "); if (b != NULL) { b->last = ngx_copy(b->last, union_station_filters[i].data, union_station_filters[i].len); } total_size += union_station_filters[i].len; PUSH_STATIC_STR("\r\n"); } } if (b != NULL) { b->last = ngx_copy(b->last, slcf->options_cache.data, slcf->options_cache.len); } total_size += slcf->options_cache.len; if (slcf->env_vars_cache.data != NULL) { PUSH_STATIC_STR("!~PASSENGER_ENV_VARS: "); if (b != NULL) { b->last = ngx_copy(b->last, slcf->env_vars_cache.data, slcf->env_vars_cache.len); } total_size += slcf->env_vars_cache.len; PUSH_STATIC_STR("\r\n"); } /* D = Dechunk response * Prevent Nginx from rechunking the response. * C = Strip 100 Continue header * S = SSL */ PUSH_STATIC_STR("!~FLAGS: DC"); #if (NGX_HTTP_SSL) if (r->http_connection->ssl) { PUSH_STATIC_STR("S"); } #endif PUSH_STATIC_STR("\r\n\r\n"); return total_size; #undef PUSH_STATIC_STR }
/****************************************************************** index指令的理解,当访问某个目录时未指定文件,如果此location 设置了index指令,将返回index指令设置的页面 ******************************************************************/ static ngx_int_t ngx_http_index_handler(ngx_http_request_t *r) { u_char *p, *name; size_t len, root, reserve, allocated; ngx_int_t rc; ngx_str_t path, uri; ngx_uint_t i, dir_tested; ngx_http_index_t *index; ngx_open_file_info_t of; ngx_http_script_code_pt code; ngx_http_script_engine_t e; ngx_http_core_loc_conf_t *clcf; ngx_http_index_loc_conf_t *ilcf; ngx_http_script_len_code_pt lcode; if (r->uri.data[r->uri.len - 1] != '/') { // uri不是“/”结尾时,说明uri中最后指定了文件,index和autoindex模块将不处理,交由static模块处理 return NGX_DECLINED; } if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD|NGX_HTTP_POST))) { return NGX_DECLINED; } // 这里获取的r->loc_conf可能是server层的也有可能是location层的,需要检查是否有匹配到配置文件中的Location ilcf = ngx_http_get_module_loc_conf(r, ngx_http_index_module); clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); allocated = 0; root = 0; dir_tested = 0; name = NULL; /* suppress MSVC warning */ path.data = NULL; index = ilcf->indices->elts; for (i = 0; i < ilcf->indices->nelts; i++) { // 遍历index指令指定的每个参数 if (index[i].lengths == NULL) { // index指令参数中没有使用变量时 if (index[i].name.data[0] == '/') { // index指定的参数以"/"开始的, 将产生内部重定向。 return ngx_http_internal_redirect(r, &index[i].name, &r->args); } reserve = ilcf->max_index_len; len = index[i].name.len; } else { // index指令参数使用了变量 // 计算index指令参数指定的变量+常量字符串的长度 ngx_memzero(&e, sizeof(ngx_http_script_engine_t)); e.ip = index[i].lengths->elts; e.request = r; e.flushed = 1; /* 1 is for terminating '\0' as in static names */ len = 1; while (*(uintptr_t *) e.ip) { lcode = *(ngx_http_script_len_code_pt *) e.ip; len += lcode(&e); } /* 16 bytes are preallocation */ reserve = len + 16; } if (reserve > allocated) { name = ngx_http_map_uri_to_path(r, &path, &root, reserve); if (name == NULL) { return NGX_ERROR; } allocated = path.data + path.len - name; // ??? } if (index[i].values == NULL) { /* index[i].name.len includes the terminating '\0' */ ngx_memcpy(name, index[i].name.data, index[i].name.len); // 拷贝index指令指定的参数(e.g. "/usr/local/nginx/html/index1/index.html") path.len = (name + index[i].name.len - 1) - path.data; } else { e.ip = index[i].values->elts; e.pos = name; while (*(uintptr_t *) e.ip) { code = *(ngx_http_script_code_pt *) e.ip; code((ngx_http_script_engine_t *) &e); } if (*name == '/') { uri.len = len - 1; uri.data = name; return ngx_http_internal_redirect(r, &uri, &r->args); } path.len = e.pos - path.data; *e.pos = '\0'; } ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "open index \"%V\"", &path); ngx_memzero(&of, sizeof(ngx_open_file_info_t)); of.read_ahead = clcf->read_ahead; of.directio = clcf->directio; of.valid = clcf->open_file_cache_valid; of.min_uses = clcf->open_file_cache_min_uses; of.test_only = 1; of.errors = clcf->open_file_cache_errors; of.events = clcf->open_file_cache_events; if (ngx_http_set_disable_symlinks(r, clcf, &path, &of) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool) != NGX_OK) { ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, of.err, "%s \"%s\" failed", of.failed, path.data); if (of.err == 0) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } #if (NGX_HAVE_OPENAT) if (of.err == NGX_EMLINK || of.err == NGX_ELOOP) { return NGX_HTTP_FORBIDDEN; } #endif if (of.err == NGX_ENOTDIR || of.err == NGX_ENAMETOOLONG || of.err == NGX_EACCES) { return ngx_http_index_error(r, clcf, path.data, of.err); } if (!dir_tested) { rc = ngx_http_index_test_dir(r, clcf, path.data, name - 1); if (rc != NGX_OK) { return rc; } dir_tested = 1; } if (of.err == NGX_ENOENT) { continue; } ngx_log_error(NGX_LOG_CRIT, r->connection->log, of.err, "%s \"%s\" failed", of.failed, path.data); return NGX_HTTP_INTERNAL_SERVER_ERROR; } uri.len = r->uri.len + len - 1; if (!clcf->alias) { uri.data = path.data + root; } else { uri.data = ngx_pnalloc(r->pool, uri.len); if (uri.data == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } p = ngx_copy(uri.data, r->uri.data, r->uri.len); ngx_memcpy(p, name, len - 1); } return ngx_http_internal_redirect(r, &uri, &r->args); }// End for return NGX_DECLINED; }
/* 配置index index.html index_large.html gmime-gmime-cipher-context.html; 2025/02/14 08:24:04[ ngx_http_process_request_headers, 1412] [debug] 2955#2955: *2 http header done 2025/02/14 08:24:04[ ngx_event_del_timer, 39] [debug] 2955#2955: *2 < ngx_http_process_request, 2013> event timer del: 3: 30909486 2025/02/14 08:24:04[ ngx_http_core_rewrite_phase, 1810] [debug] 2955#2955: *2 rewrite phase: 0 (NGX_HTTP_SERVER_REWRITE_PHASE) 2025/02/14 08:24:04[ ngx_http_core_find_config_phase, 1868] [debug] 2955#2955: *2 find config phase: 1 (NGX_HTTP_FIND_CONFIG_PHASE), uri:/ 2025/02/14 08:24:04[ ngx_http_core_find_static_location, 2753] [debug] 2955#2955: *2 static_locations test location: "/", client uri:/ 2025/02/14 08:24:04[ ngx_http_core_find_location, 2693] [debug] 2955#2955: *2 ngx pcre test location: ~ "/1mytest" 2025/02/14 08:24:04[ ngx_http_core_find_config_phase, 1888] [debug] 2955#2955: *2 using configuration "/" 2025/02/14 08:24:04[ ngx_http_core_find_config_phase, 1895] [debug] 2955#2955: *2 http cl:-1 max:1048576 2025/02/14 08:24:04[ ngx_http_core_rewrite_phase, 1810] [debug] 2955#2955: *2 rewrite phase: 2 (NGX_HTTP_REWRITE_PHASE) 2025/02/14 08:24:04[ ngx_http_core_post_rewrite_phase, 1963] [debug] 2955#2955: *2 post rewrite phase: 3 (NGX_HTTP_POST_REWRITE_PHASE) 2025/02/14 08:24:04[ ngx_http_core_generic_phase, 1746] [debug] 2955#2955: *2 generic phase: 4 (NGX_HTTP_PREACCESS_PHASE) 2025/02/14 08:24:04[ ngx_http_core_generic_phase, 1746] [debug] 2955#2955: *2 generic phase: 5 (NGX_HTTP_PREACCESS_PHASE) 2025/02/14 08:24:04[ ngx_http_core_access_phase, 2061] [debug] 2955#2955: *2 access phase: 6 (NGX_HTTP_ACCESS_PHASE) 2025/02/14 08:24:04[ ngx_http_core_access_phase, 2061] [debug] 2955#2955: *2 access phase: 7 (NGX_HTTP_ACCESS_PHASE) 2025/02/14 08:24:04[ ngx_http_core_post_access_phase, 2163] [debug] 2955#2955: *2 post access phase: 8 (NGX_HTTP_POST_ACCESS_PHASE) 2025/02/14 08:24:04[ ngx_http_core_content_phase, 2491] [debug] 2955#2955: *2 content phase: 9 (NGX_HTTP_CONTENT_PHASE) 2025/02/14 08:24:04[ ngx_http_index_handler, 144] [debug] 2955#2955: *2 yang test ... index-count:3 2025/02/14 08:24:04[ ngx_http_index_handler, 216] [debug] 2955#2955: *2 open index "/usr/local/nginx/html/index.html" 2025/02/14 08:24:04[ ngx_http_internal_redirect, 3853] [debug] 2955#2955: *2 internal redirect: "/index.html?" 2025/02/14 08:24:04[ ngx_http_core_rewrite_phase, 1810] [debug] 2955#2955: *2 rewrite phase: 0 (NGX_HTTP_SERVER_REWRITE_PHASE) 2025/02/14 08:24:04[ ngx_http_core_find_config_phase, 1868] [debug] 2955#2955: *2 find config phase: 1 (NGX_HTTP_FIND_CONFIG_PHASE), uri:/index.html 2025/02/14 08:24:04[ ngx_http_core_find_static_location, 2753] [debug] 2955#2955: *2 static_locations test location: "/", client uri:/index.html 2025/02/14 08:24:04[ ngx_http_core_find_static_location, 2753] [debug] 2955#2955: *2 static_locations test location: "proxy1", client uri:/index.html 2025/02/14 08:24:04[ ngx_http_core_find_static_location, 2753] [debug] 2955#2955: *2 static_locations test location: "mytest", client uri:/index.html 2025/02/14 08:24:04[ ngx_http_core_find_location, 2693] [debug] 2955#2955: *2 ngx pcre test location: ~ "/1mytest" 2025/02/14 08:24:04[ ngx_http_core_find_config_phase, 1888] [debug] 2955#2955: *2 using configuration "/" 2025/02/14 08:24:04[ ngx_http_core_find_config_phase, 1895] [debug] 2955#2955: *2 http cl:-1 max:1048576 2025/02/14 08:24:04[ ngx_http_core_rewrite_phase, 1810] [debug] 2955#2955: *2 rewrite phase: 2 (NGX_HTTP_REWRITE_PHASE) 2025/02/14 08:24:04[ ngx_http_core_post_rewrite_phase, 1963] [debug] 2955#2955: *2 post rewrite phase: 3 (NGX_HTTP_POST_REWRITE_PHASE) 2025/02/14 08:24:04[ ngx_http_core_generic_phase, 1746] [debug] 2955#2955: *2 generic phase: 4 (NGX_HTTP_PREACCESS_PHASE) 2025/02/14 08:24:04[ ngx_http_core_generic_phase, 1746] [debug] 2955#2955: *2 generic phase: 5 (NGX_HTTP_PREACCESS_PHASE) 2025/02/14 08:24:04[ ngx_http_core_access_phase, 2061] [debug] 2955#2955: *2 access phase: 6 (NGX_HTTP_ACCESS_PHASE) 2025/02/14 08:24:04[ ngx_http_core_access_phase, 2061] [debug] 2955#2955: *2 access phase: 7 (NGX_HTTP_ACCESS_PHASE) 2025/02/14 08:24:04[ ngx_http_core_post_access_phase, 2163] [debug] 2955#2955: *2 post access phase: 8 (NGX_HTTP_POST_ACCESS_PHASE) 2025/02/14 08:24:04[ ngx_http_core_content_phase, 2491] [debug] 2955#2955: *2 content phase: 9 (NGX_HTTP_CONTENT_PHASE) 2025/02/14 08:24:04[ ngx_http_core_content_phase, 2491] [debug] 2955#2955: *2 content phase: 10 (NGX_HTTP_CONTENT_PHASE) 2025/02/14 08:24:04[ ngx_http_core_content_phase, 2491] [debug] 2955#2955: *2 content phase: 11 (NGX_HTTP_CONTENT_PHASE) 2025/02/14 08:24:04[ ngx_http_static_handler, 85] [debug] 2955#2955: *2 http filename: "/usr/local/nginx/html/index.html" 2025/02/14 08:24:04[ ngx_http_static_handler, 145] [debug] 2955#2955: *2 http static fd: 11 2025/02/14 08:24:04[ ngx_http_discard_request_body, 734] [debug] 2955#2955: *2 http set discard body */ static ngx_int_t //主要功能是检查uri中的文件是否存在,不存在直接关闭连接,存在则做内部重定向,重定向后由于是文件路径,因此末尾没有/,走到该函数直接退出,然后在static-module中获取文件内容 ngx_http_index_handler(ngx_http_request_t *r) {//注意:ngx_http_static_handler如果uri不是以/结尾返回,ngx_http_index_handler不以/结尾返回 //循环遍历index index.html index_large.html gmime-gmime-cipher-context.html;配置的文件,存在则返回,找到一个不在遍历后面的文件 //ngx_http_static_handler ngx_http_index_handler每次都要获取缓存信息stat信息,因此每次获取很可能是上一次stat执行的时候获取的信息,除非缓存过期 u_char *p, *name; size_t len, root, reserve, allocated; ngx_int_t rc; ngx_str_t path, uri; ngx_uint_t i, dir_tested; ngx_http_index_t *index; ngx_open_file_info_t of; ngx_http_script_code_pt code; ngx_http_script_engine_t e; ngx_http_core_loc_conf_t *clcf; ngx_http_index_loc_conf_t *ilcf; ngx_http_script_len_code_pt lcode; /* 一般匹配到location / { }的时候,才会执行下面的index,然后进行内部跳转 */ /* 如果浏览器输入:http://10.135.10.167/ABC/,则也会满足要求,uri会变为/ABC/index.html,打印如下 2015/10/16 12:08:03[ ngx_event_del_timer, 39] [debug] 12610#12610: *2 < ngx_http_process_request, 2013> event timer del: 3: 1859492499 2015/10/16 12:08:03[ ngx_http_core_rewrite_phase, 1810] [debug] 12610#12610: *2 rewrite phase: 0 (NGX_HTTP_SERVER_REWRITE_PHASE) 2015/10/16 12:08:03[ ngx_http_core_find_config_phase, 1868] [debug] 12610#12610: *2 find config phase: 1 (NGX_HTTP_FIND_CONFIG_PHASE), uri:/ABC/ 2015/10/16 12:08:03[ ngx_http_core_find_static_location, 2753] [debug] 12610#12610: *2 static_locations test location: "/", client uri:/ABC/ 2015/10/16 12:08:03[ ngx_http_core_find_static_location, 2753] [debug] 12610#12610: *2 static_locations test location: "proxy1", client uri:/ABC/ 2015/10/16 12:08:03[ ngx_http_core_find_static_location, 2753] [debug] 12610#12610: *2 static_locations test location: "mytest", client uri:/ABC/ 2015/10/16 12:08:03[ ngx_http_core_find_location, 2693] [debug] 12610#12610: *2 ngx pcre test location: ~ "\.php$" 2015/10/16 12:08:03[ ngx_http_core_find_location, 2693] [debug] 12610#12610: *2 ngx pcre test location: ~ "/1mytest" 2015/10/16 12:08:03[ ngx_http_core_find_config_phase, 1888] [debug] 12610#12610: *2 using configuration "/" 2015/10/16 12:08:03[ ngx_http_core_find_config_phase, 1895] [debug] 12610#12610: *2 http cl:-1 max:1048576 2015/10/16 12:08:03[ ngx_http_core_rewrite_phase, 1810] [debug] 12610#12610: *2 rewrite phase: 2 (NGX_HTTP_REWRITE_PHASE) 2015/10/16 12:08:03[ ngx_http_core_post_rewrite_phase, 1963] [debug] 12610#12610: *2 post rewrite phase: 3 (NGX_HTTP_POST_REWRITE_PHASE) 2015/10/16 12:08:03[ ngx_http_core_generic_phase, 1746] [debug] 12610#12610: *2 generic phase: 4 (NGX_HTTP_PREACCESS_PHASE) 2015/10/16 12:08:03[ ngx_http_core_generic_phase, 1746] [debug] 12610#12610: *2 generic phase: 5 (NGX_HTTP_PREACCESS_PHASE) 2015/10/16 12:08:03[ ngx_http_core_access_phase, 2061] [debug] 12610#12610: *2 access phase: 6 (NGX_HTTP_ACCESS_PHASE) 2015/10/16 12:08:03[ ngx_http_core_access_phase, 2061] [debug] 12610#12610: *2 access phase: 7 (NGX_HTTP_ACCESS_PHASE) 2015/10/16 12:08:03[ ngx_http_core_post_access_phase, 2163] [debug] 12610#12610: *2 post access phase: 8 (NGX_HTTP_POST_ACCESS_PHASE) 2015/10/16 12:08:03[ ngx_http_core_content_phase, 2491] [debug] 12610#12610: *2 content phase: 9 (NGX_HTTP_CONTENT_PHASE) 2015/10/16 12:08:03[ ngx_http_index_handler, 191] [debug] 12610#12610: *2 yang test ... index-count:3 2015/10/16 12:08:03[ ngx_http_index_handler, 263] [debug] 12610#12610: *2 open index "/var/yyz/www/ABC/index.html" 2015/10/16 12:08:03[ ngx_http_index_handler, 283] [debug] 12610#12610: *2 stat() "/var/yyz/www/ABC/index.html" failed (2: No such file or directory) 2015/10/16 12:08:03[ ngx_http_index_test_dir, 364] [debug] 12610#12610: *2 http index check dir: "/var/yyz/www/ABC" */ //默认http://10.2.13.167的时候,浏览器都会转换为http://10.2.13.167/发送到nginx服务器 if (r->uri.data[r->uri.len - 1] != '/') { //末尾不是/,直接跳转到下一阶段 return NGX_DECLINED; } if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD|NGX_HTTP_POST))) { return NGX_DECLINED; } ilcf = ngx_http_get_module_loc_conf(r, ngx_http_index_module); clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); allocated = 0; root = 0; dir_tested = 0; name = NULL; /* suppress MSVC warning */ path.data = NULL; index = ilcf->indices->elts; //indices上默认有一个NGX_HTTP_DEFAULT_INDEX for (i = 0; i < ilcf->indices->nelts; i++) {//循环遍历index配置的文件,如果有该文件,则进行内部重定向,从新走NGX_HTTP_SERVER_REWRITE_PHASE if (index[i].lengths == NULL) { if (index[i].name.data[0] == '/') { return ngx_http_internal_redirect(r, &index[i].name, &r->args); } reserve = ilcf->max_index_len; len = index[i].name.len; } else { ngx_memzero(&e, sizeof(ngx_http_script_engine_t)); e.ip = index[i].lengths->elts; e.request = r; e.flushed = 1; /* 1 is for terminating '\0' as in static names */ len = 1; while (*(uintptr_t *) e.ip) { lcode = *(ngx_http_script_len_code_pt *) e.ip; len += lcode(&e); } /* 16 bytes are preallocation */ reserve = len + 16; } if (reserve > allocated) { name = ngx_http_map_uri_to_path(r, &path, &root, reserve); if (name == NULL) { return NGX_ERROR; } allocated = path.data + path.len - name; } if (index[i].values == NULL) { /* index[i].name.len includes the terminating '\0' */ ngx_memcpy(name, index[i].name.data, index[i].name.len); path.len = (name + index[i].name.len - 1) - path.data; } else { e.ip = index[i].values->elts; e.pos = name; while (*(uintptr_t *) e.ip) { code = *(ngx_http_script_code_pt *) e.ip; code((ngx_http_script_engine_t *) &e); } if (*name == '/') { uri.len = len - 1; uri.data = name; return ngx_http_internal_redirect(r, &uri, &r->args); } path.len = e.pos - path.data; *e.pos = '\0'; } ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "open index \"%V\"", &path); ngx_memzero(&of, sizeof(ngx_open_file_info_t)); of.read_ahead = clcf->read_ahead; of.directio = clcf->directio; of.valid = clcf->open_file_cache_valid; of.min_uses = clcf->open_file_cache_min_uses; of.test_only = 1; of.errors = clcf->open_file_cache_errors; of.events = clcf->open_file_cache_events; if (ngx_http_set_disable_symlinks(r, clcf, &path, &of) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool) != NGX_OK) { ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, of.err, "%s \"%s\" failed", of.failed, path.data); if (of.err == 0) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } #if (NGX_HAVE_OPENAT) if (of.err == NGX_EMLINK || of.err == NGX_ELOOP) { return NGX_HTTP_FORBIDDEN; } #endif if (of.err == NGX_ENOTDIR || of.err == NGX_ENAMETOOLONG || of.err == NGX_EACCES) { return ngx_http_index_error(r, clcf, path.data, of.err); } if (!dir_tested) { rc = ngx_http_index_test_dir(r, clcf, path.data, name - 1); if (rc != NGX_OK) { return rc; } dir_tested = 1; } if (of.err == NGX_ENOENT) { continue; //stat获取的参数file_name指定的文件不存在 } ngx_log_error(NGX_LOG_CRIT, r->connection->log, of.err, "%s \"%s\" failed", of.failed, path.data); return NGX_HTTP_INTERNAL_SERVER_ERROR; } uri.len = r->uri.len + len - 1; if (!clcf->alias) { uri.data = path.data + root; } else { uri.data = ngx_pnalloc(r->pool, uri.len); if (uri.data == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } p = ngx_copy(uri.data, r->uri.data, r->uri.len); ngx_memcpy(p, name, len - 1); } return ngx_http_internal_redirect(r, &uri, &r->args); //内部重定向 } return NGX_DECLINED; }
static ngx_int_t create_request(ngx_http_request_t *r) { u_char ch; const char * helper_agent_request_socket_password_data; unsigned int helper_agent_request_socket_password_len; u_char buf[sizeof("4294967296") + 1]; size_t len, size, key_len, val_len; const u_char *app_type_string; size_t app_type_string_len; int server_name_len; ngx_str_t escaped_uri; ngx_str_t *union_station_filters = NULL; void *tmp; ngx_uint_t i, n; ngx_buf_t *b; ngx_chain_t *cl, *body; ngx_list_part_t *part; ngx_table_elt_t *header; ngx_http_script_code_pt code; ngx_http_script_engine_t e, le; ngx_http_core_srv_conf_t *cscf; passenger_loc_conf_t *slcf; passenger_context_t *context; ngx_http_script_len_code_pt lcode; cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); slcf = ngx_http_get_module_loc_conf(r, ngx_http_passenger_module); context = ngx_http_get_module_ctx(r, ngx_http_passenger_module); if (context == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } app_type_string = (const u_char *) pp_get_app_type_name(context->app_type); app_type_string_len = strlen((const char *) app_type_string) + 1; /* include null terminator */ /* * Nginx unescapes URI's before passing them to Phusion Passenger, * but backend processes expect the escaped version. * http://code.google.com/p/phusion-passenger/issues/detail?id=404 */ escaped_uri.len = 2 * ngx_escape_uri(NULL, r->uri.data, r->uri.len, NGX_ESCAPE_URI) + r->uri.len; escaped_uri.data = ngx_pnalloc(r->pool, escaped_uri.len + 1); escaped_uri.data[escaped_uri.len] = '\0'; ngx_escape_uri(escaped_uri.data, r->uri.data, r->uri.len, NGX_ESCAPE_URI); /************************************************** * Determine the request header length. **************************************************/ len = 0; /* Length of the Content-Length header. A value of -1 means that the content * length is unspecified, which is the case for e.g. WebSocket requests. */ if (r->headers_in.content_length_n >= 0) { len += sizeof("CONTENT_LENGTH") + uint_to_str(r->headers_in.content_length_n, buf, sizeof(buf)) + 1; /* +1 for trailing null */ } /* DOCUMENT_ROOT, SCRIPT_NAME, RAILS_RELATIVE_URL_ROOT, PATH_INFO and REQUEST_URI. */ len += sizeof("DOCUMENT_ROOT") + context->public_dir.len + 1; if (context->base_uri.len > 0) { len += sizeof("SCRIPT_NAME") + context->base_uri.len + 1; len += sizeof("RAILS_RELATIVE_URL_ROOT") + context->base_uri.len + 1; len += sizeof("PATH_INFO") + escaped_uri.len - context->base_uri.len + 1; } else { len += sizeof("SCRIPT_NAME") + sizeof(""); len += sizeof("PATH_INFO") + escaped_uri.len + 1; } len += sizeof("REQUEST_URI") + escaped_uri.len + 1; if (r->args.len > 0) { len += 1 + r->args.len; } /* SERVER_NAME; must be equal to HTTP_HOST without the port part */ if (r->headers_in.host != NULL) { tmp = memchr(r->headers_in.host->value.data, ':', r->headers_in.host->value.len); if (tmp == NULL) { server_name_len = r->headers_in.host->value.len; } else { server_name_len = (int) ((const u_char *) tmp - r->headers_in.host->value.data); } } else { server_name_len = cscf->server_name.len; } len += sizeof("SERVER_NAME") + server_name_len + 1; /* Various other HTTP headers. */ if (r->headers_in.content_type != NULL && r->headers_in.content_type->value.len > 0) { len += sizeof("CONTENT_TYPE") + r->headers_in.content_type->value.len + 1; } #if (NGX_HTTP_SSL) if (r->http_connection->ssl) { len += sizeof("HTTPS") + sizeof("on"); } #endif /* Lengths of Passenger application pool options. */ len += slcf->options_cache.len; len += sizeof("PASSENGER_APP_TYPE") + app_type_string_len; if (slcf->union_station_filters != NGX_CONF_UNSET_PTR && slcf->union_station_filters->nelts > 0) { len += sizeof("UNION_STATION_FILTERS"); union_station_filters = (ngx_str_t *) slcf->union_station_filters->elts; for (i = 0; i < slcf->union_station_filters->nelts; i++) { if (i != 0) { len++; } len += union_station_filters[i].len; } len++; } /***********************/ /***********************/ /* Lengths of various CGI variables. */ if (slcf->vars_len) { ngx_memzero(&le, sizeof(ngx_http_script_engine_t)); ngx_http_script_flush_no_cacheable_variables(r, slcf->flushes); le.flushed = 1; le.ip = slcf->vars_len->elts; le.request = r; while (*(uintptr_t *) le.ip) { lcode = *(ngx_http_script_len_code_pt *) le.ip; key_len = lcode(&le); for (val_len = 0; *(uintptr_t *) le.ip; val_len += lcode(&le)) { lcode = *(ngx_http_script_len_code_pt *) le.ip; } le.ip += sizeof(uintptr_t); len += key_len + val_len; } } /* Lengths of HTTP headers. */ if (slcf->upstream_config.pass_request_headers) { part = &r->headers_in.headers.part; header = part->elts; for (i = 0; /* void */; i++) { if (i >= part->nelts) { if (part->next == NULL) { break; } part = part->next; header = part->elts; i = 0; } if (!header_is_transfer_encoding(&header[i].key)) { len += sizeof("HTTP_") - 1 + header[i].key.len + 1 + header[i].value.len + 1; } } } /************************************************** * Build the request header data. **************************************************/ helper_agent_request_socket_password_data = pp_agents_starter_get_request_socket_password(pp_agents_starter, &helper_agent_request_socket_password_len); size = helper_agent_request_socket_password_len + /* netstring length + ":" + trailing "," */ /* note: 10 == sizeof("4294967296") - 1 */ len + 10 + 1 + 1; b = ngx_create_temp_buf(r->pool, size); if (b == NULL) { return NGX_ERROR; } cl = ngx_alloc_chain_link(r->pool); if (cl == NULL) { return NGX_ERROR; } cl->buf = b; /* Build SCGI header netstring length part. */ b->last = ngx_copy(b->last, helper_agent_request_socket_password_data, helper_agent_request_socket_password_len); b->last = ngx_snprintf(b->last, 10, "%ui", len); *b->last++ = (u_char) ':'; if (r->headers_in.content_length_n >= 0) { b->last = ngx_copy(b->last, "CONTENT_LENGTH", sizeof("CONTENT_LENGTH")); b->last = ngx_snprintf(b->last, 10, "%ui", r->headers_in.content_length_n); *b->last++ = (u_char) 0; } /* Build DOCUMENT_ROOT, SCRIPT_NAME, RAILS_RELATIVE_URL_ROOT, PATH_INFO and REQUEST_URI. */ b->last = ngx_copy(b->last, "DOCUMENT_ROOT", sizeof("DOCUMENT_ROOT")); b->last = ngx_copy(b->last, context->public_dir.data, context->public_dir.len + 1); if (context->base_uri.len > 0) { b->last = ngx_copy(b->last, "SCRIPT_NAME", sizeof("SCRIPT_NAME")); b->last = ngx_copy(b->last, context->base_uri.data, context->base_uri.len + 1); b->last = ngx_copy(b->last, "RAILS_RELATIVE_URL_ROOT", sizeof("RAILS_RELATIVE_URL_ROOT")); b->last = ngx_copy(b->last, context->base_uri.data, context->base_uri.len + 1); b->last = ngx_copy(b->last, "PATH_INFO", sizeof("PATH_INFO")); b->last = ngx_copy(b->last, escaped_uri.data + context->base_uri.len, escaped_uri.len - context->base_uri.len); b->last = ngx_copy(b->last, "", 1); } else { b->last = ngx_copy(b->last, "SCRIPT_NAME", sizeof("SCRIPT_NAME")); b->last = ngx_copy(b->last, "", sizeof("")); b->last = ngx_copy(b->last, "PATH_INFO", sizeof("PATH_INFO")); b->last = ngx_copy(b->last, escaped_uri.data, escaped_uri.len); b->last = ngx_copy(b->last, "", 1); } b->last = ngx_copy(b->last, "REQUEST_URI", sizeof("REQUEST_URI")); b->last = ngx_copy(b->last, escaped_uri.data, escaped_uri.len); if (r->args.len > 0) { b->last = ngx_copy(b->last, "?", 1); b->last = ngx_copy(b->last, r->args.data, r->args.len); } b->last = ngx_copy(b->last, "", 1); /* SERVER_NAME */ b->last = ngx_copy(b->last, "SERVER_NAME", sizeof("SERVER_NAME")); if (r->headers_in.host != NULL) { b->last = ngx_copy(b->last, r->headers_in.host->value.data, server_name_len); } else { b->last = ngx_copy(b->last, cscf->server_name.data, server_name_len); } b->last = ngx_copy(b->last, "", 1); /* Various other HTTP headers. */ if (r->headers_in.content_type != NULL && r->headers_in.content_type->value.len > 0) { b->last = ngx_copy(b->last, "CONTENT_TYPE", sizeof("CONTENT_TYPE")); b->last = ngx_copy(b->last, r->headers_in.content_type->value.data, r->headers_in.content_type->value.len); b->last = ngx_copy(b->last, "", 1); } #if (NGX_HTTP_SSL) if (r->http_connection->ssl) { b->last = ngx_copy(b->last, "HTTPS", sizeof("HTTPS")); b->last = ngx_copy(b->last, "on", sizeof("on")); } #endif /* Build Passenger application pool option headers. */ b->last = ngx_copy(b->last, slcf->options_cache.data, slcf->options_cache.len); b->last = ngx_copy(b->last, "PASSENGER_APP_TYPE", sizeof("PASSENGER_APP_TYPE")); b->last = ngx_copy(b->last, app_type_string, app_type_string_len); if (slcf->union_station_filters != NGX_CONF_UNSET_PTR && slcf->union_station_filters->nelts > 0) { b->last = ngx_copy(b->last, "UNION_STATION_FILTERS", sizeof("UNION_STATION_FILTERS")); for (i = 0; i < slcf->union_station_filters->nelts; i++) { if (i != 0) { b->last = ngx_copy(b->last, "\1", 1); } b->last = ngx_copy(b->last, union_station_filters[i].data, union_station_filters[i].len); } b->last = ngx_copy(b->last, "\0", 1); } /***********************/ /***********************/ if (slcf->vars_len) { ngx_memzero(&e, sizeof(ngx_http_script_engine_t)); e.ip = slcf->vars->elts; e.pos = b->last; e.request = r; e.flushed = 1; le.ip = slcf->vars_len->elts; while (*(uintptr_t *) le.ip) { lcode = *(ngx_http_script_len_code_pt *) le.ip; (void) lcode(&le); for (val_len = 0; *(uintptr_t *) le.ip; val_len += lcode(&le)) { lcode = *(ngx_http_script_len_code_pt *) le.ip; } le.ip += sizeof(uintptr_t); while (*(uintptr_t *) e.ip) { code = *(ngx_http_script_code_pt *) e.ip; code((ngx_http_script_engine_t *) &e); } e.ip += sizeof(uintptr_t); } b->last = e.pos; } if (slcf->upstream_config.pass_request_headers) { part = &r->headers_in.headers.part; header = part->elts; for (i = 0; /* void */; i++) { if (i >= part->nelts) { if (part->next == NULL) { break; } part = part->next; header = part->elts; i = 0; } if (header_is_transfer_encoding(&header[i].key)) { continue; } b->last = ngx_cpymem(b->last, "HTTP_", sizeof("HTTP_") - 1); for (n = 0; n < header[i].key.len; n++) { ch = header[i].key.data[n]; if (ch >= 'a' && ch <= 'z') { ch &= ~0x20; } else if (ch == '-') { ch = '_'; } *b->last++ = ch; } *b->last++ = (u_char) 0; b->last = ngx_copy(b->last, header[i].value.data, header[i].value.len); *b->last++ = (u_char) 0; } } *b->last++ = (u_char) ','; if (slcf->upstream_config.pass_request_body) { body = r->upstream->request_bufs; r->upstream->request_bufs = cl; while (body) { b = ngx_alloc_buf(r->pool); if (b == NULL) { return NGX_ERROR; } ngx_memcpy(b, body->buf, sizeof(ngx_buf_t)); cl->next = ngx_alloc_chain_link(r->pool); if (cl->next == NULL) { return NGX_ERROR; } cl = cl->next; cl->buf = b; body = body->next; } b->flush = 1; } else { r->upstream->request_bufs = cl; } cl->next = NULL; return NGX_OK; }
static ngx_int_t create_request(ngx_http_request_t *r) { u_char ch; u_char buf[sizeof("4294967296")]; size_t len, size, key_len, val_len, content_length; const u_char *app_type_string; size_t app_type_string_len; u_char framework_spawner_idle_time_string[12]; u_char app_spawner_idle_time_string[12]; u_char *end; ngx_uint_t i, n; ngx_buf_t *b; ngx_chain_t *cl, *body; ngx_list_part_t *part; ngx_table_elt_t *header; ngx_http_script_code_pt code; ngx_http_script_engine_t e, le; passenger_loc_conf_t *slcf; passenger_main_conf_t *main_conf; passenger_context_t *context; ngx_http_script_len_code_pt lcode; #if (NGX_HTTP_SSL) ngx_http_ssl_srv_conf_t *ssl_conf; #endif slcf = ngx_http_get_module_loc_conf(r, ngx_http_passenger_module); main_conf = &passenger_main_conf; context = ngx_http_get_module_ctx(r, ngx_http_passenger_module); if (context == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } switch (context->app_type) { case AP_RAILS: app_type_string = (const u_char *) "rails"; app_type_string_len = sizeof("rails"); break; case AP_RACK: app_type_string = (const u_char *) "rack"; app_type_string_len = sizeof("rack"); break; case AP_WSGI: app_type_string = (const u_char *) "wsgi"; app_type_string_len = sizeof("wsgi"); break; default: app_type_string = (const u_char *) "rails"; app_type_string_len = sizeof("rails"); break; } /************************************************** * Determine the request header length. **************************************************/ /* Length of the Content-Length header. */ if (r->headers_in.content_length_n < 0) { content_length = 0; } else { content_length = r->headers_in.content_length_n; } uint_to_str(content_length, buf, sizeof(buf)); /* +1 for trailing null */ len = sizeof("CONTENT_LENGTH") + ngx_strlen(buf) + 1; /* DOCUMENT_ROOT, SCRIPT_NAME and base URI */ len += sizeof("DOCUMENT_ROOT") + context->public_dir.len + 1; if (context->base_uri.len > 0) { len += sizeof("SCRIPT_NAME") + context->base_uri.len + 1; len += sizeof("RAILS_RELATIVE_URL_ROOT") + context->base_uri.len + 1; } else { len += sizeof("SCRIPT_NAME") + sizeof(""); } /* Various other HTTP headers. */ if (r->headers_in.content_type != NULL && r->headers_in.content_type->value.len > 0) { len += sizeof("CONTENT_TYPE") + r->headers_in.content_type->value.len + 1; } #if (NGX_HTTP_SSL) ssl_conf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module); if (ssl_conf->enable) { len += sizeof("HTTPS") + sizeof("on"); } #endif /* Lengths of Passenger application pool options. */ if (slcf->use_global_queue) { len += sizeof("PASSENGER_USE_GLOBAL_QUEUE") + sizeof("true"); } else { len += sizeof("PASSENGER_USE_GLOBAL_QUEUE") + sizeof("false"); } len += sizeof("PASSENGER_ENVIRONMENT") + slcf->environment.len + 1; len += sizeof("PASSENGER_SPAWN_METHOD") + slcf->spawn_method.len + 1; len += sizeof("PASSENGER_APP_TYPE") + app_type_string_len; end = ngx_snprintf(framework_spawner_idle_time_string, sizeof(framework_spawner_idle_time_string) - 1, "%d", slcf->framework_spawner_idle_time); *end = '\0'; len += sizeof("PASSENGER_FRAMEWORK_SPAWNER_IDLE_TIME") + ngx_strlen(framework_spawner_idle_time_string) + 1; end = ngx_snprintf(app_spawner_idle_time_string, sizeof(app_spawner_idle_time_string) - 1, "%d", slcf->app_spawner_idle_time); *end = '\0'; len += sizeof("PASSENGER_APP_SPAWNER_IDLE_TIME") + ngx_strlen(app_spawner_idle_time_string) + 1; /* Lengths of various CGI variables. */ if (slcf->vars_len) { ngx_memzero(&le, sizeof(ngx_http_script_engine_t)); ngx_http_script_flush_no_cacheable_variables(r, slcf->flushes); le.flushed = 1; le.ip = slcf->vars_len->elts; le.request = r; while (*(uintptr_t *) le.ip) { lcode = *(ngx_http_script_len_code_pt *) le.ip; key_len = lcode(&le); for (val_len = 0; *(uintptr_t *) le.ip; val_len += lcode(&le)) { lcode = *(ngx_http_script_len_code_pt *) le.ip; } le.ip += sizeof(uintptr_t); len += key_len + val_len; } } /* Lengths of HTTP headers. */ if (slcf->upstream.pass_request_headers) { part = &r->headers_in.headers.part; header = part->elts; for (i = 0; /* void */; i++) { if (i >= part->nelts) { if (part->next == NULL) { break; } part = part->next; header = part->elts; i = 0; } len += sizeof("HTTP_") - 1 + header[i].key.len + 1 + header[i].value.len + 1; } } /* Trailing dummy header. * * If the last header value is an empty string, then the buffer * will end with "\0\0". For example, if 'SSL_CLIENT_CERT' * is the last header and it has an empty value, then the SCGI header * will end with: * * "SSL_CLIENT_CERT\0\0" * * The data in the buffer will be processed by the AbstractRequestHandler class, * which is implemented in Ruby. But it uses Hash[*data.split("\0")] to * unserialize the data. Unfortunately String#split will not transform * the trailing "\0\0" into an empty string: * * "SSL_CLIENT_CERT\0\0".split("\0") * # => desired result: ["SSL_CLIENT_CERT", ""] * # => actual result: ["SSL_CLIENT_CERT"] * * When that happens, Hash[..] will raise an ArgumentError because * data.split("\0") does not return an array with a length that is a * multiple of 2. * * So here, we add a dummy header to prevent situations like that from * happening. */ len += sizeof("_") + sizeof("_"); /************************************************** * Build the request header data. **************************************************/ size = passenger_helper_server_password.len + /* netstring length + ":" + trailing "," */ /* note: 10 == sizeof("4294967296") - 1 */ len + 10 + 1 + 1; b = ngx_create_temp_buf(r->pool, size); if (b == NULL) { return NGX_ERROR; } cl = ngx_alloc_chain_link(r->pool); if (cl == NULL) { return NGX_ERROR; } cl->buf = b; /* Build SCGI header netstring length part. */ b->last = ngx_copy(b->last, passenger_helper_server_password.data, passenger_helper_server_password.len); b->last = ngx_snprintf(b->last, 10, "%ui", len); *b->last++ = (u_char) ':'; /* Build CONTENT_LENGTH header. This must always be sent, even if 0. */ b->last = ngx_copy(b->last, "CONTENT_LENGTH", sizeof("CONTENT_LENGTH")); b->last = ngx_snprintf(b->last, 10, "%ui", content_length); *b->last++ = (u_char) 0; /* Build DOCUMENT_ROOT, SCRIPT_NAME and base URI. */ b->last = ngx_copy(b->last, "DOCUMENT_ROOT", sizeof("DOCUMENT_ROOT")); b->last = ngx_copy(b->last, context->public_dir.data, context->public_dir.len + 1); if (context->base_uri.len > 0) { b->last = ngx_copy(b->last, "SCRIPT_NAME", sizeof("SCRIPT_NAME")); b->last = ngx_copy(b->last, context->base_uri.data, context->base_uri.len + 1); b->last = ngx_copy(b->last, "RAILS_RELATIVE_URL_ROOT", sizeof("RAILS_RELATIVE_URL_ROOT")); b->last = ngx_copy(b->last, context->base_uri.data, context->base_uri.len + 1); } else { b->last = ngx_copy(b->last, "SCRIPT_NAME", sizeof("SCRIPT_NAME")); b->last = ngx_copy(b->last, "", sizeof("")); } /* Various other HTTP headers. */ if (r->headers_in.content_type != NULL && r->headers_in.content_type->value.len > 0) { b->last = ngx_copy(b->last, "CONTENT_TYPE", sizeof("CONTENT_TYPE")); b->last = ngx_copy(b->last, r->headers_in.content_type->value.data, r->headers_in.content_type->value.len + 1); } #if (NGX_HTTP_SSL) ssl_conf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module); if (ssl_conf->enable) { b->last = ngx_copy(b->last, "HTTPS", sizeof("HTTPS")); b->last = ngx_copy(b->last, "on", sizeof("on")); } #endif /* Build Passenger application pool option headers. */ b->last = ngx_copy(b->last, "PASSENGER_USE_GLOBAL_QUEUE", sizeof("PASSENGER_USE_GLOBAL_QUEUE")); if (slcf->use_global_queue) { b->last = ngx_copy(b->last, "true", sizeof("true")); } else { b->last = ngx_copy(b->last, "false", sizeof("false")); } b->last = ngx_copy(b->last, "PASSENGER_ENVIRONMENT", sizeof("PASSENGER_ENVIRONMENT")); b->last = ngx_copy(b->last, slcf->environment.data, slcf->environment.len + 1); b->last = ngx_copy(b->last, "PASSENGER_SPAWN_METHOD", sizeof("PASSENGER_SPAWN_METHOD")); b->last = ngx_copy(b->last, slcf->spawn_method.data, slcf->spawn_method.len + 1); b->last = ngx_copy(b->last, "PASSENGER_APP_TYPE", sizeof("PASSENGER_APP_TYPE")); b->last = ngx_copy(b->last, app_type_string, app_type_string_len); b->last = ngx_copy(b->last, "PASSENGER_FRAMEWORK_SPAWNER_IDLE_TIME", sizeof("PASSENGER_FRAMEWORK_SPAWNER_IDLE_TIME")); b->last = ngx_copy(b->last, framework_spawner_idle_time_string, ngx_strlen(framework_spawner_idle_time_string) + 1); b->last = ngx_copy(b->last, "PASSENGER_APP_SPAWNER_IDLE_TIME", sizeof("PASSENGER_APP_SPAWNER_IDLE_TIME")); b->last = ngx_copy(b->last, app_spawner_idle_time_string, ngx_strlen(app_spawner_idle_time_string) + 1); if (slcf->vars_len) { ngx_memzero(&e, sizeof(ngx_http_script_engine_t)); e.ip = slcf->vars->elts; e.pos = b->last; e.request = r; e.flushed = 1; le.ip = slcf->vars_len->elts; while (*(uintptr_t *) le.ip) { lcode = *(ngx_http_script_len_code_pt *) le.ip; (void) lcode(&le); for (val_len = 0; *(uintptr_t *) le.ip; val_len += lcode(&le)) { lcode = *(ngx_http_script_len_code_pt *) le.ip; } le.ip += sizeof(uintptr_t); while (*(uintptr_t *) e.ip) { code = *(ngx_http_script_code_pt *) e.ip; code((ngx_http_script_engine_t *) &e); } e.ip += sizeof(uintptr_t); } b->last = e.pos; } if (slcf->upstream.pass_request_headers) { part = &r->headers_in.headers.part; header = part->elts; for (i = 0; /* void */; i++) { if (i >= part->nelts) { if (part->next == NULL) { break; } part = part->next; header = part->elts; i = 0; } b->last = ngx_cpymem(b->last, "HTTP_", sizeof("HTTP_") - 1); for (n = 0; n < header[i].key.len; n++) { ch = header[i].key.data[n]; if (ch >= 'a' && ch <= 'z') { ch &= ~0x20; } else if (ch == '-') { ch = '_'; } *b->last++ = ch; } *b->last++ = (u_char) 0; b->last = ngx_copy(b->last, header[i].value.data, header[i].value.len); *b->last++ = (u_char) 0; } } /* Trailing dummy header. See earlier comment for explanation. */ b->last = ngx_copy(b->last, "_\0_", sizeof("_\0_")); *b->last++ = (u_char) ','; if (slcf->upstream.pass_request_body) { body = r->upstream->request_bufs; r->upstream->request_bufs = cl; while (body) { b = ngx_alloc_buf(r->pool); if (b == NULL) { return NGX_ERROR; } ngx_memcpy(b, body->buf, sizeof(ngx_buf_t)); cl->next = ngx_alloc_chain_link(r->pool); if (cl->next == NULL) { return NGX_ERROR; } cl = cl->next; cl->buf = b; body = body->next; } b->flush = 1; } else { r->upstream->request_bufs = cl; } cl->next = NULL; return NGX_OK; }
static ngx_int_t ngx_http_scgi_create_request(ngx_http_request_t *r) { u_char ch, *key, *val, *lowcase_key; size_t len, allocated; ngx_buf_t *b; ngx_str_t *content_length; ngx_uint_t i, n, hash, header_params; ngx_chain_t *cl, *body; ngx_list_part_t *part; ngx_table_elt_t *header, **ignored; ngx_http_script_code_pt code; ngx_http_script_engine_t e, le; ngx_http_scgi_loc_conf_t *scf; ngx_http_script_len_code_pt lcode; static ngx_str_t zero = ngx_string("0"); content_length = r->headers_in.content_length ? &r->headers_in.content_length->value : &zero; len = sizeof("CONTENT_LENGTH") + content_length->len + 1; header_params = 0; ignored = NULL; scf = ngx_http_get_module_loc_conf(r, ngx_http_scgi_module); if (scf->params_len) { ngx_memzero(&le, sizeof(ngx_http_script_engine_t)); ngx_http_script_flush_no_cacheable_variables(r, scf->flushes); le.flushed = 1; le.ip = scf->params_len->elts; le.request = r; while (*(uintptr_t *) le.ip) { lcode = *(ngx_http_script_len_code_pt *) le.ip; len += lcode(&le); while (*(uintptr_t *) le.ip) { lcode = *(ngx_http_script_len_code_pt *) le.ip; len += lcode(&le) + 1; } le.ip += sizeof(uintptr_t); } } if (scf->upstream.pass_request_headers) { allocated = 0; lowcase_key = NULL; if (scf->header_params) { ignored = ngx_palloc(r->pool, scf->header_params * sizeof(void *)); if (ignored == NULL) { return NGX_ERROR; } } part = &r->headers_in.headers.part; header = part->elts; for (i = 0; /* void */; i++) { if (i >= part->nelts) { if (part->next == NULL) { break; } part = part->next; header = part->elts; i = 0; } if (scf->header_params) { if (allocated < header[i].key.len) { allocated = header[i].key.len + 16; lowcase_key = ngx_pnalloc(r->pool, allocated); if (lowcase_key == NULL) { return NGX_ERROR; } } hash = 0; for (n = 0; n < header[i].key.len; n++) { ch = header[i].key.data[n]; if (ch >= 'A' && ch <= 'Z') { ch |= 0x20; } else if (ch == '-') { ch = '_'; } hash = ngx_hash(hash, ch); lowcase_key[n] = ch; } if (ngx_hash_find(&scf->headers_hash, hash, lowcase_key, n)) { ignored[header_params++] = &header[i]; continue; } } len += sizeof("HTTP_") - 1 + header[i].key.len + 1 + header[i].value.len + 1; } } /* netstring: "length:" + packet + "," */ b = ngx_create_temp_buf(r->pool, NGX_SIZE_T_LEN + 1 + len + 1); if (b == NULL) { return NGX_ERROR; } cl = ngx_alloc_chain_link(r->pool); if (cl == NULL) { return NGX_ERROR; } cl->buf = b; b->last = ngx_snprintf(b->last, NGX_SIZE_T_LEN + 1 + sizeof("CONTENT_LENGTH") + NGX_OFF_T_LEN + 1, "%ui:CONTENT_LENGTH%Z%V%Z", len, content_length); if (scf->params_len) { ngx_memzero(&e, sizeof(ngx_http_script_engine_t)); e.ip = scf->params->elts; e.pos = b->last; e.request = r; e.flushed = 1; while (*(uintptr_t *) e.ip) { #if (NGX_DEBUG) key = e.pos; #endif code = *(ngx_http_script_code_pt *) e.ip; code((ngx_http_script_engine_t *) & e); #if (NGX_DEBUG) val = e.pos; #endif while (*(uintptr_t *) e.ip) { code = *(ngx_http_script_code_pt *) e.ip; code((ngx_http_script_engine_t *) &e); } *e.pos++ = '\0'; e.ip += sizeof(uintptr_t); ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "scgi param: \"%s: %s\"", key, val); } b->last = e.pos; } if (scf->upstream.pass_request_headers) { part = &r->headers_in.headers.part; header = part->elts; for (i = 0; /* void */; i++) { if (i >= part->nelts) { if (part->next == NULL) { break; } part = part->next; header = part->elts; i = 0; } for (n = 0; n < header_params; n++) { if (&header[i] == ignored[n]) { goto next; } } key = b->last; b->last = ngx_cpymem(key, "HTTP_", sizeof("HTTP_") - 1); for (n = 0; n < header[i].key.len; n++) { ch = header[i].key.data[n]; if (ch >= 'a' && ch <= 'z') { ch &= ~0x20; } else if (ch == '-') { ch = '_'; } *b->last++ = ch; } *b->last++ = (u_char) 0; val = b->last; b->last = ngx_copy(val, header[i].value.data, header[i].value.len); *b->last++ = (u_char) 0; ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "scgi param: \"%s: %s\"", key, val); next: continue; } } *b->last++ = (u_char) ','; if (scf->upstream.pass_request_body) { body = r->upstream->request_bufs; r->upstream->request_bufs = cl; while (body) { b = ngx_alloc_buf(r->pool); if (b == NULL) { return NGX_ERROR; } ngx_memcpy(b, body->buf, sizeof(ngx_buf_t)); cl->next = ngx_alloc_chain_link(r->pool); if (cl->next == NULL) { return NGX_ERROR; } cl = cl->next; cl->buf = b; body = body->next; } } else { r->upstream->request_bufs = cl; } cl->next = NULL; return NGX_OK; }
static ngx_int_t create_request(ngx_http_request_t *r) { u_char ch; const char * helper_agent_request_socket_password_data; unsigned int helper_agent_request_socket_password_len; u_char buf[sizeof("4294967296")]; size_t len, size, key_len, val_len, content_length; const u_char *app_type_string; size_t app_type_string_len; int server_name_len; ngx_str_t escaped_uri; ngx_str_t *union_station_filters = NULL; u_char min_instances_string[12]; u_char max_requests_string[12]; u_char max_preloader_idle_time_string[12]; u_char *end; void *tmp; ngx_uint_t i, n; ngx_buf_t *b; ngx_chain_t *cl, *body; ngx_list_part_t *part; ngx_table_elt_t *header; ngx_http_script_code_pt code; ngx_http_script_engine_t e, le; ngx_http_core_srv_conf_t *cscf; passenger_loc_conf_t *slcf; passenger_context_t *context; ngx_http_script_len_code_pt lcode; #if (NGX_HTTP_SSL) ngx_http_ssl_srv_conf_t *ssl_conf; #endif cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); slcf = ngx_http_get_module_loc_conf(r, ngx_http_passenger_module); context = ngx_http_get_module_ctx(r, ngx_http_passenger_module); if (context == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } switch (context->app_type) { case AP_CLASSIC_RAILS: app_type_string = (const u_char *) "classic-rails"; app_type_string_len = sizeof("classic-rails"); break; case AP_RACK: app_type_string = (const u_char *) "rack"; app_type_string_len = sizeof("rack"); break; case AP_WSGI: app_type_string = (const u_char *) "wsgi"; app_type_string_len = sizeof("wsgi"); break; default: app_type_string = (const u_char *) "rack"; app_type_string_len = sizeof("rack"); break; } /* * Nginx unescapes URI's before passing them to Phusion Passenger, * but backend processes expect the escaped version. * http://code.google.com/p/phusion-passenger/issues/detail?id=404 */ escaped_uri.len = 2 * ngx_escape_uri(NULL, r->uri.data, r->uri.len, NGX_ESCAPE_URI) + r->uri.len; escaped_uri.data = ngx_pnalloc(r->pool, escaped_uri.len + 1); escaped_uri.data[escaped_uri.len] = '\0'; ngx_escape_uri(escaped_uri.data, r->uri.data, r->uri.len, NGX_ESCAPE_URI); /************************************************** * Determine the request header length. **************************************************/ /* Length of the Content-Length header. */ if (r->headers_in.content_length_n < 0) { content_length = 0; } else { content_length = r->headers_in.content_length_n; } uint_to_str(content_length, buf, sizeof(buf)); /* +1 for trailing null */ len = sizeof("CONTENT_LENGTH") + ngx_strlen(buf) + 1; /* DOCUMENT_ROOT, SCRIPT_NAME, RAILS_RELATIVE_URL_ROOT, PATH_INFO and REQUEST_URI. */ len += sizeof("DOCUMENT_ROOT") + context->public_dir.len + 1; if (context->base_uri.len > 0) { len += sizeof("SCRIPT_NAME") + context->base_uri.len + 1; len += sizeof("RAILS_RELATIVE_URL_ROOT") + context->base_uri.len + 1; len += sizeof("PATH_INFO") + escaped_uri.len - context->base_uri.len + 1; } else { len += sizeof("SCRIPT_NAME") + sizeof(""); len += sizeof("PATH_INFO") + escaped_uri.len + 1; } len += sizeof("REQUEST_URI") + escaped_uri.len + 1; if (r->args.len > 0) { len += 1 + r->args.len; } /* SERVER_NAME; must be equal to HTTP_HOST without the port part */ if (r->headers_in.host != NULL) { tmp = memchr(r->headers_in.host->value.data, ':', r->headers_in.host->value.len); if (tmp == NULL) { server_name_len = r->headers_in.host->value.len; } else { server_name_len = (int) ((const u_char *) tmp - r->headers_in.host->value.data); } } else { server_name_len = cscf->server_name.len; } len += sizeof("SERVER_NAME") + server_name_len + 1; /* Various other HTTP headers. */ if (r->headers_in.content_type != NULL && r->headers_in.content_type->value.len > 0) { len += sizeof("CONTENT_TYPE") + r->headers_in.content_type->value.len + 1; } #if (NGX_HTTP_SSL) ssl_conf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module); if (ssl_conf->enable) { len += sizeof("HTTPS") + sizeof("on"); } #endif /* Lengths of Passenger application pool options. */ ANALYZE_BOOLEAN_CONFIG_LENGTH("PASSENGER_FRIENDLY_ERROR_PAGES", slcf, friendly_error_pages); ANALYZE_BOOLEAN_CONFIG_LENGTH("UNION_STATION_SUPPORT", slcf, union_station_support); ANALYZE_BOOLEAN_CONFIG_LENGTH("PASSENGER_DEBUGGER", slcf, debugger); ANALYZE_BOOLEAN_CONFIG_LENGTH("PASSENGER_SHOW_VERSION_IN_HEADER", slcf, show_version_in_header); ANALYZE_STR_CONFIG_LENGTH("PASSENGER_RUBY", slcf, ruby); len += sizeof("PASSENGER_ENV") + slcf->environment.len + 1; len += sizeof("PASSENGER_SPAWN_METHOD") + slcf->spawn_method.len + 1; len += sizeof("PASSENGER_APP_TYPE") + app_type_string_len; ANALYZE_STR_CONFIG_LENGTH("PASSENGER_APP_GROUP_NAME", slcf, app_group_name); ANALYZE_STR_CONFIG_LENGTH("PASSENGER_APP_RIGHTS", slcf, app_rights); ANALYZE_STR_CONFIG_LENGTH("PASSENGER_USER", slcf, user); ANALYZE_STR_CONFIG_LENGTH("PASSENGER_GROUP", slcf, group); ANALYZE_STR_CONFIG_LENGTH("UNION_STATION_KEY", slcf, union_station_key); end = ngx_snprintf(min_instances_string, sizeof(min_instances_string) - 1, "%d", (slcf->min_instances == (ngx_int_t) -1) ? 1 : slcf->min_instances); *end = '\0'; len += sizeof("PASSENGER_MIN_INSTANCES") + ngx_strlen(min_instances_string) + 1; end = ngx_snprintf(max_requests_string, sizeof(max_requests_string) - 1, "%d", (slcf->max_requests == (ngx_int_t) -1) ? 0 : slcf->max_requests); *end = '\0'; len += sizeof("PASSENGER_MAX_REQUESTS") + ngx_strlen(max_requests_string) + 1; end = ngx_snprintf(max_preloader_idle_time_string, sizeof(max_preloader_idle_time_string) - 1, "%d", (slcf->max_preloader_idle_time == (ngx_int_t) -1) ? -1 : slcf->max_preloader_idle_time); *end = '\0'; len += sizeof("PASSENGER_MAX_PRELOADER_IDLE_TIME") + ngx_strlen(max_preloader_idle_time_string) + 1; if (slcf->union_station_filters != NGX_CONF_UNSET_PTR && slcf->union_station_filters->nelts > 0) { len += sizeof("UNION_STATION_FILTERS"); union_station_filters = (ngx_str_t *) slcf->union_station_filters->elts; for (i = 0; i < slcf->union_station_filters->nelts; i++) { if (i != 0) { len++; } len += union_station_filters[i].len; } len++; } /***********************/ /***********************/ /* Lengths of various CGI variables. */ if (slcf->vars_len) { ngx_memzero(&le, sizeof(ngx_http_script_engine_t)); ngx_http_script_flush_no_cacheable_variables(r, slcf->flushes); le.flushed = 1; le.ip = slcf->vars_len->elts; le.request = r; while (*(uintptr_t *) le.ip) { lcode = *(ngx_http_script_len_code_pt *) le.ip; key_len = lcode(&le); for (val_len = 0; *(uintptr_t *) le.ip; val_len += lcode(&le)) { lcode = *(ngx_http_script_len_code_pt *) le.ip; } le.ip += sizeof(uintptr_t); len += key_len + val_len; } } /* Lengths of HTTP headers. */ if (slcf->upstream_config.pass_request_headers) { part = &r->headers_in.headers.part; header = part->elts; for (i = 0; /* void */; i++) { if (i >= part->nelts) { if (part->next == NULL) { break; } part = part->next; header = part->elts; i = 0; } len += sizeof("HTTP_") - 1 + header[i].key.len + 1 + header[i].value.len + 1; } } /************************************************** * Build the request header data. **************************************************/ helper_agent_request_socket_password_data = agents_starter_get_request_socket_password(passenger_agents_starter, &helper_agent_request_socket_password_len); size = helper_agent_request_socket_password_len + /* netstring length + ":" + trailing "," */ /* note: 10 == sizeof("4294967296") - 1 */ len + 10 + 1 + 1; b = ngx_create_temp_buf(r->pool, size); if (b == NULL) { return NGX_ERROR; } cl = ngx_alloc_chain_link(r->pool); if (cl == NULL) { return NGX_ERROR; } cl->buf = b; /* Build SCGI header netstring length part. */ b->last = ngx_copy(b->last, helper_agent_request_socket_password_data, helper_agent_request_socket_password_len); b->last = ngx_snprintf(b->last, 10, "%ui", len); *b->last++ = (u_char) ':'; /* Build CONTENT_LENGTH header. This must always be sent, even if 0. */ b->last = ngx_copy(b->last, "CONTENT_LENGTH", sizeof("CONTENT_LENGTH")); b->last = ngx_snprintf(b->last, 10, "%ui", content_length); *b->last++ = (u_char) 0; /* Build DOCUMENT_ROOT, SCRIPT_NAME, RAILS_RELATIVE_URL_ROOT, PATH_INFO and REQUEST_URI. */ b->last = ngx_copy(b->last, "DOCUMENT_ROOT", sizeof("DOCUMENT_ROOT")); b->last = ngx_copy(b->last, context->public_dir.data, context->public_dir.len + 1); if (context->base_uri.len > 0) { b->last = ngx_copy(b->last, "SCRIPT_NAME", sizeof("SCRIPT_NAME")); b->last = ngx_copy(b->last, context->base_uri.data, context->base_uri.len + 1); b->last = ngx_copy(b->last, "RAILS_RELATIVE_URL_ROOT", sizeof("RAILS_RELATIVE_URL_ROOT")); b->last = ngx_copy(b->last, context->base_uri.data, context->base_uri.len + 1); b->last = ngx_copy(b->last, "PATH_INFO", sizeof("PATH_INFO")); b->last = ngx_copy(b->last, escaped_uri.data + context->base_uri.len, escaped_uri.len - context->base_uri.len); b->last = ngx_copy(b->last, "", 1); } else { b->last = ngx_copy(b->last, "SCRIPT_NAME", sizeof("SCRIPT_NAME")); b->last = ngx_copy(b->last, "", sizeof("")); b->last = ngx_copy(b->last, "PATH_INFO", sizeof("PATH_INFO")); b->last = ngx_copy(b->last, escaped_uri.data, escaped_uri.len); b->last = ngx_copy(b->last, "", 1); } b->last = ngx_copy(b->last, "REQUEST_URI", sizeof("REQUEST_URI")); b->last = ngx_copy(b->last, escaped_uri.data, escaped_uri.len); if (r->args.len > 0) { b->last = ngx_copy(b->last, "?", 1); b->last = ngx_copy(b->last, r->args.data, r->args.len); } b->last = ngx_copy(b->last, "", 1); /* SERVER_NAME */ b->last = ngx_copy(b->last, "SERVER_NAME", sizeof("SERVER_NAME")); if (r->headers_in.host != NULL) { b->last = ngx_copy(b->last, r->headers_in.host->value.data, server_name_len); } else { b->last = ngx_copy(b->last, cscf->server_name.data, server_name_len); } b->last = ngx_copy(b->last, "", 1); /* Various other HTTP headers. */ if (r->headers_in.content_type != NULL && r->headers_in.content_type->value.len > 0) { b->last = ngx_copy(b->last, "CONTENT_TYPE", sizeof("CONTENT_TYPE")); b->last = ngx_copy(b->last, r->headers_in.content_type->value.data, r->headers_in.content_type->value.len); b->last = ngx_copy(b->last, "", 1); } #if (NGX_HTTP_SSL) ssl_conf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module); if (ssl_conf->enable) { b->last = ngx_copy(b->last, "HTTPS", sizeof("HTTPS")); b->last = ngx_copy(b->last, "on", sizeof("on")); } #endif /* Build Passenger application pool option headers. */ SERIALIZE_BOOLEAN_CONFIG_DATA("PASSENGER_FRIENDLY_ERROR_PAGES", slcf, friendly_error_pages); SERIALIZE_BOOLEAN_CONFIG_DATA("UNION_STATION_SUPPORT", slcf, union_station_support); SERIALIZE_BOOLEAN_CONFIG_DATA("PASSENGER_DEBUGGER", slcf, debugger); SERIALIZE_BOOLEAN_CONFIG_DATA("PASSENGER_SHOW_VERSION_IN_HEADER", slcf, show_version_in_header); SERIALIZE_STR_CONFIG_DATA("PASSENGER_RUBY", slcf, ruby); b->last = ngx_copy(b->last, "PASSENGER_ENV", sizeof("PASSENGER_ENV")); b->last = ngx_copy(b->last, slcf->environment.data, slcf->environment.len + 1); b->last = ngx_copy(b->last, "PASSENGER_SPAWN_METHOD", sizeof("PASSENGER_SPAWN_METHOD")); b->last = ngx_copy(b->last, slcf->spawn_method.data, slcf->spawn_method.len + 1); SERIALIZE_STR_CONFIG_DATA("PASSENGER_APP_GROUP_NAME", slcf, app_group_name); SERIALIZE_STR_CONFIG_DATA("PASSENGER_APP_RIGHTS", slcf, app_rights); SERIALIZE_STR_CONFIG_DATA("PASSENGER_USER", slcf, user); SERIALIZE_STR_CONFIG_DATA("PASSENGER_GROUP", slcf, group); SERIALIZE_STR_CONFIG_DATA("UNION_STATION_KEY", slcf, union_station_key); b->last = ngx_copy(b->last, "PASSENGER_APP_TYPE", sizeof("PASSENGER_APP_TYPE")); b->last = ngx_copy(b->last, app_type_string, app_type_string_len); b->last = ngx_copy(b->last, "PASSENGER_MIN_INSTANCES", sizeof("PASSENGER_MIN_INSTANCES")); b->last = ngx_copy(b->last, min_instances_string, ngx_strlen(min_instances_string) + 1); b->last = ngx_copy(b->last, "PASSENGER_MAX_REQUESTS", sizeof("PASSENGER_MAX_REQUESTS")); b->last = ngx_copy(b->last, max_requests_string, ngx_strlen(max_requests_string) + 1); b->last = ngx_copy(b->last, "PASSENGER_MAX_PRELOADER_IDLE_TIME", sizeof("PASSENGER_MAX_PRELOADER_IDLE_TIME")); b->last = ngx_copy(b->last, max_preloader_idle_time_string, ngx_strlen(max_preloader_idle_time_string) + 1); if (slcf->union_station_filters != NGX_CONF_UNSET_PTR && slcf->union_station_filters->nelts > 0) { b->last = ngx_copy(b->last, "UNION_STATION_FILTERS", sizeof("UNION_STATION_FILTERS")); for (i = 0; i < slcf->union_station_filters->nelts; i++) { if (i != 0) { b->last = ngx_copy(b->last, "\1", 1); } b->last = ngx_copy(b->last, union_station_filters[i].data, union_station_filters[i].len); } b->last = ngx_copy(b->last, "\0", 1); } /***********************/ /***********************/ if (slcf->vars_len) { ngx_memzero(&e, sizeof(ngx_http_script_engine_t)); e.ip = slcf->vars->elts; e.pos = b->last; e.request = r; e.flushed = 1; le.ip = slcf->vars_len->elts; while (*(uintptr_t *) le.ip) { lcode = *(ngx_http_script_len_code_pt *) le.ip; (void) lcode(&le); for (val_len = 0; *(uintptr_t *) le.ip; val_len += lcode(&le)) { lcode = *(ngx_http_script_len_code_pt *) le.ip; } le.ip += sizeof(uintptr_t); while (*(uintptr_t *) e.ip) { code = *(ngx_http_script_code_pt *) e.ip; code((ngx_http_script_engine_t *) &e); } e.ip += sizeof(uintptr_t); } b->last = e.pos; } if (slcf->upstream_config.pass_request_headers) { part = &r->headers_in.headers.part; header = part->elts; for (i = 0; /* void */; i++) { if (i >= part->nelts) { if (part->next == NULL) { break; } part = part->next; header = part->elts; i = 0; } b->last = ngx_cpymem(b->last, "HTTP_", sizeof("HTTP_") - 1); for (n = 0; n < header[i].key.len; n++) { ch = header[i].key.data[n]; if (ch >= 'a' && ch <= 'z') { ch &= ~0x20; } else if (ch == '-') { ch = '_'; } *b->last++ = ch; } *b->last++ = (u_char) 0; b->last = ngx_copy(b->last, header[i].value.data, header[i].value.len); *b->last++ = (u_char) 0; } } *b->last++ = (u_char) ','; if (slcf->upstream_config.pass_request_body) { body = r->upstream->request_bufs; r->upstream->request_bufs = cl; while (body) { b = ngx_alloc_buf(r->pool); if (b == NULL) { return NGX_ERROR; } ngx_memcpy(b, body->buf, sizeof(ngx_buf_t)); cl->next = ngx_alloc_chain_link(r->pool); if (cl->next == NULL) { return NGX_ERROR; } cl = cl->next; cl->buf = b; body = body->next; } b->flush = 1; } else { r->upstream->request_bufs = cl; } cl->next = NULL; return NGX_OK; }
static ngx_int_t ngx_http_index_handler(ngx_http_request_t *r) { u_char *p, *name; size_t len, root, reserve, allocated; ngx_int_t rc; ngx_str_t path, uri; ngx_uint_t i, dir_tested; ngx_http_index_t *index; ngx_open_file_info_t of; ngx_http_script_code_pt code; ngx_http_script_engine_t e; ngx_http_core_loc_conf_t *clcf; ngx_http_index_loc_conf_t *ilcf; ngx_http_script_len_code_pt lcode; if (r->uri.data[r->uri.len - 1] != '/') { return NGX_DECLINED; } if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD|NGX_HTTP_POST))) { return NGX_DECLINED; } ilcf = ngx_http_get_module_loc_conf(r, ngx_http_index_module); clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); allocated = 0; root = 0; dir_tested = 0; name = NULL; /* suppress MSVC warning */ path.data = NULL; index = ilcf->indices->elts; for (i = 0; i < ilcf->indices->nelts; i++) { if (index[i].lengths == NULL) { if (index[i].name.data[0] == '/') { return ngx_http_internal_redirect(r, &index[i].name, &r->args); } reserve = ilcf->max_index_len; len = index[i].name.len; } else { ngx_memzero(&e, sizeof(ngx_http_script_engine_t)); e.ip = index[i].lengths->elts; e.request = r; e.flushed = 1; /* 1 is for terminating '\0' as in static names */ len = 1; while (*(uintptr_t *) e.ip) { lcode = *(ngx_http_script_len_code_pt *) e.ip; len += lcode(&e); } /* 16 bytes are preallocation */ reserve = len + 16; } if (reserve > allocated) { name = ngx_http_map_uri_to_path(r, &path, &root, reserve); if (name == NULL) { return NGX_ERROR; } allocated = path.data + path.len - name; } if (index[i].values == NULL) { /* index[i].name.len includes the terminating '\0' */ ngx_memcpy(name, index[i].name.data, index[i].name.len); path.len = (name + index[i].name.len - 1) - path.data; } else { e.ip = index[i].values->elts; e.pos = name; while (*(uintptr_t *) e.ip) { code = *(ngx_http_script_code_pt *) e.ip; code((ngx_http_script_engine_t *) &e); } if (*name == '/') { uri.len = len - 1; uri.data = name; return ngx_http_internal_redirect(r, &uri, &r->args); } path.len = e.pos - path.data; *e.pos = '\0'; } ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "open index \"%V\"", &path); ngx_memzero(&of, sizeof(ngx_open_file_info_t)); of.read_ahead = clcf->read_ahead; of.directio = clcf->directio; of.valid = clcf->open_file_cache_valid; of.min_uses = clcf->open_file_cache_min_uses; of.test_only = 1; of.errors = clcf->open_file_cache_errors; of.events = clcf->open_file_cache_events; if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool) != NGX_OK) { ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, of.err, "%s \"%s\" failed", of.failed, path.data); if (of.err == 0) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } if (of.err == NGX_ENOTDIR || of.err == NGX_ENAMETOOLONG || of.err == NGX_EACCES) { return ngx_http_index_error(r, clcf, path.data, of.err); } if (!dir_tested) { rc = ngx_http_index_test_dir(r, clcf, path.data, name - 1); if (rc != NGX_OK) { return rc; } dir_tested = 1; } if (of.err == NGX_ENOENT) { continue; } ngx_log_error(NGX_LOG_CRIT, r->connection->log, of.err, "%s \"%s\" failed", of.failed, path.data); return NGX_HTTP_INTERNAL_SERVER_ERROR; } uri.len = r->uri.len + len - 1; if (!clcf->alias) { uri.data = path.data + root; } else { uri.data = ngx_pnalloc(r->pool, uri.len); if (uri.data == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } p = ngx_copy(uri.data, r->uri.data, r->uri.len); ngx_memcpy(p, name, len - 1); } return ngx_http_internal_redirect(r, &uri, &r->args); } return NGX_DECLINED; }
static ngx_int_t ngx_http_kafka_script_run(ngx_http_request_t *r, ngx_pool_t *pool, ngx_str_t *msg, void *code_lengths, size_t len, void *code_values) { ngx_http_kafka_main_conf_t *kmcf; ngx_http_script_code_pt code; ngx_http_script_len_code_pt lcode; ngx_http_script_engine_t e; ngx_http_core_main_conf_t *cmcf; ngx_uint_t i; u_char *p; int32_t *crc; cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); for (i = 0; i < cmcf->variables.nelts; i++) { if (r->variables[i].no_cacheable) { r->variables[i].valid = 0; r->variables[i].not_found = 0; } } ngx_memzero(&e, sizeof(ngx_http_script_engine_t)); e.ip = code_lengths; e.request = r; e.flushed = 1; while (*(uintptr_t *) e.ip) { lcode = *(ngx_http_script_len_code_pt *) e.ip; len += lcode(&e); } if (len == 0) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "[kafka] message is null, we ignore it"); return NGX_DECLINED; } kmcf = ngx_http_get_module_main_conf(r, ngx_http_kafka_module); if (len > kmcf->msg_max_size) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "[kafka] message is too large, we ignore it"); return NGX_DECLINED; } p = ngx_pnalloc(pool, NGX_KFK_MSG_HEADER_SIZE + len); if (p == NULL) { return NGX_BUSY; } msg->data = p; msg->len = NGX_KFK_MSG_HEADER_SIZE + len; /* offset */ *(int64_t *)p = 0; p += sizeof(int64_t); /* msg size */ *(int32_t *)p = (int32_t)htonl(14 + len); p += sizeof(int32_t); /* crc(later calculate) */ crc = (int32_t *)p; p += sizeof(int32_t); /* magic */ *(int8_t *)p = 0; p += sizeof(int8_t); /* attr */ *(int8_t *)p = 0; p += sizeof(int8_t); /* key len */ *(int32_t *)p = (int32_t)htonl(-1); p += sizeof(int32_t); /* value len */ *(int32_t *)p = (int32_t)htonl(len); p += sizeof(int32_t); e.ip = code_values; e.pos = p; while (*(uintptr_t *) e.ip) { code = *(ngx_http_script_code_pt *) e.ip; code((ngx_http_script_engine_t *) &e); } if (e.pos == NULL) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "[kafka] some unexpected things happened when get request body"); ngx_http_kafka_recycle_msg(pool, msg); return NGX_ERROR; } *crc = (int32_t)htonl(ngx_crc32_long((u_char*)(crc + 1), 10 + len)); return NGX_OK; }