From 1dc99ea4515d257148f9aec53cfc78a8bd5b90bb Mon Sep 17 00:00:00 2001 From: Tamo Date: Tue, 29 Jun 2021 11:57:47 +0200 Subject: [PATCH] accept no content-type as json --- meilisearch-http/src/routes/document.rs | 16 ++++ .../tests/documents/add_documents.rs | 78 ++++++++++++++++++- 2 files changed, 93 insertions(+), 1 deletion(-) diff --git a/meilisearch-http/src/routes/document.rs b/meilisearch-http/src/routes/document.rs index 817f624d0..eb41f7eff 100644 --- a/meilisearch-http/src/routes/document.rs +++ b/meilisearch-http/src/routes/document.rs @@ -13,6 +13,7 @@ use crate::Data; const DEFAULT_RETRIEVE_DOCUMENTS_OFFSET: usize = 0; const DEFAULT_RETRIEVE_DOCUMENTS_LIMIT: usize = 20; +/* macro_rules! guard_content_type { ($fn_name:ident, $guard_value:literal) => { fn $fn_name(head: &actix_web::dev::RequestHead) -> bool { @@ -29,6 +30,19 @@ macro_rules! guard_content_type { } guard_content_type!(guard_json, "application/json"); +*/ + +fn guard_json(head: &actix_web::dev::RequestHead) -> bool { + if let Some(content_type) = head.headers.get("Content-Type") { + content_type + .to_str() + .map(|v| v.contains("application/json")) + // if no content-type is specified we still accept the data as json! + .unwrap_or(true) + } else { + false + } + } #[derive(Deserialize)] struct DocumentParam { @@ -146,6 +160,8 @@ async fn add_documents( Ok(HttpResponse::Accepted().json(serde_json::json!({ "updateId": update_status.id() }))) } +/// Route used when the payload type is "application/json" +/// Used to add or replace documents async fn update_documents( data: GuardedData, path: web::Path, diff --git a/meilisearch-http/tests/documents/add_documents.rs b/meilisearch-http/tests/documents/add_documents.rs index 5d2a91674..66e475172 100644 --- a/meilisearch-http/tests/documents/add_documents.rs +++ b/meilisearch-http/tests/documents/add_documents.rs @@ -1,7 +1,83 @@ +use crate::common::{GetAllDocumentsOptions, Server}; +use actix_web::test; use chrono::DateTime; +use meilisearch_http::create_app; use serde_json::{json, Value}; -use crate::common::{GetAllDocumentsOptions, Server}; +/// This is the basic usage of our API and every other tests uses the content-type application/json +#[actix_rt::test] +async fn add_documents_test_json_content_types() { + let document = json!([ + { + "id": 1, + "content": "Bouvier Bernois", + } + ]); + + // this is a what is expected and should work + let server = Server::new().await; + let app = test::init_service(create_app!(&server.service.0, true)).await; + let req = test::TestRequest::post() + .uri("/indexes/dog/documents") + .set_payload(document.to_string()) + .insert_header(("content-type", "application/json")) + .to_request(); + let res = test::call_service(&app, req).await; + let status_code = res.status(); + let body = test::read_body(res).await; + let response: Value = serde_json::from_slice(&body).unwrap_or_default(); + assert_eq!(status_code, 202); + assert_eq!(response, json!({ "updateId": 0 })); +} + +/// no content type is still supposed to be accepted as json +#[actix_rt::test] +async fn add_documents_test_no_content_types() { + let document = json!([ + { + "id": 1, + "content": "Montagne des Pyrénées", + } + ]); + + let server = Server::new().await; + let app = test::init_service(create_app!(&server.service.0, true)).await; + let req = test::TestRequest::post() + .uri("/indexes/dog/documents") + .set_payload(document.to_string()) + .insert_header(("content-type", "application/json")) + .to_request(); + let res = test::call_service(&app, req).await; + let status_code = res.status(); + let body = test::read_body(res).await; + let response: Value = serde_json::from_slice(&body).unwrap_or_default(); + assert_eq!(status_code, 202); + assert_eq!(response, json!({ "updateId": 0 })); +} + +/// any other content-type is must be refused +#[actix_rt::test] +async fn add_documents_test_bad_content_types() { + let document = json!([ + { + "id": 1, + "content": "Leonberg", + } + ]); + + let server = Server::new().await; + let app = test::init_service(create_app!(&server.service.0, true)).await; + let req = test::TestRequest::post() + .uri("/indexes/dog/documents") + .set_payload(document.to_string()) + .insert_header(("content-type", "text/plain")) + .to_request(); + let res = test::call_service(&app, req).await; + let status_code = res.status(); + let body = test::read_body(res).await; + assert_eq!(status_code, 405); + assert!(body.is_empty()); +} #[actix_rt::test] async fn add_documents_no_index_creation() {