Unverified Commit e613012b authored by Rupert's avatar Rupert Committed by GitHub
Browse files

Expose Error Serialization To Consumers to Allow Ergnomoic Middleware (#157)



* Prevent reading the entire body of a request if unnecessary

Prior to this, we were reading an entire UNSIGNED_PAYLOAD request into
memory, even though this was not required for verification of the
signature.

* Expose the xml serialization of Errors to build HTTP Responses

Exposing this code allows more ergonomic creation of middleware,
benefitting from the existing code in s3s to serialize HTTP responses on
errors within middleware to get consistent, "S3-Style" XML bodies for
clients to consume

---------

Co-authored-by: default avatarRupert Rutledge <rupertr@thestartupfactory.tech>
parent be630b26
Loading
Loading
Loading
Loading
+13 −1
Original line number Diff line number Diff line
mod generated;
pub use self::generated::*;

use crate::http;
use crate::ops;
use crate::xml;

use std::borrow::Cow;
use std::convert::Infallible;
use std::fmt;
@@ -124,6 +125,17 @@ impl S3Error {
    {
        Self::with_source(S3ErrorCode::InternalError, Box::new(source))
    }

    /// Serialize an `S3Error` into an `Response` that can be sent back to the client.
    /// This can be useful in creating middleware around an S3 Service implementation
    /// that want to send consistent error messages to clients on errors.
    ///
    /// # Errors
    ///
    /// Returns [`S3Error`] if it was not possible to serialize the error into XML.
    pub fn to_hyper_response(self) -> S3Result<hyper::Response<http::Body>> {
        ops::serialize_error(self, false).map(Into::into)
    }
}

impl xml::Serialize for S3Error {
+1 −1
Original line number Diff line number Diff line
@@ -59,7 +59,7 @@ fn build_s3_request<T>(input: T, req: &mut Request) -> S3Request<T> {
    }
}

fn serialize_error(mut e: S3Error, no_decl: bool) -> S3Result<Response> {
pub(crate) fn serialize_error(mut e: S3Error, no_decl: bool) -> S3Result<Response> {
    let status = e.status_code().unwrap_or(StatusCode::INTERNAL_SERVER_ERROR);
    let mut res = Response::with_status(status);
    if no_decl {