add doc comments #53
8 changed files with 42 additions and 13 deletions
|
@ -20,6 +20,7 @@ use crate::s3_get::*;
|
||||||
use crate::s3_list::*;
|
use crate::s3_list::*;
|
||||||
use crate::s3_put::*;
|
use crate::s3_put::*;
|
||||||
|
|
||||||
|
/// Run the S3 API server
|
||||||
pub async fn run_api_server(
|
pub async fn run_api_server(
|
||||||
garage: Arc<Garage>,
|
garage: Arc<Garage>,
|
||||||
shutdown_signal: impl Future<Output = ()>,
|
shutdown_signal: impl Future<Output = ()>,
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
|
//! Module containing various helpers for encoding
|
||||||
|
|
||||||
|
/// Escape &str for xml inclusion
|
||||||
pub fn xml_escape(s: &str) -> String {
|
pub fn xml_escape(s: &str) -> String {
|
||||||
s.replace("<", "<")
|
s.replace("<", "<")
|
||||||
.replace(">", ">")
|
.replace(">", ">")
|
||||||
.replace("\"", """)
|
.replace("\"", """)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Encode &str for use in a URI
|
||||||
pub fn uri_encode(string: &str, encode_slash: bool) -> String {
|
pub fn uri_encode(string: &str, encode_slash: bool) -> String {
|
||||||
let mut result = String::with_capacity(string.len() * 2);
|
let mut result = String::with_capacity(string.len() * 2);
|
||||||
for c in string.chars() {
|
for c in string.chars() {
|
||||||
|
@ -24,6 +28,7 @@ pub fn uri_encode(string: &str, encode_slash: bool) -> String {
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Encode &str either as an uri, or a valid string for xml inclusion
|
||||||
pub fn xml_encode_key(k: &str, urlencode: bool) -> String {
|
pub fn xml_encode_key(k: &str, urlencode: bool) -> String {
|
||||||
if urlencode {
|
if urlencode {
|
||||||
uri_encode(k, true)
|
uri_encode(k, true)
|
||||||
|
|
|
@ -3,44 +3,57 @@ use hyper::StatusCode;
|
||||||
|
|
||||||
use garage_util::error::Error as GarageError;
|
use garage_util::error::Error as GarageError;
|
||||||
|
|
||||||
|
/// Errors of this crate
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
// Category: internal error
|
// Category: internal error
|
||||||
|
/// Error related to deeper parts of Garage
|
||||||
#[error(display = "Internal error: {}", _0)]
|
#[error(display = "Internal error: {}", _0)]
|
||||||
InternalError(#[error(source)] GarageError),
|
InternalError(#[error(source)] GarageError),
|
||||||
|
|
||||||
|
/// Error related to Hyper
|
||||||
#[error(display = "Internal error (Hyper error): {}", _0)]
|
#[error(display = "Internal error (Hyper error): {}", _0)]
|
||||||
Hyper(#[error(source)] hyper::Error),
|
Hyper(#[error(source)] hyper::Error),
|
||||||
|
|
||||||
|
/// Error related to HTTP
|
||||||
#[error(display = "Internal error (HTTP error): {}", _0)]
|
#[error(display = "Internal error (HTTP error): {}", _0)]
|
||||||
HTTP(#[error(source)] http::Error),
|
HTTP(#[error(source)] http::Error),
|
||||||
|
|
||||||
// Category: cannot process
|
// Category: cannot process
|
||||||
|
/// No proper api key was used, or the signature was invalid
|
||||||
#[error(display = "Forbidden: {}", _0)]
|
#[error(display = "Forbidden: {}", _0)]
|
||||||
Forbidden(String),
|
Forbidden(String),
|
||||||
|
|
||||||
|
/// The object requested don't exists
|
||||||
#[error(display = "Not found")]
|
#[error(display = "Not found")]
|
||||||
NotFound,
|
NotFound,
|
||||||
|
|
||||||
// Category: bad request
|
// Category: bad request
|
||||||
|
/// The request used an invalid path
|
||||||
trinity-1686a marked this conversation as resolved
Outdated
|
|||||||
#[error(display = "Invalid UTF-8: {}", _0)]
|
#[error(display = "Invalid UTF-8: {}", _0)]
|
||||||
InvalidUTF8Str(#[error(source)] std::str::Utf8Error),
|
InvalidUTF8Str(#[error(source)] std::str::Utf8Error),
|
||||||
|
|
||||||
|
/// The request used an invalid path
|
||||||
#[error(display = "Invalid UTF-8: {}", _0)]
|
#[error(display = "Invalid UTF-8: {}", _0)]
|
||||||
InvalidUTF8String(#[error(source)] std::string::FromUtf8Error),
|
InvalidUTF8String(#[error(source)] std::string::FromUtf8Error),
|
||||||
|
|
||||||
|
/// Some base64 encoded data was badly encoded
|
||||||
#[error(display = "Invalid base64: {}", _0)]
|
#[error(display = "Invalid base64: {}", _0)]
|
||||||
InvalidBase64(#[error(source)] base64::DecodeError),
|
InvalidBase64(#[error(source)] base64::DecodeError),
|
||||||
|
|
||||||
|
/// The client sent invalid XML data
|
||||||
#[error(display = "Invalid XML: {}", _0)]
|
#[error(display = "Invalid XML: {}", _0)]
|
||||||
InvalidXML(String),
|
InvalidXML(String),
|
||||||
|
|
||||||
|
/// The client sent a header with invalid value
|
||||||
#[error(display = "Invalid header value: {}", _0)]
|
#[error(display = "Invalid header value: {}", _0)]
|
||||||
InvalidHeader(#[error(source)] hyper::header::ToStrError),
|
InvalidHeader(#[error(source)] hyper::header::ToStrError),
|
||||||
|
|
||||||
|
/// The client sent a range header with invalid value
|
||||||
#[error(display = "Invalid HTTP range: {:?}", _0)]
|
#[error(display = "Invalid HTTP range: {:?}", _0)]
|
||||||
InvalidRange(#[error(from)] http_range::HttpRangeParseError),
|
InvalidRange(#[error(from)] http_range::HttpRangeParseError),
|
||||||
|
|
||||||
|
/// The client sent an invalid request
|
||||||
#[error(display = "Bad request: {}", _0)]
|
#[error(display = "Bad request: {}", _0)]
|
||||||
BadRequest(String),
|
BadRequest(String),
|
||||||
}
|
}
|
||||||
|
@ -52,6 +65,7 @@ impl From<roxmltree::Error> for Error {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Error {
|
impl Error {
|
||||||
|
/// Convert an error into an Http status code
|
||||||
trinity-1686a marked this conversation as resolved
Outdated
lx
commented
rather rather `get the HTTP status code that best represents the meaning of the error for the client`
|
|||||||
pub fn http_status_code(&self) -> StatusCode {
|
pub fn http_status_code(&self) -> StatusCode {
|
||||||
match self {
|
match self {
|
||||||
Error::NotFound => StatusCode::NOT_FOUND,
|
Error::NotFound => StatusCode::NOT_FOUND,
|
||||||
|
@ -65,6 +79,7 @@ impl Error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Trait to map error to the Bad Request error code
|
||||||
pub trait OkOrBadRequest {
|
pub trait OkOrBadRequest {
|
||||||
type S2;
|
type S2;
|
||||||
fn ok_or_bad_request(self, reason: &'static str) -> Self::S2;
|
fn ok_or_bad_request(self, reason: &'static str) -> Self::S2;
|
||||||
|
@ -93,6 +108,7 @@ impl<T> OkOrBadRequest for Option<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Trait to map an error to an Internal Error code
|
||||||
pub trait OkOrInternalError {
|
pub trait OkOrInternalError {
|
||||||
type S2;
|
type S2;
|
||||||
fn ok_or_internal_error(self, reason: &'static str) -> Self::S2;
|
fn ok_or_internal_error(self, reason: &'static str) -> Self::S2;
|
||||||
|
|
|
@ -1,15 +1,20 @@
|
||||||
|
#![deny(missing_crate_level_docs, missing_docs)]
|
||||||
|
//! Crate for serving a S3 compatible API
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
|
||||||
pub mod error;
|
mod error;
|
||||||
|
pub use error::Error;
|
||||||
lx marked this conversation as resolved
Outdated
lx
commented
Doesn't this prevent us from using Doesn't this prevent us from using `OkOrBadRequest` and `OkOrInternalError`? (haven't read what's below yet)
trinity-1686a
commented
It prevents use from other crates, but not from this one. It does not break anything, but does prevent using those traits in web in the future, for instance ???? It prevents use from other crates, but not from this one. It does not break anything, but does prevent using those traits in web in the future, for instance ????
lx
commented
Alright, we'll make things Alright, we'll make things `pub` again if/when we need them.
|
|||||||
|
|
||||||
pub mod encoding;
|
mod encoding;
|
||||||
|
|
||||||
pub mod api_server;
|
mod api_server;
|
||||||
pub mod signature;
|
pub use api_server::run_api_server;
|
||||||
|
|
||||||
pub mod s3_copy;
|
mod signature;
|
||||||
pub mod s3_delete;
|
|
||||||
|
mod s3_copy;
|
||||||
|
mod s3_delete;
|
||||||
pub mod s3_get;
|
pub mod s3_get;
|
||||||
pub mod s3_list;
|
mod s3_list;
|
||||||
pub mod s3_put;
|
mod s3_put;
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
//! Function related to GET and HEAD requests
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::{Duration, UNIX_EPOCH};
|
use std::time::{Duration, UNIX_EPOCH};
|
||||||
|
|
||||||
|
@ -79,6 +80,7 @@ fn try_answer_cached(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Handle HEAD request
|
||||||
pub async fn handle_head(
|
pub async fn handle_head(
|
||||||
garage: Arc<Garage>,
|
garage: Arc<Garage>,
|
||||||
req: &Request<Body>,
|
req: &Request<Body>,
|
||||||
|
@ -118,6 +120,7 @@ pub async fn handle_head(
|
||||||
Ok(response)
|
Ok(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Handle GET request
|
||||||
pub async fn handle_get(
|
pub async fn handle_get(
|
||||||
garage: Arc<Garage>,
|
garage: Arc<Garage>,
|
||||||
req: &Request<Body>,
|
req: &Request<Body>,
|
||||||
|
@ -224,7 +227,7 @@ pub async fn handle_get(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn handle_get_range(
|
async fn handle_get_range(
|
||||||
garage: Arc<Garage>,
|
garage: Arc<Garage>,
|
||||||
version: &ObjectVersion,
|
version: &ObjectVersion,
|
||||||
version_data: &ObjectVersionData,
|
version_data: &ObjectVersionData,
|
||||||
|
|
|
@ -8,7 +8,7 @@ use garage_util::background::*;
|
||||||
use garage_util::config::*;
|
use garage_util::config::*;
|
||||||
use garage_util::error::Error;
|
use garage_util::error::Error;
|
||||||
|
|
||||||
use garage_api::api_server;
|
use garage_api::run_api_server;
|
||||||
use garage_model::garage::Garage;
|
use garage_model::garage::Garage;
|
||||||
use garage_rpc::rpc_server::RpcServer;
|
use garage_rpc::rpc_server::RpcServer;
|
||||||
use garage_web::run_web_server;
|
use garage_web::run_web_server;
|
||||||
|
@ -62,7 +62,7 @@ pub async fn run_server(config_file: PathBuf) -> Result<(), Error> {
|
||||||
|
|
||||||
info!("Initializing RPC and API servers...");
|
info!("Initializing RPC and API servers...");
|
||||||
let run_rpc_server = Arc::new(rpc_server).run(wait_from(watch_cancel.clone()));
|
let run_rpc_server = Arc::new(rpc_server).run(wait_from(watch_cancel.clone()));
|
||||||
let api_server = api_server::run_api_server(garage.clone(), wait_from(watch_cancel.clone()));
|
let api_server = run_api_server(garage.clone(), wait_from(watch_cancel.clone()));
|
||||||
let web_server = run_web_server(garage, wait_from(watch_cancel.clone()));
|
let web_server = run_web_server(garage, wait_from(watch_cancel.clone()));
|
||||||
|
|
||||||
futures::try_join!(
|
futures::try_join!(
|
||||||
|
|
|
@ -10,7 +10,6 @@ pub struct Key {
|
||||||
pub key_id: String,
|
pub key_id: String,
|
||||||
|
|
||||||
/// The secret_key associated
|
/// The secret_key associated
|
||||||
// shouldn't it be hashed or something, so it's trully secret?
|
|
||||||
pub secret_key: String,
|
pub secret_key: String,
|
||||||
|
|
||||||
/// Name for the key
|
/// Name for the key
|
||||||
|
|
|
@ -8,7 +8,7 @@ use garage_util::error::Error as GarageError;
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
/// An error received from the API crate
|
/// An error received from the API crate
|
||||||
#[error(display = "API error: {}", _0)]
|
#[error(display = "API error: {}", _0)]
|
||||||
ApiError(#[error(source)] garage_api::error::Error),
|
ApiError(#[error(source)] garage_api::Error),
|
||||||
|
|
||||||
// Category: internal error
|
// Category: internal error
|
||||||
/// Error internal to garage
|
/// Error internal to garage
|
||||||
|
|
Loading…
Reference in a new issue
the request contained an invalid UTF-8 sequence in its path or in other parameters
would be more accurate