netget/server/http_common/
actions.rs1use crate::llm::actions::protocol_trait::ActionResult;
4use anyhow::{Context, Result};
5use serde_json::json;
6use std::collections::HashMap;
7use tracing::debug;
8
9#[derive(Debug)]
11pub struct HttpResponseData {
12 pub status: u16,
13 pub headers: HashMap<String, String>,
14 pub body: String,
15}
16
17pub fn execute_http_response_action(action: serde_json::Value) -> Result<ActionResult> {
35 let status_value = action
36 .get("status")
37 .context("Missing 'status' parameter (HTTP status code, e.g. 200)")?;
38
39 let status = match status_value {
40 serde_json::Value::Number(n) => n.as_u64(),
41 serde_json::Value::String(s) => s.trim().parse::<u64>().ok(),
43 _ => None,
44 }
45 .filter(|s| (100..=599).contains(s))
46 .with_context(|| {
47 format!(
48 "Invalid 'status' parameter {}: expected an HTTP status code between 100 and 599",
49 status_value
50 )
51 })? as u16;
52
53 let headers = action
54 .get("headers")
55 .and_then(|v| v.as_object())
56 .map(|obj| {
57 obj.iter()
58 .filter_map(|(k, v)| match v {
59 serde_json::Value::Null => None,
60 serde_json::Value::String(s) => Some((k.clone(), s.clone())),
61 other => Some((k.clone(), other.to_string())),
62 })
63 .collect::<HashMap<String, String>>()
64 })
65 .unwrap_or_default();
66
67 let body = match action.get("body") {
68 None | Some(serde_json::Value::Null) => String::new(),
69 Some(serde_json::Value::String(s)) => s.clone(),
70 Some(other) => {
71 debug!(
72 "HTTP response body was not a string; serializing {} to JSON text",
73 other
74 );
75 other.to_string()
76 }
77 };
78
79 let response_data = json!({
81 "status": status,
82 "headers": headers,
83 "body": body
84 });
85
86 Ok(ActionResult::Output(
87 serde_json::to_vec(&response_data).context("Failed to serialize HTTP response")?,
88 ))
89}