1mod constants;
2mod content_type_handler;
3mod error_handler;
4mod msgpack;
5mod msgpack_config;
6mod msgpack_error;
7mod msgpack_extractor_future;
8mod msgpack_message;
9mod msgpack_response_builder;
10
11pub(crate) use constants::DEFAULT_PAYLOAD_LIMIT;
12pub use content_type_handler::ContentTypeHandler;
13pub use error_handler::ErrorHandler;
14pub use msgpack::MsgPack;
15pub use msgpack_config::MsgPackConfig;
16pub(crate) use msgpack_config::DEFAULT_CONFIG;
17pub use msgpack_error::MsgPackError;
18pub use msgpack_extractor_future::MsgPackExtractorFuture;
19pub use msgpack_message::MsgPackMessage;
20pub use msgpack_response_builder::MsgPackResponseBuilder;
21
22#[cfg(test)]
23mod tests {
24 use super::*;
25 use actix_web::{
26 body::MessageBody,
27 error::InternalError,
28 http::{header, Method, StatusCode},
29 test::{call_service, init_service, TestRequest},
30 web::{self, Bytes},
31 App, HttpRequest, HttpResponse, Responder,
32 };
33 use mime::{APPLICATION_JSON, APPLICATION_MSGPACK};
34 use serde::{Deserialize, Serialize};
35
36 impl PartialEq for MsgPackError {
37 fn eq(&self, other: &MsgPackError) -> bool {
38 match *self {
39 MsgPackError::Overflow => {
40 matches!(*other, MsgPackError::Overflow)
41 },
42 MsgPackError::ContentType => {
43 matches!(*other, MsgPackError::ContentType)
44 },
45 _ => false,
46 }
47 }
48 }
49
50 #[derive(Debug, Serialize, Deserialize, PartialEq)]
51 pub struct Data {
52 payload: bool,
53 }
54
55 #[actix_web::test]
56 async fn check_content_type() {
57 let (req, mut payload) = TestRequest::default().to_http_parts();
59 let msgpack = MsgPackMessage::<Data>::new(&req, &mut payload, None).await;
60
61 assert_eq!(msgpack.err().unwrap(), MsgPackError::ContentType);
62
63 let (req, mut payload) = TestRequest::default()
65 .insert_header((header::CONTENT_TYPE, APPLICATION_JSON))
66 .to_http_parts();
67 let msgpack = MsgPackMessage::<Data>::new(&req, &mut payload, None).await;
68
69 assert_eq!(msgpack.err().unwrap(), MsgPackError::ContentType);
70
71 let (req, mut payload) = TestRequest::default()
73 .insert_header((header::CONTENT_TYPE, APPLICATION_MSGPACK))
74 .to_http_parts();
75 let msgpack = MsgPackMessage::<Data>::new(&req, &mut payload, None).await;
76
77 assert_ne!(msgpack.err().unwrap(), MsgPackError::ContentType);
78 }
79
80 #[actix_web::test]
81 async fn check_default_limit() {
82 let (req, mut payload) = TestRequest::default()
84 .insert_header((header::CONTENT_TYPE, APPLICATION_MSGPACK))
85 .insert_header((header::CONTENT_LENGTH, 0))
86 .to_http_parts();
87 let msgpack = MsgPackMessage::<()>::new(&req, &mut payload, None).await;
88
89 assert_ne!(msgpack.err().unwrap(), MsgPackError::Overflow);
90
91 let (req, mut payload) = TestRequest::default()
93 .insert_header((header::CONTENT_TYPE, APPLICATION_MSGPACK))
94 .insert_header((header::CONTENT_LENGTH, DEFAULT_PAYLOAD_LIMIT))
95 .to_http_parts();
96 let msgpack = MsgPackMessage::<()>::new(&req, &mut payload, None).await;
97
98 assert_ne!(msgpack.err().unwrap(), MsgPackError::Overflow);
99
100 let (req, mut payload) = TestRequest::default()
102 .insert_header((header::CONTENT_TYPE, APPLICATION_MSGPACK))
103 .insert_header((header::CONTENT_LENGTH, DEFAULT_PAYLOAD_LIMIT + 1))
104 .to_http_parts();
105 let msgpack = MsgPackMessage::<()>::new(&req, &mut payload, None).await;
106
107 assert_eq!(msgpack.err().unwrap(), MsgPackError::Overflow);
108 }
109
110 #[actix_web::test]
111 async fn check_custom_limit() {
112 const LIMIT: usize = 10;
113
114 let (req, mut payload) = TestRequest::default()
116 .insert_header((header::CONTENT_TYPE, APPLICATION_MSGPACK))
117 .insert_header((header::CONTENT_LENGTH, LIMIT))
118 .to_http_parts();
119 let msgpack = MsgPackMessage::<()>::new(&req, &mut payload, None).limit(LIMIT).await;
120
121 assert_ne!(msgpack.err().unwrap(), MsgPackError::Overflow);
122
123 let (req, mut payload) = TestRequest::default()
125 .insert_header((header::CONTENT_TYPE, APPLICATION_MSGPACK))
126 .insert_header((header::CONTENT_LENGTH, LIMIT + 1))
127 .to_http_parts();
128 let msgpack = MsgPackMessage::<()>::new(&req, &mut payload, None).limit(LIMIT).await;
129
130 assert_eq!(msgpack.err().unwrap(), MsgPackError::Overflow);
131 }
132
133 #[actix_web::test]
134 async fn check_body() {
135 let (req, mut payload) = TestRequest::post()
137 .insert_header((header::CONTENT_TYPE, APPLICATION_MSGPACK))
138 .to_http_parts();
139
140 let msgpack = MsgPackMessage::<()>::new(&req, &mut payload, None).await;
141
142 assert!(matches!(msgpack.err().unwrap(), MsgPackError::Payload(..)));
143
144 let data = Bytes::from_static(&[0x81]);
146 let (req, mut payload) = TestRequest::post()
147 .insert_header((header::CONTENT_TYPE, APPLICATION_MSGPACK))
148 .insert_header((header::CONTENT_LENGTH, 1))
149 .set_payload(data)
150 .to_http_parts();
151 let msgpack = MsgPackMessage::<()>::new(&req, &mut payload, None).await;
152
153 assert!(matches!(msgpack.err().unwrap(), MsgPackError::Deserialize(..)));
154
155 let data =
157 Bytes::from_static(&[0x81, 0xa7, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0xc3]);
158 let (req, mut payload) = TestRequest::post()
159 .insert_header((header::CONTENT_TYPE, APPLICATION_MSGPACK))
160 .insert_header((header::CONTENT_LENGTH, 10))
161 .set_payload(data)
162 .to_http_parts();
163 let msgpack = MsgPackMessage::<Data>::new(&req, &mut payload, None).await;
164
165 assert_eq!(msgpack.ok().unwrap(), Data { payload: true })
166 }
167
168 #[actix_web::test]
169 async fn check_body_limit() {
170 let data =
172 Bytes::from_static(&[0x81, 0xa7, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0xc3]);
173 let (req, mut payload) = TestRequest::post()
174 .insert_header((header::CONTENT_TYPE, APPLICATION_MSGPACK))
175 .insert_header((header::CONTENT_LENGTH, 10))
176 .set_payload(data)
177 .to_http_parts();
178 let msgpack = MsgPackMessage::<Data>::new(&req, &mut payload, None).await;
179
180 assert_eq!(msgpack.ok().unwrap(), Data { payload: true });
181
182 let data =
184 Bytes::from_static(&[0x81, 0xa7, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0xc3]);
185 let (req, mut payload) = TestRequest::post()
186 .insert_header((header::CONTENT_TYPE, APPLICATION_MSGPACK))
187 .insert_header((header::CONTENT_LENGTH, 11))
188 .set_payload(data)
189 .to_http_parts();
190 let msgpack = MsgPackMessage::<Data>::new(&req, &mut payload, None).await;
191
192 assert_eq!(msgpack.ok().unwrap(), Data { payload: true });
193
194 let data =
196 Bytes::from_static(&[0x81, 0xa7, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0xc3]);
197 let (req, mut payload) = TestRequest::post()
198 .insert_header((header::CONTENT_TYPE, APPLICATION_MSGPACK))
199 .insert_header((header::CONTENT_LENGTH, 1))
200 .set_payload(data)
201 .to_http_parts();
202 let msgpack = MsgPackMessage::<Data>::new(&req, &mut payload, None).await;
203
204 assert_eq!(msgpack.ok().unwrap(), Data { payload: true });
205
206 let data =
208 Bytes::from_static(&[0x81, 0xa7, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0xc3]);
209 let (req, mut payload) = TestRequest::post()
210 .insert_header((header::CONTENT_TYPE, APPLICATION_MSGPACK))
211 .set_payload(data)
212 .to_http_parts();
213 let msgpack = MsgPackMessage::<Data>::new(&req, &mut payload, None).await;
214
215 assert_eq!(msgpack.ok().unwrap(), Data { payload: true });
216 }
217
218 #[actix_web::test]
219 async fn check_responses() {
220 async fn service(_: HttpRequest) -> HttpResponse {
222 let payload = Data { payload: true };
223 HttpResponse::Ok().msgpack(payload)
224 }
225
226 let request = TestRequest::post()
227 .uri("/")
228 .insert_header((header::CONTENT_TYPE, APPLICATION_MSGPACK))
229 .to_http_request();
230 let response = service(request).await;
231
232 assert_eq!(response.status(), StatusCode::OK);
233 assert_eq!(
234 response.into_body().try_into_bytes().unwrap(),
235 vec![0x81, 0xa7, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0xc3]
236 );
237 }
238
239 #[actix_web::test]
240 async fn check_responder() {
241 let request = TestRequest::default().to_http_request();
243 let payload = MsgPack(Bytes::from_static(&[
244 0x81, 0xa7, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0xc3,
245 ]));
246 let response = payload.clone().respond_to(&request);
247
248 assert_eq!(response.status(), StatusCode::OK);
249 assert_eq!(
250 response.into_body().try_into_bytes().unwrap(),
251 vec![0x81, 0xa7, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0xc3]
252 );
253 }
254
255 #[actix_web::test]
256 async fn check_empty_error_handler() {
257 async fn service(_: MsgPack<Data>) -> HttpResponse {
258 HttpResponse::Ok().finish()
259 }
260
261 let app = init_service(
262 App::new().app_data(MsgPackConfig::default()).route("/", web::post().to(service)),
263 )
264 .await;
265 let request = TestRequest::default()
266 .method(Method::POST)
267 .insert_header((header::CONTENT_TYPE, APPLICATION_MSGPACK))
268 .to_request();
269 let response = call_service(&app, request).await;
270
271 assert_eq!(response.status(), StatusCode::BAD_REQUEST);
272 }
273
274 #[actix_web::test]
275 async fn check_error_handler() {
276 async fn service(_: MsgPack<Data>) -> HttpResponse {
277 HttpResponse::Ok().finish()
278 }
279
280 let mut config = MsgPackConfig::default();
281 config.error_handler(|err, _req| {
282 InternalError::from_response(err, HttpResponse::NotAcceptable().finish()).into()
283 });
284 let app =
285 init_service(App::new().app_data(config).route("/", web::post().to(service))).await;
286
287 let request = TestRequest::default()
288 .method(Method::POST)
289 .insert_header((header::CONTENT_TYPE, APPLICATION_MSGPACK))
290 .to_request();
291 let response = call_service(&app, request).await;
292
293 assert_eq!(response.status(), StatusCode::NOT_ACCEPTABLE);
294 }
295
296 #[actix_web::test]
297 async fn check_custom_content_type() {
298 async fn service(_: MsgPack<Data>) -> HttpResponse {
299 HttpResponse::Ok().finish()
300 }
301
302 let payload =
303 Bytes::from_static(&[0x81, 0xa7, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0xc3]);
304
305 let mut config = MsgPackConfig::default();
306 config.content_type(|mime_type| mime_type == APPLICATION_JSON);
307
308 let app =
309 init_service(App::new().app_data(config).route("/", web::post().to(service))).await;
310
311 let request = TestRequest::default()
312 .method(Method::POST)
313 .set_payload(payload)
314 .insert_header((header::CONTENT_TYPE, APPLICATION_JSON))
315 .to_request();
316 let response = call_service(&app, request).await;
317
318 assert_eq!(response.status(), StatusCode::OK);
319 }
320
321 #[actix_web::test]
322 async fn check_default_content_type() {
323 async fn service(_: MsgPack<Data>) -> HttpResponse {
324 HttpResponse::Ok().finish()
325 }
326
327 let payload =
328 Bytes::from_static(&[0x81, 0xa7, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0xc3]);
329
330 let config = MsgPackConfig::default();
331
332 let app =
333 init_service(App::new().app_data(config).route("/", web::post().to(service))).await;
334
335 let request = TestRequest::default()
336 .method(Method::POST)
337 .set_payload(payload)
338 .insert_header((header::CONTENT_TYPE, APPLICATION_MSGPACK))
339 .to_request();
340 let response = call_service(&app, request).await;
341
342 assert_eq!(response.status(), StatusCode::OK);
343 }
344}