Skip to content

Commit 5430ac1

Browse files
authored
Merge pull request #3250 from itowlson/static-response
Static HTTP responses
2 parents f5f00ae + 058b175 commit 5430ac1

File tree

9 files changed

+430
-162
lines changed

9 files changed

+430
-162
lines changed

crates/http/src/config.rs

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,31 @@ use serde::{Deserialize, Serialize};
22
use spin_http_routes::HttpTriggerRouteConfig;
33

44
/// Configuration for the HTTP trigger
5-
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
5+
#[derive(Clone, Debug, Deserialize, Serialize)]
66
#[serde(deny_unknown_fields)]
77
pub struct HttpTriggerConfig {
88
/// Component ID to invoke
9-
pub component: String,
9+
pub component: Option<String>,
10+
/// Static response to send
11+
pub static_response: Option<StaticResponse>,
1012
/// HTTP route the component will be invoked for
1113
pub route: HttpTriggerRouteConfig,
1214
/// The HTTP executor the component requires
1315
#[serde(default)]
1416
pub executor: Option<HttpExecutorType>,
1517
}
1618

19+
impl HttpTriggerConfig {
20+
pub fn lookup_key(&self, trigger_id: &str) -> anyhow::Result<crate::routes::TriggerLookupKey> {
21+
match (&self.component, &self.static_response) {
22+
(None, None) => Err(anyhow::anyhow!("Triggers must specify either component or static_response - {trigger_id} has neither")),
23+
(Some(_), Some(_)) => Err(anyhow::anyhow!("Triggers must specify either component or static_response - {trigger_id} has both")),
24+
(Some(c), None) => Ok(crate::routes::TriggerLookupKey::Component(c.to_string())),
25+
(None, Some(_)) => Ok(crate::routes::TriggerLookupKey::Trigger(trigger_id.to_string())),
26+
}
27+
}
28+
}
29+
1730
/// The executor for the HTTP component.
1831
/// The component can either implement the Spin HTTP interface,
1932
/// the `wasi-http` interface, or the Wagi CGI interface.
@@ -65,6 +78,32 @@ impl Default for WagiTriggerConfig {
6578
}
6679
}
6780

81+
/// A static response to be served directly by the host
82+
/// without instantiating a component.
83+
#[derive(Clone, Debug, Deserialize, Serialize)]
84+
pub struct StaticResponse {
85+
#[serde(default)]
86+
status_code: Option<u16>,
87+
#[serde(default)]
88+
headers: indexmap::IndexMap<String, String>,
89+
#[serde(default)]
90+
body: Option<String>,
91+
}
92+
93+
impl StaticResponse {
94+
pub fn status(&self) -> u16 {
95+
self.status_code.unwrap_or(200)
96+
}
97+
98+
pub fn headers(&self) -> impl Iterator<Item = (&String, &String)> {
99+
self.headers.iter()
100+
}
101+
102+
pub fn body(&self) -> Option<&String> {
103+
self.body.as_ref()
104+
}
105+
}
106+
68107
#[cfg(test)]
69108
mod tests {
70109
use super::*;

0 commit comments

Comments
 (0)