mirror of
https://github.com/telemt/telemt.git
synced 2026-09-18 08:18:31 +03:00
WEB Debug + Trace
Co-Authored-By: brekotis <93345790+brekotis@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use hyper::header::{self, HeaderName, HeaderValue};
|
||||
use hyper::{Request, StatusCode};
|
||||
|
||||
use super::body::{CollectBodyError, CollectedBody, RequestBody, collect_body};
|
||||
use super::decoy::serve_decoy;
|
||||
use super::request::canonical_u64_header;
|
||||
use super::{
|
||||
HttpResponse, carrier_empty, carrier_headers, carrier_lane, full_response, insert_header,
|
||||
request_trace, service_unavailable,
|
||||
};
|
||||
use crate::config::WebRuntimeVhost;
|
||||
use crate::web::manager::{ManagerError, TokenHash, WebProcessRuntime};
|
||||
use crate::web::trace::{TraceDirection, TraceRoute};
|
||||
|
||||
/// Handles one authenticated long-poll downlink exchange.
|
||||
pub(super) async fn handle_down(
|
||||
request: Request<RequestBody>,
|
||||
runtime: Arc<WebProcessRuntime>,
|
||||
vhost: Arc<WebRuntimeVhost>,
|
||||
token_hash: TokenHash,
|
||||
) -> HttpResponse {
|
||||
if request.method() != hyper::Method::POST
|
||||
|| request.headers().contains_key(header::CONTENT_TYPE)
|
||||
{
|
||||
return serve_decoy(request, vhost, true, &runtime).await;
|
||||
}
|
||||
let Some(cursor) = canonical_u64_header(&request, "x-down-cursor") else {
|
||||
return serve_decoy(request, vhost, true, &runtime).await;
|
||||
};
|
||||
let Ok(session) = runtime.get_session(token_hash, &vhost.host) else {
|
||||
return serve_decoy(request, vhost, true, &runtime).await;
|
||||
};
|
||||
if let Some(trace) = request_trace(&request) {
|
||||
trace.set_route(TraceRoute::Downlink);
|
||||
trace.bind_identity(session.trace_identity());
|
||||
}
|
||||
let Some(lane_id) = carrier_lane(&request, session.carrier()) else {
|
||||
return serve_decoy(request, vhost, true, &runtime).await;
|
||||
};
|
||||
let CollectedBody {
|
||||
request,
|
||||
body,
|
||||
_body_budget,
|
||||
} = match collect_body(request, &runtime, 1, true).await {
|
||||
Ok(result) => result,
|
||||
Err(CollectBodyError::Limit) => return service_unavailable(),
|
||||
Err(CollectBodyError::Invalid(request)) => {
|
||||
return serve_decoy(request, vhost, true, &runtime).await;
|
||||
}
|
||||
};
|
||||
if !body.is_empty() {
|
||||
return serve_decoy(request, vhost, true, &runtime).await;
|
||||
}
|
||||
let _lane_poll = if lane_id.is_some() {
|
||||
let Some(permit) = runtime.try_lane_poll() else {
|
||||
return service_unavailable();
|
||||
};
|
||||
Some(permit)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let result = match lane_id {
|
||||
Some(lane_id) => session.poll_down_lane(lane_id, cursor).await,
|
||||
None => session.poll_down(cursor).await,
|
||||
};
|
||||
match result {
|
||||
Ok(result) if result.body.is_empty() => {
|
||||
let mut response = carrier_empty(StatusCode::NO_CONTENT);
|
||||
insert_header(
|
||||
&mut response,
|
||||
HeaderName::from_static("x-down-cursor"),
|
||||
&result.next_cursor.to_string(),
|
||||
);
|
||||
if result.lane_closed {
|
||||
response.headers_mut().insert(
|
||||
HeaderName::from_static("x-lane-closed"),
|
||||
HeaderValue::from_static("1"),
|
||||
);
|
||||
}
|
||||
response
|
||||
}
|
||||
Ok(result) => {
|
||||
if let Some(trace) = request_trace(&request) {
|
||||
trace.record_frames(
|
||||
TraceDirection::Response,
|
||||
&result.body,
|
||||
&runtime.active_generation().config().web.limits,
|
||||
);
|
||||
}
|
||||
let mut response = full_response(StatusCode::OK, result.body);
|
||||
carrier_headers(&mut response);
|
||||
insert_header(
|
||||
&mut response,
|
||||
HeaderName::from_static("x-down-cursor"),
|
||||
&result.next_cursor.to_string(),
|
||||
);
|
||||
response
|
||||
}
|
||||
Err(ManagerError::Concurrent | ManagerError::Backpressure | ManagerError::Limit) => {
|
||||
service_unavailable()
|
||||
}
|
||||
Err(_) => serve_decoy(request, vhost, true, &runtime).await,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user