#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,
*/
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);
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;
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;
}
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;
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 {
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);
}
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);
*/
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;
*/
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;