Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat(Radon): Enhance handling of hex-string, integers and binary buffers #2413

Open
wants to merge 25 commits into
base: 2.0-base
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
5bbea50
feat: implement HttpHead as new RADType
guidiaz Oct 10, 2023
3fdf8f9
chore: cargo fmt --all
guidiaz Oct 10, 2023
721347a
feat: handle repeated headers within http/head response
guidiaz Oct 11, 2023
ef30733
test: run valid http head retrieval
guidiaz Oct 11, 2023
a665397
test: try http-head data request w/ invalid request header
guidiaz Oct 11, 2023
198e5b8
chore: bump package versions
guidiaz Oct 11, 2023
9bae448
chore: cargo fmt --all
guidiaz Oct 11, 2023
af5ff86
chore: solve clippy warnings
guidiaz Oct 11, 2023
ac57ded
fix: use http::Response::headers(&self) to transform response to HTTP…
guidiaz Oct 11, 2023
5e073f9
chore: attend pr review comments
guidiaz Oct 20, 2023
6c4d1ac
feat(rad): add support to binary sources
guidiaz Oct 20, 2023
0cfd81d
chore(rad): refactor existing tests
guidiaz Oct 20, 2023
68c7648
chore: attend pr review comments
guidiaz Oct 26, 2023
184f768
chore: cargo clippy --fix
guidiaz Oct 26, 2023
cd4641c
feat(rad): add new RadonErrors::BufferIsNotValue
guidiaz Oct 26, 2023
f1314a4
fix(rad): http-head response headers can contain 'accept-ranges'
guidiaz Nov 14, 2023
1f2402b
feat(rad): implement StringReplace
guidiaz Nov 14, 2023
533c103
feat(rad): implement StringSlice
guidiaz Nov 14, 2023
b3322b1
feat(rad): implement StringSplit
guidiaz Nov 14, 2023
88c8674
feat(rad): first approach to ArrayJoin
guidiaz Nov 14, 2023
0ab36ce
chore(rad): rename asX <-> toX depending on whether conversion may fail
guidiaz Dec 13, 2023
1c7a4a2
feat(rad): implement RadonOpCodes::BytesAsInteger
guidiaz Dec 13, 2023
ae50ed8
feat(rad): support multiple encoding schemas on RadonOpCodes::BytesSt…
guidiaz Dec 13, 2023
888ef3b
feat(rad): implement RadonOpCodes::IntegerToBytes
guidiaz Dec 13, 2023
179503c
feat(rad): implement RadonOpCodes::StringAsBytes
guidiaz Dec 13, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat(rad): add support to binary sources
  • Loading branch information
guidiaz committed Oct 20, 2023
commit 6c4d1ac2006da442b55fa12cd2b8f7991be44547
88 changes: 50 additions & 38 deletions rad/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,12 @@ pub fn try_data_request(
.iter()
.zip(inputs.iter())
.map(|(retrieve, input)| {
run_retrieval_with_data_report(retrieve, input, &mut retrieval_context, settings)
run_retrieval_with_data_report(
retrieve,
RadonTypes::from(RadonString::from(*input)),
&mut retrieval_context,
settings,
)
})
.collect()
} else {
Expand Down Expand Up @@ -160,50 +165,36 @@ pub fn try_data_request(
}
}

/// Handle HTTP-GET and HTTP-POST response with data, and return a `RadonReport`.
fn string_response_with_data_report(
/// Execute Radon Script using as input the RadonTypes value deserialized from a retrieval response
fn handle_response_with_data_report(
retrieve: &RADRetrieve,
response: &str,
response: RadonTypes,
context: &mut ReportContext<RadonTypes>,
settings: RadonScriptExecutionSettings,
) -> Result<RadonReport<RadonTypes>> {
let input = RadonTypes::from(RadonString::from(response));
let radon_script = unpack_radon_script(&retrieve.script)?;

execute_radon_script(input, &radon_script, context, settings)
}

/// Handle Rng response with data report
fn rng_response_with_data_report(
response: &str,
context: &mut ReportContext<RadonTypes>,
) -> Result<RadonReport<RadonTypes>> {
let response_bytes = response.as_bytes();
let result = RadonTypes::from(RadonBytes::from(response_bytes.to_vec()));

Ok(RadonReport::from_result(Ok(result), context))
execute_radon_script(response, &radon_script, context, settings)
}

/// Run retrieval without performing any external network requests, return `Result<RadonReport>`.
pub fn run_retrieval_with_data_report(
retrieve: &RADRetrieve,
response: &str,
response: RadonTypes,
context: &mut ReportContext<RadonTypes>,
settings: RadonScriptExecutionSettings,
) -> Result<RadonReport<RadonTypes>> {
match retrieve.kind {
RADType::HttpGet | RADType::HttpPost | RADType::HttpHead => {
string_response_with_data_report(retrieve, response, context, settings)
RADType::HttpGet | RADType::HttpPost | RADType::HttpHead | RADType::Rng => {
handle_response_with_data_report(retrieve, response, context, settings)
}
RADType::Rng => rng_response_with_data_report(response, context),
_ => Err(RadError::UnknownRetrieval),
}
}

/// Run retrieval without performing any external network requests, return `Result<RadonTypes>`.
pub fn run_retrieval_with_data(
retrieve: &RADRetrieve,
response: &str,
response: RadonTypes,
settings: RadonScriptExecutionSettings,
active_wips: ActiveWips,
) -> Result<RadonTypes> {
Expand Down Expand Up @@ -299,26 +290,48 @@ async fn http_response(
});
}

// If at some point we want to support the retrieval of non-UTF8 data (e.g. raw bytes), this is
// where we need to decide how to read the response body
let mut response_string = String::default();

let (parts, mut body) = response.into_parts();
match retrieve.kind {
RADType::HttpHead => {
response_string = format!("{:?}", parts.headers);

let response: RadonTypes;
match parts.headers.get("accept-ranges") {
Some(_) => {
// http response is a binary stream
let mut response_bytes = Vec::<u8>::default();
match retrieve.kind {
RADType::HttpHead => {
// todo: assert http-head responses should never return binary streams
}
_ => {
// todo: before reading the response buffer, an error should thrown it was too big
body.read_to_end(&mut response_bytes).await.map_err(|x| {
RadError::HttpOther {
message: x.to_string(),
}
})?;
}
}
response = RadonTypes::from(RadonBytes::from(response_bytes));
}
_ => {
body.read_to_string(&mut response_string)
.await
.map_err(|x| RadError::HttpOther {
message: x.to_string(),
})?;
// response is a string
let mut response_string = String::default();
match retrieve.kind {
RADType::HttpHead => {
response_string = format!("{:?}", parts.headers);
}
_ => {
body.read_to_string(&mut response_string)
.await
.map_err(|x| RadError::HttpOther {
message: x.to_string(),
})?;
}
}
response = RadonTypes::from(RadonString::from(response_string));
}
}

let result = run_retrieval_with_data_report(retrieve, &response_string, context, settings);

let result = handle_response_with_data_report(retrieve, response, context, settings);
match &result {
Ok(report) => {
log::debug!(
Expand All @@ -329,7 +342,6 @@ async fn http_response(
}
Err(e) => log::debug!("Failed result for source {}: {:?}", retrieve.url, e),
}

result
}

Expand Down