featherbit/plugins/native/
serverless_post_function.rs1use async_trait::async_trait;
15use std::collections::HashMap;
16
17use crate::context::Context;
18use crate::plugins::native::serverless_pre_function::ServerlessRunner;
19use crate::plugins::{Plugin, PluginOutput, PluginResult};
20
21pub struct ServerlessPostFunctionPlugin {
24 runner: ServerlessRunner,
25}
26
27impl ServerlessPostFunctionPlugin {
28 pub fn from_config(config: &HashMap<String, serde_json::Value>) -> Result<Self, String> {
43 Ok(Self {
44 runner: ServerlessRunner::from_config(config, "serverless-post-function")?,
45 })
46 }
47}
48
49#[async_trait]
50impl Plugin for ServerlessPostFunctionPlugin {
51 fn plugin_type(&self) -> &str {
52 "serverless-post-function"
53 }
54
55 async fn execute(&self, ctx: Context) -> PluginResult {
56 let ctx = self.runner.run(ctx)?;
57 Ok(PluginOutput::success(ctx))
58 }
59}
60
61#[cfg(test)]
62mod tests {
63 use super::*;
64 use crate::context::{GatewayRequest, GatewayResponse, Protocol};
65
66 fn test_context() -> Context {
67 Context {
68 request: GatewayRequest {
69 method: "GET".to_string(),
70 path: "/test".to_string(),
71 host: "localhost".to_string(),
72 scheme: "http".to_string(),
73 headers: HashMap::new(),
74 query_params: HashMap::new(),
75 body: bytes::Bytes::new(),
76 remote_addr: "127.0.0.1:1234".to_string(),
77 protocol: Protocol::Http1,
78 },
79 response: GatewayResponse {
80 status_code: 200,
81 headers: HashMap::new(),
82 body: bytes::Bytes::new(),
83 stream: None,
84 },
85 message: HashMap::new(),
86 errors: Vec::new(),
87 }
88 }
89
90 fn cfg(functions: serde_json::Value) -> HashMap<String, serde_json::Value> {
91 let mut c = HashMap::new();
92 c.insert("functions".to_string(), functions);
93 c
94 }
95
96 #[tokio::test]
97 async fn test_serverless_post_function_mutates_response() {
98 let p = ServerlessPostFunctionPlugin::from_config(&cfg(serde_json::json!([
99 "function execute(ctx)\n ctx.response.headers[\"x-served-by\"] = {\"featherbit\"}\n return ctx\nend"
100 ])))
101 .unwrap();
102 let out = p.execute(test_context()).await.unwrap();
103 assert_eq!(
104 out.context.response.headers.get("x-served-by"),
105 Some(&vec!["featherbit".to_string()])
106 );
107 assert_eq!(p.plugin_type(), "serverless-post-function");
108 }
109
110 #[test]
111 fn test_serverless_post_function_empty_rejected() {
112 assert!(ServerlessPostFunctionPlugin::from_config(&HashMap::new()).is_err());
113 }
114}