v0.24.5
This commit is contained in:
commit
5e23e9af02
240 files changed
+99957
No files matched your search
+108
@@ -0,0 +1,108 @@
|
||||
//! Separate opt-in HTTP backend, not a shortcut inside the proxy handler.
|
||||
use axum::{
|
||||
body::Body,
|
||||
extract::Request,
|
||||
response::{Html, IntoResponse, Response},
|
||||
routing::{any, get},
|
||||
Json, Router,
|
||||
};
|
||||
use bytes::Bytes;
|
||||
use http::HeaderMap;
|
||||
use serde_json::json;
|
||||
use std::{convert::Infallible, time::Duration};
|
||||
pub fn router() -> Router {
|
||||
Router::new()
|
||||
.route(
|
||||
"/",
|
||||
get(|| async { Html(include_str!("admin/web/demo.html")) }),
|
||||
)
|
||||
.route("/ws", get(websocket))
|
||||
.route("/cache-demo", get(cache_demo))
|
||||
.route("/inspect", any(inspect))
|
||||
.route("/echo", any(echo))
|
||||
.route("/stream", get(stream))
|
||||
.fallback(|| async {
|
||||
Json(json!({"backend":"demo","message":"Request reached the separate demo backend."}))
|
||||
})
|
||||
}
|
||||
async fn inspect(request: Request) -> Json<serde_json::Value> {
|
||||
let headers = request.headers();
|
||||
let read = |name: &str| {
|
||||
headers
|
||||
.get(name)
|
||||
.and_then(|v| v.to_str().ok())
|
||||
.unwrap_or("")
|
||||
.to_owned()
|
||||
};
|
||||
Json(
|
||||
json!({"backend":"demo", "method":request.method().as_str(), "path":request.uri().path(),
|
||||
"query":request.uri().query(), "http_version":format!("{:?}", request.version()), "host":read("host"), "forwarded_for":read("x-forwarded-for"),
|
||||
"forwarded_proto":read("x-forwarded-proto"), "request_id":read("x-request-id")}),
|
||||
)
|
||||
}
|
||||
async fn echo(request: Request) -> Response {
|
||||
let content_type = request.headers().get("content-type").cloned();
|
||||
let mut response = request.into_body().into_response();
|
||||
if let Some(value) = content_type {
|
||||
response.headers_mut().insert("content-type", value);
|
||||
}
|
||||
response
|
||||
}
|
||||
async fn stream() -> (HeaderMap, Body) {
|
||||
let stream = futures_util::stream::unfold(0u32, |index| async move {
|
||||
if index >= 8 {
|
||||
return None;
|
||||
}
|
||||
tokio::time::sleep(Duration::from_millis(300)).await;
|
||||
Some((
|
||||
Ok::<_, Infallible>(Bytes::from(format!(
|
||||
"chunk={} backend=demo streaming=true\n",
|
||||
index + 1
|
||||
))),
|
||||
index + 1,
|
||||
))
|
||||
});
|
||||
let mut headers = HeaderMap::new();
|
||||
headers.insert("content-type", "text/plain; charset=utf-8".parse().unwrap());
|
||||
headers.insert("cache-control", "no-store".parse().unwrap());
|
||||
(headers, Body::from_stream(stream))
|
||||
}
|
||||
|
||||
async fn websocket(ws: axum::extract::ws::WebSocketUpgrade) -> Response {
|
||||
use axum::extract::ws::Message;
|
||||
ws.max_message_size(65_536)
|
||||
.max_frame_size(65_536)
|
||||
.on_upgrade(|mut socket| async move {
|
||||
while let Some(Ok(message)) = socket.recv().await {
|
||||
let reply = match message {
|
||||
Message::Text(_) | Message::Binary(_) => message,
|
||||
Message::Ping(data) => Message::Pong(data),
|
||||
Message::Pong(_) => continue,
|
||||
Message::Close(frame) => {
|
||||
let _ = socket.send(Message::Close(frame)).await;
|
||||
break;
|
||||
}
|
||||
};
|
||||
if socket.send(reply).await.is_err() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Explicitly public demo object for manual cache/compression checks; no request secrets.
|
||||
async fn cache_demo() -> Response {
|
||||
let now = crate::logging::now_ms();
|
||||
let text = format!(
|
||||
"RustProxy public cache demo. Origin generation time: {now} ms\n{}",
|
||||
"This is an anonymous demo object, fresh for 30 seconds.\n".repeat(100)
|
||||
);
|
||||
(
|
||||
[
|
||||
("cache-control", "public, max-age=30"),
|
||||
("content-type", "text/plain; charset=utf-8"),
|
||||
],
|
||||
text,
|
||||
)
|
||||
.into_response()
|
||||
}
|
||||
Reference in new issue
Block a user