mirror of
https://github.com/meilisearch/MeiliSearch
synced 2025-01-22 19:27:27 +01:00
makes the content-type mandatory for every routes
This commit is contained in:
parent
ddbcf449da
commit
c6d107a05f
@ -11,17 +11,21 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
pub enum MeilisearchHttpError {
|
pub enum MeilisearchHttpError {
|
||||||
#[error("A Content-Type header is missing. Accepted values for the Content-Type header are: \"application/json\", \"application/x-ndjson\", \"text/csv\"")]
|
#[error("A Content-Type header is missing. Accepted values for the Content-Type header are: {}",
|
||||||
MissingContentType,
|
.0.iter().map(|s| format!("\"{}\"", s)).collect::<Vec<_>>().join(", "))]
|
||||||
#[error("The Content-Type \"{0}\" is invalid. Accepted values for the Content-Type header are: \"application/json\", \"application/x-ndjson\", \"text/csv\"")]
|
MissingContentType(Vec<String>),
|
||||||
InvalidContentType(String),
|
#[error(
|
||||||
|
"The Content-Type \"{0}\" is invalid. Accepted values for the Content-Type header are: {}",
|
||||||
|
.1.iter().map(|s| format!("\"{}\"", s)).collect::<Vec<_>>().join(", ")
|
||||||
|
)]
|
||||||
|
InvalidContentType(String, Vec<String>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ErrorCode for MeilisearchHttpError {
|
impl ErrorCode for MeilisearchHttpError {
|
||||||
fn error_code(&self) -> Code {
|
fn error_code(&self) -> Code {
|
||||||
match self {
|
match self {
|
||||||
MeilisearchHttpError::MissingContentType => Code::MissingContentType,
|
MeilisearchHttpError::MissingContentType(_) => Code::MissingContentType,
|
||||||
MeilisearchHttpError::InvalidContentType(_) => Code::InvalidContentType,
|
MeilisearchHttpError::InvalidContentType(_, _) => Code::InvalidContentType,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,10 @@ pub mod routes;
|
|||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use crate::error::{MeilisearchHttpError, ResponseError};
|
||||||
use crate::extractors::authentication::AuthConfig;
|
use crate::extractors::authentication::AuthConfig;
|
||||||
|
use actix_web::error::JsonPayloadError;
|
||||||
|
use http::header::CONTENT_TYPE;
|
||||||
pub use option::Opt;
|
pub use option::Opt;
|
||||||
|
|
||||||
use actix_web::web;
|
use actix_web::web;
|
||||||
@ -98,9 +101,28 @@ pub fn configure_data(config: &mut web::ServiceConfig, data: MeiliSearch, opt: &
|
|||||||
.app_data(data)
|
.app_data(data)
|
||||||
.app_data(
|
.app_data(
|
||||||
web::JsonConfig::default()
|
web::JsonConfig::default()
|
||||||
.limit(http_payload_size_limit)
|
.content_type(|mime| mime == mime::APPLICATION_JSON)
|
||||||
.content_type(|_mime| true) // Accept all mime types
|
.error_handler(|err, req| match err {
|
||||||
.error_handler(|err, _req| error::payload_error_handler(err).into()),
|
JsonPayloadError::ContentType if req.headers().get(CONTENT_TYPE).is_none() => {
|
||||||
|
ResponseError::from(MeilisearchHttpError::MissingContentType(vec![
|
||||||
|
mime::APPLICATION_JSON.to_string(),
|
||||||
|
]))
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
JsonPayloadError::ContentType => {
|
||||||
|
ResponseError::from(MeilisearchHttpError::InvalidContentType(
|
||||||
|
req.headers()
|
||||||
|
.get(CONTENT_TYPE)
|
||||||
|
.unwrap()
|
||||||
|
.to_str()
|
||||||
|
.unwrap_or("unknown")
|
||||||
|
.to_string(),
|
||||||
|
vec![mime::APPLICATION_JSON.to_string()],
|
||||||
|
))
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
err => error::payload_error_handler(err).into(),
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
.app_data(PayloadConfig::new(http_payload_size_limit))
|
.app_data(PayloadConfig::new(http_payload_size_limit))
|
||||||
.app_data(
|
.app_data(
|
||||||
@ -180,6 +202,7 @@ macro_rules! create_app {
|
|||||||
use actix_web::middleware::TrailingSlash;
|
use actix_web::middleware::TrailingSlash;
|
||||||
use actix_web::App;
|
use actix_web::App;
|
||||||
use actix_web::{middleware, web};
|
use actix_web::{middleware, web};
|
||||||
|
use meilisearch_http::error::{MeilisearchHttpError, ResponseError};
|
||||||
use meilisearch_http::routes;
|
use meilisearch_http::routes;
|
||||||
use meilisearch_http::{configure_auth, configure_data, dashboard};
|
use meilisearch_http::{configure_auth, configure_data, dashboard};
|
||||||
|
|
||||||
|
@ -181,9 +181,24 @@ async fn document_addition(
|
|||||||
Some("application/x-ndjson") => DocumentAdditionFormat::Ndjson,
|
Some("application/x-ndjson") => DocumentAdditionFormat::Ndjson,
|
||||||
Some("text/csv") => DocumentAdditionFormat::Csv,
|
Some("text/csv") => DocumentAdditionFormat::Csv,
|
||||||
Some(other) => {
|
Some(other) => {
|
||||||
return Err(MeilisearchHttpError::InvalidContentType(other.to_string()).into())
|
return Err(MeilisearchHttpError::InvalidContentType(
|
||||||
|
other.to_string(),
|
||||||
|
vec![
|
||||||
|
"application/json".to_string(),
|
||||||
|
"application/x-ndjson".to_string(),
|
||||||
|
"application/csv".to_string(),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
.into())
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
return Err(MeilisearchHttpError::MissingContentType(vec![
|
||||||
|
"application/json".to_string(),
|
||||||
|
"application/x-ndjson".to_string(),
|
||||||
|
"application/csv".to_string(),
|
||||||
|
])
|
||||||
|
.into())
|
||||||
}
|
}
|
||||||
None => return Err(MeilisearchHttpError::MissingContentType.into()),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let update = Update::DocumentAddition {
|
let update = Update::DocumentAddition {
|
||||||
|
@ -67,7 +67,6 @@ async fn add_documents_test_no_content_types() {
|
|||||||
|
|
||||||
/// any other content-type is must be refused
|
/// any other content-type is must be refused
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
#[ignore]
|
|
||||||
async fn add_documents_test_bad_content_types() {
|
async fn add_documents_test_bad_content_types() {
|
||||||
let document = json!([
|
let document = json!([
|
||||||
{
|
{
|
||||||
@ -91,8 +90,14 @@ async fn add_documents_test_bad_content_types() {
|
|||||||
let res = test::call_service(&app, req).await;
|
let res = test::call_service(&app, req).await;
|
||||||
let status_code = res.status();
|
let status_code = res.status();
|
||||||
let body = test::read_body(res).await;
|
let body = test::read_body(res).await;
|
||||||
assert_eq!(status_code, 405);
|
let response: Value = serde_json::from_slice(&body).unwrap_or_default();
|
||||||
assert!(body.is_empty());
|
assert_eq!(status_code, 415);
|
||||||
|
assert_eq!(
|
||||||
|
response["message"],
|
||||||
|
json!(
|
||||||
|
r#"The Content-Type "text/plain" is invalid. Accepted values for the Content-Type header are: "application/json", "application/x-ndjson", "application/csv""#
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user