Forráskód Böngészése

Relaxed the ordering contraint on the URI matches.

Solved by doing smart insertions.
Thomas Davis 12 éve
szülő
commit
8e2d91c527
3 módosított fájl, 61 hozzáadás és 29 törlés
  1. 24 0
      examples/embedded_cpp/embedded_cpp.cpp
  2. 1 7
      include/civetweb.h
  3. 36 22
      src/civetweb.c

+ 24 - 0
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, "<html><body>");
+		mg_printf(conn, "<h2>This is the A handler!!!</h2>");
+		mg_printf(conn, "</body></html>\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, "<html><body>");
+		mg_printf(conn, "<h2>This is the AB handler!!!</h2>");
+		mg_printf(conn, "</body></html>\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);

+ 1 - 7
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

+ 36 - 22
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)
-		;
-
-    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;
+	{
+		// first try for an exact match
+		if (urilen == tmp_rh->uri_len && !strcmp(tmp_rh->uri,uri)) {
+			// 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;
+		}
+
+		// 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;
+	}
 
 }