From 78022229ec8e69ec00e7c73558079b58e61bd3a4 Mon Sep 17 00:00:00 2001 From: Samuel Henriquez Date: Wed, 15 Oct 2025 15:51:43 -0400 Subject: [PATCH 01/10] support setting a response body --- src/http/server.rs | 9 ++++++++- src/hyperapp.rs | 10 ++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/http/server.rs b/src/http/server.rs index 18bb940..4e96caa 100644 --- a/src/http/server.rs +++ b/src/http/server.rs @@ -1080,6 +1080,13 @@ impl HttpServer { /// Send an HTTP response to an incoming HTTP request ([`HttpServerRequest::Http`]). pub fn send_response(status: StatusCode, headers: Option>, body: Vec) { + // Check if there's a manual body override in the HTTP context + let final_body = crate::hyperapp::APP_HELPERS.with(|helpers| { + helpers.borrow().current_http_context.as_ref() + .and_then(|ctx| ctx.response_body.clone()) + .unwrap_or(body) // Use override if present, otherwise use the parameter + }); + KiResponse::new() .body( serde_json::to_vec(&HttpResponse { @@ -1088,7 +1095,7 @@ pub fn send_response(status: StatusCode, headers: Option }) .unwrap(), ) - .blob_bytes(body) + .blob_bytes(final_body) .send() .unwrap() } diff --git a/src/hyperapp.rs b/src/hyperapp.rs index 29a4dd0..6e4463f 100644 --- a/src/hyperapp.rs +++ b/src/hyperapp.rs @@ -38,6 +38,7 @@ pub struct HttpRequestContext { pub request: IncomingHttpRequest, pub response_headers: HashMap, pub response_status: http::StatusCode, + pub response_body: Option>, } pub struct AppContext { @@ -105,6 +106,15 @@ pub fn set_response_status(status: http::StatusCode) { }) } +// Set the HTTP response body directly (bypasses Result serialization) +pub fn set_response_body(body: Vec) { + APP_HELPERS.with(|helpers| { + if let Some(ctx) = &mut helpers.borrow_mut().current_http_context { + ctx.response_body = Some(body); + } + }) +} + pub fn clear_http_request_context() { APP_HELPERS.with(|helpers| { helpers.borrow_mut().current_http_context = None; From 7b63b239b9c6e27d6ef0af92e68edc93aa544f79 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 15 Oct 2025 19:52:13 +0000 Subject: [PATCH 02/10] Format Rust code using rustfmt --- src/http/server.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/http/server.rs b/src/http/server.rs index 4e96caa..c11a6c4 100644 --- a/src/http/server.rs +++ b/src/http/server.rs @@ -1082,9 +1082,12 @@ impl HttpServer { pub fn send_response(status: StatusCode, headers: Option>, body: Vec) { // Check if there's a manual body override in the HTTP context let final_body = crate::hyperapp::APP_HELPERS.with(|helpers| { - helpers.borrow().current_http_context.as_ref() + helpers + .borrow() + .current_http_context + .as_ref() .and_then(|ctx| ctx.response_body.clone()) - .unwrap_or(body) // Use override if present, otherwise use the parameter + .unwrap_or(body) // Use override if present, otherwise use the parameter }); KiResponse::new() From 1135751e21674366fae8a747a0315b6338e9e06b Mon Sep 17 00:00:00 2001 From: Samuel Henriquez Date: Mon, 20 Oct 2025 15:40:11 -0400 Subject: [PATCH 03/10] facilitate some HTTP interactions @Gohlub was hating on my APP_HELPERS invocation so I need something like this --- src/hyperapp.rs | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/hyperapp.rs b/src/hyperapp.rs index 6e4463f..e303559 100644 --- a/src/hyperapp.rs +++ b/src/hyperapp.rs @@ -79,6 +79,35 @@ pub fn get_http_method() -> Option { }) } +// Get a specific header from the current HTTP request +// Returns None if not in HTTP context or header doesn't exist +pub fn get_request_header(name: &str) -> Option { + APP_HELPERS.with(|helpers| { + helpers + .borrow() + .current_http_context + .as_ref() + .and_then(|ctx| { + ctx.request.headers().get(name) + .and_then(|value| value.to_str().ok()) + .map(|s| s.to_string()) + }) + }) +} + +// Get the full URL of the current HTTP request +// Returns None if not in an HTTP context +pub fn get_request_url() -> Option { + APP_HELPERS.with(|helpers| { + helpers + .borrow() + .current_http_context + .as_ref() + .and_then(|ctx| ctx.request.url().ok()) + .map(|url| url.to_string()) + }) +} + // Set response headers that will be included in the HTTP response pub fn set_response_headers(headers: HashMap) { APP_HELPERS.with(|helpers| { From d9f895bed01ece9c722479b33dac78fb7b284b03 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 20 Oct 2025 19:40:43 +0000 Subject: [PATCH 04/10] Format Rust code using rustfmt --- src/hyperapp.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hyperapp.rs b/src/hyperapp.rs index e303559..7bede60 100644 --- a/src/hyperapp.rs +++ b/src/hyperapp.rs @@ -88,7 +88,9 @@ pub fn get_request_header(name: &str) -> Option { .current_http_context .as_ref() .and_then(|ctx| { - ctx.request.headers().get(name) + ctx.request + .headers() + .get(name) .and_then(|value| value.to_str().ok()) .map(|s| s.to_string()) }) From 95228f536185c3ae736c8eb99df511e36e9a5004 Mon Sep 17 00:00:00 2001 From: Samuel Henriquez Date: Mon, 20 Oct 2025 15:51:13 -0400 Subject: [PATCH 05/10] allegedly a fix I sense slop but we'll try it --- src/hyperapp.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/hyperapp.rs b/src/hyperapp.rs index e303559..2d9c1d7 100644 --- a/src/hyperapp.rs +++ b/src/hyperapp.rs @@ -82,13 +82,17 @@ pub fn get_http_method() -> Option { // Get a specific header from the current HTTP request // Returns None if not in HTTP context or header doesn't exist pub fn get_request_header(name: &str) -> Option { + use http::header::HeaderName; + APP_HELPERS.with(|helpers| { helpers .borrow() .current_http_context .as_ref() .and_then(|ctx| { - ctx.request.headers().get(name) + // Convert string to HeaderName + let header_name = HeaderName::from_bytes(name.as_bytes()).ok()?; + ctx.request.headers().get(&header_name) .and_then(|value| value.to_str().ok()) .map(|s| s.to_string()) }) From b430396bd6b6060f10f55b563b34dd26a9afe15f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 20 Oct 2025 19:53:38 +0000 Subject: [PATCH 06/10] Format Rust code using rustfmt --- src/hyperapp.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hyperapp.rs b/src/hyperapp.rs index 2d9c1d7..8895c7e 100644 --- a/src/hyperapp.rs +++ b/src/hyperapp.rs @@ -92,7 +92,9 @@ pub fn get_request_header(name: &str) -> Option { .and_then(|ctx| { // Convert string to HeaderName let header_name = HeaderName::from_bytes(name.as_bytes()).ok()?; - ctx.request.headers().get(&header_name) + ctx.request + .headers() + .get(&header_name) .and_then(|value| value.to_str().ok()) .map(|s| s.to_string()) }) From 351efd34748f7b36f5dfcf35b9bda2e90570cec7 Mon Sep 17 00:00:00 2001 From: Samuel Henriquez Date: Mon, 20 Oct 2025 15:57:40 -0400 Subject: [PATCH 07/10] another fix erm --- src/hyperapp.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/hyperapp.rs b/src/hyperapp.rs index 2d9c1d7..01ee9e3 100644 --- a/src/hyperapp.rs +++ b/src/hyperapp.rs @@ -82,16 +82,14 @@ pub fn get_http_method() -> Option { // Get a specific header from the current HTTP request // Returns None if not in HTTP context or header doesn't exist pub fn get_request_header(name: &str) -> Option { - use http::header::HeaderName; - APP_HELPERS.with(|helpers| { helpers .borrow() .current_http_context .as_ref() .and_then(|ctx| { - // Convert string to HeaderName - let header_name = HeaderName::from_bytes(name.as_bytes()).ok()?; + // Convert string to HeaderName using process_lib's re-exported type + let header_name = http::HeaderName::from_bytes(name.as_bytes()).ok()?; ctx.request.headers().get(&header_name) .and_then(|value| value.to_str().ok()) .map(|s| s.to_string()) From b580372a7c8f4cc22b59724630908f327fcae04b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 21 Oct 2025 14:02:45 +0000 Subject: [PATCH 08/10] Format Rust code using rustfmt --- src/hyperapp.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hyperapp.rs b/src/hyperapp.rs index 01ee9e3..4732f29 100644 --- a/src/hyperapp.rs +++ b/src/hyperapp.rs @@ -90,7 +90,9 @@ pub fn get_request_header(name: &str) -> Option { .and_then(|ctx| { // Convert string to HeaderName using process_lib's re-exported type let header_name = http::HeaderName::from_bytes(name.as_bytes()).ok()?; - ctx.request.headers().get(&header_name) + ctx.request + .headers() + .get(&header_name) .and_then(|value| value.to_str().ok()) .map(|s| s.to_string()) }) From 4302df1104359ffbe7385ade6c66cd030c450b79 Mon Sep 17 00:00:00 2001 From: Samuel Henriquez Date: Tue, 21 Oct 2025 10:59:27 -0400 Subject: [PATCH 09/10] changes need to process the params. or something idk --- src/hyperapp.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/hyperapp.rs b/src/hyperapp.rs index 01ee9e3..7f5658a 100644 --- a/src/hyperapp.rs +++ b/src/hyperapp.rs @@ -164,8 +164,9 @@ pub fn source() -> Address { }) } -/// Get query parameters from the current HTTP request path +/// Get query parameters from the current HTTP request path (manually parsed) /// Returns None if not in an HTTP context or no query parameters present +/// NOTE: This manually parses the path string. For pre-parsed params, use get_parsed_query_params() pub fn get_query_params() -> Option> { get_path().map(|path| { let mut params = HashMap::new(); @@ -183,6 +184,19 @@ pub fn get_query_params() -> Option> { }) } +/// Get the pre-parsed query parameters from the current HTTP request +/// Returns None if not in an HTTP context +/// This accesses the query_params field that Hyperware already parsed (includes URL decoding) +pub fn get_parsed_query_params() -> Option> { + APP_HELPERS.with(|helpers| { + helpers + .borrow() + .current_http_context + .as_ref() + .map(|ctx| ctx.request.query_params().clone()) + }) +} + pub struct Executor { tasks: Vec>>>, } From 625636a49792c9d3de4cf6a6658ea0b6dd117728 Mon Sep 17 00:00:00 2001 From: hosted-fornet Date: Mon, 10 Nov 2025 16:17:21 -0800 Subject: [PATCH 10/10] hyperapp: remove set_response_body --- src/http/server.rs | 12 +----------- src/hyperapp.rs | 32 +------------------------------- 2 files changed, 2 insertions(+), 42 deletions(-) diff --git a/src/http/server.rs b/src/http/server.rs index c11a6c4..18bb940 100644 --- a/src/http/server.rs +++ b/src/http/server.rs @@ -1080,16 +1080,6 @@ impl HttpServer { /// Send an HTTP response to an incoming HTTP request ([`HttpServerRequest::Http`]). pub fn send_response(status: StatusCode, headers: Option>, body: Vec) { - // Check if there's a manual body override in the HTTP context - let final_body = crate::hyperapp::APP_HELPERS.with(|helpers| { - helpers - .borrow() - .current_http_context - .as_ref() - .and_then(|ctx| ctx.response_body.clone()) - .unwrap_or(body) // Use override if present, otherwise use the parameter - }); - KiResponse::new() .body( serde_json::to_vec(&HttpResponse { @@ -1098,7 +1088,7 @@ pub fn send_response(status: StatusCode, headers: Option }) .unwrap(), ) - .blob_bytes(final_body) + .blob_bytes(body) .send() .unwrap() } diff --git a/src/hyperapp.rs b/src/hyperapp.rs index ed7bfcd..6acc8fb 100644 --- a/src/hyperapp.rs +++ b/src/hyperapp.rs @@ -38,7 +38,6 @@ pub struct HttpRequestContext { pub request: IncomingHttpRequest, pub response_headers: HashMap, pub response_status: http::StatusCode, - pub response_body: Option>, } pub struct AppContext { @@ -139,15 +138,6 @@ pub fn set_response_status(status: http::StatusCode) { }) } -// Set the HTTP response body directly (bypasses Result serialization) -pub fn set_response_body(body: Vec) { - APP_HELPERS.with(|helpers| { - if let Some(ctx) = &mut helpers.borrow_mut().current_http_context { - ctx.response_body = Some(body); - } - }) -} - pub fn clear_http_request_context() { APP_HELPERS.with(|helpers| { helpers.borrow_mut().current_http_context = None; @@ -166,30 +156,10 @@ pub fn source() -> Address { }) } -/// Get query parameters from the current HTTP request path (manually parsed) -/// Returns None if not in an HTTP context or no query parameters present -/// NOTE: This manually parses the path string. For pre-parsed params, use get_parsed_query_params() -pub fn get_query_params() -> Option> { - get_path().map(|path| { - let mut params = HashMap::new(); - if let Some(query_start) = path.find('?') { - let query = &path[query_start + 1..]; - for pair in query.split('&') { - if let Some(eq_pos) = pair.find('=') { - let key = pair[..eq_pos].to_string(); - let value = pair[eq_pos + 1..].to_string(); - params.insert(key, value); - } - } - } - params - }) -} - /// Get the pre-parsed query parameters from the current HTTP request /// Returns None if not in an HTTP context /// This accesses the query_params field that Hyperware already parsed (includes URL decoding) -pub fn get_parsed_query_params() -> Option> { +pub fn get_query_params() -> Option> { APP_HELPERS.with(|helpers| { helpers .borrow()