telegram_bot_fork/connector/
hyper.rs1use std::{fmt, rc::Rc, str::FromStr};
4
5use futures::{future::result, Future, Stream};
6use hyper::{
7 self,
8 client::{connect::Connect, Client},
9 Body, Method, Request, Uri,
10};
11use hyper_tls::HttpsConnector;
12
13use telegram_bot_fork_raw::{
14 Body as TelegramBody, HttpRequest, HttpResponse, Method as TelegramMethod,
15};
16
17use errors::Error;
18use future::{NewTelegramFuture, TelegramFuture};
19
20use super::_base::Connector;
21
22pub struct HyperConnector<C> {
24 inner: Rc<Client<C>>,
25}
26
27impl<C> fmt::Debug for HyperConnector<C> {
28 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
29 "hyper connector".fmt(formatter)
30 }
31}
32
33impl<C> HyperConnector<C> {
34 pub fn new(client: Client<C>) -> Self {
35 HyperConnector {
36 inner: Rc::new(client),
37 }
38 }
39}
40
41impl<C: Connect + 'static> Connector for HyperConnector<C> {
42 fn request(
43 &self,
44 url: Option<&str>,
45 token: &str,
46 req: HttpRequest,
47 ) -> TelegramFuture<HttpResponse> {
48 let uri = result(Uri::from_str(&req.url.url(url, token))).from_err();
49
50 let client = self.inner.clone();
51 let request = uri.and_then(move |uri| {
52 let method = match req.method {
53 TelegramMethod::Get => Method::GET,
54 TelegramMethod::Post => Method::POST,
55 };
56 let mut builder = Request::builder();
57 let http_request = builder.method(method).uri(uri);
58
59 let http_request = match req.body {
60 TelegramBody::Empty => http_request.body(Body::empty()).unwrap(),
61 TelegramBody::Json(body) => {
62 let mut r = http_request.body(body.into()).unwrap();
63 r.headers_mut().insert(
64 hyper::header::CONTENT_TYPE,
65 "application/json".parse().unwrap(),
66 );
67 r
68 }
69 body => panic!("Unknown body type {:?}", body),
70 };
71
72 client.request(http_request).from_err()
73 });
74
75 let future = request.and_then(move |response| {
76 response.into_body().from_err().fold(
77 vec![],
78 |mut result, chunk| -> Result<Vec<u8>, Error> {
79 result.extend_from_slice(&chunk);
80 Ok(result)
81 },
82 )
83 });
84
85 let future = future.and_then(|body| Ok(HttpResponse { body: Some(body) }));
86
87 TelegramFuture::new(Box::new(future))
88 }
89}
90
91pub fn default_connector() -> Result<Box<Connector>, Error> {
93 let connector = HttpsConnector::new(1).map_err(|err| {
94 ::std::io::Error::new(::std::io::ErrorKind::Other, format!("tls error: {}", err))
95 })?;
96 let client = Client::builder().build(connector);
97 Ok(Box::new(HyperConnector::new(client)))
98}