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. mime_multipart functions replicated into
 multipart/related, and moved multipart/related.rs functions into a new
directory.
  • Loading branch information
Neelay Sant committed Jan 16, 2023
1 parent 28bc681 commit 0b74852
Show file tree
Hide file tree
Showing 7 changed files with 1,261 additions and 40 deletions.
8 changes: 6 additions & 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", "httparse", "tempdir", "log", "encoding", "buf-read-ext"]
serdejson = ["serde", "serde_json"]
server = ["hyper/server"]
http1 = ["hyper/http1"]
Expand Down Expand Up @@ -49,8 +49,12 @@ 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 }
httparse = { version = "1.3", optional = true }
tempdir = { version = "0.3", optional = true }
log = { version = "0.4", optional = true }
encoding = { version = "0.2", optional = true }
buf-read-ext = { version = "0.4", optional = true }

# UDS (Unix Domain Sockets)
tokio = { version = "1.0", default-features = false, optional = true }
Expand Down
38 changes: 0 additions & 38 deletions src/multipart/related.rs

This file was deleted.

132 changes: 132 additions & 0 deletions src/multipart/related/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
//! 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.
//
// File defining Error enum used in the module.

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_0_10;

/// 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,
/// The request headers ended pre-maturely.
EofInMainHeaders,
/// The request body ended prior to reaching the expected starting boundary.
EofBeforeFirstBoundary,
/// Missing CRLF after boundary.
NoCrLfAfterBoundary,
/// The request body ended prematurely while parsing headers of a multipart part.
EofInPartHeaders,
/// The request body ended prematurely while streaming a file part.
EofInFile,
/// The request body ended prematurely while reading a multipart part.
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_0_10::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_0_10::Error> for Error {
fn from(err: hyper_0_10::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.",
}
}
}
101 changes: 101 additions & 0 deletions src/multipart/related/mock.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
//! 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, Cursor, Read, Write};
use std::net::SocketAddr;
use std::time::Duration;

use hyper_0_10::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(())
}
}
Loading

0 comments on commit 0b74852

Please sign in to comment.