1
- use std:: fmt:: { Debug , Formatter } ;
2
1
use std:: sync:: Arc ;
3
2
4
3
use crate :: archiver:: Archiver ;
5
4
use serde:: Serialize ;
6
- use warp:: reject:: Reject ;
5
+ use warp:: http:: header:: CONTENT_TYPE ;
6
+ use warp:: http:: { HeaderValue , StatusCode } ;
7
+ use warp:: hyper:: Body ;
7
8
use warp:: { Filter , Rejection , Reply } ;
8
9
9
10
pub struct Api {
@@ -18,19 +19,16 @@ struct RearchiveResponse {
18
19
block_end : u64 ,
19
20
}
20
21
21
- impl Debug for RearchiveResponse {
22
- fn fmt ( & self , f : & mut Formatter < ' _ > ) -> std:: fmt:: Result {
23
- f. debug_struct ( "RearchiveResponse" )
24
- . field ( "success" , & self . success )
25
- . field ( "message" , & self . message )
26
- . field ( "block_start" , & self . block_start )
27
- . field ( "block_end" , & self . block_end )
28
- . finish ( )
22
+ impl Reply for RearchiveResponse {
23
+ fn into_response ( self ) -> warp:: reply:: Response {
24
+ let body = serde_json:: to_string ( & self ) . unwrap ( ) ;
25
+ let mut res = warp:: reply:: Response :: new ( Body :: from ( body) ) ;
26
+ res. headers_mut ( )
27
+ . insert ( CONTENT_TYPE , HeaderValue :: from_static ( "application/json" ) ) ;
28
+ res
29
29
}
30
30
}
31
31
32
- impl Reject for RearchiveResponse { }
33
-
34
32
impl Api {
35
33
pub fn new ( archiver : Archiver ) -> Self {
36
34
Self {
@@ -42,6 +40,7 @@ impl Api {
42
40
let archiver = self . archiver . clone ( ) ;
43
41
warp:: path!( "rearchive" )
44
42
. and ( warp:: get ( ) )
43
+ // todo: make validation error return json https://stackoverflow.com/questions/60554783/is-there-a-way-to-do-validation-as-part-of-a-filter-in-warp
45
44
. and ( warp:: query :: < RearchiveQuery > ( ) )
46
45
. and ( warp:: any ( ) . map ( move || archiver. clone ( ) ) )
47
46
. and_then ( Self :: rearchive_range)
@@ -61,35 +60,53 @@ impl Api {
61
60
archiver : Arc < Archiver > ,
62
61
) -> Result < impl Reply , Rejection > {
63
62
if query. from . is_none ( ) || query. to . is_none ( ) {
64
- return Err ( warp:: reject:: custom ( RearchiveResponse {
65
- success : false ,
66
- message : "Invalid query parameters" . to_string ( ) ,
67
- block_start : 0 ,
68
- block_end : 0 ,
69
- } ) ) ;
63
+ return Ok ( warp:: reply:: with_status (
64
+ RearchiveResponse {
65
+ success : false ,
66
+ message : "Invalid query parameters" . to_string ( ) ,
67
+ block_start : 0 ,
68
+ block_end : 0 ,
69
+ } ,
70
+ StatusCode :: BAD_REQUEST ,
71
+ ) ) ;
70
72
}
71
73
72
74
if query. from > query. to {
73
- return Err ( warp:: reject:: custom ( RearchiveResponse {
74
- success : false ,
75
- message : "Invalid query parameters" . to_string ( ) ,
76
- block_start : 0 ,
77
- block_end : 0 ,
78
- } ) ) ;
75
+ return Ok ( warp:: reply:: with_status (
76
+ RearchiveResponse {
77
+ success : false ,
78
+ message : "Invalid query parameters" . to_string ( ) ,
79
+ block_start : 0 ,
80
+ block_end : 0 ,
81
+ } ,
82
+ StatusCode :: BAD_REQUEST ,
83
+ ) ) ;
79
84
}
80
85
81
86
let res = archiver
82
87
. rearchive_range ( query. from . unwrap ( ) , query. to . unwrap ( ) )
83
88
. await ;
84
89
if res. error . is_some ( ) {
85
- return Err ( warp:: reject:: custom ( RearchiveResponse {
86
- success : false ,
87
- message : res. error . unwrap ( ) ,
90
+ return Ok ( warp:: reply:: with_status (
91
+ RearchiveResponse {
92
+ success : false ,
93
+ message : res. error . unwrap ( ) ,
94
+ block_start : 0 ,
95
+ block_end : 0 ,
96
+ } ,
97
+ StatusCode :: INTERNAL_SERVER_ERROR ,
98
+ ) ) ;
99
+ }
100
+
101
+ Ok ( warp:: reply:: with_status (
102
+ RearchiveResponse {
103
+ success : true ,
104
+ message : "Rearchive successful" . to_string ( ) ,
88
105
block_start : res. from ,
89
106
block_end : res. to ,
90
- } ) ) ;
91
- }
92
- Ok ( warp :: reply :: json ( & res ) )
107
+ } ,
108
+ StatusCode :: OK ,
109
+ ) )
93
110
}
94
111
}
95
112
@@ -102,6 +119,7 @@ struct RearchiveQuery {
102
119
#[ cfg( test) ]
103
120
mod tests {
104
121
use std:: path:: PathBuf ;
122
+ use std:: str:: from_utf8;
105
123
use std:: sync:: Arc ;
106
124
use std:: time:: Duration ;
107
125
@@ -157,10 +175,7 @@ mod tests {
157
175
. await ;
158
176
159
177
assert_eq ! ( res. status( ) , 200 ) ;
160
- assert_eq ! (
161
- std:: str :: from_utf8( res. body( ) ) . unwrap( ) ,
162
- "{\" status\" :\" ok\" }"
163
- ) ;
178
+ assert_eq ! ( from_utf8( res. body( ) ) . unwrap( ) , "{\" status\" :\" ok\" }" ) ;
164
179
clean_dir ( dir) ;
165
180
}
166
181
@@ -172,12 +187,54 @@ mod tests {
172
187
tokio:: fs:: create_dir_all ( dir) . await . unwrap ( ) ;
173
188
let test_storage = Arc :: new ( Mutex :: new ( TestFSStorage :: new ( storage) . await . unwrap ( ) ) ) ;
174
189
let ( archiver, _) = create_test_archiver ( test_storage. clone ( ) , rx) . await ;
175
- let res = warp:: test:: request ( )
190
+ let api = Api :: new ( archiver) ;
191
+ let mut res = warp:: test:: request ( )
176
192
. method ( "GET" )
177
193
. path ( "/rearchive?from=2001&to=2000" )
178
- . reply ( & Api :: new ( archiver) . routes ( ) )
194
+ . reply ( & api. routes ( ) )
195
+ . await ;
196
+ assert_eq ! ( res. status( ) , 400 ) ;
197
+ assert_eq ! ( from_utf8( res. body( ) ) . unwrap( ) , "{\" success\" :false,\" message\" :\" Invalid query parameters\" ,\" block_start\" :0,\" block_end\" :0}" ) ;
198
+
199
+ res = warp:: test:: request ( )
200
+ . method ( "GET" )
201
+ . path ( "/rearchive?to=2000" )
202
+ . reply ( & api. routes ( ) )
203
+ . await ;
204
+ assert_eq ! ( res. status( ) , 400 ) ;
205
+ assert_eq ! ( from_utf8( res. body( ) ) . unwrap( ) , "{\" success\" :false,\" message\" :\" Invalid query parameters\" ,\" block_start\" :0,\" block_end\" :0}" ) ;
206
+
207
+ res = warp:: test:: request ( )
208
+ . method ( "GET" )
209
+ . path ( "/rearchive?from=2000" )
210
+ . reply ( & api. routes ( ) )
211
+ . await ;
212
+ assert_eq ! ( res. status( ) , 400 ) ;
213
+ assert_eq ! ( from_utf8( res. body( ) ) . unwrap( ) , "{\" success\" :false,\" message\" :\" Invalid query parameters\" ,\" block_start\" :0,\" block_end\" :0}" ) ;
214
+
215
+ res = warp:: test:: request ( )
216
+ . method ( "GET" )
217
+ . path ( "/rearchive?from=bbb&to=2000" )
218
+ . reply ( & api. routes ( ) )
179
219
. await ;
180
- assert_eq ! ( res. status( ) , 500 ) ;
220
+ assert_eq ! ( res. status( ) , 400 ) ;
221
+ assert_eq ! ( from_utf8( res. body( ) ) . unwrap( ) , "Invalid query string" ) ;
222
+
223
+ res = warp:: test:: request ( )
224
+ . method ( "GET" )
225
+ . path ( "/rearchive?from=100&to=aaa" )
226
+ . reply ( & api. routes ( ) )
227
+ . await ;
228
+ assert_eq ! ( res. status( ) , 400 ) ;
229
+ assert_eq ! ( from_utf8( res. body( ) ) . unwrap( ) , "Invalid query string" ) ;
230
+
231
+ res = warp:: test:: request ( )
232
+ . method ( "GET" )
233
+ . path ( "/rearchive?from=11&to=15" )
234
+ . reply ( & api. routes ( ) )
235
+ . await ;
236
+ assert_eq ! ( res. status( ) , 200 ) ;
237
+ assert_eq ! ( from_utf8( res. body( ) ) . unwrap( ) , "{\" success\" :true,\" message\" :\" Rearchive successful\" ,\" block_start\" :11,\" block_end\" :15}" ) ;
181
238
clean_dir ( dir) ;
182
239
}
183
240
0 commit comments