Skip to content

Commit 254ceae

Browse files
authored
Merge pull request #365 from pietroalbini/fix-http-redirects
Fix http redirects
2 parents e608440 + b4de77c commit 254ceae

File tree

4 files changed

+38
-39
lines changed

4 files changed

+38
-39
lines changed

src/web/crate_details.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33

44
use super::pool::Pool;
5-
use super::{MetaData, duration_to_str, match_version, render_markdown, MatchVersion};
5+
use super::{MetaData, duration_to_str, match_version, render_markdown, MatchVersion, redirect_base};
66
use super::error::Nope;
77
use super::page::Page;
88
use iron::prelude::*;
@@ -240,10 +240,8 @@ pub fn crate_details_handler(req: &mut Request) -> IronResult<Response> {
240240
.to_resp("crate_details")
241241
}
242242
MatchVersion::Semver(version) => {
243-
let url = ctry!(Url::parse(&format!("{}://{}:{}/crate/{}/{}",
244-
req.url.scheme(),
245-
req.url.host(),
246-
req.url.port(),
243+
let url = ctry!(Url::parse(&format!("{}/crate/{}/{}",
244+
redirect_base(req),
247245
name,
248246
version)[..]));
249247

src/web/mod.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,24 @@ fn redirect(url: Url) -> Response {
466466
resp
467467
}
468468

469+
pub fn redirect_base(req: &Request) -> String {
470+
// Try to get the scheme from CloudFront first, and then from iron
471+
let scheme = req.headers
472+
.get_raw("cloudfront-forwarded-proto")
473+
.and_then(|values| values.get(0))
474+
.and_then(|value| std::str::from_utf8(value).ok())
475+
.filter(|proto| *proto == "http" || *proto == "https")
476+
.unwrap_or_else(|| req.url.scheme());
477+
478+
// Only include the port if it's needed
479+
let port = req.url.port();
480+
if port == 80 {
481+
format!("{}://{}", scheme, req.url.host())
482+
} else {
483+
format!("{}://{}:{}", scheme, req.url.host(), port)
484+
}
485+
}
486+
469487
fn style_css_handler(_: &mut Request) -> IronResult<Response> {
470488
let mut response = Response::with((status::Ok, STYLE_CSS));
471489
let cache = vec![CacheDirective::Public,
@@ -495,10 +513,7 @@ fn ico_handler(req: &mut Request) -> IronResult<Response> {
495513
} else {
496514
// if we're looking for something like "favicon-20190317-1.35.0-nightly-c82834e2b.ico",
497515
// redirect to the plain one so that the above branch can trigger with the correct filename
498-
let url = ctry!(Url::parse(&format!("{}://{}:{}/favicon.ico",
499-
req.url.scheme(),
500-
req.url.host(),
501-
req.url.port())[..]));
516+
let url = ctry!(Url::parse(&format!("{}/favicon.ico", redirect_base(req))[..]));
502517

503518
Ok(redirect(url))
504519
}

src/web/releases.rs

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Releases web handlers
22
33

4-
use super::{duration_to_str, match_version};
4+
use super::{duration_to_str, match_version, redirect_base};
55
use super::error::Nope;
66
use super::page::Page;
77
use super::pool::Pool;
@@ -468,10 +468,8 @@ pub fn search_handler(req: &mut Request) -> IronResult<Response> {
468468
let name: String = rows.get(0).get(0);
469469
let version: String = rows.get(0).get(1);
470470
let target_name: String = rows.get(0).get(2);
471-
let url = ctry!(Url::parse(&format!("{}://{}:{}/{}/{}/{}",
472-
req.url.scheme(),
473-
req.url.host(),
474-
req.url.port(),
471+
let url = ctry!(Url::parse(&format!("{}/{}/{}/{}",
472+
redirect_base(req),
475473
name,
476474
version,
477475
target_name)));
@@ -504,17 +502,13 @@ pub fn search_handler(req: &mut Request) -> IronResult<Response> {
504502
}
505503
};
506504
let url = if rustdoc_status {
507-
ctry!(Url::parse(&format!("{}://{}:{}/{}/{}",
508-
req.url.scheme(),
509-
req.url.host(),
510-
req.url.port(),
505+
ctry!(Url::parse(&format!("{}/{}/{}",
506+
redirect_base(req),
511507
query,
512508
version)[..]))
513509
} else {
514-
ctry!(Url::parse(&format!("{}://{}:{}/crate/{}/{}",
515-
req.url.scheme(),
516-
req.url.host(),
517-
req.url.port(),
510+
ctry!(Url::parse(&format!("{}/crate/{}/{}",
511+
redirect_base(req),
518512
query,
519513
version)[..]))
520514
};

src/web/rustdoc.rs

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
use super::pool::Pool;
55
use super::file::File;
6-
use super::latest_version;
6+
use super::{latest_version, redirect_base};
77
use super::crate_details::CrateDetails;
88
use iron::prelude::*;
99
use iron::{status, Url};
@@ -75,10 +75,8 @@ pub fn rustdoc_redirector_handler(req: &mut Request) -> IronResult<Response> {
7575
vers: &str,
7676
target_name: &str)
7777
-> IronResult<Response> {
78-
let url = ctry!(Url::parse(&format!("{}://{}:{}/{}/{}/{}/",
79-
req.url.scheme(),
80-
req.url.host(),
81-
req.url.port(),
78+
let url = ctry!(Url::parse(&format!("{}/{}/{}/{}/",
79+
redirect_base(req),
8280
name,
8381
vers,
8482
target_name)[..]));
@@ -92,10 +90,8 @@ pub fn rustdoc_redirector_handler(req: &mut Request) -> IronResult<Response> {
9290
name: &str,
9391
vers: &str)
9492
-> IronResult<Response> {
95-
let url = ctry!(Url::parse(&format!("{}://{}:{}/crate/{}/{}",
96-
req.url.scheme(),
97-
req.url.host(),
98-
req.url.port(),
93+
let url = ctry!(Url::parse(&format!("{}/crate/{}/{}",
94+
redirect_base(req),
9995
name,
10096
vers)[..]));
10197

@@ -188,10 +184,8 @@ pub fn rustdoc_html_server_handler(req: &mut Request) -> IronResult<Response> {
188184
// to prevent cloudfront caching the wrong artifacts on URLs with loose semver
189185
// versions, redirect the browser to the returned version instead of loading it
190186
// immediately
191-
let url = ctry!(Url::parse(&format!("{}://{}:{}/{}/{}/{}",
192-
req.url.scheme(),
193-
req.url.host(),
194-
req.url.port(),
187+
let url = ctry!(Url::parse(&format!("{}/{}/{}/{}",
188+
redirect_base(req),
195189
name,
196190
v,
197191
req_path.join("/"))[..]));
@@ -297,10 +291,8 @@ pub fn badge_handler(req: &mut Request) -> IronResult<Response> {
297291
}
298292
}
299293
MatchVersion::Semver(version) => {
300-
let url = ctry!(Url::parse(&format!("{}://{}:{}/{}/badge.svg?version={}",
301-
req.url.scheme(),
302-
req.url.host(),
303-
req.url.port(),
294+
let url = ctry!(Url::parse(&format!("{}/{}/badge.svg?version={}",
295+
redirect_base(req),
304296
name,
305297
version)[..]));
306298

0 commit comments

Comments
 (0)