file_ops: add compression flags and convert open flags to pointer
authorAndy Green <andy@warmcat.com>
Sun, 12 Feb 2017 10:15:15 +0000 (18:15 +0800)
committerAndy Green <andy@warmcat.com>
Sun, 12 Feb 2017 10:15:15 +0000 (18:15 +0800)
ihttps://libwebsockets.org/pipermail/libwebsockets/2017-February/003127.html

lib/libwebsockets.h
lib/lws-plat-mbed3.c
lib/lws-plat-optee.c
lib/lws-plat-unix.c
lib/lws-plat-win.c
lib/server.c
test-server/test-server-libev.c
test-server/test-server.c

index 70c9fbe..ed55bd7 100644 (file)
@@ -4181,12 +4181,21 @@ lws_cgi_kill(struct lws *wsi);
 #define LWS_FOP_READ read
 #define LWS_FOP_WRITE write
 
+#define LWS_FOP_FLAGS_MASK                ((1 << 23) - 1)
+#define LWS_FOP_FLAG_COMPR_ACCEPTABLE_GZIP (1 << 24)
+#define LWS_FOP_FLAG_COMPR_IS_GZIP        (1 << 25)
+
 struct lws_plat_file_ops {
        lws_filefd_type (*LWS_FOP_OPEN)(struct lws *wsi, const char *filename,
-                               unsigned long *filelen, int flags);
+                               unsigned long *filelen, int *flags);
        /**< Open file (always binary access if plat supports it)
         * filelen is filled on exit to be the length of the file
-        * flags should be set to O_RDONLY or O_RDWR */
+        * *flags & LWS_FOP_FLAGS_MASK should be set to O_RDONLY or O_RDWR.
+        * If the file may be gzip-compressed,
+        * LWS_FOP_FLAG_COMPR_ACCEPTABLE_GZIP is set.  If it actually is
+        * gzip-compressed, then the open handler should OR
+        * LWS_FOP_FLAG_COMPR_IS_GZIP on to *flags before returning.
+        */
        int (*LWS_FOP_CLOSE)(struct lws *wsi, lws_filefd_type fd);
        /**< close file */
        unsigned long (*LWS_FOP_SEEK_CUR)(struct lws *wsi, lws_filefd_type fd,
@@ -4223,7 +4232,7 @@ lws_get_fops(struct lws_context *context);
  */
 static LWS_INLINE lws_filefd_type LWS_WARN_UNUSED_RESULT
 lws_plat_file_open(struct lws *wsi, const char *filename,
-                  unsigned long *filelen, int flags)
+                  unsigned long *filelen, int *flags)
 {
        return lws_get_fops(lws_get_context(wsi))->LWS_FOP_OPEN(wsi, filename,
                                                    filelen, flags);
index 4065099..f1ef289 100644 (file)
@@ -167,7 +167,7 @@ delete_from_fd(struct lws_context *context, lws_sockfd_type fd)
 
 static lws_filefd_type
 _lws_plat_file_open(struct lws *wsi, const char *filename,
-                   unsigned long *filelen, int flags)
+                   unsigned long *filelen, int *flags)
 {
        (void)wsi;
        (void)filename;
index a480789..ca7e88d 100644 (file)
@@ -263,7 +263,7 @@ lws_plat_inet_ntop(int af, const void *src, char *dst, int cnt)
 
 static lws_filefd_type
 _lws_plat_file_open(struct lws *wsi, const char *filename,
-                   unsigned long *filelen, int flags)
+                   unsigned long *filelen, int *flags)
 {
        return 0;
 }
index 2625ed8..92d44c9 100644 (file)
@@ -611,10 +611,10 @@ lws_plat_inet_ntop(int af, const void *src, char *dst, int cnt)
 
 static lws_filefd_type
 _lws_plat_file_open(struct lws *wsi, const char *filename,
-                   unsigned long *filelen, int flags)
+                   unsigned long *filelen, int *flags)
 {
        struct stat stat_buf;
-       int ret = open(filename, flags, 0664);
+       int ret = open(filename, (*flags) & LWS_FOP_FLAGS_MASK, 0664);
 
        if (ret < 0)
                return LWS_INVALID_FILE;
index aabd4b7..7327ab8 100644 (file)
@@ -523,14 +523,14 @@ lws_plat_inet_ntop(int af, const void *src, char *dst, int cnt)
 
 static lws_filefd_type
 _lws_plat_file_open(struct lws *wsi, const char *filename,
-                       unsigned long *filelen, int flags)
+                       unsigned long *filelen, int *flags)
 {
        HANDLE ret;
        WCHAR buf[MAX_PATH];
 
        (void)wsi;
        MultiByteToWideChar(CP_UTF8, 0, filename, -1, buf, ARRAY_SIZE(buf));
-       if ((flags & 7) == _O_RDONLY) {
+       if (((*flags) & 7) == _O_RDONLY) {
                ret = CreateFileW(buf, GENERIC_READ, FILE_SHARE_READ,
                          NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
        } else {
index 82add22..d8ac711 100644 (file)
@@ -2143,14 +2143,21 @@ lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type,
        unsigned char *p = response;
        unsigned char *end = p + context->pt_serv_buf_size - LWS_PRE;
        unsigned long computed_total_content_length;
-       int ret = 0, cclen = 8, n = HTTP_STATUS_OK;
+       int ret = 0, cclen = 8, n = HTTP_STATUS_OK, fflags = O_RDONLY;
 #if defined(LWS_WITH_RANGES)
        int ranges;
 #endif
 
-       wsi->u.http.fd = lws_plat_file_open(wsi, file, &wsi->u.http.filelen,
-                                           O_RDONLY);
+       if (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_ACCEPT_ENCODING))
+               if (strstr("gzip",  lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_ACCEPT_ENCODING)) &&
+                   strstr("deflate",  lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_ACCEPT_ENCODING))) {
+                       lwsl_debug("client indicates GZIP is acceptable\n");
+                       fflags |= LWS_FOP_FLAG_COMPR_ACCEPTABLE_GZIP;
+               }
 
+
+       wsi->u.http.fd = lws_plat_file_open(wsi, file, &wsi->u.http.filelen,
+                                           &fflags);
        if (wsi->u.http.fd == LWS_INVALID_FILE) {
                lwsl_err("Unable to open '%s'\n", file);
 
@@ -2158,6 +2165,16 @@ lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type,
        }
        computed_total_content_length = wsi->u.http.filelen;
 
+       if ((fflags & (LWS_FOP_FLAG_COMPR_ACCEPTABLE_GZIP |
+                      LWS_FOP_FLAG_COMPR_IS_GZIP)) ==
+           (LWS_FOP_FLAG_COMPR_ACCEPTABLE_GZIP | LWS_FOP_FLAG_COMPR_IS_GZIP)) {
+               if (lws_add_http_header_by_token(wsi,
+                       WSI_TOKEN_HTTP_CONTENT_ENCODING,
+                       (unsigned char *)"gzip, deflate", 13, &p, end))
+                       return -1;
+               lwsl_debug("file is being provided in gzip\n");
+       }
+
 #if defined(LWS_WITH_RANGES)
        ranges = lws_ranges_init(wsi, rp, wsi->u.http.filelen);
 
index e7a2c9d..5dc25ed 100644 (file)
@@ -157,7 +157,7 @@ static const struct lws_extension exts[] = {
  */
 static lws_filefd_type
 test_server_fops_open(struct lws *wsi, const char *filename,
-                     unsigned long *filelen, int flags)
+                     unsigned long *filelen, int *flags)
 {
        lws_filefd_type n;
 
index 877e8ad..af28e7e 100644 (file)
@@ -128,7 +128,7 @@ static struct lws_protocols protocols[] = {
  */
 static lws_filefd_type
 test_server_fops_open(struct lws *wsi, const char *filename,
-                     unsigned long *filelen, int flags)
+                     unsigned long *filelen, int *flags)
 {
        lws_filefd_type n;