fix(upload): raise body-size limit to 512 MiB + surface upload errors
CI / Check (pull_request) Successful in 5m40s
CI / Detect Changes (pull_request) Has been skipped
CI / Deploy Agent (pull_request) Has been skipped
CI / Deploy Dashboard (pull_request) Has been skipped
CI / Deploy Docs (pull_request) Has been skipped
CI / Deploy MCP (pull_request) Has been skipped
CI / Check (pull_request) Successful in 5m40s
CI / Detect Changes (pull_request) Has been skipped
CI / Deploy Agent (pull_request) Has been skipped
CI / Deploy Dashboard (pull_request) Has been skipped
CI / Deploy Docs (pull_request) Has been skipped
CI / Deploy MCP (pull_request) Has been skipped
Artifact uploads (PLC .projectarchive, firmware images, mobile packages) larger than axum's 2 MiB default request-body limit were rejected, and the wizard swallowed the error (`let _ = upload_target_artifact`), so the target was created with no artifact — every scan then showed "blocked, no artifact provided". - agent: DefaultBodyLimit::max(512 MiB) on the API router (multipart upload route). - dashboard: DefaultBodyLimit::max(512 MiB) on the axum app serving the upload server function (the browser→dashboard hop). - wizard: surface upload failures in the error banner instead of ignoring them. Found live: a 9.9 MB CODESYS .projectarchive failed to attach (a 1.7 KB .st worked). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
55e4117369
commit
ee0efe5e22
@@ -1,6 +1,6 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use axum::extract::Request;
|
use axum::extract::{DefaultBodyLimit, Request};
|
||||||
use axum::http::HeaderValue;
|
use axum::http::HeaderValue;
|
||||||
use axum::middleware::Next;
|
use axum::middleware::Next;
|
||||||
use axum::response::Response;
|
use axum::response::Response;
|
||||||
@@ -74,6 +74,9 @@ pub async fn start_api_server(agent: ComplianceAgent, port: u16) -> Result<(), A
|
|||||||
|
|
||||||
let mut app = routes::build_router()
|
let mut app = routes::build_router()
|
||||||
.merge(admin_router)
|
.merge(admin_router)
|
||||||
|
// Allow large artifact uploads (PLC .projectarchive, firmware images,
|
||||||
|
// mobile packages) — axum's default request-body limit is only 2 MiB.
|
||||||
|
.layer(DefaultBodyLimit::max(512 * 1024 * 1024))
|
||||||
.layer(Extension(Arc::new(agent.clone())))
|
.layer(Extension(Arc::new(agent.clone())))
|
||||||
.layer(CorsLayer::permissive())
|
.layer(CorsLayer::permissive())
|
||||||
.layer(TraceLayer::new_for_http())
|
.layer(TraceLayer::new_for_http())
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use axum::extract::DefaultBodyLimit;
|
||||||
use axum::routing::{get, post};
|
use axum::routing::{get, post};
|
||||||
use axum::{middleware, Extension};
|
use axum::{middleware, Extension};
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
@@ -66,6 +67,9 @@ pub fn server_start(app: fn() -> Element) -> Result<(), DashboardError> {
|
|||||||
// Webhook proxy: forward to agent (no auth required)
|
// Webhook proxy: forward to agent (no auth required)
|
||||||
.route("/webhook/{platform}/{repo_id}", post(webhook_proxy))
|
.route("/webhook/{platform}/{repo_id}", post(webhook_proxy))
|
||||||
.serve_dioxus_application(ServeConfig::new(), app)
|
.serve_dioxus_application(ServeConfig::new(), app)
|
||||||
|
// Allow large artifact uploads through the upload server function
|
||||||
|
// (PLC .projectarchive, firmware, mobile) — default is 2 MiB.
|
||||||
|
.layer(DefaultBodyLimit::max(512 * 1024 * 1024))
|
||||||
.layer(Extension(PendingOAuthStore::default()))
|
.layer(Extension(PendingOAuthStore::default()))
|
||||||
.layer(middleware::from_fn(require_auth))
|
.layer(middleware::from_fn(require_auth))
|
||||||
.layer(Extension(server_state))
|
.layer(Extension(server_state))
|
||||||
|
|||||||
@@ -520,14 +520,20 @@ pub fn OnboardingPage() -> Element {
|
|||||||
created_id.set(Some(id.clone()));
|
created_id.set(Some(id.clone()));
|
||||||
// Upload staged file artifacts now that the target exists.
|
// Upload staged file artifacts now that the target exists.
|
||||||
for pf in files {
|
for pf in files {
|
||||||
let _ = upload_target_artifact(
|
let fname = pf.filename.clone();
|
||||||
|
if let Err(e) = upload_target_artifact(
|
||||||
id.clone(),
|
id.clone(),
|
||||||
pf.kind,
|
pf.kind,
|
||||||
pf.plc_format,
|
pf.plc_format,
|
||||||
pf.filename,
|
pf.filename,
|
||||||
pf.bytes,
|
pf.bytes,
|
||||||
)
|
)
|
||||||
.await;
|
.await
|
||||||
|
{
|
||||||
|
error.set(Some(format!(
|
||||||
|
"Upload failed for {fname}: {e}"
|
||||||
|
)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if let Ok(sc) = fetch_applicable_scans(id.clone()).await {
|
if let Ok(sc) = fetch_applicable_scans(id.clone()).await {
|
||||||
scans.set(sc.data.scans);
|
scans.set(sc.data.scans);
|
||||||
|
|||||||
Reference in New Issue
Block a user