1
1
use actix_rt:: Runtime ;
2
2
use actix_web:: {
3
- dev:: Body , guard, http, web, web:: Query , App , FromRequest , HttpRequest , HttpResponse ,
4
- HttpServer ,
3
+ dev:: Body ,
4
+ guard, http,
5
+ web:: { self , BytesMut , Query } ,
6
+ App , FromRequest , HttpRequest , HttpResponse , HttpServer ,
5
7
} ;
6
- use bytes :: Bytes ;
8
+ use futures :: StreamExt ;
7
9
use std:: path:: PathBuf ;
8
10
9
11
use super :: ast:: { AstCallback , AstCfg , AstPayload } ;
@@ -22,7 +24,16 @@ struct Error {
22
24
error : & ' static str ,
23
25
}
24
26
25
- fn ast_parser ( item : web:: Json < AstPayload > , _req : HttpRequest ) -> HttpResponse {
27
+ async fn get_code ( mut body : web:: Payload ) -> Result < Vec < u8 > , actix_web:: Error > {
28
+ let mut code = BytesMut :: new ( ) ;
29
+ while let Some ( item) = body. next ( ) . await {
30
+ code. extend_from_slice ( & item?) ;
31
+ }
32
+
33
+ Ok ( code. to_vec ( ) )
34
+ }
35
+
36
+ fn ast_parser ( item : web:: Json < AstPayload > ) -> HttpResponse {
26
37
let path = PathBuf :: from ( & item. file_name ) ;
27
38
let payload = item. into_inner ( ) ;
28
39
let buf = payload. code . into_bytes ( ) ;
@@ -50,7 +61,7 @@ fn ast_parser(item: web::Json<AstPayload>, _req: HttpRequest) -> HttpResponse {
50
61
}
51
62
}
52
63
53
- fn comment_removal_json ( item : web:: Json < WebCommentPayload > , _req : HttpRequest ) -> HttpResponse {
64
+ fn comment_removal_json ( item : web:: Json < WebCommentPayload > ) -> HttpResponse {
54
65
let path = PathBuf :: from ( & item. file_name ) ;
55
66
let payload = item. into_inner ( ) ;
56
67
let buf = payload. code . into_bytes ( ) ;
@@ -77,30 +88,33 @@ fn comment_removal_json(item: web::Json<WebCommentPayload>, _req: HttpRequest) -
77
88
}
78
89
}
79
90
80
- fn comment_removal_plain ( code : Bytes , info : Query < WebCommentInfo > ) -> HttpResponse {
91
+ async fn comment_removal_plain (
92
+ body : web:: Payload ,
93
+ info : Query < WebCommentInfo > ,
94
+ ) -> Result < HttpResponse , actix_web:: Error > {
95
+ let buf = get_code ( body) . await ?;
81
96
let path = PathBuf :: from ( & info. file_name ) ;
82
- let buf = code. to_vec ( ) ;
83
97
let ( language, _) = guess_language ( & buf, & path) ;
84
98
if let Some ( language) = language {
85
99
let cfg = WebCommentCfg { id : "" . to_string ( ) } ;
86
100
let res = action :: < WebCommentCallback > ( & language, buf, & PathBuf :: from ( "" ) , None , cfg) ;
87
101
if let Some ( res_code) = res. code {
88
- HttpResponse :: Ok ( )
102
+ Ok ( HttpResponse :: Ok ( )
89
103
. header ( http:: header:: CONTENT_TYPE , "application/octet-stream" )
90
- . body ( res_code)
104
+ . body ( res_code) )
91
105
} else {
92
- HttpResponse :: NoContent ( )
106
+ Ok ( HttpResponse :: NoContent ( )
93
107
. header ( http:: header:: CONTENT_TYPE , "application/octet-stream" )
94
- . body ( Body :: Empty )
108
+ . body ( Body :: Empty ) )
95
109
}
96
110
} else {
97
- HttpResponse :: NotFound ( )
111
+ Ok ( HttpResponse :: NotFound ( )
98
112
. header ( http:: header:: CONTENT_TYPE , "text/plain" )
99
- . body ( format ! ( "error: {}" , INVALID_LANGUAGE ) )
113
+ . body ( format ! ( "error: {}" , INVALID_LANGUAGE ) ) )
100
114
}
101
115
}
102
116
103
- fn metrics_json ( item : web:: Json < WebMetricsPayload > , _req : HttpRequest ) -> HttpResponse {
117
+ fn metrics_json ( item : web:: Json < WebMetricsPayload > ) -> HttpResponse {
104
118
let path = PathBuf :: from ( & item. file_name ) ;
105
119
let payload = item. into_inner ( ) ;
106
120
let buf = payload. code . into_bytes ( ) ;
@@ -127,9 +141,12 @@ fn metrics_json(item: web::Json<WebMetricsPayload>, _req: HttpRequest) -> HttpRe
127
141
}
128
142
}
129
143
130
- fn metrics_plain ( code : Bytes , info : Query < WebMetricsInfo > ) -> HttpResponse {
144
+ async fn metrics_plain (
145
+ body : web:: Payload ,
146
+ info : Query < WebMetricsInfo > ,
147
+ ) -> Result < HttpResponse , actix_web:: Error > {
148
+ let buf = get_code ( body) . await ?;
131
149
let path = PathBuf :: from ( & info. file_name ) ;
132
- let buf = code. to_vec ( ) ;
133
150
let ( language, name) = guess_language ( & buf, & path) ;
134
151
if let Some ( language) = language {
135
152
let cfg = WebMetricsCfg {
@@ -141,17 +158,17 @@ fn metrics_plain(code: Bytes, info: Query<WebMetricsInfo>) -> HttpResponse {
141
158
. map_or ( false , |s| s == "1" || s == "true" ) ,
142
159
language : name,
143
160
} ;
144
- HttpResponse :: Ok ( ) . json ( action :: < WebMetricsCallback > (
161
+ Ok ( HttpResponse :: Ok ( ) . json ( action :: < WebMetricsCallback > (
145
162
& language,
146
163
buf,
147
164
& PathBuf :: from ( "" ) ,
148
165
None ,
149
166
cfg,
150
- ) )
167
+ ) ) )
151
168
} else {
152
- HttpResponse :: NotFound ( )
169
+ Ok ( HttpResponse :: NotFound ( )
153
170
. header ( http:: header:: CONTENT_TYPE , "text/plain" )
154
- . body ( format ! ( "error: {}" , INVALID_LANGUAGE ) )
171
+ . body ( format ! ( "error: {}" , INVALID_LANGUAGE ) ) )
155
172
}
156
173
}
157
174
@@ -177,23 +194,26 @@ fn function_json(item: web::Json<WebFunctionPayload>, _req: HttpRequest) -> Http
177
194
}
178
195
}
179
196
180
- fn function_plain ( code : Bytes , info : Query < WebFunctionInfo > ) -> HttpResponse {
197
+ async fn function_plain (
198
+ body : web:: Payload ,
199
+ info : Query < WebFunctionInfo > ,
200
+ ) -> Result < HttpResponse , actix_web:: Error > {
201
+ let buf = get_code ( body) . await ?;
181
202
let path = PathBuf :: from ( & info. file_name ) ;
182
- let buf = code. to_vec ( ) ;
183
203
let ( language, _) = guess_language ( & buf, & path) ;
184
204
if let Some ( language) = language {
185
205
let cfg = WebFunctionCfg { id : "" . to_string ( ) } ;
186
- HttpResponse :: Ok ( ) . json ( action :: < WebFunctionCallback > (
206
+ Ok ( HttpResponse :: Ok ( ) . json ( action :: < WebFunctionCallback > (
187
207
& language,
188
208
buf,
189
209
& PathBuf :: from ( "" ) ,
190
210
None ,
191
211
cfg,
192
- ) )
212
+ ) ) )
193
213
} else {
194
- HttpResponse :: NotFound ( )
214
+ Ok ( HttpResponse :: NotFound ( )
195
215
. header ( http:: header:: CONTENT_TYPE , "text/plain" )
196
- . body ( format ! ( "error: {}" , INVALID_LANGUAGE ) )
216
+ . body ( format ! ( "error: {}" , INVALID_LANGUAGE ) ) )
197
217
}
198
218
}
199
219
@@ -204,49 +224,59 @@ fn ping() -> HttpResponse {
204
224
pub fn run ( host : String , port : u16 , n_threads : usize ) -> std:: io:: Result < ( ) > {
205
225
let _ = actix_rt:: System :: new ( "server" ) ;
206
226
let mut rt = Runtime :: new ( ) ?;
227
+ let max_size = 1024 * 1024 * 4 ;
207
228
208
229
rt. block_on ( async move {
209
- HttpServer :: new ( || {
230
+ HttpServer :: new ( move || {
210
231
App :: new ( )
211
232
. service (
212
233
web:: resource ( "/ast" )
213
- . data ( web:: JsonConfig :: default ( ) . limit ( std:: u32:: MAX as usize ) )
234
+ . guard ( guard:: Header ( "content-type" , "application/json" ) )
235
+ . app_data ( web:: Json :: < AstPayload > :: configure ( |cfg| {
236
+ cfg. limit ( max_size)
237
+ } ) )
214
238
. route ( web:: post ( ) . to ( ast_parser) ) ,
215
239
)
216
240
. service (
217
241
web:: resource ( "/comment" )
218
242
. guard ( guard:: Header ( "content-type" , "application/json" ) )
219
- . data ( web:: JsonConfig :: default ( ) . limit ( std:: u32:: MAX as usize ) )
243
+ . app_data ( web:: Json :: < WebCommentPayload > :: configure ( |cfg| {
244
+ cfg. limit ( max_size)
245
+ } ) )
220
246
. route ( web:: post ( ) . to ( comment_removal_json) ) ,
221
247
)
222
248
. service (
223
249
web:: resource ( "/comment" )
224
250
. guard ( guard:: Header ( "content-type" , "application/octet-stream" ) )
225
- . data ( Bytes :: configure ( |cfg| cfg . limit ( std :: u32 :: MAX as usize ) ) )
251
+ . data ( web :: PayloadConfig :: default ( ) . limit ( max_size ) )
226
252
. route ( web:: post ( ) . to ( comment_removal_plain) ) ,
227
253
)
228
254
. service (
229
255
web:: resource ( "/metrics" )
230
256
. guard ( guard:: Header ( "content-type" , "application/json" ) )
231
- . data ( web:: JsonConfig :: default ( ) . limit ( std:: u32:: MAX as usize ) )
257
+ . app_data ( web:: Json :: < WebMetricsPayload > :: configure ( |cfg| {
258
+ cfg. limit ( max_size)
259
+ } ) )
232
260
. route ( web:: post ( ) . to ( metrics_json) ) ,
233
261
)
234
262
. service (
235
263
web:: resource ( "/metrics" )
236
264
. guard ( guard:: Header ( "content-type" , "application/octet-stream" ) )
237
- . data ( Bytes :: configure ( |cfg| cfg . limit ( std :: u32 :: MAX as usize ) ) )
265
+ . data ( web :: PayloadConfig :: default ( ) . limit ( max_size ) )
238
266
. route ( web:: post ( ) . to ( metrics_plain) ) ,
239
267
)
240
268
. service (
241
269
web:: resource ( "/function" )
242
270
. guard ( guard:: Header ( "content-type" , "application/json" ) )
243
- . data ( web:: JsonConfig :: default ( ) . limit ( std:: u32:: MAX as usize ) )
271
+ . app_data ( web:: Json :: < WebFunctionPayload > :: configure ( |cfg| {
272
+ cfg. limit ( max_size)
273
+ } ) )
244
274
. route ( web:: post ( ) . to ( function_json) ) ,
245
275
)
246
276
. service (
247
277
web:: resource ( "/function" )
248
278
. guard ( guard:: Header ( "content-type" , "application/octet-stream" ) )
249
- . data ( Bytes :: configure ( |cfg| cfg . limit ( std :: u32 :: MAX as usize ) ) )
279
+ . data ( web :: PayloadConfig :: default ( ) . limit ( max_size ) )
250
280
. route ( web:: post ( ) . to ( function_plain) ) ,
251
281
)
252
282
. service ( web:: resource ( "/ping" ) . route ( web:: get ( ) . to ( ping) ) )
0 commit comments