mirror of
https://github.com/cesanta/mongoose.git
synced 2025-08-06 05:26:15 +08:00
Add extra headers param to mg_ws_upgrade()
This commit is contained in:
parent
72d3a49352
commit
ae6fd6aa35
@ -806,10 +806,13 @@ Create client Websocket connection.
|
|||||||
### mg\_ws\_upgrade()
|
### mg\_ws\_upgrade()
|
||||||
|
|
||||||
```c
|
```c
|
||||||
void mg_ws_upgrade(struct mg_connection *, struct mg_http_message *);
|
void mg_ws_upgrade(struct mg_connection *, struct mg_http_message *,
|
||||||
|
const char *fmt, ...);
|
||||||
```
|
```
|
||||||
|
|
||||||
Upgrade given HTTP connection to Websocket.
|
Upgrade given HTTP connection to Websocket. The `fmt` is a printf-like
|
||||||
|
format string for the extra HTTP headers returned to the client in a
|
||||||
|
Websocket handshake. Set `fmt` to `NULL` if no extra headers needs to be passed.
|
||||||
|
|
||||||
|
|
||||||
### mg\_ws\_send()
|
### mg\_ws\_send()
|
||||||
|
@ -18,7 +18,7 @@ static const char *s_listen_on = "http://localhost:8000";
|
|||||||
static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
||||||
if (ev == MG_EV_HTTP_MSG) {
|
if (ev == MG_EV_HTTP_MSG) {
|
||||||
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
|
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
|
||||||
mg_ws_upgrade(c, hm);
|
mg_ws_upgrade(c, hm, NULL);
|
||||||
} else if (ev == MG_EV_WS_MSG) {
|
} else if (ev == MG_EV_WS_MSG) {
|
||||||
// Got websocket frame. Received data is wm->data. Echo it back!
|
// Got websocket frame. Received data is wm->data. Echo it back!
|
||||||
struct mg_ws_message *wm = (struct mg_ws_message *) ev_data;
|
struct mg_ws_message *wm = (struct mg_ws_message *) ev_data;
|
||||||
@ -42,9 +42,9 @@ static void timer_fn(void *arg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
struct mg_mgr mgr; // Event manager
|
struct mg_mgr mgr; // Event manager
|
||||||
struct mg_timer t1; // Timer
|
struct mg_timer t1; // Timer
|
||||||
mg_mgr_init(&mgr); // Initialise event manager
|
mg_mgr_init(&mgr); // Initialise event manager
|
||||||
mg_timer_init(&t1, 300, MG_TIMER_REPEAT, timer_fn, &mgr); // Init timer
|
mg_timer_init(&t1, 300, MG_TIMER_REPEAT, timer_fn, &mgr); // Init timer
|
||||||
mg_http_listen(&mgr, s_listen_on, fn, NULL); // Create HTTP listener
|
mg_http_listen(&mgr, s_listen_on, fn, NULL); // Create HTTP listener
|
||||||
for (;;) mg_mgr_poll(&mgr, 1000); // Infinite event loop
|
for (;;) mg_mgr_poll(&mgr, 1000); // Infinite event loop
|
||||||
|
@ -21,7 +21,7 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
|||||||
if (mg_http_match_uri(hm, "/websocket")) {
|
if (mg_http_match_uri(hm, "/websocket")) {
|
||||||
// Upgrade to websocket. From now on, a connection is a full-duplex
|
// Upgrade to websocket. From now on, a connection is a full-duplex
|
||||||
// Websocket connection, which will receive MG_EV_WS_MSG events.
|
// Websocket connection, which will receive MG_EV_WS_MSG events.
|
||||||
mg_ws_upgrade(c, hm);
|
mg_ws_upgrade(c, hm, NULL);
|
||||||
} else if (mg_http_match_uri(hm, "/rest")) {
|
} else if (mg_http_match_uri(hm, "/rest")) {
|
||||||
// Serve REST response
|
// Serve REST response
|
||||||
mg_http_reply(c, 200, "", "{\"result\": %d}\n", 123);
|
mg_http_reply(c, 200, "", "{\"result\": %d}\n", 123);
|
||||||
|
26
mongoose.c
26
mongoose.c
@ -3967,25 +3967,27 @@ struct ws_msg {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void ws_handshake(struct mg_connection *c, const char *key,
|
static void ws_handshake(struct mg_connection *c, const char *key,
|
||||||
size_t key_len) {
|
size_t key_len, const char *fmt, va_list ap) {
|
||||||
const char *magic = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
|
const char *magic = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
|
||||||
unsigned char sha[20], b64_sha[30];
|
unsigned char sha[20], b64_sha[30];
|
||||||
// mem[256], *buf = mem;
|
char mem[128], *buf = mem;
|
||||||
// int len = 0;
|
|
||||||
mg_sha1_ctx sha_ctx;
|
mg_sha1_ctx sha_ctx;
|
||||||
mg_sha1_init(&sha_ctx);
|
mg_sha1_init(&sha_ctx);
|
||||||
mg_sha1_update(&sha_ctx, (unsigned char *) key, key_len);
|
mg_sha1_update(&sha_ctx, (unsigned char *) key, key_len);
|
||||||
mg_sha1_update(&sha_ctx, (unsigned char *) magic, 36);
|
mg_sha1_update(&sha_ctx, (unsigned char *) magic, 36);
|
||||||
mg_sha1_final(sha, &sha_ctx);
|
mg_sha1_final(sha, &sha_ctx);
|
||||||
mg_base64_encode(sha, sizeof(sha), (char *) b64_sha);
|
mg_base64_encode(sha, sizeof(sha), (char *) b64_sha);
|
||||||
|
buf[0] = '\0';
|
||||||
|
if (fmt != NULL) mg_vasprintf(&buf, sizeof(mem), fmt, ap);
|
||||||
mg_printf(c,
|
mg_printf(c,
|
||||||
"HTTP/1.1 101 Switching Protocols\r\n"
|
"HTTP/1.1 101 Switching Protocols\r\n"
|
||||||
"Upgrade: websocket\r\n"
|
"Upgrade: websocket\r\n"
|
||||||
"Connection: Upgrade\r\n"
|
"Connection: Upgrade\r\n"
|
||||||
"Sec-WebSocket-Accept: %s\r\n\r\n",
|
"Sec-WebSocket-Accept: %s\r\n"
|
||||||
b64_sha);
|
"%s\r\n",
|
||||||
// mg_send(c, buf, len);
|
b64_sha, buf);
|
||||||
// if (buf != mem) free(buf);
|
if (buf != mem) free(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t ws_process(uint8_t *buf, size_t len, struct ws_msg *msg) {
|
static size_t ws_process(uint8_t *buf, size_t len, struct ws_msg *msg) {
|
||||||
@ -4145,9 +4147,15 @@ struct mg_connection *mg_ws_connect(struct mg_mgr *mgr, const char *url,
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mg_ws_upgrade(struct mg_connection *c, struct mg_http_message *hm) {
|
void mg_ws_upgrade(struct mg_connection *c, struct mg_http_message *hm,
|
||||||
|
const char *fmt, ...) {
|
||||||
struct mg_str *wskey = mg_http_get_header(hm, "Sec-WebSocket-Key");
|
struct mg_str *wskey = mg_http_get_header(hm, "Sec-WebSocket-Key");
|
||||||
c->pfn = mg_ws_cb;
|
c->pfn = mg_ws_cb;
|
||||||
if (wskey != NULL) ws_handshake(c, wskey->ptr, wskey->len);
|
if (wskey != NULL) {
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
ws_handshake(c, wskey->ptr, wskey->len, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
c->is_websocket = 1;
|
c->is_websocket = 1;
|
||||||
}
|
}
|
||||||
|
@ -740,7 +740,8 @@ struct mg_ws_message {
|
|||||||
struct mg_connection *mg_ws_connect(struct mg_mgr *, const char *url,
|
struct mg_connection *mg_ws_connect(struct mg_mgr *, const char *url,
|
||||||
mg_event_handler_t fn, void *fn_data,
|
mg_event_handler_t fn, void *fn_data,
|
||||||
const char *fmt, ...);
|
const char *fmt, ...);
|
||||||
void mg_ws_upgrade(struct mg_connection *, struct mg_http_message *);
|
void mg_ws_upgrade(struct mg_connection *, struct mg_http_message *,
|
||||||
|
const char *fmt, ...);
|
||||||
size_t mg_ws_send(struct mg_connection *, const char *buf, size_t len, int op);
|
size_t mg_ws_send(struct mg_connection *, const char *buf, size_t len, int op);
|
||||||
|
|
||||||
|
|
||||||
|
26
src/ws.c
26
src/ws.c
@ -15,25 +15,27 @@ struct ws_msg {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void ws_handshake(struct mg_connection *c, const char *key,
|
static void ws_handshake(struct mg_connection *c, const char *key,
|
||||||
size_t key_len) {
|
size_t key_len, const char *fmt, va_list ap) {
|
||||||
const char *magic = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
|
const char *magic = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
|
||||||
unsigned char sha[20], b64_sha[30];
|
unsigned char sha[20], b64_sha[30];
|
||||||
// mem[256], *buf = mem;
|
char mem[128], *buf = mem;
|
||||||
// int len = 0;
|
|
||||||
mg_sha1_ctx sha_ctx;
|
mg_sha1_ctx sha_ctx;
|
||||||
mg_sha1_init(&sha_ctx);
|
mg_sha1_init(&sha_ctx);
|
||||||
mg_sha1_update(&sha_ctx, (unsigned char *) key, key_len);
|
mg_sha1_update(&sha_ctx, (unsigned char *) key, key_len);
|
||||||
mg_sha1_update(&sha_ctx, (unsigned char *) magic, 36);
|
mg_sha1_update(&sha_ctx, (unsigned char *) magic, 36);
|
||||||
mg_sha1_final(sha, &sha_ctx);
|
mg_sha1_final(sha, &sha_ctx);
|
||||||
mg_base64_encode(sha, sizeof(sha), (char *) b64_sha);
|
mg_base64_encode(sha, sizeof(sha), (char *) b64_sha);
|
||||||
|
buf[0] = '\0';
|
||||||
|
if (fmt != NULL) mg_vasprintf(&buf, sizeof(mem), fmt, ap);
|
||||||
mg_printf(c,
|
mg_printf(c,
|
||||||
"HTTP/1.1 101 Switching Protocols\r\n"
|
"HTTP/1.1 101 Switching Protocols\r\n"
|
||||||
"Upgrade: websocket\r\n"
|
"Upgrade: websocket\r\n"
|
||||||
"Connection: Upgrade\r\n"
|
"Connection: Upgrade\r\n"
|
||||||
"Sec-WebSocket-Accept: %s\r\n\r\n",
|
"Sec-WebSocket-Accept: %s\r\n"
|
||||||
b64_sha);
|
"%s\r\n",
|
||||||
// mg_send(c, buf, len);
|
b64_sha, buf);
|
||||||
// if (buf != mem) free(buf);
|
if (buf != mem) free(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t ws_process(uint8_t *buf, size_t len, struct ws_msg *msg) {
|
static size_t ws_process(uint8_t *buf, size_t len, struct ws_msg *msg) {
|
||||||
@ -193,9 +195,15 @@ struct mg_connection *mg_ws_connect(struct mg_mgr *mgr, const char *url,
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mg_ws_upgrade(struct mg_connection *c, struct mg_http_message *hm) {
|
void mg_ws_upgrade(struct mg_connection *c, struct mg_http_message *hm,
|
||||||
|
const char *fmt, ...) {
|
||||||
struct mg_str *wskey = mg_http_get_header(hm, "Sec-WebSocket-Key");
|
struct mg_str *wskey = mg_http_get_header(hm, "Sec-WebSocket-Key");
|
||||||
c->pfn = mg_ws_cb;
|
c->pfn = mg_ws_cb;
|
||||||
if (wskey != NULL) ws_handshake(c, wskey->ptr, wskey->len);
|
if (wskey != NULL) {
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
ws_handshake(c, wskey->ptr, wskey->len, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
c->is_websocket = 1;
|
c->is_websocket = 1;
|
||||||
}
|
}
|
||||||
|
3
src/ws.h
3
src/ws.h
@ -20,5 +20,6 @@ struct mg_ws_message {
|
|||||||
struct mg_connection *mg_ws_connect(struct mg_mgr *, const char *url,
|
struct mg_connection *mg_ws_connect(struct mg_mgr *, const char *url,
|
||||||
mg_event_handler_t fn, void *fn_data,
|
mg_event_handler_t fn, void *fn_data,
|
||||||
const char *fmt, ...);
|
const char *fmt, ...);
|
||||||
void mg_ws_upgrade(struct mg_connection *, struct mg_http_message *);
|
void mg_ws_upgrade(struct mg_connection *, struct mg_http_message *,
|
||||||
|
const char *fmt, ...);
|
||||||
size_t mg_ws_send(struct mg_connection *, const char *buf, size_t len, int op);
|
size_t mg_ws_send(struct mg_connection *, const char *buf, size_t len, int op);
|
||||||
|
@ -331,7 +331,7 @@ static void eh1(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
|||||||
if (mg_http_match_uri(hm, "/foo/*")) {
|
if (mg_http_match_uri(hm, "/foo/*")) {
|
||||||
mg_http_reply(c, 200, "", "uri: %.*s", hm->uri.len - 5, hm->uri.ptr + 5);
|
mg_http_reply(c, 200, "", "uri: %.*s", hm->uri.len - 5, hm->uri.ptr + 5);
|
||||||
} else if (mg_http_match_uri(hm, "/ws")) {
|
} else if (mg_http_match_uri(hm, "/ws")) {
|
||||||
mg_ws_upgrade(c, hm);
|
mg_ws_upgrade(c, hm, NULL);
|
||||||
} else if (mg_http_match_uri(hm, "/body")) {
|
} else if (mg_http_match_uri(hm, "/body")) {
|
||||||
mg_http_reply(c, 200, "", "%.*s", (int) hm->body.len, hm->body.ptr);
|
mg_http_reply(c, 200, "", "%.*s", (int) hm->body.len, hm->body.ptr);
|
||||||
} else if (mg_http_match_uri(hm, "/bar")) {
|
} else if (mg_http_match_uri(hm, "/bar")) {
|
||||||
|
Loading…
Reference in New Issue
Block a user