-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwebhook.rs
95 lines (87 loc) · 3.13 KB
/
webhook.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
use std::error::Error;
use std::fs::File;
use std::io::Read;
use std::net::TcpListener;
use std::os::unix::net::UnixListener;
use std::process;
use futures::Future;
use hyper;
use hyper::server::conn::Http;
use hyper_tls;
use native_tls;
use tokio::executor::thread_pool::ThreadPool;
use tokio_io::io::AllowStdIo;
use config::{self,TomlConfig};
macro_rules! serve_impl {
( $func_name:ident, $type:ident ) => {
fn $func_name(self) -> Result<(), Box<Error>> {
let mut tls_acceptor = None;
if let Some(ident) = self.identity {
tls_acceptor = native_tls::TlsAcceptor::new(ident).ok();
}
for sock_result in $type::bind(self.config.listen_addr)?.incoming() {
let sock = match sock_result {
Ok(s) => s,
Err(e) => {
error!("{}", e);
continue;
},
};
let stream = if let Some(ref mut acceptor) = tls_acceptor.as_mut() {
let tls_stream = match acceptor.accept(AllowStdIo::new(sock)) {
Ok(ts) => ts,
Err(e) => {
error!("{}", e);
continue;
},
};
hyper_tls::MaybeHttpsStream::from(tls_stream)
} else {
hyper_tls::MaybeHttpsStream::from(AllowStdIo::new(sock))
};
self.pool.spawn(Http::new().serve_connection(stream, hyper::service::service_fn(self.callback))
.map_err(|_| ()));
}
Ok(())
}
}
}
pub enum UseTls {
Yes(String, String),
No,
}
pub struct WebhookServer {
config: TomlConfig,
pool: ThreadPool,
identity: Option<native_tls::Identity>,
callback: fn(hyper::Request<hyper::Body>) -> Result<hyper::Response<hyper::Body>, hyper::Error>
}
impl WebhookServer {
pub fn new(config: TomlConfig, use_tls: UseTls,
service: fn(hyper::Request<hyper::Body>)
-> Result<hyper::Response<hyper::Body>, hyper::Error>)
-> Result<Self, Box<Error>> {
let identity = match use_tls {
UseTls::Yes(identity_path, pw) => {
let mut file = File::open(identity_path)?;
let mut pkcs12 = Vec::new();
file.read_to_end(&mut pkcs12)?;
Some(native_tls::Identity::from_pkcs12(&pkcs12, &pw)?)
},
UseTls::No => None,
};
Ok(WebhookServer { config, pool: ThreadPool::new(), identity, callback: service })
}
serve_impl!(serve_tcp, TcpListener);
serve_impl!(serve_unix, UnixListener);
pub fn serve(self) -> Result<(), Box<Error>> {
match self.config.trigger_type {
config::TriggerType::Webhook => self.serve_tcp(),
config::TriggerType::UnixSocket => self.serve_unix(),
config::TriggerType::UnknownTriggerType => {
error!("Trigger type not recognized - exiting");
process::exit(1);
}
}
}
}