Skip to content

Commit 7bf3fd7

Browse files
committed
feat: implement HttpHead as new RADType
1 parent 1c2c8cf commit 7bf3fd7

File tree

5 files changed

+45
-10
lines changed

5 files changed

+45
-10
lines changed

data_structures/src/chain/mod.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -1645,11 +1645,14 @@ pub enum RADType {
16451645
/// HTTP POST request
16461646
#[serde(rename = "HTTP-POST")]
16471647
HttpPost,
1648+
/// HTTP HEAD request
1649+
#[serde(rename = "HTTP-HEAD")]
1650+
HttpHead,
16481651
}
16491652

16501653
impl RADType {
16511654
pub fn is_http(&self) -> bool {
1652-
matches!(self, RADType::HttpGet | RADType::HttpPost)
1655+
matches!(self, RADType::HttpGet | RADType::HttpPost | RADType::HttpHead)
16531656
}
16541657
}
16551658

@@ -1701,7 +1704,7 @@ pub struct RADRetrieve {
17011704
pub script: Vec<u8>,
17021705
/// Body of a HTTP-POST request
17031706
pub body: Vec<u8>,
1704-
/// Extra headers of a HTTP-GET or HTTP-POST request
1707+
/// Extra headers of a HTTP-GET, HTTP-POST or HTTP-HEAD request
17051708
pub headers: Vec<(String, String)>,
17061709
}
17071710

@@ -1809,7 +1812,8 @@ impl RADRetrieve {
18091812
&[Field::Kind, Field::Url, Field::Script],
18101813
&[Field::Body, Field::Headers],
18111814
)
1812-
}
1815+
},
1816+
RADType::HttpHead => check(&[Field::Kind, Field::Url, Field::Script], &[Field::Headers])
18131817
}
18141818
}
18151819

data_structures/src/proto/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ impl ProtobufConvert for chain::RADType {
5151
chain::RADType::HttpGet => witnet::DataRequestOutput_RADRequest_RADType::HttpGet,
5252
chain::RADType::Rng => witnet::DataRequestOutput_RADRequest_RADType::Rng,
5353
chain::RADType::HttpPost => witnet::DataRequestOutput_RADRequest_RADType::HttpPost,
54+
chain::RADType::HttpHead => witnet::DataRequestOutput_RADRequest_RADType::HttpHead,
5455
}
5556
}
5657

@@ -60,6 +61,7 @@ impl ProtobufConvert for chain::RADType {
6061
witnet::DataRequestOutput_RADRequest_RADType::HttpGet => chain::RADType::HttpGet,
6162
witnet::DataRequestOutput_RADRequest_RADType::Rng => chain::RADType::Rng,
6263
witnet::DataRequestOutput_RADRequest_RADType::HttpPost => chain::RADType::HttpPost,
64+
witnet::DataRequestOutput_RADRequest_RADType::HttpHead => chain::RADType::HttpHead,
6365
})
6466
}
6567
}

data_structures/src/serialization_helpers.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ struct RADRetrieveSerializationHelperJson {
360360
/// Body of a HTTP-POST request
361361
#[serde(default, skip_serializing_if = "Vec::is_empty")]
362362
pub body: Vec<u8>,
363-
/// Extra headers of a HTTP-GET or HTTP-POST request
363+
/// Extra headers of a HTTP-GET, HTTP-HEAD or HTTP-POST request
364364
#[serde(default, skip_serializing_if = "Vec::is_empty")]
365365
pub headers: Vec<(String, String)>,
366366
}
@@ -377,7 +377,7 @@ struct RADRetrieveSerializationHelperBincode {
377377
pub script: Vec<u8>,
378378
/// Body of a HTTP-POST request
379379
pub body: Vec<u8>,
380-
/// Extra headers of a HTTP-GET or HTTP-POST request
380+
/// Extra headers of a HTTP-GET, HTTP-HEAD or HTTP-POST request
381381
pub headers: Vec<(String, String)>,
382382
}
383383

rad/src/lib.rs

+32-4
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,11 @@ use crate::{
2525
create_radon_script_from_filters_and_reducer, execute_radon_script, unpack_radon_script,
2626
RadonScriptExecutionSettings,
2727
},
28-
types::{array::RadonArray, bytes::RadonBytes, string::RadonString, RadonTypes},
28+
types::{array::RadonArray, bytes::RadonBytes, string::RadonString, map::RadonMap, RadonTypes},
2929
user_agents::UserAgent,
3030
};
3131
use core::convert::From;
32+
use std::collections::BTreeMap;
3233
use witnet_net::client::http::{WitnetHttpBody, WitnetHttpRequest};
3334

3435
pub mod conditions;
@@ -173,6 +174,25 @@ fn string_response_with_data_report(
173174
execute_radon_script(input, &radon_script, context, settings)
174175
}
175176

177+
/// Handle HTTP-HEAD response with data, and return a `RadonReport`.
178+
fn headers_response_with_data_report(
179+
retrieve: &RADRetrieve,
180+
response: &str,
181+
context: &mut ReportContext<RadonTypes>,
182+
settings: RadonScriptExecutionSettings,
183+
) -> Result<RadonReport<RadonTypes>> {
184+
let headers: BTreeMap<String, RadonTypes> = response.split("\r\n").map(|line| {
185+
let parts: Vec<&str> = line.split(":").map(|part| part.trim()).collect();
186+
// todo: check there are two parts, and two parts only
187+
// todo: make sure that values from repeated keys get appended within a RadonArray
188+
(String::from(parts[0]), RadonTypes::from(RadonString::from(parts[1])))
189+
}).collect();
190+
let input = RadonTypes::from(RadonMap::from(headers));
191+
let radon_script = unpack_radon_script(&retrieve.script)?;
192+
193+
execute_radon_script(input, &radon_script, context, settings)
194+
}
195+
176196
/// Handle Rng response with data report
177197
fn rng_response_with_data_report(
178198
response: &str,
@@ -196,7 +216,10 @@ pub fn run_retrieval_with_data_report(
196216
RADType::Rng => rng_response_with_data_report(response, context),
197217
RADType::HttpPost => {
198218
string_response_with_data_report(retrieve, response, context, settings)
199-
}
219+
},
220+
RADType::HttpHead => {
221+
headers_response_with_data_report(retrieve, response, context, settings)
222+
},
200223
_ => Err(RadError::UnknownRetrieval),
201224
}
202225
}
@@ -214,7 +237,7 @@ pub fn run_retrieval_with_data(
214237
.map(RadonReport::into_inner)
215238
}
216239

217-
/// Handle generic HTTP (GET/POST) response
240+
/// Handle generic HTTP (GET/POST/HEAD) response
218241
async fn http_response(
219242
retrieve: &RADRetrieve,
220243
context: &mut ReportContext<RadonTypes>,
@@ -258,7 +281,11 @@ async fn http_response(
258281
builder.method("POST").uri(&retrieve.url),
259282
WitnetHttpBody::from(retrieve.body.clone()),
260283
)
261-
}
284+
},
285+
RADType::HttpHead => (
286+
builder.method("HEAD").uri(&retrieve.url),
287+
WitnetHttpBody::empty(),
288+
),
262289
_ => panic!(
263290
"Called http_response with invalid retrieval kind {:?}",
264291
retrieve.kind
@@ -357,6 +384,7 @@ pub async fn run_retrieval_report(
357384
RADType::HttpGet => http_response(retrieve, context, settings, client).await,
358385
RADType::Rng => rng_response(context, settings).await,
359386
RADType::HttpPost => http_response(retrieve, context, settings, client).await,
387+
RADType::HttpHead => http_response(retrieve, context, settings, client).await,
360388
_ => Err(RadError::UnknownRetrieval),
361389
}
362390
}

schemas/witnet/witnet.proto

+2-1
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ message DataRequestOutput {
121121
HttpGet = 1;
122122
Rng = 2;
123123
HttpPost = 3;
124+
HttpHead = 4;
124125
}
125126
message RADFilter {
126127
uint32 op = 1;
@@ -133,7 +134,7 @@ message DataRequestOutput {
133134
bytes script = 3;
134135
// Body of HTTP-POST request
135136
bytes body = 4;
136-
// Extra headers for HTTP-GET and HTTP-POST requests
137+
// Extra headers for HTTP-GET, HTTP-HEAD and HTTP-POST requests
137138
repeated StringPair headers = 5;
138139
}
139140
message RADAggregate {

0 commit comments

Comments
 (0)