mirror of https://github.com/rwf2/Rocket.git
Keep an op-log for sync 'CookieJar'.
In brief, this commit: * Updates to the latest upstream 'cookie', fixing a memory leak. * Make changes to 'CookieJar' observable only through 'pending()'. * Deprecates 'Client::new()' in favor of 'Client::tracked()'. * Makes 'dispatch()' on tracked 'Client's synchronize on cookies. * Makes 'Client::untracked()' actually untracked. This commit updates to the latest 'cookie' which removes support for 'Sync' cookie jars. Instead of relying on 'cookie', this commit implements an op-log based 'CookieJar' which internally keeps track of changes. The API is such that changes are only observable through specialized '_pending()' methods.
This commit is contained in:
parent
2f330d2967
commit
5d9035ddc1
|
@ -1130,7 +1130,5 @@ mod tests {
|
||||||
assert_eq!(pool_size, database_config.pool_size);
|
assert_eq!(pool_size, database_config.pool_size);
|
||||||
assert_eq!(true, database_config.extras.contains_key("certs"));
|
assert_eq!(true, database_config.extras.contains_key("certs"));
|
||||||
assert_eq!(true, database_config.extras.contains_key("key"));
|
assert_eq!(true, database_config.extras.contains_key("key"));
|
||||||
|
|
||||||
println!("{:#?}", database_config);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -330,7 +330,7 @@ impl Template {
|
||||||
///
|
///
|
||||||
/// fn main() {
|
/// fn main() {
|
||||||
/// let rocket = rocket::ignite().attach(Template::fairing());
|
/// let rocket = rocket::ignite().attach(Template::fairing());
|
||||||
/// let client = Client::new(rocket).expect("valid rocket");
|
/// let client = Client::untracked(rocket).expect("valid rocket");
|
||||||
///
|
///
|
||||||
/// // Create a `context`. Here, just an empty `HashMap`.
|
/// // Create a `context`. Here, just an empty `HashMap`.
|
||||||
/// let mut context = HashMap::new();
|
/// let mut context = HashMap::new();
|
||||||
|
|
|
@ -66,7 +66,7 @@ mod compress_responder_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_prioritizes_brotli() {
|
fn test_prioritizes_brotli() {
|
||||||
let client = Client::new(rocket()).expect("valid rocket instance");
|
let client = Client::tracked(rocket()).expect("valid rocket instance");
|
||||||
let mut response = client
|
let mut response = client
|
||||||
.get("/")
|
.get("/")
|
||||||
.header(Header::new("Accept-Encoding", "deflate, gzip, br"))
|
.header(Header::new("Accept-Encoding", "deflate, gzip, br"))
|
||||||
|
@ -90,7 +90,7 @@ mod compress_responder_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_br_font() {
|
fn test_br_font() {
|
||||||
let client = Client::new(rocket()).expect("valid rocket instance");
|
let client = Client::tracked(rocket()).expect("valid rocket instance");
|
||||||
let mut response = client
|
let mut response = client
|
||||||
.get("/font")
|
.get("/font")
|
||||||
.header(Header::new("Accept-Encoding", "deflate, gzip, br"))
|
.header(Header::new("Accept-Encoding", "deflate, gzip, br"))
|
||||||
|
@ -114,7 +114,7 @@ mod compress_responder_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fallback_gzip() {
|
fn test_fallback_gzip() {
|
||||||
let client = Client::new(rocket()).expect("valid rocket instance");
|
let client = Client::tracked(rocket()).expect("valid rocket instance");
|
||||||
let mut response = client
|
let mut response = client
|
||||||
.get("/")
|
.get("/")
|
||||||
.header(Header::new("Accept-Encoding", "deflate, gzip"))
|
.header(Header::new("Accept-Encoding", "deflate, gzip"))
|
||||||
|
@ -137,7 +137,7 @@ mod compress_responder_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_does_not_recompress() {
|
fn test_does_not_recompress() {
|
||||||
let client = Client::new(rocket()).expect("valid rocket instance");
|
let client = Client::tracked(rocket()).expect("valid rocket instance");
|
||||||
let mut response = client
|
let mut response = client
|
||||||
.get("/already_encoded")
|
.get("/already_encoded")
|
||||||
.header(Header::new("Accept-Encoding", "deflate, gzip, br"))
|
.header(Header::new("Accept-Encoding", "deflate, gzip, br"))
|
||||||
|
@ -160,7 +160,7 @@ mod compress_responder_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_does_not_compress_explicit_identity() {
|
fn test_does_not_compress_explicit_identity() {
|
||||||
let client = Client::new(rocket()).expect("valid rocket instance");
|
let client = Client::tracked(rocket()).expect("valid rocket instance");
|
||||||
let mut response = client
|
let mut response = client
|
||||||
.get("/identity")
|
.get("/identity")
|
||||||
.header(Header::new("Accept-Encoding", "deflate, gzip, br"))
|
.header(Header::new("Accept-Encoding", "deflate, gzip, br"))
|
||||||
|
@ -178,7 +178,7 @@ mod compress_responder_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_ignore_exceptions() {
|
fn test_ignore_exceptions() {
|
||||||
let client = Client::new(rocket()).expect("valid rocket instance");
|
let client = Client::tracked(rocket()).expect("valid rocket instance");
|
||||||
let mut response = client
|
let mut response = client
|
||||||
.get("/image")
|
.get("/image")
|
||||||
.header(Header::new("Accept-Encoding", "deflate, gzip, br"))
|
.header(Header::new("Accept-Encoding", "deflate, gzip, br"))
|
||||||
|
@ -202,7 +202,7 @@ mod compress_responder_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_ignores_unimplemented_encodings() {
|
fn test_ignores_unimplemented_encodings() {
|
||||||
let client = Client::new(rocket()).expect("valid rocket instance");
|
let client = Client::tracked(rocket()).expect("valid rocket instance");
|
||||||
let mut response = client
|
let mut response = client
|
||||||
.get("/")
|
.get("/")
|
||||||
.header(Header::new("Accept-Encoding", "deflate"))
|
.header(Header::new("Accept-Encoding", "deflate"))
|
||||||
|
@ -220,7 +220,7 @@ mod compress_responder_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_respects_identity_only() {
|
fn test_respects_identity_only() {
|
||||||
let client = Client::new(rocket()).expect("valid rocket instance");
|
let client = Client::tracked(rocket()).expect("valid rocket instance");
|
||||||
let mut response = client
|
let mut response = client
|
||||||
.get("/")
|
.get("/")
|
||||||
.header(Header::new("Accept-Encoding", "identity"))
|
.header(Header::new("Accept-Encoding", "identity"))
|
||||||
|
|
|
@ -85,7 +85,7 @@ mod compression_fairing_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_prioritizes_brotli() {
|
fn test_prioritizes_brotli() {
|
||||||
let client = Client::new(rocket()).expect("valid rocket instance");
|
let client = Client::tracked(rocket()).expect("valid rocket instance");
|
||||||
let mut response = client
|
let mut response = client
|
||||||
.get("/")
|
.get("/")
|
||||||
.header(Header::new("Accept-Encoding", "deflate, gzip, br"))
|
.header(Header::new("Accept-Encoding", "deflate, gzip, br"))
|
||||||
|
@ -109,7 +109,7 @@ mod compression_fairing_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_br_font() {
|
fn test_br_font() {
|
||||||
let client = Client::new(rocket()).expect("valid rocket instance");
|
let client = Client::tracked(rocket()).expect("valid rocket instance");
|
||||||
let mut response = client
|
let mut response = client
|
||||||
.get("/font")
|
.get("/font")
|
||||||
.header(Header::new("Accept-Encoding", "deflate, gzip, br"))
|
.header(Header::new("Accept-Encoding", "deflate, gzip, br"))
|
||||||
|
@ -133,7 +133,7 @@ mod compression_fairing_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fallback_gzip() {
|
fn test_fallback_gzip() {
|
||||||
let client = Client::new(rocket()).expect("valid rocket instance");
|
let client = Client::tracked(rocket()).expect("valid rocket instance");
|
||||||
let mut response = client
|
let mut response = client
|
||||||
.get("/")
|
.get("/")
|
||||||
.header(Header::new("Accept-Encoding", "deflate, gzip"))
|
.header(Header::new("Accept-Encoding", "deflate, gzip"))
|
||||||
|
@ -156,7 +156,7 @@ mod compression_fairing_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_does_not_recompress() {
|
fn test_does_not_recompress() {
|
||||||
let client = Client::new(rocket()).expect("valid rocket instance");
|
let client = Client::tracked(rocket()).expect("valid rocket instance");
|
||||||
let mut response = client
|
let mut response = client
|
||||||
.get("/already_encoded")
|
.get("/already_encoded")
|
||||||
.header(Header::new("Accept-Encoding", "deflate, gzip, br"))
|
.header(Header::new("Accept-Encoding", "deflate, gzip, br"))
|
||||||
|
@ -179,7 +179,7 @@ mod compression_fairing_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_does_not_compress_explicit_identity() {
|
fn test_does_not_compress_explicit_identity() {
|
||||||
let client = Client::new(rocket()).expect("valid rocket instance");
|
let client = Client::tracked(rocket()).expect("valid rocket instance");
|
||||||
let mut response = client
|
let mut response = client
|
||||||
.get("/identity")
|
.get("/identity")
|
||||||
.header(Header::new("Accept-Encoding", "deflate, gzip, br"))
|
.header(Header::new("Accept-Encoding", "deflate, gzip, br"))
|
||||||
|
@ -197,7 +197,7 @@ mod compression_fairing_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_does_not_compress_image() {
|
fn test_does_not_compress_image() {
|
||||||
let client = Client::new(rocket()).expect("valid rocket instance");
|
let client = Client::tracked(rocket()).expect("valid rocket instance");
|
||||||
let mut response = client
|
let mut response = client
|
||||||
.get("/image")
|
.get("/image")
|
||||||
.header(Header::new("Accept-Encoding", "deflate, gzip, br"))
|
.header(Header::new("Accept-Encoding", "deflate, gzip, br"))
|
||||||
|
@ -215,7 +215,7 @@ mod compression_fairing_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_ignores_unimplemented_encodings() {
|
fn test_ignores_unimplemented_encodings() {
|
||||||
let client = Client::new(rocket()).expect("valid rocket instance");
|
let client = Client::tracked(rocket()).expect("valid rocket instance");
|
||||||
let mut response = client
|
let mut response = client
|
||||||
.get("/")
|
.get("/")
|
||||||
.header(Header::new("Accept-Encoding", "deflate"))
|
.header(Header::new("Accept-Encoding", "deflate"))
|
||||||
|
@ -233,7 +233,7 @@ mod compression_fairing_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_respects_identity_only() {
|
fn test_respects_identity_only() {
|
||||||
let client = Client::new(rocket()).expect("valid rocket instance");
|
let client = Client::tracked(rocket()).expect("valid rocket instance");
|
||||||
let mut response = client
|
let mut response = client
|
||||||
.get("/")
|
.get("/")
|
||||||
.header(Header::new("Accept-Encoding", "identity"))
|
.header(Header::new("Accept-Encoding", "identity"))
|
||||||
|
@ -251,7 +251,7 @@ mod compression_fairing_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_does_not_compress_custom_exception() {
|
fn test_does_not_compress_custom_exception() {
|
||||||
let client = Client::new(rocket_tar_exception()).expect("valid rocket instance");
|
let client = Client::tracked(rocket_tar_exception()).expect("valid rocket instance");
|
||||||
let mut response = client
|
let mut response = client
|
||||||
.get("/tar")
|
.get("/tar")
|
||||||
.header(Header::new("Accept-Encoding", "deflate, gzip, br"))
|
.header(Header::new("Accept-Encoding", "deflate, gzip, br"))
|
||||||
|
@ -269,7 +269,7 @@ mod compression_fairing_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_compress_custom_removed_exception() {
|
fn test_compress_custom_removed_exception() {
|
||||||
let client = Client::new(rocket_tar_exception()).expect("valid rocket instance");
|
let client = Client::tracked(rocket_tar_exception()).expect("valid rocket instance");
|
||||||
let mut response = client
|
let mut response = client
|
||||||
.get("/image")
|
.get("/image")
|
||||||
.header(Header::new("Accept-Encoding", "deflate, gzip, br"))
|
.header(Header::new("Accept-Encoding", "deflate, gzip, br"))
|
||||||
|
|
|
@ -32,7 +32,7 @@ mod helmet_tests {
|
||||||
macro_rules! dispatch {
|
macro_rules! dispatch {
|
||||||
($helmet:expr, $closure:expr) => {{
|
($helmet:expr, $closure:expr) => {{
|
||||||
let rocket = rocket::ignite().mount("/", routes![hello]).attach($helmet);
|
let rocket = rocket::ignite().mount("/", routes![hello]).attach($helmet);
|
||||||
let client = Client::new(rocket).unwrap();
|
let client = Client::tracked(rocket).unwrap();
|
||||||
let response = client.get("/").dispatch();
|
let response = client.get("/").dispatch();
|
||||||
assert_eq!(response.status(), Status::Ok);
|
assert_eq!(response.status(), Status::Ok);
|
||||||
$closure(response)
|
$closure(response)
|
||||||
|
|
|
@ -69,7 +69,7 @@ mod static_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_static_no_index() {
|
fn test_static_no_index() {
|
||||||
let client = Client::new(rocket()).expect("valid rocket");
|
let client = Client::tracked(rocket()).expect("valid rocket");
|
||||||
assert_all(&client, "no_index", REGULAR_FILES, true);
|
assert_all(&client, "no_index", REGULAR_FILES, true);
|
||||||
assert_all(&client, "no_index", HIDDEN_FILES, false);
|
assert_all(&client, "no_index", HIDDEN_FILES, false);
|
||||||
assert_all(&client, "no_index", INDEXED_DIRECTORIES, false);
|
assert_all(&client, "no_index", INDEXED_DIRECTORIES, false);
|
||||||
|
@ -77,7 +77,7 @@ mod static_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_static_hidden() {
|
fn test_static_hidden() {
|
||||||
let client = Client::new(rocket()).expect("valid rocket");
|
let client = Client::tracked(rocket()).expect("valid rocket");
|
||||||
assert_all(&client, "dots", REGULAR_FILES, true);
|
assert_all(&client, "dots", REGULAR_FILES, true);
|
||||||
assert_all(&client, "dots", HIDDEN_FILES, true);
|
assert_all(&client, "dots", HIDDEN_FILES, true);
|
||||||
assert_all(&client, "dots", INDEXED_DIRECTORIES, false);
|
assert_all(&client, "dots", INDEXED_DIRECTORIES, false);
|
||||||
|
@ -85,7 +85,7 @@ mod static_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_static_index() {
|
fn test_static_index() {
|
||||||
let client = Client::new(rocket()).expect("valid rocket");
|
let client = Client::tracked(rocket()).expect("valid rocket");
|
||||||
assert_all(&client, "index", REGULAR_FILES, true);
|
assert_all(&client, "index", REGULAR_FILES, true);
|
||||||
assert_all(&client, "index", HIDDEN_FILES, false);
|
assert_all(&client, "index", HIDDEN_FILES, false);
|
||||||
assert_all(&client, "index", INDEXED_DIRECTORIES, true);
|
assert_all(&client, "index", INDEXED_DIRECTORIES, true);
|
||||||
|
@ -97,7 +97,7 @@ mod static_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_static_all() {
|
fn test_static_all() {
|
||||||
let client = Client::new(rocket()).expect("valid rocket");
|
let client = Client::tracked(rocket()).expect("valid rocket");
|
||||||
assert_all(&client, "both", REGULAR_FILES, true);
|
assert_all(&client, "both", REGULAR_FILES, true);
|
||||||
assert_all(&client, "both", HIDDEN_FILES, true);
|
assert_all(&client, "both", HIDDEN_FILES, true);
|
||||||
assert_all(&client, "both", INDEXED_DIRECTORIES, true);
|
assert_all(&client, "both", INDEXED_DIRECTORIES, true);
|
||||||
|
@ -129,7 +129,7 @@ mod static_tests {
|
||||||
fn catch_two(a: &RawStr, b: &RawStr) -> String { format!("{}/{}", a, b) }
|
fn catch_two(a: &RawStr, b: &RawStr) -> String { format!("{}/{}", a, b) }
|
||||||
|
|
||||||
let rocket = rocket().mount("/default", routes![catch_one, catch_two]);
|
let rocket = rocket().mount("/default", routes![catch_one, catch_two]);
|
||||||
let client = Client::new(rocket).expect("valid rocket");
|
let client = Client::tracked(rocket).expect("valid rocket");
|
||||||
|
|
||||||
let response = client.get("/default/ireallydontexist").dispatch();
|
let response = client.get("/default/ireallydontexist").dispatch();
|
||||||
assert_eq!(response.status(), Status::Ok);
|
assert_eq!(response.status(), Status::Ok);
|
||||||
|
@ -146,7 +146,7 @@ mod static_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_redirection() {
|
fn test_redirection() {
|
||||||
let client = Client::new(rocket()).expect("valid rocket");
|
let client = Client::tracked(rocket()).expect("valid rocket");
|
||||||
|
|
||||||
// Redirection only happens if enabled, and doesn't affect index behaviour.
|
// Redirection only happens if enabled, and doesn't affect index behaviour.
|
||||||
let response = client.get("/no_index/inner").dispatch();
|
let response = client.get("/no_index/inner").dispatch();
|
||||||
|
|
|
@ -66,7 +66,7 @@ mod templates_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_template_metadata_with_tera() {
|
fn test_template_metadata_with_tera() {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
|
|
||||||
let response = client.get("/tera/txt_test").dispatch();
|
let response = client.get("/tera/txt_test").dispatch();
|
||||||
assert_eq!(response.status(), Status::Ok);
|
assert_eq!(response.status(), Status::Ok);
|
||||||
|
@ -107,7 +107,7 @@ mod templates_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_template_metadata_with_handlebars() {
|
fn test_template_metadata_with_handlebars() {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
|
|
||||||
let response = client.get("/hbs/test").dispatch();
|
let response = client.get("/hbs/test").dispatch();
|
||||||
assert_eq!(response.status(), Status::Ok);
|
assert_eq!(response.status(), Status::Ok);
|
||||||
|
@ -144,7 +144,7 @@ mod templates_tests {
|
||||||
write_file(&reload_path, INITIAL_TEXT);
|
write_file(&reload_path, INITIAL_TEXT);
|
||||||
|
|
||||||
// set up the client. if we can't reload templates, then just quit
|
// set up the client. if we can't reload templates, then just quit
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
let res = client.get("/is_reloading").dispatch();
|
let res = client.get("/is_reloading").dispatch();
|
||||||
if res.status() != Status::Ok {
|
if res.status() != Status::Ok {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -34,7 +34,7 @@ foo!("/hello/<name>", name);
|
||||||
#[test]
|
#[test]
|
||||||
fn test_reexpansion() {
|
fn test_reexpansion() {
|
||||||
let rocket = rocket::ignite().mount("/", routes![easy, hard, hi]);
|
let rocket = rocket::ignite().mount("/", routes![easy, hard, hi]);
|
||||||
let client = Client::new(rocket).unwrap();
|
let client = Client::tracked(rocket).unwrap();
|
||||||
|
|
||||||
let response = client.get("/easy/327").dispatch();
|
let response = client.get("/easy/327").dispatch();
|
||||||
assert_eq!(response.into_string().unwrap(), "easy id: 327");
|
assert_eq!(response.into_string().unwrap(), "easy id: 327");
|
||||||
|
@ -60,7 +60,7 @@ index!(i32);
|
||||||
#[test]
|
#[test]
|
||||||
fn test_index() {
|
fn test_index() {
|
||||||
let rocket = rocket::ignite().mount("/", routes![index]).manage(100i32);
|
let rocket = rocket::ignite().mount("/", routes![index]).manage(100i32);
|
||||||
let client = Client::new(rocket).unwrap();
|
let client = Client::tracked(rocket).unwrap();
|
||||||
|
|
||||||
let response = client.get("/").dispatch();
|
let response = client.get("/").dispatch();
|
||||||
assert_eq!(response.into_string().unwrap(), "Thing: 100");
|
assert_eq!(response.into_string().unwrap(), "Thing: 100");
|
||||||
|
|
|
@ -21,7 +21,7 @@ pub enum Foo<'r> {
|
||||||
|
|
||||||
#[rocket::async_test]
|
#[rocket::async_test]
|
||||||
async fn responder_foo() {
|
async fn responder_foo() {
|
||||||
let client = Client::new(rocket::ignite()).await.expect("valid rocket");
|
let client = Client::tracked(rocket::ignite()).await.expect("valid rocket");
|
||||||
let local_req = client.get("/");
|
let local_req = client.get("/");
|
||||||
let req = local_req.inner();
|
let req = local_req.inner();
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ pub struct Bar<'r> {
|
||||||
|
|
||||||
#[rocket::async_test]
|
#[rocket::async_test]
|
||||||
async fn responder_bar() {
|
async fn responder_bar() {
|
||||||
let client = Client::new(rocket::ignite()).await.expect("valid rocket");
|
let client = Client::tracked(rocket::ignite()).await.expect("valid rocket");
|
||||||
let local_req = client.get("/");
|
let local_req = client.get("/");
|
||||||
let req = local_req.inner();
|
let req = local_req.inner();
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ pub struct Baz {
|
||||||
|
|
||||||
#[rocket::async_test]
|
#[rocket::async_test]
|
||||||
async fn responder_baz() {
|
async fn responder_baz() {
|
||||||
let client = Client::new(rocket::ignite()).await.expect("valid rocket");
|
let client = Client::tracked(rocket::ignite()).await.expect("valid rocket");
|
||||||
let local_req = client.get("/");
|
let local_req = client.get("/");
|
||||||
let req = local_req.inner();
|
let req = local_req.inner();
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ fn simple(simple: Simple) -> String { simple.0 }
|
||||||
#[test]
|
#[test]
|
||||||
fn test_data() {
|
fn test_data() {
|
||||||
let rocket = rocket::ignite().mount("/", routes![form, simple]);
|
let rocket = rocket::ignite().mount("/", routes![form, simple]);
|
||||||
let client = Client::new(rocket).unwrap();
|
let client = Client::tracked(rocket).unwrap();
|
||||||
|
|
||||||
let response = client.post("/f")
|
let response = client.post("/f")
|
||||||
.header(ContentType::Form)
|
.header(ContentType::Form)
|
||||||
|
|
|
@ -37,7 +37,7 @@ fn test_formats() {
|
||||||
.mount("/", routes![json, xml, json_long, msgpack_long, msgpack,
|
.mount("/", routes![json, xml, json_long, msgpack_long, msgpack,
|
||||||
plain, binary, other]);
|
plain, binary, other]);
|
||||||
|
|
||||||
let client = Client::new(rocket).unwrap();
|
let client = Client::tracked(rocket).unwrap();
|
||||||
|
|
||||||
let response = client.post("/").header(ContentType::JSON).dispatch();
|
let response = client.post("/").header(ContentType::JSON).dispatch();
|
||||||
assert_eq!(response.into_string().unwrap(), "json");
|
assert_eq!(response.into_string().unwrap(), "json");
|
||||||
|
@ -83,7 +83,7 @@ fn test_custom_formats() {
|
||||||
let rocket = rocket::ignite()
|
let rocket = rocket::ignite()
|
||||||
.mount("/", routes![get_foo, post_foo, get_bar_baz, put_bar_baz]);
|
.mount("/", routes![get_foo, post_foo, get_bar_baz, put_bar_baz]);
|
||||||
|
|
||||||
let client = Client::new(rocket).unwrap();
|
let client = Client::tracked(rocket).unwrap();
|
||||||
|
|
||||||
let foo_a = Accept::new(&[MediaType::new("application", "foo").into()]);
|
let foo_a = Accept::new(&[MediaType::new("application", "foo").into()]);
|
||||||
let foo_ct = ContentType::new("application", "foo");
|
let foo_ct = ContentType::new("application", "foo");
|
||||||
|
|
|
@ -19,7 +19,7 @@ fn get3(_number: u64) -> &'static str { "3" }
|
||||||
#[test]
|
#[test]
|
||||||
fn test_ranking() {
|
fn test_ranking() {
|
||||||
let rocket = rocket::ignite().mount("/", routes![get0, get1, get2, get3]);
|
let rocket = rocket::ignite().mount("/", routes![get0, get1, get2, get3]);
|
||||||
let client = Client::new(rocket).unwrap();
|
let client = Client::tracked(rocket).unwrap();
|
||||||
|
|
||||||
let response = client.get("/0").dispatch();
|
let response = client.get("/0").dispatch();
|
||||||
assert_eq!(response.into_string().unwrap(), "0");
|
assert_eq!(response.into_string().unwrap(), "0");
|
||||||
|
@ -44,7 +44,7 @@ fn test_rank_collision() {
|
||||||
use rocket::error::LaunchErrorKind;
|
use rocket::error::LaunchErrorKind;
|
||||||
|
|
||||||
let rocket = rocket::ignite().mount("/", routes![get0, get0b]);
|
let rocket = rocket::ignite().mount("/", routes![get0, get0b]);
|
||||||
let client_result = Client::new(rocket);
|
let client_result = Client::tracked(rocket);
|
||||||
match client_result.as_ref().map_err(|e| e.kind()) {
|
match client_result.as_ref().map_err(|e| e.kind()) {
|
||||||
Err(LaunchErrorKind::Collision(..)) => { /* o.k. */ },
|
Err(LaunchErrorKind::Collision(..)) => { /* o.k. */ },
|
||||||
Ok(_) => panic!("client succeeded unexpectedly"),
|
Ok(_) => panic!("client succeeded unexpectedly"),
|
||||||
|
|
|
@ -77,7 +77,7 @@ fn test_full_route() {
|
||||||
.mount("/1", routes![post1])
|
.mount("/1", routes![post1])
|
||||||
.mount("/2", routes![post2]);
|
.mount("/2", routes![post2]);
|
||||||
|
|
||||||
let client = Client::new(rocket).unwrap();
|
let client = Client::tracked(rocket).unwrap();
|
||||||
|
|
||||||
let a = "A%20A";
|
let a = "A%20A";
|
||||||
let name = "Bob%20McDonald";
|
let name = "Bob%20McDonald";
|
||||||
|
|
|
@ -14,9 +14,7 @@ error[E0277]: the trait bound `Header<'_>: From<u8>` is not satisfied
|
||||||
|
|
|
|
||||||
= help: the following implementations were found:
|
= help: the following implementations were found:
|
||||||
<Header<'static> as From<&Cookie<'_>>>
|
<Header<'static> as From<&Cookie<'_>>>
|
||||||
<Header<'static> as From<&CookieCrumb>>
|
|
||||||
<Header<'static> as From<Cookie<'_>>>
|
<Header<'static> as From<Cookie<'_>>>
|
||||||
<Header<'static> as From<CookieCrumb>>
|
|
||||||
= note: required because of the requirements on the impl of `Into<Header<'_>>` for `u8`
|
= note: required because of the requirements on the impl of `Into<Header<'_>>` for `u8`
|
||||||
|
|
||||||
error[E0277]: the trait bound `u8: Responder<'_, '_>` is not satisfied
|
error[E0277]: the trait bound `u8: Responder<'_, '_>` is not satisfied
|
||||||
|
@ -35,9 +33,7 @@ error[E0277]: the trait bound `Header<'_>: From<u8>` is not satisfied
|
||||||
|
|
|
|
||||||
= help: the following implementations were found:
|
= help: the following implementations were found:
|
||||||
<Header<'static> as From<&Cookie<'_>>>
|
<Header<'static> as From<&Cookie<'_>>>
|
||||||
<Header<'static> as From<&CookieCrumb>>
|
|
||||||
<Header<'static> as From<Cookie<'_>>>
|
<Header<'static> as From<Cookie<'_>>>
|
||||||
<Header<'static> as From<CookieCrumb>>
|
|
||||||
= note: required because of the requirements on the impl of `Into<Header<'_>>` for `u8`
|
= note: required because of the requirements on the impl of `Into<Header<'_>>` for `u8`
|
||||||
|
|
||||||
error[E0277]: the trait bound `Header<'_>: From<std::string::String>` is not satisfied
|
error[E0277]: the trait bound `Header<'_>: From<std::string::String>` is not satisfied
|
||||||
|
@ -48,9 +44,7 @@ error[E0277]: the trait bound `Header<'_>: From<std::string::String>` is not sat
|
||||||
|
|
|
|
||||||
= help: the following implementations were found:
|
= help: the following implementations were found:
|
||||||
<Header<'static> as From<&Cookie<'_>>>
|
<Header<'static> as From<&Cookie<'_>>>
|
||||||
<Header<'static> as From<&CookieCrumb>>
|
|
||||||
<Header<'static> as From<Cookie<'_>>>
|
<Header<'static> as From<Cookie<'_>>>
|
||||||
<Header<'static> as From<CookieCrumb>>
|
|
||||||
= note: required because of the requirements on the impl of `Into<Header<'_>>` for `std::string::String`
|
= note: required because of the requirements on the impl of `Into<Header<'_>>` for `std::string::String`
|
||||||
|
|
||||||
error[E0277]: the trait bound `usize: Responder<'_, '_>` is not satisfied
|
error[E0277]: the trait bound `usize: Responder<'_, '_>` is not satisfied
|
||||||
|
|
|
@ -14,9 +14,7 @@ error[E0277]: the trait bound `rocket::http::Header<'_>: std::convert::From<u8>`
|
||||||
|
|
|
|
||||||
= help: the following implementations were found:
|
= help: the following implementations were found:
|
||||||
<rocket::http::Header<'static> as std::convert::From<&rocket::http::Cookie<'_>>>
|
<rocket::http::Header<'static> as std::convert::From<&rocket::http::Cookie<'_>>>
|
||||||
<rocket::http::Header<'static> as std::convert::From<&rocket::http::CookieCrumb>>
|
|
||||||
<rocket::http::Header<'static> as std::convert::From<rocket::http::Cookie<'_>>>
|
<rocket::http::Header<'static> as std::convert::From<rocket::http::Cookie<'_>>>
|
||||||
<rocket::http::Header<'static> as std::convert::From<rocket::http::CookieCrumb>>
|
|
||||||
= note: required because of the requirements on the impl of `std::convert::Into<rocket::http::Header<'_>>` for `u8`
|
= note: required because of the requirements on the impl of `std::convert::Into<rocket::http::Header<'_>>` for `u8`
|
||||||
|
|
||||||
error[E0277]: the trait bound `u8: rocket::response::Responder<'_, '_>` is not satisfied
|
error[E0277]: the trait bound `u8: rocket::response::Responder<'_, '_>` is not satisfied
|
||||||
|
@ -35,9 +33,7 @@ error[E0277]: the trait bound `rocket::http::Header<'_>: std::convert::From<u8>`
|
||||||
|
|
|
|
||||||
= help: the following implementations were found:
|
= help: the following implementations were found:
|
||||||
<rocket::http::Header<'static> as std::convert::From<&rocket::http::Cookie<'_>>>
|
<rocket::http::Header<'static> as std::convert::From<&rocket::http::Cookie<'_>>>
|
||||||
<rocket::http::Header<'static> as std::convert::From<&rocket::http::CookieCrumb>>
|
|
||||||
<rocket::http::Header<'static> as std::convert::From<rocket::http::Cookie<'_>>>
|
<rocket::http::Header<'static> as std::convert::From<rocket::http::Cookie<'_>>>
|
||||||
<rocket::http::Header<'static> as std::convert::From<rocket::http::CookieCrumb>>
|
|
||||||
= note: required because of the requirements on the impl of `std::convert::Into<rocket::http::Header<'_>>` for `u8`
|
= note: required because of the requirements on the impl of `std::convert::Into<rocket::http::Header<'_>>` for `u8`
|
||||||
|
|
||||||
error[E0277]: the trait bound `rocket::http::Header<'_>: std::convert::From<std::string::String>` is not satisfied
|
error[E0277]: the trait bound `rocket::http::Header<'_>: std::convert::From<std::string::String>` is not satisfied
|
||||||
|
@ -48,9 +44,7 @@ error[E0277]: the trait bound `rocket::http::Header<'_>: std::convert::From<std:
|
||||||
|
|
|
|
||||||
= help: the following implementations were found:
|
= help: the following implementations were found:
|
||||||
<rocket::http::Header<'static> as std::convert::From<&rocket::http::Cookie<'_>>>
|
<rocket::http::Header<'static> as std::convert::From<&rocket::http::Cookie<'_>>>
|
||||||
<rocket::http::Header<'static> as std::convert::From<&rocket::http::CookieCrumb>>
|
|
||||||
<rocket::http::Header<'static> as std::convert::From<rocket::http::Cookie<'_>>>
|
<rocket::http::Header<'static> as std::convert::From<rocket::http::Cookie<'_>>>
|
||||||
<rocket::http::Header<'static> as std::convert::From<rocket::http::CookieCrumb>>
|
|
||||||
= note: required because of the requirements on the impl of `std::convert::Into<rocket::http::Header<'_>>` for `std::string::String`
|
= note: required because of the requirements on the impl of `std::convert::Into<rocket::http::Header<'_>>` for `std::string::String`
|
||||||
|
|
||||||
error[E0277]: the trait bound `usize: rocket::response::Responder<'_, '_>` is not satisfied
|
error[E0277]: the trait bound `usize: rocket::response::Responder<'_, '_>` is not satisfied
|
||||||
|
|
|
@ -34,10 +34,11 @@ unicode-xid = "0.2"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
ref-cast = "1.0"
|
ref-cast = "1.0"
|
||||||
uncased = "0.9"
|
uncased = "0.9"
|
||||||
|
parking_lot = "0.11"
|
||||||
|
|
||||||
[dependencies.cookie]
|
[dependencies.cookie]
|
||||||
git = "https://github.com/SergioBenitez/cookie-rs.git"
|
git = "https://github.com/SergioBenitez/cookie-rs.git"
|
||||||
rev = "3795f2e"
|
rev = "9675944"
|
||||||
features = ["percent-encode"]
|
features = ["percent-encode"]
|
||||||
|
|
||||||
[dependencies.pear]
|
[dependencies.pear]
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
|
use parking_lot::Mutex;
|
||||||
|
|
||||||
use crate::Header;
|
use crate::Header;
|
||||||
|
|
||||||
pub use cookie::{Cookie, CookieCrumb, SameSite, Iter};
|
pub use cookie::{Cookie, SameSite, Iter};
|
||||||
#[doc(hidden)] pub use self::key::*;
|
#[doc(hidden)] pub use self::key::*;
|
||||||
|
|
||||||
/// Types and methods to manage a `Key` when private cookies are enabled.
|
/// Types and methods to manage a `Key` when private cookies are enabled.
|
||||||
|
@ -26,21 +28,68 @@ mod key {
|
||||||
|
|
||||||
/// Collection of one or more HTTP cookies.
|
/// Collection of one or more HTTP cookies.
|
||||||
///
|
///
|
||||||
/// The `CookieJar` type allows for retrieval of cookies from an incoming
|
/// `CookieJar` allows for retrieval of cookies from an incoming request. It
|
||||||
/// request as well as modifications to cookies to be reflected by Rocket on
|
/// also tracks modifications (additions and removals) and marks them as
|
||||||
/// outgoing responses.
|
/// pending.
|
||||||
|
///
|
||||||
|
/// # Pending
|
||||||
|
///
|
||||||
|
/// Changes to a `CookieJar` are _not_ visible via the normal [`get()`] and
|
||||||
|
/// [`get_private()`] methods. This is typically the desired effect as a
|
||||||
|
/// `CookieJar` always reflects the cookies in an incoming request. In cases
|
||||||
|
/// where this is not desired, the [`get_pending()`] and
|
||||||
|
/// [`get_private_pending()`] methods are available, which always return the
|
||||||
|
/// latest changes.
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # #[macro_use] extern crate rocket;
|
||||||
|
/// use rocket::http::{CookieJar, Cookie};
|
||||||
|
///
|
||||||
|
/// #[get("/message")]
|
||||||
|
/// fn message(jar: &CookieJar<'_>) {
|
||||||
|
/// jar.add(Cookie::new("message", "hello!"));
|
||||||
|
/// jar.add(Cookie::new("other", "bye!"));
|
||||||
|
///
|
||||||
|
/// // `get()` does not reflect changes.
|
||||||
|
/// assert!(jar.get("other").is_none());
|
||||||
|
/// # assert_eq!(jar.get("message").map(|c| c.value()), Some("hi"));
|
||||||
|
///
|
||||||
|
/// // `get_pending()` does.
|
||||||
|
/// let other_pending = jar.get_pending("other");
|
||||||
|
/// let message_pending = jar.get_pending("message");
|
||||||
|
/// assert_eq!(other_pending.as_ref().map(|c| c.value()), Some("bye!"));
|
||||||
|
/// assert_eq!(message_pending.as_ref().map(|c| c.value()), Some("hello!"));
|
||||||
|
/// # jar.remove(Cookie::named("message"));
|
||||||
|
/// # assert_eq!(jar.get("message").map(|c| c.value()), Some("hi"));
|
||||||
|
/// # assert!(jar.get_pending("message").is_none());
|
||||||
|
/// }
|
||||||
|
/// # fn main() {
|
||||||
|
/// # use rocket::local::blocking::Client;
|
||||||
|
/// # let rocket = rocket::ignite().mount("/", routes![message]);
|
||||||
|
/// # let client = Client::tracked(rocket).unwrap();
|
||||||
|
/// # let response = client.get("/message")
|
||||||
|
/// # .cookie(Cookie::new("message", "hi"))
|
||||||
|
/// # .dispatch();
|
||||||
|
/// #
|
||||||
|
/// # assert!(response.status().class().is_success());
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
///
|
///
|
||||||
/// # Usage
|
/// # Usage
|
||||||
///
|
///
|
||||||
/// A type of `&CookieJar` can be retrieved via its `FromRequest` implementation
|
/// A type of `&CookieJar` can be retrieved via its `FromRequest` implementation
|
||||||
/// as a request guard or via the [`Request::cookies()`] method. Individual
|
/// as a request guard or via the [`Request::cookies()`] method. Individual
|
||||||
/// cookies can be retrieved via the [`get()`] and [`get_private()`] methods.
|
/// cookies can be retrieved via the [`get()`] and [`get_private()`] methods.
|
||||||
/// Cookies can be added or removed via the [`add()`], [`add_private()`],
|
/// Pending changes can be observed via the [`get_pending()`] and
|
||||||
/// [`remove()`], and [`remove_private()`] methods.
|
/// [`get_private_pending()`] methods. Cookies can be added or removed via the
|
||||||
|
/// [`add()`], [`add_private()`], [`remove()`], and [`remove_private()`]
|
||||||
|
/// methods.
|
||||||
///
|
///
|
||||||
/// [`Request::cookies()`]: rocket::Request::cookies()
|
/// [`Request::cookies()`]: rocket::Request::cookies()
|
||||||
/// [`get()`]: #method.get
|
/// [`get()`]: #method.get
|
||||||
/// [`get_private()`]: #method.get_private
|
/// [`get_private()`]: #method.get_private
|
||||||
|
/// [`get_pending()`]: #method.get_pending
|
||||||
|
/// [`get_private_pending()`]: #method.get_private_pending
|
||||||
/// [`add()`]: #method.add
|
/// [`add()`]: #method.add
|
||||||
/// [`add_private()`]: #method.add_private
|
/// [`add_private()`]: #method.add_private
|
||||||
/// [`remove()`]: #method.remove
|
/// [`remove()`]: #method.remove
|
||||||
|
@ -56,8 +105,8 @@ mod key {
|
||||||
/// use rocket::http::CookieJar;
|
/// use rocket::http::CookieJar;
|
||||||
///
|
///
|
||||||
/// #[get("/message")]
|
/// #[get("/message")]
|
||||||
/// fn message(jar: &CookieJar<'_>) -> Option<String> {
|
/// fn message<'a>(jar: &'a CookieJar<'_>) -> Option<&'a str> {
|
||||||
/// jar.get("message").map(|c| format!("Message: {}", c.value()))
|
/// jar.get("message").map(|cookie| cookie.value())
|
||||||
/// }
|
/// }
|
||||||
/// # fn main() { }
|
/// # fn main() { }
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -123,15 +172,43 @@ mod key {
|
||||||
/// is usually done through tools like `openssl`. Using `openssl`, for instance,
|
/// is usually done through tools like `openssl`. Using `openssl`, for instance,
|
||||||
/// a 256-bit base64 key can be generated with the command `openssl rand -base64
|
/// a 256-bit base64 key can be generated with the command `openssl rand -base64
|
||||||
/// 32`.
|
/// 32`.
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct CookieJar<'a> {
|
pub struct CookieJar<'a> {
|
||||||
jar: cookie::CookieJar,
|
jar: cookie::CookieJar,
|
||||||
key: &'a Key,
|
key: &'a Key,
|
||||||
|
ops: Mutex<Vec<Op>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Clone for CookieJar<'a> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
CookieJar {
|
||||||
|
jar: self.jar.clone(),
|
||||||
|
key: self.key,
|
||||||
|
ops: Mutex::new(self.ops.lock().clone()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
enum Op {
|
||||||
|
Add(Cookie<'static>, bool),
|
||||||
|
Remove(Cookie<'static>, bool),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Op {
|
||||||
|
fn cookie(&self) -> &Cookie<'static> {
|
||||||
|
match self {
|
||||||
|
Op::Add(c, _) | Op::Remove(c, _) => c
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> CookieJar<'a> {
|
impl<'a> CookieJar<'a> {
|
||||||
/// Returns a reference to the `Cookie` inside this container with the name
|
/// Returns a reference to the _original_ `Cookie` inside this container
|
||||||
/// `name`. If no such cookie exists, returns `None`.
|
/// with the name `name`. If no such cookie exists, returns `None`.
|
||||||
|
///
|
||||||
|
/// **Note:** This method _does not_ obverse changes made via additions and
|
||||||
|
/// removals to the cookie jar. To observe those changes, use
|
||||||
|
/// [`CookieJar::get_pending()`].
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
|
@ -144,14 +221,18 @@ impl<'a> CookieJar<'a> {
|
||||||
/// let cookie = jar.get("name");
|
/// let cookie = jar.get("name");
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn get(&self, name: &str) -> Option<CookieCrumb> {
|
pub fn get(&self, name: &str) -> Option<&Cookie<'static>> {
|
||||||
self.jar.get(name)
|
self.jar.get(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a reference to the `Cookie` inside this collection with the name
|
/// Retrives the _original_ `Cookie` inside this collection with the name
|
||||||
/// `name` and authenticates and decrypts the cookie's value, returning a
|
/// `name` and authenticates and decrypts the cookie's value. If the cookie
|
||||||
/// `Cookie` with the decrypted value. If the cookie cannot be found, or the
|
/// cannot be found, or the cookie fails to authenticate or decrypt, `None`
|
||||||
/// cookie fails to authenticate or decrypt, `None` is returned.
|
/// is returned.
|
||||||
|
///
|
||||||
|
/// **Note:** This method _does not_ obverse changes made via additions and
|
||||||
|
/// removals to the cookie jar. To observe those changes, use
|
||||||
|
/// [`CookieJar::get_private_pending()`].
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
|
@ -170,6 +251,55 @@ impl<'a> CookieJar<'a> {
|
||||||
self.jar.private(&*self.key).get(name)
|
self.jar.private(&*self.key).get(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a reference to the _original or pending_ `Cookie` inside this
|
||||||
|
/// container with the name `name`. If no such cookie exists, returns
|
||||||
|
/// `None`.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # #[macro_use] extern crate rocket;
|
||||||
|
/// use rocket::http::{Cookie, CookieJar};
|
||||||
|
///
|
||||||
|
/// #[get("/")]
|
||||||
|
/// fn handler(jar: &CookieJar<'_>) {
|
||||||
|
/// let pending_cookie = jar.get_pending("name");
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub fn get_pending(&self, name: &str) -> Option<Cookie<'static>> {
|
||||||
|
let ops = self.ops.lock();
|
||||||
|
for op in ops.iter().rev().filter(|op| op.cookie().name() == name) {
|
||||||
|
match op {
|
||||||
|
Op::Add(c, _) => return Some(c.clone()),
|
||||||
|
Op::Remove(_, _) => return None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
drop(ops);
|
||||||
|
self.get(name).map(|c| c.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Retrives the _original or pending_ `Cookie` inside this collection with
|
||||||
|
/// the name `name` and authenticates and decrypts the cookie's value. If
|
||||||
|
/// the cookie cannot be found, or the cookie fails to authenticate or
|
||||||
|
/// decrypt, `None` is returned.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # #[macro_use] extern crate rocket;
|
||||||
|
/// use rocket::http::{Cookie, CookieJar};
|
||||||
|
///
|
||||||
|
/// #[get("/")]
|
||||||
|
/// fn handler(jar: &CookieJar<'_>) {
|
||||||
|
/// let pending_cookie = jar.get_private_pending("name");
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub fn get_private_pending(&self, name: &str) -> Option<Cookie<'static>> {
|
||||||
|
let cookie = self.get_pending(name)?;
|
||||||
|
self.jar.private(&*self.key).decrypt(cookie)
|
||||||
|
}
|
||||||
|
|
||||||
/// Adds `cookie` to this collection.
|
/// Adds `cookie` to this collection.
|
||||||
///
|
///
|
||||||
/// Unless a value is set for the given property, the following defaults are
|
/// Unless a value is set for the given property, the following defaults are
|
||||||
|
@ -198,7 +328,7 @@ impl<'a> CookieJar<'a> {
|
||||||
/// ```
|
/// ```
|
||||||
pub fn add(&self, mut cookie: Cookie<'static>) {
|
pub fn add(&self, mut cookie: Cookie<'static>) {
|
||||||
Self::set_defaults(&mut cookie);
|
Self::set_defaults(&mut cookie);
|
||||||
self.jar.add(cookie)
|
self.ops.lock().push(Op::Add(cookie, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds `cookie` to the collection. The cookie's value is encrypted with
|
/// Adds `cookie` to the collection. The cookie's value is encrypted with
|
||||||
|
@ -233,7 +363,7 @@ impl<'a> CookieJar<'a> {
|
||||||
#[cfg_attr(nightly, doc(cfg(feature = "secrets")))]
|
#[cfg_attr(nightly, doc(cfg(feature = "secrets")))]
|
||||||
pub fn add_private(&self, mut cookie: Cookie<'static>) {
|
pub fn add_private(&self, mut cookie: Cookie<'static>) {
|
||||||
Self::set_private_defaults(&mut cookie);
|
Self::set_private_defaults(&mut cookie);
|
||||||
self.jar.private(&*self.key).add(cookie)
|
self.ops.lock().push(Op::Add(cookie, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Removes `cookie` from this collection and generates a "removal" cookies
|
/// Removes `cookie` from this collection and generates a "removal" cookies
|
||||||
|
@ -263,7 +393,7 @@ impl<'a> CookieJar<'a> {
|
||||||
cookie.set_path("/");
|
cookie.set_path("/");
|
||||||
}
|
}
|
||||||
|
|
||||||
self.jar.remove(cookie)
|
self.ops.lock().push(Op::Remove(cookie, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Removes the private `cookie` from the collection.
|
/// Removes the private `cookie` from the collection.
|
||||||
|
@ -290,10 +420,14 @@ impl<'a> CookieJar<'a> {
|
||||||
cookie.set_path("/");
|
cookie.set_path("/");
|
||||||
}
|
}
|
||||||
|
|
||||||
self.jar.private(&*self.key).remove(cookie)
|
self.ops.lock().push(Op::Remove(cookie, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an iterator over all of the cookies present in this collection.
|
/// Returns an iterator over all of the _original_ cookies present in this
|
||||||
|
/// collection.
|
||||||
|
///
|
||||||
|
/// **Note:** This method _does not_ obverse changes made via additions and
|
||||||
|
/// removals to the cookie jar.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
|
@ -308,38 +442,64 @@ impl<'a> CookieJar<'a> {
|
||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn iter(&self) -> impl Iterator<Item = CookieCrumb> + '_ {
|
pub fn iter(&self) -> impl Iterator<Item=&Cookie<'static>> {
|
||||||
self.jar.iter()
|
self.jar.iter()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// WARNING: These is unstable! Do not use outside of Rocket!
|
/// WARNING: These are unstable! Do not use outside of Rocket!
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
impl<'a> CookieJar<'a> {
|
impl<'a> CookieJar<'a> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn new(key: &'a Key) -> CookieJar<'a> {
|
pub fn new(key: &'a Key) -> Self {
|
||||||
CookieJar { jar: cookie::CookieJar::new(), key }
|
CookieJar {
|
||||||
|
jar: cookie::CookieJar::new(),
|
||||||
|
key, ops: Mutex::new(Vec::new()),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn from(jar: cookie::CookieJar, key: &'a Key) -> CookieJar<'a> {
|
pub fn from(jar: cookie::CookieJar, key: &'a Key) -> CookieJar<'a> {
|
||||||
CookieJar { jar, key }
|
CookieJar { jar, key, ops: Mutex::new(Vec::new()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Removes all delta cookies.
|
/// Removes all delta cookies.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn reset_delta(&self) {
|
pub fn reset_delta(&self) {
|
||||||
self.jar.reset_delta()
|
self.ops.lock().clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// TODO: This could be faster by just returning the cookies directly via
|
||||||
|
/// an ordered hash-set of sorts.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn delta(&self) -> cookie::Delta {
|
pub fn take_delta_jar(&self) -> cookie::CookieJar {
|
||||||
self.jar.delta()
|
let ops = std::mem::replace(&mut *self.ops.lock(), Vec::new());
|
||||||
|
let mut jar = cookie::CookieJar::new();
|
||||||
|
|
||||||
|
for op in ops {
|
||||||
|
match op {
|
||||||
|
Op::Add(c, false) => jar.add(c),
|
||||||
|
#[cfg(feature = "private-cookies")]
|
||||||
|
Op::Add(c, true) => jar.private_mut(self.key).add(c),
|
||||||
|
Op::Remove(mut c, _) => {
|
||||||
|
if self.jar.get(c.name()).is_some() {
|
||||||
|
c.make_removal();
|
||||||
|
jar.add(c);
|
||||||
|
} else {
|
||||||
|
jar.remove(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[allow(unreachable_patterns)]
|
||||||
|
_ => unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
jar
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds an original `cookie` to this collection.
|
/// Adds an original `cookie` to this collection.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn add_original(&self, cookie: Cookie<'static>) {
|
pub fn add_original(&mut self, cookie: Cookie<'static>) {
|
||||||
self.jar.add_original(cookie)
|
self.jar.add_original(cookie)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,8 +507,8 @@ impl<'a> CookieJar<'a> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[cfg(feature = "private-cookies")]
|
#[cfg(feature = "private-cookies")]
|
||||||
#[cfg_attr(nightly, doc(cfg(feature = "secrets")))]
|
#[cfg_attr(nightly, doc(cfg(feature = "secrets")))]
|
||||||
pub fn add_original_private(&self, cookie: Cookie<'static>) {
|
pub fn add_original_private(&mut self, cookie: Cookie<'static>) {
|
||||||
self.jar.private(&*self.key).add_original(cookie);
|
self.jar.private_mut(&*self.key).add_original(cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// For each property mentioned below, this method checks if there is a
|
/// For each property mentioned below, this method checks if there is a
|
||||||
|
@ -400,7 +560,16 @@ impl<'a> CookieJar<'a> {
|
||||||
|
|
||||||
impl fmt::Debug for CookieJar<'_> {
|
impl fmt::Debug for CookieJar<'_> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
self.jar.fmt(f)
|
let pending: Vec<_> = self.ops.lock()
|
||||||
|
.iter()
|
||||||
|
.map(|c| c.cookie())
|
||||||
|
.cloned()
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
f.debug_struct("CookieJar")
|
||||||
|
.field("original", &self.jar)
|
||||||
|
.field("pending", &pending)
|
||||||
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -415,15 +584,3 @@ impl From<&Cookie<'_>> for Header<'static> {
|
||||||
Header::new("Set-Cookie", cookie.encoded().to_string())
|
Header::new("Set-Cookie", cookie.encoded().to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<CookieCrumb> for Header<'static> {
|
|
||||||
fn from(cookie: CookieCrumb) -> Header<'static> {
|
|
||||||
Header::new("Set-Cookie", cookie.encoded().to_string())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&CookieCrumb> for Header<'static> {
|
|
||||||
fn from(cookie: &CookieCrumb) -> Header<'static> {
|
|
||||||
Header::new("Set-Cookie", cookie.encoded().to_string())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -74,4 +74,4 @@ pub use crate::status::{Status, StatusClass};
|
||||||
pub use crate::header::{Header, HeaderMap};
|
pub use crate::header::{Header, HeaderMap};
|
||||||
pub use crate::raw_str::RawStr;
|
pub use crate::raw_str::RawStr;
|
||||||
pub use crate::media_type::MediaType;
|
pub use crate::media_type::MediaType;
|
||||||
pub use crate::cookies::{Cookie, CookieJar, CookieCrumb, SameSite};
|
pub use crate::cookies::{Cookie, CookieJar, SameSite};
|
||||||
|
|
|
@ -40,11 +40,7 @@ async-trait = "0.1"
|
||||||
ref-cast = "1.0"
|
ref-cast = "1.0"
|
||||||
atomic = "0.5"
|
atomic = "0.5"
|
||||||
ubyte = "0.10"
|
ubyte = "0.10"
|
||||||
|
parking_lot = "0.11"
|
||||||
[dependencies.cookie]
|
|
||||||
git = "https://github.com/SergioBenitez/cookie-rs.git"
|
|
||||||
rev = "3795f2e"
|
|
||||||
features = ["percent-encode"]
|
|
||||||
|
|
||||||
[dependencies.pear]
|
[dependencies.pear]
|
||||||
git = "https://github.com/SergioBenitez/Pear.git"
|
git = "https://github.com/SergioBenitez/Pear.git"
|
||||||
|
|
|
@ -19,25 +19,25 @@ use bencher::Bencher;
|
||||||
use rocket::http::{Accept, ContentType};
|
use rocket::http::{Accept, ContentType};
|
||||||
|
|
||||||
fn accept_format(b: &mut Bencher) {
|
fn accept_format(b: &mut Bencher) {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
let request = client.get("/").header(Accept::JSON);
|
let request = client.get("/").header(Accept::JSON);
|
||||||
b.iter(|| { request.clone().dispatch(); });
|
b.iter(|| { request.clone().dispatch(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wrong_accept_format(b: &mut Bencher) {
|
fn wrong_accept_format(b: &mut Bencher) {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
let request = client.get("/").header(Accept::HTML);
|
let request = client.get("/").header(Accept::HTML);
|
||||||
b.iter(|| { request.clone().dispatch(); });
|
b.iter(|| { request.clone().dispatch(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
fn content_type_format(b: &mut Bencher) {
|
fn content_type_format(b: &mut Bencher) {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
let request = client.post("/").header(ContentType::JSON);
|
let request = client.post("/").header(ContentType::JSON);
|
||||||
b.iter(|| { request.clone().dispatch(); });
|
b.iter(|| { request.clone().dispatch(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wrong_content_type_format(b: &mut Bencher) {
|
fn wrong_content_type_format(b: &mut Bencher) {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
let request = client.post("/").header(ContentType::Plain);
|
let request = client.post("/").header(ContentType::Plain);
|
||||||
b.iter(|| { request.clone().dispatch(); });
|
b.iter(|| { request.clone().dispatch(); });
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ use rocket::local::blocking::Client;
|
||||||
use rocket::http::{Accept, ContentType};
|
use rocket::http::{Accept, ContentType};
|
||||||
|
|
||||||
fn accept_format(b: &mut Bencher) {
|
fn accept_format(b: &mut Bencher) {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
let requests = vec![
|
let requests = vec![
|
||||||
client.get("/").header(Accept::JSON),
|
client.get("/").header(Accept::JSON),
|
||||||
client.get("/").header(Accept::HTML),
|
client.get("/").header(Accept::HTML),
|
||||||
|
@ -48,7 +48,7 @@ fn accept_format(b: &mut Bencher) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn content_type_format(b: &mut Bencher) {
|
fn content_type_format(b: &mut Bencher) {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
let requests = vec![
|
let requests = vec![
|
||||||
client.post("/").header(ContentType::JSON),
|
client.post("/").header(ContentType::JSON),
|
||||||
client.post("/").header(ContentType::HTML),
|
client.post("/").header(ContentType::HTML),
|
||||||
|
|
|
@ -44,7 +44,7 @@ use bencher::Bencher;
|
||||||
use rocket::local::blocking::Client;
|
use rocket::local::blocking::Client;
|
||||||
|
|
||||||
fn bench_hello_world(b: &mut Bencher) {
|
fn bench_hello_world(b: &mut Bencher) {
|
||||||
let client = Client::new(hello_world_rocket()).unwrap();
|
let client = Client::tracked(hello_world_rocket()).unwrap();
|
||||||
|
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
client.get("/").dispatch();
|
client.get("/").dispatch();
|
||||||
|
@ -52,7 +52,7 @@ fn bench_hello_world(b: &mut Bencher) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bench_single_get_index(b: &mut Bencher) {
|
fn bench_single_get_index(b: &mut Bencher) {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
|
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
client.get("/").dispatch();
|
client.get("/").dispatch();
|
||||||
|
@ -60,7 +60,7 @@ fn bench_single_get_index(b: &mut Bencher) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bench_get_put_post_index(b: &mut Bencher) {
|
fn bench_get_put_post_index(b: &mut Bencher) {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
|
|
||||||
// Hold all of the requests we're going to make during the benchmark.
|
// Hold all of the requests we're going to make during the benchmark.
|
||||||
let mut requests = vec![];
|
let mut requests = vec![];
|
||||||
|
@ -76,7 +76,7 @@ fn bench_get_put_post_index(b: &mut Bencher) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bench_dynamic(b: &mut Bencher) {
|
fn bench_dynamic(b: &mut Bencher) {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
|
|
||||||
// Hold all of the requests we're going to make during the benchmark.
|
// Hold all of the requests we're going to make during the benchmark.
|
||||||
let mut requests = vec![];
|
let mut requests = vec![];
|
||||||
|
@ -92,7 +92,7 @@ fn bench_dynamic(b: &mut Bencher) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bench_simple_routing(b: &mut Bencher) {
|
fn bench_simple_routing(b: &mut Bencher) {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
|
|
||||||
// Hold all of the requests we're going to make during the benchmark.
|
// Hold all of the requests we're going to make during the benchmark.
|
||||||
let mut requests = vec![];
|
let mut requests = vec![];
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
|
use parking_lot::RwLock;
|
||||||
|
|
||||||
use crate::local::asynchronous::{LocalRequest, LocalResponse};
|
use crate::local::asynchronous::{LocalRequest, LocalResponse};
|
||||||
use crate::rocket::{Rocket, Cargo};
|
use crate::rocket::{Rocket, Cargo};
|
||||||
use crate::http::{private::cookie, Method};
|
use crate::http::{private::cookie, Method};
|
||||||
|
@ -11,7 +13,7 @@ use crate::error::LaunchError;
|
||||||
/// For the `blocking` version, see
|
/// For the `blocking` version, see
|
||||||
/// [`blocking::Client`](crate::local::blocking::Client).
|
/// [`blocking::Client`](crate::local::blocking::Client).
|
||||||
///
|
///
|
||||||
/// ## Multithreaded Synchronization Pitfalls
|
/// ## Multithreaded Tracking Synchronization Pitfalls
|
||||||
///
|
///
|
||||||
/// Unlike its [`blocking`](crate::local::blocking) variant, this `async`
|
/// Unlike its [`blocking`](crate::local::blocking) variant, this `async`
|
||||||
/// `Client` implements `Sync`. However, using it in a multithreaded environment
|
/// `Client` implements `Sync`. However, using it in a multithreaded environment
|
||||||
|
@ -19,11 +21,14 @@ use crate::error::LaunchError;
|
||||||
/// This is because while cookie modifications are serialized, the ordering
|
/// This is because while cookie modifications are serialized, the ordering
|
||||||
/// depends on the ordering of request dispatch.
|
/// depends on the ordering of request dispatch.
|
||||||
///
|
///
|
||||||
/// If possible, refrain from sharing a single instance of `Client` across
|
/// If possible, refrain from sharing a single instance of a tracking `Client`
|
||||||
/// multiple threads. Instead, prefer to create a unique instance of `Client`
|
/// across multiple threads. Instead, prefer to create a unique instance of
|
||||||
/// per thread. If this is not possible, ensure that you are not depending on
|
/// `Client` per thread. If this is not possible, ensure that you are not
|
||||||
/// the ordering of cookie modifications or have arranged for request dispatch
|
/// depending on the ordering of cookie modifications or have arranged for
|
||||||
/// to occur in a deterministic manner.
|
/// request dispatch to occur in a deterministic manner.
|
||||||
|
///
|
||||||
|
/// Alternatively, use an untracked client, which does not suffer from these
|
||||||
|
/// pitfalls.
|
||||||
///
|
///
|
||||||
/// ## Example
|
/// ## Example
|
||||||
///
|
///
|
||||||
|
@ -35,7 +40,7 @@ use crate::error::LaunchError;
|
||||||
///
|
///
|
||||||
/// # rocket::async_test(async {
|
/// # rocket::async_test(async {
|
||||||
/// let rocket = rocket::ignite();
|
/// let rocket = rocket::ignite();
|
||||||
/// let client = Client::new(rocket).await.expect("valid rocket");
|
/// let client = Client::tracked(rocket).await.expect("valid rocket");
|
||||||
/// let response = client.post("/")
|
/// let response = client.post("/")
|
||||||
/// .body("Hello, world!")
|
/// .body("Hello, world!")
|
||||||
/// .dispatch()
|
/// .dispatch()
|
||||||
|
@ -44,8 +49,8 @@ use crate::error::LaunchError;
|
||||||
/// ```
|
/// ```
|
||||||
pub struct Client {
|
pub struct Client {
|
||||||
cargo: Cargo,
|
cargo: Cargo,
|
||||||
|
cookies: RwLock<cookie::CookieJar>,
|
||||||
pub(in super) tracked: bool,
|
pub(in super) tracked: bool,
|
||||||
pub(in super) cookies: cookie::CookieJar,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Client {
|
impl Client {
|
||||||
|
@ -55,8 +60,8 @@ impl Client {
|
||||||
) -> Result<Client, LaunchError> {
|
) -> Result<Client, LaunchError> {
|
||||||
rocket.prelaunch_check().await?;
|
rocket.prelaunch_check().await?;
|
||||||
let cargo = rocket.into_cargo().await;
|
let cargo = rocket.into_cargo().await;
|
||||||
|
let cookies = RwLock::new(cookie::CookieJar::new());
|
||||||
Ok(Client { cargo, tracked, cookies: cookie::CookieJar::new() })
|
Ok(Client { cargo, tracked, cookies })
|
||||||
}
|
}
|
||||||
|
|
||||||
// WARNING: This is unstable! Do not use this method outside of Rocket!
|
// WARNING: This is unstable! Do not use this method outside of Rocket!
|
||||||
|
@ -66,7 +71,7 @@ impl Client {
|
||||||
{
|
{
|
||||||
crate::async_test(async {
|
crate::async_test(async {
|
||||||
let rocket = crate::ignite();
|
let rocket = crate::ignite();
|
||||||
let client = Client::new(rocket).await.expect("valid rocket");
|
let client = Client::untracked(rocket).await.expect("valid rocket");
|
||||||
let request = client.get("/");
|
let request = client.get("/");
|
||||||
let response = request.clone().dispatch().await;
|
let response = request.clone().dispatch().await;
|
||||||
f(&client, request, response)
|
f(&client, request, response)
|
||||||
|
@ -79,8 +84,17 @@ impl Client {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn _cookies(&self) -> &cookie::CookieJar {
|
pub(crate) fn _with_raw_cookies<F, T>(&self, f: F) -> T
|
||||||
&self.cookies
|
where F: FnOnce(&cookie::CookieJar) -> T
|
||||||
|
{
|
||||||
|
f(&*self.cookies.read())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub(crate) fn _with_raw_cookies_mut<F, T>(&self, f: F) -> T
|
||||||
|
where F: FnOnce(&mut cookie::CookieJar) -> T
|
||||||
|
{
|
||||||
|
f(&mut *self.cookies.write())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
|
|
@ -19,7 +19,7 @@ use super::{Client, LocalResponse};
|
||||||
/// use rocket::http::{ContentType, Cookie};
|
/// use rocket::http::{ContentType, Cookie};
|
||||||
///
|
///
|
||||||
/// # rocket::async_test(async {
|
/// # rocket::async_test(async {
|
||||||
/// let client = Client::new(rocket::ignite()).await.expect("valid rocket");
|
/// let client = Client::tracked(rocket::ignite()).await.expect("valid rocket");
|
||||||
/// let req = client.post("/")
|
/// let req = client.post("/")
|
||||||
/// .header(ContentType::JSON)
|
/// .header(ContentType::JSON)
|
||||||
/// .remote("127.0.0.1:8000".parse().unwrap())
|
/// .remote("127.0.0.1:8000".parse().unwrap())
|
||||||
|
@ -45,13 +45,15 @@ impl<'c> LocalRequest<'c> {
|
||||||
// We try to validate the URI now so that the inner `Request` contains a
|
// We try to validate the URI now so that the inner `Request` contains a
|
||||||
// valid URI. If it doesn't, we set a dummy one.
|
// valid URI. If it doesn't, we set a dummy one.
|
||||||
let origin = Origin::parse(&uri).unwrap_or_else(|_| Origin::dummy());
|
let origin = Origin::parse(&uri).unwrap_or_else(|_| Origin::dummy());
|
||||||
let request = Request::new(client.rocket(), method, origin.into_owned());
|
let mut request = Request::new(client.rocket(), method, origin.into_owned());
|
||||||
|
|
||||||
// Add any cookies we know about.
|
// Add any cookies we know about.
|
||||||
if client.tracked {
|
if client.tracked {
|
||||||
for crumb in client.cookies.iter() {
|
client._with_raw_cookies(|jar| {
|
||||||
request.cookies().add_original(crumb.into_cookie());
|
for cookie in jar.iter() {
|
||||||
|
request.cookies_mut().add_original(cookie.clone());
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalRequest { client, request, uri, data: vec![] }
|
LocalRequest { client, request, uri, data: vec![] }
|
||||||
|
@ -92,18 +94,19 @@ impl<'c> LocalRequest<'c> {
|
||||||
// If the client is tracking cookies, updates the internal cookie jar
|
// If the client is tracking cookies, updates the internal cookie jar
|
||||||
// with the changes reflected by `response`.
|
// with the changes reflected by `response`.
|
||||||
if self.client.tracked {
|
if self.client.tracked {
|
||||||
let jar = &self.client.cookies;
|
self.client._with_raw_cookies_mut(|jar| {
|
||||||
let current_time = time::OffsetDateTime::now_utc();
|
let current_time = time::OffsetDateTime::now_utc();
|
||||||
for cookie in response.cookies().iter() {
|
for cookie in response.cookies().iter() {
|
||||||
if let Some(expires) = cookie.expires() {
|
if let Some(expires) = cookie.expires() {
|
||||||
if expires <= current_time {
|
if expires <= current_time {
|
||||||
jar.force_remove(&cookie);
|
jar.force_remove(cookie);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
jar.add(cookie.into_cookie());
|
jar.add_original(cookie.clone());
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
response
|
response
|
||||||
|
|
|
@ -36,7 +36,7 @@ use crate::{Request, Response};
|
||||||
///
|
///
|
||||||
/// # async fn read_body_manually() -> io::Result<()> {
|
/// # async fn read_body_manually() -> io::Result<()> {
|
||||||
/// // Dispatch a `GET /` request.
|
/// // Dispatch a `GET /` request.
|
||||||
/// let client = Client::new(rocket()).await.expect("valid rocket");
|
/// let client = Client::tracked(rocket()).await.expect("valid rocket");
|
||||||
/// let mut response = client.get("/").dispatch().await;
|
/// let mut response = client.get("/").dispatch().await;
|
||||||
///
|
///
|
||||||
/// // Check metadata validity.
|
/// // Check metadata validity.
|
||||||
|
@ -89,9 +89,9 @@ impl<'c> LocalResponse<'c> {
|
||||||
|
|
||||||
async move {
|
async move {
|
||||||
let response: Response<'c> = f(request).await;
|
let response: Response<'c> = f(request).await;
|
||||||
let cookies = CookieJar::new(request.state.config.secret_key());
|
let mut cookies = CookieJar::new(request.state.config.secret_key());
|
||||||
for cookie in response.cookies() {
|
for cookie in response.cookies() {
|
||||||
cookies.add(cookie.into_owned());
|
cookies.add_original(cookie.into_owned());
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalResponse { cookies, _request: boxed_req, response, }
|
LocalResponse { cookies, _request: boxed_req, response, }
|
||||||
|
|
|
@ -20,7 +20,7 @@ use crate::http::Method;
|
||||||
/// use rocket::local::blocking::Client;
|
/// use rocket::local::blocking::Client;
|
||||||
///
|
///
|
||||||
/// let rocket = rocket::ignite();
|
/// let rocket = rocket::ignite();
|
||||||
/// let client = Client::new(rocket).expect("valid rocket");
|
/// let client = Client::tracked(rocket).expect("valid rocket");
|
||||||
/// let response = client.post("/")
|
/// let response = client.post("/")
|
||||||
/// .body("Hello, world!")
|
/// .body("Hello, world!")
|
||||||
/// .dispatch();
|
/// .dispatch();
|
||||||
|
@ -49,7 +49,7 @@ impl Client {
|
||||||
where F: FnOnce(&Self, LocalRequest<'_>, LocalResponse<'_>) -> T + Send
|
where F: FnOnce(&Self, LocalRequest<'_>, LocalResponse<'_>) -> T + Send
|
||||||
{
|
{
|
||||||
let rocket = crate::ignite();
|
let rocket = crate::ignite();
|
||||||
let client = Client::new(rocket).expect("valid rocket");
|
let client = Client::untracked(rocket).expect("valid rocket");
|
||||||
let request = client.get("/");
|
let request = client.get("/");
|
||||||
let response = request.clone().dispatch();
|
let response = request.clone().dispatch();
|
||||||
f(&client, request, response)
|
f(&client, request, response)
|
||||||
|
@ -68,8 +68,10 @@ impl Client {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn _cookies(&self) -> &cookie::CookieJar {
|
pub(crate) fn _with_raw_cookies<F, T>(&self, f: F) -> T
|
||||||
self.inner._cookies()
|
where F: FnOnce(&crate::http::private::cookie::CookieJar) -> T
|
||||||
|
{
|
||||||
|
self.inner._with_raw_cookies(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
|
|
@ -17,7 +17,7 @@ use super::{Client, LocalResponse};
|
||||||
/// use rocket::local::blocking::{Client, LocalRequest};
|
/// use rocket::local::blocking::{Client, LocalRequest};
|
||||||
/// use rocket::http::{ContentType, Cookie};
|
/// use rocket::http::{ContentType, Cookie};
|
||||||
///
|
///
|
||||||
/// let client = Client::new(rocket::ignite()).expect("valid rocket");
|
/// let client = Client::tracked(rocket::ignite()).expect("valid rocket");
|
||||||
/// let req = client.post("/")
|
/// let req = client.post("/")
|
||||||
/// .header(ContentType::JSON)
|
/// .header(ContentType::JSON)
|
||||||
/// .remote("127.0.0.1:8000".parse().unwrap())
|
/// .remote("127.0.0.1:8000".parse().unwrap())
|
||||||
|
|
|
@ -33,7 +33,7 @@ use super::Client;
|
||||||
///
|
///
|
||||||
/// # fn read_body_manually() -> io::Result<()> {
|
/// # fn read_body_manually() -> io::Result<()> {
|
||||||
/// // Dispatch a `GET /` request.
|
/// // Dispatch a `GET /` request.
|
||||||
/// let client = Client::new(rocket()).expect("valid rocket");
|
/// let client = Client::tracked(rocket()).expect("valid rocket");
|
||||||
/// let mut response = client.get("/").dispatch();
|
/// let mut response = client.get("/").dispatch();
|
||||||
///
|
///
|
||||||
/// // Check metadata validity.
|
/// // Check metadata validity.
|
||||||
|
|
|
@ -41,22 +41,19 @@ macro_rules! req_method {
|
||||||
macro_rules! pub_client_impl {
|
macro_rules! pub_client_impl {
|
||||||
($import:literal $(@$prefix:tt $suffix:tt)?) =>
|
($import:literal $(@$prefix:tt $suffix:tt)?) =>
|
||||||
{
|
{
|
||||||
/// Construct a new `Client` from an instance of `Rocket` with cookie
|
/// Construct a new `Client` from an instance of `Rocket` _with_ cookie
|
||||||
/// tracking.
|
/// tracking. This is typically the desired mode of operation for testing.
|
||||||
///
|
///
|
||||||
/// # Cookie Tracking
|
/// # Cookie Tracking
|
||||||
///
|
///
|
||||||
/// By default, a `Client` propagates cookie changes made by responses
|
/// With cookie tracking enabled, a `Client` propagates cookie changes made
|
||||||
/// to previously dispatched requests. In other words, if a previously
|
/// by responses to previously dispatched requests. In other words,
|
||||||
/// dispatched request resulted in a response that adds a cookie, any
|
/// succeeding requests reflect changes (additions and removals) made by any
|
||||||
/// future requests will contain the new cookies. Similarly, cookies
|
/// prior responses.
|
||||||
/// removed by a response won't be propagated further.
|
|
||||||
///
|
///
|
||||||
/// This is typically the desired mode of operation for a `Client` as it
|
/// Cookie tracking requires synchronization between dispatches. **As such,
|
||||||
/// removes the burden of manually tracking cookies. Under some
|
/// cookie tracking _should not_ be enabled if a local client is being used
|
||||||
/// circumstances, however, disabling tracking may be desired. The
|
/// to serve requests on multiple threads.**
|
||||||
/// [`untracked()`](Client::untracked()) method creates a `Client` that
|
|
||||||
/// _will not_ track cookies.
|
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
///
|
///
|
||||||
|
@ -67,10 +64,10 @@ macro_rules! pub_client_impl {
|
||||||
#[doc = $import]
|
#[doc = $import]
|
||||||
///
|
///
|
||||||
/// let rocket = rocket::ignite();
|
/// let rocket = rocket::ignite();
|
||||||
/// let client = Client::new(rocket);
|
/// let client = Client::tracked(rocket);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub $($prefix)? fn new(rocket: Rocket) -> Result<Self, LaunchError> {
|
pub $($prefix)? fn tracked(rocket: Rocket) -> Result<Self, LaunchError> {
|
||||||
Self::_new(rocket, true) $(.$suffix)?
|
Self::_new(rocket, true) $(.$suffix)?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,8 +76,9 @@ macro_rules! pub_client_impl {
|
||||||
///
|
///
|
||||||
/// # Cookie Tracking
|
/// # Cookie Tracking
|
||||||
///
|
///
|
||||||
/// Unlike the [`new()`](Client::new()) constructor, a `Client` returned
|
/// Unlike the [`tracked()`](Client::tracked()) constructor, a `Client`
|
||||||
/// from this method _does not_ automatically propagate cookie changes.
|
/// returned from this method _does not_ automatically propagate cookie
|
||||||
|
/// changes and thus requires no synchronization between dispatches.
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
///
|
///
|
||||||
|
@ -94,7 +92,16 @@ macro_rules! pub_client_impl {
|
||||||
/// let client = Client::untracked(rocket);
|
/// let client = Client::untracked(rocket);
|
||||||
/// ```
|
/// ```
|
||||||
pub $($prefix)? fn untracked(rocket: Rocket) -> Result<Self, LaunchError> {
|
pub $($prefix)? fn untracked(rocket: Rocket) -> Result<Self, LaunchError> {
|
||||||
Self::_new(rocket, true) $(.$suffix)?
|
Self::_new(rocket, false) $(.$suffix)?
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Deprecated alias to [`Client::tracked()`].
|
||||||
|
#[deprecated(
|
||||||
|
since = "0.5",
|
||||||
|
note = "choose between `Client::untracked()` and `Client::tracked()`"
|
||||||
|
)]
|
||||||
|
pub $($prefix)? fn new(rocket: Rocket) -> Result<Self, LaunchError> {
|
||||||
|
Self::tracked(rocket) $(.$suffix)?
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a reference to the `Rocket` this client is creating requests
|
/// Returns a reference to the `Rocket` this client is creating requests
|
||||||
|
@ -153,7 +160,8 @@ macro_rules! pub_client_impl {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn cookies(&self) -> crate::http::CookieJar<'_> {
|
pub fn cookies(&self) -> crate::http::CookieJar<'_> {
|
||||||
let key = self.rocket().config.secret_key();
|
let key = self.rocket().config.secret_key();
|
||||||
crate::http::CookieJar::from(self._cookies().clone(), key)
|
let jar = self._with_raw_cookies(|jar| jar.clone());
|
||||||
|
crate::http::CookieJar::from(jar, key)
|
||||||
}
|
}
|
||||||
|
|
||||||
req_method!($import, "GET", get, Method::Get);
|
req_method!($import, "GET", get, Method::Get);
|
||||||
|
|
|
@ -55,7 +55,7 @@
|
||||||
//! fn test_hello_world_blocking() {
|
//! fn test_hello_world_blocking() {
|
||||||
//! // Construct a client to use for dispatching requests.
|
//! // Construct a client to use for dispatching requests.
|
||||||
//! use rocket::local::blocking::Client;
|
//! use rocket::local::blocking::Client;
|
||||||
//! let client = Client::new(super::rocket())
|
//! let client = Client::tracked(super::rocket())
|
||||||
//! .expect("valid `Rocket`");
|
//! .expect("valid `Rocket`");
|
||||||
//!
|
//!
|
||||||
//! // Dispatch a request to 'GET /' and validate the response.
|
//! // Dispatch a request to 'GET /' and validate the response.
|
||||||
|
@ -68,7 +68,7 @@
|
||||||
//! async fn test_hello_world_async() {
|
//! async fn test_hello_world_async() {
|
||||||
//! // Construct a client to use for dispatching requests.
|
//! // Construct a client to use for dispatching requests.
|
||||||
//! use rocket::local::asynchronous::Client;
|
//! use rocket::local::asynchronous::Client;
|
||||||
//! let client = Client::new(super::rocket()).await
|
//! let client = Client::tracked(super::rocket()).await
|
||||||
//! .expect("valid `Rocket`");
|
//! .expect("valid `Rocket`");
|
||||||
//!
|
//!
|
||||||
//! // Dispatch a request to 'GET /' and validate the response.
|
//! // Dispatch a request to 'GET /' and validate the response.
|
||||||
|
@ -91,7 +91,7 @@
|
||||||
//!
|
//!
|
||||||
//! **Usage**
|
//! **Usage**
|
||||||
//!
|
//!
|
||||||
//! A `Client` is constructed via the [`new()`] ([`async` `new()`]) or
|
//! A `Client` is constructed via the [`tracked()`] ([`async` `tracked()`]) or
|
||||||
//! [`untracked()`] ([`async` `untracked()`]) methods from an already
|
//! [`untracked()`] ([`async` `untracked()`]) methods from an already
|
||||||
//! constructed `Rocket` instance. Once a value of `Client` has been
|
//! constructed `Rocket` instance. Once a value of `Client` has been
|
||||||
//! constructed, [`get()`], [`put()`], [`post()`], and so on ([`async` `get()`],
|
//! constructed, [`get()`], [`put()`], [`post()`], and so on ([`async` `get()`],
|
||||||
|
@ -100,7 +100,7 @@
|
||||||
//!
|
//!
|
||||||
//! **Cookie Tracking**
|
//! **Cookie Tracking**
|
||||||
//!
|
//!
|
||||||
//! A `Client` constructed using `new()` propagates cookie changes made by
|
//! A `Client` constructed using `tracked()` propagates cookie changes made by
|
||||||
//! responses to previously dispatched requests. In other words, if a previously
|
//! responses to previously dispatched requests. In other words, if a previously
|
||||||
//! dispatched request resulted in a response that adds a cookie, any future
|
//! dispatched request resulted in a response that adds a cookie, any future
|
||||||
//! requests will contain that cookie. Similarly, cookies removed by a response
|
//! requests will contain that cookie. Similarly, cookies removed by a response
|
||||||
|
@ -117,9 +117,9 @@
|
||||||
//! [`LocalRequest`]: blocking::LocalRequest
|
//! [`LocalRequest`]: blocking::LocalRequest
|
||||||
//! [`async` `LocalRequest`]: asynchronous::LocalRequest
|
//! [`async` `LocalRequest`]: asynchronous::LocalRequest
|
||||||
//!
|
//!
|
||||||
//! [`new()`]: blocking::Client::new()
|
//! [`tracked()`]: blocking::Client::tracked()
|
||||||
//! [`untracked()`]: blocking::Client::untracked()
|
//! [`untracked()`]: blocking::Client::untracked()
|
||||||
//! [`async` `new()`]: asynchronous::Client::new()
|
//! [`async` `tracked()`]: asynchronous::Client::tracked()
|
||||||
//! [`async` `untracked()`]: asynchronous::Client::untracked()
|
//! [`async` `untracked()`]: asynchronous::Client::untracked()
|
||||||
//!
|
//!
|
||||||
//! [`get()`]: blocking::Client::get()
|
//! [`get()`]: blocking::Client::get()
|
||||||
|
|
|
@ -111,8 +111,8 @@ macro_rules! pub_request_impl {
|
||||||
/// # });
|
/// # });
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn cookie(self, cookie: crate::http::Cookie<'_>) -> Self {
|
pub fn cookie(mut self, cookie: crate::http::Cookie<'_>) -> Self {
|
||||||
self._request().cookies().add_original(cookie.into_owned());
|
self._request_mut().cookies_mut().add_original(cookie.into_owned());
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,11 +131,11 @@ macro_rules! pub_request_impl {
|
||||||
/// # });
|
/// # });
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn cookies<'a, C>(self, cookies: C) -> Self
|
pub fn cookies<'a, C>(mut self, cookies: C) -> Self
|
||||||
where C: IntoIterator<Item = crate::http::Cookie<'a>>
|
where C: IntoIterator<Item = crate::http::Cookie<'a>>
|
||||||
{
|
{
|
||||||
for cookie in cookies {
|
for cookie in cookies {
|
||||||
self._request().cookies().add_original(cookie.into_owned());
|
self._request_mut().cookies_mut().add_original(cookie.into_owned());
|
||||||
}
|
}
|
||||||
|
|
||||||
self
|
self
|
||||||
|
@ -161,8 +161,8 @@ macro_rules! pub_request_impl {
|
||||||
#[cfg(feature = "secrets")]
|
#[cfg(feature = "secrets")]
|
||||||
#[cfg_attr(nightly, doc(cfg(feature = "secrets")))]
|
#[cfg_attr(nightly, doc(cfg(feature = "secrets")))]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn private_cookie(self, cookie: crate::http::Cookie<'static>) -> Self {
|
pub fn private_cookie(mut self, cookie: crate::http::Cookie<'static>) -> Self {
|
||||||
self._request().cookies().add_original_private(cookie);
|
self._request_mut().cookies_mut().add_original_private(cookie);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -832,6 +832,10 @@ impl<'r> Request<'r> {
|
||||||
self.method.store(method, Ordering::Release)
|
self.method.store(method, Ordering::Release)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn cookies_mut(&mut self) -> &mut CookieJar<'r> {
|
||||||
|
&mut self.state.cookies
|
||||||
|
}
|
||||||
|
|
||||||
/// Convert from Hyper types into a Rocket Request.
|
/// Convert from Hyper types into a Rocket Request.
|
||||||
pub(crate) fn from_hyp(
|
pub(crate) fn from_hyp(
|
||||||
rocket: &'r Rocket,
|
rocket: &'r Rocket,
|
||||||
|
|
|
@ -182,7 +182,6 @@ impl<R> Flash<R> {
|
||||||
|
|
||||||
Cookie::build(FLASH_COOKIE_NAME, content)
|
Cookie::build(FLASH_COOKIE_NAME, content)
|
||||||
.max_age(Duration::minutes(5))
|
.max_age(Duration::minutes(5))
|
||||||
.path("/")
|
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -215,8 +214,7 @@ impl<'a, 'r> Flash<&'a Request<'r>> {
|
||||||
fn clear_cookie_if_needed(&self) {
|
fn clear_cookie_if_needed(&self) {
|
||||||
// Remove the cookie if it hasn't already been removed.
|
// Remove the cookie if it hasn't already been removed.
|
||||||
if !self.consumed.swap(true, Ordering::Relaxed) {
|
if !self.consumed.swap(true, Ordering::Relaxed) {
|
||||||
let cookie = Cookie::build(FLASH_COOKIE_NAME, "").path("/").finish();
|
self.inner.cookies().remove(Cookie::named(FLASH_COOKIE_NAME));
|
||||||
self.inner.cookies().remove(cookie);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -731,7 +731,7 @@ impl<'r> Response<'r> {
|
||||||
self.status = Some(Status::new(code, reason));
|
self.status = Some(Status::new(code, reason));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a vector of the cookies set in `self` as identified by the
|
/// Returns an iterator over the cookies in `self` as identified by the
|
||||||
/// `Set-Cookie` header. Malformed cookies are skipped.
|
/// `Set-Cookie` header. Malformed cookies are skipped.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
|
|
|
@ -50,7 +50,7 @@ impl<'r, R> Created<R> {
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// # let rocket = rocket::ignite().mount("/", routes![create]);
|
/// # let rocket = rocket::ignite().mount("/", routes![create]);
|
||||||
/// # let client = Client::new(rocket).unwrap();
|
/// # let client = Client::tracked(rocket).unwrap();
|
||||||
/// let response = client.get("/").dispatch();
|
/// let response = client.get("/").dispatch();
|
||||||
///
|
///
|
||||||
/// let loc = response.headers().get_one("Location");
|
/// let loc = response.headers().get_one("Location");
|
||||||
|
@ -79,7 +79,7 @@ impl<'r, R> Created<R> {
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// # let rocket = rocket::ignite().mount("/", routes![create]);
|
/// # let rocket = rocket::ignite().mount("/", routes![create]);
|
||||||
/// # let client = Client::new(rocket).unwrap();
|
/// # let client = Client::tracked(rocket).unwrap();
|
||||||
/// let response = client.get("/").dispatch();
|
/// let response = client.get("/").dispatch();
|
||||||
///
|
///
|
||||||
/// let loc = response.headers().get_one("Location");
|
/// let loc = response.headers().get_one("Location");
|
||||||
|
@ -112,7 +112,7 @@ impl<'r, R> Created<R> {
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// # let rocket = rocket::ignite().mount("/", routes![create]);
|
/// # let rocket = rocket::ignite().mount("/", routes![create]);
|
||||||
/// # let client = Client::new(rocket).unwrap();
|
/// # let client = Client::tracked(rocket).unwrap();
|
||||||
/// let response = client.get("/").dispatch();
|
/// let response = client.get("/").dispatch();
|
||||||
///
|
///
|
||||||
/// let loc = response.headers().get_one("Location");
|
/// let loc = response.headers().get_one("Location");
|
||||||
|
|
|
@ -347,7 +347,8 @@ impl Rocket {
|
||||||
request._set_method(Method::Get);
|
request._set_method(Method::Get);
|
||||||
|
|
||||||
// Return early so we don't set cookies twice.
|
// Return early so we don't set cookies twice.
|
||||||
let try_next: BoxFuture<'_, _> = Box::pin(self.route_and_process(request, data));
|
let try_next: BoxFuture<'_, _> =
|
||||||
|
Box::pin(self.route_and_process(request, data));
|
||||||
return try_next.await;
|
return try_next.await;
|
||||||
} else {
|
} else {
|
||||||
// No match was found and it can't be autohandled. 404.
|
// No match was found and it can't be autohandled. 404.
|
||||||
|
@ -359,8 +360,9 @@ impl Rocket {
|
||||||
|
|
||||||
// Set the cookies. Note that error responses will only include
|
// Set the cookies. Note that error responses will only include
|
||||||
// cookies set by the error handler. See `handle_error` for more.
|
// cookies set by the error handler. See `handle_error` for more.
|
||||||
for crumb in request.cookies().delta() {
|
let delta_jar = request.cookies().take_delta_jar();
|
||||||
response.adjoin_header(crumb)
|
for cookie in delta_jar.delta() {
|
||||||
|
response.adjoin_header(cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
response
|
response
|
||||||
|
|
|
@ -19,7 +19,7 @@ mod test_absolute_uris_okay {
|
||||||
#[test]
|
#[test]
|
||||||
fn redirect_works() {
|
fn redirect_works() {
|
||||||
let rocket = rocket::ignite().mount("/", routes![google, redirect]);
|
let rocket = rocket::ignite().mount("/", routes![google, redirect]);
|
||||||
let client = Client::new(rocket).unwrap();
|
let client = Client::tracked(rocket).unwrap();
|
||||||
|
|
||||||
let response = client.get("/google").dispatch();
|
let response = client.get("/google").dispatch();
|
||||||
let location = response.headers().get_one("Location");
|
let location = response.headers().get_one("Location");
|
||||||
|
|
|
@ -25,11 +25,11 @@ mod tests {
|
||||||
let rocket = rocket::ignite()
|
let rocket = rocket::ignite()
|
||||||
.mount("/", routes![index])
|
.mount("/", routes![index])
|
||||||
.register(catchers![not_found])
|
.register(catchers![not_found])
|
||||||
.attach(AdHoc::on_request("Add Fairing Cookie", |req, _| Box::pin(async move {
|
.attach(AdHoc::on_request("Add Cookie", |req, _| Box::pin(async move {
|
||||||
req.cookies().add(Cookie::new("fairing", "woo"));
|
req.cookies().add(Cookie::new("fairing", "woo"));
|
||||||
})));
|
})));
|
||||||
|
|
||||||
let client = Client::new(rocket).unwrap();
|
let client = Client::tracked(rocket).unwrap();
|
||||||
|
|
||||||
// Check that the index returns the `index` and `fairing` cookie.
|
// Check that the index returns the `index` and `fairing` cookie.
|
||||||
let response = client.get("/").dispatch();
|
let response = client.get("/").dispatch();
|
||||||
|
|
|
@ -20,7 +20,7 @@ mod conditionally_set_server_header {
|
||||||
#[test]
|
#[test]
|
||||||
fn do_not_overwrite_server_header() {
|
fn do_not_overwrite_server_header() {
|
||||||
let rocket = rocket::ignite().mount("/", routes![do_not_overwrite, use_default]);
|
let rocket = rocket::ignite().mount("/", routes![do_not_overwrite, use_default]);
|
||||||
let client = Client::new(rocket).unwrap();
|
let client = Client::tracked(rocket).unwrap();
|
||||||
|
|
||||||
let response = client.get("/do_not_overwrite").dispatch();
|
let response = client.get("/do_not_overwrite").dispatch();
|
||||||
let server = response.headers().get_one("Server");
|
let server = response.headers().get_one("Server");
|
||||||
|
|
|
@ -46,7 +46,7 @@ fn test_derive_reexports() {
|
||||||
use rocket::local::blocking::Client;
|
use rocket::local::blocking::Client;
|
||||||
|
|
||||||
let rocket = rocket::ignite().mount("/", routes![index, number]);
|
let rocket = rocket::ignite().mount("/", routes![index, number]);
|
||||||
let client = Client::new(rocket).unwrap();
|
let client = Client::tracked(rocket).unwrap();
|
||||||
|
|
||||||
let response = client.get("/").dispatch();
|
let response = client.get("/").dispatch();
|
||||||
assert_eq!(response.into_string().unwrap(), "hello");
|
assert_eq!(response.into_string().unwrap(), "hello");
|
||||||
|
|
|
@ -40,7 +40,7 @@ mod fairing_before_head_strip {
|
||||||
})
|
})
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let client = Client::new(rocket).unwrap();
|
let client = Client::tracked(rocket).unwrap();
|
||||||
let response = client.head("/").dispatch();
|
let response = client.head("/").dispatch();
|
||||||
assert_eq!(response.status(), Status::Ok);
|
assert_eq!(response.status(), Status::Ok);
|
||||||
assert!(response.body().is_none());
|
assert!(response.body().is_none());
|
||||||
|
@ -71,7 +71,7 @@ mod fairing_before_head_strip {
|
||||||
})
|
})
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let client = Client::new(rocket).unwrap();
|
let client = Client::tracked(rocket).unwrap();
|
||||||
let response = client.head("/").dispatch();
|
let response = client.head("/").dispatch();
|
||||||
assert_eq!(response.status(), Status::Ok);
|
assert_eq!(response.status(), Status::Ok);
|
||||||
assert!(response.body().is_none());
|
assert!(response.body().is_none());
|
||||||
|
|
|
@ -28,7 +28,7 @@ mod flash_lazy_remove_tests {
|
||||||
fn test() {
|
fn test() {
|
||||||
use super::*;
|
use super::*;
|
||||||
let r = rocket::ignite().mount("/", routes![set, unused, used]);
|
let r = rocket::ignite().mount("/", routes![set, unused, used]);
|
||||||
let client = Client::new(r).unwrap();
|
let client = Client::tracked(r).unwrap();
|
||||||
|
|
||||||
// Ensure the cookie's not there at first.
|
// Ensure the cookie's not there at first.
|
||||||
let response = client.get("/unused").dispatch();
|
let response = client.get("/unused").dispatch();
|
||||||
|
|
|
@ -20,7 +20,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn method_eval() {
|
fn method_eval() {
|
||||||
let client = Client::new(rocket::ignite().mount("/", routes![bug])).unwrap();
|
let client = Client::tracked(rocket::ignite().mount("/", routes![bug])).unwrap();
|
||||||
let response = client.post("/")
|
let response = client.post("/")
|
||||||
.header(ContentType::Form)
|
.header(ContentType::Form)
|
||||||
.body("_method=patch&form_data=Form+data")
|
.body("_method=patch&form_data=Form+data")
|
||||||
|
@ -31,7 +31,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn get_passes_through() {
|
fn get_passes_through() {
|
||||||
let client = Client::new(rocket::ignite().mount("/", routes![bug])).unwrap();
|
let client = Client::tracked(rocket::ignite().mount("/", routes![bug])).unwrap();
|
||||||
let response = client.get("/")
|
let response = client.get("/")
|
||||||
.header(ContentType::Form)
|
.header(ContentType::Form)
|
||||||
.body("_method=patch&form_data=Form+data")
|
.body("_method=patch&form_data=Form+data")
|
||||||
|
|
|
@ -19,7 +19,7 @@ mod tests {
|
||||||
use rocket::http::Status;
|
use rocket::http::Status;
|
||||||
|
|
||||||
fn check_decoding(raw: &str, decoded: &str) {
|
fn check_decoding(raw: &str, decoded: &str) {
|
||||||
let client = Client::new(rocket::ignite().mount("/", routes![bug])).unwrap();
|
let client = Client::tracked(rocket::ignite().mount("/", routes![bug])).unwrap();
|
||||||
let response = client.post("/")
|
let response = client.post("/")
|
||||||
.header(ContentType::Form)
|
.header(ContentType::Form)
|
||||||
.body(format!("form_data={}", raw))
|
.body(format!("form_data={}", raw))
|
||||||
|
|
|
@ -30,7 +30,7 @@ mod head_handling_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn auto_head() {
|
fn auto_head() {
|
||||||
let client = Client::new(rocket::ignite().mount("/", routes())).unwrap();
|
let client = Client::tracked(rocket::ignite().mount("/", routes())).unwrap();
|
||||||
let response = client.head("/").dispatch();
|
let response = client.head("/").dispatch();
|
||||||
|
|
||||||
let content_type: Vec<_> = response.headers().get("Content-Type").collect();
|
let content_type: Vec<_> = response.headers().get("Content-Type").collect();
|
||||||
|
@ -46,7 +46,7 @@ mod head_handling_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn user_head() {
|
fn user_head() {
|
||||||
let client = Client::new(rocket::ignite().mount("/", routes())).unwrap();
|
let client = Client::tracked(rocket::ignite().mount("/", routes())).unwrap();
|
||||||
let response = client.head("/other").dispatch();
|
let response = client.head("/other").dispatch();
|
||||||
|
|
||||||
let content_type: Vec<_> = response.headers().get("Content-Type").collect();
|
let content_type: Vec<_> = response.headers().get("Content-Type").collect();
|
||||||
|
|
|
@ -29,7 +29,7 @@ mod limits_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn large_enough() {
|
fn large_enough() {
|
||||||
let client = Client::new(rocket_with_forms_limit(128)).unwrap();
|
let client = Client::tracked(rocket_with_forms_limit(128)).unwrap();
|
||||||
let response = client.post("/")
|
let response = client.post("/")
|
||||||
.body("value=Hello+world")
|
.body("value=Hello+world")
|
||||||
.header(ContentType::Form)
|
.header(ContentType::Form)
|
||||||
|
@ -40,7 +40,7 @@ mod limits_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn just_large_enough() {
|
fn just_large_enough() {
|
||||||
let client = Client::new(rocket_with_forms_limit(17)).unwrap();
|
let client = Client::tracked(rocket_with_forms_limit(17)).unwrap();
|
||||||
let response = client.post("/")
|
let response = client.post("/")
|
||||||
.body("value=Hello+world")
|
.body("value=Hello+world")
|
||||||
.header(ContentType::Form)
|
.header(ContentType::Form)
|
||||||
|
@ -51,7 +51,7 @@ mod limits_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn much_too_small() {
|
fn much_too_small() {
|
||||||
let client = Client::new(rocket_with_forms_limit(4)).unwrap();
|
let client = Client::tracked(rocket_with_forms_limit(4)).unwrap();
|
||||||
let response = client.post("/")
|
let response = client.post("/")
|
||||||
.body("value=Hello+world")
|
.body("value=Hello+world")
|
||||||
.header(ContentType::Form)
|
.header(ContentType::Form)
|
||||||
|
@ -62,7 +62,7 @@ mod limits_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn contracted() {
|
fn contracted() {
|
||||||
let client = Client::new(rocket_with_forms_limit(10)).unwrap();
|
let client = Client::tracked(rocket_with_forms_limit(10)).unwrap();
|
||||||
let response = client.post("/")
|
let response = client.post("/")
|
||||||
.body("value=Hello+world")
|
.body("value=Hello+world")
|
||||||
.header(ContentType::Form)
|
.header(ContentType::Form)
|
||||||
|
|
|
@ -54,7 +54,7 @@ mod local_request_content_type_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn has_no_ct() {
|
fn has_no_ct() {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
|
|
||||||
let req = client.post("/");
|
let req = client.post("/");
|
||||||
assert_eq!(req.clone().dispatch().into_string(), Some("Absent".to_string()));
|
assert_eq!(req.clone().dispatch().into_string(), Some("Absent".to_string()));
|
||||||
|
@ -69,7 +69,7 @@ mod local_request_content_type_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn has_ct() {
|
fn has_ct() {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
|
|
||||||
let req = client.post("/").header(ContentType::JSON);
|
let req = client.post("/").header(ContentType::JSON);
|
||||||
assert_eq!(req.clone().dispatch().into_string(), Some("Present".to_string()));
|
assert_eq!(req.clone().dispatch().into_string(), Some("Present".to_string()));
|
||||||
|
|
|
@ -20,7 +20,7 @@ mod private_cookies {
|
||||||
fn private_cookie_is_returned() {
|
fn private_cookie_is_returned() {
|
||||||
let rocket = rocket::ignite().mount("/", routes![return_private_cookie]);
|
let rocket = rocket::ignite().mount("/", routes![return_private_cookie]);
|
||||||
|
|
||||||
let client = Client::new(rocket).unwrap();
|
let client = Client::tracked(rocket).unwrap();
|
||||||
let req = client.get("/").private_cookie(Cookie::new("cookie_name", "cookie_value"));
|
let req = client.get("/").private_cookie(Cookie::new("cookie_name", "cookie_value"));
|
||||||
let response = req.dispatch();
|
let response = req.dispatch();
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ mod private_cookies {
|
||||||
fn regular_cookie_is_not_returned() {
|
fn regular_cookie_is_not_returned() {
|
||||||
let rocket = rocket::ignite().mount("/", routes![return_private_cookie]);
|
let rocket = rocket::ignite().mount("/", routes![return_private_cookie]);
|
||||||
|
|
||||||
let client = Client::new(rocket).unwrap();
|
let client = Client::tracked(rocket).unwrap();
|
||||||
let req = client.get("/").cookie(Cookie::new("cookie_name", "cookie_value"));
|
let req = client.get("/").cookie(Cookie::new("cookie_name", "cookie_value"));
|
||||||
let response = req.dispatch();
|
let response = req.dispatch();
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ mod many_cookie_jars_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_mutli_add() {
|
fn test_mutli_add() {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
let response = client.post("/").dispatch();
|
let response = client.post("/").dispatch();
|
||||||
let cookies = response.cookies();
|
let cookies = response.cookies();
|
||||||
assert_eq!(cookies.iter().count(), 2);
|
assert_eq!(cookies.iter().count(), 2);
|
||||||
|
@ -38,7 +38,7 @@ mod many_cookie_jars_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_mutli_get() {
|
fn test_mutli_get() {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
let response = client.get("/")
|
let response = client.get("/")
|
||||||
.cookie(Cookie::new("a", "a_val"))
|
.cookie(Cookie::new("a", "a_val"))
|
||||||
.cookie(Cookie::new("b", "hi!"))
|
.cookie(Cookie::new("b", "hi!"))
|
||||||
|
|
|
@ -30,7 +30,7 @@ mod mapped_base_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn only_prefix() {
|
fn only_prefix() {
|
||||||
let client = Client::new(super::rocket()).unwrap();
|
let client = Client::tracked(super::rocket()).unwrap();
|
||||||
|
|
||||||
let response = client.get("/a/b/3").dispatch();
|
let response = client.get("/a/b/3").dispatch();
|
||||||
assert_eq!(response.into_string().unwrap(), "3");
|
assert_eq!(response.into_string().unwrap(), "3");
|
||||||
|
@ -44,7 +44,7 @@ mod mapped_base_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn prefix_and_base() {
|
fn prefix_and_base() {
|
||||||
let client = Client::new(super::rocket()).unwrap();
|
let client = Client::tracked(super::rocket()).unwrap();
|
||||||
|
|
||||||
let response = client.get("/foo/a/b/23").dispatch();
|
let response = client.get("/foo/a/b/23").dispatch();
|
||||||
assert_eq!(response.into_string().unwrap(), "23");
|
assert_eq!(response.into_string().unwrap(), "23");
|
||||||
|
|
|
@ -46,7 +46,7 @@ mod nested_fairing_attaches_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_counts() {
|
fn test_counts() {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
let response = client.get("/").dispatch();
|
let response = client.get("/").dispatch();
|
||||||
assert_eq!(response.into_string(), Some("1, 1".into()));
|
assert_eq!(response.into_string(), Some("1, 1".into()));
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ mod tests {
|
||||||
|
|
||||||
macro_rules! check_dispatch {
|
macro_rules! check_dispatch {
|
||||||
($mount:expr, $ct:expr, $body:expr) => (
|
($mount:expr, $ct:expr, $body:expr) => (
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
let mut req = client.post($mount);
|
let mut req = client.post($mount);
|
||||||
let ct: Option<ContentType> = $ct;
|
let ct: Option<ContentType> = $ct;
|
||||||
if let Some(ct) = ct {
|
if let Some(ct) = ct {
|
||||||
|
|
|
@ -14,9 +14,8 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn error_catcher_redirect() {
|
fn error_catcher_redirect() {
|
||||||
let client = Client::new(rocket::ignite().register(catchers![not_found])).unwrap();
|
let client = Client::tracked(rocket::ignite().register(catchers![not_found])).unwrap();
|
||||||
let response = client.get("/unknown").dispatch();
|
let response = client.get("/unknown").dispatch();
|
||||||
println!("Response:\n{:?}", response);
|
|
||||||
|
|
||||||
let location: Vec<_> = response.headers().get("location").collect();
|
let location: Vec<_> = response.headers().get("location").collect();
|
||||||
assert_eq!(response.status(), Status::SeeOther);
|
assert_eq!(response.status(), Status::SeeOther);
|
||||||
|
|
|
@ -24,7 +24,7 @@ mod route_guard_tests {
|
||||||
.mount("/first", routes![files])
|
.mount("/first", routes![files])
|
||||||
.mount("/second", routes![files]);
|
.mount("/second", routes![files]);
|
||||||
|
|
||||||
let client = Client::new(rocket).unwrap();
|
let client = Client::tracked(rocket).unwrap();
|
||||||
assert_path(&client, "/first/some/path");
|
assert_path(&client, "/first/some/path");
|
||||||
assert_path(&client, "/second/some/path");
|
assert_path(&client, "/second/some/path");
|
||||||
assert_path(&client, "/first/second/b/c");
|
assert_path(&client, "/first/second/b/c");
|
||||||
|
|
|
@ -36,7 +36,7 @@ mod tests {
|
||||||
let rocket = rocket::ignite()
|
let rocket = rocket::ignite()
|
||||||
.mount("/", routes![test, two, one_two, none, dual])
|
.mount("/", routes![test, two, one_two, none, dual])
|
||||||
.mount("/point", routes![test, two, one_two, dual]);
|
.mount("/point", routes![test, two, one_two, dual]);
|
||||||
let client = Client::new(rocket).unwrap();
|
let client = Client::tracked(rocket).unwrap();
|
||||||
|
|
||||||
// We construct a path that matches each of the routes above. We ensure the
|
// We construct a path that matches each of the routes above. We ensure the
|
||||||
// prefix is stripped, confirming that dynamic segments are working.
|
// prefix is stripped, confirming that dynamic segments are working.
|
||||||
|
|
|
@ -26,7 +26,7 @@ mod strict_and_lenient_forms_tests {
|
||||||
const FIELD_VALUE: &str = "just_some_value";
|
const FIELD_VALUE: &str = "just_some_value";
|
||||||
|
|
||||||
fn client() -> Client {
|
fn client() -> Client {
|
||||||
Client::new(rocket::ignite().mount("/", routes![strict, lenient])).unwrap()
|
Client::tracked(rocket::ignite().mount("/", routes![strict, lenient])).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -3,7 +3,7 @@ use rocket::local::blocking::Client;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_local_request_clone_soundness() {
|
fn test_local_request_clone_soundness() {
|
||||||
let client = Client::new(rocket::ignite()).unwrap();
|
let client = Client::tracked(rocket::ignite()).unwrap();
|
||||||
|
|
||||||
// creates two LocalRequest instances that shouldn't share the same req
|
// creates two LocalRequest instances that shouldn't share the same req
|
||||||
let r1 = client.get("/").header(Header::new("key", "val1"));
|
let r1 = client.get("/").header(Header::new("key", "val1"));
|
||||||
|
|
|
@ -33,7 +33,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn uri_percent_encoding_redirect() {
|
fn uri_percent_encoding_redirect() {
|
||||||
let expected_location = vec!["/hello/John%5B%5D%7C%5C%25@%5E"];
|
let expected_location = vec!["/hello/John%5B%5D%7C%5C%25@%5E"];
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
|
|
||||||
let response = client.get("/raw").dispatch();
|
let response = client.get("/raw").dispatch();
|
||||||
let location: Vec<_> = response.headers().get("location").collect();
|
let location: Vec<_> = response.headers().get("location").collect();
|
||||||
|
@ -48,7 +48,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn uri_percent_encoding_get() {
|
fn uri_percent_encoding_get() {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
let name = Uri::percent_encode(NAME);
|
let name = Uri::percent_encode(NAME);
|
||||||
let response = client.get(format!("/hello/{}", name)).dispatch();
|
let response = client.get(format!("/hello/{}", name)).dispatch();
|
||||||
assert_eq!(response.status(), Status::Ok);
|
assert_eq!(response.status(), Status::Ok);
|
||||||
|
|
|
@ -62,7 +62,7 @@ pub fn test_config(environment: Environment) {
|
||||||
}))
|
}))
|
||||||
.mount("/", routes![check_config]);
|
.mount("/", routes![check_config]);
|
||||||
|
|
||||||
let client = Client::new(rocket).unwrap();
|
let client = Client::tracked(rocket).unwrap();
|
||||||
let response = client.get("/check_config").dispatch();
|
let response = client.get("/check_config").dispatch();
|
||||||
assert_eq!(response.status(), Status::Ok);
|
assert_eq!(response.status(), Status::Ok);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use rocket::local::blocking::Client;
|
||||||
fn test<H>(method: Method, uri: &str, header: H, status: Status, body: String)
|
fn test<H>(method: Method, uri: &str, header: H, status: Status, body: String)
|
||||||
where H: Into<Header<'static>>
|
where H: Into<Header<'static>>
|
||||||
{
|
{
|
||||||
let client = Client::new(super::rocket()).unwrap();
|
let client = Client::tracked(super::rocket()).unwrap();
|
||||||
let response = client.req(method, uri).header(header).dispatch();
|
let response = client.req(method, uri).header(header).dispatch();
|
||||||
assert_eq!(response.status(), status);
|
assert_eq!(response.status(), status);
|
||||||
assert_eq!(response.into_string(), Some(body));
|
assert_eq!(response.into_string(), Some(body));
|
||||||
|
|
|
@ -7,7 +7,7 @@ use rocket_contrib::templates::Template;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_submit() {
|
fn test_submit() {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
let response = client.post("/submit")
|
let response = client.post("/submit")
|
||||||
.header(ContentType::Form)
|
.header(ContentType::Form)
|
||||||
.body("message=Hello from Rocket!")
|
.body("message=Hello from Rocket!")
|
||||||
|
@ -24,7 +24,7 @@ fn test_submit() {
|
||||||
|
|
||||||
fn test_body(optional_cookie: Option<Cookie<'static>>, expected_body: String) {
|
fn test_body(optional_cookie: Option<Cookie<'static>>, expected_body: String) {
|
||||||
// Attach a cookie if one is given.
|
// Attach a cookie if one is given.
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
let response = match optional_cookie {
|
let response = match optional_cookie {
|
||||||
Some(cookie) => client.get("/").cookie(cookie).dispatch(),
|
Some(cookie) => client.get("/").cookie(cookie).dispatch(),
|
||||||
None => client.get("/").dispatch(),
|
None => client.get("/").dispatch(),
|
||||||
|
@ -36,7 +36,7 @@ fn test_body(optional_cookie: Option<Cookie<'static>>, expected_body: String) {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_index() {
|
fn test_index() {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
|
|
||||||
// Render the template with an empty context.
|
// Render the template with an empty context.
|
||||||
let mut context: HashMap<&str, &str> = HashMap::new();
|
let mut context: HashMap<&str, &str> = HashMap::new();
|
||||||
|
|
|
@ -3,7 +3,7 @@ use rocket::http::Status;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_hello() {
|
fn test_hello() {
|
||||||
let client = Client::new(super::rocket()).unwrap();
|
let client = Client::tracked(super::rocket()).unwrap();
|
||||||
|
|
||||||
let (name, age) = ("Arthur", 42);
|
let (name, age) = ("Arthur", 42);
|
||||||
let uri = format!("/hello/{}/{}", name, age);
|
let uri = format!("/hello/{}/{}", name, age);
|
||||||
|
@ -15,7 +15,7 @@ fn test_hello() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn forced_error_and_default_catcher() {
|
fn forced_error_and_default_catcher() {
|
||||||
let client = Client::new(super::rocket()).unwrap();
|
let client = Client::tracked(super::rocket()).unwrap();
|
||||||
|
|
||||||
let request = client.get("/404");
|
let request = client.get("/404");
|
||||||
let expected = super::not_found(request.inner());
|
let expected = super::not_found(request.inner());
|
||||||
|
@ -44,7 +44,7 @@ fn forced_error_and_default_catcher() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_hello_invalid_age() {
|
fn test_hello_invalid_age() {
|
||||||
let client = Client::new(super::rocket()).unwrap();
|
let client = Client::tracked(super::rocket()).unwrap();
|
||||||
|
|
||||||
for &(name, age) in &[("Ford", -129), ("Trillian", 128)] {
|
for &(name, age) in &[("Ford", -129), ("Trillian", 128)] {
|
||||||
let request = client.get(format!("/hello/{}/{}", name, age));
|
let request = client.get(format!("/hello/{}/{}", name, age));
|
||||||
|
|
|
@ -3,14 +3,14 @@ use rocket::local::blocking::Client;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rewrite_get_put() {
|
fn rewrite_get_put() {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
let response = client.get("/").dispatch();
|
let response = client.get("/").dispatch();
|
||||||
assert_eq!(response.into_string(), Some("Hello, fairings!".into()));
|
assert_eq!(response.into_string(), Some("Hello, fairings!".into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn counts() {
|
fn counts() {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
|
|
||||||
// Issue 1 GET request.
|
// Issue 1 GET request.
|
||||||
client.get("/").dispatch();
|
client.get("/").dispatch();
|
||||||
|
@ -30,7 +30,7 @@ fn counts() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn token() {
|
fn token() {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
|
|
||||||
// Ensure the token is '123', which is what we have in `Rocket.toml`.
|
// Ensure the token is '123', which is what we have in `Rocket.toml`.
|
||||||
let res = client.get("/token").dispatch();
|
let res = client.get("/token").dispatch();
|
||||||
|
|
|
@ -42,7 +42,7 @@ macro_rules! assert_valid_raw_form {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_good_forms() {
|
fn test_good_forms() {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
let mut input = FormInput {
|
let mut input = FormInput {
|
||||||
checkbox: true,
|
checkbox: true,
|
||||||
number: 310,
|
number: 310,
|
||||||
|
@ -121,7 +121,7 @@ macro_rules! assert_invalid_raw_form {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn check_semantically_invalid_forms() {
|
fn check_semantically_invalid_forms() {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
let mut form_vals = ["true", "1", "a", "hi", "hey", "b"];
|
let mut form_vals = ["true", "1", "a", "hi", "hey", "b"];
|
||||||
|
|
||||||
form_vals[0] = "not true";
|
form_vals[0] = "not true";
|
||||||
|
@ -177,7 +177,7 @@ fn check_semantically_invalid_forms() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn check_structurally_invalid_forms() {
|
fn check_structurally_invalid_forms() {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
assert_invalid_raw_form!(&client, "==&&&&&&==");
|
assert_invalid_raw_form!(&client, "==&&&&&&==");
|
||||||
assert_invalid_raw_form!(&client, "a&=b");
|
assert_invalid_raw_form!(&client, "a&=b");
|
||||||
assert_invalid_raw_form!(&client, "=");
|
assert_invalid_raw_form!(&client, "=");
|
||||||
|
@ -185,7 +185,7 @@ fn check_structurally_invalid_forms() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn check_bad_utf8() {
|
fn check_bad_utf8() {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
unsafe {
|
unsafe {
|
||||||
let bad_str = std::str::from_utf8_unchecked(b"a=\xff");
|
let bad_str = std::str::from_utf8_unchecked(b"a=\xff");
|
||||||
assert_form_eq!(&client, bad_str, "Form input was invalid UTF-8.".into());
|
assert_form_eq!(&client, bad_str, "Form input was invalid UTF-8.".into());
|
||||||
|
|
|
@ -5,7 +5,7 @@ use rocket::http::{ContentType, Status};
|
||||||
fn test_login<T>(user: &str, pass: &str, age: &str, status: Status, body: T)
|
fn test_login<T>(user: &str, pass: &str, age: &str, status: Status, body: T)
|
||||||
where T: Into<Option<&'static str>> + Send
|
where T: Into<Option<&'static str>> + Send
|
||||||
{
|
{
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
let query = format!("username={}&password={}&age={}", user, pass, age);
|
let query = format!("username={}&password={}&age={}", user, pass, age);
|
||||||
let response = client.post("/login")
|
let response = client.post("/login")
|
||||||
.header(ContentType::Form)
|
.header(ContentType::Form)
|
||||||
|
@ -44,7 +44,7 @@ fn test_invalid_age() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_bad_form(form_str: &str, status: Status) {
|
fn check_bad_form(form_str: &str, status: Status) {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
let response = client.post("/login")
|
let response = client.post("/login")
|
||||||
.header(ContentType::Form)
|
.header(ContentType::Form)
|
||||||
.body(form_str)
|
.body(form_str)
|
||||||
|
|
|
@ -7,7 +7,7 @@ use rocket_contrib::templates::Template;
|
||||||
|
|
||||||
macro_rules! dispatch {
|
macro_rules! dispatch {
|
||||||
($method:expr, $path:expr, |$client:ident, $response:ident| $body:expr) => ({
|
($method:expr, $path:expr, |$client:ident, $response:ident| $body:expr) => ({
|
||||||
let $client = Client::new(rocket()).unwrap();
|
let $client = Client::tracked(rocket()).unwrap();
|
||||||
let $response = $client.req($method, $path).dispatch();
|
let $response = $client.req($method, $path).dispatch();
|
||||||
$body
|
$body
|
||||||
})
|
})
|
||||||
|
|
|
@ -2,7 +2,7 @@ use rocket::{self, local::blocking::Client};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn hello_world() {
|
fn hello_world() {
|
||||||
let client = Client::new(super::rocket()).unwrap();
|
let client = Client::tracked(super::rocket()).unwrap();
|
||||||
let response = client.get("/").dispatch();
|
let response = client.get("/").dispatch();
|
||||||
assert_eq!(response.into_string(), Some("Hello, Rust 2018!".into()));
|
assert_eq!(response.into_string(), Some("Hello, Rust 2018!".into()));
|
||||||
}
|
}
|
||||||
|
@ -35,14 +35,14 @@ mod scoped_uri_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_inner_hello() {
|
fn test_inner_hello() {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
let response = client.get("/").dispatch();
|
let response = client.get("/").dispatch();
|
||||||
assert_eq!(response.into_string(), Some("Hello! Try /Rust%202018.".into()));
|
assert_eq!(response.into_string(), Some("Hello! Try /Rust%202018.".into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_hello_name() {
|
fn test_hello_name() {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
let response = client.get("/Rust%202018").dispatch();
|
let response = client.get("/Rust%202018").dispatch();
|
||||||
assert_eq!(response.into_string().unwrap(), "Hello, Rust 2018! This is /Rust%202018.");
|
assert_eq!(response.into_string().unwrap(), "Hello, Rust 2018! This is /Rust%202018.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,12 @@ use rocket::local::blocking::Client;
|
||||||
use rocket::http::Status;
|
use rocket::http::Status;
|
||||||
|
|
||||||
fn test(uri: String, expected: String) {
|
fn test(uri: String, expected: String) {
|
||||||
let client = Client::new(super::rocket()).unwrap();
|
let client = Client::tracked(super::rocket()).unwrap();
|
||||||
assert_eq!(client.get(&uri).dispatch().into_string(), Some(expected));
|
assert_eq!(client.get(&uri).dispatch().into_string(), Some(expected));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_404(uri: &'static str) {
|
fn test_404(uri: &'static str) {
|
||||||
let client = Client::new(super::rocket()).unwrap();
|
let client = Client::tracked(super::rocket()).unwrap();
|
||||||
assert_eq!(client.get(uri).dispatch().status(), Status::NotFound);
|
assert_eq!(client.get(uri).dispatch().status(), Status::NotFound);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ use rocket::local::blocking::Client;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn hello_world() {
|
fn hello_world() {
|
||||||
let client = Client::new(super::rocket()).unwrap();
|
let client = Client::tracked(super::rocket()).unwrap();
|
||||||
let response = client.get("/").dispatch();
|
let response = client.get("/").dispatch();
|
||||||
assert_eq!(response.into_string(), Some("Hello, world!".into()));
|
assert_eq!(response.into_string(), Some("Hello, world!".into()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ use rocket::http::{Status, ContentType};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn bad_get_put() {
|
fn bad_get_put() {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
|
|
||||||
// Try to get a message with an ID that doesn't exist.
|
// Try to get a message with an ID that doesn't exist.
|
||||||
let res = client.get("/message/99").header(ContentType::JSON).dispatch();
|
let res = client.get("/message/99").header(ContentType::JSON).dispatch();
|
||||||
|
@ -34,7 +34,7 @@ fn bad_get_put() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn post_get_put_get() {
|
fn post_get_put_get() {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
|
|
||||||
// Check that a message with ID 1 doesn't exist.
|
// Check that a message with ID 1 doesn't exist.
|
||||||
let res = client.get("/message/1").header(ContentType::JSON).dispatch();
|
let res = client.get("/message/1").header(ContentType::JSON).dispatch();
|
||||||
|
|
|
@ -3,7 +3,7 @@ use rocket::http::Status;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_push_pop() {
|
fn test_push_pop() {
|
||||||
let client = Client::new(super::rocket()).unwrap();
|
let client = Client::tracked(super::rocket()).unwrap();
|
||||||
|
|
||||||
let response = client.put("/push?event=test1").dispatch();
|
let response = client.put("/push?event=test1").dispatch();
|
||||||
assert_eq!(response.status(), Status::Ok);
|
assert_eq!(response.status(), Status::Ok);
|
||||||
|
|
|
@ -3,7 +3,7 @@ use rocket::local::blocking::Client;
|
||||||
use rocket::http::{ContentType, Status};
|
use rocket::http::{ContentType, Status};
|
||||||
|
|
||||||
fn test(uri: &str, content_type: ContentType, status: Status, body: String) {
|
fn test(uri: &str, content_type: ContentType, status: Status, body: String) {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
let response = client.get(uri).header(content_type).dispatch();
|
let response = client.get(uri).header(content_type).dispatch();
|
||||||
assert_eq!(response.status(), status);
|
assert_eq!(response.status(), status);
|
||||||
assert_eq!(response.into_string(), Some(body));
|
assert_eq!(response.into_string(), Some(body));
|
||||||
|
@ -30,7 +30,7 @@ fn test_echo() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_upload() {
|
fn test_upload() {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
let expected_body = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, \
|
let expected_body = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, \
|
||||||
sed do eiusmod tempor incididunt ut labore et dolore \
|
sed do eiusmod tempor incididunt ut labore et dolore \
|
||||||
magna aliqua".to_string();
|
magna aliqua".to_string();
|
||||||
|
|
|
@ -12,7 +12,7 @@ struct Message {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn msgpack_get() {
|
fn msgpack_get() {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
let res = client.get("/message/1").header(ContentType::MsgPack).dispatch();
|
let res = client.get("/message/1").header(ContentType::MsgPack).dispatch();
|
||||||
assert_eq!(res.status(), Status::Ok);
|
assert_eq!(res.status(), Status::Ok);
|
||||||
assert_eq!(res.content_type(), Some(ContentType::MsgPack));
|
assert_eq!(res.content_type(), Some(ContentType::MsgPack));
|
||||||
|
@ -25,7 +25,7 @@ fn msgpack_get() {
|
||||||
#[test]
|
#[test]
|
||||||
fn msgpack_post() {
|
fn msgpack_post() {
|
||||||
// Dispatch request with a message of `[2, "Goodbye, world!"]`.
|
// Dispatch request with a message of `[2, "Goodbye, world!"]`.
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
let res = client.post("/message")
|
let res = client.post("/message")
|
||||||
.header(ContentType::MsgPack)
|
.header(ContentType::MsgPack)
|
||||||
.body(&[146, 2, 175, 71, 111, 111, 100, 98, 121, 101, 44, 32, 119, 111, 114, 108, 100, 33])
|
.body(&[146, 2, 175, 71, 111, 111, 100, 98, 121, 101, 44, 32, 119, 111, 114, 108, 100, 33])
|
||||||
|
|
|
@ -2,14 +2,14 @@ use rocket::local::blocking::Client;
|
||||||
use rocket::http::Status;
|
use rocket::http::Status;
|
||||||
|
|
||||||
fn test_200(uri: &str, expected_body: &str) {
|
fn test_200(uri: &str, expected_body: &str) {
|
||||||
let client = Client::new(super::rocket()).unwrap();
|
let client = Client::tracked(super::rocket()).unwrap();
|
||||||
let response = client.get(uri).dispatch();
|
let response = client.get(uri).dispatch();
|
||||||
assert_eq!(response.status(), Status::Ok);
|
assert_eq!(response.status(), Status::Ok);
|
||||||
assert_eq!(response.into_string(), Some(expected_body.to_string()));
|
assert_eq!(response.into_string(), Some(expected_body.to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_303(uri: &str, expected_location: &str) {
|
fn test_303(uri: &str, expected_location: &str) {
|
||||||
let client = Client::new(super::rocket()).unwrap();
|
let client = Client::tracked(super::rocket()).unwrap();
|
||||||
let response = client.get(uri).dispatch();
|
let response = client.get(uri).dispatch();
|
||||||
let location_headers: Vec<_> = response.headers().get("Location").collect();
|
let location_headers: Vec<_> = response.headers().get("Location").collect();
|
||||||
assert_eq!(response.status(), Status::SeeOther);
|
assert_eq!(response.status(), Status::SeeOther);
|
||||||
|
|
|
@ -8,7 +8,7 @@ fn extract_id(from: &str) -> Option<String> {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn check_index() {
|
fn check_index() {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
|
|
||||||
// Ensure the index returns what we expect.
|
// Ensure the index returns what we expect.
|
||||||
let response = client.get("/").dispatch();
|
let response = client.get("/").dispatch();
|
||||||
|
@ -32,7 +32,7 @@ fn download_paste(client: &Client, id: &str) -> String {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn pasting() {
|
fn pasting() {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
|
|
||||||
// Do a trivial upload, just to make sure it works.
|
// Do a trivial upload, just to make sure it works.
|
||||||
let body_1 = "Hello, world!";
|
let body_1 = "Hello, world!";
|
||||||
|
|
|
@ -4,7 +4,7 @@ use rocket::http::Status;
|
||||||
|
|
||||||
macro_rules! run_test {
|
macro_rules! run_test {
|
||||||
($query:expr, |$response:ident| $body:expr) => ({
|
($query:expr, |$response:ident| $body:expr) => ({
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
let mut $response = client.get(format!("/hello{}", $query)).dispatch();
|
let mut $response = client.get(format!("/hello{}", $query)).dispatch();
|
||||||
$body
|
$body
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use rocket::local::blocking::Client;
|
use rocket::local::blocking::Client;
|
||||||
|
|
||||||
fn test(uri: String, expected: String) {
|
fn test(uri: String, expected: String) {
|
||||||
let client = Client::new(super::rocket()).unwrap();
|
let client = Client::tracked(super::rocket()).unwrap();
|
||||||
let response = client.get(&uri).dispatch();
|
let response = client.get(&uri).dispatch();
|
||||||
assert_eq!(response.into_string(), Some(expected));
|
assert_eq!(response.into_string(), Some(expected));
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ use rocket::local::blocking::Client;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn hello() {
|
fn hello() {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
let response = client.get("/").dispatch();
|
let response = client.get("/").dispatch();
|
||||||
assert_eq!(response.into_string(), Some("Rocketeer".into()));
|
assert_eq!(response.into_string(), Some("Rocketeer".into()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ const UPLOAD_CONTENTS: &str = "Hey! I'm going to be uploaded. :D Yay!";
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_index() {
|
fn test_index() {
|
||||||
let client = Client::new(super::rocket()).unwrap();
|
let client = Client::tracked(super::rocket()).unwrap();
|
||||||
let res = client.get("/").dispatch();
|
let res = client.get("/").dispatch();
|
||||||
assert_eq!(res.into_string(), Some(super::index().to_string()));
|
assert_eq!(res.into_string(), Some(super::index().to_string()));
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ fn test_raw_upload() {
|
||||||
let _ = fs::remove_file(&upload_file);
|
let _ = fs::remove_file(&upload_file);
|
||||||
|
|
||||||
// Do the upload. Make sure we get the expected results.
|
// Do the upload. Make sure we get the expected results.
|
||||||
let client = Client::new(super::rocket()).unwrap();
|
let client = Client::tracked(super::rocket()).unwrap();
|
||||||
let res = client.post("/upload")
|
let res = client.post("/upload")
|
||||||
.header(ContentType::Plain)
|
.header(ContentType::Plain)
|
||||||
.body(UPLOAD_CONTENTS)
|
.body(UPLOAD_CONTENTS)
|
||||||
|
|
|
@ -3,7 +3,7 @@ use rocket::http::Status;
|
||||||
|
|
||||||
fn client() -> Client {
|
fn client() -> Client {
|
||||||
let rocket = rocket::ignite().mount("/", routes![super::root, super::login]);
|
let rocket = rocket::ignite().mount("/", routes![super::root, super::login]);
|
||||||
Client::new(rocket).unwrap()
|
Client::tracked(rocket).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -31,7 +31,7 @@ mod test {
|
||||||
use rocket::http::Header;
|
use rocket::http::Header;
|
||||||
|
|
||||||
fn test_header_count<'h>(headers: Vec<Header<'static>>) {
|
fn test_header_count<'h>(headers: Vec<Header<'static>>) {
|
||||||
let client = Client::new(super::rocket()).unwrap();
|
let client = Client::tracked(super::rocket()).unwrap();
|
||||||
let mut req = client.get("/");
|
let mut req = client.get("/");
|
||||||
for header in headers.iter().cloned() {
|
for header in headers.iter().cloned() {
|
||||||
req.add_header(header);
|
req.add_header(header);
|
||||||
|
|
|
@ -5,7 +5,7 @@ use rocket::local::blocking::Client;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test() {
|
fn test() {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
client.get("/sync").dispatch();
|
client.get("/sync").dispatch();
|
||||||
|
|
||||||
let atomics = client.cargo().state::<Atomics>().unwrap();
|
let atomics = client.cargo().state::<Atomics>().unwrap();
|
||||||
|
|
|
@ -23,7 +23,7 @@ fn login(client: &Client, user: &str, pass: &str) -> Option<Cookie<'static>> {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn redirect_on_index() {
|
fn redirect_on_index() {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
let response = client.get("/").dispatch();
|
let response = client.get("/").dispatch();
|
||||||
assert_eq!(response.status(), Status::SeeOther);
|
assert_eq!(response.status(), Status::SeeOther);
|
||||||
assert_eq!(response.headers().get_one("Location"), Some("/login"));
|
assert_eq!(response.headers().get_one("Location"), Some("/login"));
|
||||||
|
@ -31,7 +31,7 @@ fn redirect_on_index() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn can_login() {
|
fn can_login() {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
|
|
||||||
let response = client.get("/login").dispatch();
|
let response = client.get("/login").dispatch();
|
||||||
assert_eq!(response.status(), Status::Ok);
|
assert_eq!(response.status(), Status::Ok);
|
||||||
|
@ -41,14 +41,14 @@ fn can_login() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn login_fails() {
|
fn login_fails() {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
assert!(login(&client, "Seergio", "password").is_none());
|
assert!(login(&client, "Seergio", "password").is_none());
|
||||||
assert!(login(&client, "Sergio", "idontknow").is_none());
|
assert!(login(&client, "Sergio", "idontknow").is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn login_logout_succeeds() {
|
fn login_logout_succeeds() {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
let login_cookie = login(&client, "Sergio", "password").expect("logged in");
|
let login_cookie = login(&client, "Sergio", "password").expect("logged in");
|
||||||
|
|
||||||
// Ensure we're logged in.
|
// Ensure we're logged in.
|
||||||
|
|
|
@ -13,7 +13,7 @@ fn get_count(client: &Client) -> usize {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_count() {
|
fn test_count() {
|
||||||
let client = Client::new(super::rocket()).unwrap();
|
let client = Client::tracked(super::rocket()).unwrap();
|
||||||
|
|
||||||
// Count should start at 0.
|
// Count should start at 0.
|
||||||
assert_eq!(get_count(&client), 0);
|
assert_eq!(get_count(&client), 0);
|
||||||
|
|
|
@ -9,7 +9,7 @@ use super::rocket;
|
||||||
fn test_query_file<T> (path: &str, file: T, status: Status)
|
fn test_query_file<T> (path: &str, file: T, status: Status)
|
||||||
where T: Into<Option<&'static str>>
|
where T: Into<Option<&'static str>>
|
||||||
{
|
{
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
let response = client.get(path).dispatch();
|
let response = client.get(path).dispatch();
|
||||||
assert_eq!(response.status(), status);
|
assert_eq!(response.status(), status);
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ use rocket::local::blocking::Client;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_root() {
|
fn test_root() {
|
||||||
let client = Client::new(super::rocket()).unwrap();
|
let client = Client::tracked(super::rocket()).unwrap();
|
||||||
let res = client.get("/").dispatch();
|
let res = client.get("/").dispatch();
|
||||||
|
|
||||||
// Check that we have exactly 25,000 'a'.
|
// Check that we have exactly 25,000 'a'.
|
||||||
|
@ -24,7 +24,7 @@ fn test_file() {
|
||||||
file.write_all(CONTENTS.as_bytes()).expect("write to big_file");
|
file.write_all(CONTENTS.as_bytes()).expect("write to big_file");
|
||||||
|
|
||||||
// Get the big file contents, hopefully.
|
// Get the big file contents, hopefully.
|
||||||
let client = Client::new(super::rocket()).unwrap();
|
let client = Client::tracked(super::rocket()).unwrap();
|
||||||
let res = client.get("/big_file").dispatch();
|
let res = client.get("/big_file").dispatch();
|
||||||
assert_eq!(res.into_string(), Some(CONTENTS.into()));
|
assert_eq!(res.into_string(), Some(CONTENTS.into()));
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ use rocket_contrib::templates::Template;
|
||||||
|
|
||||||
macro_rules! dispatch {
|
macro_rules! dispatch {
|
||||||
($method:expr, $path:expr, |$client:ident, $response:ident| $body:expr) => ({
|
($method:expr, $path:expr, |$client:ident, $response:ident| $body:expr) => ({
|
||||||
let $client = Client::new(rocket()).unwrap();
|
let $client = Client::tracked(rocket()).unwrap();
|
||||||
let $response = $client.req($method, $path).dispatch();
|
let $response = $client.req($method, $path).dispatch();
|
||||||
$body
|
$body
|
||||||
})
|
})
|
||||||
|
|
|
@ -26,7 +26,7 @@ mod test {
|
||||||
async fn test_rendezvous() {
|
async fn test_rendezvous() {
|
||||||
use rocket::local::asynchronous::Client;
|
use rocket::local::asynchronous::Client;
|
||||||
|
|
||||||
let client = Client::new(rocket()).await.unwrap();
|
let client = Client::tracked(rocket()).await.unwrap();
|
||||||
let req = client.get("/barrier");
|
let req = client.get("/barrier");
|
||||||
|
|
||||||
let (r1, r2) = rocket::tokio::join!(req.clone().dispatch(), req.dispatch());
|
let (r1, r2) = rocket::tokio::join!(req.clone().dispatch(), req.dispatch());
|
||||||
|
|
|
@ -21,7 +21,7 @@ mod test {
|
||||||
fn test_hello() {
|
fn test_hello() {
|
||||||
use rocket::local::blocking::Client;
|
use rocket::local::blocking::Client;
|
||||||
|
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
let response = client.get("/").dispatch();
|
let response = client.get("/").dispatch();
|
||||||
assert_eq!(response.status(), Status::Ok);
|
assert_eq!(response.status(), Status::Ok);
|
||||||
assert_eq!(response.into_string(), Some("Hello, world!".into()));
|
assert_eq!(response.into_string(), Some("Hello, world!".into()));
|
||||||
|
|
|
@ -2,7 +2,7 @@ use rocket::local::blocking::Client;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn hello_world() {
|
fn hello_world() {
|
||||||
let client = Client::new(super::rocket()).unwrap();
|
let client = Client::tracked(super::rocket()).unwrap();
|
||||||
let response = client.get("/").dispatch();
|
let response = client.get("/").dispatch();
|
||||||
assert_eq!(response.into_string(), Some("Hello, world!".into()));
|
assert_eq!(response.into_string(), Some("Hello, world!".into()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ macro_rules! run_test {
|
||||||
|
|
||||||
rocket::async_test(async move {
|
rocket::async_test(async move {
|
||||||
let rocket = super::rocket();
|
let rocket = super::rocket();
|
||||||
let $client = Client::new(rocket).await.expect("Rocket client");
|
let $client = Client::tracked(rocket).await.expect("Rocket client");
|
||||||
let db = super::DbConn::get_one($client.cargo()).await;
|
let db = super::DbConn::get_one($client.cargo()).await;
|
||||||
let $conn = db.expect("failed to get database connection for testing");
|
let $conn = db.expect("failed to get database connection for testing");
|
||||||
Task::delete_all(&$conn).await.expect("failed to delete all tasks for testing");
|
Task::delete_all(&$conn).await.expect("failed to delete all tasks for testing");
|
||||||
|
|
|
@ -3,13 +3,13 @@ use rocket::local::blocking::Client;
|
||||||
use rocket::http::Status;
|
use rocket::http::Status;
|
||||||
|
|
||||||
fn test(uri: &str, expected: &str) {
|
fn test(uri: &str, expected: &str) {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
let res = client.get(uri).dispatch();
|
let res = client.get(uri).dispatch();
|
||||||
assert_eq!(res.into_string(), Some(expected.into()));
|
assert_eq!(res.into_string(), Some(expected.into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_404(uri: &str) {
|
fn test_404(uri: &str) {
|
||||||
let client = Client::new(rocket()).unwrap();
|
let client = Client::tracked(rocket()).unwrap();
|
||||||
let res = client.get(uri).dispatch();
|
let res = client.get(uri).dispatch();
|
||||||
assert_eq!(res.status(), Status::NotFound);
|
assert_eq!(res.status(), Status::NotFound);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ instance. Usage is straightforward:
|
||||||
```rust
|
```rust
|
||||||
# use rocket::local::blocking::Client;
|
# use rocket::local::blocking::Client;
|
||||||
# let rocket = rocket::ignite();
|
# let rocket = rocket::ignite();
|
||||||
let client = Client::new(rocket).unwrap();
|
let client = Client::tracked(rocket).unwrap();
|
||||||
# let _ = client;
|
# let _ = client;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ instance. Usage is straightforward:
|
||||||
```rust
|
```rust
|
||||||
# use rocket::local::blocking::Client;
|
# use rocket::local::blocking::Client;
|
||||||
# let rocket = rocket::ignite();
|
# let rocket = rocket::ignite();
|
||||||
# let client = Client::new(rocket).unwrap();
|
# let client = Client::tracked(rocket).unwrap();
|
||||||
let req = client.get("/");
|
let req = client.get("/");
|
||||||
# let _ = req;
|
# let _ = req;
|
||||||
```
|
```
|
||||||
|
@ -43,7 +43,7 @@ instance. Usage is straightforward:
|
||||||
```rust
|
```rust
|
||||||
# use rocket::local::blocking::Client;
|
# use rocket::local::blocking::Client;
|
||||||
# let rocket = rocket::ignite();
|
# let rocket = rocket::ignite();
|
||||||
# let client = Client::new(rocket).unwrap();
|
# let client = Client::tracked(rocket).unwrap();
|
||||||
# let req = client.get("/");
|
# let req = client.get("/");
|
||||||
let response = req.dispatch();
|
let response = req.dispatch();
|
||||||
# let _ = response;
|
# let _ = response;
|
||||||
|
@ -101,7 +101,7 @@ use rocket::local::blocking::Client;
|
||||||
use rocket::http::{ContentType, Status};
|
use rocket::http::{ContentType, Status};
|
||||||
|
|
||||||
let rocket = rocket::ignite().mount("/", routes![hello]);
|
let rocket = rocket::ignite().mount("/", routes![hello]);
|
||||||
let client = Client::new(rocket).expect("valid rocket instance");
|
let client = Client::tracked(rocket).expect("valid rocket instance");
|
||||||
let mut response = client.get("/").dispatch();
|
let mut response = client.get("/").dispatch();
|
||||||
|
|
||||||
assert_eq!(response.status(), Status::Ok);
|
assert_eq!(response.status(), Status::Ok);
|
||||||
|
@ -168,7 +168,7 @@ testing: we _want_ our tests to panic when something goes wrong.
|
||||||
# fn rocket() -> rocket::Rocket { rocket::ignite() }
|
# fn rocket() -> rocket::Rocket { rocket::ignite() }
|
||||||
# use rocket::local::blocking::Client;
|
# use rocket::local::blocking::Client;
|
||||||
|
|
||||||
let client = Client::new(rocket()).expect("valid rocket instance");
|
let client = Client::tracked(rocket()).expect("valid rocket instance");
|
||||||
```
|
```
|
||||||
|
|
||||||
Then, we create a new `GET /` request and dispatch it, getting back our
|
Then, we create a new `GET /` request and dispatch it, getting back our
|
||||||
|
@ -177,7 +177,7 @@ application's response:
|
||||||
```rust
|
```rust
|
||||||
# fn rocket() -> rocket::Rocket { rocket::ignite() }
|
# fn rocket() -> rocket::Rocket { rocket::ignite() }
|
||||||
# use rocket::local::blocking::Client;
|
# use rocket::local::blocking::Client;
|
||||||
# let client = Client::new(rocket()).expect("valid rocket instance");
|
# let client = Client::tracked(rocket()).expect("valid rocket instance");
|
||||||
let mut response = client.get("/").dispatch();
|
let mut response = client.get("/").dispatch();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -199,7 +199,7 @@ We do this by checking the `Response` object directly:
|
||||||
use rocket::http::{ContentType, Status};
|
use rocket::http::{ContentType, Status};
|
||||||
#
|
#
|
||||||
# let rocket = rocket::ignite().mount("/", routes![hello]);
|
# let rocket = rocket::ignite().mount("/", routes![hello]);
|
||||||
# let client = Client::new(rocket).expect("valid rocket instance");
|
# let client = Client::tracked(rocket).expect("valid rocket instance");
|
||||||
# let mut response = client.get("/").dispatch();
|
# let mut response = client.get("/").dispatch();
|
||||||
|
|
||||||
assert_eq!(response.status(), Status::Ok);
|
assert_eq!(response.status(), Status::Ok);
|
||||||
|
@ -232,7 +232,7 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
# */ pub
|
# */ pub
|
||||||
fn hello_world() {
|
fn hello_world() {
|
||||||
let client = Client::new(rocket()).expect("valid rocket instance");
|
let client = Client::tracked(rocket()).expect("valid rocket instance");
|
||||||
let mut response = client.get("/").dispatch();
|
let mut response = client.get("/").dispatch();
|
||||||
assert_eq!(response.status(), Status::Ok);
|
assert_eq!(response.status(), Status::Ok);
|
||||||
assert_eq!(response.into_string(), Some("Hello, world!".into()));
|
assert_eq!(response.into_string(), Some("Hello, world!".into()));
|
||||||
|
|
Loading…
Reference in New Issue