Преглед изворни кода

Rewrite step 5 of handle_request

This is a further enhancement of the fix for issue #88,
and a preparation for a possible implementation of enhancement #30.
bel пре 10 година
родитељ
комит
30ea216a45
1 измењених фајлова са 50 додато и 29 уклоњено
  1. 50 29
      src/civetweb.c

+ 50 - 29
src/civetweb.c

@@ -816,6 +816,7 @@ struct mg_request_handler_info {
     char *uri;
     size_t uri_len;
     mg_request_handler handler;
+    int is_websocket_handler;
 
     void *cbdata;
     struct mg_request_handler_info *next;
@@ -2533,8 +2534,8 @@ static int pull(FILE *fp, struct mg_connection *conn, char *buf, int len)
         }
     } while ((timeout<=0) || (mg_difftimespec(&now,&start)<=timeout));
 
-    /* Timeout occured. Return the amount of data received up to now. */
-    return nread;
+    /* Timeout occured, but no data available. */
+    return -1;
 }
 
 static int pull_all(FILE *fp, struct mg_connection *conn, char *buf, int len)
@@ -6167,7 +6168,7 @@ 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)
+static void mg_set_request_handler_type(struct mg_context *ctx, const char *uri, mg_request_handler handler, void *cbdata, int is_websocket_handler)
 {
     struct mg_request_handler_info *tmp_rh, *lastref = NULL;
     size_t urilen = strlen(uri);
@@ -6184,6 +6185,7 @@ void mg_set_request_handler(struct mg_context *ctx, const char *uri, mg_request_
                 /* change this entry */
                 tmp_rh->handler = handler;
                 tmp_rh->cbdata = cbdata;
+                tmp_rh->is_websocket_handler = is_websocket_handler;                
             } else {
                 /* remove this entry */
                 if (lastref != NULL)
@@ -6220,6 +6222,7 @@ void mg_set_request_handler(struct mg_context *ctx, const char *uri, mg_request_
     tmp_rh->uri_len = urilen;
     tmp_rh->handler = handler;
     tmp_rh->cbdata = cbdata;
+    tmp_rh->is_websocket_handler = is_websocket_handler;
 
     if (lastref == NULL) {
         tmp_rh->next = ctx->request_handlers;
@@ -6230,40 +6233,51 @@ void mg_set_request_handler(struct mg_context *ctx, const char *uri, mg_request_
     }
 }
 
-static int get_request_handler(struct mg_connection *conn, mg_request_handler *handler, void **cbdata)
+void mg_set_request_handler(struct mg_context *ctx, const char *uri, mg_request_handler handler, void *cbdata)
+{
+    mg_set_request_handler_type(ctx, uri, handler, cbdata, 0);
+}
+
+static int get_request_handler(struct mg_connection *conn, int is_websocket_request, mg_request_handler *handler, void **cbdata)
 {
     struct mg_request_info *request_info = mg_get_request_info(conn);
     const char *uri = request_info->uri;
     size_t urilen = strlen(uri);
     struct mg_request_handler_info *tmp_rh;
-
+    
     /* first try for an exact match */
     for (tmp_rh = conn->ctx->request_handlers; tmp_rh != NULL; tmp_rh = tmp_rh->next) {
-        if (urilen == tmp_rh->uri_len && !strcmp(tmp_rh->uri,uri)) {
-            *handler = tmp_rh->handler;
-            *cbdata = tmp_rh->cbdata;
-            return 1;
+        if (tmp_rh->is_websocket_handler == is_websocket_request) {
+            if (urilen == tmp_rh->uri_len && !strcmp(tmp_rh->uri,uri)) {
+                *handler = tmp_rh->handler;
+                *cbdata = tmp_rh->cbdata;
+                return 1;
+            }
         }
     }
 
     /* next try for a partial match, we will accept uri/something */
     for (tmp_rh = conn->ctx->request_handlers; tmp_rh != NULL; tmp_rh = tmp_rh->next) {
-        if (tmp_rh->uri_len < urilen
-            && uri[tmp_rh->uri_len] == '/'
-            && memcmp(tmp_rh->uri, uri, tmp_rh->uri_len) == 0) {
-
-            *handler = tmp_rh->handler;
-            *cbdata = tmp_rh->cbdata;
-            return 1;
+        if (tmp_rh->is_websocket_handler == is_websocket_request) {
+            if (tmp_rh->uri_len < urilen
+                && uri[tmp_rh->uri_len] == '/'
+                && memcmp(tmp_rh->uri, uri, tmp_rh->uri_len) == 0) {
+
+                *handler = tmp_rh->handler;
+                *cbdata = tmp_rh->cbdata;
+                return 1;
+            }
         }
     }
 
     /* finally try for pattern match */
     for (tmp_rh = conn->ctx->request_handlers; tmp_rh != NULL; tmp_rh = tmp_rh->next) {
-        if (match_prefix(tmp_rh->uri, (int)tmp_rh->uri_len, uri) > 0) {
-            *handler = tmp_rh->handler;
-            *cbdata = tmp_rh->cbdata;
-            return 1;
+        if (tmp_rh->is_websocket_handler == is_websocket_request) {
+            if (match_prefix(tmp_rh->uri, (int)tmp_rh->uri_len, uri) > 0) {
+                *handler = tmp_rh->handler;
+                *cbdata = tmp_rh->cbdata;
+                return 1;
+            }
         }
     }
 
@@ -6288,6 +6302,8 @@ static void handle_request(struct mg_connection *conn)
     char date[64];
 #endif
 
+    path[0] = 0;
+
     /* 1. get the request url */
     /* 1.1. split into url and query string */
     if ((conn->request_info.query_string = strchr(ri->uri, '?')) != NULL) {
@@ -6348,15 +6364,20 @@ static void handle_request(struct mg_connection *conn)
        is processed here */
 
     /* 5. interpret the url to find out how the request must be handled */
-    /* 5.1. file system based requests */
-    path[0] = '\0';
-    interpret_uri(conn, path, sizeof(path), &file, &is_script_resource, &is_websocket_request, &is_put_or_delete_request);
-
-    if (!is_websocket_request) {
-        /* 5.2. url handler based requests */
-        if (get_request_handler(conn, &callback_handler, &callback_data)) {
-            is_script_resource = 1;
-        }
+    /* 5.1. first test, if the request targets the regular http(s):// protocol namespace 
+            or the websocket ws(s):// protocol namespace. */
+    is_websocket_request = is_websocket_protocol(conn);
+
+    /* 5.2. check if the request will be handled by a callback */
+    if (get_request_handler(conn, is_websocket_request, &callback_handler, &callback_data)) {
+        /* 5.2.1. A callback will handle this request. All requests handled by a callback 
+                  have to be considered as requests to a script resource. */
+        is_script_resource = 1;
+        is_put_or_delete_request = is_put_or_delete_method(conn);
+    } else {
+        /* 5.2.2. No callback is responsible for this request. The URI addresses a file 
+                  based resource (static content or Lua/cgi scripts in the file system). */
+        interpret_uri(conn, path, sizeof(path), &file, &is_script_resource, &is_websocket_request, &is_put_or_delete_request);
     }
 
     /* 6. authorization check */