diff --git a/lib/roles/http/server/server.c b/lib/roles/http/server/server.c index 90a05f9c8..763d8b812 100644 --- a/lib/roles/http/server/server.c +++ b/lib/roles/http/server/server.c @@ -2339,6 +2339,11 @@ lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type, return !wsi->http2_substream; } } + + /* + * Caution... wsi->http.fop_fd is live from here + */ + wsi->http.filelen = lws_vfs_get_length(wsi->http.fop_fd); total_content_length = wsi->http.filelen; @@ -2358,7 +2363,7 @@ lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type, lws_return_http_status(wsi, HTTP_STATUS_REQ_RANGE_NOT_SATISFIABLE, NULL); if (lws_http_transaction_completed(wsi)) - return -1; /* <0 means just hang up */ + goto bail; /* <0 means just hang up */ lws_vfs_file_close(&wsi->http.fop_fd); @@ -2369,7 +2374,7 @@ lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type, #endif if (lws_add_http_header_status(wsi, n, &p, end)) - return -1; + goto bail; if ((wsi->http.fop_fd->flags & (LWS_FOP_FLAG_COMPR_ACCEPTABLE_GZIP | LWS_FOP_FLAG_COMPR_IS_GZIP)) == @@ -2377,7 +2382,7 @@ lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type, if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_CONTENT_ENCODING, (unsigned char *)"gzip", 4, &p, end)) - return -1; + goto bail; lwsl_info("file is being provided in gzip\n"); } #if defined(LWS_WITH_HTTP_STREAM_COMPRESSION) @@ -2406,7 +2411,7 @@ lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type, (unsigned char *)content_type, (int)strlen(content_type), &p, end)) - return -1; + goto bail; #if defined(LWS_WITH_RANGES) if (ranges >= 2) { /* multipart byteranges */ @@ -2419,7 +2424,7 @@ lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type, "multipart/byteranges; " "boundary=_lws", 20, &p, end)) - return -1; + goto bail; /* * our overall content length has to include @@ -2465,14 +2470,14 @@ lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type, WSI_TOKEN_HTTP_CONTENT_RANGE, (unsigned char *)cache_control, n, &p, end)) - return -1; + goto bail; } wsi->http.range.inside = 0; if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_ACCEPT_RANGES, (unsigned char *)"bytes", 5, &p, end)) - return -1; + goto bail; #endif if (!wsi->http2_substream) { @@ -2488,7 +2493,7 @@ lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type, */ if (lws_add_http_header_content_length(wsi, total_content_length, &p, end)) - return -1; + goto bail; } else { #if defined(LWS_WITH_HTTP_STREAM_COMPRESSION) @@ -2506,7 +2511,7 @@ lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type, WSI_TOKEN_HTTP_TRANSFER_ENCODING, (unsigned char *)"chunked", 7, &p, end)) - return -1; + goto bail; /* * ...this is fun, isn't it :-) For h1 that is @@ -2546,24 +2551,24 @@ lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type, if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_CACHE_CONTROL, (unsigned char *)cc, cclen, &p, end)) - return -1; + goto bail; } if (other_headers) { if ((end - p) < other_headers_len) - return -1; + goto bail; memcpy(p, other_headers, other_headers_len); p += other_headers_len; } if (lws_finalize_http_header(wsi, &p, end)) - return -1; + goto bail; ret = lws_write(wsi, response, p - response, LWS_WRITE_HTTP_HEADERS); if (ret != (p - response)) { lwsl_err("_write returned %d from %ld\n", ret, (long)(p - response)); - return -1; + goto bail; } wsi->http.filepos = 0; @@ -2571,8 +2576,9 @@ lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type, if (lws_hdr_total_length(wsi, WSI_TOKEN_HEAD_URI)) { /* we do not emit the body */ + lws_vfs_file_close(&wsi->http.fop_fd); if (lws_http_transaction_completed(wsi)) - return -1; + goto bail; return 0; } @@ -2580,6 +2586,11 @@ lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type, lws_callback_on_writable(wsi); return 0; + +bail: + lws_vfs_file_close(&wsi->http.fop_fd); + + return -1; } #endif