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;
+ }
}