https support for webhooks (#2660)

* add TLS support
* configurable nthreads and timeout
This commit is contained in:
Mike Dallas 2019-03-12 12:23:40 +00:00 committed by hashmap
parent c3496b45dd
commit a58d671853
4 changed files with 45 additions and 5 deletions

1
Cargo.lock generated
View file

@ -888,6 +888,7 @@ dependencies = [
"grin_util 1.1.0", "grin_util 1.1.0",
"http 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.12.24 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.12.24 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper-rustls 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
"lmdb-zero 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "lmdb-zero 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",

View file

@ -11,6 +11,7 @@ edition = "2018"
[dependencies] [dependencies]
hyper = "0.12" hyper = "0.12"
hyper-rustls = "0.14"
fs2 = "0.4" fs2 = "0.4"
futures = "0.1" futures = "0.1"
http = "0.1" http = "0.1"

View file

@ -16,20 +16,23 @@
//! callback simply implement the coresponding trait and add it to the init function //! callback simply implement the coresponding trait and add it to the init function
extern crate hyper; extern crate hyper;
extern crate hyper_rustls;
extern crate tokio; extern crate tokio;
use crate::chain::BlockStatus; use crate::chain::BlockStatus;
use crate::common::types::{ServerConfig, WebHooksConfig}; use crate::common::types::{ServerConfig, WebHooksConfig};
use crate::core::core; use crate::core::core;
use crate::core::core::hash::Hashed; use crate::core::core::hash::Hashed;
use crate::p2p::types::PeerAddr;
use futures::future::Future; use futures::future::Future;
use hyper::client::HttpConnector; use hyper::client::HttpConnector;
use hyper::header::HeaderValue; use hyper::header::HeaderValue;
use hyper::Client; use hyper::Client;
use hyper::{Body, Method, Request}; use hyper::{Body, Method, Request};
use hyper_rustls::HttpsConnector;
use serde::Serialize; use serde::Serialize;
use serde_json::{json, to_string}; use serde_json::{json, to_string};
use crate::p2p::types::PeerAddr; use std::time::Duration;
use tokio::runtime::Runtime; use tokio::runtime::Runtime;
/// Returns the list of event hooks that will be initialized for network events /// Returns the list of event hooks that will be initialized for network events
@ -150,8 +153,11 @@ fn parse_url(value: &Option<String>) -> Option<hyper::Uri> {
Err(_) => panic!("Invalid url : {}", url), Err(_) => panic!("Invalid url : {}", url),
}; };
let scheme = uri.scheme_part().map(|s| s.as_str()); let scheme = uri.scheme_part().map(|s| s.as_str());
if scheme != Some("http") { if (scheme != Some("http")) && (scheme != Some("https")) {
panic!("Invalid url scheme {}, expected 'http'", url) panic!(
"Invalid url scheme {}, expected one of ['http', https']",
url
)
}; };
Some(uri) Some(uri)
} }
@ -170,7 +176,7 @@ struct WebHook {
/// url to POST block data when a new block is accepted by our node (might be a reorg or a fork) /// url to POST block data when a new block is accepted by our node (might be a reorg or a fork)
block_accepted_url: Option<hyper::Uri>, block_accepted_url: Option<hyper::Uri>,
/// The hyper client to be used for all requests /// The hyper client to be used for all requests
client: Client<HttpConnector>, client: Client<HttpsConnector<HttpConnector>>,
/// The tokio event loop /// The tokio event loop
runtime: Runtime, runtime: Runtime,
} }
@ -182,13 +188,27 @@ impl WebHook {
header_received_url: Option<hyper::Uri>, header_received_url: Option<hyper::Uri>,
block_received_url: Option<hyper::Uri>, block_received_url: Option<hyper::Uri>,
block_accepted_url: Option<hyper::Uri>, block_accepted_url: Option<hyper::Uri>,
nthreads: u16,
timeout: u16,
) -> WebHook { ) -> WebHook {
let keep_alive = Duration::from_secs(timeout as u64);
info!(
"Spawning {} threads for webhooks (timeout set to {} secs)",
nthreads, timeout
);
let https = HttpsConnector::new(nthreads as usize);
let client = Client::builder()
.keep_alive_timeout(keep_alive)
.build::<_, hyper::Body>(https);
WebHook { WebHook {
tx_received_url, tx_received_url,
block_received_url, block_received_url,
header_received_url, header_received_url,
block_accepted_url, block_accepted_url,
client: Client::new(), client,
runtime: Runtime::new().unwrap(), runtime: Runtime::new().unwrap(),
} }
} }
@ -200,6 +220,8 @@ impl WebHook {
parse_url(&config.header_received_url), parse_url(&config.header_received_url),
parse_url(&config.block_received_url), parse_url(&config.block_received_url),
parse_url(&config.block_accepted_url), parse_url(&config.block_accepted_url),
config.nthreads,
config.timeout,
) )
} }

View file

@ -248,6 +248,20 @@ pub struct WebHooksConfig {
pub block_received_url: Option<String>, pub block_received_url: Option<String>,
/// url to POST block data when a new block is accepted by our node (might be a reorg or a fork) /// url to POST block data when a new block is accepted by our node (might be a reorg or a fork)
pub block_accepted_url: Option<String>, pub block_accepted_url: Option<String>,
/// number of worker threads in the tokio runtime
#[serde(default = "default_nthreads")]
pub nthreads: u16,
/// timeout in seconds for the http request
#[serde(default = "default_timeout")]
pub timeout: u16,
}
fn default_timeout() -> u16 {
10
}
fn default_nthreads() -> u16 {
4
} }
impl Default for WebHooksConfig { impl Default for WebHooksConfig {
@ -257,6 +271,8 @@ impl Default for WebHooksConfig {
header_received_url: None, header_received_url: None,
block_received_url: None, block_received_url: None,
block_accepted_url: None, block_accepted_url: None,
nthreads: default_nthreads(),
timeout: default_timeout(),
} }
} }
} }