1
1
pub mod response;
2
2
3
+ use hyper:: { client:: HttpConnector , Body , Request , StatusCode } ;
4
+ #[ cfg( feature = "hyper-rustls" ) ]
5
+ use hyper_rustls:: HttpsConnector ;
6
+ #[ cfg( feature = "hyper-tls" ) ]
7
+ use hyper_tls:: HttpsConnector ;
8
+
3
9
pub use crate :: client:: response:: * ;
4
10
5
11
use crate :: message:: Message ;
6
- use reqwest:: header:: { AUTHORIZATION , CONTENT_LENGTH , CONTENT_TYPE , RETRY_AFTER } ;
7
- use reqwest:: { Body , StatusCode } ;
8
12
9
13
/// An async client for sending the notification payload.
10
14
pub struct Client {
11
- http_client : reqwest :: Client ,
15
+ http_client : hyper :: Client < HttpsConnector < HttpConnector > > ,
12
16
}
13
17
14
18
impl Default for Client {
@@ -19,40 +23,43 @@ impl Default for Client {
19
23
20
24
impl Client {
21
25
/// Get a new instance of Client.
22
- pub fn new ( ) -> Client {
23
- let http_client = reqwest:: ClientBuilder :: new ( )
24
- . pool_max_idle_per_host ( std:: usize:: MAX )
25
- . build ( )
26
- . unwrap ( ) ;
26
+ pub fn new ( ) -> Self {
27
+ #[ cfg( feature = "hyper-tls" ) ]
28
+ let connector = HttpsConnector :: new ( ) ;
29
+
30
+ #[ cfg( feature = "hyper-rustls" ) ]
31
+ let connector = HttpsConnector :: with_native_roots ( ) ;
27
32
28
- Client { http_client }
33
+ Self {
34
+ http_client : hyper:: Client :: builder ( ) . build :: < _ , Body > ( connector) ,
35
+ }
29
36
}
30
37
31
38
/// Try sending a `Message` to FCM.
32
39
pub async fn send ( & self , message : Message < ' _ > ) -> Result < FcmResponse , FcmError > {
33
40
let payload = serde_json:: to_vec ( & message. body ) . unwrap ( ) ;
34
41
35
- let request = self
36
- . http_client
37
- . post ( "https://fcm.googleapis.com/fcm/send" )
38
- . header ( CONTENT_TYPE , "application/json" )
39
- . header ( CONTENT_LENGTH , format ! ( "{}" , payload. len( ) as u64 ) . as_bytes ( ) )
40
- . header ( AUTHORIZATION , format ! ( "key={}" , message. api_key) . as_bytes ( ) )
41
- . body ( Body :: from ( payload) )
42
- . build ( ) ?;
43
- let response = self . http_client . execute ( request) . await ?;
42
+ let request = Request :: builder ( )
43
+ . method ( "POST" )
44
+ . uri ( "https://fcm.googleapis.com/fcm/send" )
45
+ . header ( "Content-Type" , "application/json" )
46
+ . header ( "Content-Length" , format ! ( "{}" , payload. len( ) as u64 ) )
47
+ . header ( "Athorization" , format ! ( "key={}" , message. api_key) )
48
+ . body ( Body :: from ( payload) ) ?;
49
+ let response = self . http_client . request ( request) . await ?;
44
50
45
51
let response_status = response. status ( ) ;
46
52
47
53
let retry_after = response
48
54
. headers ( )
49
- . get ( RETRY_AFTER )
55
+ . get ( "Retry-After" )
50
56
. and_then ( |ra| ra. to_str ( ) . ok ( ) )
51
57
. and_then ( |ra| ra. parse :: < RetryAfter > ( ) . ok ( ) ) ;
52
58
53
59
match response_status {
54
60
StatusCode :: OK => {
55
- let fcm_response: FcmResponse = response. json ( ) . await . unwrap ( ) ;
61
+ let buf = hyper:: body:: to_bytes ( response) . await ?;
62
+ let fcm_response: FcmResponse = serde_json:: from_slice ( & buf) ?;
56
63
57
64
match fcm_response. error {
58
65
Some ( ErrorReason :: Unavailable ) => Err ( response:: FcmError :: ServerError ( retry_after) ) ,
0 commit comments