Skip to content

Commit

Permalink
Changed the order of handlers: protocol first, user second
Browse files Browse the repository at this point in the history
  • Loading branch information
cpq committed Jan 25, 2024
1 parent 8dc62c2 commit ce1790a
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 38 deletions.
6 changes: 3 additions & 3 deletions examples/file-upload-single-post/main.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2020 Cesanta Software Limited
// Copyright (c) 2020-2024 Cesanta Software Limited
// All rights reserved
//
// Streaming upload example. Demonstrates how to use MG_EV_READ events
Expand All @@ -11,7 +11,7 @@
// HTTP request handler function. It implements the following endpoints:
// /upload - Saves the next file chunk
// all other URI - serves web_root/ directory
static void cb(struct mg_connection *c, int ev, void *ev_data) {
static void fn(struct mg_connection *c, int ev, void *ev_data) {
if (ev == MG_EV_READ) {
// Parse the incoming data ourselves. If we can parse the request,
// store two size_t variables in the c->data: expected len and recv len.
Expand Down Expand Up @@ -46,7 +46,7 @@ int main(void) {

mg_mgr_init(&mgr);
mg_log_set(MG_LL_DEBUG); // Set debug log level
mg_http_listen(&mgr, "http://localhost:8000", cb, NULL);
mg_listen(&mgr, "http://localhost:8000", fn, NULL);

for (;;) mg_mgr_poll(&mgr, 50);
mg_mgr_free(&mgr);
Expand Down
43 changes: 17 additions & 26 deletions examples/http-streaming-client/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,53 +27,44 @@ static void fn(struct mg_connection *c, int ev, void *ev_data) {
// Send request
mg_printf(c,
"GET %s HTTP/1.1\r\n"
"Connection: keep-alive\r\n"
"Keep-Alive: timeout=60\r\n"
"Connection: close\r\n"
"Host: %.*s\r\n"
"\r\n",
mg_url_uri(s_url), (int) host.len, host.ptr);
} else if (ev == MG_EV_READ) {
// Parse the incoming data ourselves. If we can parse the request,
// store two size_t variables in the c->data: expected len and recv len.
size_t *data = (size_t *) c->data;
if (data[0]) { // Already parsed, simply print received data
data[1] += c->recv.len;
fwrite(c->recv.buf, 1, c->recv.len, stdout);
c->recv.len = 0; // And cleanup the receive buffer. Streming!
if (data[1] >= data[0]) * (bool *) c->fn_data = true;
} else {
// c->data[0] holds a flag, whether we have parsed the request already
if (c->data[0] == 0) {
struct mg_http_message hm;
int n = mg_http_parse((char *) c->recv.buf, c->recv.len, &hm);
if (n < 0) mg_error(c, "Bad response");
if (n > 0) {
fwrite(c->recv.buf + n, 1, c->recv.len - n, stdout); // Print body
data[0] = n + hm.body.len;
data[1] = c->recv.len;
c->recv.len = 0; // Cleanup receive buffer
if (data[1] >= data[0]) * (bool *) c->fn_data = true;
c->data[0] = 1; // Request parsed, set the flag
}
} else {
fwrite(c->recv.buf, 1, c->recv.len, stdout);
c->recv.len = 0; // Cleanup the receive buffer
}
} else if (ev == MG_EV_CLOSE) {
*(bool *) c->fn_data = true; // tell event loop to stop
*(bool *) c->fn_data = true; // Done, tell event loop to stop
} else if (ev == MG_EV_ERROR) {
*(bool *) c->fn_data = true; // Error, tell event loop to stop
*(bool *) c->fn_data = true; // Error, Tell event loop to stop
}
(void) ev_data;
}

int main(int argc, char *argv[]) {
struct mg_mgr mgr; // Event manager
bool done = false; // Event handler flips it to true
const char *log_level = getenv("V"); // Log level
struct mg_mgr mgr; // Event manager
bool done = false; // Event handler flips it to true

mg_mgr_init(&mgr); // Initialise event manager
if (log_level == NULL) log_level = "2"; // If not set, set to DEBUG
mg_log_set(atoi(log_level)); // Set to 0 to disable debug log
if (argc > 1) s_url = argv[1]; // Use URL from command line
mg_mgr_init(&mgr); // Initialise event manager
mg_log_set(MG_LL_INFO); // Set to 0 to disable debug log

mg_http_connect(&mgr, s_url, fn, &done); // Create client connection
while (!done) mg_mgr_poll(&mgr, 1000); // Infinite event loop
mg_mgr_free(&mgr); // Free resources
if (argc > 1) s_url = argv[1]; // Use URL from command line
mg_connect(&mgr, s_url, fn, &done); // Create client connection
while (!done) mg_mgr_poll(&mgr, 1000); // Infinite event loop
mg_mgr_free(&mgr); // Free resources

return 0;
}
6 changes: 2 additions & 4 deletions mongoose.c
Original file line number Diff line number Diff line change
Expand Up @@ -1345,11 +1345,9 @@ void mg_call(struct mg_connection *c, int ev, void *ev_data) {
MG_PROF_ADD(c, names[ev]);
}
#endif
// Run user-defined handler first, in order to give it an ability
// to intercept processing (e.g. clean input buffer) before the
// protocol handler kicks in
if (c->fn != NULL) c->fn(c, ev, ev_data);
// Fire protocol handler first, user handler second. See #2559
if (c->pfn != NULL) c->pfn(c, ev, ev_data);
if (c->fn != NULL) c->fn(c, ev, ev_data);
}

void mg_error(struct mg_connection *c, const char *fmt, ...) {
Expand Down
6 changes: 2 additions & 4 deletions src/event.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,9 @@ void mg_call(struct mg_connection *c, int ev, void *ev_data) {
MG_PROF_ADD(c, names[ev]);
}
#endif
// Run user-defined handler first, in order to give it an ability
// to intercept processing (e.g. clean input buffer) before the
// protocol handler kicks in
if (c->fn != NULL) c->fn(c, ev, ev_data);
// Fire protocol handler first, user handler second. See #2559
if (c->pfn != NULL) c->pfn(c, ev, ev_data);
if (c->fn != NULL) c->fn(c, ev, ev_data);
}

void mg_error(struct mg_connection *c, const char *fmt, ...) {
Expand Down
2 changes: 1 addition & 1 deletion test/unit_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -1407,7 +1407,7 @@ static void test_http_no_content_length(void) {
for (i = 0; i < 1000 && strchr(buf2, 'c') == NULL; i++) mg_mgr_poll(&mgr, 10);
MG_INFO(("[%s] [%s]", buf1, buf2));
ASSERT(strcmp(buf1, "mc") == 0);
ASSERT(strcmp(buf2, "cm") == 0); // See #1475
ASSERT(strcmp(buf2, "mc") == 0);
mg_mgr_free(&mgr);
ASSERT(mgr.conns == NULL);
}
Expand Down

0 comments on commit ce1790a

Please sign in to comment.