mirror of
https://github.com/actix/actix-extras.git
synced 2025-01-22 14:55:56 +01:00
Do not create a session if the session state is empty (#207)
This commit is contained in:
parent
74ec115161
commit
e77ed16f49
@ -1,8 +1,10 @@
|
|||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
## Unreleased - 2021-xx-xx
|
## Unreleased - 2021-xx-xx
|
||||||
|
* A session will be created in Redis if and only if there is some data inside the session state. This reduces the performance impact of `RedisSession` on routes that do not leverage sessions. [#207]
|
||||||
* Update `actix-web` dependency to `4.0.0.beta-14`. [#209]
|
* Update `actix-web` dependency to `4.0.0.beta-14`. [#209]
|
||||||
|
|
||||||
|
[#207]: https://github.com/actix/actix-extras/pull/207
|
||||||
[#209]: https://github.com/actix/actix-extras/pull/209
|
[#209]: https://github.com/actix/actix-extras/pull/209
|
||||||
|
|
||||||
|
|
||||||
|
@ -170,13 +170,10 @@ where
|
|||||||
let mut res = srv.call(req).await?;
|
let mut res = srv.call(req).await?;
|
||||||
|
|
||||||
match Session::get_changes(&mut res) {
|
match Session::get_changes(&mut res) {
|
||||||
(SessionStatus::Unchanged, state) => {
|
(SessionStatus::Unchanged, _) => {
|
||||||
if value.is_none() {
|
// If the session already exists, we don't need to update the state stored in Redis
|
||||||
// implies the session is new
|
// If the session is new, creating an empty session in Redis is unnecessary overhead
|
||||||
inner.update(res, state, value).await
|
Ok(res)
|
||||||
} else {
|
|
||||||
Ok(res)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(SessionStatus::Changed, state) => inner.update(res, state, value).await,
|
(SessionStatus::Changed, state) => inner.update(res, state, value).await,
|
||||||
@ -453,14 +450,14 @@ mod test {
|
|||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn test_session_workflow() {
|
async fn test_session_workflow() {
|
||||||
// Step 1: GET index
|
// Step 1: GET index
|
||||||
// - set-cookie actix-session will be in response (session cookie #1)
|
// - set-cookie actix-session should NOT be in response (session data is empty)
|
||||||
// - response should be: {"counter": 0, "user_id": None}
|
// - response should be: {"counter": 0, "user_id": None}
|
||||||
// - cookie should have default max-age of 7 days
|
// Step 2: POST to do_something
|
||||||
// Step 2: GET index, including session cookie #1 in request
|
|
||||||
// - set-cookie will *not* be in response
|
|
||||||
// - response should be: {"counter": 0, "user_id": None}
|
|
||||||
// Step 3: POST to do_something, including session cookie #1 in request
|
|
||||||
// - adds new session state in redis: {"counter": 1}
|
// - adds new session state in redis: {"counter": 1}
|
||||||
|
// - set-cookie actix-session should be in response (session cookie #1)
|
||||||
|
// - response should be: {"counter": 1, "user_id": None}
|
||||||
|
// Step 3: GET index, including session cookie #1 in request
|
||||||
|
// - set-cookie will *not* be in response
|
||||||
// - response should be: {"counter": 1, "user_id": None}
|
// - response should be: {"counter": 1, "user_id": None}
|
||||||
// Step 4: POST again to do_something, including session cookie #1 in request
|
// Step 4: POST again to do_something, including session cookie #1 in request
|
||||||
// - updates session state in redis: {"counter": 2}
|
// - updates session state in redis: {"counter": 2}
|
||||||
@ -472,15 +469,15 @@ mod test {
|
|||||||
// - response should be: {"counter": 2, "user_id": "ferris"}
|
// - response should be: {"counter": 2, "user_id": "ferris"}
|
||||||
// Step 7: POST again to do_something, including session cookie #2 in request
|
// Step 7: POST again to do_something, including session cookie #2 in request
|
||||||
// - updates session state in redis: {"counter": 3, "user_id": "ferris"}
|
// - updates session state in redis: {"counter": 3, "user_id": "ferris"}
|
||||||
// - response should be: {"counter": 2, "user_id": None}
|
// - response should be: {"counter": 3, "user_id": "ferris"}
|
||||||
// Step 8: GET index, including session cookie #1 in request
|
// Step 8: GET index, including session cookie #1 in request
|
||||||
// - set-cookie actix-session will be in response (session cookie #3)
|
// - set-cookie actix-session should NOT be in response (session data is empty)
|
||||||
// - response should be: {"counter": 0, "user_id": None}
|
// - response should be: {"counter": 0, "user_id": None}
|
||||||
// Step 9: POST to logout, including session cookie #2
|
// Step 9: POST to logout, including session cookie #2
|
||||||
// - set-cookie actix-session will be in response with session cookie #2
|
// - set-cookie actix-session will be in response with session cookie #2
|
||||||
// invalidation logic
|
// invalidation logic
|
||||||
// Step 10: GET index, including session cookie #2 in request
|
// Step 10: GET index, including session cookie #2 in request
|
||||||
// - set-cookie actix-session will be in response (session cookie #3)
|
// - set-cookie actix-session should NOT be in response (session data is empty)
|
||||||
// - response should be: {"counter": 0, "user_id": None}
|
// - response should be: {"counter": 0, "user_id": None}
|
||||||
|
|
||||||
let srv = actix_test::start(|| {
|
let srv = actix_test::start(|| {
|
||||||
@ -494,17 +491,11 @@ mod test {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Step 1: GET index
|
// Step 1: GET index
|
||||||
// - set-cookie actix-session will be in response (session cookie #1)
|
// - set-cookie actix-session should NOT be in response (session data is empty)
|
||||||
// - response should be: {"counter": 0, "user_id": None}
|
// - response should be: {"counter": 0, "user_id": None}
|
||||||
let req_1a = srv.get("/").send();
|
let req_1a = srv.get("/").send();
|
||||||
let mut resp_1 = req_1a.await.unwrap();
|
let mut resp_1 = req_1a.await.unwrap();
|
||||||
let cookie_1 = resp_1
|
assert!(resp_1.cookies().unwrap().is_empty());
|
||||||
.cookies()
|
|
||||||
.unwrap()
|
|
||||||
.clone()
|
|
||||||
.into_iter()
|
|
||||||
.find(|c| c.name() == "test-session")
|
|
||||||
.unwrap();
|
|
||||||
let result_1 = resp_1.json::<IndexResponse>().await.unwrap();
|
let result_1 = resp_1.json::<IndexResponse>().await.unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
result_1,
|
result_1,
|
||||||
@ -513,26 +504,28 @@ mod test {
|
|||||||
counter: 0
|
counter: 0
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
assert_eq!(cookie_1.max_age(), Some(Duration::days(7)));
|
|
||||||
|
|
||||||
// Step 2: GET index, including session cookie #1 in request
|
// Step 2: POST to do_something
|
||||||
// - set-cookie will *not* be in response
|
// - adds new session state in redis: {"counter": 1}
|
||||||
// - response should be: {"counter": 0, "user_id": None}
|
// - set-cookie actix-session should be in response (session cookie #1)
|
||||||
let req_2 = srv.get("/").cookie(cookie_1.clone()).send();
|
// - response should be: {"counter": 1, "user_id": None}
|
||||||
|
let req_2 = srv.post("/do_something").send();
|
||||||
let resp_2 = req_2.await.unwrap();
|
let resp_2 = req_2.await.unwrap();
|
||||||
let cookie_2 = resp_2
|
let cookie_1 = resp_2
|
||||||
.cookies()
|
.cookies()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.clone()
|
.clone()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.find(|c| c.name() == "test-session");
|
.find(|c| c.name() == "test-session")
|
||||||
assert_eq!(cookie_2, None);
|
.unwrap();
|
||||||
|
assert_eq!(cookie_1.max_age(), Some(Duration::days(7)));
|
||||||
|
|
||||||
// Step 3: POST to do_something, including session cookie #1 in request
|
// Step 3: GET index, including session cookie #1 in request
|
||||||
// - adds new session state in redis: {"counter": 1}
|
// - set-cookie will *not* be in response
|
||||||
// - response should be: {"counter": 1, "user_id": None}
|
// - response should be: {"counter": 1, "user_id": None}
|
||||||
let req_3 = srv.post("/do_something").cookie(cookie_1.clone()).send();
|
let req_3 = srv.get("/").cookie(cookie_1.clone()).send();
|
||||||
let mut resp_3 = req_3.await.unwrap();
|
let mut resp_3 = req_3.await.unwrap();
|
||||||
|
assert!(resp_3.cookies().unwrap().is_empty());
|
||||||
let result_3 = resp_3.json::<IndexResponse>().await.unwrap();
|
let result_3 = resp_3.json::<IndexResponse>().await.unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
result_3,
|
result_3,
|
||||||
@ -597,7 +590,7 @@ mod test {
|
|||||||
|
|
||||||
// Step 7: POST again to do_something, including session cookie #2 in request
|
// Step 7: POST again to do_something, including session cookie #2 in request
|
||||||
// - updates session state in redis: {"counter": 3, "user_id": "ferris"}
|
// - updates session state in redis: {"counter": 3, "user_id": "ferris"}
|
||||||
// - response should be: {"counter": 2, "user_id": None}
|
// - response should be: {"counter": 3, "user_id": "ferris"}
|
||||||
let req_7 = srv.post("/do_something").cookie(cookie_2.clone()).send();
|
let req_7 = srv.post("/do_something").cookie(cookie_2.clone()).send();
|
||||||
let mut resp_7 = req_7.await.unwrap();
|
let mut resp_7 = req_7.await.unwrap();
|
||||||
let result_7 = resp_7.json::<IndexResponse>().await.unwrap();
|
let result_7 = resp_7.json::<IndexResponse>().await.unwrap();
|
||||||
@ -610,17 +603,11 @@ mod test {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Step 8: GET index, including session cookie #1 in request
|
// Step 8: GET index, including session cookie #1 in request
|
||||||
// - set-cookie actix-session will be in response (session cookie #3)
|
// - set-cookie actix-session should NOT be in response (session data is empty)
|
||||||
// - response should be: {"counter": 0, "user_id": None}
|
// - response should be: {"counter": 0, "user_id": None}
|
||||||
let req_8 = srv.get("/").cookie(cookie_1.clone()).send();
|
let req_8 = srv.get("/").cookie(cookie_1.clone()).send();
|
||||||
let mut resp_8 = req_8.await.unwrap();
|
let mut resp_8 = req_8.await.unwrap();
|
||||||
let cookie_3 = resp_8
|
assert!(resp_8.cookies().unwrap().is_empty());
|
||||||
.cookies()
|
|
||||||
.unwrap()
|
|
||||||
.clone()
|
|
||||||
.into_iter()
|
|
||||||
.find(|c| c.name() == "test-session")
|
|
||||||
.unwrap();
|
|
||||||
let result_8 = resp_8.json::<IndexResponse>().await.unwrap();
|
let result_8 = resp_8.json::<IndexResponse>().await.unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
result_8,
|
result_8,
|
||||||
@ -629,14 +616,13 @@ mod test {
|
|||||||
counter: 0
|
counter: 0
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
assert_ne!(cookie_3.value(), cookie_2.value());
|
|
||||||
|
|
||||||
// Step 9: POST to logout, including session cookie #2
|
// Step 9: POST to logout, including session cookie #2
|
||||||
// - set-cookie actix-session will be in response with session cookie #2
|
// - set-cookie actix-session will be in response with session cookie #2
|
||||||
// invalidation logic
|
// invalidation logic
|
||||||
let req_9 = srv.post("/logout").cookie(cookie_2.clone()).send();
|
let req_9 = srv.post("/logout").cookie(cookie_2.clone()).send();
|
||||||
let resp_9 = req_9.await.unwrap();
|
let resp_9 = req_9.await.unwrap();
|
||||||
let cookie_4 = resp_9
|
let cookie_3 = resp_9
|
||||||
.cookies()
|
.cookies()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.clone()
|
.clone()
|
||||||
@ -645,17 +631,18 @@ mod test {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
assert_ne!(
|
assert_ne!(
|
||||||
OffsetDateTime::now_utc().year(),
|
OffsetDateTime::now_utc().year(),
|
||||||
cookie_4
|
cookie_3
|
||||||
.expires()
|
.expires()
|
||||||
.map(|t| t.datetime().expect("Expiration is a datetime").year())
|
.map(|t| t.datetime().expect("Expiration is a datetime").year())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
);
|
);
|
||||||
|
|
||||||
// Step 10: GET index, including session cookie #2 in request
|
// Step 10: GET index, including session cookie #2 in request
|
||||||
// - set-cookie actix-session will be in response (session cookie #3)
|
// - set-cookie actix-session should NOT be in response (session data is empty)
|
||||||
// - response should be: {"counter": 0, "user_id": None}
|
// - response should be: {"counter": 0, "user_id": None}
|
||||||
let req_10 = srv.get("/").cookie(cookie_2.clone()).send();
|
let req_10 = srv.get("/").cookie(cookie_2.clone()).send();
|
||||||
let mut resp_10 = req_10.await.unwrap();
|
let mut resp_10 = req_10.await.unwrap();
|
||||||
|
assert!(resp_10.cookies().unwrap().is_empty());
|
||||||
let result_10 = resp_10.json::<IndexResponse>().await.unwrap();
|
let result_10 = resp_10.json::<IndexResponse>().await.unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
result_10,
|
result_10,
|
||||||
@ -664,15 +651,6 @@ mod test {
|
|||||||
counter: 0
|
counter: 0
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
let cookie_5 = resp_10
|
|
||||||
.cookies()
|
|
||||||
.unwrap()
|
|
||||||
.clone()
|
|
||||||
.into_iter()
|
|
||||||
.find(|c| c.name() == "test-session")
|
|
||||||
.unwrap();
|
|
||||||
assert_ne!(cookie_5.value(), cookie_2.value());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
@ -688,10 +666,10 @@ mod test {
|
|||||||
.cookie_max_age(None),
|
.cookie_max_age(None),
|
||||||
)
|
)
|
||||||
.wrap(middleware::Logger::default())
|
.wrap(middleware::Logger::default())
|
||||||
.service(resource("/").route(get().to(index)))
|
.service(resource("/do_something").route(post().to(do_something)))
|
||||||
});
|
});
|
||||||
|
|
||||||
let req = srv.get("/").send();
|
let req = srv.post("/do_something").send();
|
||||||
let resp = req.await.unwrap();
|
let resp = req.await.unwrap();
|
||||||
let cookie = resp
|
let cookie = resp
|
||||||
.cookies()
|
.cookies()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user