mirror of
https://github.com/meilisearch/MeiliSearch
synced 2024-11-22 12:54:26 +01:00
invalid content type error
This commit is contained in:
parent
ddd40d87a7
commit
18cb514073
@ -84,6 +84,7 @@ pub enum Code {
|
||||
DumpAlreadyInProgress,
|
||||
DumpProcessFailed,
|
||||
|
||||
InvalidContentType,
|
||||
MissingContentType,
|
||||
MalformedPayload,
|
||||
}
|
||||
@ -158,7 +159,8 @@ impl Code {
|
||||
ErrCode::internal("dump_process_failed", StatusCode::INTERNAL_SERVER_ERROR)
|
||||
}
|
||||
MissingContentType => ErrCode::invalid("missing_content_type", StatusCode::UNSUPPORTED_MEDIA_TYPE),
|
||||
MalformedPayload => ErrCode::invalid("malformed_payload", StatusCode::BAD_REQUEST)
|
||||
MalformedPayload => ErrCode::invalid("malformed_payload", StatusCode::BAD_REQUEST),
|
||||
InvalidContentType => ErrCode::invalid("invalid_content_type", StatusCode::UNSUPPORTED_MEDIA_TYPE),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,12 +13,15 @@ use serde::{Deserialize, Serialize};
|
||||
pub enum MeilisearchHttpError {
|
||||
#[error("A Content-Type header is missing. Accepted values for the Content-Type header are: \"application/json\", \"application/x-ndjson\", \"test/csv\"")]
|
||||
MissingContentType,
|
||||
#[error("The Content-Type \"{0}\" is invalid. Accepted values for the Content-Type header are: \"application/json\", \"application/x-ndjson\", \"test/csv\"")]
|
||||
InvalidContentType(String),
|
||||
}
|
||||
|
||||
impl ErrorCode for MeilisearchHttpError {
|
||||
fn error_code(&self) -> Code {
|
||||
match self {
|
||||
MeilisearchHttpError::MissingContentType => Code::MissingContentType,
|
||||
MeilisearchHttpError::InvalidContentType(_) => Code::InvalidContentType,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use actix_web::error::PayloadError;
|
||||
use actix_web::web::Bytes;
|
||||
use actix_web::{web, HttpResponse};
|
||||
use actix_web::{web, HttpRequest, HttpResponse};
|
||||
use futures::{Stream, StreamExt};
|
||||
use log::debug;
|
||||
use meilisearch_lib::index_controller::{DocumentAdditionFormat, Update};
|
||||
@ -18,29 +18,6 @@ use crate::routes::IndexParam;
|
||||
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 {
|
||||
if let Some(content_type) = head.headers.get("Content-Type") {
|
||||
content_type
|
||||
.to_str()
|
||||
.map(|v| v.contains($guard_value))
|
||||
.unwrap_or(false)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
guard_content_type!(guard_ndjson, "application/x-ndjson");
|
||||
guard_content_type!(guard_csv, "text/csv");
|
||||
guard_content_type!(guard_json, "application/json");
|
||||
|
||||
fn empty_application_type(head: &actix_web::dev::RequestHead) -> bool {
|
||||
head.headers.get("Content-Type").is_none()
|
||||
}
|
||||
|
||||
/// This is required because Payload is not Sync nor Send
|
||||
fn payload_to_stream(mut payload: Payload) -> impl Stream<Item = Result<Bytes, PayloadError>> {
|
||||
let (snd, recv) = mpsc::channel(1);
|
||||
@ -62,26 +39,8 @@ pub fn configure(cfg: &mut web::ServiceConfig) {
|
||||
cfg.service(
|
||||
web::resource("")
|
||||
.route(web::get().to(get_all_documents))
|
||||
// replace documents routes
|
||||
.route(
|
||||
web::post()
|
||||
.guard(empty_application_type)
|
||||
.to(missing_content_type_error),
|
||||
)
|
||||
.route(web::post().guard(guard_json).to(add_documents_json))
|
||||
.route(web::post().guard(guard_ndjson).to(add_documents_ndjson))
|
||||
.route(web::post().guard(guard_csv).to(add_documents_csv))
|
||||
.route(web::post().to(HttpResponse::UnsupportedMediaType))
|
||||
// update documents routes
|
||||
.route(
|
||||
web::put()
|
||||
.guard(empty_application_type)
|
||||
.to(missing_content_type_error),
|
||||
)
|
||||
.route(web::put().guard(guard_json).to(update_documents_json))
|
||||
.route(web::put().guard(guard_ndjson).to(update_documents_ndjson))
|
||||
.route(web::put().guard(guard_csv).to(update_documents_csv))
|
||||
.route(web::put().to(HttpResponse::UnsupportedMediaType))
|
||||
.route(web::post().to(add_documents))
|
||||
.route(web::put().to(update_documents))
|
||||
.route(web::delete().to(clear_all_documents)),
|
||||
)
|
||||
// this route needs to be before the /documents/{document_id} to match properly
|
||||
@ -93,10 +52,6 @@ pub fn configure(cfg: &mut web::ServiceConfig) {
|
||||
);
|
||||
}
|
||||
|
||||
async fn missing_content_type_error() -> Result<HttpResponse, ResponseError> {
|
||||
Err(MeilisearchHttpError::MissingContentType.into())
|
||||
}
|
||||
|
||||
pub async fn get_document(
|
||||
meilisearch: GuardedData<Public, MeiliSearch>,
|
||||
path: web::Path<DocumentParam>,
|
||||
@ -169,126 +124,69 @@ pub struct UpdateDocumentsQuery {
|
||||
primary_key: Option<String>,
|
||||
}
|
||||
|
||||
pub async fn add_documents_json(
|
||||
pub async fn add_documents(
|
||||
meilisearch: GuardedData<Private, MeiliSearch>,
|
||||
path: web::Path<IndexParam>,
|
||||
params: web::Query<UpdateDocumentsQuery>,
|
||||
body: Payload,
|
||||
req: HttpRequest,
|
||||
) -> Result<HttpResponse, ResponseError> {
|
||||
debug!("called with params: {:?}", params);
|
||||
document_addition(
|
||||
req.headers().get("Content-type").map(|s| s.to_str().unwrap_or("unkown")),
|
||||
meilisearch,
|
||||
path,
|
||||
params,
|
||||
path.into_inner().index_uid,
|
||||
params.into_inner().primary_key,
|
||||
body,
|
||||
DocumentAdditionFormat::Json,
|
||||
IndexDocumentsMethod::ReplaceDocuments,
|
||||
)
|
||||
IndexDocumentsMethod::ReplaceDocuments)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn add_documents_ndjson(
|
||||
pub async fn update_documents(
|
||||
meilisearch: GuardedData<Private, MeiliSearch>,
|
||||
path: web::Path<IndexParam>,
|
||||
params: web::Query<UpdateDocumentsQuery>,
|
||||
body: Payload,
|
||||
req: HttpRequest,
|
||||
) -> Result<HttpResponse, ResponseError> {
|
||||
debug!("called with params: {:?}", params);
|
||||
document_addition(
|
||||
req.headers().get("Content-type").map(|s| s.to_str().unwrap_or("unkown")),
|
||||
meilisearch,
|
||||
path,
|
||||
params,
|
||||
path.into_inner().index_uid,
|
||||
params.into_inner().primary_key,
|
||||
body,
|
||||
DocumentAdditionFormat::Ndjson,
|
||||
IndexDocumentsMethod::ReplaceDocuments,
|
||||
)
|
||||
IndexDocumentsMethod::UpdateDocuments)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn add_documents_csv(
|
||||
meilisearch: GuardedData<Private, MeiliSearch>,
|
||||
path: web::Path<IndexParam>,
|
||||
params: web::Query<UpdateDocumentsQuery>,
|
||||
body: Payload,
|
||||
) -> Result<HttpResponse, ResponseError> {
|
||||
document_addition(
|
||||
meilisearch,
|
||||
path,
|
||||
params,
|
||||
body,
|
||||
DocumentAdditionFormat::Csv,
|
||||
IndexDocumentsMethod::ReplaceDocuments,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn update_documents_json(
|
||||
meilisearch: GuardedData<Private, MeiliSearch>,
|
||||
path: web::Path<IndexParam>,
|
||||
params: web::Query<UpdateDocumentsQuery>,
|
||||
body: Payload,
|
||||
) -> Result<HttpResponse, ResponseError> {
|
||||
document_addition(
|
||||
meilisearch,
|
||||
path,
|
||||
params,
|
||||
body,
|
||||
DocumentAdditionFormat::Json,
|
||||
IndexDocumentsMethod::UpdateDocuments,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn update_documents_ndjson(
|
||||
meilisearch: GuardedData<Private, MeiliSearch>,
|
||||
path: web::Path<IndexParam>,
|
||||
params: web::Query<UpdateDocumentsQuery>,
|
||||
body: Payload,
|
||||
) -> Result<HttpResponse, ResponseError> {
|
||||
document_addition(
|
||||
meilisearch,
|
||||
path,
|
||||
params,
|
||||
body,
|
||||
DocumentAdditionFormat::Ndjson,
|
||||
IndexDocumentsMethod::UpdateDocuments,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn update_documents_csv(
|
||||
meilisearch: GuardedData<Private, MeiliSearch>,
|
||||
path: web::Path<IndexParam>,
|
||||
params: web::Query<UpdateDocumentsQuery>,
|
||||
body: Payload,
|
||||
) -> Result<HttpResponse, ResponseError> {
|
||||
document_addition(
|
||||
meilisearch,
|
||||
path,
|
||||
params,
|
||||
body,
|
||||
DocumentAdditionFormat::Csv,
|
||||
IndexDocumentsMethod::UpdateDocuments,
|
||||
)
|
||||
.await
|
||||
}
|
||||
/// Route used when the payload type is "application/json"
|
||||
/// Used to add or replace documents
|
||||
async fn document_addition(
|
||||
content_type: Option<&str>,
|
||||
meilisearch: GuardedData<Private, MeiliSearch>,
|
||||
path: web::Path<IndexParam>,
|
||||
params: web::Query<UpdateDocumentsQuery>,
|
||||
index_uid: String,
|
||||
primary_key: Option<String>,
|
||||
body: Payload,
|
||||
format: DocumentAdditionFormat,
|
||||
method: IndexDocumentsMethod,
|
||||
) -> Result<HttpResponse, ResponseError> {
|
||||
debug!("called with params: {:?}", params);
|
||||
let format = match content_type {
|
||||
Some("application/json") => DocumentAdditionFormat::Json,
|
||||
Some("application/x-ndjson") => DocumentAdditionFormat::Ndjson,
|
||||
Some("text/csv") => DocumentAdditionFormat::Csv,
|
||||
Some(other) => return Err(MeilisearchHttpError::InvalidContentType(other.to_string()).into()),
|
||||
None => return Err(MeilisearchHttpError::MissingContentType.into()),
|
||||
};
|
||||
|
||||
let update = Update::DocumentAddition {
|
||||
payload: Box::new(payload_to_stream(body)),
|
||||
primary_key: params.primary_key.clone(),
|
||||
primary_key,
|
||||
method,
|
||||
format,
|
||||
};
|
||||
|
||||
let update_status = meilisearch
|
||||
.register_update(path.into_inner().index_uid, update, true)
|
||||
.register_update(index_uid, update, true)
|
||||
.await?;
|
||||
|
||||
debug!("returns: {:?}", update_status);
|
||||
|
@ -361,10 +361,8 @@ mod test {
|
||||
|
||||
indexes::documents::clear_all_documents,
|
||||
indexes::documents::delete_documents,
|
||||
indexes::documents::update_documents_json,
|
||||
indexes::documents::update_documents_csv,
|
||||
indexes::documents::add_documents_json,
|
||||
indexes::documents::add_documents_csv,
|
||||
indexes::documents::update_documents,
|
||||
indexes::documents::add_documents,
|
||||
indexes::documents::delete_document,
|
||||
|
||||
indexes::updates::get_all_updates_status,
|
||||
|
Loading…
Reference in New Issue
Block a user