MCPcopy Create free account
hub / github.com/bdring/FluidNC / myStreamFile

Method myStreamFile

FluidNC/src/WebUI/WebUIServer.cpp:276–399  ·  view source on GitHub ↗

Send a file, either the specified path or path.gz

Source from the content-addressed store, hash-verified

274 }
275 // Send a file, either the specified path or path.gz
276 bool WebUI_Server::myStreamFile(AsyncWebServerRequest* request, const char* path, bool download, bool setSession) {
277 std::error_code ec;
278 FluidPath fpath { path, LocalFS, ec };
279 if (ec) {
280 return false;
281 }
282
283 bool acceptGz = false;
284 if (request->hasHeader("Accept-Encoding")) {
285 auto encodings = std::string(request->getHeader("Accept-Encoding")->value().c_str());
286 if (encodings.find("gzip") != std::string::npos) {
287 acceptGz = true;
288 }
289 }
290
291 std::string hash;
292
293 // If you load or reload WebUI while a program is running, there is a high
294 // risk of stalling the motion because serving a file from
295 // the local FLASH filesystem takes away a lot of CPU cycles. If we get
296 // a request for a file when running, reject it to preserve the motion
297 // integrity.
298 // This can make it hard to debug ISR IRAM problems, because the easiest
299 // way to trigger such problems is to refresh WebUI during motion.
300 if (http_block_during_motion->get() && inMotionState()) {
301 // Check to see if we have a cached hash of the file that can be retrieved without accessing FLASH
302 hash = HashFS::hash(fpath, true);
303 if (!hash.length() && acceptGz) {
304 std::filesystem::path gzpath(fpath);
305 gzpath += ".gz";
306 hash = HashFS::hash(gzpath, true);
307 }
308
309 if (hash.length() && request->hasHeader("If-None-Match") &&
310 std::string(request->getHeader("If-None-Match")->value().c_str()) == hash) {
311 request->send(304);
312 return true;
313 }
314
315 WebUI_Server::handleReloadBlocked(request);
316 return true;
317 }
318
319 // Check for browser cache match
320 hash = HashFS::hash(fpath);
321 if (!hash.length() && acceptGz) {
322 std::filesystem::path gzpath(fpath);
323 gzpath += ".gz";
324 hash = HashFS::hash(gzpath);
325 }
326 if (hash.length() && request->hasHeader("If-None-Match") &&
327 std::string(request->getHeader("If-None-Match")->value().c_str()) == hash) {
328 if (setSession && getSessionCookie(request) == "") {
329 char session[9];
330 get_random_string(session, sizeof(session) - 1);
331 AsyncWebServerResponse* response = request->beginResponse(304);
332 response->addHeader("Set-Cookie", ("sessionId=" + std::string(session)).c_str());
333 request->send(response);

Callers

nothing calls this directly

Calls 11

inMotionStateFunction · 0.85
get_random_stringFunction · 0.85
getContentTypeFunction · 0.85
c_strMethod · 0.80
lengthMethod · 0.80
valueMethod · 0.45
findMethod · 0.45
getMethod · 0.45
sizeMethod · 0.45
closeMethod · 0.45
readMethod · 0.45

Tested by

no test coverage detected