add an "insert entry" (PUT) endpoint

feat/vaults
Tomáš Mládek 2021-02-19 21:58:35 +01:00
parent dc71bec67a
commit 3ad31a482d
5 changed files with 34 additions and 3 deletions

1
Cargo.lock generated
View File

@ -2260,6 +2260,7 @@ dependencies = [
"dotenv",
"env_logger",
"filebuffer",
"futures-util",
"lexpr",
"libsqlite3-sys",
"log",

View File

@ -16,6 +16,7 @@ anyhow = "1.0"
thiserror = "1.0"
rayon = "1.4.0"
futures-util = "~0.3.12"
diesel = { version = "1.4", features = ["sqlite", "r2d2", "chrono", "serde_json"] }
diesel_migrations = "1.4"

View File

@ -15,7 +15,6 @@ use lexpr::Value::Cons;
use log::{debug, trace};
use nonempty::NonEmpty;
use serde::{Deserialize, Serialize};
use serde_json::json;
use std::borrow::Borrow;
use std::convert::TryFrom;
use std::fs;

View File

@ -86,6 +86,7 @@ fn main() -> Result<()> {
.service(routes::get_query)
.service(routes::get_raw)
.service(routes::get_object)
.service(routes::put_object)
.service(routes::list_hier)
.service(routes::get_lookup)
.service(routes::api_refresh)

View File

@ -1,11 +1,14 @@
use crate::addressing::Address;
use crate::database::{query, remove_object, retrieve_file, retrieve_object, DbPool, Entry, Query};
use crate::database::{
insert_entry, query, remove_object, retrieve_file, retrieve_object, DbPool, Entry, Query,
};
use crate::filesystem::{list_directory, lookup_by_filename, UPath};
use crate::hash::{decode, encode, Hashable};
use actix_files::NamedFile;
use actix_web::error::{ErrorBadRequest, ErrorInternalServerError, ErrorNotFound};
use actix_web::{delete, error, get, post, web, Error, HttpResponse};
use actix_web::{delete, error, get, post, put, web, Error, HttpResponse};
use anyhow::Result;
use futures_util::StreamExt;
use log::debug;
use serde::Deserialize;
use std::collections::HashMap;
@ -63,6 +66,32 @@ pub async fn get_object(
Ok(HttpResponse::Ok().json(result))
}
const MAX_SIZE: usize = 1_000_000;
#[put("/api/obj")]
pub async fn put_object(
state: web::Data<State>,
mut payload: web::Payload,
) -> Result<HttpResponse, Error> {
let connection = state.db_pool.get().map_err(ErrorInternalServerError)?;
let mut body = web::BytesMut::new();
while let Some(chunk) = payload.next().await {
let chunk = chunk?;
// limit max size of in-memory payload
if (body.len() + chunk.len()) > MAX_SIZE {
return Err(error::ErrorBadRequest("overflow."));
}
body.extend_from_slice(&chunk);
}
let entry = serde_json::from_slice::<Entry>(&body)?;
insert_entry(&connection, entry).map_err(ErrorInternalServerError)?;
Ok(HttpResponse::Ok().finish())
}
#[delete("/api/obj/{address_str}")]
pub async fn delete_object(
state: web::Data<State>,