@@ -2,11 +2,15 @@ use std::convert::TryInto;
2
2
use std:: sync:: OnceLock ;
3
3
4
4
use async_trait:: async_trait;
5
- use gleam_core:: { Error , Result } ;
5
+ use camino:: Utf8PathBuf ;
6
+ use gleam_core:: {
7
+ error:: { FileIoAction , FileKind } ,
8
+ Error , Result ,
9
+ } ;
6
10
use http:: { Request , Response } ;
11
+ use reqwest:: { Certificate , Client } ;
7
12
8
- static REQWEST_CLIENT : OnceLock < reqwest:: Client > = OnceLock :: new ( ) ;
9
- static CERTS_ENV_VAR : & str = "GLEAM_CACERTS_PATH" ;
13
+ static REQWEST_CLIENT : OnceLock < Client > = OnceLock :: new ( ) ;
10
14
11
15
#[ derive( Debug ) ]
12
16
pub struct HttpClient ;
@@ -27,11 +31,8 @@ impl gleam_core::io::HttpClient for HttpClient {
27
31
let request = request
28
32
. try_into ( )
29
33
. expect ( "Unable to convert HTTP request for use by reqwest library" ) ;
30
- let mut response = REQWEST_CLIENT
31
- . get_or_init ( init_client)
32
- . execute ( request)
33
- . await
34
- . map_err ( Error :: http) ?;
34
+ let client = init_client ( ) . map_err ( Error :: http) ?;
35
+ let mut response = client. execute ( request) . await . map_err ( Error :: http) ?;
35
36
let mut builder = Response :: builder ( )
36
37
. status ( response. status ( ) )
37
38
. version ( response. version ( ) ) ;
@@ -44,31 +45,36 @@ impl gleam_core::io::HttpClient for HttpClient {
44
45
}
45
46
}
46
47
47
- fn init_client ( ) -> reqwest:: Client {
48
- if let Some ( cert) = get_certificate ( ) {
49
- return reqwest:: Client :: builder ( )
50
- . add_root_certificate ( cert)
51
- . build ( )
52
- . expect ( "Unable to initialize a reqwest HTTP client" ) ;
53
- } else {
54
- return reqwest:: Client :: new ( ) ;
48
+ fn init_client ( ) -> Result < & ' static Client , Error > {
49
+ if let Some ( client) = REQWEST_CLIENT . get ( ) {
50
+ return Ok ( client) ;
55
51
}
56
- }
57
52
58
- fn get_certificate ( ) -> Option < reqwest:: Certificate > {
59
- match std:: env:: var ( CERTS_ENV_VAR ) {
60
- Ok ( certs_path) => {
61
- let data = std:: fs:: read ( certs_path) . expect ( & format ! (
62
- "Unable to read certs file set as `{}`" ,
63
- CERTS_ENV_VAR
64
- ) ) ;
65
- let cert = reqwest:: Certificate :: from_pem ( & data) . expect ( & format ! (
66
- "Unable to construct a certificate from certs file set as `{}`" ,
67
- CERTS_ENV_VAR
68
- ) ) ;
53
+ let certificate_path = std:: env:: var ( "GLEAM_CACERTS_PATH" ) . map_err ( |error| Error :: FileIo {
54
+ kind : FileKind :: Directory ,
55
+ action : FileIoAction :: Read ,
56
+ path : Utf8PathBuf :: new ( ) ,
57
+ err : Some ( error. to_string ( ) ) ,
58
+ } ) ?;
69
59
70
- Some ( cert)
71
- }
72
- _ => None ,
73
- }
60
+ let certificate_bytes = std:: fs:: read ( & certificate_path) . map_err ( |error| Error :: FileIo {
61
+ kind : FileKind :: File ,
62
+ action : FileIoAction :: Parse ,
63
+ path : Utf8PathBuf :: from ( & certificate_path) ,
64
+ err : Some ( error. to_string ( ) ) ,
65
+ } ) ?;
66
+
67
+ let certificate = Certificate :: from_pem ( & certificate_bytes) . map_err ( |error| Error :: FileIo {
68
+ kind : FileKind :: File ,
69
+ action : FileIoAction :: Parse ,
70
+ path : Utf8PathBuf :: from ( & certificate_path) ,
71
+ err : Some ( error. to_string ( ) ) ,
72
+ } ) ?;
73
+
74
+ Ok ( REQWEST_CLIENT . get_or_init ( || {
75
+ Client :: builder ( )
76
+ . add_root_certificate ( certificate)
77
+ . build ( )
78
+ . expect ( "Failed to create reqwest client" )
79
+ } ) )
74
80
}
0 commit comments