Cleanup and a bit less heap allocation

This commit is contained in:
Valentin Brandl 2019-08-09 16:19:55 +02:00
parent 16a5ac7553
commit 44cf0c93a2
No known key found for this signature in database
GPG Key ID: 30D341DD34118D7D
2 changed files with 96 additions and 113 deletions

View File

@ -13,7 +13,7 @@ impl Cloudflare {
&CF_ZONE_IDENT &CF_ZONE_IDENT
} }
pub(crate) fn dbg<T: Service>( pub(crate) fn purge_cache<T: Service>(
client: &Client, client: &Client,
file: &str, file: &str,
) -> impl Future<Item = HttpResponse, Error = Error> { ) -> impl Future<Item = HttpResponse, Error = Error> {
@ -31,29 +31,23 @@ impl Cloudflare {
.send_json(&payload) .send_json(&payload)
.from_err() .from_err()
.and_then(|response| HttpResponse::build(response.status()).streaming(response)) .and_then(|response| HttpResponse::build(response.status()).streaming(response))
} // client
// .post(format!(
pub(crate) fn purge_cache<T: Service>( // "https://api.cloudflare.com/client/v4/zones/{}/purge_cache",
client: &Client, // Self::identifier()
file: &str, // ))
) -> impl Future<Item = bool, Error = Error> { // .header(header::USER_AGENT, statics::USER_AGENT.as_str())
client // .header("X-Auth-Email", Self::auth_email())
.post(format!( // .header("X-Auth-Key", Self::auth_key())
"https://api.cloudflare.com/client/v4/zones/{}/purge_cache", // .content_type("application/json")
Self::identifier() // .send_json(&CfPurgeRequest::singleton::<T>(file))
)) // .from_err()
.header(header::USER_AGENT, statics::USER_AGENT.as_str()) // .and_then(|mut response| {
.header("X-Auth-Email", Self::auth_email()) // response
.header("X-Auth-Key", Self::auth_key()) // .json::<CfPurgeResponse>()
.content_type("application/json") // .map(|resp| resp.success)
.send_json(&CfPurgeRequest::singleton::<T>(file)) // .from_err()
.from_err() // })
.and_then(|mut response| {
response
.json::<CfPurgeResponse>()
.map(|resp| resp.success)
.from_err()
})
} }
fn auth_key() -> &'static str { fn auth_key() -> &'static str {
@ -83,7 +77,7 @@ impl CfPurgeRequest {
} }
} }
#[derive(Deserialize)] // #[derive(Deserialize)]
struct CfPurgeResponse { // struct CfPurgeResponse {
success: bool, // success: bool,
} // }

View File

@ -35,32 +35,30 @@ use time_cache::{Cache, CacheResult};
fn proxy_file<T: Service>( fn proxy_file<T: Service>(
client: web::Data<Client>, client: web::Data<Client>,
data: web::Path<FilePath>, data: web::Path<FilePath>,
) -> Box<dyn Future<Item = HttpResponse, Error = Error>> { ) -> impl Future<Item = HttpResponse, Error = Error> {
Box::new( client
client .get(&T::raw_url(
.get(&T::raw_url( &data.user,
&data.user, &data.repo,
&data.repo, &data.commit,
&data.commit, &data.file,
&data.file, ))
)) .header(header::USER_AGENT, statics::USER_AGENT.as_str())
.header(header::USER_AGENT, statics::USER_AGENT.as_str()) .send()
.send() .from_err()
.from_err() .and_then(move |response| match response.status() {
.and_then(move |response| match response.status() { StatusCode::OK => {
StatusCode::OK => { let mime = mime_guess::guess_mime_type(&*data.file);
let mime = mime_guess::guess_mime_type(&*data.file); Ok(HttpResponse::Ok()
Ok(HttpResponse::Ok() .content_type(mime.to_string().as_str())
.content_type(mime.to_string().as_str()) .set(CacheControl(vec![
.set(CacheControl(vec![ CacheDirective::Public,
CacheDirective::Public, CacheDirective::MaxAge(2_592_000_000),
CacheDirective::MaxAge(2_592_000_000), ]))
])) .streaming(response))
.streaming(response)) }
} code => Ok(HttpResponse::build(code).finish()),
code => Ok(HttpResponse::build(code).finish()), })
}),
)
} }
fn redirect<T: Service>( fn redirect<T: Service>(
@ -109,18 +107,6 @@ fn redirect<T: Service>(
) )
} }
fn handle_request<T: Service>(
client: web::Data<Client>,
cache: web::Data<State>,
data: web::Path<FilePath>,
) -> Box<dyn Future<Item = HttpResponse, Error = Error>> {
if data.commit.len() == 40 {
proxy_file::<T>(client, data)
} else {
redirect::<T>(client, cache, data)
}
}
fn serve_gist( fn serve_gist(
client: web::Data<Client>, client: web::Data<Client>,
data: web::Path<FilePath>, data: web::Path<FilePath>,
@ -160,49 +146,28 @@ fn favicon32() -> HttpResponse {
.body(FAVICON) .body(FAVICON)
} }
fn purge_cache<T: 'static + Service>( fn purge_local_cache<T: 'static + Service>(
client: web::Data<Client>,
cache: web::Data<State>, cache: web::Data<State>,
data: web::Path<FilePath>, data: web::Path<FilePath>,
) -> Box<dyn Future<Item = HttpResponse, Error = Error>> { ) -> impl Future<Item = HttpResponse, Error = Error> {
if data.commit.len() == 40 { let cache = cache.clone();
Box::new( futures::future::ok(()).map(move |_| {
Cloudflare::purge_cache::<T>(&client, &data.path()) if let Ok(mut cache) = cache.write() {
.map(|success| HttpResponse::Ok().body(success.to_string())), let key = data.to_key::<T>();
) cache.invalidate(&key);
} else { HttpResponse::Ok().finish()
let cache = cache.clone(); } else {
Box::new(futures::future::ok(()).map(move |_| { HttpResponse::InternalServerError().finish()
if let Ok(mut cache) = cache.write() { }
let key = data.to_key::<T>(); })
cache.invalidate(&key);
HttpResponse::Ok().finish()
} else {
HttpResponse::InternalServerError().finish()
}
}))
}
} }
fn dbg<T: 'static + Service>( fn purge_cf_cache<T: 'static + Service>(
client: web::Data<Client>, client: web::Data<Client>,
cache: web::Data<State>,
data: web::Path<FilePath>, data: web::Path<FilePath>,
) -> Box<dyn Future<Item = HttpResponse, Error = Error>> { ) -> impl Future<Item = HttpResponse, Error = Error> {
if data.commit.len() == 40 { Cloudflare::purge_cache::<T>(&client, &data.path())
Box::new(Cloudflare::dbg::<T>(&client, &data.path())) // .map(|success| HttpResponse::Ok().body(success.to_string()))
} else {
let cache = cache.clone();
Box::new(futures::future::ok(()).map(move |_| {
if let Ok(mut cache) = cache.write() {
let key = data.to_key::<T>();
cache.invalidate(&key);
HttpResponse::Ok().finish()
} else {
HttpResponse::InternalServerError().finish()
}
}))
}
} }
fn main() -> Result<()> { fn main() -> Result<()> {
@ -219,33 +184,57 @@ fn main() -> Result<()> {
.wrap(middleware::NormalizePath) .wrap(middleware::NormalizePath)
.service(favicon32) .service(favicon32)
.route( .route(
"/github/{user}/{repo}/{commit}/{file:.*}", "/github/{user}/{repo}/{commit:[0-9a-fA-F]{40}}/{file:.*}",
web::get().to_async(handle_request::<Github>), web::get().to_async(proxy_file::<Github>),
) )
.route( .route(
"/github/{user}/{repo}/{commit}/{file:.*}", "/github/{user}/{repo}/{commit}/{file:.*}",
web::delete().to_async(dbg::<Github>), web::get().to_async(redirect::<Github>),
)
.route(
"/github/{user}/{repo}/{commit:[0-9a-fA-F]{40}}/{file:.*}",
web::delete().to_async(purge_cf_cache::<Github>),
)
.route(
"/github/{user}/{repo}/{commit}/{file:.*}",
web::delete().to_async(purge_local_cache::<Github>),
)
.route(
"/bitbucket/{user}/{repo}/{commit:[0-9a-fA-F]{40}}/{file:.*}",
web::get().to_async(proxy_file::<Bitbucket>),
) )
.route( .route(
"/bitbucket/{user}/{repo}/{commit}/{file:.*}", "/bitbucket/{user}/{repo}/{commit}/{file:.*}",
web::get().to_async(handle_request::<Bitbucket>), web::get().to_async(redirect::<Bitbucket>),
)
.route(
"/bitbucket/{user}/{repo}/{commit:[0-9a-fA-F]{40}}/{file:.*}",
web::delete().to_async(purge_cf_cache::<Bitbucket>),
) )
.route( .route(
"/bitbucket/{user}/{repo}/{commit}/{file:.*}", "/bitbucket/{user}/{repo}/{commit}/{file:.*}",
web::delete().to_async(dbg::<Bitbucket>), web::delete().to_async(purge_local_cache::<Bitbucket>),
)
.route(
"/gitlab/{user}/{repo}/{commit:[0-9a-fA-F]{40}}/{file:.*}",
web::get().to_async(proxy_file::<GitLab>),
) )
.route( .route(
"/gitlab/{user}/{repo}/{commit}/{file:.*}", "/gitlab/{user}/{repo}/{commit}/{file:.*}",
web::get().to_async(handle_request::<GitLab>), web::get().to_async(redirect::<GitLab>),
)
.route(
"/gitlab/{user}/{repo}/{commit:[0-9a-fA-F]{40}}/{file:.*}",
web::delete().to_async(purge_cf_cache::<GitLab>),
)
.route(
"/gitlab/{user}/{repo}/{commit}/{file:.*}",
web::delete().to_async(purge_cf_cache::<GitLab>),
) )
.route( .route(
"/gist/{user}/{repo}/{commit}/{file:.*}", "/gist/{user}/{repo}/{commit}/{file:.*}",
web::get().to_async(serve_gist), web::get().to_async(serve_gist),
) )
.route(
"/gitlab/{user}/{repo}/{commit}/{file:.*}",
web::delete().to_async(dbg::<GitLab>),
)
.service(actix_files::Files::new("/", "./public").index_file("index.html")) .service(actix_files::Files::new("/", "./public").index_file("index.html"))
}) })
.workers(OPT.workers) .workers(OPT.workers)