@@ -6,33 +6,36 @@ use std::sync::Arc;
6
6
use anyhow:: { bail, format_err, Context , Error } ;
7
7
use base64:: prelude:: BASE64_STANDARD_NO_PAD ;
8
8
use base64:: Engine ;
9
+ use bytes:: Bytes ;
9
10
use ed25519_dalek:: SigningKey ;
10
11
use http:: header:: { AUTHORIZATION , CONTENT_TYPE } ;
11
12
use http:: request:: { Builder , Parts } ;
12
13
use http:: { HeaderValue , Uri } ;
13
- use hyper:: body:: { to_bytes, HttpBody } ;
14
- use hyper:: client:: connect:: Connect ;
15
- use hyper:: { Body , Client , Request , Response } ;
14
+ use http_body_util:: { BodyExt , Full } ;
15
+ use hyper:: { Request , Response } ;
16
+ use hyper_util:: client:: legacy:: connect:: Connect ;
17
+ use hyper_util:: client:: legacy:: Client ;
18
+ use hyper_util:: rt:: TokioExecutor ;
16
19
use serde:: Serialize ;
17
20
use serde_json:: value:: RawValue ;
18
21
use signed_json:: signed:: Wrap ;
19
22
use signed_json:: { Canonical , CanonicalWrapper , Signed } ;
20
23
21
24
use crate :: server_resolver:: { handle_delegated_server, MatrixConnector } ;
22
25
23
- /// A [`hyper:: Client`] that routes `matrix://` (Synapse <1.87.0rc1 (2023-06-27)) and
24
- /// `matrix-federation://` (Synapse >=1.87.0rc1 (2023-06-27)) URIs correctly, but does
25
- /// not sign the requests.
26
+ /// A [`hyper_util::client::legacy:: Client`] that routes `matrix://` (Synapse <1.87.0rc1
27
+ /// (2023-06-27)) and `matrix-federation://` (Synapse >=1.87.0rc1 (2023-06-27)) URIs
28
+ /// correctly, but does not sign the requests.
26
29
///
27
30
/// Either use [`SigningFederationClient`] if you want requests to be automatically
28
31
/// signed, or [`sign_and_build_json_request`] to sign the requests.
29
32
#[ derive( Debug , Clone ) ]
30
33
pub struct FederationClient {
31
- pub client : hyper :: Client < MatrixConnector > ,
34
+ pub client : Client < MatrixConnector , Full < Bytes > > ,
32
35
}
33
36
34
37
impl FederationClient {
35
- pub fn new ( client : hyper :: Client < MatrixConnector > ) -> Self {
38
+ pub fn new ( client : Client < MatrixConnector , Full < Bytes > > ) -> Self {
36
39
FederationClient { client }
37
40
}
38
41
@@ -41,11 +44,14 @@ impl FederationClient {
41
44
let connector = MatrixConnector :: with_default_resolver ( ) ?;
42
45
43
46
Ok ( FederationClient {
44
- client : Client :: builder ( ) . build ( connector) ,
47
+ client : Client :: builder ( TokioExecutor :: new ( ) ) . build ( connector) ,
45
48
} )
46
49
}
47
50
48
- pub async fn request ( & self , mut req : Request < Body > ) -> Result < Response < Body > , Error > {
51
+ pub async fn request (
52
+ & self ,
53
+ mut req : Request < Full < Bytes > > ,
54
+ ) -> Result < Response < Full < Bytes > > , Error > {
49
55
req = handle_delegated_server ( & self . client , req) . await ?;
50
56
51
57
Ok ( self . client . request ( req) . await ?)
@@ -79,7 +85,7 @@ impl SigningFederationClient<MatrixConnector> {
79
85
let connector = MatrixConnector :: with_default_resolver ( ) ?;
80
86
81
87
Ok ( SigningFederationClient {
82
- client : Client :: builder ( ) . build ( connector) ,
88
+ client : Client :: builder ( TokioExecutor :: new ( ) ) . build ( connector) ,
83
89
server_name : server_name. to_string ( ) ,
84
90
key_id : key_id. to_string ( ) ,
85
91
secret_key : Arc :: new ( secret_key) ,
@@ -114,8 +120,8 @@ where
114
120
/// Make a GET request to the given URI.
115
121
///
116
122
/// Will sign the request if the URI has a `matrix` scheme.
117
- pub async fn get ( & self , uri : Uri ) -> Result < Response < Body > , Error > {
118
- let body = Body :: default ( ) ;
123
+ pub async fn get ( & self , uri : Uri ) -> Result < Response < Full < Bytes > > , Error > {
124
+ let body = Full :: new ( Bytes :: new ( ) ) ;
119
125
120
126
let mut req = Request :: new ( body) ;
121
127
* req. uri_mut ( ) = uri;
@@ -126,7 +132,10 @@ where
126
132
///
127
133
/// For `matrix://` or `matrix-federation://` URIs the request body must be JSON (if
128
134
/// not empty) and the request will be signed.
129
- pub async fn request ( & self , mut req : Request < Body > ) -> Result < Response < Body > , Error > {
135
+ pub async fn request (
136
+ & self ,
137
+ mut req : Request < Full < Bytes > > ,
138
+ ) -> Result < Response < Full < Bytes > > , Error > {
130
139
req = handle_delegated_server ( & self . client , req) . await ?;
131
140
132
141
// Return-early and make a normal request if the URI scheme is not `matrix://`
@@ -136,19 +145,14 @@ where
136
145
_ => return Ok ( self . client . request ( req) . await ?) ,
137
146
}
138
147
139
- if !req. body ( ) . is_end_stream ( )
140
- && req. headers ( ) . get ( CONTENT_TYPE )
141
- != Some ( & HeaderValue :: from_static ( "application/json" ) )
142
- {
148
+ if req. headers ( ) . get ( CONTENT_TYPE ) != Some ( & HeaderValue :: from_static ( "application/json" ) ) {
143
149
bail ! ( "Request has a non-JSON body" )
144
150
}
145
151
146
152
let ( mut parts, body) = req. into_parts ( ) ;
147
153
148
- let content = if body. is_end_stream ( ) {
149
- None
150
- } else {
151
- let bytes = to_bytes ( body) . await ?;
154
+ let content = {
155
+ let bytes = BodyExt :: collect ( body) . await . unwrap ( ) . to_bytes ( ) ;
152
156
let json_string = String :: from_utf8 ( bytes. to_vec ( ) ) ?;
153
157
Some ( RawValue :: from_string ( json_string) ?)
154
158
} ;
@@ -167,7 +171,7 @@ where
167
171
let new_body = if let Some ( raw_value) = content {
168
172
raw_value. to_string ( ) . into ( )
169
173
} else {
170
- Body :: default ( )
174
+ Full :: new ( Bytes :: new ( ) )
171
175
} ;
172
176
173
177
let new_req = Request :: from_parts ( parts, new_body) ;
@@ -237,7 +241,7 @@ pub fn sign_and_build_json_request<T: serde::Serialize>(
237
241
secret_key : & SigningKey ,
238
242
mut request_builder : Builder ,
239
243
content : Option < T > ,
240
- ) -> Result < Request < Body > , Error > {
244
+ ) -> Result < Request < Full < Bytes > > , Error > {
241
245
let uri = request_builder
242
246
. uri_ref ( )
243
247
. ok_or_else ( || format_err ! ( "URI must be set" ) ) ?;
@@ -276,9 +280,9 @@ pub fn sign_and_build_json_request<T: serde::Serialize>(
276
280
let header_value = header_string. try_into ( ) ?;
277
281
278
282
let body = if let Some ( c) = canonical_content {
279
- Body :: from ( c. into_canonical ( ) )
283
+ Full :: new ( Bytes :: from ( c. into_canonical ( ) ) )
280
284
} else {
281
- Body :: default ( )
285
+ Full :: new ( Bytes :: new ( ) )
282
286
} ;
283
287
284
288
request_builder
@@ -327,7 +331,7 @@ pub trait SignedRequestBuilderExt {
327
331
server_name : & str ,
328
332
key_id : & str ,
329
333
secret_key : & SigningKey ,
330
- ) -> Result < Request < Body > , Error > ;
334
+ ) -> Result < Request < Full < Bytes > > , Error > ;
331
335
332
336
/// Sign and build the request with the given JSON body.
333
337
fn signed_json < T : Serialize > (
@@ -336,7 +340,7 @@ pub trait SignedRequestBuilderExt {
336
340
key_id : & str ,
337
341
secret_key : & SigningKey ,
338
342
content : T ,
339
- ) -> Result < Request < Body > , Error > ;
343
+ ) -> Result < Request < Full < Bytes > > , Error > ;
340
344
341
345
/// Sign and build the request with optional JSON body.
342
346
fn signed_json_opt < T : Serialize > (
@@ -345,7 +349,7 @@ pub trait SignedRequestBuilderExt {
345
349
key_id : & str ,
346
350
secret_key : & SigningKey ,
347
351
content : Option < T > ,
348
- ) -> Result < Request < Body > , Error > ;
352
+ ) -> Result < Request < Full < Bytes > > , Error > ;
349
353
}
350
354
351
355
impl SignedRequestBuilderExt for Builder {
@@ -354,7 +358,7 @@ impl SignedRequestBuilderExt for Builder {
354
358
server_name : & str ,
355
359
key_id : & str ,
356
360
secret_key : & SigningKey ,
357
- ) -> Result < Request < Body > , Error > {
361
+ ) -> Result < Request < Full < Bytes > > , Error > {
358
362
sign_and_build_json_request :: < ( ) > ( server_name, key_id, secret_key, self , None )
359
363
}
360
364
@@ -364,7 +368,7 @@ impl SignedRequestBuilderExt for Builder {
364
368
key_id : & str ,
365
369
secret_key : & SigningKey ,
366
370
content : T ,
367
- ) -> Result < Request < Body > , Error > {
371
+ ) -> Result < Request < Full < Bytes > > , Error > {
368
372
sign_and_build_json_request ( server_name, key_id, secret_key, self , Some ( content) )
369
373
}
370
374
@@ -374,7 +378,7 @@ impl SignedRequestBuilderExt for Builder {
374
378
key_id : & str ,
375
379
secret_key : & SigningKey ,
376
380
content : Option < T > ,
377
- ) -> Result < Request < Body > , Error > {
381
+ ) -> Result < Request < Full < Bytes > > , Error > {
378
382
if let Some ( content) = content {
379
383
self . signed_json ( server_name, key_id, secret_key, content)
380
384
} else {
0 commit comments