44#![ warn( missing_docs) ]
55#![ cfg_attr( docsrs, feature( doc_cfg, doc_auto_cfg) ) ]
66
7+ use std:: convert:: Infallible ;
78use std:: error:: Error as StdError ;
89use std:: fmt;
910use std:: future:: Future ;
1011use std:: pin:: Pin ;
1112use std:: str:: FromStr ;
13+ use std:: task:: { Context , Poll } ;
1214use std:: time:: { Duration , SystemTime } ;
1315
1416use async_trait:: async_trait;
15- use bytes:: Bytes ;
17+ use bytes:: { Buf , Bytes } ;
1618use http:: header:: { CONTENT_TYPE , RETRY_AFTER } ;
1719use http:: { Method , Request , Response , StatusCode } ;
18- use http_body_util:: { BodyExt , Full } ;
20+ use http_body:: { Frame , SizeHint } ;
21+ use http_body_util:: BodyExt ;
1922use httpdate:: HttpDate ;
2023#[ cfg( feature = "hyper-rustls" ) ]
2124use hyper:: body:: Incoming ;
@@ -56,7 +59,7 @@ impl Client {
5659 async fn new ( directory_url : String , http : Box < dyn HttpClient > ) -> Result < Self , Error > {
5760 let req = Request :: builder ( )
5861 . uri ( & directory_url)
59- . body ( Full :: default ( ) )
62+ . body ( BodyWrapper :: default ( ) )
6063 . expect ( "infallible error should not occur" ) ;
6164 let rsp = http. request ( req) . await ?;
6265 let body = rsp. body ( ) . await . map_err ( Error :: Other ) ?;
@@ -117,7 +120,7 @@ impl Client {
117120 . method ( Method :: POST )
118121 . uri ( url)
119122 . header ( CONTENT_TYPE , JOSE_JSON )
120- . body ( Full :: from ( serde_json:: to_vec ( & body) ?) ) ?;
123+ . body ( BodyWrapper :: from ( serde_json:: to_vec ( & body) ?) ) ?;
121124
122125 self . http . request ( request) . await
123126 }
@@ -130,7 +133,7 @@ impl Client {
130133 let request = Request :: builder ( )
131134 . method ( Method :: HEAD )
132135 . uri ( & self . directory . new_nonce )
133- . body ( Full :: default ( ) )
136+ . body ( BodyWrapper :: default ( ) )
134137 . expect ( "infallible error should not occur" ) ;
135138
136139 let rsp = self . http . request ( request) . await ?;
@@ -187,7 +190,7 @@ fn retry_after(rsp: &BytesResponse) -> Option<SystemTime> {
187190}
188191
189192#[ cfg( feature = "hyper-rustls" ) ]
190- struct DefaultClient ( HyperClient < hyper_rustls:: HttpsConnector < HttpConnector > , Full < Bytes > > ) ;
193+ struct DefaultClient ( HyperClient < hyper_rustls:: HttpsConnector < HttpConnector > , BodyWrapper < Bytes > > ) ;
191194
192195#[ cfg( feature = "hyper-rustls" ) ]
193196impl DefaultClient {
@@ -210,7 +213,7 @@ impl DefaultClient {
210213impl HttpClient for DefaultClient {
211214 fn request (
212215 & self ,
213- req : Request < Full < Bytes > > ,
216+ req : Request < BodyWrapper < Bytes > > ,
214217 ) -> Pin < Box < dyn Future < Output = Result < BytesResponse , Error > > + Send > > {
215218 let fut = self . 0 . request ( req) ;
216219 Box :: pin ( async move { BytesResponse :: try_from ( fut. await ) } )
@@ -222,15 +225,15 @@ pub trait HttpClient: Send + Sync + 'static {
222225 /// Send the given request and return the response
223226 fn request (
224227 & self ,
225- req : Request < Full < Bytes > > ,
228+ req : Request < BodyWrapper < Bytes > > ,
226229 ) -> Pin < Box < dyn Future < Output = Result < BytesResponse , Error > > + Send > > ;
227230}
228231
229232#[ cfg( feature = "hyper-rustls" ) ]
230- impl < C : Connect + Clone + Send + Sync + ' static > HttpClient for HyperClient < C , Full < Bytes > > {
233+ impl < C : Connect + Clone + Send + Sync + ' static > HttpClient for HyperClient < C , BodyWrapper < Bytes > > {
231234 fn request (
232235 & self ,
233- req : Request < Full < Bytes > > ,
236+ req : Request < BodyWrapper < Bytes > > ,
234237 ) -> Pin < Box < dyn Future < Output = Result < BytesResponse , Error > > + Send > > {
235238 let fut = self . request ( req) ;
236239 Box :: pin ( async move { BytesResponse :: try_from ( fut. await ) } )
@@ -276,7 +279,9 @@ where
276279 }
277280}
278281
279- struct BodyWrapper < B > {
282+ /// A simple HTTP body wrapper type
283+ #[ derive( Default ) ]
284+ pub struct BodyWrapper < B > {
280285 inner : Option < B > ,
281286}
282287
@@ -299,6 +304,37 @@ where
299304 }
300305}
301306
307+ impl http_body:: Body for BodyWrapper < Bytes > {
308+ type Data = Bytes ;
309+ type Error = Infallible ;
310+
311+ fn poll_frame (
312+ mut self : Pin < & mut Self > ,
313+ _cx : & mut Context < ' _ > ,
314+ ) -> Poll < Option < Result < Frame < Self :: Data > , Self :: Error > > > {
315+ Poll :: Ready ( self . inner . take ( ) . map ( |d| Ok ( Frame :: data ( d) ) ) )
316+ }
317+
318+ fn is_end_stream ( & self ) -> bool {
319+ self . inner . is_none ( )
320+ }
321+
322+ fn size_hint ( & self ) -> SizeHint {
323+ match self . inner . as_ref ( ) {
324+ Some ( data) => SizeHint :: with_exact ( u64:: try_from ( data. remaining ( ) ) . unwrap ( ) ) ,
325+ None => SizeHint :: with_exact ( 0 ) ,
326+ }
327+ }
328+ }
329+
330+ impl From < Vec < u8 > > for BodyWrapper < Bytes > {
331+ fn from ( data : Vec < u8 > ) -> Self {
332+ BodyWrapper {
333+ inner : Some ( Bytes :: from ( data) ) ,
334+ }
335+ }
336+ }
337+
302338#[ async_trait]
303339impl BytesBody for Bytes {
304340 async fn into_bytes ( & mut self ) -> Result < Bytes , Box < dyn StdError + Send + Sync + ' static > > {
0 commit comments