feat(web): per-device file tunnel for devicefile/uploadnodefile/uploadfilebatch (VS-3) #45
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/device-file-tunnel-vs-3"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Implements VS-3: one per-device file-tunnel allocator, and the three legacy HTTP file endpoints wired onto it.
Allocator
device_file::open_file_tunnel()follows the proven mcp_gateway pattern: stash oneSideof an in-process relay pair inmesh_relaysunder a randomfile-<rand>id, mint a 60-second node-scopedrauthcookie, sendmsg/tunnel(usage=5,tunnel_mode::FILE_TRANSFER) over the agent's control WS with the*-prefixed relay URL, then wait for the rendezvous'c'before returning. The agent's existingrun_filesloop answers; zero agent-side changes.Endpoints (all with
/:domain/mirrors)GET /devicefile.ashx?agent_id=<node>&path=<abs>(aliasesnodeid/n,f): streams the file as anattachmentdownload, one ack per 4-byte-header chunk, agentcancelmaps to 404. No Content-Length; a mid-stream failure surfaces as a truncated chunked body.POST /uploadnodefile.ashx?agent_id=<node>&path=<dir>: replays multipart file parts over one tunnel (upload/uploadstart/uploadack/uploaddone), applying the SPA's0x00escape for chunks starting with'{'or0x00. Filenames are sanitized to their basename.POST /uploadfilebatch.ashx?agent_ids=<a,b,c>&path=<dir>(aliasnodeids): spools parts to temp files once (cleaned up on every return path via Drop), then pushes to each device over a fresh tunnel; per-node failures land in the JSON result map without aborting the batch.Decisions (resolve the issue's open question)
REMOTE_CONTROLon the node's mesh required,NO_FILESrestriction denies, mesh ADMIN and full site-admins pass (upstream parity plus the file-restriction bit).Acceptance criteria
run_files(rendezvous handshake, protocol digit, end-bit chunk rule, escape strip).download_works_via_per_domain_mirror.download_streams_file_end_to_end(40 bytes across three chunks, asserts headers, body, and zero orphaned rendezvous stashes).Plus: two-node batch fan-out test, byte-for-byte upload assertion including the escape rule, and 401/403/503 gate tests. Upload routes carry a 1 GiB
DefaultBodyLimitmatching the agent's per-transfer ceiling.cargo test --workspace,cargo fmt --check, andcargo clippy --workspace --all-targetsare clean.Resolves VS-3.
Adds crates/meshcentral-web/src/device_file.rs: open_file_tunnel() stashes one side of an in-process relay pair in mesh_relays, mints a 60s node-scoped rauth cookie, sends msg/tunnel (usage=5, FILE_TRANSFER) over the agent's control WS, and waits for the rendezvous 'c' before handing back a FileTunnel that speaks the agent's run_files protocol through the meshrelay text/binary tag framing. Built on it, three 501 hints become real handlers, each with a per-domain mirror: - GET /devicefile.ashx?agent_id&path streams the file back as an attachment, one download ack per 4-byte-header chunk, agent open failures map to 404. - POST /uploadnodefile.ashx?agent_id&path replays multipart file parts over one tunnel via upload/uploadstart/uploadack/uploaddone, applying the 0x00 escape for chunks starting with '{' or 0x00. - POST /uploadfilebatch.ashx?agent_ids&path spools the parts to temp files once, then fans out to every listed device over a fresh tunnel each; per-node failures land in the result map instead of aborting the batch. AuthZ per the VS-3 decision: REMOTE_CONTROL required on the node's mesh and the NO_FILES restriction denies; mesh ADMIN and site-admins pass. The multipart endpoints reuse the agent's existing tunnel upload lifecycle (the issue's open question, resolved with niceguyit) so no agent-side changes are needed. Upload routes get a 1 GiB DefaultBodyLimit matching the agent's per-transfer ceiling. meshrelay's frame tags become pub(crate) for the tunnel driver; reqwest dev-dep grows the multipart feature. Integration tests stand up the full router with a stub agent that mirrors vervain-agent's run_files loop (rendezvous handshake, protocol digit, end-bit chunking, escape strip): download round-trip incl. per-domain mirror and 404 mapping, single and two-node multipart uploads byte-for-byte, plus 401/403/503 gates. #VS-3