From 5e92f5a34d330e1ee6bbfea083fc79ef850d518e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Se=CC=81bastien=20Metrot?= Date: Fri, 21 Aug 2026 02:31:37 +0200 Subject: [PATCH] Expose the read-only file API on embedded-filesystem builds rr_filelist answered {err:1} on a USE_EMBEDDED_FILES build, so DWC and AxisControl showed a broken file browser. The whole file API in HttpResponder is gated on HAS_MASS_STORAGE, which USE_EMBEDDED_FILES turns off - but EmbeddedFiles.cpp implements the very MassStorage functions those endpoints call (FileExists, DirectoryExists, FindFirst, FindNext). The capability was there; only the HTTP layer hid it. fileinfo, filelist and files are now available when either backing store is present. upload, delete, move and mkdir stay mass-storage only, since an embedded filesystem is read-only. thumbnail also stays mass-storage only: it calls RepRap::GetFileFragment, which is not compiled for embedded builds, and enabling it failed at link time rather than cleanly. Two things worth recording: - the fallback for boards with neither store emitted {err:1}, which is not valid JSON. Clients report it as a parse error rather than as an error code. Now {"err":1}; - adding a rejection branch for the write endpoints pushed GetJsonResponse past the range of a Thumb branch and the link failed with "dangerous relocation". That function is close enough to the limit that it is worth knowing before adding anything to it. The write endpoints fall through to unknown-request handling instead. Duet3_MB6HC is byte-for-byte the same size afterwards (text 998468), so nothing changes on the mass-storage path. --- src/Networking/HttpResponder.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/Networking/HttpResponder.cpp b/src/Networking/HttpResponder.cpp index a29a8b71d..27402f516 100644 --- a/src/Networking/HttpResponder.cpp +++ b/src/Networking/HttpResponder.cpp @@ -566,7 +566,11 @@ bool HttpResponder::GetJsonResponse(const char *_ecv_array request, OutputBuffer response->printf("{\"buff\":%u}", httpInput->BufferSpaceLeft()); } } -#if HAS_MASS_STORAGE +// An embedded filesystem can be read and listed - EmbeddedFiles.cpp implements the MassStorage +// FileExists/DirectoryExists/FindFirst/FindNext used below - it just cannot be written to. Gating the +// whole file API on HAS_MASS_STORAGE therefore hid working functionality: rr_filelist answered {err:1} +// on an embedded-files build, so DWC and AxisControl showed an empty, broken file browser. +#if HAS_MASS_STORAGE || HAS_EMBEDDED_FILES else if (StringEqualsIgnoreCase(request, "fileinfo")) { const char *_ecv_array _ecv_null const nameVal = GetKeyValue("name"); @@ -608,6 +612,7 @@ bool HttpResponder::GetJsonResponse(const char *_ecv_array request, OutputBuffer const int maxItems = (maxVal == nullptr) ? -1 : StrToI32(maxVal, nullptr); response = reprap.GetFilesResponse(nullptr, dir, startAt, maxItems, flagDirs); // this may return nullptr } +#if HAS_MASS_STORAGE else if (StringEqualsIgnoreCase(request, "upload")) { response->printf("{\"err\":%d}", (uploadError) ? 1 : 0); @@ -643,6 +648,8 @@ bool HttpResponder::GetJsonResponse(const char *_ecv_array request, OutputBuffer } response->printf("{\"err\":%d}", (success) ? 0 : 1); } + // thumbnail stays mass-storage only: it calls RepRap::GetFileFragment, which is not compiled + // for an embedded filesystem, and enabling it produced a link failure rather than a clean error. else if (StringEqualsIgnoreCase(request, "thumbnail")) { const char *_ecv_array _ecv_null const nameVal = GetKeyValue("name"); @@ -658,6 +665,7 @@ bool HttpResponder::GetJsonResponse(const char *_ecv_array request, OutputBuffer response->copy("{\"err\":1}"); } } +#endif #else else if ( StringEqualsIgnoreCase(request, "fileinfo") || StringEqualsIgnoreCase(request, "upload") @@ -669,7 +677,7 @@ bool HttpResponder::GetJsonResponse(const char *_ecv_array request, OutputBuffer || StringEqualsIgnoreCase(request, "thumbnail") ) { - response->copy("{err:1}"); + response->copy("{\"err\":1}"); } #endif