From 04b7ce0afa7e2680b0d81d53bc75e75974e3312c Mon Sep 17 00:00:00 2001 From: Sam Gibson Date: Sun, 16 Aug 2015 17:34:34 +1000 Subject: [PATCH] Tests rewriting redirects of POST as GET --- components/net/http_loader.rs | 17 ++++++++++------- tests/unit/net/http_loader.rs | 26 ++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/components/net/http_loader.rs b/components/net/http_loader.rs index d4a6b10f7b0..3abe0d89aec 100644 --- a/components/net/http_loader.rs +++ b/components/net/http_loader.rs @@ -417,7 +417,7 @@ enum Decoders { Plain(R) } -pub fn load(mut load_data: LoadData, +pub fn load(load_data: LoadData, resource_mgr_chan: IpcSender, devtools_chan: Option>, request_factory: &HttpRequestFactory) @@ -433,6 +433,7 @@ pub fn load(mut load_data: LoadData, // specified in the hosts file. let mut url = replace_hosts(&load_data.url); let mut redirected_to = HashSet::new(); + let mut method = load_data.method.clone(); // If the URL is a view-source scheme then the scheme data contains the // real URL that should be used for which the source is to be viewed. @@ -488,11 +489,11 @@ pub fn load(mut load_data: LoadData, set_request_cookies(doc_url.clone(), &mut request_headers, &resource_mgr_chan); // --- Send the request - let mut req = try!(request_factory.create(url.clone(), load_data.method.clone())); + let mut req = try!(request_factory.create(url.clone(), method.clone())); *req.headers_mut() = request_headers; if log_enabled!(log::LogLevel::Info) { - info!("{}", load_data.method); + info!("{}", method); for header in req.headers_mut().iter() { info!(" - {}", header); } @@ -522,7 +523,7 @@ pub fn load(mut load_data: LoadData, let request_id = uuid::Uuid::new_v4().to_simple_string(); if let Some(ref chan) = devtools_chan { let net_event = NetworkEvent::HttpRequest(load_data.url.clone(), - load_data.method.clone(), + method.clone(), load_data.headers.clone(), load_data.data.clone()); chan.send(DevtoolsControlMsg::FromChrome( @@ -559,22 +560,24 @@ pub fn load(mut load_data: LoadData, } _ => {} } + let new_doc_url = match UrlParser::new().base_url(&doc_url).parse(&new_url) { Ok(u) => u, Err(e) => { return Err(LoadError::InvalidRedirect(doc_url, e.to_string())); } }; + info!("redirecting to {}", new_doc_url); url = replace_hosts(&new_doc_url); doc_url = new_doc_url; // According to https://tools.ietf.org/html/rfc7231#section-6.4.2, // historically UAs have rewritten POST->GET on 301 and 302 responses. - if load_data.method == Method::Post && + if method == Method::Post && (response.status() == StatusCode::MovedPermanently || response.status() == StatusCode::Found) { - load_data.method = Method::Get; + method = Method::Get; } if redirected_to.contains(&url) { @@ -593,8 +596,8 @@ pub fn load(mut load_data: LoadData, if viewing_source { adjusted_headers.set(ContentType(Mime(TopLevel::Text, SubLevel::Plain, vec![]))); } - let mut metadata: Metadata = Metadata::default(doc_url.clone()); + let mut metadata: Metadata = Metadata::default(doc_url.clone()); metadata.set_content_type(match adjusted_headers.get() { Some(&ContentType(ref mime)) => Some(mime), None => None diff --git a/tests/unit/net/http_loader.rs b/tests/unit/net/http_loader.rs index 956a9b073e5..d928f6d1eaf 100644 --- a/tests/unit/net/http_loader.rs +++ b/tests/unit/net/http_loader.rs @@ -208,6 +208,32 @@ impl HttpRequest for AssertMustHaveBodyRequest { } } +#[test] +fn test_load_when_redirecting_from_a_post_should_rewrite_next_request_as_get() { + struct Factory; + + impl HttpRequestFactory for Factory { + type R=MockRequest; + + fn create(&self, url: Url, method: Method) -> Result { + if url.domain().unwrap() == "mozilla.com" { + assert_eq!(Method::Post, method); + Ok(MockRequest::new(RequestType::Redirect("http://mozilla.org".to_string()))) + } else { + assert_eq!(Method::Get, method); + Ok(MockRequest::new(RequestType::Text(<[_]>::to_vec("Yay!".as_bytes())))) + } + } + } + + let url = Url::parse("http://mozilla.com").unwrap(); + let resource_mgr = new_resource_task(None, None); + let mut load_data = LoadData::new(url.clone(), None); + load_data.method = Method::Post; + + let _ = load::(load_data, resource_mgr, None, &Factory); +} + #[test] fn test_load_should_decode_the_response_as_deflate_when_response_headers_have_content_encoding_deflate() { struct Factory;