Skip to content

Commit d333ab5

Browse files
committed
keep queries when doing lucky, :: or crate-name searches
enables `docs.rs/releases/search?query=tokio::spawn&i-am-feeling-lucky=1&go_to_first=true` and `docs.rs/tokio::spawn?go_to_first=true` to go to first result after redirect
1 parent 4abe7e9 commit d333ab5

File tree

2 files changed

+46
-5
lines changed

2 files changed

+46
-5
lines changed

src/web/releases.rs

+30-1
Original file line numberDiff line numberDiff line change
@@ -561,11 +561,25 @@ pub fn search_handler(req: &mut Request) -> IronResult<Response> {
561561
return redirect_to_random_crate(req, &mut conn);
562562
}
563563

564-
let (krate, query) = match query.split_once("::") {
564+
let (krate, mut query) = match query.split_once("::") {
565565
Some((krate, query)) => (krate.to_string(), format!("?search={query}")),
566566
None => (query.clone(), "".to_string()),
567567
};
568568

569+
for (k, v) in params
570+
.iter()
571+
.filter(|(k, _)| !matches!(k.as_ref(), "i-am-feeling-lucky" | "query"))
572+
{
573+
if query.is_empty() {
574+
query.push('?');
575+
} else {
576+
query.push('&')
577+
}
578+
query.push_str(k);
579+
query.push('=');
580+
query.push_str(v);
581+
}
582+
569583
// since we never pass a version into `match_version` here, we'll never get
570584
// `MatchVersion::Exact`, so the distinction between `Exact` and `Semver` doesn't
571585
// matter
@@ -884,6 +898,21 @@ mod tests {
884898
})
885899
}
886900

901+
#[test]
902+
fn search_coloncolon_path_redirects_to_crate_docs_and_keeps_query() {
903+
wrapper(|env| {
904+
let web = env.frontend();
905+
env.fake_release().name("some_random_crate").create()?;
906+
907+
assert_redirect(
908+
"/releases/search?query=some_random_crate::somepath&go_to_first=true",
909+
"/some_random_crate/1.0.0/some_random_crate/?search=somepath&go_to_first=true",
910+
web,
911+
)?;
912+
Ok(())
913+
})
914+
}
915+
887916
#[test]
888917
fn search_result_passes_cratesio_pagination_links() {
889918
wrapper(|env| {

src/web/rustdoc.rs

+16-4
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,19 @@ pub fn rustdoc_redirector_handler(req: &mut Request) -> IronResult<Response> {
4646
permanent: bool,
4747
path_in_crate: Option<&str>,
4848
) -> IronResult<Response> {
49-
if let Some(query) = req.url.query() {
50-
url_str.push('?');
51-
url_str.push_str(query);
52-
} else if let Some(path) = path_in_crate {
49+
let mut question_mark = false;
50+
if let Some(path) = path_in_crate {
5351
url_str.push_str("?search=");
5452
url_str.push_str(path);
53+
question_mark = true;
54+
}
55+
if let Some(query) = req.url.query() {
56+
if !question_mark {
57+
url_str.push('?');
58+
} else {
59+
url_str.push('&');
60+
}
61+
url_str.push_str(query);
5562
}
5663
let url = ctry!(req, Url::parse(&url_str));
5764
let (status_code, max_age) = if permanent {
@@ -1776,6 +1783,11 @@ mod test {
17761783
"/some_random_crate/latest/some_random_crate/?search=some::path",
17771784
web,
17781785
)?;
1786+
assert_redirect(
1787+
"/some_random_crate::some::path?go_to_first=true",
1788+
"/some_random_crate/latest/some_random_crate/?search=some::path&go_to_first=true",
1789+
web,
1790+
)?;
17791791

17801792
assert_redirect(
17811793
"/std::some::path",

0 commit comments

Comments
 (0)