Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
a85ff2a54b | ||
|
97377a2442 | ||
|
0ea5f38f83 |
@ -16,6 +16,9 @@ mod error;
|
|||||||
mod service;
|
mod service;
|
||||||
mod statics;
|
mod statics;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
cdn::Cloudflare,
|
cdn::Cloudflare,
|
||||||
data::{FilePath, State},
|
data::{FilePath, State},
|
||||||
|
@ -9,28 +9,25 @@ lazy_static! {
|
|||||||
pub(crate) static ref USER_AGENT: String = format!("yagcdn/{}", VERSION);
|
pub(crate) static ref USER_AGENT: String = format!("yagcdn/{}", VERSION);
|
||||||
pub(crate) static ref OPT: Opt = Opt::from_args();
|
pub(crate) static ref OPT: Opt = Opt::from_args();
|
||||||
pub(crate) static ref GITHUB_AUTH_QUERY: Cow<'static, str> =
|
pub(crate) static ref GITHUB_AUTH_QUERY: Cow<'static, str> =
|
||||||
Github::auth_query().unwrap_or_default().into();
|
Github::auth_query().unwrap_or_default();
|
||||||
pub(crate) static ref CF_ZONE_IDENT: Cow<'static, str> = OPT
|
pub(crate) static ref CF_ZONE_IDENT: Cow<'static, str> = OPT
|
||||||
.cf_zone
|
.cf_zone
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(Cow::from)
|
.map(Cow::from)
|
||||||
.or_else(|| load_env_var("CF_ZONE_IDENT"))
|
.or_else(|| load_env_var("CF_ZONE_IDENT"))
|
||||||
.expect("Cloudflare zone identifier not set")
|
.expect("Cloudflare zone identifier not set");
|
||||||
.into();
|
|
||||||
pub(crate) static ref CF_AUTH_KEY: Cow<'static, str> = OPT
|
pub(crate) static ref CF_AUTH_KEY: Cow<'static, str> = OPT
|
||||||
.cf_auth_key
|
.cf_auth_key
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(Cow::from)
|
.map(Cow::from)
|
||||||
.or_else(|| load_env_var("CF_AUTH_KEY"))
|
.or_else(|| load_env_var("CF_AUTH_KEY"))
|
||||||
.expect("Cloudflare auth key not set")
|
.expect("Cloudflare auth key not set");
|
||||||
.into();
|
|
||||||
pub(crate) static ref CF_AUTH_USER: Cow<'static, str> = OPT
|
pub(crate) static ref CF_AUTH_USER: Cow<'static, str> = OPT
|
||||||
.cf_auth_user
|
.cf_auth_user
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(Cow::from)
|
.map(Cow::from)
|
||||||
.or_else(|| load_env_var("CF_AUTH_USER"))
|
.or_else(|| load_env_var("CF_AUTH_USER"))
|
||||||
.expect("Cloudflare auth user not set")
|
.expect("Cloudflare auth user not set");
|
||||||
.into();
|
|
||||||
pub(crate) static ref HOSTNAME: Cow<'static, str> = OPT
|
pub(crate) static ref HOSTNAME: Cow<'static, str> = OPT
|
||||||
.hostname
|
.hostname
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
125
backend/src/test/bitbucket.rs
Normal file
125
backend/src/test/bitbucket.rs
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
use crate::{
|
||||||
|
data::{Key, Service, State},
|
||||||
|
proxy_file, purge_local_cache, redirect,
|
||||||
|
service::Bitbucket,
|
||||||
|
REDIRECT_AGE,
|
||||||
|
};
|
||||||
|
use actix_web::{dev::Service as _, http::StatusCode, middleware, test, web, App};
|
||||||
|
use awc::Client;
|
||||||
|
use std::sync::{Arc, RwLock};
|
||||||
|
use time_cache::{Cache, CacheResult};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn requesting_branch_redirects() {
|
||||||
|
let state: State = Arc::new(RwLock::new(Cache::new(REDIRECT_AGE)));
|
||||||
|
let mut app = test::init_service(
|
||||||
|
App::new()
|
||||||
|
.data(Client::new())
|
||||||
|
.data(state)
|
||||||
|
.wrap(middleware::NormalizePath)
|
||||||
|
.route(
|
||||||
|
"/bitbucket/{user}/{repo}/{commit}/{file:.*}",
|
||||||
|
web::get().to_async(redirect::<Bitbucket>),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
let req =
|
||||||
|
test::TestRequest::with_uri("/bitbucket/vbrandl/vbrandl.net/master/README.md").to_request();
|
||||||
|
let resp = test::block_fn(|| app.call(req)).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(StatusCode::SEE_OTHER, resp.status());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn invalid_file_404() {
|
||||||
|
let state: State = Arc::new(RwLock::new(Cache::new(REDIRECT_AGE)));
|
||||||
|
let mut app = test::init_service(
|
||||||
|
App::new()
|
||||||
|
.data(Client::new())
|
||||||
|
.data(state)
|
||||||
|
.wrap(middleware::NormalizePath)
|
||||||
|
.route(
|
||||||
|
"/bitbucket/{user}/{repo}/{commit:[0-9a-fA-F]{40}}/{file:.*}",
|
||||||
|
web::get().to_async(proxy_file::<Bitbucket>),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
let req = test::TestRequest::with_uri(
|
||||||
|
"/bitbucket/vbrandl/vbrandl.net/369c392927a6d75f16c5dc38e2577276b94676bd/README.md.invalid",
|
||||||
|
)
|
||||||
|
.to_request();
|
||||||
|
let resp = test::block_fn(|| app.call(req)).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(StatusCode::NOT_FOUND, resp.status());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn valid_file_200() {
|
||||||
|
let state: State = Arc::new(RwLock::new(Cache::new(REDIRECT_AGE)));
|
||||||
|
let mut app = test::init_service(
|
||||||
|
App::new()
|
||||||
|
.data(Client::new())
|
||||||
|
.data(state)
|
||||||
|
.wrap(middleware::NormalizePath)
|
||||||
|
.route(
|
||||||
|
"/bitbucket/{user}/{repo}/{commit:[0-9a-fA-F]{40}}/{file:.*}",
|
||||||
|
web::get().to_async(proxy_file::<Bitbucket>),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
let req = test::TestRequest::with_uri(
|
||||||
|
"/bitbucket/vbrandl/vbrandl.net/369c392927a6d75f16c5dc38e2577276b94676bd/README.md",
|
||||||
|
)
|
||||||
|
.to_request();
|
||||||
|
let resp = test::block_fn(|| app.call(req)).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(StatusCode::OK, resp.status());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn redirect_cache() {
|
||||||
|
let state: State = Arc::new(RwLock::new(Cache::new(REDIRECT_AGE)));
|
||||||
|
let mut app = test::init_service(
|
||||||
|
App::new()
|
||||||
|
.data(Client::new())
|
||||||
|
.data(Arc::clone(&state))
|
||||||
|
.wrap(middleware::NormalizePath)
|
||||||
|
.route(
|
||||||
|
"/bitbucket/{user}/{repo}/{commit}/{file:.*}",
|
||||||
|
web::get().to_async(redirect::<Bitbucket>),
|
||||||
|
)
|
||||||
|
.route(
|
||||||
|
"/bitbucket/{user}/{repo}/{commit}/{file:.*}",
|
||||||
|
web::delete().to_async(purge_local_cache::<Bitbucket>),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
let req =
|
||||||
|
test::TestRequest::with_uri("/bitbucket/vbrandl/vbrandl.net/master/README.md").to_request();
|
||||||
|
let resp = test::block_fn(|| app.call(req)).unwrap();
|
||||||
|
assert_eq!(StatusCode::SEE_OTHER, resp.status());
|
||||||
|
|
||||||
|
let key = Key::new(
|
||||||
|
Service::Bitbucket,
|
||||||
|
Arc::new("vbrandl".to_string()),
|
||||||
|
Arc::new("vbrandl.net".to_string()),
|
||||||
|
Arc::new("master".to_string()),
|
||||||
|
);
|
||||||
|
{
|
||||||
|
let cache = state.read().unwrap();
|
||||||
|
let res = cache.get(&key);
|
||||||
|
assert_ne!(CacheResult::Empty, res);
|
||||||
|
assert_ne!(CacheResult::Invalid, res);
|
||||||
|
} // release the lock
|
||||||
|
|
||||||
|
let req = test::TestRequest::delete()
|
||||||
|
.uri("/bitbucket/vbrandl/vbrandl.net/master/README.md")
|
||||||
|
.to_request();
|
||||||
|
let resp = test::block_fn(|| app.call(req)).unwrap();
|
||||||
|
assert_eq!(StatusCode::OK, resp.status());
|
||||||
|
|
||||||
|
{
|
||||||
|
let cache = state.read().unwrap();
|
||||||
|
assert_eq!(CacheResult::Empty, cache.get(&key));
|
||||||
|
} // release the lock
|
||||||
|
}
|
123
backend/src/test/github.rs
Normal file
123
backend/src/test/github.rs
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
use crate::{
|
||||||
|
data::{Key, Service, State},
|
||||||
|
proxy_file, purge_local_cache, redirect,
|
||||||
|
service::Github,
|
||||||
|
REDIRECT_AGE,
|
||||||
|
};
|
||||||
|
use actix_web::{dev::Service as _, http::StatusCode, middleware, test, web, App};
|
||||||
|
use awc::Client;
|
||||||
|
use std::sync::{Arc, RwLock};
|
||||||
|
use time_cache::{Cache, CacheResult};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn requesting_branch_redirects() {
|
||||||
|
let state: State = Arc::new(RwLock::new(Cache::new(REDIRECT_AGE)));
|
||||||
|
let mut app = test::init_service(
|
||||||
|
App::new()
|
||||||
|
.data(Client::new())
|
||||||
|
.data(state)
|
||||||
|
.wrap(middleware::NormalizePath)
|
||||||
|
.route(
|
||||||
|
"/github/{user}/{repo}/{commit}/{file:.*}",
|
||||||
|
web::get().to_async(redirect::<Github>),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
let req = test::TestRequest::with_uri("/github/vbrandl/yagcdn/master/Cargo.toml").to_request();
|
||||||
|
let resp = test::block_fn(|| app.call(req)).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(StatusCode::SEE_OTHER, resp.status());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn invalid_file_404() {
|
||||||
|
let state: State = Arc::new(RwLock::new(Cache::new(REDIRECT_AGE)));
|
||||||
|
let mut app = test::init_service(
|
||||||
|
App::new()
|
||||||
|
.data(Client::new())
|
||||||
|
.data(state)
|
||||||
|
.wrap(middleware::NormalizePath)
|
||||||
|
.route(
|
||||||
|
"/github/{user}/{repo}/{commit:[0-9a-fA-F]{40}}/{file:.*}",
|
||||||
|
web::get().to_async(proxy_file::<Github>),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
let req = test::TestRequest::with_uri(
|
||||||
|
"/github/vbrandl/yagcdn/f1b35e7c05b952be6de559051d7daad2ecf05369/Cargo.toml.invalid",
|
||||||
|
)
|
||||||
|
.to_request();
|
||||||
|
let resp = test::block_fn(|| app.call(req)).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(StatusCode::NOT_FOUND, resp.status());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn valid_file_200() {
|
||||||
|
let state: State = Arc::new(RwLock::new(Cache::new(REDIRECT_AGE)));
|
||||||
|
let mut app = test::init_service(
|
||||||
|
App::new()
|
||||||
|
.data(Client::new())
|
||||||
|
.data(state)
|
||||||
|
.wrap(middleware::NormalizePath)
|
||||||
|
.route(
|
||||||
|
"/github/{user}/{repo}/{commit:[0-9a-fA-F]{40}}/{file:.*}",
|
||||||
|
web::get().to_async(proxy_file::<Github>),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
// github
|
||||||
|
let req = test::TestRequest::with_uri(
|
||||||
|
"/github/vbrandl/yagcdn/f1b35e7c05b952be6de559051d7daad2ecf05369/backend/Cargo.toml",
|
||||||
|
)
|
||||||
|
.to_request();
|
||||||
|
let resp = test::block_fn(|| app.call(req)).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(StatusCode::OK, resp.status());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn redirect_cache() {
|
||||||
|
let state: State = Arc::new(RwLock::new(Cache::new(REDIRECT_AGE)));
|
||||||
|
let mut app = test::init_service(
|
||||||
|
App::new()
|
||||||
|
.data(Client::new())
|
||||||
|
.data(Arc::clone(&state))
|
||||||
|
.wrap(middleware::NormalizePath)
|
||||||
|
.route(
|
||||||
|
"/github/{user}/{repo}/{commit}/{file:.*}",
|
||||||
|
web::get().to_async(redirect::<Github>),
|
||||||
|
)
|
||||||
|
.route(
|
||||||
|
"/github/{user}/{repo}/{commit}/{file:.*}",
|
||||||
|
web::delete().to_async(purge_local_cache::<Github>),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
let req = test::TestRequest::with_uri("/github/vbrandl/yagcdn/master/Cargo.toml").to_request();
|
||||||
|
let resp = test::block_fn(|| app.call(req)).unwrap();
|
||||||
|
assert_eq!(StatusCode::SEE_OTHER, resp.status());
|
||||||
|
|
||||||
|
let key = Key::new(
|
||||||
|
Service::GitHub,
|
||||||
|
Arc::new("vbrandl".to_string()),
|
||||||
|
Arc::new("yagcdn".to_string()),
|
||||||
|
Arc::new("master".to_string()),
|
||||||
|
);
|
||||||
|
{
|
||||||
|
let cache = state.read().unwrap();
|
||||||
|
let res = cache.get(&key);
|
||||||
|
assert_ne!(CacheResult::Empty, res);
|
||||||
|
assert_ne!(CacheResult::Invalid, res);
|
||||||
|
} // release the lock
|
||||||
|
|
||||||
|
let req = test::TestRequest::delete()
|
||||||
|
.uri("/github/vbrandl/yagcdn/master/Cargo.toml")
|
||||||
|
.to_request();
|
||||||
|
let resp = test::block_fn(|| app.call(req)).unwrap();
|
||||||
|
assert_eq!(StatusCode::OK, resp.status());
|
||||||
|
|
||||||
|
{
|
||||||
|
let cache = state.read().unwrap();
|
||||||
|
assert_eq!(CacheResult::Empty, cache.get(&key));
|
||||||
|
} // release the lock
|
||||||
|
}
|
123
backend/src/test/gitlab.rs
Normal file
123
backend/src/test/gitlab.rs
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
use crate::{
|
||||||
|
data::{Key, Service, State},
|
||||||
|
proxy_file, purge_local_cache, redirect,
|
||||||
|
service::GitLab,
|
||||||
|
REDIRECT_AGE,
|
||||||
|
};
|
||||||
|
use actix_web::{dev::Service as _, http::StatusCode, middleware, test, web, App};
|
||||||
|
use awc::Client;
|
||||||
|
use std::sync::{Arc, RwLock};
|
||||||
|
use time_cache::{Cache, CacheResult};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn requesting_branch_redirects() {
|
||||||
|
let state: State = Arc::new(RwLock::new(Cache::new(REDIRECT_AGE)));
|
||||||
|
let mut app = test::init_service(
|
||||||
|
App::new()
|
||||||
|
.data(Client::new())
|
||||||
|
.data(state)
|
||||||
|
.wrap(middleware::NormalizePath)
|
||||||
|
.route(
|
||||||
|
"/gitlab/{user}/{repo}/{commit}/{file:.*}",
|
||||||
|
web::get().to_async(redirect::<GitLab>),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
let req = test::TestRequest::with_uri("/gitlab/vbrandl/hoc/master/Cargo.toml").to_request();
|
||||||
|
let resp = test::block_fn(|| app.call(req)).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(StatusCode::SEE_OTHER, resp.status());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn invalid_file_404() {
|
||||||
|
let state: State = Arc::new(RwLock::new(Cache::new(REDIRECT_AGE)));
|
||||||
|
let mut app = test::init_service(
|
||||||
|
App::new()
|
||||||
|
.data(Client::new())
|
||||||
|
.data(state)
|
||||||
|
.wrap(middleware::NormalizePath)
|
||||||
|
.route(
|
||||||
|
"/gitlab/{user}/{repo}/{commit:[0-9a-fA-F]{40}}/{file:.*}",
|
||||||
|
web::get().to_async(proxy_file::<GitLab>),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
let req = test::TestRequest::with_uri(
|
||||||
|
"/gitlab/vbrandl/hoc/1223d429db877e46653260b15aa2bbd326bcd495/Cargo.toml.invalid",
|
||||||
|
)
|
||||||
|
.to_request();
|
||||||
|
let resp = test::block_fn(|| app.call(req)).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(StatusCode::NOT_FOUND, resp.status());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn valid_file_200() {
|
||||||
|
let state: State = Arc::new(RwLock::new(Cache::new(REDIRECT_AGE)));
|
||||||
|
let mut app = test::init_service(
|
||||||
|
App::new()
|
||||||
|
.data(Client::new())
|
||||||
|
.data(state)
|
||||||
|
.wrap(middleware::NormalizePath)
|
||||||
|
.route(
|
||||||
|
"/gitlab/{user}/{repo}/{commit:[0-9a-fA-F]{40}}/{file:.*}",
|
||||||
|
web::get().to_async(proxy_file::<GitLab>),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
let req = test::TestRequest::with_uri(
|
||||||
|
"/gitlab/vbrandl/hoc/1223d429db877e46653260b15aa2bbd326bcd495/Cargo.toml",
|
||||||
|
)
|
||||||
|
.to_request();
|
||||||
|
let resp = test::block_fn(|| app.call(req)).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(StatusCode::OK, resp.status());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn redirect_cache() {
|
||||||
|
let state: State = Arc::new(RwLock::new(Cache::new(REDIRECT_AGE)));
|
||||||
|
let mut app = test::init_service(
|
||||||
|
App::new()
|
||||||
|
.data(Client::new())
|
||||||
|
.data(Arc::clone(&state))
|
||||||
|
.wrap(middleware::NormalizePath)
|
||||||
|
.route(
|
||||||
|
"/gitlab/{user}/{repo}/{commit}/{file:.*}",
|
||||||
|
web::get().to_async(redirect::<GitLab>),
|
||||||
|
)
|
||||||
|
.route(
|
||||||
|
"/gitlab/{user}/{repo}/{commit}/{file:.*}",
|
||||||
|
web::delete().to_async(purge_local_cache::<GitLab>),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
let req = test::TestRequest::with_uri("/gitlab/vbrandl/hoc/master/Cargo.toml").to_request();
|
||||||
|
let resp = test::block_fn(|| app.call(req)).unwrap();
|
||||||
|
assert_eq!(StatusCode::SEE_OTHER, resp.status());
|
||||||
|
|
||||||
|
let key = Key::new(
|
||||||
|
Service::GitLab,
|
||||||
|
Arc::new("vbrandl".to_string()),
|
||||||
|
Arc::new("hoc".to_string()),
|
||||||
|
Arc::new("master".to_string()),
|
||||||
|
);
|
||||||
|
{
|
||||||
|
let cache = state.read().unwrap();
|
||||||
|
let res = cache.get(&key);
|
||||||
|
assert_ne!(CacheResult::Empty, res);
|
||||||
|
assert_ne!(CacheResult::Invalid, res);
|
||||||
|
} // release the lock
|
||||||
|
|
||||||
|
let req = test::TestRequest::delete()
|
||||||
|
.uri("/gitlab/vbrandl/hoc/master/Cargo.toml")
|
||||||
|
.to_request();
|
||||||
|
let resp = test::block_fn(|| app.call(req)).unwrap();
|
||||||
|
assert_eq!(StatusCode::OK, resp.status());
|
||||||
|
|
||||||
|
{
|
||||||
|
let cache = state.read().unwrap();
|
||||||
|
assert_eq!(CacheResult::Empty, cache.get(&key));
|
||||||
|
} // release the lock
|
||||||
|
}
|
3
backend/src/test/mod.rs
Normal file
3
backend/src/test/mod.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
mod bitbucket;
|
||||||
|
mod github;
|
||||||
|
mod gitlab;
|
Loading…
Reference in New Issue
Block a user