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
#[macro_use]
mod macros;
mod config;
mod connection;
mod response;
mod status;
use std::str;
use self::response::ResponseReader;
pub use self::{config::HttpConfig, connection::HttpConnection, status::ConnectorStatus};
use super::{Connection, ConnectionError, ConnectionErrorKind::ResponseError, Connector};
use serial_number::SerialNumber;
pub const USER_AGENT: &str = concat!("yubihsm.rs ", env!("CARGO_PKG_VERSION"));
pub const MAX_RESPONSE_SIZE: usize = 4096;
const CONNECTOR_STATUS_PATH: &str = "/connector/status";
#[derive(Clone, Default, Debug)]
pub struct HttpConnector(HttpConfig);
impl HttpConnector {
pub fn new(config: &HttpConfig) -> Result<Self, ConnectionError> {
Ok(HttpConnector(config.clone()))
}
pub fn status(&self) -> Result<ConnectorStatus, ConnectionError> {
let http_response = HttpConnection::open(&self.0)?.get(CONNECTOR_STATUS_PATH)?;
ConnectorStatus::parse(str::from_utf8(&http_response)?)
}
}
impl Connector for HttpConnector {
fn connect(&self) -> Result<Box<Connection>, ConnectionError> {
Ok(Box::new(HttpConnection::open(&self.0)?))
}
fn healthcheck(&self) -> Result<(), ConnectionError> {
let status = self.status()?;
if status.message == self::status::CONNECTOR_STATUS_OK {
Ok(())
} else {
fail!(
ResponseError,
"yubihsm-connector returned unhealthy /connector/status: {}",
&status.message
);
}
}
fn serial_number(&self) -> Result<SerialNumber, ConnectionError> {
self.status()?.serial_number.ok_or_else(|| {
err!(
ResponseError,
"no serial number in yubihsm-connector /connector/status"
)
})
}
}
impl Into<Box<Connector>> for HttpConnector {
fn into(self) -> Box<Connector> {
Box::new(self)
}
}