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;
}
Exemple #2
0
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;
}
Exemple #7
0
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;
}
Exemple #8
0
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;
}
Exemple #10
0
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;
}