@@ -19,20 +19,100 @@ fn get_source() -> String {
1919 std:: env:: var ( "CORGEA_SOURCE" ) . unwrap_or_else ( |_| "cli" . to_string ( ) )
2020}
2121
22- pub fn http_client ( ) -> reqwest:: blocking:: Client {
23- let mut builder =
24- reqwest:: blocking:: Client :: builder ( ) . timeout ( std:: time:: Duration :: from_secs ( 5 * 30 ) ) ;
22+ static COOKIE_JAR : std:: sync:: LazyLock < std:: sync:: Arc < reqwest:: cookie:: Jar > > =
23+ std:: sync:: LazyLock :: new ( || std:: sync:: Arc :: new ( reqwest:: cookie:: Jar :: default ( ) ) ) ;
2524
26- if let Ok ( https_proxy) = std:: env:: var ( "https_proxy" ) {
27- debug ( & format ! ( "https_proxy detected: {}" , https_proxy) ) ;
25+ static SHARED_CLIENT : std:: sync:: LazyLock < reqwest:: blocking:: Client > =
26+ std:: sync:: LazyLock :: new ( || {
27+ let mut builder = reqwest:: blocking:: Client :: builder ( )
28+ . timeout ( std:: time:: Duration :: from_secs ( 5 * 30 ) )
29+ . cookie_provider ( COOKIE_JAR . clone ( ) ) ;
2830
29- if std:: env:: var ( "CORGEA_ACCEPT_CERT" ) . is_ok ( ) {
30- debug ( & format ! ( "Skipping CA cert validation" ) ) ;
31- builder = builder. danger_accept_invalid_certs ( true ) ;
31+ if let Ok ( https_proxy) = std:: env:: var ( "https_proxy" ) {
32+ debug ( & format ! ( "https_proxy detected: {}" , https_proxy) ) ;
33+
34+ if std:: env:: var ( "CORGEA_ACCEPT_CERT" ) . is_ok ( ) {
35+ debug ( & format ! ( "Skipping CA cert validation" ) ) ;
36+ builder = builder. danger_accept_invalid_certs ( true ) ;
37+ }
3238 }
39+
40+ builder. build ( ) . expect ( "Failed to build http client" )
41+ } ) ;
42+
43+ pub struct HttpClient {
44+ inner : reqwest:: blocking:: Client ,
45+ }
46+
47+ pub struct DebugRequestBuilder {
48+ client : reqwest:: blocking:: Client ,
49+ inner : reqwest:: blocking:: RequestBuilder ,
50+ }
51+
52+ impl HttpClient {
53+ pub fn get < U : reqwest:: IntoUrl > ( & self , url : U ) -> DebugRequestBuilder {
54+ DebugRequestBuilder { client : self . inner . clone ( ) , inner : self . inner . get ( url) }
3355 }
3456
35- builder. build ( ) . expect ( "Failed to build http client" )
57+ pub fn post < U : reqwest:: IntoUrl > ( & self , url : U ) -> DebugRequestBuilder {
58+ DebugRequestBuilder { client : self . inner . clone ( ) , inner : self . inner . post ( url) }
59+ }
60+
61+ pub fn patch < U : reqwest:: IntoUrl > ( & self , url : U ) -> DebugRequestBuilder {
62+ DebugRequestBuilder { client : self . inner . clone ( ) , inner : self . inner . patch ( url) }
63+ }
64+ }
65+
66+ impl DebugRequestBuilder {
67+ pub fn header < K , V > ( self , key : K , value : V ) -> Self
68+ where
69+ reqwest:: header:: HeaderName : TryFrom < K > ,
70+ <reqwest:: header:: HeaderName as TryFrom < K > >:: Error : Into < http:: Error > ,
71+ reqwest:: header:: HeaderValue : TryFrom < V > ,
72+ <reqwest:: header:: HeaderValue as TryFrom < V > >:: Error : Into < http:: Error > ,
73+ {
74+ Self { inner : self . inner . header ( key, value) , client : self . client }
75+ }
76+
77+ pub fn headers ( self , headers : reqwest:: header:: HeaderMap ) -> Self {
78+ Self { inner : self . inner . headers ( headers) , client : self . client }
79+ }
80+
81+ pub fn query < T : Serialize + ?Sized > ( self , query : & T ) -> Self {
82+ Self { inner : self . inner . query ( query) , client : self . client }
83+ }
84+
85+ pub fn multipart ( self , form : reqwest:: blocking:: multipart:: Form ) -> Self {
86+ Self { inner : self . inner . multipart ( form) , client : self . client }
87+ }
88+
89+ pub fn body < T : Into < reqwest:: blocking:: Body > > ( self , body : T ) -> Self {
90+ Self { inner : self . inner . body ( body) , client : self . client }
91+ }
92+
93+ pub fn send ( self ) -> reqwest:: Result < reqwest:: blocking:: Response > {
94+ use reqwest:: cookie:: CookieStore ;
95+
96+ let request = self . inner . build ( ) ?;
97+
98+ debug ( & format ! ( "→ {} {}" , request. method( ) , request. url( ) ) ) ;
99+ debug ( & format ! ( " Request headers: {:?}" , request. headers( ) ) ) ;
100+ match COOKIE_JAR . cookies ( request. url ( ) ) {
101+ Some ( cookies) => debug ( & format ! ( " Cookie: {}" , cookies. to_str( ) . unwrap_or( "<binary>" ) ) ) ,
102+ None => debug ( " Cookie: (none in jar for this URL)" ) ,
103+ }
104+
105+ let response = self . client . execute ( request) ?;
106+
107+ debug ( & format ! ( "← {} {}" , response. status( ) , response. url( ) ) ) ;
108+ debug ( & format ! ( " Response headers: {:?}" , response. headers( ) ) ) ;
109+
110+ Ok ( response)
111+ }
112+ }
113+
114+ pub fn http_client ( ) -> HttpClient {
115+ HttpClient { inner : SHARED_CLIENT . clone ( ) }
36116}
37117
38118fn check_for_warnings ( headers : & HeaderMap , status : StatusCode ) {
0 commit comments