Bladeren bron

rpc/jsonrpc: Transparently handle arbitrary protocols for requests.

parazyd 4 jaren geleden
bovenliggende
commit
1b55841418
6 gewijzigde bestanden met toevoegingen van 70 en 65 verwijderingen
  1. 8 7
      bin/cashierd/src/service/eth.rs
  2. 5 7
      bin/darkfid/src/main.rs
  3. 1 1
      bin/drk/src/main.rs
  4. 2 2
      bin/ircd/src/main.rs
  5. 1 1
      bin/map/src/main.rs
  6. 53 47
      src/rpc/jsonrpc.rs

+ 8 - 7
bin/cashierd/src/service/eth.rs

@@ -347,13 +347,14 @@ impl EthClient {
 
     async fn request(&self, r: jsonrpc::JsonRequest) -> EthResult<Value> {
         debug!(target: "ETH RPC", "--> {}", serde_json::to_string(&r)?);
-        let reply: JsonResult = match jsonrpc::send_unix_request(&self.socket_path, json!(r))
-            .await
-            .map_err(EthFailed::from)
-        {
-            Ok(v) => v,
-            Err(e) => return Err(e),
-        };
+        let reply: JsonResult =
+            match jsonrpc::send_request(&format!("unix://{}", self.socket_path), json!(r))
+                .await
+                .map_err(EthFailed::from)
+            {
+                Ok(v) => v,
+                Err(e) => return Err(e),
+            };
 
         match reply {
             JsonResult::Resp(r) => {

+ 5 - 7
bin/darkfid/src/main.rs

@@ -28,8 +28,8 @@ use darkfi::{
     },
     rpc::{
         jsonrpc::{
-            error as jsonerr, request as jsonreq, response as jsonresp, send_raw_request,
-            ErrorCode::*, JsonRequest, JsonResult,
+            error as jsonerr, request as jsonreq, response as jsonresp, send_request, ErrorCode::*,
+            JsonRequest, JsonResult,
         },
         rpcserver::{listen_and_serve, RequestHandler, RpcServerConfig},
     },
@@ -450,7 +450,7 @@ impl Darkfid {
         let req = jsonreq(json!("features"), json!([]));
         let rep: JsonResult =
             // NOTE: this just selects the first cashier in the list
-            match send_raw_request(&self.cashiers[0].rpc_url, json!(req)).await {
+            match send_request(&self.cashiers[0].rpc_url, json!(req)).await {
                 Ok(v) => v,
                 Err(e) => return JsonResult::Err(jsonerr(ServerError(-32004), Some(e.to_string()), id)),
             };
@@ -515,7 +515,7 @@ impl Darkfid {
         // (and token), it shall return a valid address where tokens can be deposited.
         // If not, an error is returned, and forwarded to the method caller.
         let req = jsonreq(json!("deposit"), json!([network, token_id, pubkey]));
-        let rep: JsonResult = match send_raw_request(&self.cashiers[0].rpc_url, json!(req)).await {
+        let rep: JsonResult = match send_request(&self.cashiers[0].rpc_url, json!(req)).await {
             Ok(v) => v,
             Err(e) => {
                 debug!(target: "DARKFID", "REQUEST IS ERR");
@@ -592,9 +592,7 @@ impl Darkfid {
         };
 
         let req = jsonreq(json!("withdraw"), json!([network, token_id, address, amount_in_apo]));
-        let mut rep: JsonResult = match send_raw_request(&self.cashiers[0].rpc_url, json!(req))
-            .await
-        {
+        let mut rep: JsonResult = match send_request(&self.cashiers[0].rpc_url, json!(req)).await {
             Ok(v) => v,
             Err(e) => return JsonResult::Err(jsonerr(ServerError(-32004), Some(e.to_string()), id)),
         };

+ 1 - 1
bin/drk/src/main.rs

@@ -48,7 +48,7 @@ impl Drk {
     }
 
     async fn request(&self, r: jsonrpc::JsonRequest) -> Result<Value> {
-        let reply: JsonResult = match jsonrpc::send_raw_request(&self.url, json!(r)).await {
+        let reply: JsonResult = match jsonrpc::send_request(&self.url, json!(r)).await {
             Ok(v) => v,
             Err(e) => return Err(e),
         };

+ 2 - 2
bin/ircd/src/main.rs

@@ -17,8 +17,8 @@ use darkfi::{
     net,
     rpc::{
         jsonrpc::{
-            error as jsonerr, request as jsonreq, response as jsonresp, send_raw_request,
-            ErrorCode::*, JsonRequest, JsonResult,
+            error as jsonerr, request as jsonreq, response as jsonresp, ErrorCode::*, JsonRequest,
+            JsonResult,
         },
         rpcserver::{listen_and_serve, RequestHandler, RpcServerConfig},
     },

+ 1 - 1
bin/map/src/main.rs

@@ -5,7 +5,7 @@ use tui::{
     Terminal,
 };
 
-use map::{App, ui};
+use map::{ui, App};
 
 fn main() -> Result<(), io::Error> {
     // Set up terminal output

+ 53 - 47
src/rpc/jsonrpc.rs

@@ -9,6 +9,7 @@ use rand::Rng;
 use serde::{Deserialize, Serialize};
 use serde_json::{json, Value};
 use smol::Async;
+use url::Url;
 
 use crate::Error;
 
@@ -140,65 +141,70 @@ pub fn notification(m: Value, p: Value) -> JsonNotification {
     JsonNotification { jsonrpc: json!("2.0"), method: m, params: p }
 }
 
-pub async fn send_raw_request(url: &str, data: Value) -> Result<JsonResult, Error> {
-    let use_tls: bool;
-    let parsed_url = url::Url::parse(url)?;
-
-    match parsed_url.scheme() {
-        "tcp" => use_tls = false,
+pub async fn send_request(uri: &str, data: Value) -> Result<JsonResult, Error> {
+    // let mut use_tor = false;
+    // let mut use_nym = false;
+    let mut use_tcp = false;
+    let mut use_tls = false;
+    let mut use_unix = false;
+
+    let parsed_uri = Url::parse(uri)?;
+    match parsed_uri.scheme() {
+        "tor" => unimplemented!(),
+        "nym" => unimplemented!(),
+        "tcp" => use_tcp = true,
         "tls" => use_tls = true,
-        scheme => {
-            return Err(Error::UrlParseError(format!(
-                "Invalid scheme `{}` found in `{}`",
-                scheme, parsed_url
-            )))
-        }
+        "unix" => use_unix = true,
+        s => unimplemented!("Protocol `{}` not supported.", s),
     }
 
-    let host = parsed_url
-        .host()
-        .ok_or_else(|| Error::UrlParseError(format!("Missing host in {}", url)))?
-        .to_string();
-    let port = parsed_url
-        .port()
-        .ok_or_else(|| Error::UrlParseError(format!("Missing port in {}", url)))?;
-
-    let socket_addr = {
-        let host = host.clone();
-        smol::unblock(move || (host.as_str(), port).to_socket_addrs())
-            .await?
-            .next()
-            .ok_or(Error::NoUrlFound)?
-    };
-
     let mut buf = [0; 2048];
     let bytes_read: usize;
     let data_str = serde_json::to_string(&data)?;
 
-    let mut stream = Async::<TcpStream>::connect(socket_addr).await?;
+    if use_tcp || use_tls {
+        let host = parsed_uri
+            .host()
+            .ok_or_else(|| Error::UrlParseError(format!("Missing host in {}", uri)))?
+            .to_string();
+        let port = parsed_uri
+            .port()
+            .ok_or_else(|| Error::UrlParseError(format!("Missing port in {}", uri)))?;
+
+        let socket_addr = {
+            let host = host.clone();
+            smol::unblock(move || (host.as_str(), port).to_socket_addrs())
+                .await?
+                .next()
+                .ok_or(Error::NoUrlFound)?
+        };
 
-    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 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])?;
+        return Ok(reply)
     }
 
-    let reply: JsonResult = serde_json::from_slice(&buf[0..bytes_read])?;
-    Ok(reply)
-}
+    if use_unix {
+        let path = uri.strip_prefix("unix://").unwrap();
 
-pub async fn send_unix_request(path: &str, data: Value) -> Result<JsonResult, Error> {
-    let mut buf = [0; 2048];
-    let data_str = serde_json::to_string(&data)?;
+        let mut stream = Async::<UnixStream>::connect(path).await?;
+        stream.write_all(data_str.as_bytes()).await?;
 
-    let mut stream = Async::<UnixStream>::connect(path).await?;
-    stream.write_all(data_str.as_bytes()).await?;
+        bytes_read = stream.read(&mut buf[..]).await?;
 
-    let bytes_read: usize = stream.read(&mut buf[..]).await?;
+        let reply: JsonResult = serde_json::from_slice(&buf[0..bytes_read])?;
+        return Ok(reply)
+    }
 
-    let reply: JsonResult = serde_json::from_slice(&buf[0..bytes_read])?;
-    Ok(reply)
+    unreachable!();
 }