Skip to content

Commit d6b987d

Browse files
committed
Add execute_with_headers method to Transport trait to allow passing HTTP headers
1 parent 68f2a6d commit d6b987d

File tree

13 files changed

+69
-38
lines changed

13 files changed

+69
-38
lines changed

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ edition = "2018"
1414
[dependencies]
1515
arrayvec = "0.7.1"
1616
derive_more = "0.99.1"
17-
ethabi = "17.0.0"
18-
ethereum-types = "0.13.0"
17+
ethabi = "18.0.0"
18+
ethereum-types = "0.14.1"
1919
futures = "0.3.5"
2020
futures-timer = "3.0.2"
2121
hex = "0.4"

examples/bench.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ where
3030
for _ in 0..max {
3131
let ticker = ticker.clone();
3232
ticker.start();
33-
let accounts = web3.eth().block_number().then(move |res| {
33+
let accounts = web3.eth().block_number(None).then(move |res| {
3434
if let Err(e) = res {
3535
println!("Error: {:?}", e);
3636
}

examples/transport_batch.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ async fn main() -> web3::Result {
55
let web3 = web3::Web3::new(web3::transports::Batch::new(http));
66

77
let accounts = web3.eth().accounts();
8-
let block = web3.eth().block_number();
8+
let block = web3.eth().block_number(None);
99

1010
let result = web3.transport().submit_batch().await?;
1111
println!("Result: {:?}", result);

src/api/eth.rs

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! `Eth` namespace
22
3+
use headers::HeaderMap;
4+
35
use crate::{
46
api::Namespace,
57
helpers::{self, CallFuture},
@@ -37,8 +39,8 @@ impl<T: Transport> Eth<T> {
3739
}
3840

3941
/// Get current block number
40-
pub fn block_number(&self) -> CallFuture<U64, T::Out> {
41-
CallFuture::new(self.transport.execute("eth_blockNumber", vec![]))
42+
pub fn block_number(&self, headers: Option<HeaderMap>) -> CallFuture<U64, T::Out> {
43+
CallFuture::new(self.transport.execute_with_headers("eth_blockNumber", vec![], headers))
4244
}
4345

4446
/// Call a constant method of contract without changing the state of the blockchain.
@@ -116,23 +118,28 @@ impl<T: Transport> Eth<T> {
116118
}
117119

118120
/// Get all logs matching a given filter object
119-
pub fn logs(&self, filter: Filter) -> CallFuture<Vec<Log>, T::Out> {
121+
pub fn logs(&self, filter: Filter, headers: Option<HeaderMap>) -> CallFuture<Vec<Log>, T::Out> {
120122
let filter = helpers::serialize(&filter);
121-
CallFuture::new(self.transport.execute("eth_getLogs", vec![filter]))
123+
CallFuture::new(
124+
self.transport
125+
.execute_with_headers("eth_getLogs", vec![filter], headers),
126+
)
122127
}
123128

124129
/// Get block details with transaction hashes.
125-
pub fn block(&self, block: BlockId) -> CallFuture<Option<Block<H256>>, T::Out> {
130+
pub fn block(&self, block: BlockId, headers: Option<HeaderMap>) -> CallFuture<Option<Block<H256>>, T::Out> {
126131
let include_txs = helpers::serialize(&false);
127132

128133
let result = match block {
129134
BlockId::Hash(hash) => {
130135
let hash = helpers::serialize(&hash);
131-
self.transport.execute("eth_getBlockByHash", vec![hash, include_txs])
136+
self.transport
137+
.execute_with_headers("eth_getBlockByHash", vec![hash, include_txs], headers)
132138
}
133139
BlockId::Number(num) => {
134140
let num = helpers::serialize(&num);
135-
self.transport.execute("eth_getBlockByNumber", vec![num, include_txs])
141+
self.transport
142+
.execute_with_headers("eth_getBlockByNumber", vec![num, include_txs], headers)
136143
}
137144
};
138145

@@ -558,7 +565,7 @@ mod tests {
558565
);
559566

560567
rpc_test! (
561-
Eth:block_number => "eth_blockNumber";
568+
Eth:block_number, None => "eth_blockNumber", Vec::<String>::new();
562569
Value::String("0x123".into()) => 0x123
563570
);
564571

@@ -653,21 +660,21 @@ mod tests {
653660
);
654661

655662
rpc_test! (
656-
Eth:logs, FilterBuilder::default().build() => "eth_getLogs", vec!["{}"];
663+
Eth:logs, FilterBuilder::default().build(), None => "eth_getLogs", vec!["{}"];
657664
Value::Array(vec![::serde_json::from_str(EXAMPLE_LOG).unwrap()])
658665
=> vec![::serde_json::from_str::<Log>(EXAMPLE_LOG).unwrap()]
659666
);
660667

661668
rpc_test! (
662-
Eth:block:block_by_hash, BlockId::Hash(H256::from_low_u64_be(0x123))
669+
Eth:block:block_by_hash, BlockId::Hash(H256::from_low_u64_be(0x123)), None
663670
=>
664671
"eth_getBlockByHash", vec![r#""0x0000000000000000000000000000000000000000000000000000000000000123""#, r#"false"#];
665672
::serde_json::from_str(EXAMPLE_BLOCK).unwrap()
666673
=> Some(::serde_json::from_str::<Block<H256>>(EXAMPLE_BLOCK).unwrap())
667674
);
668675

669676
rpc_test! (
670-
Eth:block, BlockNumber::Pending
677+
Eth:block, BlockNumber::Pending, None
671678
=>
672679
"eth_getBlockByNumber", vec![r#""pending""#, r#"false"#];
673680
::serde_json::from_str(EXAMPLE_PENDING_BLOCK).unwrap()

src/confirm.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ where
5555
loop {
5656
let _ = filter_stream.next().await;
5757
if let Some(confirmation_block_number) = check.check().await? {
58-
let block_number = eth.block_number().await?;
58+
let block_number = eth.block_number(None).await?;
5959
if confirmation_block_number.low_u64() + confirmations as u64 <= block_number.low_u64() {
6060
return Ok(());
6161
}

src/contract/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ impl<T: Transport> Contract<T> {
310310

311311
let logs = self
312312
.eth
313-
.logs(FilterBuilder::default().topic_filter(filter).build())
313+
.logs(FilterBuilder::default().topic_filter(filter).build(), None)
314314
.await?;
315315
logs.into_iter()
316316
.map(move |l| {

src/lib.rs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
// select! in WS transport
1212
#![recursion_limit = "256"]
1313

14+
use headers::HeaderMap;
1415
use jsonrpc_core as rpc;
1516

1617
/// Re-export of the `futures` crate.
@@ -52,12 +53,18 @@ pub trait Transport: std::fmt::Debug + Clone {
5253
fn prepare(&self, method: &str, params: Vec<rpc::Value>) -> (RequestId, rpc::Call);
5354

5455
/// Execute prepared RPC call.
55-
fn send(&self, id: RequestId, request: rpc::Call) -> Self::Out;
56+
fn send(&self, id: RequestId, request: rpc::Call, headers: Option<HeaderMap>) -> Self::Out;
5657

5758
/// Execute remote method with given parameters.
5859
fn execute(&self, method: &str, params: Vec<rpc::Value>) -> Self::Out {
5960
let (id, request) = self.prepare(method, params);
60-
self.send(id, request)
61+
self.send(id, request, None)
62+
}
63+
64+
/// Execute remote method with given parameters and headers.
65+
fn execute_with_headers(&self, method: &str, params: Vec<rpc::Value>, headers: Option<HeaderMap>) -> Self::Out {
66+
let (id, request) = self.prepare(method, params);
67+
self.send(id, request, headers)
6168
}
6269
}
6370

@@ -97,8 +104,8 @@ where
97104
(**self).prepare(method, params)
98105
}
99106

100-
fn send(&self, id: RequestId, request: rpc::Call) -> Self::Out {
101-
(**self).send(id, request)
107+
fn send(&self, id: RequestId, request: rpc::Call, headers: Option<HeaderMap>) -> Self::Out {
108+
(**self).send(id, request, headers)
102109
}
103110
}
104111

@@ -143,6 +150,7 @@ mod tests {
143150

144151
use crate::api::Web3;
145152
use futures::future::BoxFuture;
153+
use headers::HeaderMap;
146154
use std::sync::Arc;
147155

148156
#[derive(Debug, Clone)]
@@ -155,7 +163,7 @@ mod tests {
155163
unimplemented!()
156164
}
157165

158-
fn send(&self, _id: RequestId, _request: rpc::Call) -> Self::Out {
166+
fn send(&self, _id: RequestId, _request: rpc::Call, _headers: Option<HeaderMap>) -> Self::Out {
159167
unimplemented!()
160168
}
161169
}

src/transports/batch.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use futures::{
99
task::{Context, Poll},
1010
Future, FutureExt,
1111
};
12+
use headers::HeaderMap;
1213
use parking_lot::Mutex;
1314
use std::{collections::BTreeMap, pin::Pin, sync::Arc};
1415

@@ -72,7 +73,7 @@ where
7273
self.transport.prepare(method, params)
7374
}
7475

75-
fn send(&self, id: RequestId, request: rpc::Call) -> Self::Out {
76+
fn send(&self, id: RequestId, request: rpc::Call, _headers: Option<HeaderMap>) -> Self::Out {
7677
let (tx, rx) = oneshot::channel();
7778
self.pending.lock().insert(id, tx);
7879
self.batch.lock().push((id, request));

src/transports/either.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use futures::{
55
future::{BoxFuture, FutureExt},
66
stream::{BoxStream, StreamExt},
77
};
8+
use headers::HeaderMap;
89

910
/// A wrapper over two possible transports.
1011
///
@@ -36,10 +37,10 @@ where
3637
}
3738
}
3839

39-
fn send(&self, id: RequestId, request: rpc::Call) -> Self::Out {
40+
fn send(&self, id: RequestId, request: rpc::Call, headers: Option<HeaderMap>) -> Self::Out {
4041
match *self {
41-
Self::Left(ref a) => a.send(id, request).boxed(),
42-
Self::Right(ref b) => b.send(id, request).boxed(),
42+
Self::Left(ref a) => a.send(id, request, headers).boxed(),
43+
Self::Right(ref b) => b.send(id, request, headers).boxed(),
4344
}
4445
}
4546
}

src/transports/http.rs

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use crate::{
88
use futures::future::BoxFuture;
99
#[cfg(feature = "wasm")]
1010
use futures::future::LocalBoxFuture as BoxFuture;
11+
use headers::HeaderMap;
1112
use jsonrpc_core::types::{Call, Output, Request, Value};
1213
use reqwest::{Client, Url};
1314
use serde::de::DeserializeOwned;
@@ -73,11 +74,21 @@ impl Http {
7374
}
7475

7576
// Id is only used for logging.
76-
async fn execute_rpc<T: DeserializeOwned>(client: &Client, url: Url, request: &Request, id: RequestId) -> Result<T> {
77+
async fn execute_rpc<T: DeserializeOwned>(
78+
client: &Client,
79+
url: Url,
80+
request: &Request,
81+
id: RequestId,
82+
headers: Option<HeaderMap>,
83+
) -> Result<T> {
7784
log::debug!("[id:{}] sending request: {:?}", id, serde_json::to_string(&request)?);
78-
let response = client
79-
.post(url)
80-
.json(request)
85+
let mut request_builder = client.post(url).json(request);
86+
87+
if let Some(headers) = headers {
88+
request_builder = request_builder.headers(headers);
89+
}
90+
91+
let response = request_builder
8192
.send()
8293
.await
8394
.map_err(|err| Error::Transport(TransportError::Message(format!("failed to send request: {}", err))))?;
@@ -116,10 +127,10 @@ impl Transport for Http {
116127
(id, request)
117128
}
118129

119-
fn send(&self, id: RequestId, call: Call) -> Self::Out {
130+
fn send(&self, id: RequestId, call: Call, headers: Option<HeaderMap>) -> Self::Out {
120131
let (client, url) = self.new_request();
121132
Box::pin(async move {
122-
let output: Output = execute_rpc(&client, url, &Request::Single(call), id).await?;
133+
let output: Output = execute_rpc(&client, url, &Request::Single(call), id, headers).await?;
123134
helpers::to_result_from_output(output)
124135
})
125136
}
@@ -137,7 +148,7 @@ impl BatchTransport for Http {
137148
let (client, url) = self.new_request();
138149
let (ids, calls): (Vec<_>, Vec<_>) = requests.into_iter().unzip();
139150
Box::pin(async move {
140-
let outputs: Vec<Output> = execute_rpc(&client, url, &Request::Batch(calls), id).await?;
151+
let outputs: Vec<Output> = execute_rpc(&client, url, &Request::Batch(calls), id, None).await?;
141152
handle_batch_response(&ids, outputs)
142153
})
143154
}

0 commit comments

Comments
 (0)