aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/api/dashboard/mod.rs6
-rw-r--r--src/api/mod.rs7
-rw-r--r--src/api/store.rs5
3 files changed, 17 insertions, 1 deletions
diff --git a/src/api/dashboard/mod.rs b/src/api/dashboard/mod.rs
index 2557906..db7efa3 100644
--- a/src/api/dashboard/mod.rs
+++ b/src/api/dashboard/mod.rs
@@ -619,7 +619,11 @@ async fn events(Extension(hub): Extension<Arc<Hub>>) -> impl IntoResponse {
}
}
};
- Sse::new(stream).keep_alive(KeepAlive::default())
+ (
+ // Through nginx too as it comes, not buffered (`operations.md`).
+ [(super::UNBUFFERED.0, super::UNBUFFERED.1)],
+ Sse::new(stream).keep_alive(KeepAlive::default()),
+ )
}
/// The node stops: the client may reconnect once it is back.
diff --git a/src/api/mod.rs b/src/api/mod.rs
index 9bb2bed..9bda84a 100644
--- a/src/api/mod.rs
+++ b/src/api/mod.rs
@@ -110,6 +110,13 @@ pub(crate) fn relay_only_router(
.with_state(relay)
}
+/// On a response that streams: a reverse proxy passes it on as it comes, not once it
+/// has buffered enough (nginx's `X-Accel-Buffering`).
+pub(crate) const UNBUFFERED: (axum::http::HeaderName, &str) = (
+ axum::http::HeaderName::from_static("x-accel-buffering"),
+ "no",
+);
+
/// An error answer: `{"error": message}` with `details`' fields added (`docs/openapi.yaml`,
/// `Error`).
pub(crate) fn error_response(
diff --git a/src/api/store.rs b/src/api/store.rs
index 2b21c83..eac3262 100644
--- a/src/api/store.rs
+++ b/src/api/store.rs
@@ -923,6 +923,11 @@ async fn stream(state: AppState, key: String, path: Vec<String>) -> Result<Respo
axum::http::header::CACHE_CONTROL,
HeaderValue::from_static("no-cache, no-transform"),
);
+ // Through nginx too as it comes, not buffered (`operations.md`).
+ response.headers_mut().insert(
+ super::UNBUFFERED.0,
+ HeaderValue::from_static(super::UNBUFFERED.1),
+ );
Ok(response)
}