Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
M
mongoose
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
esp
mongoose
Commits
bf7dd7ac
Commit
bf7dd7ac
authored
Mar 15, 2017
by
Dmitry Frank
Committed by
Cesanta Bot
Mar 15, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add separate userdata for each http endpoint hdlr
PUBLISHED_FROM=29a204c2c7f35724b6f1e8435edb94869da2362c
parent
0fc33708
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
86 additions
and
54 deletions
+86
-54
mg_register_http_endpoint.md
docs/c-api/http_server.h/mg_register_http_endpoint.md
+2
-1
big_upload.c
examples/big_upload/big_upload.c
+1
-1
mongoose.c
mongoose.c
+81
-51
mongoose.h
mongoose.h
+2
-1
No files found.
docs/c-api/http_server.h/mg_register_http_endpoint.md
View file @
bf7dd7ac
...
...
@@ -4,7 +4,8 @@ decl_name: "mg_register_http_endpoint"
symbol_kind
:
"
func"
signature
:
|
void mg_register_http_endpoint(struct mg_connection *nc, const char *uri_path,
mg_event_handler_t handler);
MG_CB(mg_event_handler_t handler,
void *user_data);
---
Registers a callback for a specified http endpoint
...
...
examples/big_upload/big_upload.c
View file @
bf7dd7ac
...
...
@@ -98,7 +98,7 @@ int main(void) {
mg_mgr_init
(
&
mgr
,
NULL
);
nc
=
mg_bind
(
&
mgr
,
s_http_port
,
ev_handler
);
mg_register_http_endpoint
(
nc
,
"/upload"
,
handle_upload
);
mg_register_http_endpoint
(
nc
,
"/upload"
,
handle_upload
MG_UD_ARG
(
NULL
)
);
// Set up HTTP server parameters
mg_set_protocol_http_websocket
(
nc
);
...
...
mongoose.c
View file @
bf7dd7ac
...
...
@@ -62,7 +62,8 @@ MG_INTERNAL struct mg_connection *mg_do_connect(struct mg_connection *nc,
MG_INTERNAL int mg_parse_address(const char *str, union socket_address *sa,
int *proto, char *host, size_t host_len);
MG_INTERNAL void mg_call(struct mg_connection *nc,
mg_event_handler_t ev_handler, int ev, void *ev_data);
mg_event_handler_t ev_handler, void *user_data, int ev,
void *ev_data);
void mg_forward(struct mg_connection *from, struct mg_connection *to);
MG_INTERNAL void mg_add_conn(struct mg_mgr *mgr, struct mg_connection *c);
MG_INTERNAL void mg_remove_conn(struct mg_connection *c);
...
...
@@ -2021,7 +2022,8 @@ MG_INTERNAL void mg_remove_conn(struct mg_connection *conn) {
}
MG_INTERNAL void mg_call(struct mg_connection *nc,
mg_event_handler_t ev_handler, int ev, void *ev_data) {
mg_event_handler_t ev_handler, void *user_data, int ev,
void *ev_data) {
if (ev_handler == NULL) {
/*
* If protocol handler is specified, call it. Otherwise, call user-specified
...
...
@@ -2051,7 +2053,7 @@ MG_INTERNAL void mg_call(struct mg_connection *nc,
if (ev_handler != NULL) {
unsigned long flags_before = nc->flags;
size_t recv_mbuf_before = nc->recv_mbuf.len, recved;
ev_handler(nc, ev, ev_data MG_UD_ARG(
nc->
user_data));
ev_handler(nc, ev, ev_data MG_UD_ARG(user_data));
recved = (recv_mbuf_before - nc->recv_mbuf.len);
/* Prevent user handler from fiddling with system flags. */
if (ev_handler == nc->handler && nc->flags != flags_before) {
...
...
@@ -2067,12 +2069,15 @@ MG_INTERNAL void mg_call(struct mg_connection *nc,
ev_handler == nc->handler ? "user" : "proto", nc->flags,
(int) nc->recv_mbuf.len, (int) nc->send_mbuf.len));
}
#if !MG_ENABLE_CALLBACK_USERDATA
(void) user_data;
#endif
}
void mg_if_timer(struct mg_connection *c, double now) {
if (c->ev_timer_time > 0 && now >= c->ev_timer_time) {
double old_value = c->ev_timer_time;
mg_call(c, NULL, MG_EV_TIMER, &now);
mg_call(c, NULL,
c->user_data,
MG_EV_TIMER, &now);
/*
* To prevent timer firing all the time, reset the timer after delivery.
* However, in case user sets it to new value, do not reset.
...
...
@@ -2085,7 +2090,7 @@ void mg_if_timer(struct mg_connection *c, double now) {
void mg_if_poll(struct mg_connection *nc, time_t now) {
if (!(nc->flags & MG_F_SSL) || (nc->flags & MG_F_SSL_HANDSHAKE_DONE)) {
mg_call(nc, NULL, MG_EV_POLL, &now);
mg_call(nc, NULL,
nc->user_data,
MG_EV_POLL, &now);
}
}
...
...
@@ -2108,7 +2113,7 @@ void mg_close_conn(struct mg_connection *conn) {
DBG(("%p %lu %d", conn, conn->flags, conn->sock));
mg_remove_conn(conn);
conn->iface->vtable->destroy_conn(conn);
mg_call(conn, NULL, MG_EV_CLOSE, NULL);
mg_call(conn, NULL,
conn->user_data,
MG_EV_CLOSE, NULL);
mg_destroy_conn(conn, 0 /* destroy_if */);
}
...
...
@@ -2452,7 +2457,7 @@ void mg_if_accept_tcp_cb(struct mg_connection *nc, union socket_address *sa,
size_t sa_len) {
(void) sa_len;
nc->sa = *sa;
mg_call(nc, NULL, MG_EV_ACCEPT, &nc->sa);
mg_call(nc, NULL,
nc->user_data,
MG_EV_ACCEPT, &nc->sa);
}
void mg_send(struct mg_connection *nc, const void *buf, int len) {
...
...
@@ -2473,7 +2478,7 @@ void mg_if_sent_cb(struct mg_connection *nc, int num_sent) {
if (num_sent < 0) {
nc->flags |= MG_F_CLOSE_IMMEDIATELY;
}
mg_call(nc, NULL, MG_EV_SEND, &num_sent);
mg_call(nc, NULL,
nc->user_data,
MG_EV_SEND, &num_sent);
}
MG_INTERNAL void mg_recv_common(struct mg_connection *nc, void *buf, int len,
...
...
@@ -2502,7 +2507,7 @@ MG_INTERNAL void mg_recv_common(struct mg_connection *nc, void *buf, int len,
mbuf_append(&nc->recv_mbuf, buf, len);
MG_FREE(buf);
}
mg_call(nc, NULL, MG_EV_RECV, &len);
mg_call(nc, NULL,
nc->user_data,
MG_EV_RECV, &len);
}
void mg_if_recv_tcp_cb(struct mg_connection *nc, void *buf, int len, int own) {
...
...
@@ -2550,7 +2555,7 @@ void mg_if_recv_udp_cb(struct mg_connection *nc, void *buf, int len,
*/
nc->flags |= MG_F_SEND_AND_CLOSE;
mg_add_conn(lc->mgr, nc);
mg_call(nc, NULL, MG_EV_ACCEPT, &nc->sa);
mg_call(nc, NULL,
nc->user_data,
MG_EV_ACCEPT, &nc->sa);
} else {
DBG(("OOM"));
/* No return here, we still need to drop on the floor */
...
...
@@ -2594,7 +2599,7 @@ void mg_if_connect_cb(struct mg_connection *nc, int err) {
if (err != 0) {
nc->flags |= MG_F_CLOSE_IMMEDIATELY;
}
mg_call(nc, NULL, MG_EV_CONNECT, &err);
mg_call(nc, NULL,
nc->user_data,
MG_EV_CONNECT, &err);
}
#if MG_ENABLE_ASYNC_RESOLVER
...
...
@@ -2632,14 +2637,14 @@ static void resolve_cb(struct mg_dns_message *msg, void *data,
if (e == MG_RESOLVE_TIMEOUT) {
double now = mg_time();
mg_call(nc, NULL, MG_EV_TIMER, &now);
mg_call(nc, NULL,
nc->user_data,
MG_EV_TIMER, &now);
}
/*
* If we get there was no MG_DNS_A_RECORD in the answer
*/
mg_call(nc, NULL, MG_EV_CONNECT, &failure);
mg_call(nc, NULL, MG_EV_CLOSE, NULL);
mg_call(nc, NULL,
nc->user_data,
MG_EV_CONNECT, &failure);
mg_call(nc, NULL,
nc->user_data,
MG_EV_CLOSE, NULL);
mg_destroy_conn(nc, 1 /* destroy_if */);
}
#endif
...
...
@@ -5021,6 +5026,9 @@ struct mg_http_endpoint {
const char *name;
size_t name_len;
mg_event_handler_t handler;
#if MG_ENABLE_CALLBACK_USERDATA
void *user_data;
#endif
};
enum mg_http_multipart_stream_state {
...
...
@@ -5502,7 +5510,7 @@ MG_INTERNAL size_t mg_handle_chunked(struct mg_connection *nc,
/* Send MG_EV_HTTP_CHUNK event */
nc->flags &= ~MG_F_DELETE_CHUNK;
mg_call(nc, nc->handler, MG_EV_HTTP_CHUNK, hm);
mg_call(nc, nc->handler,
nc->user_data,
MG_EV_HTTP_CHUNK, hm);
/* Delete processed data if user set MG_F_DELETE_CHUNK flag */
if (nc->flags & MG_F_DELETE_CHUNK) {
...
...
@@ -5523,10 +5531,10 @@ MG_INTERNAL size_t mg_handle_chunked(struct mg_connection *nc,
return body_len;
}
st
atic mg_event_handler_t mg_http_get_endpoint_handler(
struct mg_connection *nc,
struct mg_str *uri_path) {
st
ruct mg_http_endpoint *mg_http_get_endpoint_handler(struct mg_connection *nc,
struct mg_str *uri_path) {
struct mg_http_proto_data *pd;
mg_event_handler_t
ret = NULL;
struct mg_http_endpoint *
ret = NULL;
int matched, matched_max = 0;
struct mg_http_endpoint *ep;
...
...
@@ -5542,7 +5550,7 @@ static mg_event_handler_t mg_http_get_endpoint_handler(
if ((matched = mg_match_prefix_n(name_s, *uri_path)) != -1) {
if (matched > matched_max) {
/* Looking for the longest suitable handler */
ret = ep
->handler
;
ret = ep;
matched_max = matched;
}
}
...
...
@@ -5556,15 +5564,20 @@ static mg_event_handler_t mg_http_get_endpoint_handler(
static void mg_http_call_endpoint_handler(struct mg_connection *nc, int ev,
struct http_message *hm) {
struct mg_http_proto_data *pd = mg_http_get_proto_data(nc);
void *user_data = nc->user_data;
if (pd->endpoint_handler == NULL || ev == MG_EV_HTTP_REQUEST) {
pd->endpoint_handler =
ev == MG_EV_HTTP_REQUEST
? mg_http_get_endpoint_handler(nc->listener, &hm->uri)
: NULL;
if (ev == MG_EV_HTTP_REQUEST) {
struct mg_http_endpoint *ep =
mg_http_get_endpoint_handler(nc->listener, &hm->uri);
if (ep != NULL) {
pd->endpoint_handler = ep->handler;
#if MG_ENABLE_CALLBACK_USERDATA
user_data = ep->user_data;
#endif
}
}
mg_call(nc, pd->endpoint_handler ? pd->endpoint_handler : nc->handler,
ev,
hm);
mg_call(nc, pd->endpoint_handler ? pd->endpoint_handler : nc->handler,
user_data, ev,
hm);
}
#if MG_ENABLE_HTTP_STREAMING_MULTIPART
...
...
@@ -5627,11 +5640,11 @@ void mg_http_handler(struct mg_connection *nc, int ev,
mp.var_name = pd->mp_stream.var_name;
mp.file_name = pd->mp_stream.file_name;
mg_call(nc, (pd->endpoint_handler ? pd->endpoint_handler : nc->handler),
MG_EV_HTTP_PART_END, &mp);
nc->user_data,
MG_EV_HTTP_PART_END, &mp);
mp.var_name = NULL;
mp.file_name = NULL;
mg_call(nc, (pd->endpoint_handler ? pd->endpoint_handler : nc->handler),
MG_EV_HTTP_MULTIPART_REQUEST_END, &mp);
nc->user_data,
MG_EV_HTTP_MULTIPART_REQUEST_END, &mp);
} else
#endif
if (io->len > 0 && mg_parse_http(io->buf, io->len, hm, is_req) > 0) {
...
...
@@ -5652,7 +5665,7 @@ void mg_http_handler(struct mg_connection *nc, int ev,
}
#endif
mg_call(nc, nc->handler, ev, ev_data);
mg_call(nc, nc->handler,
nc->user_data,
ev, ev_data);
if (ev == MG_EV_RECV) {
struct mg_str *s;
...
...
@@ -5697,11 +5710,12 @@ void mg_http_handler(struct mg_connection *nc, int ev,
mbuf_remove(io, req_len);
nc->proto_handler = mg_ws_handler;
nc->flags |= MG_F_IS_WEBSOCKET;
mg_call(nc, nc->handler, MG_EV_WEBSOCKET_HANDSHAKE_DONE, NULL);
mg_call(nc, nc->handler, nc->user_data, MG_EV_WEBSOCKET_HANDSHAKE_DONE,
NULL);
mg_ws_handler(nc, MG_EV_RECV, ev_data MG_UD_ARG(user_data));
} else if (nc->listener != NULL &&
(vec = mg_get_http_header(hm, "Sec-WebSocket-Key")) != NULL) {
mg_event_handler_t handler
;
struct mg_http_endpoint *ep
;
/* This is a websocket request. Switch protocol handlers. */
mbuf_remove(io, req_len);
...
...
@@ -5713,18 +5727,23 @@ void mg_http_handler(struct mg_connection *nc, int ev,
* deliver subsequent websocket events to this handler after the
* protocol switch.
*/
handler = mg_http_get_endpoint_handler(nc->listener, &hm->uri);
if (handler != NULL) {
nc->handler = handler;
ep = mg_http_get_endpoint_handler(nc->listener, &hm->uri);
if (ep != NULL) {
nc->handler = ep->handler;
#if MG_ENABLE_CALLBACK_USERDATA
nc->user_data = ep->user_data;
#endif
}
/* Send handshake */
mg_call(nc, nc->handler, MG_EV_WEBSOCKET_HANDSHAKE_REQUEST, hm);
mg_call(nc, nc->handler, nc->user_data, MG_EV_WEBSOCKET_HANDSHAKE_REQUEST,
hm);
if (!(nc->flags & (MG_F_CLOSE_IMMEDIATELY | MG_F_SEND_AND_CLOSE))) {
if (nc->send_mbuf.len == 0) {
mg_ws_handshake(nc, vec);
}
mg_call(nc, nc->handler, MG_EV_WEBSOCKET_HANDSHAKE_DONE, NULL);
mg_call(nc, nc->handler, nc->user_data, MG_EV_WEBSOCKET_HANDSHAKE_DONE,
NULL);
mg_ws_handler(nc, MG_EV_RECV, ev_data MG_UD_ARG(user_data));
}
}
...
...
@@ -5805,6 +5824,7 @@ static void mg_http_multipart_begin(struct mg_connection *nc,
struct mg_http_proto_data *pd = mg_http_get_proto_data(nc);
struct mg_str *ct;
struct mbuf *io = &nc->recv_mbuf;
void *user_data = nc->user_data;
char boundary[100];
int boundary_len;
...
...
@@ -5841,17 +5861,23 @@ static void mg_http_multipart_begin(struct mg_connection *nc,
*/
nc->flags |= MG_F_CLOSE_IMMEDIATELY;
} else {
struct mg_http_endpoint *ep = NULL;
pd->mp_stream.state = MPS_BEGIN;
pd->mp_stream.boundary = strdup(boundary);
pd->mp_stream.boundary_len = strlen(boundary);
pd->mp_stream.var_name = pd->mp_stream.file_name = NULL;
pd->endpoint_handler = nc->handler;
pd->endpoint_handler = mg_http_get_endpoint_handler(nc->listener, &hm->uri);
if (pd->endpoint_handler == NULL) {
pd->endpoint_handler = nc->handler;
ep = mg_http_get_endpoint_handler(nc->listener, &hm->uri);
if (ep != NULL) {
pd->endpoint_handler = ep->handler;
#if MG_ENABLE_CALLBACK_USERDATA
user_data = ep->user_data;
#endif
}
mg_call(nc, pd->endpoint_handler, MG_EV_HTTP_MULTIPART_REQUEST, hm);
mg_call(nc, pd->endpoint_handler, user_data, MG_EV_HTTP_MULTIPART_REQUEST,
hm);
mbuf_remove(io, req_len);
}
...
...
@@ -5872,7 +5898,7 @@ static void mg_http_multipart_call_handler(struct mg_connection *c, int ev,
mp.user_data = pd->mp_stream.user_data;
mp.data.p = data;
mp.data.len = data_len;
mg_call(c, pd->endpoint_handler, ev, &mp);
mg_call(c, pd->endpoint_handler,
c->user_data,
ev, &mp);
pd->mp_stream.user_data = mp.user_data;
}
...
...
@@ -7834,7 +7860,8 @@ size_t mg_parse_multipart(const char *buf, size_t buf_len, char *var_name,
}
void mg_register_http_endpoint(struct mg_connection *nc, const char *uri_path,
mg_event_handler_t handler) {
MG_CB(mg_event_handler_t handler,
void *user_data)) {
struct mg_http_proto_data *pd = NULL;
struct mg_http_endpoint *new_ep = NULL;
...
...
@@ -7846,6 +7873,9 @@ void mg_register_http_endpoint(struct mg_connection *nc, const char *uri_path,
new_ep->name = strdup(uri_path);
new_ep->name_len = strlen(new_ep->name);
new_ep->handler = handler;
#if MG_ENABLE_CALLBACK_USERDATA
new_ep->user_data = user_data;
#endif
new_ep->next = pd->endpoints;
pd->endpoints = new_ep;
}
...
...
@@ -8480,9 +8510,9 @@ static void mg_send_ssi_file(struct mg_connection *nc, struct http_message *hm,
cctx.req = hm;
cctx.file = mg_mk_str(path);
cctx.arg = mg_mk_str(p + d_call.len + 1);
mg_call(nc, NULL, MG_EV_SSI_CALL,
mg_call(nc, NULL,
nc->user_data,
MG_EV_SSI_CALL,
(void *) cctx.arg.p); /* NUL added above */
mg_call(nc, NULL, MG_EV_SSI_CALL_CTX, &cctx);
mg_call(nc, NULL,
nc->user_data,
MG_EV_SSI_CALL_CTX, &cctx);
#if MG_ENABLE_HTTP_SSI_EXEC
} else if (strncmp(p, d_exec.p, d_exec.len) == 0) {
do_ssi_exec(nc, p + d_exec.len + 1);
...
...
@@ -8846,9 +8876,9 @@ static int mg_is_ws_first_fragment(unsigned char flags) {
static void mg_handle_incoming_websocket_frame(struct mg_connection *nc,
struct websocket_message *wsm) {
if (wsm->flags & 0x8) {
mg_call(nc, nc->handler, MG_EV_WEBSOCKET_CONTROL_FRAME, wsm);
mg_call(nc, nc->handler,
nc->user_data,
MG_EV_WEBSOCKET_CONTROL_FRAME, wsm);
} else {
mg_call(nc, nc->handler, MG_EV_WEBSOCKET_FRAME, wsm);
mg_call(nc, nc->handler,
nc->user_data,
MG_EV_WEBSOCKET_FRAME, wsm);
}
}
...
...
@@ -9071,7 +9101,7 @@ void mg_printf_websocket_frame(struct mg_connection *nc, int op,
MG_INTERNAL void mg_ws_handler(struct mg_connection *nc, int ev,
void *ev_data MG_UD_ARG(void *user_data)) {
mg_call(nc, nc->handler, ev, ev_data);
mg_call(nc, nc->handler,
nc->user_data,
ev, ev_data);
switch (ev) {
case MG_EV_RECV:
...
...
@@ -12057,7 +12087,7 @@ static void mg_sntp_util_ev_handler(struct mg_connection *c, int ev,
switch (ev) {
case MG_EV_CONNECT:
if (*(int *) ev_data != 0) {
mg_call(c, sd->hander, MG_SNTP_FAILED, NULL);
mg_call(c, sd->hander,
c->user_data,
MG_SNTP_FAILED, NULL);
break;
}
/* fallthrough */
...
...
@@ -12067,16 +12097,16 @@ static void mg_sntp_util_ev_handler(struct mg_connection *c, int ev,
mg_set_timer(c, mg_time() + 10);
sd->count++;
} else {
mg_call(c, sd->hander, MG_SNTP_FAILED, NULL);
mg_call(c, sd->hander,
c->user_data,
MG_SNTP_FAILED, NULL);
c->flags |= MG_F_CLOSE_IMMEDIATELY;
}
break;
case MG_SNTP_MALFORMED_REPLY:
mg_call(c, sd->hander, MG_SNTP_FAILED, NULL);
mg_call(c, sd->hander,
c->user_data,
MG_SNTP_FAILED, NULL);
c->flags |= MG_F_CLOSE_IMMEDIATELY;
break;
case MG_SNTP_REPLY:
mg_call(c, sd->hander, MG_SNTP_REPLY, ev_data);
mg_call(c, sd->hander,
c->user_data,
MG_SNTP_REPLY, ev_data);
c->flags |= MG_F_CLOSE_IMMEDIATELY;
break;
case MG_EV_CLOSE:
...
...
mongoose.h
View file @
bf7dd7ac
...
...
@@ -4792,7 +4792,8 @@ void mg_file_upload_handler(struct mg_connection *nc, int ev, void *ev_data,
* ```
*/
void
mg_register_http_endpoint
(
struct
mg_connection
*
nc
,
const
char
*
uri_path
,
mg_event_handler_t
handler
);
MG_CB
(
mg_event_handler_t
handler
,
void
*
user_data
));
/*
* Authenticates a HTTP request against an opened password file.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment