lwsws conf mount extra mimetypes
authorAndy Green <andy@warmcat.com>
Sat, 14 May 2016 02:48:28 +0000 (10:48 +0800)
committerAndy Green <andy@warmcat.com>
Sat, 14 May 2016 02:48:28 +0000 (10:48 +0800)
This patch adds the ability to provide extra mimtypes on a mount.

lwsws conf learns how to do them.

Signed-off-by: Andy Green <andy@warmcat.com>
README.lwsws.md
lib/libwebsockets.h
lib/server.c
lwsws/conf.c
test-server/test-server-v2.0.c

index 96174d1909baa1a683846bc6c60b7a46843d5071..cebc6b298db61bb7a9744f38a67a8009ceb7dafa 100644 (file)
@@ -275,6 +275,14 @@ options are given, the content is marked uncacheable.
        }
 
 
+4) You can also define a list of additional mimetypes per-mount
+
+        "extra-mimetypes": {
+                 ".zip": "application/zip",
+                 ".doc": "text/evil"
+         }
+
+
 Plugins
 -------
 
index 4256c5b7d8b78597a03df3584fdf1ba3ad15e592..0affce07d14bb2f3626fd05ca98e7d8f6aab9fe2 100644 (file)
@@ -1391,6 +1391,7 @@ struct lws_http_mount {
        const char *def; /* default target, eg, "index.html" */
 
        const struct lws_protocol_vhost_options *cgienv;
+       const struct lws_protocol_vhost_options *extra_mimetypes;
 
        int cgi_timeout;
        int cache_max_age;
index 82ebc2def83f3143018c13d1fb9640592f4fb0da..fd373b1ec7d16f606ddc5e29adf058ca9919d64d 100644 (file)
@@ -192,9 +192,14 @@ lws_select_vhost(struct lws_context *context, int port, const char *servername)
        return NULL;
 }
 
-static const char * get_mimetype(const char *file)
+static const char *
+get_mimetype(const char *file, const struct lws_http_mount *m)
 {
        int n = strlen(file);
+       const struct lws_protocol_vhost_options *pvo = NULL;
+
+       if (m)
+               pvo = m->extra_mimetypes;
 
        if (n < 5)
                return NULL;
@@ -238,10 +243,19 @@ static const char * get_mimetype(const char *file)
        if (!strcmp(&file[n - 4], ".xml"))
                return "application/xml";
 
+       while (pvo) {
+               if (!strcmp(&file[n - strlen(pvo->name)], pvo->name))
+                       return pvo->value;
+
+               pvo = pvo->next;
+       }
+
        return NULL;
 }
 
-int lws_http_serve(struct lws *wsi, char *uri, const char *origin)
+static int
+lws_http_serve(struct lws *wsi, char *uri, const char *origin,
+              const struct lws_http_mount *m)
 {
        const char *mimetype;
 #ifndef _WIN32_WCE
@@ -329,7 +343,7 @@ int lws_http_serve(struct lws *wsi, char *uri, const char *origin)
                return -1;
 #endif
 
-       mimetype = get_mimetype(path);
+       mimetype = get_mimetype(path, m);
        if (!mimetype) {
                lwsl_err("unknown mimetype for %s", path);
                goto bail;
@@ -696,7 +710,7 @@ lws_http_action(struct lws *wsi)
                wsi->cache_revalidate = hit->cache_revalidate;
                wsi->cache_intermediaries = hit->cache_intermediaries;
 
-               n = lws_http_serve(wsi, s, hit->origin);
+               n = lws_http_serve(wsi, s, hit->origin, hit);
                if (n) {
                        /*
                         *      lws_return_http_status(wsi, HTTP_STATUS_NOT_FOUND, NULL);
index ce77d94083dcabf29faea6a7229a8300f632e03b..fa00095db45aa2d08b6b3740ece4a5c1aae63822 100644 (file)
@@ -60,6 +60,7 @@ static const char * const paths_vhosts[] = {
        "vhosts[].mounts[].cache-reuse",
        "vhosts[].mounts[].cache-revalidate",
        "vhosts[].mounts[].cache-intermediaries",
+       "vhosts[].mounts[].extra-mimetypes.*",
        "vhosts[].ws-protocols[].*.*",
        "vhosts[].ws-protocols[].*",
        "vhosts[].ws-protocols[]",
@@ -89,6 +90,7 @@ enum lejp_vhost_paths {
        LEJPVP_MOUNT_CACHE_REUSE,
        LEJPVP_MOUNT_CACHE_REVALIDATE,
        LEJPVP_MOUNT_CACHE_INTERMEDIARIES,
+       LEJPVP_MOUNT_EXTRA_MIMETYPES,
        LEJPVP_PROTOCOL_NAME_OPT,
        LEJPVP_PROTOCOL_NAME,
        LEJPVP_PROTOCOL,
@@ -108,9 +110,12 @@ struct jpargs {
        struct lws_http_mount *head, *last;
 
        struct lws_protocol_vhost_options *pvo;
+       struct lws_protocol_vhost_options *pvo_em;
        struct lws_http_mount m;
        const char **plugin_dirs;
        int count_plugin_dirs;
+
+       unsigned int fresh_mount:1;
 };
 
 static void *
@@ -229,8 +234,10 @@ lejp_vhosts_cb(struct lejp_ctx *ctx, char reason)
        }
 
        if (reason == LEJPCB_OBJECT_START &&
-           ctx->path_match == LEJPVP_MOUNTS + 1)
+           ctx->path_match == LEJPVP_MOUNTS + 1) {
+               a->fresh_mount = 1;
                memset(&a->m, 0, sizeof(a->m));
+       }
 
        /* this catches, eg, vhosts[].ws-protocols[].xxx-protocol */
        if (reason == LEJPCB_OBJECT_START &&
@@ -243,7 +250,7 @@ lejp_vhosts_cb(struct lejp_ctx *ctx, char reason)
                a->pvo->next = a->info->pvo;
                a->info->pvo = a->pvo;
                a->pvo->name = a->p;
-               lwsl_err("adding %s\n", a->p);
+               lwsl_notice("  adding protocol %s\n", a->p);
                a->p += n;
                a->pvo->value = a->p;
                a->pvo->options = NULL;
@@ -283,10 +290,14 @@ lejp_vhosts_cb(struct lejp_ctx *ctx, char reason)
                        ">https://",
                };
 
+               if (!a->fresh_mount)
+                       return 0;
+
                if (!a->m.mountpoint || !a->m.origin) {
                        lwsl_err("mountpoint and origin required\n");
                        return 1;
                }
+               lwsl_debug("adding mount %s\n", a->m.mountpoint);
                m = lwsws_align(a);
                memcpy(m, &a->m, sizeof(*m));
                if (a->last)
@@ -310,6 +321,7 @@ lejp_vhosts_cb(struct lejp_ctx *ctx, char reason)
                        a->head = m;
 
                a->last = m;
+               a->fresh_mount = 0;
        }
 
        /* we only match on the prepared path strings */
@@ -419,8 +431,21 @@ lejp_vhosts_cb(struct lejp_ctx *ctx, char reason)
                a->p += n;
                pvo->value = a->p;
                pvo->options = NULL;
-               a->p += snprintf(a->p, a->end - a->p, "%s", ctx->buf);
-               *(a->p)++ = '\0';
+               break;
+
+       case LEJPVP_MOUNT_EXTRA_MIMETYPES:
+               a->pvo_em = lwsws_align(a);
+               a->p += sizeof(*a->pvo_em);
+
+               n = lejp_get_wildcard(ctx, 0, a->p, a->end - a->p);
+               /* ie, enable this protocol, no options yet */
+               a->pvo_em->next = a->m.extra_mimetypes;
+               a->m.extra_mimetypes = a->pvo_em;
+               a->pvo_em->name = a->p;
+               lwsl_notice("  adding extra-mimetypes %s -> %s\n", a->p, ctx->buf);
+               a->p += n;
+               a->pvo_em->value = a->p;
+               a->pvo_em->options = NULL;
                break;
 
        default:
index 56afca58172d706e1434b96d0a8882e3d585e509..7df518197eb88d5f5b84c5fbf33979cf409d9fdb 100644 (file)
@@ -83,6 +83,7 @@ static const struct lws_http_mount mount = {
        LOCAL_RESOURCE_PATH, /* where to go on the filesystem for that */
        "test.html",    /* default filename if none given */
        NULL,
+       NULL,
        0,
        0,
        0,