1pub mod auth;
2pub mod client;
3pub mod content_encryption;
4pub mod devserver;
5pub mod extract;
6pub mod log;
7pub mod metrics;
8pub mod middleware;
9pub mod recovery;
10pub mod resilience;
11pub mod response;
12pub mod route;
13pub mod security;
14pub mod server;
15pub mod sse;
16pub mod static_assets;
17pub mod trace;
18
19pub use actix_cors::Cors;
20pub use auth::{encode_hs256, BearerAuth, JwtAuth, JwtError, RequestSignatureAuth};
21pub use client::{HttpClient, HttpClientConfig, HttpClientError};
22pub use content_encryption::{
23 ContentEncryption, ContentEncryptionError, ContentEncryptionKey, ContentKeyProvider,
24 StaticContentKeyProvider, CONTENT_ENCRYPTION_HEADER, CONTENT_KEY_ID_HEADER,
25};
26pub use devserver::{DevServer, DevServerConfig};
27pub use extract::{
28 FromRequestHeaders, MultipartConfig, MultipartForm, RequestExtractionError, UploadedFile,
29 ValidatedForm, ValidatedHeader, ValidatedJson, ValidatedPath, ValidatedQuery, ValidatedRequest,
30};
31pub use log::{LoggingMiddleware, StructuredLogging};
32pub use metrics::{HttpClientMetrics, HttpMetrics, MetricsMiddleware};
33pub use middleware::{AdaptiveLoadShed, ConcurrencyLimit, RateLimit, RequestBodyLimit, Timeout};
34pub use recovery::Recover;
35pub use resilience::{RequestId, RequestIdValue};
36pub use response::{grpc_status_to_http, streaming_response, ApiError, ResponsePolicy};
37pub use route::{
38 RouteGroupConfig, RouteJwtConfig, RouteMiddleware, RouteMiddlewareFuture, RouteMiddlewareNext,
39 RoutePolicyConfig,
40};
41pub use rust_zero_core::{
42 sign_request, AuthFailure, JwtClaimProjection, RequestSignature, RequestSignatureVerifier,
43 AUTH_KEY_ID_HEADER, AUTH_SIGNATURE_HEADER, AUTH_TIMESTAMP_HEADER,
44};
45pub use security::SecurityHeaders;
46pub use server::{
47 RestServer, RestServerConfig, RestServerConfigError, ServerlessHandler, ServerlessRequest,
48 ServerlessResponse,
49};
50pub use sse::{sse_response, SseEvent};
51pub use static_assets::{EmbeddedAsset, StaticAssets, StaticAssetsError};
52#[cfg(feature = "telemetry")]
53pub use trace::OpenTelemetryTracing;
54pub use trace::TraceContextMiddleware;
55
56#[cfg(test)]
57mod tests {
58 use super::Cors;
59 use actix_web::{
60 http::{header, Method, StatusCode},
61 test, web, App, HttpResponse,
62 };
63
64 #[actix_rt::test]
65 async fn permissive_cors_handles_browser_preflight() {
66 let app = test::init_service(
67 App::new()
68 .wrap(Cors::permissive())
69 .route("/", web::get().to(|| async { HttpResponse::Ok().finish() })),
70 )
71 .await;
72
73 let response = test::call_service(
74 &app,
75 test::TestRequest::default()
76 .method(Method::OPTIONS)
77 .uri("/")
78 .insert_header((header::ORIGIN, "https://frontend.example"))
79 .insert_header((header::ACCESS_CONTROL_REQUEST_METHOD, "GET"))
80 .to_request(),
81 )
82 .await;
83
84 assert_eq!(response.status(), StatusCode::OK);
85 assert_eq!(
86 response
87 .headers()
88 .get(header::ACCESS_CONTROL_ALLOW_ORIGIN)
89 .unwrap(),
90 "https://frontend.example"
91 );
92 }
93}