Skip to content

Commit

Permalink
Add fallback route
Browse files Browse the repository at this point in the history
  • Loading branch information
casey committed Mar 14, 2024
1 parent 463a2e0 commit c78bcd4
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 8 deletions.
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ tokio = { version = "1.17.0", features = ["rt-multi-thread"] }
tokio-stream = "0.1.9"
tokio-util = {version = "0.7.3", features = ["compat"] }
tower-http = { version = "0.4.0", features = ["auth", "compression-br", "compression-gzip", "cors", "set-header"] }
urlencoding = "2.1.3"

[dev-dependencies]
criterion = "0.5.1"
Expand Down
78 changes: 70 additions & 8 deletions src/subcommand/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ impl Server {
.route("/static/*path", get(Self::static_asset))
.route("/status", get(Self::status))
.route("/tx/:txid", get(Self::transaction))
.fallback(Self::fallback)
.layer(Extension(index))
.layer(Extension(server_config.clone()))
.layer(Extension(settings.clone()))
Expand Down Expand Up @@ -483,6 +484,29 @@ impl Server {
})
}

async fn fallback(Extension(index): Extension<Arc<Index>>, uri: Uri) -> ServerResult<Response> {
let path = urlencoding::decode(uri.path().trim_matches('/'))
.map_err(|err| ServerError::BadRequest(err.to_string()))?;

let prefix = if re::INSCRIPTION_ID.is_match(&path) || re::INSCRIPTION_NUMBER.is_match(&path) {
"inscription"
} else if re::RUNE_ID.is_match(&path) || re::SPACED_RUNE.is_match(&path) {
"rune"
} else if re::OUTPOINT.is_match(&path) {
"output"
} else if re::HASH.is_match(&path) {
if index.block_header(path.parse().unwrap())?.is_some() {
"block"
} else {
"tx"
}
} else {
return Ok(StatusCode::NOT_FOUND.into_response());
};

Ok(Redirect::to(&format!("/{prefix}/{path}")).into_response())
}

async fn sat(
Extension(server_config): Extension<Arc<ServerConfig>>,
Extension(index): Extension<Arc<Index>>,
Expand Down Expand Up @@ -950,7 +974,7 @@ impl Server {
}
} else if re::OUTPOINT.is_match(query) {
Ok(Redirect::to(&format!("/output/{query}")))
} else if re::INSCRIPTION_ID.is_match(query) {
} else if re::INSCRIPTION_ID.is_match(query) || re::INSCRIPTION_NUMBER.is_match(query) {
Ok(Redirect::to(&format!("/inscription/{query}")))
} else if re::SPACED_RUNE.is_match(query) {
Ok(Redirect::to(&format!("/rune/{query}")))
Expand Down Expand Up @@ -2303,11 +2327,6 @@ mod tests {
TestServer::new().assert_redirect("/faq", "https://docs.ordinals.com/faq/");
}

#[test]
fn search_by_query_returns_sat() {
TestServer::new().assert_redirect("/search?query=0", "/sat/0");
}

#[test]
fn search_by_query_returns_rune() {
TestServer::new().assert_redirect("/search?query=ABCD", "/rune/ABCD");
Expand All @@ -2326,14 +2345,19 @@ mod tests {
);
}

#[test]
fn search_by_query_returns_inscription_by_number() {
TestServer::new().assert_redirect("/search?query=0", "/inscription/0");
}

#[test]
fn search_is_whitespace_insensitive() {
TestServer::new().assert_redirect("/search/ 0 ", "/sat/0");
TestServer::new().assert_redirect("/search/ abc ", "/sat/abc");
}

#[test]
fn search_by_path_returns_sat() {
TestServer::new().assert_redirect("/search/0", "/sat/0");
TestServer::new().assert_redirect("/search/abc", "/sat/abc");
}

#[test]
Expand Down Expand Up @@ -2423,6 +2447,44 @@ mod tests {
);
}

#[test]
fn fallback() {
let server = TestServer::new();

server.assert_redirect("/0", "/inscription/0");
server.assert_redirect("/0/", "/inscription/0");
server.assert_redirect("/0//", "/inscription/0");
server.assert_redirect(
"/521f8eccffa4c41a3a7728dd012ea5a4a02feed81f41159231251ecf1e5c79dai0",
"/inscription/521f8eccffa4c41a3a7728dd012ea5a4a02feed81f41159231251ecf1e5c79dai0",
);
server.assert_redirect("/-1", "/inscription/-1");
server.assert_redirect("/FOO", "/rune/FOO");
server.assert_redirect("/FO.O", "/rune/FO.O");
server.assert_redirect("/FO•O", "/rune/FO•O");
server.assert_redirect("/0:0", "/rune/0:0");
server.assert_redirect(
"/4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b:0",
"/output/4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b:0",
);
server.assert_redirect(
"/search/000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",
"/block/000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",
);
server.assert_redirect(
"/search/0000000000000000000000000000000000000000000000000000000000000000",
"/tx/0000000000000000000000000000000000000000000000000000000000000000",
);

server.assert_response_regex("/hello", StatusCode::NOT_FOUND, "");

server.assert_response_regex(
"/%C3%28",
StatusCode::BAD_REQUEST,
"invalid utf-8 sequence of 1 bytes from index 0",
);
}

#[test]
fn runes_can_be_queried_by_rune_id() {
let server = TestServer::builder()
Expand Down

0 comments on commit c78bcd4

Please sign in to comment.