1
0
Fork 0
mirror of https://github.com/actix/actix-web.git synced 2024-11-26 19:41:12 +00:00

document full percent-decoding of web::Path

This commit is contained in:
Rob Ede 2022-01-22 16:17:46 +00:00
parent c25dd23820
commit c92aa31f91
No known key found for this signature in database
GPG key ID: 97C636207D3EF933
2 changed files with 13 additions and 8 deletions

View file

@ -129,10 +129,11 @@ impl HttpRequest {
/// later in a request handler to access the matched value for that parameter. /// later in a request handler to access the matched value for that parameter.
/// ///
/// # Percent Encoding and URL Parameters /// # Percent Encoding and URL Parameters
/// Because each URL parameter is able to capture multiple path segments, both `["%2F", "%25"]` /// Because each URL parameter is able to capture multiple path segments, none of
/// found in the request URI are not decoded into `["/", "%"]` in order to preserve path /// `["%2F", "%25", "%2B"]` found in the request URI are decoded into `["/", "%", "+"]` in order
/// segment boundaries. If a url parameter is expected to contain these characters, then it is /// to preserve path integrity. If a URL parameter is expected to contain these characters, then
/// on the user to decode them. /// it is on the user to decode them or use the [`web::Path`](crate::web::Path) extractor which
/// _will_ decode these special sequences.
#[inline] #[inline]
pub fn match_info(&self) -> &Path<Url> { pub fn match_info(&self) -> &Path<Url> {
&self.inner.path &self.inner.path
@ -504,12 +505,11 @@ impl HttpRequestPool {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use actix_service::Service;
use bytes::Bytes; use bytes::Bytes;
use super::*; use super::*;
use crate::{ use crate::{
dev::{ResourceDef, ResourceMap}, dev::{ResourceDef, ResourceMap, Service},
http::{header, StatusCode}, http::{header, StatusCode},
test::{self, call_service, init_service, read_body, TestRequest}, test::{self, call_service, init_service, read_body, TestRequest},
web, App, HttpResponse, web, App, HttpResponse,
@ -902,6 +902,7 @@ mod tests {
// `body` equals http://localhost:8080/bar/nested // `body` equals http://localhost:8080/bar/nested
// because nested from /bar overrides /foo's // because nested from /bar overrides /foo's
// to do this any other way would require something like a custom tree search // to do this any other way would require something like a custom tree search
// see https://github.com/actix/actix-web/issues/1763
assert_eq!(body, "http://localhost:8080/bar/nested"); assert_eq!(body, "http://localhost:8080/bar/nested");
let bar_resp = let bar_resp =

View file

@ -18,6 +18,9 @@ use crate::{
/// ///
/// Use [`PathConfig`] to configure extraction option. /// Use [`PathConfig`] to configure extraction option.
/// ///
/// Unlike, [`HttpRequest::match_info`], this extractor will fully percent-decode dynamic segments,
/// including `/`, `%`, and `+`.
///
/// # Examples /// # Examples
/// ``` /// ```
/// use actix_web::{get, web}; /// use actix_web::{get, web};
@ -259,13 +262,14 @@ mod tests {
#[actix_rt::test] #[actix_rt::test]
async fn paths_decoded() { async fn paths_decoded() {
let resource = ResourceDef::new("/{key}/{value}"); let resource = ResourceDef::new("/{key}/{value}");
let mut req = TestRequest::with_uri("/na%2Bme/us%2Fer%251").to_srv_request(); let mut req = TestRequest::with_uri("/na%2Bme/us%2Fer%254%32").to_srv_request();
resource.capture_match_info(req.match_info_mut()); resource.capture_match_info(req.match_info_mut());
let (req, mut pl) = req.into_parts(); let (req, mut pl) = req.into_parts();
let path_items = Path::<MyStruct>::from_request(&req, &mut pl).await.unwrap(); let path_items = Path::<MyStruct>::from_request(&req, &mut pl).await.unwrap();
assert_eq!(path_items.key, "na+me"); assert_eq!(path_items.key, "na+me");
assert_eq!(path_items.value, "us/er%1"); assert_eq!(path_items.value, "us/er%42");
assert_eq!(req.match_info().as_str(), "/na%2Bme/us%2Fer%2542");
} }
#[actix_rt::test] #[actix_rt::test]