1
0
mirror of https://github.com/actix/actix-extras.git synced 2024-11-25 00:12:59 +01:00
actix-extras/tests/test_client.rs

509 lines
16 KiB
Rust
Raw Normal View History

2018-05-01 07:04:24 +02:00
#![allow(deprecated)]
extern crate actix;
extern crate actix_web;
extern crate bytes;
2018-02-24 05:29:35 +01:00
extern crate flate2;
2018-04-14 01:02:01 +02:00
extern crate futures;
2018-03-06 20:02:03 +01:00
extern crate rand;
#[cfg(all(unix, feature = "uds"))]
extern crate tokio_uds;
2018-02-24 05:29:35 +01:00
use std::io::{Read, Write};
use std::{net, thread};
use bytes::Bytes;
2018-04-14 01:02:01 +02:00
use flate2::read::GzDecoder;
2018-02-24 05:29:35 +01:00
use futures::stream::once;
2018-04-29 07:55:47 +02:00
use futures::Future;
2018-03-06 20:02:03 +01:00
use rand::Rng;
use actix_web::*;
2018-04-14 01:02:01 +02:00
const STR: &str = "Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World";
#[test]
fn test_simple() {
2018-04-14 01:02:01 +02:00
let mut srv =
test::TestServer::new(|app| app.handler(|_| HttpResponse::Ok().body(STR)));
let request = srv.get().header("x-test", "111").finish().unwrap();
let repr = format!("{:?}", request);
assert!(repr.contains("ClientRequest"));
assert!(repr.contains("x-test"));
let response = srv.execute(request.send()).unwrap();
assert!(response.status().is_success());
// read response
let bytes = srv.execute(response.body()).unwrap();
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
let request = srv.post().finish().unwrap();
let response = srv.execute(request.send()).unwrap();
assert!(response.status().is_success());
// read response
let bytes = srv.execute(response.body()).unwrap();
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
}
2018-02-24 05:29:35 +01:00
#[test]
fn test_connection_close() {
let mut srv =
test::TestServer::new(|app| app.handler(|_| HttpResponse::Ok().body(STR)));
let request = srv.get().header("Connection", "close").finish().unwrap();
let response = srv.execute(request.send()).unwrap();
assert!(response.status().is_success());
}
2018-03-14 21:45:49 +01:00
#[test]
fn test_with_query_parameter() {
2018-04-14 01:02:01 +02:00
let mut srv = test::TestServer::new(|app| {
2018-06-25 06:58:04 +02:00
app.handler(|req: &HttpRequest| match req.query().get("qp") {
Some(_) => HttpResponse::Ok().finish(),
None => HttpResponse::BadRequest().finish(),
2018-04-14 01:02:01 +02:00
})
});
2018-03-14 21:45:49 +01:00
2018-05-17 21:20:20 +02:00
let request = srv.get().uri(srv.url("/?qp=5").as_str()).finish().unwrap();
2018-03-14 21:45:49 +01:00
let response = srv.execute(request.send()).unwrap();
assert!(response.status().is_success());
}
2018-02-24 05:29:35 +01:00
#[test]
fn test_no_decompress() {
2018-04-14 01:02:01 +02:00
let mut srv =
test::TestServer::new(|app| app.handler(|_| HttpResponse::Ok().body(STR)));
2018-02-24 05:29:35 +01:00
let request = srv.get().disable_decompress().finish().unwrap();
let response = srv.execute(request.send()).unwrap();
assert!(response.status().is_success());
// read response
let bytes = srv.execute(response.body()).unwrap();
let mut e = GzDecoder::new(&bytes[..]);
let mut dec = Vec::new();
e.read_to_end(&mut dec).unwrap();
assert_eq!(Bytes::from(dec), Bytes::from_static(STR.as_ref()));
// POST
let request = srv.post().disable_decompress().finish().unwrap();
let response = srv.execute(request.send()).unwrap();
let bytes = srv.execute(response.body()).unwrap();
let mut e = GzDecoder::new(&bytes[..]);
let mut dec = Vec::new();
e.read_to_end(&mut dec).unwrap();
assert_eq!(Bytes::from(dec), Bytes::from_static(STR.as_ref()));
}
#[test]
fn test_client_gzip_encoding() {
2018-04-14 01:02:01 +02:00
let mut srv = test::TestServer::new(|app| {
2018-06-25 06:58:04 +02:00
app.handler(|req: &HttpRequest| {
2018-04-14 01:02:01 +02:00
req.body()
.and_then(|bytes: Bytes| {
Ok(HttpResponse::Ok()
.content_encoding(http::ContentEncoding::Deflate)
.body(bytes))
2018-08-23 18:48:01 +02:00
}).responder()
2018-04-14 01:02:01 +02:00
})
});
2018-02-24 05:29:35 +01:00
// client request
2018-05-17 21:20:20 +02:00
let request = srv
.post()
2018-04-29 18:09:08 +02:00
.content_encoding(http::ContentEncoding::Gzip)
.body(STR)
.unwrap();
2018-02-24 05:29:35 +01:00
let response = srv.execute(request.send()).unwrap();
assert!(response.status().is_success());
// read response
let bytes = srv.execute(response.body()).unwrap();
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
}
#[test]
fn test_client_gzip_encoding_large() {
2018-03-05 02:54:58 +01:00
let data = STR.repeat(10);
2018-04-14 01:02:01 +02:00
let mut srv = test::TestServer::new(|app| {
2018-06-25 06:58:04 +02:00
app.handler(|req: &HttpRequest| {
2018-04-14 01:02:01 +02:00
req.body()
.and_then(|bytes: Bytes| {
Ok(HttpResponse::Ok()
.content_encoding(http::ContentEncoding::Deflate)
.body(bytes))
2018-08-23 18:48:01 +02:00
}).responder()
2018-04-14 01:02:01 +02:00
})
});
// client request
2018-05-17 21:20:20 +02:00
let request = srv
.post()
2018-03-31 02:31:18 +02:00
.content_encoding(http::ContentEncoding::Gzip)
2018-04-14 01:02:01 +02:00
.body(data.clone())
.unwrap();
let response = srv.execute(request.send()).unwrap();
assert!(response.status().is_success());
// read response
let bytes = srv.execute(response.body()).unwrap();
assert_eq!(bytes, Bytes::from(data));
}
2018-02-24 05:29:35 +01:00
#[test]
2018-03-06 20:02:03 +01:00
fn test_client_gzip_encoding_large_random() {
2018-04-29 18:09:08 +02:00
let data = rand::thread_rng()
.gen_ascii_chars()
.take(100_000)
.collect::<String>();
2018-03-06 20:02:03 +01:00
2018-04-14 01:02:01 +02:00
let mut srv = test::TestServer::new(|app| {
2018-06-25 06:58:04 +02:00
app.handler(|req: &HttpRequest| {
2018-04-14 01:02:01 +02:00
req.body()
.and_then(|bytes: Bytes| {
Ok(HttpResponse::Ok()
.content_encoding(http::ContentEncoding::Deflate)
.body(bytes))
2018-08-23 18:48:01 +02:00
}).responder()
2018-04-14 01:02:01 +02:00
})
});
2018-02-24 05:29:35 +01:00
2018-03-06 20:02:03 +01:00
// client request
2018-05-17 21:20:20 +02:00
let request = srv
.post()
2018-03-31 02:31:18 +02:00
.content_encoding(http::ContentEncoding::Gzip)
2018-04-14 01:02:01 +02:00
.body(data.clone())
.unwrap();
2018-03-06 20:02:03 +01:00
let response = srv.execute(request.send()).unwrap();
assert!(response.status().is_success());
// read response
let bytes = srv.execute(response.body()).unwrap();
assert_eq!(bytes, Bytes::from(data));
}
#[cfg(all(unix, feature = "uds"))]
#[test]
fn test_compatible_with_unix_socket_stream() {
let (stream, _) = tokio_uds::UnixStream::pair().unwrap();
let _ = client::Connection::from_stream(stream);
}
2018-04-14 01:02:01 +02:00
#[cfg(feature = "brotli")]
2018-03-06 20:02:03 +01:00
#[test]
fn test_client_brotli_encoding() {
2018-04-14 01:02:01 +02:00
let mut srv = test::TestServer::new(|app| {
2018-06-25 06:58:04 +02:00
app.handler(|req: &HttpRequest| {
2018-04-14 01:02:01 +02:00
req.body()
.and_then(|bytes: Bytes| {
Ok(HttpResponse::Ok()
.content_encoding(http::ContentEncoding::Gzip)
.body(bytes))
2018-08-23 18:48:01 +02:00
}).responder()
2018-04-14 01:02:01 +02:00
})
});
2018-03-06 20:02:03 +01:00
2018-02-24 05:29:35 +01:00
// client request
2018-05-17 21:20:20 +02:00
let request = srv
.client(http::Method::POST, "/")
2018-03-31 02:31:18 +02:00
.content_encoding(http::ContentEncoding::Br)
2018-04-14 01:02:01 +02:00
.body(STR)
.unwrap();
2018-02-24 05:29:35 +01:00
let response = srv.execute(request.send()).unwrap();
assert!(response.status().is_success());
// read response
let bytes = srv.execute(response.body()).unwrap();
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
}
2018-04-14 01:02:01 +02:00
#[cfg(feature = "brotli")]
2018-03-06 20:02:03 +01:00
#[test]
fn test_client_brotli_encoding_large_random() {
2018-04-29 18:09:08 +02:00
let data = rand::thread_rng()
.gen_ascii_chars()
.take(70_000)
.collect::<String>();
2018-03-06 20:02:03 +01:00
2018-04-14 01:02:01 +02:00
let mut srv = test::TestServer::new(|app| {
2018-06-25 06:58:04 +02:00
app.handler(|req: &HttpRequest| {
2018-04-14 01:02:01 +02:00
req.body()
.and_then(move |bytes: Bytes| {
Ok(HttpResponse::Ok()
.content_encoding(http::ContentEncoding::Gzip)
.body(bytes))
2018-08-23 18:48:01 +02:00
}).responder()
2018-04-14 01:02:01 +02:00
})
});
2018-03-06 20:02:03 +01:00
// client request
2018-05-17 21:20:20 +02:00
let request = srv
.client(http::Method::POST, "/")
2018-03-31 02:31:18 +02:00
.content_encoding(http::ContentEncoding::Br)
2018-04-14 01:02:01 +02:00
.body(data.clone())
.unwrap();
2018-03-06 20:02:03 +01:00
let response = srv.execute(request.send()).unwrap();
assert!(response.status().is_success());
// read response
let bytes = srv.execute(response.body()).unwrap();
assert_eq!(bytes.len(), data.len());
assert_eq!(bytes, Bytes::from(data));
}
2018-04-14 01:02:01 +02:00
#[cfg(feature = "brotli")]
2018-02-24 05:29:35 +01:00
#[test]
fn test_client_deflate_encoding() {
2018-04-14 01:02:01 +02:00
let mut srv = test::TestServer::new(|app| {
2018-06-25 06:58:04 +02:00
app.handler(|req: &HttpRequest| {
2018-04-14 01:02:01 +02:00
req.body()
.and_then(|bytes: Bytes| {
Ok(HttpResponse::Ok()
.content_encoding(http::ContentEncoding::Br)
.body(bytes))
2018-08-23 18:48:01 +02:00
}).responder()
2018-04-14 01:02:01 +02:00
})
});
2018-02-24 05:29:35 +01:00
// client request
2018-05-17 21:20:20 +02:00
let request = srv
.post()
2018-04-29 18:09:08 +02:00
.content_encoding(http::ContentEncoding::Deflate)
.body(STR)
.unwrap();
2018-02-24 05:29:35 +01:00
let response = srv.execute(request.send()).unwrap();
assert!(response.status().is_success());
// read response
let bytes = srv.execute(response.body()).unwrap();
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
}
2018-04-14 01:02:01 +02:00
#[cfg(feature = "brotli")]
2018-03-06 20:02:03 +01:00
#[test]
fn test_client_deflate_encoding_large_random() {
2018-04-29 18:09:08 +02:00
let data = rand::thread_rng()
.gen_ascii_chars()
.take(70_000)
.collect::<String>();
2018-03-06 20:02:03 +01:00
2018-04-14 01:02:01 +02:00
let mut srv = test::TestServer::new(|app| {
2018-06-25 06:58:04 +02:00
app.handler(|req: &HttpRequest| {
2018-04-14 01:02:01 +02:00
req.body()
.and_then(|bytes: Bytes| {
Ok(HttpResponse::Ok()
.content_encoding(http::ContentEncoding::Br)
.body(bytes))
2018-08-23 18:48:01 +02:00
}).responder()
2018-04-14 01:02:01 +02:00
})
});
2018-03-06 20:02:03 +01:00
// client request
2018-05-17 21:20:20 +02:00
let request = srv
.post()
2018-03-31 02:31:18 +02:00
.content_encoding(http::ContentEncoding::Deflate)
2018-04-14 01:02:01 +02:00
.body(data.clone())
.unwrap();
2018-03-06 20:02:03 +01:00
let response = srv.execute(request.send()).unwrap();
assert!(response.status().is_success());
// read response
let bytes = srv.execute(response.body()).unwrap();
assert_eq!(bytes, Bytes::from(data));
}
2018-02-24 05:29:35 +01:00
#[test]
fn test_client_streaming_explicit() {
2018-04-14 01:02:01 +02:00
let mut srv = test::TestServer::new(|app| {
2018-06-25 06:58:04 +02:00
app.handler(|req: &HttpRequest| {
2018-04-14 01:02:01 +02:00
req.body()
2018-02-24 05:29:35 +01:00
.map_err(Error::from)
.and_then(|body| {
Ok(HttpResponse::Ok()
2018-04-14 01:02:01 +02:00
.chunked()
.content_encoding(http::ContentEncoding::Identity)
.body(body))
2018-08-23 18:48:01 +02:00
}).responder()
2018-04-14 01:02:01 +02:00
})
});
2018-02-24 05:29:35 +01:00
let body = once(Ok(Bytes::from_static(STR.as_ref())));
2018-06-19 06:15:16 +02:00
let request = srv.get().body(Body::Streaming(Box::new(body))).unwrap();
2018-02-24 05:29:35 +01:00
let response = srv.execute(request.send()).unwrap();
assert!(response.status().is_success());
// read response
let bytes = srv.execute(response.body()).unwrap();
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
}
#[test]
fn test_body_streaming_implicit() {
2018-04-14 01:02:01 +02:00
let mut srv = test::TestServer::new(|app| {
app.handler(|_| {
2018-02-24 05:29:35 +01:00
let body = once(Ok(Bytes::from_static(STR.as_ref())));
HttpResponse::Ok()
2018-03-31 02:31:18 +02:00
.content_encoding(http::ContentEncoding::Gzip)
2018-04-14 01:02:01 +02:00
.body(Body::Streaming(Box::new(body)))
})
});
2018-02-24 05:29:35 +01:00
let request = srv.get().finish().unwrap();
let response = srv.execute(request.send()).unwrap();
assert!(response.status().is_success());
// read response
let bytes = srv.execute(response.body()).unwrap();
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
}
2018-03-07 12:43:55 +01:00
#[test]
fn test_client_cookie_handling() {
2018-03-31 02:31:18 +02:00
use actix_web::http::Cookie;
2018-03-07 12:43:55 +01:00
fn err() -> Error {
2018-04-14 01:02:01 +02:00
use std::io::{Error as IoError, ErrorKind};
2018-03-07 12:43:55 +01:00
// stub some generic error
Error::from(IoError::from(ErrorKind::NotFound))
}
let cookie1 = Cookie::build("cookie1", "value1").finish();
let cookie2 = Cookie::build("cookie2", "value2")
.domain("www.example.org")
.path("/")
.secure(true)
.http_only(true)
.finish();
// Q: are all these clones really necessary? A: Yes, possibly
let cookie1b = cookie1.clone();
let cookie2b = cookie2.clone();
2018-04-14 01:02:01 +02:00
let mut srv = test::TestServer::new(move |app| {
let cookie1 = cookie1b.clone();
let cookie2 = cookie2b.clone();
2018-06-25 06:58:04 +02:00
app.handler(move |req: &HttpRequest| {
2018-04-14 01:02:01 +02:00
// Check cookies were sent correctly
req.cookie("cookie1")
.ok_or_else(err)
.and_then(|c1| {
if c1.value() == "value1" {
2018-03-07 12:43:55 +01:00
Ok(())
} else {
Err(err())
}
}).and_then(|()| req.cookie("cookie2").ok_or_else(err))
.and_then(|c2| {
if c2.value() == "value2" {
2018-03-07 12:43:55 +01:00
Ok(())
} else {
Err(err())
}
})
// Send some cookies back
.map(|_| {
HttpResponse::Ok()
.cookie(cookie1.clone())
.cookie(cookie2.clone())
.finish()
})
2018-04-14 01:02:01 +02:00
})
});
2018-03-07 12:43:55 +01:00
2018-05-17 21:20:20 +02:00
let request = srv
.get()
2018-04-29 18:09:08 +02:00
.cookie(cookie1.clone())
.cookie(cookie2.clone())
.finish()
.unwrap();
2018-03-07 12:43:55 +01:00
let response = srv.execute(request.send()).unwrap();
assert!(response.status().is_success());
let c1 = response.cookie("cookie1").expect("Missing cookie1");
assert_eq!(c1, cookie1);
2018-03-07 12:43:55 +01:00
let c2 = response.cookie("cookie2").expect("Missing cookie2");
assert_eq!(c2, cookie2);
2018-03-07 12:43:55 +01:00
}
#[test]
fn test_default_headers() {
let srv = test::TestServer::new(|app| app.handler(|_| HttpResponse::Ok().body(STR)));
let request = srv.get().finish().unwrap();
let repr = format!("{:?}", request);
assert!(repr.contains("\"accept-encoding\": \"gzip, deflate\""));
2018-06-04 08:15:04 +02:00
assert!(repr.contains(concat!(
"\"user-agent\": \"actix-web/",
2018-06-04 08:15:04 +02:00
env!("CARGO_PKG_VERSION"),
"\""
)));
2018-07-16 07:17:45 +02:00
let request_override = srv
.get()
.header("User-Agent", "test")
.header("Accept-Encoding", "over_test")
.finish()
.unwrap();
let repr_override = format!("{:?}", request_override);
assert!(repr_override.contains("\"user-agent\": \"test\""));
assert!(repr_override.contains("\"accept-encoding\": \"over_test\""));
assert!(!repr_override.contains("\"accept-encoding\": \"gzip, deflate\""));
2018-06-04 08:15:04 +02:00
assert!(!repr_override.contains(concat!(
"\"user-agent\": \"Actix-web/",
env!("CARGO_PKG_VERSION"),
"\""
)));
}
#[test]
fn client_read_until_eof() {
let addr = test::TestServer::unused_addr();
thread::spawn(move || {
let lst = net::TcpListener::bind(addr).unwrap();
for stream in lst.incoming() {
let mut stream = stream.unwrap();
let mut b = [0; 1000];
let _ = stream.read(&mut b).unwrap();
let _ = stream
.write_all(b"HTTP/1.1 200 OK\r\nconnection: close\r\n\r\nwelcome!");
}
});
let mut sys = actix::System::new("test");
// client request
let req = client::ClientRequest::get(format!("http://{}/", addr).as_str())
.finish()
.unwrap();
let response = sys.block_on(req.send()).unwrap();
assert!(response.status().is_success());
// read response
let bytes = sys.block_on(response.body()).unwrap();
assert_eq!(bytes, Bytes::from_static(b"welcome!"));
}