http_static: clean up http redirect generation 85/37785/1
authorDave Barach <dave@barachs.net>
Fri, 9 Dec 2022 14:07:17 +0000 (09:07 -0500)
committerDave Barach <dave@barachs.net>
Fri, 9 Dec 2022 14:07:58 +0000 (09:07 -0500)
Don't redirect to "favicon.ico/index.html" if you can't find
"favicon.ico".

If asked to serve up a nonexistent path, see if the path ends with a
known suffix: ".jpg, .html, .ico" etc. If it does, flunk the request
on the spot: "Error 404 Not Found." Do not issue a redirect.

This change will not break the obvious corner case: if the browser
asks for "its_a_dir.mp3/index.html" - and the file exists - the server
will produce it.

Type: improvement

Signed-off-by: Dave Barach <dave@barachs.net>
Change-Id: I91aad90be05b98ba2b40e240d13d71816aed4526

src/plugins/http_static/static_server.c

index 4d0373a..040cdca 100644 (file)
@@ -145,6 +145,44 @@ hss_session_send_data (hss_url_handler_args_t *args)
   start_send_data (hs, args->sc);
 }
 
+/*
+ * path_has_known_suffix()
+ * Returns 1 if the request ends with a known suffix, like .htm or .ico
+ * Used to avoid looking for "/favicon.ico/index.html" or similar.
+ */
+
+static int
+path_has_known_suffix (u8 *request)
+{
+  u8 *ext;
+  uword *p;
+
+  if (vec_len (request) == 0)
+    {
+      return 0;
+    }
+
+  ext = request + vec_len (request) - 1;
+
+  while (ext > request && ext[0] != '.')
+    ext--;
+
+  if (ext == request)
+    return 0;
+
+  p = hash_get_mem (hss_main.mime_type_indices_by_file_extensions, ext);
+  if (p)
+    return 1;
+
+  return 0;
+}
+
+/*
+ * content_type_from_request
+ * Returns the index of the request's suffix in the
+ * http-layer http_content_type_str[] array.
+ */
+
 static http_content_type_t
 content_type_from_request (u8 *request)
 {
@@ -185,6 +223,12 @@ try_url_handler (hss_main_t *hsm, hss_session_t *hs, http_req_method_t rt,
   if (!hsm->enable_url_handlers || !request)
     return -1;
 
+  /* zero-length? try "index.html" */
+  if (vec_len (request) == 0)
+    {
+      request = format (request, "index.html");
+    }
+
   type = content_type_from_request (request);
 
   /* Look for built-in GET / POST handlers */
@@ -340,7 +384,6 @@ try_file_handler (hss_main_t *hsm, hss_session_t *hs, http_req_method_t rt,
   if (hs->data && hs->free_data)
     vec_free (hs->data);
 
-  hs->path = path;
   hs->data_offset = 0;
 
   ce_index =
@@ -349,6 +392,17 @@ try_file_handler (hss_main_t *hsm, hss_session_t *hs, http_req_method_t rt,
     {
       if (!file_path_is_valid (path))
        {
+         /*
+          * Generate error 404 right now if we can't find a path with
+          * a known file extension. It's silly to look for
+          * "favicon.ico/index.html" if you can't find
+          * "favicon.ico"; realistic example which used to happen.
+          */
+         if (path_has_known_suffix (path))
+           {
+             sc = HTTP_STATUS_NOT_FOUND;
+             goto done;
+           }
          sc = try_index_file (hsm, hs, path);
          goto done;
        }
@@ -361,6 +415,7 @@ try_file_handler (hss_main_t *hsm, hss_session_t *hs, http_req_method_t rt,
        }
     }
 
+  hs->path = path;
   hs->cache_pool_index = ce_index;
 
 done: