rpc/jsonrpc: Support TLS in send_request.

This implies all URLs passed to the function should have a schema.

tcp:// or tls:// are supported.
This commit is contained in:
parazyd
2021-09-23 20:04:56 +02:00
parent 110c7d6770
commit 967b0e0f31
4 changed files with 45 additions and 8 deletions

1
Cargo.lock generated
View File

@@ -1208,6 +1208,7 @@ dependencies = [
"spl-token",
"tokio-tungstenite",
"toml",
"url",
"zcash_primitives",
"zcash_proofs",
"zeromq",

View File

@@ -49,6 +49,7 @@ log = "0.4.14"
clap = "2.33.3"
toml = "0.5.8"
dirs = "4.0.0"
url = "2.2.2"
serde = { version = "1.0.126", features = ["derive"]}
serde_json = "1.0.61"
bytes = "1.0.1"

View File

@@ -16,6 +16,7 @@ pub enum Error {
ParseFailed(&'static str),
ParseIntError,
ParseFloatError,
UrlParseError,
AsyncChannelSenderError,
AsyncChannelReceiverError,
AsyncNativeTlsError,
@@ -75,6 +76,7 @@ impl fmt::Display for Error {
Error::ParseFailed(ref err) => write!(f, "parse failed: {}", err),
Error::ParseIntError => f.write_str("Parse int error"),
Error::ParseFloatError => f.write_str("Parse float error"),
Error::UrlParseError => f.write_str("Failed to parse URL"),
Error::AsyncChannelSenderError => f.write_str("Async_channel sender error"),
Error::AsyncChannelReceiverError => f.write_str("Async_channel receiver error"),
Error::AsyncNativeTlsError => f.write_str("Async_Native_TLS error"),
@@ -195,6 +197,12 @@ impl From<std::net::AddrParseError> for Error {
}
}
impl From<url::ParseError> for Error {
fn from(_err: url::ParseError) -> Error {
Error::UrlParseError
}
}
impl From<std::num::ParseIntError> for Error {
fn from(_err: std::num::ParseIntError) -> Error {
Error::ParseIntError

View File

@@ -1,12 +1,11 @@
use std::net::{TcpStream, ToSocketAddrs};
use std::str;
use async_std::{
io::{ReadExt, WriteExt},
net::TcpStream,
};
use async_std::io::{ReadExt, WriteExt};
use rand::Rng;
use serde::{Deserialize, Serialize};
use serde_json::{json, Value};
use smol::Async;
use crate::Error;
@@ -133,13 +132,41 @@ pub fn notification(m: Value, p: Value) -> JsonNotification {
}
pub async fn send_request(url: &str, data: Value) -> Result<JsonResult, Error> {
// TODO: TLS
let use_tls: bool;
let parsed_url = url::Url::parse(url)?;
match parsed_url.scheme() {
"tcp" => use_tls = false,
"tls" => use_tls = true,
_ => return Err(Error::UrlParseError),
}
// TODO: Error handling
let host = parsed_url.host().unwrap().to_string();
let port = parsed_url.port().unwrap();
let socket_addr = {
let host = host.clone();
smol::unblock(move || (host.as_str(), port).to_socket_addrs())
.await?
.next()
.ok_or_else(|| Error::UrlParseError)?
};
let mut buf = [0; 2048];
let mut stream = TcpStream::connect(url).await?;
let bytes_read: usize;
let data_str = serde_json::to_string(&data)?;
stream.write_all(&data_str.as_bytes()).await?;
let bytes_read = stream.read(&mut buf[..]).await?;
let mut stream = Async::<TcpStream>::connect(socket_addr).await?;
if use_tls {
let mut stream = async_native_tls::connect(&host, stream).await?;
stream.write_all(&data_str.as_bytes()).await?;
bytes_read = stream.read(&mut buf[..]).await?;
} else {
stream.write_all(&data_str.as_bytes()).await?;
bytes_read = stream.read(&mut buf[..]).await?;
}
let reply: JsonResult = serde_json::from_slice(&buf[0..bytes_read])?;
Ok(reply)