diff --git a/examples/embedded_cpp/embedded_cpp.cpp b/examples/embedded_cpp/embedded_cpp.cpp index 60744a10..0a1d190f 100644 --- a/examples/embedded_cpp/embedded_cpp.cpp +++ b/examples/embedded_cpp/embedded_cpp.cpp @@ -40,6 +40,28 @@ public: } }; +class AHandler: public CivetHandler { +public: + bool handleGet(CivetServer *server, struct mg_connection *conn) { + mg_printf(conn, "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"); + mg_printf(conn, ""); + mg_printf(conn, "

This is the A handler!!!

"); + mg_printf(conn, "\n"); + return true; + } +}; + +class ABHandler: public CivetHandler { +public: + bool handleGet(CivetServer *server, struct mg_connection *conn) { + mg_printf(conn, "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"); + mg_printf(conn, ""); + mg_printf(conn, "

This is the AB handler!!!

"); + mg_printf(conn, "\n"); + return true; + } +}; + int main(int argc, char *argv[]) { const char * options[] = { "document_root", DOCUMENT_ROOT, @@ -49,6 +71,8 @@ int main(int argc, char *argv[]) { server.addHandler(EXAMPLE_URI, new ExampleHandler()); server.addHandler(EXIT_URI, new ExitHandler()); + server.addHandler("/a", new AHandler()); + server.addHandler("/a/b", new ABHandler()); // going out of order with this to see if it will work. printf("Browse files at http://localhost:%s/\n", PORT); printf("Run example at http://localhost:%s%s\n", PORT, EXAMPLE_URI); diff --git a/include/civetweb.h b/include/civetweb.h index f1a56f97..90caafea 100644 --- a/include/civetweb.h +++ b/include/civetweb.h @@ -186,16 +186,10 @@ typedef int (* mg_request_handler)(struct mg_connection *conn, void *cbdata); // Sets or removes a URI mapping for a request handler. // // URI's are ordered and prefixed URI's are supported. For example, -// consider two URIs in order: -// /a/b then /a +// consider two URIs: /a/b and /a // /a matches /a // /a/b matches /a/b // /a/c matches /a -// Reversing the order: -// /a then /a/b -// /a matches /a -// /a/b matches /a -// /a/c matches /a // // Parameters: // ctx: server context diff --git a/src/civetweb.c b/src/civetweb.c index 71735d3f..7ee891f6 100644 --- a/src/civetweb.c +++ b/src/civetweb.c @@ -4279,30 +4279,42 @@ static void redirect_to_https_port(struct mg_connection *conn, int ssl_index) { void mg_set_request_handler(struct mg_context *ctx, const char *uri, mg_request_handler handler, void *cbdata) { struct mg_request_handler_info *tmp_rh, *lastref = 0; + size_t urilen = strlen(uri); // first see it the uri exists for (tmp_rh = ctx->request_handlers; tmp_rh != NULL && strcmp(uri, tmp_rh->uri); lastref = tmp_rh, tmp_rh = tmp_rh->next) - ; + { + // first try for an exact match + if (urilen == tmp_rh->uri_len && !strcmp(tmp_rh->uri,uri)) { + // already there... - if (tmp_rh != NULL) { - // already there... - - if (handler != NULL) { - // change this entry - tmp_rh->handler = handler; - tmp_rh->cbdata = cbdata; - } else { - // remove this entry - if (lastref != NULL) - lastref->next = tmp_rh->next; - else - ctx->request_handlers = tmp_rh->next; - free(tmp_rh->uri); - free(tmp_rh); - } - return; + if (handler != NULL) { + // change this entry + tmp_rh->handler = handler; + tmp_rh->cbdata = cbdata; + } else { + // remove this entry + if (lastref != NULL) + lastref->next = tmp_rh->next; + else + ctx->request_handlers = tmp_rh->next; + free(tmp_rh->uri); + free(tmp_rh); + } + return; + } + + // next try for a partial match, we will accept uri/something + if (tmp_rh->uri_len < urilen + && uri[tmp_rh->uri_len] == '/' + && memcmp(tmp_rh->uri, uri, tmp_rh->uri_len) == 0) { + // if there is a partical match this new entry MUST go BEFORE + // the current position otherwise it will never be matched. + break; + } + } if (handler == NULL) { @@ -4315,12 +4327,14 @@ void mg_set_request_handler(struct mg_context *ctx, const char *uri, mg_request_ tmp_rh->uri_len = strlen(uri); tmp_rh->handler = handler; tmp_rh->cbdata = cbdata; - tmp_rh->next = NULL; - if (lastref == NULL) + if (lastref == NULL) { + tmp_rh->next = ctx->request_handlers; ctx->request_handlers = tmp_rh; - else + } else { + tmp_rh->next = lastref->next; lastref->next = tmp_rh; + } }