bump tide version

This commit is contained in:
qdequele 2020-01-15 17:10:33 +01:00
parent a35eb16a2a
commit 0e12920910
No known key found for this signature in database
GPG Key ID: B3F0A000EBF11745
15 changed files with 404 additions and 806 deletions

764
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -37,27 +37,14 @@ sysinfo = "0.9.5"
ureq = { version = "0.11.2", features = ["tls"], default-features = false }
walkdir = "2.2.9"
whoami = "0.6"
tide = "0.5.1"
async-std = { version = "1.0.1", features = ["unstable", "attributes"] }
[dependencies.async-compression]
default-features = false
features = ["stream", "gzip", "zlib", "brotli", "zstd"]
version = "=0.1.0-alpha.7"
[dev-dependencies]
http-service-mock = "0.4.0"
http-service = "0.4.0"
[dependencies.tide]
git = "https://github.com/rustasync/tide"
rev = "e77709370bb24cf776fe6da902467c35131535b1"
[dependencies.tide-log]
git = "https://github.com/rustasync/tide"
rev = "e77709370bb24cf776fe6da902467c35131535b1"
[dependencies.tide-slog]
git = "https://github.com/rustasync/tide"
rev = "e77709370bb24cf776fe6da902467c35131535b1"
[dependencies.tide-compression]
git = "https://github.com/rustasync/tide"
rev = "e77709370bb24cf776fe6da902467c35131535b1"
tempdir = "0.3.7"
[build-dependencies]
vergen = "3.0.4"

View File

@ -3,7 +3,7 @@ use std::fmt::Display;
use http::status::StatusCode;
use log::{error, warn};
use serde::{Deserialize, Serialize};
use tide::response::IntoResponse;
use tide::IntoResponse;
use tide::Response;
pub type SResult<T> = Result<T, ResponseError>;
@ -120,7 +120,5 @@ struct ErrorMessage {
fn error(message: String, status: StatusCode) -> Response {
let message = ErrorMessage { message };
tide::response::json(message)
.with_status(status)
.into_response()
tide::Response::new(status.as_u16()).body_json(&message).unwrap()
}

View File

@ -4,9 +4,9 @@ use crate::Data;
use chrono::Utc;
use heed::types::{SerdeBincode, Str};
use meilisearch_core::Index;
use tide::Context;
use tide::Request;
pub trait ContextExt {
pub trait RequestExt {
fn is_allowed(&self, acl: ACL) -> SResult<()>;
fn header(&self, name: &str) -> Result<String, ResponseError>;
fn url_param(&self, name: &str) -> Result<String, ResponseError>;
@ -14,14 +14,16 @@ pub trait ContextExt {
fn identifier(&self) -> Result<String, ResponseError>;
}
impl ContextExt for Context<Data> {
impl RequestExt for Request<Data> {
fn is_allowed(&self, acl: ACL) -> SResult<()> {
let api_key = match &self.state().api_key {
Some(api_key) => api_key,
None => return Ok(()),
};
let user_api_key = self.header("X-Meili-API-Key")?;
let user_api_key = self.header("X-Meili-API-Key")
.ok_or(ResponseError::missing_header("X-Meili-API-Key"))?;
if user_api_key == *api_key {
return Ok(());
}

View File

@ -1,12 +1,12 @@
use std::env::VarError::NotPresent;
use std::{env, thread};
use http::header::HeaderValue;
use async_std::task;
use log::info;
use main_error::MainError;
use structopt::StructOpt;
use tide::middleware::{CorsMiddleware, CorsOrigin};
use tide_log::RequestLogger;
// use tide::middleware::{CorsMiddleware, CorsOrigin};
// use tide_log::RequestLogger;
use meilisearch_http::data::Data;
use meilisearch_http::option::Opt;
@ -34,21 +34,23 @@ pub fn main() -> Result<(), MainError> {
index_update_callback(name, &data_cloned, status);
}));
let mut app = tide::App::with_state(data);
let mut app = tide::with_state(data);
app.middleware(
CorsMiddleware::new()
.allow_origin(CorsOrigin::from("*"))
.allow_methods(HeaderValue::from_static("GET, POST, OPTIONS")),
);
app.middleware(RequestLogger::new());
app.middleware(tide_compression::Compression::new());
app.middleware(tide_compression::Decompression::new());
// app.middleware(
// CorsMiddleware::new()
// .allow_origin(CorsOrigin::from("*"))
// .allow_methods(HeaderValue::from_static("GET, POST, OPTIONS")),
// );
// app.middleware(RequestLogger::new());
// app.middleware(tide_compression::Compression::new());
// app.middleware(tide_compression::Decompression::new());
routes::load_routes(&mut app);
info!("Server HTTP enabled");
app.run(opt.http_addr)?;
task::block_on(async {
app.listen(opt.http_addr).await.unwrap();
});
Ok(())
}

View File

@ -1,21 +1,18 @@
use std::collections::{BTreeSet, HashSet};
use http::StatusCode;
use indexmap::IndexMap;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use tide::querystring::ContextExt as QSContextExt;
use tide::response::IntoResponse;
use tide::{Context, Response};
use tide::{Request, Response};
use meilisearch_core::settings::Settings;
use crate::error::{ResponseError, SResult};
use crate::helpers::tide::ContextExt;
use crate::helpers::tide::RequestExt;
use crate::models::token::ACL::*;
use crate::Data;
pub async fn get_document(ctx: Context<Data>) -> SResult<Response> {
pub async fn get_document(ctx: Request<Data>) -> SResult<Response> {
ctx.is_allowed(DocumentsRead)?;
let index = ctx.index()?;
@ -35,7 +32,7 @@ pub async fn get_document(ctx: Context<Data>) -> SResult<Response> {
return Err(ResponseError::document_not_found(identifier));
}
Ok(tide::response::json(response))
Ok(tide::Response::new(200).body_json(&response).unwrap())
}
#[derive(Default, Serialize)]
@ -44,7 +41,7 @@ pub struct IndexUpdateResponse {
pub update_id: u64,
}
pub async fn delete_document(ctx: Context<Data>) -> SResult<Response> {
pub async fn delete_document(ctx: Request<Data>) -> SResult<Response> {
ctx.is_allowed(DocumentsWrite)?;
let index = ctx.index()?;
@ -63,9 +60,7 @@ pub async fn delete_document(ctx: Context<Data>) -> SResult<Response> {
update_writer.commit().map_err(ResponseError::internal)?;
let response_body = IndexUpdateResponse { update_id };
Ok(tide::response::json(response_body)
.with_status(StatusCode::ACCEPTED)
.into_response())
Ok(tide::Response::new(202).body_json(&response_body).unwrap())
}
#[derive(Default, Deserialize)]
@ -76,11 +71,11 @@ struct BrowseQuery {
attributes_to_retrieve: Option<String>,
}
pub async fn get_all_documents(ctx: Context<Data>) -> SResult<Response> {
pub async fn get_all_documents(ctx: Request<Data>) -> SResult<Response> {
ctx.is_allowed(DocumentsRead)?;
let index = ctx.index()?;
let query: BrowseQuery = ctx.url_query().unwrap_or(BrowseQuery::default());
let query: BrowseQuery = ctx.query().unwrap_or(BrowseQuery::default());
let offset = query.offset.unwrap_or(0);
let limit = query.limit.unwrap_or(20);
@ -116,7 +111,7 @@ pub async fn get_all_documents(ctx: Context<Data>) -> SResult<Response> {
}
}
Ok(tide::response::json(response_body))
Ok(tide::Response::new(200).body_json(&response_body).unwrap())
}
fn find_identifier(document: &IndexMap<String, Value>) -> Option<String> {
@ -134,15 +129,14 @@ struct UpdateDocumentsQuery {
identifier: Option<String>,
}
async fn update_multiple_documents(mut ctx: Context<Data>, is_partial: bool) -> SResult<Response> {
async fn update_multiple_documents(mut ctx: Request<Data>, is_partial: bool) -> SResult<Response> {
ctx.is_allowed(DocumentsWrite)?;
let index = ctx.index()?;
let data: Vec<IndexMap<String, Value>> =
ctx.body_json().await.map_err(ResponseError::bad_request)?;
let query: UpdateDocumentsQuery = ctx
.url_query().unwrap_or_default();
let query: UpdateDocumentsQuery = ctx.query().unwrap_or_default();
let db = &ctx.state().db;
let reader = db.main_read_txn().map_err(ResponseError::internal)?;
@ -188,20 +182,18 @@ async fn update_multiple_documents(mut ctx: Context<Data>, is_partial: bool) ->
update_writer.commit().map_err(ResponseError::internal)?;
let response_body = IndexUpdateResponse { update_id };
Ok(tide::response::json(response_body)
.with_status(StatusCode::ACCEPTED)
.into_response())
Ok(tide::Response::new(202).body_json(&response_body).unwrap())
}
pub async fn add_or_replace_multiple_documents(ctx: Context<Data>) -> SResult<Response> {
pub async fn add_or_replace_multiple_documents(ctx: Request<Data>) -> SResult<Response> {
update_multiple_documents(ctx, false).await
}
pub async fn add_or_update_multiple_documents(ctx: Context<Data>) -> SResult<Response> {
pub async fn add_or_update_multiple_documents(ctx: Request<Data>) -> SResult<Response> {
update_multiple_documents(ctx, true).await
}
pub async fn delete_multiple_documents(mut ctx: Context<Data>) -> SResult<Response> {
pub async fn delete_multiple_documents(mut ctx: Request<Data>) -> SResult<Response> {
ctx.is_allowed(DocumentsWrite)?;
let data: Vec<Value> = ctx.body_json().await.map_err(ResponseError::bad_request)?;
@ -226,12 +218,10 @@ pub async fn delete_multiple_documents(mut ctx: Context<Data>) -> SResult<Respon
writer.commit().map_err(ResponseError::internal)?;
let response_body = IndexUpdateResponse { update_id };
Ok(tide::response::json(response_body)
.with_status(StatusCode::ACCEPTED)
.into_response())
Ok(tide::Response::new(202).body_json(&response_body).unwrap())
}
pub async fn clear_all_documents(ctx: Context<Data>) -> SResult<Response> {
pub async fn clear_all_documents(ctx: Request<Data>) -> SResult<Response> {
ctx.is_allowed(DocumentsWrite)?;
let index = ctx.index()?;
@ -245,7 +235,5 @@ pub async fn clear_all_documents(ctx: Context<Data>) -> SResult<Response> {
writer.commit().map_err(ResponseError::internal)?;
let response_body = IndexUpdateResponse { update_id };
Ok(tide::response::json(response_body)
.with_status(StatusCode::ACCEPTED)
.into_response())
Ok(tide::Response::new(202).body_json(&response_body).unwrap())
}

View File

@ -1,15 +1,15 @@
use crate::error::{ResponseError, SResult};
use crate::helpers::tide::ContextExt;
use crate::helpers::tide::RequestExt;
use crate::models::token::ACL::*;
use crate::Data;
use heed::types::{Str, Unit};
use serde::Deserialize;
use tide::Context;
use tide::{Response, Request};
const UNHEALTHY_KEY: &str = "_is_unhealthy";
pub async fn get_health(ctx: Context<Data>) -> SResult<()> {
pub async fn get_health(ctx: Request<Data>) -> SResult<Response> {
let db = &ctx.state().db;
let reader = db.main_read_txn().map_err(ResponseError::internal)?;
@ -19,10 +19,10 @@ pub async fn get_health(ctx: Context<Data>) -> SResult<()> {
return Err(ResponseError::Maintenance);
}
Ok(())
Ok(tide::Response::new(200))
}
pub async fn set_healthy(ctx: Context<Data>) -> SResult<()> {
pub async fn set_healthy(ctx: Request<Data>) -> SResult<Response> {
ctx.is_allowed(Admin)?;
let db = &ctx.state().db;
@ -38,10 +38,10 @@ pub async fn set_healthy(ctx: Context<Data>) -> SResult<()> {
return Err(ResponseError::internal(e));
}
Ok(())
Ok(tide::Response::new(200))
}
pub async fn set_unhealthy(ctx: Context<Data>) -> SResult<()> {
pub async fn set_unhealthy(ctx: Request<Data>) -> SResult<Response> {
ctx.is_allowed(Admin)?;
let db = &ctx.state().db;
@ -57,7 +57,7 @@ pub async fn set_unhealthy(ctx: Context<Data>) -> SResult<()> {
return Err(ResponseError::internal(e));
}
Ok(())
Ok(tide::Response::new(200))
}
#[derive(Deserialize, Clone)]
@ -65,7 +65,7 @@ struct HealtBody {
health: bool,
}
pub async fn change_healthyness(mut ctx: Context<Data>) -> SResult<()> {
pub async fn change_healthyness(mut ctx: Request<Data>) -> SResult<Response> {
let body: HealtBody = ctx.body_json().await.map_err(ResponseError::bad_request)?;
if body.health {

View File

@ -1,16 +1,13 @@
use chrono::{DateTime, Utc};
use http::StatusCode;
use log::error;
use meilisearch_core::ProcessedUpdateResult;
// use meilisearch_schema::Schema;
use rand::seq::SliceRandom;
use serde::{Deserialize, Serialize};
use serde_json::json;
use tide::response::IntoResponse;
use tide::{Context, Response};
use tide::{Request, Response};
use crate::error::{ResponseError, SResult};
use crate::helpers::tide::ContextExt;
use crate::helpers::tide::RequestExt;
use crate::models::token::ACL::*;
use crate::Data;
@ -23,7 +20,7 @@ fn generate_uid() -> String {
.collect()
}
pub async fn list_indexes(ctx: Context<Data>) -> SResult<Response> {
pub async fn list_indexes(ctx: Request<Data>) -> SResult<Response> {
ctx.is_allowed(IndexesRead)?;
let indexes_uids = ctx.state().db.indexes_uids();
@ -69,7 +66,7 @@ pub async fn list_indexes(ctx: Context<Data>) -> SResult<Response> {
}
}
Ok(tide::response::json(response_body))
Ok(tide::Response::new(200).body_json(&response_body).unwrap())
}
#[derive(Debug, Serialize)]
@ -81,7 +78,7 @@ struct IndexResponse {
updated_at: DateTime<Utc>,
}
pub async fn get_index(ctx: Context<Data>) -> SResult<Response> {
pub async fn get_index(ctx: Request<Data>) -> SResult<Response> {
ctx.is_allowed(IndexesRead)?;
let index = ctx.index()?;
@ -113,7 +110,7 @@ pub async fn get_index(ctx: Context<Data>) -> SResult<Response> {
updated_at,
};
Ok(tide::response::json(response_body))
Ok(tide::Response::new(200).body_json(&response_body).unwrap())
}
#[derive(Debug, Deserialize)]
@ -129,14 +126,11 @@ struct IndexCreateRequest {
struct IndexCreateResponse {
name: String,
uid: String,
// schema: Option<SchemaBody>,
// #[serde(skip_serializing_if = "Option::is_none")]
// update_id: Option<u64>,
created_at: DateTime<Utc>,
updated_at: DateTime<Utc>,
}
pub async fn create_index(mut ctx: Context<Data>) -> SResult<Response> {
pub async fn create_index(mut ctx: Request<Data>) -> SResult<Response> {
ctx.is_allowed(IndexesWrite)?;
let body = ctx
@ -171,27 +165,17 @@ pub async fn create_index(mut ctx: Context<Data>) -> SResult<Response> {
// let schema: Option<Schema> = body.schema.clone().map(Into::into);
// let mut response_update_id = None;
// if let Some(schema) = schema {
// let update_id = created_index
// .schema_update(&mut update_writer, schema)
// .map_err(ResponseError::internal)?;
// response_update_id = Some(update_id)
// }
// writer.commit().map_err(ResponseError::internal)?;
// update_writer.commit().map_err(ResponseError::internal)?;
writer.commit().map_err(ResponseError::internal)?;
let response_body = IndexCreateResponse {
name: body.name,
name: name,
uid,
// schema: body.schema,
// update_id: update_id,
created_at: Utc::now(),
updated_at: Utc::now(),
};
Ok(tide::response::json(response_body)
.with_status(StatusCode::CREATED)
.into_response())
Ok(tide::Response::new(201).body_json(&response_body).unwrap())
}
#[derive(Debug, Deserialize)]
@ -209,7 +193,7 @@ struct UpdateIndexResponse {
updated_at: DateTime<Utc>,
}
pub async fn update_index(mut ctx: Context<Data>) -> SResult<Response> {
pub async fn update_index(mut ctx: Request<Data>) -> SResult<Response> {
ctx.is_allowed(IndexesWrite)?;
let body = ctx
@ -254,12 +238,10 @@ pub async fn update_index(mut ctx: Context<Data>) -> SResult<Response> {
updated_at,
};
Ok(tide::response::json(response_body)
.with_status(StatusCode::OK)
.into_response())
Ok(tide::Response::new(200).body_json(&response_body).unwrap())
}
pub async fn get_update_status(ctx: Context<Data>) -> SResult<Response> {
pub async fn get_update_status(ctx: Request<Data>) -> SResult<Response> {
ctx.is_allowed(IndexesRead)?;
let db = &ctx.state().db;
@ -275,41 +257,33 @@ pub async fn get_update_status(ctx: Context<Data>) -> SResult<Response> {
.map_err(ResponseError::internal)?;
let response = match status {
Some(status) => tide::response::json(status)
.with_status(StatusCode::OK)
.into_response(),
None => tide::response::json(json!({ "message": "unknown update id" }))
.with_status(StatusCode::NOT_FOUND)
.into_response(),
Some(status) => tide::Response::new(200).body_json(&status).unwrap(),
None => tide::Response::new(404).body_json(&json!({ "message": "unknown update id" })).unwrap(),
};
Ok(response)
}
pub async fn get_all_updates_status(ctx: Context<Data>) -> SResult<Response> {
pub async fn get_all_updates_status(ctx: Request<Data>) -> SResult<Response> {
ctx.is_allowed(IndexesRead)?;
let db = &ctx.state().db;
let reader = db.update_read_txn().map_err(ResponseError::internal)?;
let index = ctx.index()?;
let all_status = index
let response = index
.all_updates_status(&reader)
.map_err(ResponseError::internal)?;
let response = tide::response::json(all_status)
.with_status(StatusCode::OK)
.into_response();
Ok(response)
Ok(tide::Response::new(200).body_json(&response).unwrap())
}
pub async fn delete_index(ctx: Context<Data>) -> SResult<StatusCode> {
pub async fn delete_index(ctx: Request<Data>) -> SResult<Response> {
ctx.is_allowed(IndexesWrite)?;
let _ = ctx.index()?;
let index_uid = ctx.url_param("index")?;
ctx.state().db.delete_index(&index_uid).map_err(ResponseError::internal)?;
Ok(StatusCode::NO_CONTENT)
Ok(tide::Response::new(204))
}
pub fn index_update_callback(index_uid: &str, data: &Data, status: ProcessedUpdateResult) {

View File

@ -1,14 +1,12 @@
use chrono::serde::ts_seconds;
use chrono::{DateTime, Utc};
use heed::types::{SerdeBincode, Str};
use http::StatusCode;
use rand::seq::SliceRandom;
use serde::{Deserialize, Serialize};
use tide::response::IntoResponse;
use tide::{Context, Response};
use tide::{Request, Response};
use crate::error::{ResponseError, SResult};
use crate::helpers::tide::ContextExt;
use crate::helpers::tide::RequestExt;
use crate::models::token::ACL::*;
use crate::models::token::*;
use crate::Data;
@ -22,7 +20,7 @@ fn generate_api_key() -> String {
.collect()
}
pub async fn list(ctx: Context<Data>) -> SResult<Response> {
pub async fn list(ctx: Request<Data>) -> SResult<Response> {
ctx.is_allowed(Admin)?;
let db = &ctx.state().db;
@ -41,10 +39,10 @@ pub async fn list(ctx: Context<Data>) -> SResult<Response> {
response.push(token);
}
Ok(tide::response::json(response))
Ok(tide::Response::new(200).body_json(&response).unwrap())
}
pub async fn get(ctx: Context<Data>) -> SResult<Response> {
pub async fn get(ctx: Request<Data>) -> SResult<Response> {
ctx.is_allowed(Admin)?;
let request_key = ctx.url_param("key")?;
@ -62,7 +60,7 @@ pub async fn get(ctx: Context<Data>) -> SResult<Response> {
token_key
)))?;
Ok(tide::response::json(token_config))
Ok(tide::Response::new(200).body_json(&token_config).unwrap())
}
#[derive(Debug, Serialize, Deserialize)]
@ -75,7 +73,7 @@ pub struct CreatedRequest {
expires_at: DateTime<Utc>,
}
pub async fn create(mut ctx: Context<Data>) -> SResult<Response> {
pub async fn create(mut ctx: Request<Data>) -> SResult<Response> {
ctx.is_allowed(Admin)?;
let data: CreatedRequest = ctx.body_json().await.map_err(ResponseError::bad_request)?;
@ -103,9 +101,7 @@ pub async fn create(mut ctx: Context<Data>) -> SResult<Response> {
writer.commit().map_err(ResponseError::internal)?;
Ok(tide::response::json(token_definition)
.with_status(StatusCode::CREATED)
.into_response())
Ok(tide::Response::new(201).body_json(&token_definition).unwrap())
}
#[derive(Debug, Serialize, Deserialize)]
@ -118,7 +114,7 @@ pub struct UpdatedRequest {
revoked: Option<bool>,
}
pub async fn update(mut ctx: Context<Data>) -> SResult<Response> {
pub async fn update(mut ctx: Request<Data>) -> SResult<Response> {
ctx.is_allowed(Admin)?;
let request_key = ctx.url_param("key")?;
@ -168,12 +164,10 @@ pub async fn update(mut ctx: Context<Data>) -> SResult<Response> {
writer.commit().map_err(ResponseError::internal)?;
Ok(tide::response::json(token_config)
.with_status(StatusCode::OK)
.into_response())
Ok(tide::Response::new(200).body_json(&token_config).unwrap())
}
pub async fn delete(ctx: Context<Data>) -> SResult<StatusCode> {
pub async fn delete(ctx: Request<Data>) -> SResult<Response> {
ctx.is_allowed(Admin)?;
let request_key = ctx.url_param("key")?;
@ -190,5 +184,5 @@ pub async fn delete(ctx: Context<Data>) -> SResult<StatusCode> {
writer.commit().map_err(ResponseError::internal)?;
Ok(StatusCode::NO_CONTENT)
Ok(tide::Response::new(204))
}

View File

@ -1,3 +1,6 @@
use tide::Response;
use tide::IntoResponse;
use std::future::Future;
use crate::data::Data;
pub mod document;
@ -10,113 +13,108 @@ pub mod stats;
pub mod stop_words;
pub mod synonym;
pub fn load_routes(app: &mut tide::App<Data>) {
async fn into_response<T: IntoResponse, U: IntoResponse>(x: impl Future<Output = Result<T, U>>) -> Response {
match x.await {
Ok(resp) => resp.into_response(),
Err(resp) => resp.into_response(),
}
}
pub fn load_routes(app: &mut tide::Server<Data>) {
app.at("").nest(|router| {
// expose the web interface static files
router.at("/").get(|_| async {
let content = include_str!("../../public/interface.html").to_owned();
tide::http::Response::builder()
.header(tide::http::header::CONTENT_TYPE, "text/html; charset=utf-8")
.status(tide::http::StatusCode::OK)
.body(content).unwrap()
router.at("/").get(|_| async move {
let response = include_str!("../../public/interface.html");
response
});
router.at("/bulma.min.css").get(|_| async {
let content = include_str!("../../public/bulma.min.css");
tide::http::Response::builder()
.header(tide::http::header::CONTENT_TYPE, "text/css; charset=utf-8")
.status(tide::http::StatusCode::OK)
.body(content).unwrap()
let response = include_str!("../../public/bulma.min.css");
response
});
router.at("/indexes").nest(|router| {
router
.at("/")
.get(index::list_indexes)
.post(index::create_index);
.get(|ctx| into_response(index::list_indexes(ctx)))
.post(|ctx| into_response(index::create_index(ctx)));
router.at("/search").post(search::search_multi_index);
router.at("/search").post(|ctx| into_response(search::search_multi_index(ctx)));
router.at("/:index").nest(|router| {
router.at("/search").get(search::search_with_url_query);
router.at("/search").get(|ctx| into_response(search::search_with_url_query(ctx)));
router.at("/updates").nest(|router| {
router.at("/").get(index::get_all_updates_status);
router.at("/").get(|ctx| into_response(index::get_all_updates_status(ctx)));
router.at("/:update_id").get(index::get_update_status);
router.at("/:update_id").get(|ctx| into_response(index::get_update_status(ctx)));
});
router
.at("/")
.get(index::get_index)
.put(index::update_index)
.delete(index::delete_index);
// router
// .at("/schema")
// .get(index::get_index_schema)
// .put(index::update_schema);
.get(|ctx| into_response(index::get_index(ctx)))
.put(|ctx| into_response(index::update_index(ctx)))
.delete(|ctx| into_response(index::delete_index(ctx)));
router.at("/documents").nest(|router| {
router
.at("/")
.get(document::get_all_documents)
.post(document::add_or_replace_multiple_documents)
.put(document::add_or_update_multiple_documents)
.delete(document::clear_all_documents);
.get(|ctx| into_response(document::get_all_documents(ctx)))
.post(|ctx| into_response(document::add_or_replace_multiple_documents(ctx)))
.put(|ctx| into_response(document::add_or_update_multiple_documents(ctx)))
.delete(|ctx| into_response(document::clear_all_documents(ctx)));
router.at("/:identifier").nest(|router| {
router
.at("/")
.get(document::get_document)
.delete(document::delete_document);
.get(|ctx| into_response(document::get_document(ctx)))
.delete(|ctx| into_response(document::delete_document(ctx)));
});
router
.at("/delete-batch")
.post(document::delete_multiple_documents);
.post(|ctx| into_response(document::delete_multiple_documents(ctx)));
});
router.at("/settings").nest(|router| {
router.at("/synonyms")
.get(synonym::get)
.post(synonym::update)
.delete(synonym::delete);
.get(|ctx| into_response(synonym::get(ctx)))
.post(|ctx| into_response(synonym::update(ctx)))
.delete(|ctx| into_response(synonym::delete(ctx)));
router.at("/stop-words")
.get(stop_words::get)
.post(stop_words::update)
.delete(stop_words::delete);
.get(|ctx| into_response(stop_words::get(ctx)))
.post(|ctx| into_response(stop_words::update(ctx)))
.delete(|ctx| into_response(stop_words::delete(ctx)));
})
.get(setting::get)
.post(setting::update);
.get(|ctx| into_response(setting::get(ctx)))
.post(|ctx| into_response(setting::update(ctx)));
router.at("/stats").get(stats::index_stat);
router.at("/stats").get(|ctx| into_response(stats::index_stat(ctx)));
});
});
router.at("/keys").nest(|router| {
router.at("/").get(key::list).post(key::create);
router.at("/").get(|ctx| into_response(key::list(ctx))).post(|ctx| into_response(key::create(ctx)));
router
.at("/:key")
.get(key::get)
.put(key::update)
.delete(key::delete);
.get(|ctx| into_response(key::get(ctx)))
.put(|ctx| into_response(key::update(ctx)))
.delete(|ctx| into_response(key::delete(ctx)));
});
});
app.at("").nest(|router| {
router
.at("/health")
.get(health::get_health)
.put(health::change_healthyness);
.get(|ctx| into_response(health::get_health(ctx)))
.put(|ctx| into_response(health::change_healthyness(ctx)));
router.at("/stats").get(stats::get_stats);
router.at("/version").get(stats::get_version);
router.at("/sys-info").get(stats::get_sys_info);
router.at("/stats").get(|ctx| into_response(stats::get_stats(ctx)));
router.at("/version").get(|ctx| into_response(stats::get_version(ctx)));
router.at("/sys-info").get(|ctx| into_response(stats::get_sys_info(ctx)));
router
.at("/sys-info/pretty")
.get(stats::get_sys_info_pretty);
.get(|ctx| into_response(stats::get_sys_info_pretty(ctx)));
});
}

View File

@ -5,12 +5,11 @@ use std::time::Duration;
use meilisearch_core::Index;
use rayon::iter::{IntoParallelIterator, ParallelIterator};
use serde::{Deserialize, Serialize};
use tide::querystring::ContextExt as QSContextExt;
use tide::{Context, Response};
use tide::{Request, Response};
use crate::error::{ResponseError, SResult};
use crate::helpers::meilisearch::{Error, IndexSearchExt, SearchHit};
use crate::helpers::tide::ContextExt;
use crate::helpers::tide::RequestExt;
use crate::Data;
#[derive(Deserialize)]
@ -28,7 +27,7 @@ struct SearchQuery {
matches: Option<bool>,
}
pub async fn search_with_url_query(ctx: Context<Data>) -> SResult<Response> {
pub async fn search_with_url_query(ctx: Request<Data>) -> SResult<Response> {
// ctx.is_allowed(DocumentsRead)?;
let index = ctx.index()?;
@ -41,8 +40,7 @@ pub async fn search_with_url_query(ctx: Context<Data>) -> SResult<Response> {
.map_err(ResponseError::internal)?
.ok_or(ResponseError::open_index("No Schema found"))?;
let query: SearchQuery = ctx
.url_query()
let query: SearchQuery = ctx.query()
.map_err(|_| ResponseError::bad_request("invalid query parameter"))?;
let mut search_builder = index.new_search(query.q.clone());
@ -111,7 +109,7 @@ pub async fn search_with_url_query(ctx: Context<Data>) -> SResult<Response> {
Err(others) => return Err(ResponseError::bad_request(others)),
};
Ok(tide::response::json(response))
Ok(tide::Response::new(200).body_json(&response).unwrap())
}
#[derive(Clone, Deserialize)]
@ -140,7 +138,7 @@ struct SearchMultiBodyResponse {
query: String,
}
pub async fn search_multi_index(mut ctx: Context<Data>) -> SResult<Response> {
pub async fn search_multi_index(mut ctx: Request<Data>) -> SResult<Response> {
// ctx.is_allowed(DocumentsRead)?;
let body = ctx
.body_json::<SearchMultiBody>()
@ -232,5 +230,5 @@ pub async fn search_multi_index(mut ctx: Context<Data>) -> SResult<Response> {
query: body.query,
};
Ok(tide::response::json(response))
Ok(tide::Response::new(200).body_json(&response).unwrap())
}

View File

@ -1,11 +1,8 @@
use http::StatusCode;
use serde::{Deserialize, Serialize, Deserializer};
use tide::response::IntoResponse;
use tide::{Context, Response};
// use indexmap::IndexMap;
use tide::{Request, Response};
use crate::error::{ResponseError, SResult};
use crate::helpers::tide::ContextExt;
use crate::helpers::tide::RequestExt;
use crate::models::token::ACL::*;
use crate::routes::document::IndexUpdateResponse;
use crate::Data;
@ -13,7 +10,6 @@ use crate::Data;
#[derive(Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
pub struct Setting {
// pub ranking_order: Option<RankingOrder>,
pub distinct_field: Option<DistinctField>,
pub ranking_rules: Option<RankingRules>,
}
@ -25,11 +21,10 @@ pub enum RankingOrdering {
Dsc,
}
// pub type RankingOrder = Vec<String>;
pub type DistinctField = String;
pub type RankingRules = Vec<String>;
pub async fn get(ctx: Context<Data>) -> SResult<Response> {
pub async fn get(ctx: Request<Data>) -> SResult<Response> {
ctx.is_allowed(SettingsRead)?;
let index = ctx.index()?;
@ -41,14 +36,12 @@ pub async fn get(ctx: Context<Data>) -> SResult<Response> {
None => Setting::default(),
};
Ok(tide::response::json(settings))
Ok(tide::Response::new(200).body_json(&settings).unwrap())
}
#[derive(Deserialize)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
pub struct SettingBody {
// #[serde(default, deserialize_with = "deserialize_some")]
// pub ranking_order: Option<Option<RankingOrder>>,
#[serde(default, deserialize_with = "deserialize_some")]
pub distinct_field: Option<Option<DistinctField>>,
#[serde(default, deserialize_with = "deserialize_some")]
@ -63,7 +56,7 @@ fn deserialize_some<'de, T, D>(deserializer: D) -> Result<Option<T>, D::Error>
Deserialize::deserialize(deserializer).map(Some)
}
pub async fn update(mut ctx: Context<Data>) -> SResult<Response> {
pub async fn update(mut ctx: Request<Data>) -> SResult<Response> {
ctx.is_allowed(SettingsWrite)?;
let settings: SettingBody = ctx.body_json().await.map_err(ResponseError::bad_request)?;
@ -79,10 +72,6 @@ pub async fn update(mut ctx: Context<Data>) -> SResult<Response> {
None => Setting::default(),
};
// if let Some(ranking_order) = settings.ranking_order {
// current_settings.ranking_order = ranking_order;
// }
if let Some(distinct_field) = settings.distinct_field {
current_settings.distinct_field = distinct_field;
}
@ -100,7 +89,5 @@ pub async fn update(mut ctx: Context<Data>) -> SResult<Response> {
writer.commit().map_err(ResponseError::internal)?;
let response_body = IndexUpdateResponse { update_id };
Ok(tide::response::json(response_body)
.with_status(StatusCode::ACCEPTED)
.into_response())
Ok(tide::Response::new(202).body_json(&response_body).unwrap())
}

View File

@ -5,11 +5,11 @@ use log::error;
use pretty_bytes::converter::convert;
use serde::Serialize;
use sysinfo::{NetworkExt, Pid, ProcessExt, ProcessorExt, System, SystemExt};
use tide::{Context, Response};
use tide::{Request, Response};
use walkdir::WalkDir;
use crate::error::{ResponseError, SResult};
use crate::helpers::tide::ContextExt;
use crate::helpers::tide::RequestExt;
use crate::models::token::ACL::*;
use crate::Data;
@ -21,7 +21,7 @@ struct IndexStatsResponse {
fields_frequency: HashMap<String, usize>,
}
pub async fn index_stat(ctx: Context<Data>) -> SResult<Response> {
pub async fn index_stat(ctx: Request<Data>) -> SResult<Response> {
ctx.is_allowed(Admin)?;
let index_uid = ctx.url_param("index")?;
let index = ctx.index()?;
@ -52,7 +52,7 @@ pub async fn index_stat(ctx: Context<Data>) -> SResult<Response> {
is_indexing,
fields_frequency,
};
Ok(tide::response::json(response))
Ok(tide::Response::new(200).body_json(&response).unwrap())
}
#[derive(Serialize)]
@ -63,7 +63,7 @@ struct StatsResult {
indexes: HashMap<String, IndexStatsResponse>,
}
pub async fn get_stats(ctx: Context<Data>) -> SResult<Response> {
pub async fn get_stats(ctx: Request<Data>) -> SResult<Response> {
ctx.is_allowed(Admin)?;
let mut index_list = HashMap::new();
@ -127,7 +127,7 @@ pub async fn get_stats(ctx: Context<Data>) -> SResult<Response> {
indexes: index_list,
};
Ok(tide::response::json(response))
Ok(tide::Response::new(200).body_json(&response).unwrap())
}
#[derive(Serialize)]
@ -138,7 +138,7 @@ struct VersionResponse {
pkg_version: String,
}
pub async fn get_version(ctx: Context<Data>) -> SResult<Response> {
pub async fn get_version(ctx: Request<Data>) -> SResult<Response> {
ctx.is_allowed(Admin)?;
let response = VersionResponse {
commit_sha: env!("VERGEN_SHA").to_string(),
@ -146,7 +146,7 @@ pub async fn get_version(ctx: Context<Data>) -> SResult<Response> {
pkg_version: env!("CARGO_PKG_VERSION").to_string(),
};
Ok(tide::response::json(response))
Ok(tide::Response::new(200).body_json(&response).unwrap())
}
#[derive(Serialize)]
@ -236,9 +236,10 @@ pub(crate) fn report(pid: Pid) -> SysInfo {
info
}
pub async fn get_sys_info(ctx: Context<Data>) -> SResult<Response> {
pub async fn get_sys_info(ctx: Request<Data>) -> SResult<Response> {
ctx.is_allowed(Admin)?;
Ok(tide::response::json(report(ctx.state().server_pid)))
let response = report(ctx.state().server_pid);
Ok(tide::Response::new(200).body_json(&response).unwrap())
}
#[derive(Serialize)]
@ -332,7 +333,8 @@ pub(crate) fn report_pretty(pid: Pid) -> SysInfoPretty {
info
}
pub async fn get_sys_info_pretty(ctx: Context<Data>) -> SResult<Response> {
pub async fn get_sys_info_pretty(ctx: Request<Data>) -> SResult<Response> {
ctx.is_allowed(Admin)?;
Ok(tide::response::json(report_pretty(ctx.state().server_pid)))
let response = report_pretty(ctx.state().server_pid);
Ok(tide::Response::new(200).body_json(&response).unwrap())
}

View File

@ -1,17 +1,15 @@
use std::collections::BTreeSet;
use http::StatusCode;
use tide::response::IntoResponse;
use tide::{Context, Response};
use tide::{Request, Response};
use meilisearch_core::settings::{SettingsUpdate, UpdateState};
use crate::error::{ResponseError, SResult};
use crate::helpers::tide::ContextExt;
use crate::helpers::tide::RequestExt;
use crate::models::token::ACL::*;
use crate::routes::document::IndexUpdateResponse;
use crate::Data;
pub async fn get(ctx: Context<Data>) -> SResult<Response> {
pub async fn get(ctx: Request<Data>) -> SResult<Response> {
ctx.is_allowed(SettingsRead)?;
let index = ctx.index()?;
@ -29,10 +27,10 @@ pub async fn get(ctx: Context<Data>) -> SResult<Response> {
.into_strs()
.map_err(ResponseError::internal)?;
Ok(tide::response::json(stop_words))
Ok(tide::Response::new(200).body_json(&stop_words).unwrap())
}
pub async fn update(mut ctx: Context<Data>) -> SResult<Response> {
pub async fn update(mut ctx: Request<Data>) -> SResult<Response> {
ctx.is_allowed(SettingsRead)?;
let index = ctx.index()?;
@ -52,12 +50,10 @@ pub async fn update(mut ctx: Context<Data>) -> SResult<Response> {
writer.commit().map_err(ResponseError::internal)?;
let response_body = IndexUpdateResponse { update_id };
Ok(tide::response::json(response_body)
.with_status(StatusCode::ACCEPTED)
.into_response())
Ok(tide::Response::new(202).body_json(&response_body).unwrap())
}
pub async fn delete(ctx: Context<Data>) -> SResult<Response> {
pub async fn delete(ctx: Request<Data>) -> SResult<Response> {
ctx.is_allowed(SettingsRead)?;
let index = ctx.index()?;
@ -75,7 +71,5 @@ pub async fn delete(ctx: Context<Data>) -> SResult<Response> {
writer.commit().map_err(ResponseError::internal)?;
let response_body = IndexUpdateResponse { update_id };
Ok(tide::response::json(response_body)
.with_status(StatusCode::ACCEPTED)
.into_response())
Ok(tide::Response::new(202).body_json(&response_body).unwrap())
}

View File

@ -1,18 +1,16 @@
use std::collections::BTreeMap;
use http::StatusCode;
use tide::response::IntoResponse;
use tide::{Context, Response};
use tide::{Request, Response};
use indexmap::IndexMap;
use meilisearch_core::settings::{SettingsUpdate, UpdateState};
use crate::error::{ResponseError, SResult};
use crate::helpers::tide::ContextExt;
use crate::helpers::tide::RequestExt;
use crate::models::token::ACL::*;
use crate::routes::document::IndexUpdateResponse;
use crate::Data;
pub async fn get(ctx: Context<Data>) -> SResult<Response> {
pub async fn get(ctx: Request<Data>) -> SResult<Response> {
ctx.is_allowed(SettingsRead)?;
let index = ctx.index()?;
@ -42,10 +40,10 @@ pub async fn get(ctx: Context<Data>) -> SResult<Response> {
}
}
Ok(tide::response::json(response))
Ok(tide::Response::new(200).body_json(&response).unwrap())
}
pub async fn update(mut ctx: Context<Data>) -> SResult<Response> {
pub async fn update(mut ctx: Request<Data>) -> SResult<Response> {
ctx.is_allowed(SettingsWrite)?;
let data: BTreeMap<String, Vec<String>> = ctx.body_json().await.map_err(ResponseError::bad_request)?;
@ -66,13 +64,11 @@ pub async fn update(mut ctx: Context<Data>) -> SResult<Response> {
writer.commit().map_err(ResponseError::internal)?;
let response_body = IndexUpdateResponse { update_id };
Ok(tide::response::json(response_body)
.with_status(StatusCode::ACCEPTED)
.into_response())
Ok(tide::Response::new(202).body_json(&response_body).unwrap())
}
pub async fn delete(ctx: Context<Data>) -> SResult<Response> {
pub async fn delete(ctx: Request<Data>) -> SResult<Response> {
ctx.is_allowed(SettingsWrite)?;
let index = ctx.index()?;
@ -91,7 +87,5 @@ pub async fn delete(ctx: Context<Data>) -> SResult<Response> {
writer.commit().map_err(ResponseError::internal)?;
let response_body = IndexUpdateResponse { update_id };
Ok(tide::response::json(response_body)
.with_status(StatusCode::ACCEPTED)
.into_response())
Ok(tide::Response::new(202).body_json(&response_body).unwrap())
}