[OpenWrt-Devel] Fwd: [PATCH] uhttpd: serve precompressed files

Adrian Kotelba adrian.kotelba at gmail.com
Sun Sep 6 09:02:56 EDT 2015


Serving precompressed content with uhttpd.

Signed-off-by: Adrian Kotelba >adrian.kotelba at gmail.com>
---
diff --git a/file.c b/file.c
index 480c40b..81f8186 100644
--- a/file.c
+++ b/file.c
@@ -136,6 +136,7 @@ uh_path_lookup(struct client *cl, const char *url)
  int docroot_len = strlen(docroot);
  char *pathptr = NULL;
  bool slash;
+ bool precompressed = 0;

  int i = 0;
  int len;
@@ -191,11 +192,26 @@ uh_path_lookup(struct client *cl, const char *url)
  continue;

  /* test current path */
- if (stat(path_phys, &p.stat))
+ if (stat(path_phys, &p.stat) == 0) {
+ snprintf(path_info, sizeof(path_info), "%s", uh_buf + i);
+ break;
+ }
+
+ pathptr = path_phys + strlen(path_phys);
+
+ /* try to locate precompressed file */
+ len = path_phys + sizeof(path_phys) - pathptr - 1;
+ if (strlen(".gz") > len)
  continue;

- snprintf(path_info, sizeof(path_info), "%s", uh_buf + i);
- break;
+ strcpy(pathptr, ".gz");
+ if (stat(path_phys, &p.stat) == 0) {
+ snprintf(path_info, sizeof(path_info), "%s", uh_buf + i);
+ precompressed = 1;
+ break;
+ }
+
+ *pathptr = 0;
  }

  /* check whether found path is within docroot */
@@ -210,6 +226,7 @@ uh_path_lookup(struct client *cl, const char *url)
  p.phys = path_phys;
  p.name = &path_phys[docroot_len];
  p.info = path_info[0] ? path_info : NULL;
+ p.compressed = precompressed;
  return &p;
  }

@@ -258,9 +275,27 @@ uh_path_lookup(struct client *cl, const char *url)
  *pathptr = 0;
  }

+ /* try to locate precompressed index file */
+ len = path_phys + sizeof(path_phys) - pathptr - 1;
+ list_for_each_entry(idx, &index_files, list) {
+ if (strlen(idx->name) + strlen(".gz") > len)
+ continue;
+
+ strcpy(pathptr, idx->name);
+ strcpy(pathptr + strlen(idx->name), ".gz");
+ if (!stat(path_phys, &s) && (s.st_mode & S_IFREG)) {
+ memcpy(&p.stat, &s, sizeof(p.stat));
+ precompressed = 1;
+ break;
+ }
+
+ *pathptr = 0;
+ }
+
  p.root = docroot;
  p.phys = path_phys;
  p.name = &path_phys[docroot_len];
+ p.compressed = precompressed;

  return p.phys ? &p : NULL;
 }
@@ -561,6 +596,8 @@ static void uh_file_free(struct client *cl)

 static void uh_file_data(struct client *cl, struct path_info *pi, int fd)
 {
+ static char name[PATH_MAX];
+
  /* test preconditions */
  if (!uh_file_if_modified_since(cl, &pi->stat) ||
  !uh_file_if_match(cl, &pi->stat) ||
@@ -576,8 +613,15 @@ static void uh_file_data(struct client *cl,
struct path_info *pi, int fd)
  /* write status */
  uh_file_response_200(cl, &pi->stat);

+ strcpy(name, pi->name);
+
+ if (pi->compressed) {
+ name[strlen(name) - strlen(".gz")] = 0;
+ ustream_printf(cl->us, "Content-Encoding: gzip\r\n");
+ }
+
  ustream_printf(cl->us, "Content-Type: %s\r\n",
-   uh_file_mime_lookup(pi->name));
+   uh_file_mime_lookup(name));

  ustream_printf(cl->us, "Content-Length: %" PRIu64 "\r\n\r\n",
    pi->stat.st_size);
diff --git a/uhttpd.h b/uhttpd.h
index fbcb1ed..7b580e4 100644
--- a/uhttpd.h
+++ b/uhttpd.h
@@ -140,6 +140,7 @@ struct path_info {
  const char *query;
  const char *auth;
  bool redirected;
+ bool compressed;
  struct stat stat;
  const struct interpreter *ip;
 };
_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel



More information about the openwrt-devel mailing list