mirror of
https://github.com/cesanta/mongoose.git
synced 2024-11-24 11:09:01 +08:00
Promote tun example to a unit test
PUBLISHED_FROM=0454cdeec5c7120eb4bf905fdd5b7abdcb4003c2
This commit is contained in:
parent
a0d98b7a39
commit
3c5d48ea13
@ -1,3 +0,0 @@
|
|||||||
PROG = tun
|
|
||||||
MODULE_CFLAGS =
|
|
||||||
include ../examples.mk
|
|
@ -1,72 +0,0 @@
|
|||||||
#include "mongoose.h"
|
|
||||||
|
|
||||||
static const char *s_local_port = ":8001";
|
|
||||||
static const char *s_dispatcher = "ws://foo:bar@localhost:8000";
|
|
||||||
|
|
||||||
void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
|
||||||
struct http_message *hm = (struct http_message *) ev_data;
|
|
||||||
int i;
|
|
||||||
switch (ev) {
|
|
||||||
case MG_EV_ACCEPT:
|
|
||||||
fprintf(stderr, "HTTP accept. nc=%p\n", nc);
|
|
||||||
break;
|
|
||||||
case MG_EV_RECV:
|
|
||||||
fprintf(stderr, "recvd: %d bytes\n", *(int *) ev_data);
|
|
||||||
break;
|
|
||||||
case MG_EV_HTTP_REQUEST:
|
|
||||||
fprintf(stderr, "HTTP got request. nc=%p path=%.*s\n", nc,
|
|
||||||
(int) hm->uri.len, hm->uri.p);
|
|
||||||
|
|
||||||
mg_printf(nc, "%s",
|
|
||||||
"HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n");
|
|
||||||
|
|
||||||
for (i = 0; i < 10; i++) {
|
|
||||||
mg_printf_http_chunk(nc, "OK %d\n", i);
|
|
||||||
}
|
|
||||||
mg_send_http_chunk(nc, "", 0); /* Send empty chunk, the end of response */
|
|
||||||
nc->flags |= MG_F_SEND_AND_CLOSE;
|
|
||||||
break;
|
|
||||||
case MG_EV_CLOSE:
|
|
||||||
fprintf(stderr, "HTTP close\n");
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
|
||||||
struct mg_mgr mgr;
|
|
||||||
struct mg_connection *nc;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
mg_mgr_init(&mgr, NULL);
|
|
||||||
|
|
||||||
/* Parse command line arguments */
|
|
||||||
for (i = 1; i < argc; i++) {
|
|
||||||
if (strcmp(argv[i], "-D") == 0) {
|
|
||||||
mgr.hexdump_file = argv[++i];
|
|
||||||
} else if (strcmp(argv[i], "-l") == 0) {
|
|
||||||
s_local_port = argv[++i];
|
|
||||||
} else if (strcmp(argv[i], "-d") == 0) {
|
|
||||||
s_dispatcher = argv[++i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((nc = mg_bind(&mgr, s_dispatcher, ev_handler)) == NULL) {
|
|
||||||
fprintf(stderr, "Cannot create tunneled listening socket on [%s]\n",
|
|
||||||
s_dispatcher);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
mg_set_protocol_http_websocket(nc);
|
|
||||||
fprintf(stderr, "Tun listener: %p\n", nc);
|
|
||||||
|
|
||||||
if ((nc = mg_bind(&mgr, s_local_port, ev_handler)) == NULL) {
|
|
||||||
fprintf(stderr, "Cannot bind to local port %s\n", s_local_port);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
mg_set_protocol_http_websocket(nc);
|
|
||||||
fprintf(stderr, "Local listening connection: %p\n", nc);
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
mg_mgr_poll(&mgr, 1000);
|
|
||||||
}
|
|
||||||
}
|
|
24
mongoose.c
24
mongoose.c
@ -1871,6 +1871,8 @@ int mg_tun_parse_frame(void *data, size_t len, struct mg_tun_frame *frame);
|
|||||||
void mg_tun_send_frame(struct mg_connection *ws, uint32_t stream_id,
|
void mg_tun_send_frame(struct mg_connection *ws, uint32_t stream_id,
|
||||||
uint8_t type, uint8_t flags, struct mg_str msg);
|
uint8_t type, uint8_t flags, struct mg_str msg);
|
||||||
|
|
||||||
|
void mg_tun_destroy_client(struct mg_tun_client *client);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
@ -3783,10 +3785,13 @@ int mg_tun_if_create_conn(struct mg_connection *nc) {
|
|||||||
|
|
||||||
void mg_tun_if_destroy_conn(struct mg_connection *nc) {
|
void mg_tun_if_destroy_conn(struct mg_connection *nc) {
|
||||||
struct mg_tun_client *client = (struct mg_tun_client *) nc->iface->data;
|
struct mg_tun_client *client = (struct mg_tun_client *) nc->iface->data;
|
||||||
|
|
||||||
|
if (nc->flags & MG_F_LISTENING) {
|
||||||
|
mg_tun_destroy_client(client);
|
||||||
|
} else if (client->disp) {
|
||||||
uint32_t stream_id = (uint32_t)(uintptr_t) nc->mgr_data;
|
uint32_t stream_id = (uint32_t)(uintptr_t) nc->mgr_data;
|
||||||
struct mg_str msg = {NULL, 0};
|
struct mg_str msg = {NULL, 0};
|
||||||
|
|
||||||
if (client->disp) {
|
|
||||||
LOG(LL_DEBUG, ("closing %zu:", stream_id));
|
LOG(LL_DEBUG, ("closing %zu:", stream_id));
|
||||||
mg_tun_send_frame(client->disp, stream_id, MG_TUN_DATA_FRAME,
|
mg_tun_send_frame(client->disp, stream_id, MG_TUN_DATA_FRAME,
|
||||||
MG_TUN_F_END_STREAM, msg);
|
MG_TUN_F_END_STREAM, msg);
|
||||||
@ -11191,7 +11196,8 @@ static void mg_tun_close_all(struct mg_tun_client *client) {
|
|||||||
for (nc = client->mgr->active_connections; nc != NULL; nc = nc->next) {
|
for (nc = client->mgr->active_connections; nc != NULL; nc = nc->next) {
|
||||||
if (nc->iface == client->iface && !(nc->flags & MG_F_LISTENING)) {
|
if (nc->iface == client->iface && !(nc->flags & MG_F_LISTENING)) {
|
||||||
LOG(LL_DEBUG, ("Closing tunneled connection %p", nc));
|
LOG(LL_DEBUG, ("Closing tunneled connection %p", nc));
|
||||||
mg_close_conn(nc);
|
nc->flags |= MG_F_CLOSE_IMMEDIATELY;
|
||||||
|
/* mg_close_conn(nc); */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -11257,10 +11263,16 @@ static void mg_tun_client_handler(struct mg_connection *nc, int ev,
|
|||||||
}
|
}
|
||||||
case MG_EV_CLOSE: {
|
case MG_EV_CLOSE: {
|
||||||
LOG(LL_DEBUG, ("Closing all tunneled connections"));
|
LOG(LL_DEBUG, ("Closing all tunneled connections"));
|
||||||
|
/*
|
||||||
|
* The client might have been already freed when the listening socket is
|
||||||
|
* closed.
|
||||||
|
*/
|
||||||
|
if (client != NULL) {
|
||||||
mg_tun_close_all(client);
|
mg_tun_close_all(client);
|
||||||
client->disp = NULL;
|
client->disp = NULL;
|
||||||
LOG(LL_INFO, ("Dispatcher connection is no more, reconnecting"));
|
LOG(LL_INFO, ("Dispatcher connection is no more, reconnecting"));
|
||||||
mg_tun_reconnect(client);
|
mg_tun_reconnect(client);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -11329,6 +11341,14 @@ static struct mg_tun_client *mg_tun_create_client(struct mg_mgr *mgr,
|
|||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mg_tun_destroy_client(struct mg_tun_client *client) {
|
||||||
|
/* the dispatcher connection handler will in turn close all tunnels */
|
||||||
|
client->disp->flags |= MG_F_CLOSE_IMMEDIATELY;
|
||||||
|
/* this is used as a signal to other tun handlers that the party is over */
|
||||||
|
client->disp->user_data = client->iface->data = NULL;
|
||||||
|
MG_FREE(client);
|
||||||
|
}
|
||||||
|
|
||||||
static struct mg_connection *mg_tun_do_bind(struct mg_tun_client *client,
|
static struct mg_connection *mg_tun_do_bind(struct mg_tun_client *client,
|
||||||
mg_event_handler_t handler,
|
mg_event_handler_t handler,
|
||||||
struct mg_bind_opts opts) {
|
struct mg_bind_opts opts) {
|
||||||
|
Loading…
Reference in New Issue
Block a user