From 879462a2437aeee07a6fc266eb7ed44e38a542f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20M=2E=20Pi=C3=B1eiro?= Date: Fri, 22 Aug 2025 18:42:21 +0200 Subject: [PATCH 1/3] Refactor AsyncFileResponse (File overload) This PR refactors a single overload of the AsyncFileResponse constructor. The changes improve speed, readability and maintainability by: - Replacing the strlen(contentType) == 0 check - Restructuring the logic for setting the Content-Disposition header. Explicitly separates inline serving from download attachments. - Not altering behavior. --- src/WebResponses.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/WebResponses.cpp b/src/WebResponses.cpp index f5c4eef0a..3ab33b58e 100644 --- a/src/WebResponses.cpp +++ b/src/WebResponses.cpp @@ -764,22 +764,23 @@ AsyncFileResponse::AsyncFileResponse(File content, const String &path, const cha _content = content; _contentLength = _content.size(); - if (strlen(contentType) == 0) { + if (*contentType == '\0') { _setContentTypeFromPath(path); } else { _contentType = contentType; } - int filenameStart = path.lastIndexOf('/') + 1; - char buf[26 + path.length() - filenameStart]; - char *filename = (char *)path.c_str() + filenameStart; - if (download) { - snprintf_P(buf, sizeof(buf), PSTR("attachment; filename=\"%s\""), filename); + // Extract filename from path and set as download attachment + int filenameStart = path.lastIndexOf('/') + 1; + char buf[26 + path.length() - filenameStart]; + char *filename = (char *)path.c_str() + filenameStart; + snprintf(buf, sizeof(buf), T_attachment, filename); + addHeader(T_Content_Disposition, buf, false); } else { - snprintf_P(buf, sizeof(buf), PSTR("inline")); + // Serve file inline (display in browser) + addHeader(T_Content_Disposition, T_inline, false); } - addHeader(T_Content_Disposition, buf, false); } size_t AsyncFileResponse::_fillBuffer(uint8_t *data, size_t len) { From 1d81c9c021a9cd47c939e7df0981d710383b306d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20M=2E=20Pi=C3=B1eiro?= Date: Sat, 23 Aug 2025 21:05:34 +0200 Subject: [PATCH 2/3] Mathieucarbou's suggestion was implemented used Arduino String + reserve() + heap allocation --- src/WebResponses.cpp | 18 ++++++++++++------ src/literals.h | 2 +- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/WebResponses.cpp b/src/WebResponses.cpp index 228dafdcf..410ed17ca 100644 --- a/src/WebResponses.cpp +++ b/src/WebResponses.cpp @@ -738,9 +738,12 @@ AsyncFileResponse::AsyncFileResponse(FS &fs, const String &path, const char *con if (download) { // Extract filename from path and set as download attachment int filenameStart = path.lastIndexOf('/') + 1; - char buf[26 + path.length() - filenameStart]; - char *filename = (char *)path.c_str() + filenameStart; - snprintf(buf, sizeof(buf), T_attachment, filename); + const char *filename = path.c_str() + filenameStart; + String buf; + buf.reserve(strlen(T_attachment) + strlen(filename) + 2); + buf = T_attachment; + buf += filename; + buf += "\""; addHeader(T_Content_Disposition, buf, false); } else { // Serve file inline (display in browser) @@ -773,9 +776,12 @@ AsyncFileResponse::AsyncFileResponse(File content, const String &path, const cha if (download) { // Extract filename from path and set as download attachment int filenameStart = path.lastIndexOf('/') + 1; - char buf[26 + path.length() - filenameStart]; - char *filename = (char *)path.c_str() + filenameStart; - snprintf(buf, sizeof(buf), T_attachment, filename); + const char *filename = path.c_str() + filenameStart; + String buf; + buf.reserve(strlen(T_attachment) + strlen(filename) + 2); + buf = T_attachment; + buf += filename; + buf += "\""; addHeader(T_Content_Disposition, buf, false); } else { // Serve file inline (display in browser) diff --git a/src/literals.h b/src/literals.h index 055e83a5a..577be6900 100644 --- a/src/literals.h +++ b/src/literals.h @@ -12,7 +12,7 @@ static constexpr const char *T_100_CONTINUE = "100-continue"; static constexpr const char *T_13 = "13"; static constexpr const char *T_ACCEPT = "Accept"; static constexpr const char *T_Accept_Ranges = "Accept-Ranges"; -static constexpr const char *T_attachment = "attachment; filename=\"%s\""; +static constexpr const char *T_attachment = "attachment; filename=\""; static constexpr const char *T_AUTH = "Authorization"; static constexpr const char *T_auth_nonce = "\", qop=\"auth\", nonce=\""; static constexpr const char *T_BASIC = "Basic"; From 149d7ca45a48fa9b9d28804700489631b3f2e60b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci-lite[bot]" <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Date: Mon, 25 Aug 2025 11:49:07 +0000 Subject: [PATCH 3/3] ci(pre-commit): Apply automatic fixes --- src/WebResponses.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/WebResponses.cpp b/src/WebResponses.cpp index 410ed17ca..71158854b 100644 --- a/src/WebResponses.cpp +++ b/src/WebResponses.cpp @@ -741,7 +741,7 @@ AsyncFileResponse::AsyncFileResponse(FS &fs, const String &path, const char *con const char *filename = path.c_str() + filenameStart; String buf; buf.reserve(strlen(T_attachment) + strlen(filename) + 2); - buf = T_attachment; + buf = T_attachment; buf += filename; buf += "\""; addHeader(T_Content_Disposition, buf, false); @@ -779,7 +779,7 @@ AsyncFileResponse::AsyncFileResponse(File content, const String &path, const cha const char *filename = path.c_str() + filenameStart; String buf; buf.reserve(strlen(T_attachment) + strlen(filename) + 2); - buf = T_attachment; + buf = T_attachment; buf += filename; buf += "\""; addHeader(T_Content_Disposition, buf, false);