rl_lang/interpreter/stdlib/http/
http_respond.rs1use crate::{
2 interpreter::{
3 evaluator::Evaluator,
4 stdlib::{
5 common::{check_arity_range, extract_number, extract_string, verr, vok, vs},
6 http::HttpHandle,
7 },
8 values::Value,
9 },
10 utils::{errors::Error, span::Span},
11};
12
13pub fn func(eval: &mut Evaluator, args: Vec<Value>, span: Span) -> Result<Value, Error> {
14 check_arity_range(&args, 3, 4, "http_post", span)?;
15
16 let id = match extract_number(args[0].clone(), "http_respond") {
17 Ok(a) if a as i64 >= 0 => a as i64,
18 Ok(_) => {
19 return Ok(verr!(vs!(
20 "http_respond: id handle cannot be negative".to_string()
21 )));
22 }
23 Err(e) => return Ok(verr!(vs!(format!("{}", e)))),
24 };
25
26 let status = match &args[1] {
27 Value::Integer(n) if (100..=599).contains(n) => *n as u16,
28 other => {
29 return Ok(verr!(vs!(format!(
30 "http_respond: expects a valid HTTP status int, got {}",
31 other.type_name()
32 ))));
33 }
34 };
35
36 let body = match extract_string(args[1].clone(), "http_respond") {
37 Ok(s) => s,
38 Err(e) => return Ok(verr!(vs!(format!("{e}")))),
39 };
40 let content_type = match args.get(3) {
41 Some(Value::String(s)) => Some(s.clone()),
42 Some(other) => {
43 return Ok(verr!(vs!(format!(
44 "http_respond: expects a string content_type, got {}",
45 other.type_name()
46 ))));
47 }
48 None => None,
49 };
50
51 let request = match eval.http_handles.remove(&id) {
52 Some(HttpHandle::Request(request)) => request,
53 Some(other) => {
54 eval.http_handles.insert(id, other);
55 return Ok(verr!(vs!(format!(
56 "http_respond: handle {} is not a request",
57 id
58 ))));
59 }
60 None => return Ok(verr!(vs!(format!("http_respond: unknown handle {}", id)))),
61 };
62
63 let mut response = tiny_http::Response::from_string(body).with_status_code(status);
64 if let Some(ct) = content_type
65 && let Ok(header) = tiny_http::Header::from_bytes(&b"Content-Type"[..], ct.as_bytes())
66 {
67 response = response.with_header(header);
68 }
69
70 match request.respond(response) {
71 Ok(()) => Ok(vok!(Value::Null)),
72 Err(e) => Ok(verr!(vs!(format!("http_respond: {}", e)))),
73 }
74}