server: vfs: make sure handle freed if problems while setting up file transfer
https://github.com/warmcat/libwebsockets/issues/1765
diff --git a/lib/roles/http/server/server.c b/lib/roles/http/server/server.c
index 04d12fe..fa2c408 100644
--- a/lib/roles/http/server/server.c
+++ b/lib/roles/http/server/server.c
@@ -2369,6 +2369,11 @@
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;
@@ -2388,7 +2393,7 @@
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);
@@ -2399,7 +2404,7 @@
#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)) ==
@@ -2407,7 +2412,7 @@
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)
@@ -2436,7 +2441,7 @@
(unsigned char *)content_type,
(int)strlen(content_type),
&p, end))
- return -1;
+ goto bail;
#if defined(LWS_WITH_RANGES)
if (ranges >= 2) { /* multipart byteranges */
@@ -2449,7 +2454,7 @@
"multipart/byteranges; "
"boundary=_lws",
20, &p, end))
- return -1;
+ goto bail;
/*
* our overall content length has to include
@@ -2495,14 +2500,14 @@
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) {
@@ -2518,7 +2523,7 @@
*/
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)
@@ -2536,7 +2541,7 @@
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
@@ -2576,24 +2581,24 @@
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;
@@ -2601,8 +2606,9 @@
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;
}
@@ -2610,6 +2616,11 @@
lws_callback_on_writable(wsi);
return 0;
+
+bail:
+ lws_vfs_file_close(&wsi->http.fop_fd);
+
+ return -1;
}
#endif