Skip to content

Commit 9413ca2

Browse files
committed
fix: use Url base_url support for parsing
1 parent d686a8e commit 9413ca2

File tree

2 files changed

+47
-31
lines changed

2 files changed

+47
-31
lines changed

src/async_impl/client.rs

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@ use crate::cookie::service::CookieService;
3232
use crate::dns::hickory::HickoryDnsResolver;
3333
use crate::dns::{gai::GaiResolver, DnsResolverWithOverrides, DynResolver, Resolve};
3434
use crate::error::{self, BoxError};
35-
use crate::into_url::try_uri;
3635
use crate::proxy::Matcher as ProxyMatcher;
3736
use crate::redirect::{self, TowerRedirectPolicy};
3837
#[cfg(feature = "__rustls")]
3938
use crate::tls::CertificateRevocationList;
39+
use crate::into_url::{try_uri, IntoUrlSealed};
4040
#[cfg(feature = "__tls")]
4141
use crate::tls::{self, TlsBackend};
4242
#[cfg(feature = "__tls")]
@@ -1057,7 +1057,7 @@ impl ClientBuilder {
10571057
/// base url has been set.
10581058
pub fn base_url<U>(mut self, base_url: U) -> ClientBuilder
10591059
where
1060-
U: IntoUrl
1060+
U: IntoUrl,
10611061
{
10621062
match base_url.into_url() {
10631063
Ok(base_url) => {
@@ -2464,25 +2464,14 @@ impl Client {
24642464
///
24652465
/// This method fails whenever the supplied `Url` cannot be parsed.
24662466
pub fn request<U: IntoUrl>(&self, method: Method, url: U) -> RequestBuilder {
2467-
let mut maybe_url = url.into_url();
2468-
2469-
if let Some(base_url) = &self.inner.base_url {
2470-
if let Err(url_parse_error) = &maybe_url {
2471-
if url_parse_error.is_builder() {
2472-
if let Some(url) = url_parse_error.url() {
2473-
if !url.has_host() {
2474-
let mut replacement_url = base_url.clone();
2475-
2476-
replacement_url.set_path(url.path());
2477-
replacement_url.set_query(url.query());
2478-
replacement_url.set_fragment(url.fragment());
2479-
2480-
maybe_url = Ok(replacement_url);
2481-
}
2482-
}
2483-
}
2484-
}
2485-
}
2467+
let maybe_url = match &self.inner.base_url {
2468+
Some(ref base_url) => Url::options()
2469+
.base_url(Some(base_url))
2470+
.parse(url.as_str())
2471+
.map_err(crate::error::builder)
2472+
.and_then(IntoUrlSealed::into_url),
2473+
None => url.into_url(),
2474+
};
24862475

24872476
let req = maybe_url.map(move |url| Request::new(method, url));
24882477
RequestBuilder::new(self.clone(), req)

tests/client.rs

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -530,32 +530,59 @@ async fn error_has_url() {
530530
}
531531

532532
#[test]
533-
fn client_cannot_be_built_with_non_absolute_url() {
533+
fn client_cannot_be_built_with_relative_base_url() {
534534
let result = reqwest::Client::builder().base_url("/users/123").build();
535535

536536
assert!(result.is_err());
537537
}
538538

539-
/*
539+
#[test]
540+
fn client_can_be_built_with_absolute_base_url() {
541+
let result = reqwest::Client::builder()
542+
.base_url("http://example.com/users/123")
543+
.build();
544+
545+
assert!(result.is_ok());
546+
}
547+
540548
#[tokio::test]
541-
async fn todo_() {
549+
async fn client_with_base_url_accepts_relative_urls() {
542550
let _ = env_logger::builder().is_test(true).try_init();
543551
let server = server::http(move |_req| async { http::Response::new("Hello".into()) });
544552

545-
let url = format!(
546-
"http://{overridden_domain}:{}/domain_override",
547-
server.addr().port()
548-
);
553+
let server_base_url = format!("http://{}", server.addr());
549554
let client = reqwest::Client::builder()
555+
.base_url(server_base_url)
550556
.no_proxy()
551-
.resolve(overridden_domain, server.addr())
552557
.build()
553558
.expect("client builder");
554-
let req = client.get(&url);
559+
560+
// use a relative url on request
561+
let req = client.get("/hello");
562+
let res = req.send().await.expect("request");
563+
564+
assert_eq!(res.status(), reqwest::StatusCode::OK);
565+
let text = res.text().await.expect("Failed to get text");
566+
assert_eq!("Hello", text);
567+
}
568+
569+
#[tokio::test]
570+
async fn client_with_base_url_accepts_absolute_urls() {
571+
let _ = env_logger::builder().is_test(true).try_init();
572+
let server = server::http(move |_req| async { http::Response::new("Hello".into()) });
573+
574+
let client = reqwest::Client::builder()
575+
.base_url("http://example.com")
576+
.no_proxy()
577+
.build()
578+
.expect("client builder");
579+
580+
// use an absolute url on request
581+
let request_absolute_url = format!("http://{}/hello", server.addr());
582+
let req = client.get(request_absolute_url);
555583
let res = req.send().await.expect("request");
556584

557585
assert_eq!(res.status(), reqwest::StatusCode::OK);
558586
let text = res.text().await.expect("Failed to get text");
559587
assert_eq!("Hello", text);
560588
}
561-
*/

0 commit comments

Comments
 (0)