Skip to content

Commit

Permalink
removed mime_multipart dependency and replicated required functionality
Browse files Browse the repository at this point in the history
This was done to remove a crypto dependency in the textnonce crate.
Most functionality from mime_multipart has been copied with the relevant
copyright and licensing.

replicated mime_multipart functions

removed write-multipart-chunked
  • Loading branch information
Neelay Sant committed Jan 13, 2023
1 parent d02405e commit b224349
Show file tree
Hide file tree
Showing 7 changed files with 1,060 additions and 13 deletions.
3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ repository = "Metaswitch/swagger-rs"
[features]
default = ["serdejson"]
multipart_form = ["mime"]
multipart_related = ["mime_multipart", "hyper_0_10", "mime_0_2"]
multipart_related = ["hyper_0_10", "mime_0_2"]
serdejson = ["serde", "serde_json"]
server = ["hyper/server"]
http1 = ["hyper/http1"]
Expand Down Expand Up @@ -49,7 +49,6 @@ mime = { version = "0.3", optional = true }

# multipart/related
hyper_0_10 = {package = "hyper", version = "0.10", default-features = false, optional=true}
mime_multipart = {version = "0.6", optional = true}
mime_0_2 = { package = "mime", version = "0.2.6", optional = true }

# UDS (Unix Domain Sockets)
Expand Down
127 changes: 127 additions & 0 deletions src/multipart/mime_multipart/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
// Copyright 2016 mime-multipart Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.

use std::borrow::Cow;
use std::error::Error as StdError;
use std::fmt::{self, Display};
use std::io;
use std::string::FromUtf8Error;

use httparse;
use hyper;

/// An error type for the `mime-multipart` crate.
pub enum Error {
/// The Hyper request did not have a Content-Type header.
NoRequestContentType,
/// The Hyper request Content-Type top-level Mime was not `Multipart`.
NotMultipart,
/// The Content-Type header failed to specify boundary token.
BoundaryNotSpecified,
/// A multipart section contained only partial headers.
PartialHeaders,
EofInMainHeaders,
EofBeforeFirstBoundary,
NoCrLfAfterBoundary,
EofInPartHeaders,
EofInFile,
EofInPart,
/// An HTTP parsing error from a multipart section.
Httparse(httparse::Error),
/// An I/O error.
Io(io::Error),
/// An error was returned from Hyper.
Hyper(hyper::Error),
/// An error occurred during UTF-8 processing.
Utf8(FromUtf8Error),
/// An error occurred during character decoding
Decoding(Cow<'static, str>),
}

impl From<io::Error> for Error {
fn from(err: io::Error) -> Error {
Error::Io(err)
}
}

impl From<httparse::Error> for Error {
fn from(err: httparse::Error) -> Error {
Error::Httparse(err)
}
}

impl From<hyper::Error> for Error {
fn from(err: hyper::Error) -> Error {
Error::Hyper(err)
}
}

impl From<FromUtf8Error> for Error {
fn from(err: FromUtf8Error) -> Error {
Error::Utf8(err)
}
}

impl Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Error::Httparse(ref e) =>
format!("Httparse: {:?}", e).fmt(f),
Error::Io(ref e) =>
format!("Io: {}", e).fmt(f),
Error::Hyper(ref e) =>
format!("Hyper: {}", e).fmt(f),
Error::Utf8(ref e) =>
format!("Utf8: {}", e).fmt(f),
Error::Decoding(ref e) =>
format!("Decoding: {}", e).fmt(f),
_ => format!("{}", self).fmt(f),
}
}
}

impl fmt::Debug for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self)?;
if self.source().is_some() {
write!(f, ": {:?}", self.source().unwrap())?; // recurse
}
Ok(())
}
}

impl StdError for Error {
fn description(&self) -> &str{
match *self {
Error::NoRequestContentType => "The Hyper request did not have a Content-Type header.",
Error::NotMultipart =>
"The Hyper request Content-Type top-level Mime was not multipart.",
Error::BoundaryNotSpecified =>
"The Content-Type header failed to specify a boundary token.",
Error::PartialHeaders =>
"A multipart section contained only partial headers.",
Error::EofInMainHeaders =>
"The request headers ended pre-maturely.",
Error::EofBeforeFirstBoundary =>
"The request body ended prior to reaching the expected starting boundary.",
Error::NoCrLfAfterBoundary =>
"Missing CRLF after boundary.",
Error::EofInPartHeaders =>
"The request body ended prematurely while parsing headers of a multipart part.",
Error::EofInFile =>
"The request body ended prematurely while streaming a file part.",
Error::EofInPart =>
"The request body ended prematurely while reading a multipart part.",
Error::Httparse(_) =>
"A parse error occurred while parsing the headers of a multipart section.",
Error::Io(_) => "An I/O error occurred.",
Error::Hyper(_) => "A Hyper error occurred.",
Error::Utf8(_) => "A UTF-8 error occurred.",
Error::Decoding(_) => "A decoding error occurred.",
}
}
}
96 changes: 96 additions & 0 deletions src/multipart/mime_multipart/mock.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
//! Code taken from Hyper, stripped down and with modification.
//!
//! See [https://github.com/hyperium/hyper](Hyper) for more information

// Copyright (c) 2014 Sean McArthur
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

use std::fmt;
use std::io::{self, Read, Write, Cursor};
use std::net::SocketAddr;
use std::time::Duration;

use hyper::net::NetworkStream;

pub struct MockStream {
pub read: Cursor<Vec<u8>>,
pub write: Vec<u8>,
}

impl Clone for MockStream {
fn clone(&self) -> MockStream {
MockStream {
read: Cursor::new(self.read.get_ref().clone()),
write: self.write.clone(),
}
}
}

impl fmt::Debug for MockStream {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "MockStream {{ read: {:?}, write: {:?} }}", self.read.get_ref(), self.write)
}
}

impl PartialEq for MockStream {
fn eq(&self, other: &MockStream) -> bool {
self.read.get_ref() == other.read.get_ref() && self.write == other.write
}
}

impl MockStream {
#[allow(dead_code)]
pub fn with_input(input: &[u8]) -> MockStream {
MockStream {
read: Cursor::new(input.to_vec()),
write: vec![],
}
}
}

impl Read for MockStream {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.read.read(buf)
}
}

impl Write for MockStream {
fn write(&mut self, msg: &[u8]) -> io::Result<usize> {
Write::write(&mut self.write, msg)
}

fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}

impl NetworkStream for MockStream {
fn peer_addr(&mut self) -> io::Result<SocketAddr> {
Ok("127.0.0.1:1337".parse().unwrap())
}

fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
Ok(())
}

fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
Ok(())
}
}

0 comments on commit b224349

Please sign in to comment.