Skip to content

Commit

Permalink
Merge pull request #13 from PureW/master
Browse files Browse the repository at this point in the history
Making native-tls an optional feature
  • Loading branch information
Nazarii Sheremet committed Dec 8, 2017
2 parents 013058f + ecd485a commit 90b0cc0
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 50 deletions.
8 changes: 4 additions & 4 deletions Cargo.toml
Expand Up @@ -12,12 +12,12 @@ readme = "README.md"
keywords = ["rust", "http-client"]
license = "MPL-2.0"

[features]
default = ["native-tls"]

[dependencies]
serde_json = "1.0.*"
rand = "0.3"
native-tls = "0.1.4"
native-tls = { version = "0.1.4", optional = true }
url = "1.6"
clippy = { version = "0.0.134", optional = true}

[features]
default = []
9 changes: 6 additions & 3 deletions src/consts.rs
@@ -1,11 +1,14 @@
pub const HTTP_VERSION: &'static str = "HTTP/1.1";
pub const CL_METHODS: [&'static str; 2] = ["POST", "PUT"];
pub const C_TYPE: [&'static str; 3] = ["application/json",
"application/x-www-form-urlencoded",
"multipart/form-data"];
pub const C_TYPE: [&'static str; 3] = [
"application/json",
"application/x-www-form-urlencoded",
"multipart/form-data",
];
pub const SEP: &'static str = "\r\n";

pub const DEF_PORT: u16 = 80;
#[cfg(feature = "native_tls")]
pub const DEF_SSL_PORT: u16 = 443;
pub const DEF_ACCEPT: &'static str = "*/*";
pub const DEF_CONN: &'static str = "close";
Expand Down
17 changes: 17 additions & 0 deletions src/err.rs
@@ -1,22 +1,28 @@
extern crate serde_json;
#[cfg(feature = "native_tls")]
extern crate native_tls;

use std::fmt;
use std::error;
use std::io;
#[cfg(feature = "native_tls")]
use std::net::TcpStream;
use std::num::ParseIntError;
use url::ParseError;
#[cfg(feature = "native_tls")]
use native_tls::HandshakeError;

#[derive(Debug)]
pub enum HttpError {
Parse(ParseError),
IO(io::Error),
Json(serde_json::Error),
#[cfg(feature = "native_tls")]
TLS(native_tls::Error),
#[cfg(feature = "native_tls")]
SSL(HandshakeError<TcpStream>),
ParseInt(ParseIntError),
MissingFeature(String),
}

impl From<ParseError> for HttpError {
Expand All @@ -37,12 +43,14 @@ impl From<serde_json::Error> for HttpError {
}
}

#[cfg(feature = "native_tls")]
impl From<native_tls::Error> for HttpError {
fn from(err: native_tls::Error) -> HttpError {
HttpError::TLS(err)
}
}

#[cfg(feature = "native_tls")]
impl From<HandshakeError<TcpStream>> for HttpError {
fn from(err: HandshakeError<TcpStream>) -> HttpError {
HttpError::SSL(err)
Expand All @@ -61,9 +69,12 @@ impl fmt::Display for HttpError {
HttpError::Parse(ref err) => write!(f, "Parse error: {}", err),
HttpError::IO(ref err) => write!(f, "Parse error: {}", err),
HttpError::Json(ref err) => write!(f, "Parse error: {}", err),
#[cfg(feature = "native_tls")]
HttpError::TLS(ref err) => write!(f, "Parse error: {}", err),
#[cfg(feature = "native_tls")]
HttpError::SSL(ref err) => write!(f, "Parse error: {}", err),
HttpError::ParseInt(ref err) => write!(f, "Parse error: {}", err),
HttpError::MissingFeature(ref err) => write!(f, "Missing feature: {}", err),
}
}
}
Expand All @@ -74,9 +85,12 @@ impl error::Error for HttpError {
HttpError::Parse(ref err) => err.description(),
HttpError::IO(ref err) => err.description(),
HttpError::Json(ref err) => err.description(),
#[cfg(feature = "native_tls")]
HttpError::TLS(ref err) => err.description(),
#[cfg(feature = "native_tls")]
HttpError::SSL(ref err) => err.description(),
HttpError::ParseInt(ref err) => err.description(),
HttpError::MissingFeature(ref err) => err,
}
}

Expand All @@ -85,9 +99,12 @@ impl error::Error for HttpError {
HttpError::Parse(ref err) => Some(err),
HttpError::IO(ref err) => Some(err),
HttpError::Json(ref err) => Some(err),
#[cfg(feature = "native_tls")]
HttpError::TLS(ref err) => Some(err),
#[cfg(feature = "native_tls")]
HttpError::SSL(ref err) => Some(err),
HttpError::ParseInt(ref err) => Some(err),
HttpError::MissingFeature(ref _err) => None,
}
}
}
93 changes: 54 additions & 39 deletions src/lib.rs
Expand Up @@ -4,6 +4,7 @@
extern crate url;
extern crate rand;
extern crate serde_json;
#[cfg(feature = "native_tls")]
extern crate native_tls;

use std::net::TcpStream;
Expand All @@ -18,6 +19,7 @@ use url::{Url, ParseError};
use consts::*;
use err::HttpError;
use response::*;
#[cfg(feature = "native_tls")]
use native_tls::TlsConnector;

mod err;
Expand Down Expand Up @@ -52,7 +54,6 @@ pub enum Data {
}

impl HTTP {

/// HTTP struct instance
///
/// ```rust
Expand All @@ -77,18 +78,18 @@ impl HTTP {
};

Ok(HTTP {
response: response,
url: url,

method: String::new(),
body: HashMap::new(),
header: HashMap::new(),
body_str: String::new(),

host: host_url,
boundary: String::new(),
response_str: String::new(),
})
response: response,
url: url,

method: String::new(),
body: HashMap::new(),
header: HashMap::new(),
body_str: String::new(),

host: host_url,
boundary: String::new(),
response_str: String::new(),
})
}

/// How to send simple GET request
Expand Down Expand Up @@ -256,24 +257,35 @@ impl HTTP {
stream.write_all(request.as_bytes())?;
stream.read_to_string(&mut self.response_str)?;
} else {
let port = match self.url.port() {
Some(p) => p,
None => DEF_SSL_PORT,
};
let addr = format!("{}:{}", url, port);
let connector = TlsConnector::builder()?.build()?;
let stream = TcpStream::connect(addr)?;
let mut stream = connector.connect(&self.host, stream)?;

stream.write_all(request.as_bytes())?;
stream.read_to_string(&mut self.response_str)?;
self.tls_transport(url)?;
}

response = self.response_str.clone();
let resp = Response::new(response).unwrap();
Ok(resp)
}

#[cfg(feature = "native_tls")]
fn tls_transport(&self, url: &str) -> Result<(), HttpError> {
let port = match self.url.port() {
Some(p) => p,
None => DEF_SSL_PORT,
};
let addr = format!("{}:{}", url, port);
let connector = TlsConnector::builder()?.build()?;
let stream = TcpStream::connect(addr)?;
let mut stream = connector.connect(&self.host, stream)?;

stream.write_all(request.as_bytes())?;
stream.read_to_string(&mut self.response_str)?;
}

#[cfg(not(feature = "native_tls"))]
fn tls_transport(&self, _url: &str) -> Result<(), HttpError> {
Err(HttpError::MissingFeature(
"Lib not compiled with feature native_tls active".into(),
))
}
/// Create Reqeust String
///
/// Params: &mut self (HTTP)
Expand Down Expand Up @@ -302,11 +314,7 @@ impl HTTP {
None => self.url.path().to_string(),
};
let mut str = String::new();
str += &format!("{} {} {}{}",
self.method,
path,
HTTP_VERSION,
SEP);
str += &format!("{} {} {}{}", self.method, path, HTTP_VERSION, SEP);

for (key, val) in &header {
str += &format!("{}: {}{}", key, val, SEP);
Expand All @@ -322,11 +330,12 @@ impl HTTP {
///
/// Response: Result<String, `HttpError`>
///
fn create_body(c_type: &str,
body: &HashMap<String, Data>,
mut header: HashMap<String, String>,
b: &str)
-> Result<String, HttpError> {
fn create_body(
c_type: &str,
body: &HashMap<String, Data>,
mut header: HashMap<String, String>,
b: &str,
) -> Result<String, HttpError> {
let mut res = String::new();

if c_type == C_TYPE[1] {
Expand All @@ -347,7 +356,9 @@ fn create_body(c_type: &str,
match *val {
Data::File(ref str) => {
res += &format!("Content-Disposition: form-data; name={};", key);
let file_name = Path::new(str).file_name().ok_or_else(|| Error::new(ErrorKind::InvalidData, "wrong file path"))?;
let file_name = Path::new(str).file_name().ok_or_else(|| {
Error::new(ErrorKind::InvalidData, "wrong file path")
})?;
res += &format!(" filename={0}{1}{1}", file_name.to_str().unwrap(), SEP);
let mut buffer = String::new();
let mut file = File::open(str)?;
Expand Down Expand Up @@ -385,9 +396,10 @@ fn create_body(c_type: &str,
///
/// Response: (Result<String, `HttpError`>, String)
///
fn organize_header(header: &HashMap<String, String>,
host: &str)
-> (HashMap<String, String>, String) {
fn organize_header(
header: &HashMap<String, String>,
host: &str,
) -> (HashMap<String, String>, String) {
let mut data: HashMap<String, String> = HashMap::new();
let mut c_type = String::new();

Expand Down Expand Up @@ -437,6 +449,9 @@ mod tests {
fn test_query_params() {
let mut http = HTTP::new("http://moo.com/?foo=bar").unwrap();
let expected = "GET /?foo=bar".to_string();
assert_eq!(http.get().create_request().unwrap()[0 .. expected.len()], expected);
assert_eq!(
http.get().create_request().unwrap()[0..expected.len()],
expected
);
}
}
8 changes: 4 additions & 4 deletions src/response.rs
Expand Up @@ -49,10 +49,10 @@ impl Response {
}

Ok(Response {
status: status,
header: header,
body: body,
})
status: status,
header: header,
body: body,
})
}

pub fn as_str(&self) -> String {
Expand Down

0 comments on commit 90b0cc0

Please sign in to comment.