Skip to content

Commit 32f6da4

Browse files
committed
Revert RequestHandler type refactoring
Signed-off-by: Ryan Levick <[email protected]>
1 parent 6a67cef commit 32f6da4

File tree

5 files changed

+104
-146
lines changed

5 files changed

+104
-146
lines changed

crates/trigger-http2/src/outbound_http.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,17 @@ use spin_http::routes::RouteMatch;
1111
use spin_outbound_networking::parse_service_chaining_target;
1212
use wasmtime_wasi_http::types::IncomingResponse;
1313

14-
use crate::server::RequestHandler;
14+
use crate::HttpServer;
1515

1616
/// An outbound HTTP interceptor that handles service chaining requests.
1717
pub struct OutboundHttpInterceptor {
18-
handler: Arc<RequestHandler>,
18+
server: Arc<HttpServer>,
1919
origin: SelfRequestOrigin,
2020
}
2121

2222
impl OutboundHttpInterceptor {
23-
pub fn new(handler: Arc<RequestHandler>, origin: SelfRequestOrigin) -> Self {
24-
Self { handler, origin }
23+
pub fn new(server: Arc<HttpServer>, origin: SelfRequestOrigin) -> Self {
24+
Self { server, origin }
2525
}
2626
}
2727

@@ -41,10 +41,10 @@ impl spin_factor_outbound_http::OutboundHttpInterceptor for OutboundHttpIntercep
4141
let route_match = RouteMatch::synthetic(&component_id, uri.path());
4242
let req = std::mem::take(request);
4343
let between_bytes_timeout = config.between_bytes_timeout;
44-
let server = self.handler.clone();
44+
let server = self.server.clone();
4545
let resp_fut = async move {
4646
match server
47-
.handle_trigger_route(req, &route_match, Scheme::HTTP, CHAINED_CLIENT_ADDR)
47+
.handle_trigger_route(req, route_match, Scheme::HTTP, CHAINED_CLIENT_ADDR)
4848
.await
4949
{
5050
Ok(resp) => Ok(Ok(IncomingResponse {

crates/trigger-http2/src/server.rs

Lines changed: 91 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,18 @@ use crate::{
3838

3939
/// An HTTP server which runs Spin apps.
4040
pub struct HttpServer {
41+
/// The address the server is listening on.
42+
listen_addr: SocketAddr,
43+
/// The TLS configuration for the server.
4144
tls_config: Option<TlsConfig>,
45+
/// Request router.
4246
router: Router,
43-
handler: Arc<RequestHandler>,
47+
/// The app being triggered.
48+
trigger_app: TriggerApp,
49+
// Component ID -> component trigger config
50+
component_trigger_configs: HashMap<String, HttpTriggerConfig>,
51+
// Component ID -> handler type
52+
component_handler_types: HashMap<String, HandlerType>,
4453
}
4554

4655
impl HttpServer {
@@ -52,27 +61,32 @@ impl HttpServer {
5261
router: Router,
5362
component_trigger_configs: HashMap<String, HttpTriggerConfig>,
5463
) -> anyhow::Result<Self> {
64+
let component_handler_types = component_trigger_configs
65+
.keys()
66+
.map(|component_id| {
67+
let component = trigger_app.get_component(component_id)?;
68+
let handler_type = HandlerType::from_component(trigger_app.engine(), component)?;
69+
Ok((component_id.clone(), handler_type))
70+
})
71+
.collect::<anyhow::Result<_>>()?;
5572
Ok(Self {
73+
listen_addr,
5674
tls_config,
5775
router,
58-
handler: Arc::new(RequestHandler::new(
59-
listen_addr,
60-
trigger_app,
61-
component_trigger_configs,
62-
)?),
76+
trigger_app,
77+
component_trigger_configs,
78+
component_handler_types,
6379
})
6480
}
6581

6682
/// Serve incoming requests over the provided [`TcpListener`].
6783
pub async fn serve(self: Arc<Self>) -> anyhow::Result<()> {
68-
let listener = TcpListener::bind(self.handler.listen_addr)
69-
.await
70-
.with_context(|| {
71-
format!(
72-
"Unable to listen on {listen_addr}",
73-
listen_addr = self.handler.listen_addr
74-
)
75-
})?;
84+
let listener = TcpListener::bind(self.listen_addr).await.with_context(|| {
85+
format!(
86+
"Unable to listen on {listen_addr}",
87+
listen_addr = self.listen_addr
88+
)
89+
})?;
7690
if let Some(tls_config) = self.tls_config.clone() {
7791
self.serve_https(listener, tls_config).await?;
7892
} else {
@@ -112,7 +126,7 @@ impl HttpServer {
112126
///
113127
/// This method handles well known paths and routes requests to the handler when the router
114128
/// matches the requests path.
115-
async fn handle(
129+
pub async fn handle(
116130
self: &Arc<Self>,
117131
mut req: Request<Body>,
118132
server_scheme: Scheme,
@@ -150,15 +164,70 @@ impl HttpServer {
150164
/// Handles a successful route match.
151165
pub async fn handle_trigger_route(
152166
self: &Arc<Self>,
153-
req: Request<Body>,
167+
mut req: Request<Body>,
154168
route_match: RouteMatch,
155169
server_scheme: Scheme,
156170
client_addr: SocketAddr,
157171
) -> anyhow::Result<Response<Body>> {
158-
let res = self
159-
.handler
160-
.handle_trigger_route(req, &route_match, server_scheme, client_addr)
161-
.await;
172+
set_req_uri(&mut req, server_scheme.clone())?;
173+
let app_id = self
174+
.trigger_app
175+
.app()
176+
.get_metadata(APP_NAME_KEY)?
177+
.unwrap_or_else(|| "<unnamed>".into());
178+
179+
let component_id = route_match.component_id();
180+
181+
spin_telemetry::metrics::monotonic_counter!(
182+
spin.request_count = 1,
183+
trigger_type = "http",
184+
app_id = app_id,
185+
component_id = component_id
186+
);
187+
188+
let mut instance_builder = self.trigger_app.prepare(component_id)?;
189+
190+
// Set up outbound HTTP request origin and service chaining
191+
let origin = SelfRequestOrigin::create(server_scheme, &self.listen_addr)?;
192+
instance_builder
193+
.factor_builders()
194+
.outbound_http()
195+
.set_request_interceptor(OutboundHttpInterceptor::new(self.clone(), origin))?;
196+
197+
// Prepare HTTP executor
198+
let trigger_config = self.component_trigger_configs.get(component_id).unwrap();
199+
let handler_type = self.component_handler_types.get(component_id).unwrap();
200+
let executor = trigger_config
201+
.executor
202+
.as_ref()
203+
.unwrap_or(&HttpExecutorType::Http);
204+
205+
let res = match executor {
206+
HttpExecutorType::Http => match handler_type {
207+
HandlerType::Spin => {
208+
SpinHttpExecutor
209+
.execute(instance_builder, &route_match, req, client_addr)
210+
.await
211+
}
212+
HandlerType::Wasi0_2
213+
| HandlerType::Wasi2023_11_10
214+
| HandlerType::Wasi2023_10_18 => {
215+
WasiHttpExecutor {
216+
handler_type: *handler_type,
217+
}
218+
.execute(instance_builder, &route_match, req, client_addr)
219+
.await
220+
}
221+
},
222+
HttpExecutorType::Wagi(wagi_config) => {
223+
let executor = WagiHttpExecutor {
224+
wagi_config: wagi_config.clone(),
225+
};
226+
executor
227+
.execute(instance_builder, &route_match, req, client_addr)
228+
.await
229+
}
230+
};
162231
match res {
163232
Ok(res) => Ok(MatchedRoute::with_response_extension(
164233
res,
@@ -174,7 +243,7 @@ impl HttpServer {
174243

175244
/// Returns spin status information.
176245
fn app_info(&self, route: String) -> anyhow::Result<Response<Body>> {
177-
let info = AppInfo::new(self.handler.trigger_app.app());
246+
let info = AppInfo::new(self.trigger_app.app());
178247
let body = serde_json::to_vec_pretty(&info)?;
179248
Ok(MatchedRoute::with_response_extension(
180249
Response::builder()
@@ -278,7 +347,7 @@ impl HttpServer {
278347
println!("Available Routes:");
279348
for (route, component_id) in self.router.routes() {
280349
println!(" {}: {}{}", component_id, base_url, route);
281-
if let Some(component) = self.handler.trigger_app.app().get_component(component_id) {
350+
if let Some(component) = self.trigger_app.app().get_component(component_id) {
282351
if let Some(description) = component.get_metadata(APP_DESCRIPTION_KEY)? {
283352
println!(" {}", description);
284353
}
@@ -288,111 +357,6 @@ impl HttpServer {
288357
}
289358
}
290359

291-
/// Handles a routed HTTP trigger request.
292-
pub struct RequestHandler {
293-
/// The address the server is listening on.
294-
pub(crate) listen_addr: SocketAddr,
295-
/// The app being triggered.
296-
trigger_app: TriggerApp,
297-
// Component ID -> component trigger config
298-
component_trigger_configs: HashMap<String, HttpTriggerConfig>,
299-
// Component ID -> handler type
300-
component_handler_types: HashMap<String, HandlerType>,
301-
}
302-
303-
impl RequestHandler {
304-
/// Create a new [`RequestHandler`]
305-
pub fn new(
306-
listen_addr: SocketAddr,
307-
trigger_app: TriggerApp,
308-
component_trigger_configs: HashMap<String, HttpTriggerConfig>,
309-
) -> anyhow::Result<Self> {
310-
let component_handler_types = component_trigger_configs
311-
.keys()
312-
.map(|component_id| {
313-
let component = trigger_app.get_component(component_id)?;
314-
let handler_type = HandlerType::from_component(trigger_app.engine(), component)?;
315-
Ok((component_id.clone(), handler_type))
316-
})
317-
.collect::<anyhow::Result<_>>()?;
318-
Ok(Self {
319-
listen_addr,
320-
trigger_app,
321-
component_trigger_configs,
322-
component_handler_types,
323-
})
324-
}
325-
326-
/// Handle a routed request.
327-
pub async fn handle_trigger_route(
328-
self: &Arc<Self>,
329-
mut req: Request<Body>,
330-
route_match: &RouteMatch,
331-
server_scheme: Scheme,
332-
client_addr: SocketAddr,
333-
) -> anyhow::Result<Response<Body>> {
334-
set_req_uri(&mut req, server_scheme.clone())?;
335-
let app_id = self
336-
.trigger_app
337-
.app()
338-
.get_metadata(APP_NAME_KEY)?
339-
.unwrap_or_else(|| "<unnamed>".into());
340-
341-
let component_id = route_match.component_id();
342-
343-
spin_telemetry::metrics::monotonic_counter!(
344-
spin.request_count = 1,
345-
trigger_type = "http",
346-
app_id = app_id,
347-
component_id = component_id
348-
);
349-
350-
let mut instance_builder = self.trigger_app.prepare(component_id)?;
351-
352-
// Set up outbound HTTP request origin and service chaining
353-
let origin = SelfRequestOrigin::create(server_scheme, &self.listen_addr)?;
354-
instance_builder
355-
.factor_builders()
356-
.outbound_http()
357-
.set_request_interceptor(OutboundHttpInterceptor::new(self.clone(), origin))?;
358-
359-
// Prepare HTTP executor
360-
let trigger_config = self.component_trigger_configs.get(component_id).unwrap();
361-
let handler_type = self.component_handler_types.get(component_id).unwrap();
362-
let executor = trigger_config
363-
.executor
364-
.as_ref()
365-
.unwrap_or(&HttpExecutorType::Http);
366-
367-
match executor {
368-
HttpExecutorType::Http => match handler_type {
369-
HandlerType::Spin => {
370-
SpinHttpExecutor
371-
.execute(instance_builder, route_match, req, client_addr)
372-
.await
373-
}
374-
HandlerType::Wasi0_2
375-
| HandlerType::Wasi2023_11_10
376-
| HandlerType::Wasi2023_10_18 => {
377-
WasiHttpExecutor {
378-
handler_type: *handler_type,
379-
}
380-
.execute(instance_builder, route_match, req, client_addr)
381-
.await
382-
}
383-
},
384-
HttpExecutorType::Wagi(wagi_config) => {
385-
let executor = WagiHttpExecutor {
386-
wagi_config: wagi_config.clone(),
387-
};
388-
executor
389-
.execute(instance_builder, route_match, req, client_addr)
390-
.await
391-
}
392-
}
393-
}
394-
}
395-
396360
/// The incoming request's scheme and authority
397361
///
398362
/// The incoming request's URI is relative to the server, so we need to set the scheme and authority.

tests/conformance-tests/src/lib.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use anyhow::Context as _;
2-
use test_environment::http::Request;
32
use testing_framework::runtimes::spin_cli::{SpinCli, SpinConfig};
43

54
/// Run a single conformance test against the supplied spin binary.
@@ -57,11 +56,9 @@ pub fn run_test(
5756
let conformance_tests::config::Invocation::Http(mut invocation) = invocation;
5857
invocation.request.substitute_from_env(&mut env)?;
5958
let spin = env.runtime_mut();
60-
let actual = invocation.request.send(|request| {
61-
let request =
62-
Request::full(request.method, request.path, request.headers, request.body);
63-
spin.make_http_request(request)
64-
})?;
59+
let actual = invocation
60+
.request
61+
.send(|request| spin.make_http_request(request))?;
6562

6663
conformance_tests::assertions::assert_response(&invocation.response, &actual)
6764
.with_context(|| {

tests/testing-framework/Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ regex = "1.10.2"
1414
reqwest = { workspace = true }
1515
temp-dir = "0.1.11"
1616
test-environment = { workspace = true }
17-
spin-factors-executor = { path = "../../crates/factors-executor" }
1817
spin-app = { path = "../../crates/app" }
19-
spin-trigger-http2 = { path = "../../crates/trigger-http2" }
18+
spin-factors-executor = { path = "../../crates/factors-executor" }
2019
spin-http = { path = "../../crates/http" }
21-
spin-trigger2 = { path = "../../crates/trigger2" }
2220
spin-loader = { path = "../../crates/loader" }
21+
spin-trigger2 = { path = "../../crates/trigger2" }
22+
spin-trigger-http2 = { path = "../../crates/trigger-http2" }
2323
toml = "0.8.6"
2424
tokio = "1.23"
2525
wasmtime-wasi-http = { workspace = true }

tests/testing-framework/src/runtimes/in_process_spin.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
use std::{path::PathBuf, sync::Arc};
44

55
use anyhow::Context as _;
6-
use spin_http::routes::RouteMatch;
76
use spin_trigger2::cli::{TriggerAppBuilder, TriggerAppOptions};
87
use spin_trigger_http2::{HttpServer, HttpTrigger};
98
use test_environment::{
@@ -54,12 +53,10 @@ impl InProcessSpin {
5453
}
5554
// TODO(rylev): convert body as well
5655
let req = builder.body(spin_http::body::empty()).unwrap();
57-
let route_match = RouteMatch::synthetic("test", "/");
5856
let response = self
5957
.server
60-
.handle_trigger_route(
58+
.handle(
6159
req,
62-
route_match,
6360
http::uri::Scheme::HTTP,
6461
(std::net::Ipv4Addr::LOCALHOST, 7000).into(),
6562
)

0 commit comments

Comments
 (0)