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
96
97
98
99
use std::io::{Error, ErrorKind};
use prost::bytes::Bytes;
use tonic::transport::Channel;
pub struct Client {
inner: avalanche_proto::http::http_client::HttpClient<Channel>,
}
impl Client {
pub fn new(client_conn: Channel) -> Box<dyn crate::rpcchainvm::http::Handler + Send + Sync> {
Box::new(Client {
inner: avalanche_proto::http::http_client::HttpClient::new(client_conn),
})
}
}
#[tonic::async_trait]
impl crate::rpcchainvm::http::Handler for Client {
async fn serve_http(
&mut self,
_req: http::Request<Vec<u8>>,
) -> std::io::Result<http::Response<Vec<u8>>> {
Err(std::io::Error::new(
ErrorKind::Other,
format!("not implemented"),
))
}
async fn serve_http_simple(
&mut self,
req: http::Request<Vec<u8>>,
) -> std::io::Result<http::Response<Vec<u8>>> {
let req = get_http_simple_request(req)?;
let resp = self.inner.handle_simple(req).await.map_err(|e| {
Error::new(
ErrorKind::Other,
format!("handle simple request failed: {:?}", e),
)
})?;
get_http_response(resp.into_inner())
}
}
fn get_http_simple_request(
req: http::Request<Vec<u8>>,
) -> std::io::Result<avalanche_proto::http::HandleSimpleHttpRequest> {
let headers = convert_to_proto_headers(req.headers())?;
Ok(avalanche_proto::http::HandleSimpleHttpRequest {
method: req.method().to_string(),
url: req.uri().to_string(),
body: Bytes::from(req.body().to_owned()),
headers: headers,
})
}
fn get_http_response(
resp: avalanche_proto::http::HandleSimpleHttpResponse,
) -> std::io::Result<http::Response<Vec<u8>>> {
let mut http_resp = http::Response::builder().status(resp.code as u16);
for header in resp.headers.into_iter() {
http_resp = http_resp.header(header.key, header.values.concat());
}
let http_resp = http_resp
.body(resp.body.to_vec())
.map_err(|e| {
Error::new(
ErrorKind::Other,
format!("failed to generate http response {:?}", e),
)
})
.unwrap();
Ok(http_resp)
}
fn convert_to_proto_headers(
headers: &http::HeaderMap<http::HeaderValue>,
) -> std::io::Result<Vec<avalanche_proto::http::Element>> {
let mut vec_headers: Vec<avalanche_proto::http::Element> =
Vec::with_capacity(headers.keys_len());
for (key, value) in headers.into_iter() {
let element = avalanche_proto::http::Element {
key: key.to_string(),
values: vec![String::from_utf8_lossy(value.as_bytes()).to_string()],
};
vec_headers.push(element);
}
Ok(vec_headers)
}