use hyper;
use futures::{Future, Stream};
use std::io::Write;
use errors::FunctionError;
pub fn body_as_bytes(b: hyper::Body) -> Result<Vec<u8>, FunctionError> {
match b.concat2()
.map(|chunk| chunk.iter().cloned().collect::<Vec<u8>>())
.wait() {
Ok(v) => Ok(v),
Err(e) => Err(FunctionError::io(e)),
}
}
pub fn no_content() -> hyper::Response {
hyper::Response::new().with_status(hyper::StatusCode::NoContent)
}
pub fn success<T>(data: T) -> hyper::Response
where
T: Into<Vec<u8>>,
{
let bytes: Vec<u8> = data.into();
hyper::Response::new()
.with_status(hyper::StatusCode::Ok)
.with_header(hyper::header::ContentLength(bytes.len() as u64))
.with_body(bytes)
}
pub fn client_error<T>(data: T) -> hyper::Response
where
T: Into<Vec<u8>>,
{
let bytes: Vec<u8> = data.into();
hyper::Response::new()
.with_status(hyper::StatusCode::BadRequest)
.with_header(hyper::header::ContentLength(bytes.len() as u64))
.with_body(bytes)
}
pub fn server_error<T>(data: T) -> hyper::Response
where
T: Into<Vec<u8>>,
{
let bytes: Vec<u8> = data.into();
hyper::Response::new()
.with_status(hyper::StatusCode::InternalServerError)
.with_header(hyper::header::ContentLength(bytes.len() as u64))
.with_body(bytes)
}
pub fn write_request_full(req: hyper::Request, writer: &mut Write) -> Result<(), FunctionError> {
let (method, uri, version, headers, body) = req.deconstruct();
match writer.write_all(format!("{} {} {}\r\n", method, uri, version).as_bytes()) {
Ok(_) => (),
Err(e) => return Err(FunctionError::io(e)),
};
for hv in headers.iter() {
match writer.write_all(
format!("{}: {}\r\n", hv.name(), hv.value_string()).as_bytes(),
) {
Ok(_) => (),
Err(e) => return Err(FunctionError::io(e)),
}
}
match writer.write_all(format!("\r\n").as_bytes()) {
Ok(_) => (),
Err(e) => return Err(FunctionError::io(e)),
};
match body_as_bytes(body) {
Ok(bytes) => {
match writer.write_all(&bytes) {
Ok(_) => {
match writer.flush() {
Ok(_) => Ok(()),
Err(e) => Err(FunctionError::io(e)),
}
}
Err(e) => Err(FunctionError::io(e)),
}
}
Err(e) => Err(e),
}
}
pub fn write_response_body(resp: hyper::Response, writer: &mut Write) -> Result<(), FunctionError> {
match body_as_bytes(resp.body()) {
Ok(bytes) => {
match writer.write_all(&bytes) {
Ok(_) => {
match writer.flush() {
Ok(_) => Ok(()),
Err(e) => Err(FunctionError::io(e)),
}
}
Err(e) => Err(FunctionError::io(e)),
}
}
Err(e) => Err(e),
}
}
pub fn write_response_full(resp: hyper::Response, writer: &mut Write) -> Result<(), FunctionError> {
match writer.write_all(
format!("{} {}\r\n", resp.version(), resp.status()).as_bytes(),
) {
Ok(_) => (),
Err(e) => return Err(FunctionError::io(e)),
};
for hv in resp.headers().iter() {
match writer.write_all(
format!("{}: {}\r\n", hv.name(), hv.value_string()).as_bytes(),
) {
Ok(_) => (),
Err(e) => return Err(FunctionError::io(e)),
}
}
match writer.write_all(format!("\r\n").as_bytes()) {
Ok(_) => (),
Err(e) => return Err(FunctionError::io(e)),
}
write_response_body(resp, writer)
}
pub fn exit_code_from_response(resp: &hyper::Response) -> i32 {
if resp.status().is_server_error() {
2
} else {
if resp.status().is_client_error() {
1
} else {
0
}
}
}
pub fn clone_response(resp: hyper::Response) -> (hyper::Response, hyper::Response) {
let mut r1 = hyper::Response::new()
.with_status(resp.status())
.with_headers(resp.headers().clone());
let mut r2 = hyper::Response::new()
.with_status(resp.status())
.with_headers(resp.headers().clone());
let bbytes = body_as_bytes(resp.body()).unwrap();
r1.set_body(bbytes.clone());
r2.set_body(bbytes);
(r1, r2)
}