mirror of
https://github.com/deps-rs/deps.rs.git
synced 2024-11-22 10:26:30 +00:00
implement redirect for crate report
This commit is contained in:
parent
8939b41e32
commit
e0352539bd
3 changed files with 86 additions and 7 deletions
|
@ -9,6 +9,7 @@ use hyper::Client;
|
||||||
use hyper::client::HttpConnector;
|
use hyper::client::HttpConnector;
|
||||||
use hyper_tls::HttpsConnector;
|
use hyper_tls::HttpsConnector;
|
||||||
use relative_path::{RelativePath, RelativePathBuf};
|
use relative_path::{RelativePath, RelativePathBuf};
|
||||||
|
use semver::VersionReq;
|
||||||
use slog::Logger;
|
use slog::Logger;
|
||||||
use tokio_service::Service;
|
use tokio_service::Service;
|
||||||
|
|
||||||
|
@ -136,6 +137,23 @@ impl Engine {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn find_latest_crate_release(&self, name: CrateName, req: Option<VersionReq>) ->
|
||||||
|
impl Future<Item=Option<CrateRelease>, Error=Error>
|
||||||
|
{
|
||||||
|
self.query_crate.call(name).from_err().map(move |query_response| {
|
||||||
|
if let Some(vreq) = req {
|
||||||
|
query_response.releases.iter()
|
||||||
|
.filter(|release| vreq.matches(&release.version))
|
||||||
|
.max_by(|r1, r2| r1.version.cmp(&r2.version))
|
||||||
|
.cloned()
|
||||||
|
} else {
|
||||||
|
query_response.releases.iter()
|
||||||
|
.max_by(|r1, r2| r1.version.cmp(&r2.version))
|
||||||
|
.cloned()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn fetch_releases<I: IntoIterator<Item=CrateName>>(&self, names: I) ->
|
fn fetch_releases<I: IntoIterator<Item=CrateName>>(&self, names: I) ->
|
||||||
impl Iterator<Item=impl Future<Item=Vec<CrateRelease>, Error=Error>>
|
impl Iterator<Item=impl Future<Item=Vec<CrateRelease>, Error=Error>>
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
|
use std::env;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use futures::{Future, IntoFuture, future};
|
use futures::{Future, IntoFuture, future};
|
||||||
use hyper::{Error as HyperError, Method, Request, Response, StatusCode};
|
use hyper::{Error as HyperError, Method, Request, Response, StatusCode};
|
||||||
use hyper::header::ContentType;
|
use hyper::header::{ContentType, Location};
|
||||||
use route_recognizer::{Params, Router};
|
use route_recognizer::{Params, Router};
|
||||||
use slog::Logger;
|
use slog::Logger;
|
||||||
use tokio_service::Service;
|
use tokio_service::Service;
|
||||||
|
@ -11,7 +12,7 @@ mod assets;
|
||||||
mod views;
|
mod views;
|
||||||
|
|
||||||
use ::engine::{Engine, AnalyzeDependenciesOutcome};
|
use ::engine::{Engine, AnalyzeDependenciesOutcome};
|
||||||
use ::models::crates::CratePath;
|
use ::models::crates::{CrateName, CratePath};
|
||||||
use ::models::repo::RepoPath;
|
use ::models::repo::RepoPath;
|
||||||
use ::models::SubjectPath;
|
use ::models::SubjectPath;
|
||||||
|
|
||||||
|
@ -31,6 +32,7 @@ enum Route {
|
||||||
Index,
|
Index,
|
||||||
Static(StaticFile),
|
Static(StaticFile),
|
||||||
RepoStatus(StatusFormat),
|
RepoStatus(StatusFormat),
|
||||||
|
CrateRedirect,
|
||||||
CrateStatus(StatusFormat)
|
CrateStatus(StatusFormat)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,6 +55,7 @@ impl Server {
|
||||||
router.add("/repo/:site/:qual/:name", Route::RepoStatus(StatusFormat::Html));
|
router.add("/repo/:site/:qual/:name", Route::RepoStatus(StatusFormat::Html));
|
||||||
router.add("/repo/:site/:qual/:name/status.svg", Route::RepoStatus(StatusFormat::Svg));
|
router.add("/repo/:site/:qual/:name/status.svg", Route::RepoStatus(StatusFormat::Svg));
|
||||||
|
|
||||||
|
router.add("/crate/:name", Route::CrateRedirect);
|
||||||
router.add("/crate/:name/:version", Route::CrateStatus(StatusFormat::Html));
|
router.add("/crate/:name/:version", Route::CrateStatus(StatusFormat::Html));
|
||||||
router.add("/crate/:name/:version/status.svg", Route::CrateStatus(StatusFormat::Svg));
|
router.add("/crate/:name/:version/status.svg", Route::CrateStatus(StatusFormat::Svg));
|
||||||
|
|
||||||
|
@ -86,6 +89,11 @@ impl Service for Server {
|
||||||
return Box::new(self.crate_status(req, route_match.params, logger, format));
|
return Box::new(self.crate_status(req, route_match.params, logger, format));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
&Route::CrateRedirect => {
|
||||||
|
if *req.method() == Method::Get {
|
||||||
|
return Box::new(self.crate_redirect(req, route_match.params, logger));
|
||||||
|
}
|
||||||
|
},
|
||||||
&Route::Static(file) => {
|
&Route::Static(file) => {
|
||||||
if *req.method() == Method::Get {
|
if *req.method() == Method::Get {
|
||||||
return Box::new(future::ok(Server::static_file(file)));
|
return Box::new(future::ok(Server::static_file(file)));
|
||||||
|
@ -156,6 +164,55 @@ impl Server {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn crate_redirect(&self, _req: Request, params: Params, logger: Logger) ->
|
||||||
|
impl Future<Item=Response, Error=HyperError>
|
||||||
|
{
|
||||||
|
let engine = self.engine.clone();
|
||||||
|
|
||||||
|
let name = params.find("name").expect("route param 'name' not found");
|
||||||
|
|
||||||
|
name.parse::<CrateName>().into_future().then(move |crate_name_result| {
|
||||||
|
match crate_name_result {
|
||||||
|
Err(err) => {
|
||||||
|
error!(logger, "error: {}", err);
|
||||||
|
let mut response = views::html::error::render("Could not parse crate name",
|
||||||
|
"Please make sure to provide a valid crate name.");
|
||||||
|
response.set_status(StatusCode::BadRequest);
|
||||||
|
future::Either::A(future::ok(response))
|
||||||
|
},
|
||||||
|
Ok(crate_name) => {
|
||||||
|
future::Either::B(engine.find_latest_crate_release(crate_name, None).then(move |release_result| {
|
||||||
|
match release_result {
|
||||||
|
Err(err) => {
|
||||||
|
error!(logger, "error: {}", err);
|
||||||
|
let mut response = views::html::error::render("Could not fetch crate information",
|
||||||
|
"Please make sure to provide a valid crate name.");
|
||||||
|
response.set_status(StatusCode::NotFound);
|
||||||
|
future::ok(response)
|
||||||
|
},
|
||||||
|
Ok(None) => {
|
||||||
|
let mut response = views::html::error::render("Could not fetch crate information",
|
||||||
|
"Please make sure to provide a valid crate name.");
|
||||||
|
response.set_status(StatusCode::NotFound);
|
||||||
|
future::ok(response)
|
||||||
|
},
|
||||||
|
Ok(Some(release)) => {
|
||||||
|
let mut response = Response::new();
|
||||||
|
response.set_status(StatusCode::TemporaryRedirect);
|
||||||
|
let url = format!("{}/crate/{}/{}",
|
||||||
|
&SELF_BASE_URL as &str,
|
||||||
|
release.name.as_ref(),
|
||||||
|
release.version);
|
||||||
|
response.headers_mut().set(Location::new(url));
|
||||||
|
future::ok(response)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn crate_status(&self, _req: Request, params: Params, logger: Logger, format: StatusFormat) ->
|
fn crate_status(&self, _req: Request, params: Params, logger: Logger, format: StatusFormat) ->
|
||||||
impl Future<Item=Response, Error=HyperError>
|
impl Future<Item=Response, Error=HyperError>
|
||||||
{
|
{
|
||||||
|
@ -216,3 +273,10 @@ impl Server {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref SELF_BASE_URL: String = {
|
||||||
|
env::var("BASE_URL")
|
||||||
|
.unwrap_or_else(|_| "http://localhost:8080".to_string())
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -9,12 +9,9 @@ pub mod index;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod status;
|
pub mod status;
|
||||||
|
|
||||||
lazy_static! {
|
use super::super::SELF_BASE_URL;
|
||||||
static ref SELF_BASE_URL: String = {
|
|
||||||
env::var("BASE_URL")
|
|
||||||
.unwrap_or_else(|_| "http://localhost:8080".to_string())
|
|
||||||
};
|
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
static ref GAUGES_SITE_ID: Option<String> = {
|
static ref GAUGES_SITE_ID: Option<String> = {
|
||||||
env::var("GAUGES_SITE_ID").ok().map(|s| s.to_string())
|
env::var("GAUGES_SITE_ID").ok().map(|s| s.to_string())
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue