Skip to content

Commit a7c0077

Browse files
committed
rsscript: enable sync http get bytes
1 parent d295c3f commit a7c0077

3 files changed

Lines changed: 36 additions & 8 deletions

File tree

crates/rsscript/src/reg_vm/runtime_values.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,7 @@ pub(super) fn http_response_value(status: i64, body: impl Into<String>) -> VmVal
408408
pub(super) fn http_get_local(url: &str) -> Result<VmValue, VmValue> {
409409
let Some(rest) = url.strip_prefix("http://") else {
410410
return Err(http_error_value(format!(
411-
"HTTP client runtime is not configured for GET {url}"
411+
"HTTP request failed for {url}: error sending request for url ({url})"
412412
)));
413413
};
414414
let (host_port, path) = match rest.split_once('/') {

crates/runtime/src/collections.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -884,7 +884,7 @@ pub fn bytes_from_string(value: &str) -> Vec<u8> {
884884
}
885885

886886
pub fn bytes_from_uints(values: &[i64]) -> Vec<u8> {
887-
values.iter().map(|value| (*value as u8)).collect()
887+
values.iter().map(|value| *value as u8).collect()
888888
}
889889

890890
pub fn bytes_to_uints(value: &[u8]) -> Vec<i64> {

crates/runtime/src/domain.rs

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::collections::HashMap;
22
use std::fmt;
33

4-
use crate::async_runtime::{NativeAsyncPending, spawn_tokio_native};
4+
use crate::async_runtime::{NativeAsyncPending, run_pending, spawn_tokio_native};
55
use crate::channel::{ChannelError, RssStream, stream_from_iterator};
66
use std::io::{BufRead, Read};
77
use std::str::Utf8Error;
@@ -19,6 +19,7 @@ pub struct Request {
1919
pub struct Response {
2020
status: i64,
2121
body: String,
22+
body_bytes: Vec<u8>,
2223
}
2324

2425
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -440,6 +441,7 @@ pub fn response_ok(body: &str) -> Result<Response, HttpError> {
440441
Ok(Response {
441442
status: 200,
442443
body: body.to_string(),
444+
body_bytes: body.as_bytes().to_vec(),
443445
})
444446
}
445447

@@ -452,9 +454,7 @@ pub fn response_body(response: &Response) -> String {
452454
}
453455

454456
pub fn http_get(url: &str) -> Result<Response, HttpError> {
455-
Err(HttpError {
456-
message: format!("HTTP client runtime is not configured for GET {url}"),
457-
})
457+
run_pending(http_get_async(url))
458458
}
459459

460460
pub fn http_get_async(url: &str) -> NativeAsyncPending<Result<Response, HttpError>> {
@@ -674,9 +674,11 @@ async fn http_request_async(
674674
let body = response.bytes().await.map_err(|error| HttpError {
675675
message: format!("failed to read HTTP response body from {url}: {error}"),
676676
})?;
677+
let body_bytes = body.to_vec();
677678
Ok(Response {
678679
status,
679-
body: String::from_utf8_lossy(&body).to_string(),
680+
body: String::from_utf8_lossy(&body_bytes).to_string(),
681+
body_bytes,
680682
})
681683
}
682684

@@ -746,7 +748,7 @@ pub fn http_response_text(response: &Response) -> String {
746748
}
747749

748750
pub fn http_response_bytes(response: &Response) -> Vec<u8> {
749-
response.body.as_bytes().to_vec()
751+
response.body_bytes.clone()
750752
}
751753

752754
pub fn http_response_lines(response: &Response) -> Vec<String> {
@@ -1823,6 +1825,32 @@ mod tests {
18231825
handle.join().expect("server thread should finish");
18241826
}
18251827

1828+
#[test]
1829+
fn http_get_sync_uses_reqwest_tokio_io_and_preserves_bytes() {
1830+
use std::io::{Read, Write};
1831+
use std::net::TcpListener;
1832+
1833+
let listener = TcpListener::bind("127.0.0.1:0").expect("test listener should bind");
1834+
let addr = listener.local_addr().expect("listener addr should exist");
1835+
let handle = std::thread::spawn(move || {
1836+
let (mut stream, _) = listener.accept().expect("client should connect");
1837+
let mut request = [0_u8; 1024];
1838+
let read = stream.read(&mut request).expect("request should read");
1839+
let request = String::from_utf8_lossy(&request[..read]);
1840+
assert!(request.starts_with("GET /bytes HTTP/1.1"));
1841+
stream
1842+
.write_all(b"HTTP/1.1 200 OK\r\nContent-Length: 3\r\nConnection: close\r\n\r\n\x00\xffA")
1843+
.expect("response should write");
1844+
});
1845+
1846+
let response = http_get(&format!("http://{addr}/bytes"))
1847+
.expect("sync HTTP GET should succeed");
1848+
1849+
assert_eq!(response.status, 200);
1850+
assert_eq!(http_response_bytes(&response), vec![0, 255, 65]);
1851+
handle.join().expect("server thread should finish");
1852+
}
1853+
18261854
#[test]
18271855
fn http_post_json_async_sends_body_through_reqwest_tokio_io() {
18281856
use std::io::{Read, Write};

0 commit comments

Comments
 (0)