mirror of
https://github.com/cesanta/mongoose.git
synced 2025-01-01 19:17:48 +08:00
Fix coredump in mg_reverse_proxy_handler
PUBLISHED_FROM=ca0ae588290f133ef7640ca538847a63c0cb544b
This commit is contained in:
parent
7267fc757d
commit
ea2069df51
43
mongoose.c
43
mongoose.c
@ -4992,6 +4992,10 @@ struct mg_http_multipart_stream {
|
|||||||
int processing_part;
|
int processing_part;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct mg_reverse_proxy_data {
|
||||||
|
struct mg_connection *linked_conn;
|
||||||
|
};
|
||||||
|
|
||||||
struct mg_http_proto_data {
|
struct mg_http_proto_data {
|
||||||
#if MG_ENABLE_FILESYSTEM
|
#if MG_ENABLE_FILESYSTEM
|
||||||
struct mg_http_proto_data_file file;
|
struct mg_http_proto_data_file file;
|
||||||
@ -5005,6 +5009,7 @@ struct mg_http_proto_data {
|
|||||||
struct mg_http_proto_data_chuncked chunk;
|
struct mg_http_proto_data_chuncked chunk;
|
||||||
struct mg_http_endpoint *endpoints;
|
struct mg_http_endpoint *endpoints;
|
||||||
mg_event_handler_t endpoint_handler;
|
mg_event_handler_t endpoint_handler;
|
||||||
|
struct mg_reverse_proxy_data reverse_proxy_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void mg_http_conn_destructor(void *proto_data);
|
static void mg_http_conn_destructor(void *proto_data);
|
||||||
@ -5057,6 +5062,22 @@ static void mg_http_free_proto_data_endpoints(struct mg_http_endpoint **ep) {
|
|||||||
ep = NULL;
|
ep = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void mg_http_free_reverse_proxy_data(struct mg_reverse_proxy_data *rpd) {
|
||||||
|
if (rpd->linked_conn != NULL) {
|
||||||
|
/*
|
||||||
|
* Connection has linked one, we have to unlink & close it
|
||||||
|
* since _this_ connection is going to die and
|
||||||
|
* it doesn't make sense to keep another one
|
||||||
|
*/
|
||||||
|
struct mg_http_proto_data *pd = mg_http_get_proto_data(rpd->linked_conn);
|
||||||
|
if (pd->reverse_proxy_data.linked_conn != NULL) {
|
||||||
|
pd->reverse_proxy_data.linked_conn->flags |= MG_F_SEND_AND_CLOSE;
|
||||||
|
pd->reverse_proxy_data.linked_conn = NULL;
|
||||||
|
}
|
||||||
|
rpd->linked_conn = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void mg_http_conn_destructor(void *proto_data) {
|
static void mg_http_conn_destructor(void *proto_data) {
|
||||||
struct mg_http_proto_data *pd = (struct mg_http_proto_data *) proto_data;
|
struct mg_http_proto_data *pd = (struct mg_http_proto_data *) proto_data;
|
||||||
#if MG_ENABLE_FILESYSTEM
|
#if MG_ENABLE_FILESYSTEM
|
||||||
@ -5069,6 +5090,7 @@ static void mg_http_conn_destructor(void *proto_data) {
|
|||||||
mg_http_free_proto_data_mp_stream(&pd->mp_stream);
|
mg_http_free_proto_data_mp_stream(&pd->mp_stream);
|
||||||
#endif
|
#endif
|
||||||
mg_http_free_proto_data_endpoints(&pd->endpoints);
|
mg_http_free_proto_data_endpoints(&pd->endpoints);
|
||||||
|
mg_http_free_reverse_proxy_data(&pd->reverse_proxy_data);
|
||||||
free(proto_data);
|
free(proto_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7005,22 +7027,28 @@ static int mg_http_send_port_based_redirect(
|
|||||||
static void mg_reverse_proxy_handler(struct mg_connection *nc, int ev,
|
static void mg_reverse_proxy_handler(struct mg_connection *nc, int ev,
|
||||||
void *ev_data) {
|
void *ev_data) {
|
||||||
struct http_message *hm = (struct http_message *) ev_data;
|
struct http_message *hm = (struct http_message *) ev_data;
|
||||||
struct mg_connection *upstream = (struct mg_connection *) nc->user_data;
|
struct mg_http_proto_data *pd = mg_http_get_proto_data(nc);
|
||||||
|
|
||||||
|
if (pd == NULL || pd->reverse_proxy_data.linked_conn == NULL) {
|
||||||
|
DBG(("%p: upstream closed", nc));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (ev) {
|
switch (ev) {
|
||||||
case MG_EV_CONNECT:
|
case MG_EV_CONNECT:
|
||||||
if (*(int *) ev_data != 0) {
|
if (*(int *) ev_data != 0) {
|
||||||
mg_http_send_error(upstream, 502, NULL);
|
mg_http_send_error(pd->reverse_proxy_data.linked_conn, 502, NULL);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
/* TODO(mkm): handle streaming */
|
/* TODO(mkm): handle streaming */
|
||||||
case MG_EV_HTTP_REPLY:
|
case MG_EV_HTTP_REPLY:
|
||||||
mg_send(upstream, hm->message.p, hm->message.len);
|
mg_send(pd->reverse_proxy_data.linked_conn, hm->message.p,
|
||||||
upstream->flags |= MG_F_SEND_AND_CLOSE;
|
hm->message.len);
|
||||||
|
pd->reverse_proxy_data.linked_conn->flags |= MG_F_SEND_AND_CLOSE;
|
||||||
nc->flags |= MG_F_CLOSE_IMMEDIATELY;
|
nc->flags |= MG_F_CLOSE_IMMEDIATELY;
|
||||||
break;
|
break;
|
||||||
case MG_EV_CLOSE:
|
case MG_EV_CLOSE:
|
||||||
upstream->flags |= MG_F_SEND_AND_CLOSE;
|
pd->reverse_proxy_data.linked_conn->flags |= MG_F_SEND_AND_CLOSE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -7052,7 +7080,10 @@ void mg_http_reverse_proxy(struct mg_connection *nc,
|
|||||||
mg_http_send_error(nc, 502, NULL);
|
mg_http_send_error(nc, 502, NULL);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
be->user_data = nc;
|
|
||||||
|
/* link connections to each other, they must live and die together */
|
||||||
|
mg_http_get_proto_data(be)->reverse_proxy_data.linked_conn = nc;
|
||||||
|
mg_http_get_proto_data(nc)->reverse_proxy_data.linked_conn = be;
|
||||||
|
|
||||||
/* send request upstream */
|
/* send request upstream */
|
||||||
mg_printf(be, "%.*s %s HTTP/1.1\r\n", (int) hm->method.len, hm->method.p,
|
mg_printf(be, "%.*s %s HTTP/1.1\r\n", (int) hm->method.len, hm->method.p,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user