Skip to content

Fix: bypass 512MB postMessage limit for file transfer and add file integrity checksum - #310

Merged
LiuLikeQian merged 6 commits into
Snapmaker:bugfix_syhfrom
SukiSunYuhang:bugfix_wcp
May 13, 2026
Merged

Fix: bypass 512MB postMessage limit for file transfer and add file integrity checksum#310
LiuLikeQian merged 6 commits into
Snapmaker:bugfix_syhfrom
SukiSunYuhang:bugfix_wcp

Conversation

@SukiSunYuhang

Copy link
Copy Markdown
  1. Add download URL for file transfer, bypassing 512MB postMessage limit
  2. Add checksum field for file integrity verification
  3. Add origin_size field
  4. Use URL-safe base64 for path encoding in /wcp_download/ route

Description

This PR addresses the file transfer failure for files larger than ~512MB. Previously,
both sw_GetFileStream and sw_GetActiveFile read entire file content into memory and
passed it through the WebView postMessage bridge, which has a hard limit around 512MB.
Files exceeding this size get silently truncated.

Changes

sw_GetFileStream

  • Replace in-memory file content transfer with a local HTTP download URL
  • Files are now served via HttpServer at /wcp_download/
  • The Flutter client downloads files via HTTP GET, avoiding the postMessage size limit

sw_GetActiveFile

  • Add origin_size (file size in bytes) and checksum fields to the response
  • Client can display file size and verify download integrity without extra requests

HttpServer

  • Add /wcp_download/ route that decodes URL-safe base64 back to the native file path
  • Add m_native_path flag to ResponseFile to skip UTF-8 encoding conversion for decoded paths
  • Add fallback path opening when native path fails

Checksum Algorithm

  • SHA-256 digest → standard Base64 (matching Flutter's base64Encode(sha256.convert(bytes).bytes))
  • Computed via streaming (64KB chunks) to handle large files without memory pressure

Tests

  • Verified sw_GetActiveFile returns correct file_name, file_path, origin_size, and checksum
  • Verified sw_GetFileStream returns a downloadable file_url
  • Downloaded a 16.7MB gcode file via the returned URL and verified SHA-256 checksum matches
  • Tested with is_zip=false on Windows 11

@
1. Add download URL for file transfer, bypassing 512MB postMessage limit
2. Add checksum field for file integrity verification
3. Add origin_size field
4. Use URL-safe base64 for path encoding in /wcp_download/ route
@
@
Fix: remove in-memory fallback and magic number

- Replace duplicated in-memory response logic with a simple retry
  using utf8_to_filesystem_encoding, then fall through to existing
  streaming path
- Replace char buf[64*1024] with static constexpr + std::string
@
Comment thread src/slic3r/GUI/SSWCP.cpp Outdated
auto& server = wxGetApp().m_page_http_server;
std::string b64 = base64_encode(file_path.data(), file_path.size());
for (auto& c : b64) {
if (c == '+') c = '-';

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line break;

Comment thread src/slic3r/GUI/SSWCP.cpp Outdated
std::string b64 = base64_encode(file_path.data(), file_path.size());
for (auto& c : b64) {
if (c == '+') c = '-';
else if (c == '/') c = '_';

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line break;

Comment thread src/slic3r/GUI/HttpServer.cpp Outdated
else if (c == '_') c = '/';
}
// Pad to multiple of 4 for base64 decode
while (b64.size() % 4 != 0) b64 += '=';

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line break;

Comment thread src/slic3r/GUI/HttpServer.cpp Outdated
// Decode URL-safe base64-encoded path: revert '-'→'+', '_'→'/', then pad
auto b64 = std::string(trimmed_url.substr(strlen(WCP_DOWNLOAD_PREFIX)).ToStdString(wxConvUTF8));
for (auto& c : b64) {
if (c == '-') c = '+';

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line break;

Comment thread src/slic3r/GUI/HttpServer.cpp Outdated
auto b64 = std::string(trimmed_url.substr(strlen(WCP_DOWNLOAD_PREFIX)).ToStdString(wxConvUTF8));
for (auto& c : b64) {
if (c == '-') c = '+';
else if (c == '_') c = '/';

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line break;

Comment thread src/slic3r/GUI/HttpServer.cpp Outdated

// Convert UTF-8 path to filesystem encoding (auto-adapts for Windows UTF-8 mode).
// If m_native_path is true, the path is already in system encoding (e.g., from base64 decode).
std::string system_file_path = m_native_path ? file_path : utf8_to_filesystem_encoding(file_path);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

on system langue setting to close utf8 support global language, and should pass for testing chinese path;

Comment thread src/slic3r/GUI/HttpServer.cpp Outdated
std::ifstream file(system_file_path, std::ios::binary);
if (!file && m_native_path) {
// Native path failed; retry with UTF-8 → filesystem encoding conversion
system_file_path = utf8_to_filesystem_encoding(file_path);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the same as above;

Comment thread src/slic3r/GUI/SSWCP.cpp Outdated
static std::string calc_sha256_base64(const std::string& file_path)
{
std::ifstream ifs(file_path, std::ios::binary);
if (!ifs.is_open()) return "";

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line break;

Comment thread src/slic3r/GUI/SSWCP.cpp Outdated
std::string zipname = generate_zip_path(oriname, targetname);
json res = get_or_create_zip_json(oriname, targetname, zipname);
wxGetApp().CallAfter([weak_self, res]() {
if (!self) return;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line break;

Comment thread src/slic3r/GUI/SSWCP.cpp Outdated
if (name_index == std::string::npos || path_index == std::string::npos) {
wxGetApp().CallAfter([weak_self]() {
auto self = weak_self.lock();
if (self) self->handle_general_fail();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line break;

Comment thread src/slic3r/GUI/SSWCP.cpp Outdated
if (self) {
self->m_res_data["name"] = res["zip_name"];
self->m_res_data["content"] = res["zip_data"];
if (!self) return;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line break;

Comment thread src/slic3r/GUI/SSWCP.cpp Outdated
} catch (std::exception&) {
wxGetApp().CallAfter([weak_self]() {
auto self = weak_self.lock();
if (self) self->handle_general_fail();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line break;

Comment thread src/slic3r/GUI/SSWCP.cpp Outdated
self->handle_general_fail();
return;
}
if (!self) return;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line break;

@
Fix: add missing line breaks for all if/else statements

Ensure consistent code style by adding proper braces and line breaks
to single-line if/else-if/else blocks across HttpServer.cpp and SSWCP.cpp.
@
@
Fix: add braces to single-line while statement
@
@
Fix: remove try-catch blocks in sw_GetFileStream and refactor file path encoding in ResponseFile

- SSWCP: Remove try-catch blocks added by PR Snapmaker#310 inside m_work_thread lambdas
  in sw_GetFileStream(), letting exceptions propagate naturally
- HttpServer: Refactor ResponseFile::write_response to use m_native_path flag
  for encoding decision, with fallback to raw path when conversion fails
@
@LiuLikeQian
LiuLikeQian merged commit c5b2393 into Snapmaker:bugfix_syh May 13, 2026
LiuLikeQian pushed a commit that referenced this pull request May 22, 2026
…display (#360)

* fix: downloadFileFromOrca fails when HTTP server port changes

When the default port 13619 is occupied, the HTTP server switches to an
alternative port. The C++ side correctly uses the dynamic port for loading
the Flutter UI page, but sw_GetActiveFile() did not include the "url"
field in its JSON response. The Flutter JS downloadFileFromOrca function
falls back to a hardcoded http://127.0.0.1:13619/localfile/... when the
url field is null, causing requests to time out.

Fix:
- Populate the "url" field with the actual port via get_page_http_port()
  in both the zip and non-zip branches of sw_GetActiveFile()
- Normalize Windows backslash path separators to forward slashes
- URL-encode the file path to handle spaces and non-ASCII characters
  consistently across all platforms

* @
1. Add download URL for file transfer, bypassing 512MB postMessage limit
2. Add checksum field for file integrity verification
3. Add origin_size field
4. Use URL-safe base64 for path encoding in /wcp_download/ route
@

* @
Fix: remove in-memory fallback and magic number

- Replace duplicated in-memory response logic with a simple retry
  using utf8_to_filesystem_encoding, then fall through to existing
  streaming path
- Replace char buf[64*1024] with static constexpr + std::string
@

* @
Fix: add missing line breaks for all if/else statements

Ensure consistent code style by adding proper braces and line breaks
to single-line if/else-if/else blocks across HttpServer.cpp and SSWCP.cpp.
@

* @
Fix: add braces to single-line while statement
@

* @
Fix: remove try-catch blocks in sw_GetFileStream and refactor file path encoding in ResponseFile

- SSWCP: Remove try-catch blocks added by PR #310 inside m_work_thread lambdas
  in sw_GetFileStream(), letting exceptions propagate naturally
- HttpServer: Refactor ResponseFile::write_response to use m_native_path flag
  for encoding decision, with fallback to raw path when conversion fails
@

* Fix: bypass 512MB postMessage limit for file transfer and add file integrity checksum (#310)

* @
1. Add download URL for file transfer, bypassing 512MB postMessage limit
2. Add checksum field for file integrity verification
3. Add origin_size field
4. Use URL-safe base64 for path encoding in /wcp_download/ route
@

* @
Fix: remove in-memory fallback and magic number

- Replace duplicated in-memory response logic with a simple retry
  using utf8_to_filesystem_encoding, then fall through to existing
  streaming path
- Replace char buf[64*1024] with static constexpr + std::string
@

* @
Fix: add missing line breaks for all if/else statements

Ensure consistent code style by adding proper braces and line breaks
to single-line if/else-if/else blocks across HttpServer.cpp and SSWCP.cpp.
@

* @
Fix: add braces to single-line while statement
@

* @
Fix: remove try-catch blocks in sw_GetFileStream and refactor file path encoding in ResponseFile

- SSWCP: Remove try-catch blocks added by PR #310 inside m_work_thread lambdas
  in sw_GetFileStream(), letting exceptions propagate naturally
- HttpServer: Refactor ResponseFile::write_response to use m_native_path flag
  for encoding decision, with fallback to raw path when conversion fails
@

* @
@ Add: cross-platform test scripts for port 13619 fallback verification
@

* Fix: update Flutter web resources and SSWCP.cpp refinement

- Replace Flutter web package with latest version from Flutter team
- Update SSWCP.cpp with related adjustments

* delete test case

---------

Co-authored-by: YukiMacMini <yukimacmini@YukiMacMinideMac-mini.local>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants