Welcome! Log In Create A New Profile

Advanced

Re: Proxying request - HTTP/1.1 502 Bad Gateway

August 10, 2011 07:56AM
We have found out that the problem is caused by my frpc module. Everything is OK withnout the module. This frpc module reads POST request body and thed generates a response. In location /public/RPC2 the module is off but some initial function of the module are carried out. There is probably an incorrect construnction in module initialization that doesn't allow to run proxy module.

The major part of my module's source code (C++ used):

typedef struct {
ngx_str_t frpc_log;
ngx_str_t frpc_service;
} ngx_http_ap_frpc_ctx_t;

typedef struct {
ngx_flag_t enable;
ngx_int_t gsidindex;
ngx_str_t services;
ngx_str_t controlserver;
ngx_str_t servertype;
} ngx_http_ap_frpc_handler_loc_conf_t;

static ngx_command_t ngx_http_ap_frpc_handler_commands[] = {
{ ngx_string("ap_frpc"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1,
ngx_conf_set_flag_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_ap_frpc_handler_loc_conf_t, enable),
NULL },
// cookie vygenerovana ap_filter modulem
{ ngx_string("ap_frpc_gsid"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1,
ngx_http_ap_frpc_gsid,
NGX_HTTP_LOC_CONF_OFFSET,
0,
NULL },
// seznam rozrazovanych sluzeb z konfiguracniho souboru - ostatni se loguji do other
{ ngx_string("ap_frpc_services"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_ap_frpc_handler_loc_conf_t, services),
NULL },
// adresa controlserveru pro ohlasovani APcka
{ ngx_string("ap_frpc_controlserver"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_ap_frpc_handler_loc_conf_t, controlserver),
NULL },
// server_type pro ohlasovani na control server
{ ngx_string("ap_frpc_servertype"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_ap_frpc_handler_loc_conf_t, servertype),
NULL },
ngx_null_command
};
static ngx_http_module_t ngx_http_ap_frpc_handler_module_ctx = {
ngx_http_ap_frpc_add_variables, /* preconfiguration */
ngx_http_ap_frpc_init, /* postconfiguration */
NULL, /* create main configuration */
NULL, /* init main configuration */
NULL, /* create server configuration */
NULL, /* merge server configuration */
ngx_http_ap_frpc_handler_create_loc_conf, /* create location configuration */
ngx_http_ap_frpc_handler_merge_loc_conf /* merge location configuration */
};

ngx_module_t ngx_http_ap_frpc_handler_module = {
NGX_MODULE_V1,
&ngx_http_ap_frpc_handler_module_ctx, /* module context */
ngx_http_ap_frpc_handler_commands, /* module directives */
NGX_HTTP_MODULE, /* module type */
NULL, /* init master */
NULL, /* init module */
NULL, /* init process */
NULL, /* init thread */
NULL, /* exit thread */
NULL, /* exit process */
NULL, /* exit master */
NGX_MODULE_V1_PADDING
};

static ngx_http_variable_t ngx_http_ap_frpc_vars[] = {
// $ap_frc_log - informace k zalogovani
{ ngx_string("ap_frpc_log"), NULL, ngx_http_ap_frpc_log_variable, 0,
NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 },
{ ngx_string("ap_frpc_service"), NULL, ngx_http_ap_frpc_service_variable, 0,
NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 },

{ ngx_null_string, NULL, NULL, 0, 0, 0 }
};

static ngx_int_t ngx_http_ap_frpc_add_variables(ngx_conf_t *cf) {
ngx_http_variable_t *var, *v;

for (v = ngx_http_ap_frpc_vars; v->name.len; v++) {
var = ngx_http_add_variable(cf, &v->name, v->flags);
if (var == NULL) {
return NGX_ERROR;
}

var->get_handler = v->get_handler;
var->data = v->data;
}

return NGX_OK;
}

// inicializace promenne $ap_frpc_log
static ngx_int_t ngx_http_ap_frpc_log_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data) {
ngx_http_ap_frpc_ctx_t *ctx;

ctx = reinterpret_cast<ngx_http_ap_frpc_ctx_t*>
(ngx_http_get_module_ctx(r, ngx_http_ap_frpc_handler_module));

if (ctx == NULL) {
v->not_found = 1;
return NGX_OK;
}

v->len = ctx->frpc_log.len;
v->valid = 1;
v->no_cacheable = 0;
v->not_found = 0;
v->data = ctx->frpc_log.data;

return NGX_OK;
}

static ngx_int_t ngx_http_ap_frpc_service_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data) {
ngx_http_ap_frpc_ctx_t *ctx;

ctx = reinterpret_cast<ngx_http_ap_frpc_ctx_t*>(ngx_http_get_module_ctx(r, ngx_http_ap_frpc_handler_module));

if (ctx == NULL) {
v->not_found = 1;
return NGX_OK;
}

v->len = ctx->frpc_service.len;
v->valid = 1;
v->no_cacheable = 0;
v->not_found = 0;
v->data = ctx->frpc_service.data;

return NGX_OK;
}

static ngx_int_t ngx_http_ap_frpc_init(ngx_conf_t *cf){
ngx_http_handler_pt *h;
ngx_http_core_main_conf_t *cmcf;

cmcf = reinterpret_cast<ngx_http_core_main_conf_t*>(ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module));

h = reinterpret_cast<ngx_http_handler_pt*>(ngx_array_push(&cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers));

if (h == NULL) {
return NGX_ERROR;
}

*h = ngx_http_ap_frpc_access_handler;
return NGX_OK;
}

static ngx_int_t ngx_http_ap_frpc_access_handler(ngx_http_request_t *r) {
if (r->method != NGX_HTTP_POST) {
return NGX_DECLINED;
}
ngx_int_t rc = ngx_http_read_client_request_body(r, ngx_http_ap_frpc_request);
if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) {
return rc;
}
if (rc == NGX_AGAIN) {
return NGX_DONE;
}

return NGX_DECLINED;
}

static void ngx_http_ap_frpc_request(ngx_http_request_t *r) {
ngx_http_ap_frpc_ctx_t *ctx;
ctx = reinterpret_cast<ngx_http_ap_frpc_ctx_t*>(ngx_http_get_module_ctx(r, ngx_http_ap_frpc_handler_module));
if (ctx == NULL) {
ctx = reinterpret_cast<ngx_http_ap_frpc_ctx_t*>(ngx_pcalloc(r->pool, sizeof(ngx_http_ap_frpc_handler_module)));
ngx_http_set_ctx(r, ctx, ngx_http_ap_frpc_handler_module);
}
ngx_http_ap_frpc(r, ctx);
ngx_http_finalize_request(r, NGX_DONE);
}

static void *ngx_http_ap_frpc_handler_create_loc_conf(ngx_conf_t *cf)
{
ngx_http_ap_frpc_handler_loc_conf_t *conf;

conf = reinterpret_cast<ngx_http_ap_frpc_handler_loc_conf_t*>(ngx_pcalloc(cf->pool,
sizeof(ngx_http_ap_frpc_handler_loc_conf_t)));
if (conf == NULL) {
return NGX_CONF_ERROR;
}
conf->enable = NGX_CONF_UNSET_UINT;
conf->gsidindex = NGX_CONF_UNSET;

return conf;
}

static char *ngx_http_ap_frpc_handler_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
{
ngx_http_ap_frpc_handler_loc_conf_t *prev = reinterpret_cast<ngx_http_ap_frpc_handler_loc_conf_t*>(parent);
ngx_http_ap_frpc_handler_loc_conf_t *conf = reinterpret_cast<ngx_http_ap_frpc_handler_loc_conf_t*>(child);

ngx_conf_merge_value(conf->enable, prev->enable, 0);
ngx_conf_merge_str_value(conf->services, prev->services, "other");
ngx_conf_merge_str_value(conf->controlserver, prev->controlserver, "http://skcontrol:3337/RPC2");
ngx_conf_merge_str_value(conf->servertype, prev->servertype, "targeting-advertproxy");
if (conf->gsidindex == NGX_CONF_UNSET) {
conf->gsidindex = prev->gsidindex;
}
return NGX_CONF_OK;
}

static char *ngx_http_ap_frpc_gsid(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) {
ngx_str_t *value;

ngx_http_ap_frpc_handler_loc_conf_t *lcf = reinterpret_cast<ngx_http_ap_frpc_handler_loc_conf_t*>(conf);
value = reinterpret_cast<ngx_str_t*>(cf->args->elts);

if (value[1].data[0] == '$') {
value[1].len--;
value[1].data++;

lcf->gsidindex = ngx_http_get_variable_index(cf, &value[1]);
if (lcf->gsidindex == NGX_ERROR) {
return reinterpret_cast<char*>(NGX_CONF_ERROR);
}
}

return NGX_CONF_OK;
}

static ngx_int_t ngx_http_ap_frpc_parse_header(ngx_http_request_t *r) {
if (r->headers_in.content_type != NULL) {
if (ngx_strncmp(r->headers_in.content_type->value.data, "text/xml", 8) == 0) {
return 0;
} else if (ngx_strncmp(r->headers_in.content_type->value.data, "application/x-frpc", 18) == 0) {
return 1;
}
}
return -1;
}

static ngx_int_t ngx_http_ap_frpc_read_body(ngx_http_request_t *r, ngx_str_t *request_body) {
u_char *p;
size_t len;
ngx_buf_t *buf, *next;
ngx_chain_t *cl;

if (r->request_body == NULL
|| r->request_body->bufs == NULL
|| r->request_body->temp_file)
{
return 0;
}

cl = r->request_body->bufs;
buf = cl->buf;

if (cl->next == NULL) {
len = buf->last - buf->pos;
p = reinterpret_cast<u_char*>(ngx_pnalloc(r->pool, len));
if (p == NULL) {
return NGX_ERROR;
}
ngx_cpystrn(p, cl->buf->pos, len);

ngx_str_set(request_body, p);
request_body->len = len;
return len;
}

next = cl->next->buf;
len = (buf->last - buf->pos) + (next->last - next->pos);

p = reinterpret_cast<u_char*>(ngx_pnalloc(r->pool, len));
if (p == NULL) {
return NGX_ERROR;
}

request_body->data = p;

p = ngx_cpymem(p, buf->pos, buf->last - buf->pos);
ngx_memcpy(p, next->pos, next->last - next->pos);

request_body->len = len;
return len;
}

static ngx_int_t ngx_http_ap_frpc_response(ngx_http_request_t *r, std::string *response_body, bool binary) {
ngx_buf_t *b;
ngx_chain_t out;

b = reinterpret_cast<ngx_buf_t*>(ngx_pcalloc(r->pool, sizeof(ngx_buf_t)));
if (b == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
b->pos = reinterpret_cast<u_char*>(const_cast<char*>(response_body->c_str()));
b->last = reinterpret_cast<u_char*>(const_cast<char*>(response_body->c_str())) + response_body->size();

b->memory = 1;
b->last_buf = 1;
out.buf = b;
out.next = NULL;

ngx_str_t content_type;
if (!binary) {
ngx_str_set(&content_type, "text/xml");
} else {
ngx_str_set(&content_type, "application/x-frpc");
}
r->headers_out.status = NGX_HTTP_OK;
r->headers_out.content_length_n = response_body->size();
r->headers_out.content_type.len = content_type.len;
r->headers_out.content_type.data = content_type.data;
r->keepalive = 0; // Connection: close

ngx_int_t rc = ngx_http_send_header(r);

if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
return rc;
}

ngx_http_output_filter(r, &out);
ngx_pfree(r->pool, b);
return NGX_OK;
}

static ngx_int_t ngx_http_ap_frpc(ngx_http_request_t *r, ngx_http_ap_frpc_ctx_t *ctx)
{
ngx_http_ap_frpc_handler_loc_conf_t *cglcf;
cglcf = reinterpret_cast<ngx_http_ap_frpc_handler_loc_conf_t*>(ngx_http_get_module_loc_conf(r,
ngx_http_ap_frpc_handler_module));

if (cglcf->enable == 0) {
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "ap_frpc disable");
return NGX_OK;
} else {
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "ap_frpc enable");
}
// Priznak zda je spojeni xml-rpc (0) nebo fastrpc (1)
bool binary = false;
if (ngx_http_ap_frpc_parse_header(r) == -1) {
return NGX_ERROR;
}
else {
binary = (ngx_http_ap_frpc_parse_header(r) == 1);
}
// precteni tela pozadavku
ngx_str_t request_body;
ngx_int_t bodyLength = ngx_http_ap_frpc_read_body(r, &request_body);
if (bodyLength <= 0) {
return NGX_ERROR;
}

....... process the request and generate response
}

Body of my ngx_int_t ngx_http_ap_frpc function is not important because it is not carried out in /public/RPC2 location
Debug log:
2011/08/10 13:25:55 [debug] 22105#0: *39 http cl:1886 max:1048576
2011/08/10 13:25:55 [debug] 22105#0: *39 rewrite phase: 2
2011/08/10 13:25:55 [debug] 22105#0: *39 ap_filter enable
2011/08/10 13:25:55 [debug] 22105#0: *39 rewrite phase: 3
2011/08/10 13:25:55 [debug] 22105#0: *39 post rewrite phase: 4
2011/08/10 13:25:55 [debug] 22105#0: *39 access phase: 5
2011/08/10 13:25:55 [debug] 22105#0: *39 posix_memalign: 000000000E1143E0:4096 @16
2011/08/10 13:25:55 [debug] 22105#0: *39 http read client request body
2011/08/10 13:25:55 [debug] 22105#0: *39 recv: fd:43 1354 of 1886
2011/08/10 13:25:55 [debug] 22105#0: *39 http client request body recv 1354
2011/08/10 13:25:55 [debug] 22105#0: *39 http client request body rest 532
2011/08/10 13:25:55 [debug] 22105#0: *39 recv: fd:43 -1 of 532
2011/08/10 13:25:55 [debug] 22105#0: *39 recv() not ready (11: Resource temporarily unavailable)
2011/08/10 13:25:55 [debug] 22105#0: *39 http client request body recv -2
2011/08/10 13:25:55 [debug] 22105#0: *39 http client request body rest 532
2011/08/10 13:25:55 [debug] 22105#0: *39 event timer add: 43: 60000:1312975615320
2011/08/10 13:25:55 [debug] 22105#0: *39 post event 00002BA47A8CE148
2011/08/10 13:25:55 [debug] 22105#0: *39 delete posted event 00002BA47A8CE148
2011/08/10 13:25:55 [debug] 22105#0: *39 http run request: "/public/RPC2?"
2011/08/10 13:25:55 [debug] 22105#0: *39 http read client request body
2011/08/10 13:25:55 [debug] 22105#0: *39 recv: fd:43 532 of 532
2011/08/10 13:25:55 [debug] 22105#0: *39 http client request body recv 532
2011/08/10 13:25:55 [debug] 22105#0: *39 http client request body rest 0
2011/08/10 13:25:55 [debug] 22105#0: *39 event timer del: 43: 1312975615320
2011/08/10 13:25:55 [debug] 22105#0: *39 ap_frpc disable
2011/08/10 13:25:55 [debug] 22105#0: *39 http finalize request: -4, "/public/RPC2?" a:1, c:2
2011/08/10 13:25:55 [debug] 22105#0: *39 http request count:2 blk:0

and a part of configuration:

location /public/RPC2 {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://localhost:3352;
}

# RPC rozhrani AP pro hitovani
location /RPC2HIT {
ap_frpc on;
ap_frpc_gsid $ap_filter_cookie_sid;
ap_frpc_services "hp|email";
ap_frpc_controlserver http://skcontrol:3337/RPC2;
}
Subject Author Posted

Proxying request - HTTP/1.1 502 Bad Gateway

michalkraus August 09, 2011 02:12AM

Re: Proxying request - HTTP/1.1 502 Bad Gateway

Maxim Dounin August 09, 2011 05:02AM

Re: Proxying request - HTTP/1.1 502 Bad Gateway

michalkraus August 10, 2011 07:56AM



Sorry, only registered users may post in this forum.

Click here to login

Online Users

Guests: 285
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready