Skip to content

Commit

Permalink
feat: implement HttpHead as new RADType
Browse files Browse the repository at this point in the history
  • Loading branch information
guidiaz committed Oct 10, 2023
1 parent 1c2c8cf commit 7bf3fd7
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 10 deletions.
10 changes: 7 additions & 3 deletions data_structures/src/chain/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1645,11 +1645,14 @@ pub enum RADType {
/// HTTP POST request
#[serde(rename = "HTTP-POST")]
HttpPost,
/// HTTP HEAD request
#[serde(rename = "HTTP-HEAD")]
HttpHead,
}

impl RADType {
pub fn is_http(&self) -> bool {
matches!(self, RADType::HttpGet | RADType::HttpPost)
matches!(self, RADType::HttpGet | RADType::HttpPost | RADType::HttpHead)
}
}

Expand Down Expand Up @@ -1701,7 +1704,7 @@ pub struct RADRetrieve {
pub script: Vec<u8>,
/// Body of a HTTP-POST request
pub body: Vec<u8>,
/// Extra headers of a HTTP-GET or HTTP-POST request
/// Extra headers of a HTTP-GET, HTTP-POST or HTTP-HEAD request
pub headers: Vec<(String, String)>,
}

Expand Down Expand Up @@ -1809,7 +1812,8 @@ impl RADRetrieve {
&[Field::Kind, Field::Url, Field::Script],
&[Field::Body, Field::Headers],
)
}
},
RADType::HttpHead => check(&[Field::Kind, Field::Url, Field::Script], &[Field::Headers])
}
}

Expand Down
2 changes: 2 additions & 0 deletions data_structures/src/proto/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ impl ProtobufConvert for chain::RADType {
chain::RADType::HttpGet => witnet::DataRequestOutput_RADRequest_RADType::HttpGet,
chain::RADType::Rng => witnet::DataRequestOutput_RADRequest_RADType::Rng,
chain::RADType::HttpPost => witnet::DataRequestOutput_RADRequest_RADType::HttpPost,
chain::RADType::HttpHead => witnet::DataRequestOutput_RADRequest_RADType::HttpHead,
}
}

Expand All @@ -60,6 +61,7 @@ impl ProtobufConvert for chain::RADType {
witnet::DataRequestOutput_RADRequest_RADType::HttpGet => chain::RADType::HttpGet,
witnet::DataRequestOutput_RADRequest_RADType::Rng => chain::RADType::Rng,
witnet::DataRequestOutput_RADRequest_RADType::HttpPost => chain::RADType::HttpPost,
witnet::DataRequestOutput_RADRequest_RADType::HttpHead => chain::RADType::HttpHead,
})
}
}
Expand Down
4 changes: 2 additions & 2 deletions data_structures/src/serialization_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ struct RADRetrieveSerializationHelperJson {
/// Body of a HTTP-POST request
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub body: Vec<u8>,
/// Extra headers of a HTTP-GET or HTTP-POST request
/// Extra headers of a HTTP-GET, HTTP-HEAD or HTTP-POST request
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub headers: Vec<(String, String)>,
}
Expand All @@ -377,7 +377,7 @@ struct RADRetrieveSerializationHelperBincode {
pub script: Vec<u8>,
/// Body of a HTTP-POST request
pub body: Vec<u8>,
/// Extra headers of a HTTP-GET or HTTP-POST request
/// Extra headers of a HTTP-GET, HTTP-HEAD or HTTP-POST request
pub headers: Vec<(String, String)>,
}

Expand Down
36 changes: 32 additions & 4 deletions rad/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@ use crate::{
create_radon_script_from_filters_and_reducer, execute_radon_script, unpack_radon_script,
RadonScriptExecutionSettings,
},
types::{array::RadonArray, bytes::RadonBytes, string::RadonString, RadonTypes},
types::{array::RadonArray, bytes::RadonBytes, string::RadonString, map::RadonMap, RadonTypes},
user_agents::UserAgent,
};
use core::convert::From;
use std::collections::BTreeMap;
use witnet_net::client::http::{WitnetHttpBody, WitnetHttpRequest};

pub mod conditions;
Expand Down Expand Up @@ -173,6 +174,25 @@ fn string_response_with_data_report(
execute_radon_script(input, &radon_script, context, settings)
}

/// Handle HTTP-HEAD response with data, and return a `RadonReport`.
fn headers_response_with_data_report(
retrieve: &RADRetrieve,
response: &str,
context: &mut ReportContext<RadonTypes>,
settings: RadonScriptExecutionSettings,
) -> Result<RadonReport<RadonTypes>> {
let headers: BTreeMap<String, RadonTypes> = response.split("\r\n").map(|line| {
let parts: Vec<&str> = line.split(":").map(|part| part.trim()).collect();
// todo: check there are two parts, and two parts only
// todo: make sure that values from repeated keys get appended within a RadonArray
(String::from(parts[0]), RadonTypes::from(RadonString::from(parts[1])))
}).collect();
let input = RadonTypes::from(RadonMap::from(headers));
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,
Expand All @@ -196,7 +216,10 @@ pub fn run_retrieval_with_data_report(
RADType::Rng => rng_response_with_data_report(response, context),
RADType::HttpPost => {
string_response_with_data_report(retrieve, response, context, settings)
}
},
RADType::HttpHead => {
headers_response_with_data_report(retrieve, response, context, settings)
},
_ => Err(RadError::UnknownRetrieval),
}
}
Expand All @@ -214,7 +237,7 @@ pub fn run_retrieval_with_data(
.map(RadonReport::into_inner)
}

/// Handle generic HTTP (GET/POST) response
/// Handle generic HTTP (GET/POST/HEAD) response
async fn http_response(
retrieve: &RADRetrieve,
context: &mut ReportContext<RadonTypes>,
Expand Down Expand Up @@ -258,7 +281,11 @@ async fn http_response(
builder.method("POST").uri(&retrieve.url),
WitnetHttpBody::from(retrieve.body.clone()),
)
}
},
RADType::HttpHead => (
builder.method("HEAD").uri(&retrieve.url),
WitnetHttpBody::empty(),
),
_ => panic!(
"Called http_response with invalid retrieval kind {:?}",
retrieve.kind
Expand Down Expand Up @@ -357,6 +384,7 @@ pub async fn run_retrieval_report(
RADType::HttpGet => http_response(retrieve, context, settings, client).await,
RADType::Rng => rng_response(context, settings).await,
RADType::HttpPost => http_response(retrieve, context, settings, client).await,
RADType::HttpHead => http_response(retrieve, context, settings, client).await,
_ => Err(RadError::UnknownRetrieval),
}
}
Expand Down
3 changes: 2 additions & 1 deletion schemas/witnet/witnet.proto
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ message DataRequestOutput {
HttpGet = 1;
Rng = 2;
HttpPost = 3;
HttpHead = 4;
}
message RADFilter {
uint32 op = 1;
Expand All @@ -133,7 +134,7 @@ message DataRequestOutput {
bytes script = 3;
// Body of HTTP-POST request
bytes body = 4;
// Extra headers for HTTP-GET and HTTP-POST requests
// Extra headers for HTTP-GET, HTTP-HEAD and HTTP-POST requests
repeated StringPair headers = 5;
}
message RADAggregate {
Expand Down

0 comments on commit 7bf3fd7

Please sign in to comment.