Update S3 features and make S3 support optional
This commit is contained in:
parent
10e06737cf
commit
1cb9459a23
@ -19,7 +19,6 @@ rocket = "0.4.11"
|
|||||||
rocket_contrib = { version = "0.4.11", features = ["json"] }
|
rocket_contrib = { version = "0.4.11", features = ["json"] }
|
||||||
rocket_i18n = "0.4.1"
|
rocket_i18n = "0.4.1"
|
||||||
scheduled-thread-pool = "0.2.6"
|
scheduled-thread-pool = "0.2.6"
|
||||||
#aws-creds = { version = "0.34", default-features = false, features = ["native-tls"] }
|
|
||||||
serde = "1.0.137"
|
serde = "1.0.137"
|
||||||
serde_json = "1.0.81"
|
serde_json = "1.0.81"
|
||||||
shrinkwraprs = "0.3.0"
|
shrinkwraprs = "0.3.0"
|
||||||
@ -69,7 +68,7 @@ ructe = "0.15.0"
|
|||||||
rsass = "0.26"
|
rsass = "0.26"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["postgres", "s3"]
|
default = ["postgres"]
|
||||||
postgres = ["plume-models/postgres", "diesel/postgres"]
|
postgres = ["plume-models/postgres", "diesel/postgres"]
|
||||||
sqlite = ["plume-models/sqlite", "diesel/sqlite"]
|
sqlite = ["plume-models/sqlite", "diesel/sqlite"]
|
||||||
debug-mailer = []
|
debug-mailer = []
|
||||||
|
@ -18,7 +18,6 @@ rocket_i18n = "0.4.1"
|
|||||||
reqwest = "0.11.11"
|
reqwest = "0.11.11"
|
||||||
scheduled-thread-pool = "0.2.6"
|
scheduled-thread-pool = "0.2.6"
|
||||||
serde = "1.0.137"
|
serde = "1.0.137"
|
||||||
#rust-s3 = { version = "0.29.0", default-features = false, features = ["blocking"] }
|
|
||||||
rust-s3 = { version = "0.33.0", optional = true, features = ["blocking"] }
|
rust-s3 = { version = "0.33.0", optional = true, features = ["blocking"] }
|
||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
||||||
serde_json = "1.0.81"
|
serde_json = "1.0.81"
|
||||||
|
@ -6,9 +6,8 @@ use rocket::Config as RocketConfig;
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::env::{self, var};
|
use std::env::{self, var};
|
||||||
|
|
||||||
use s3::{Bucket, Region};
|
#[cfg(feature = "s3")]
|
||||||
use s3::creds::Credentials;
|
use s3::{Bucket, Region, creds::Credentials};
|
||||||
|
|
||||||
|
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
const DB_NAME: &str = "plume";
|
const DB_NAME: &str = "plume";
|
||||||
@ -382,6 +381,7 @@ pub struct S3Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl S3Config {
|
impl S3Config {
|
||||||
|
#[cfg(feature = "s3")]
|
||||||
pub fn get_bucket(&self) -> Bucket {
|
pub fn get_bucket(&self) -> Bucket {
|
||||||
let region = Region::Custom {
|
let region = Region::Custom {
|
||||||
region: self.region.clone(),
|
region: self.region.clone(),
|
||||||
@ -411,41 +411,49 @@ fn get_s3_config() -> Option<S3Config> {
|
|||||||
if bucket.is_none() && access_key_id.is_none() && access_key_secret.is_none() {
|
if bucket.is_none() && access_key_id.is_none() && access_key_secret.is_none() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
if bucket.is_none() || access_key_id.is_none() || access_key_secret.is_none() {
|
|
||||||
panic!("Invalid S3 configuration: some required values are set, but not others");
|
#[cfg(not(feature = "s3"))]
|
||||||
|
panic!("S3 support is not enabled in this build");
|
||||||
|
|
||||||
|
#[cfg(feature = "s3")]
|
||||||
|
{
|
||||||
|
if bucket.is_none() || access_key_id.is_none() || access_key_secret.is_none() {
|
||||||
|
panic!("Invalid S3 configuration: some required values are set, but not others");
|
||||||
|
}
|
||||||
|
let bucket = bucket.unwrap();
|
||||||
|
let access_key_id = access_key_id.unwrap();
|
||||||
|
let access_key_secret = access_key_secret.unwrap();
|
||||||
|
|
||||||
|
let region = var("S3_REGION").unwrap_or_else(|_| "us-east-1".to_owned());
|
||||||
|
let hostname = var("S3_HOSTNAME").unwrap_or_else(|_| format!("{}.amazonaws.com", region));
|
||||||
|
|
||||||
|
let protocol = var("S3_PROTOCOL").unwrap_or_else(|_| "https".to_owned());
|
||||||
|
if protocol != "http" && protocol != "https" {
|
||||||
|
panic!("Invalid S3 configuration: invalid protocol {}", protocol);
|
||||||
|
}
|
||||||
|
|
||||||
|
let path_style = var("S3_PATH_STYLE").unwrap_or_else(|_| "false".to_owned());
|
||||||
|
let path_style = string_to_bool(&path_style, "S3_PATH_STYLE");
|
||||||
|
let direct_upload = var("S3_DIRECT_UPLOAD").unwrap_or_else(|_| "false".to_owned());
|
||||||
|
let direct_upload = string_to_bool(&direct_upload, "S3_DIRECT_UPLOAD");
|
||||||
|
let direct_download = var("S3_DIRECT_DOWNLOAD").unwrap_or_else(|_| "false".to_owned());
|
||||||
|
let direct_download = string_to_bool(&direct_download, "S3_DIRECT_DOWNLOAD");
|
||||||
|
|
||||||
|
let alias = var("S3_ALIAS_HOST").ok();
|
||||||
|
|
||||||
|
Some(S3Config {
|
||||||
|
bucket,
|
||||||
|
access_key_id,
|
||||||
|
access_key_secret,
|
||||||
|
region,
|
||||||
|
hostname,
|
||||||
|
protocol,
|
||||||
|
path_style,
|
||||||
|
direct_upload,
|
||||||
|
direct_download,
|
||||||
|
alias,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
let bucket = bucket.unwrap();
|
|
||||||
let access_key_id = access_key_id.unwrap();
|
|
||||||
let access_key_secret = access_key_secret.unwrap();
|
|
||||||
|
|
||||||
let region = var("S3_REGION").unwrap_or_else(|_| "us-east-1".to_owned());
|
|
||||||
let hostname = var("S3_HOSTNAME").unwrap_or_else(|_| format!("{}.amazonaws.com", region));
|
|
||||||
|
|
||||||
let protocol = var("S3_PROTOCOL").unwrap_or_else(|_| "https".to_owned());
|
|
||||||
if protocol != "http" && protocol != "https" {
|
|
||||||
panic!("Invalid S3 configuration: invalid protocol {}", protocol);
|
|
||||||
}
|
|
||||||
|
|
||||||
let path_style = var("S3_PATH_STYLE").unwrap_or_else(|_| "false".to_owned());
|
|
||||||
let path_style = string_to_bool(&path_style, "S3_PATH_STYLE");
|
|
||||||
let direct_upload = var("S3_DIRECT_UPLOAD").unwrap_or_else(|_| "false".to_owned());
|
|
||||||
let direct_upload = string_to_bool(&direct_upload, "S3_DIRECT_UPLOAD");
|
|
||||||
let direct_download = var("S3_DIRECT_DOWNLOAD").unwrap_or_else(|_| "false".to_owned());
|
|
||||||
let direct_download = string_to_bool(&direct_download, "S3_DIRECT_DOWNLOAD");
|
|
||||||
|
|
||||||
let alias = var("S3_ALIAS_HOST").ok();
|
|
||||||
Some(S3Config {
|
|
||||||
bucket,
|
|
||||||
access_key_id,
|
|
||||||
access_key_secret,
|
|
||||||
region,
|
|
||||||
hostname,
|
|
||||||
protocol,
|
|
||||||
path_style,
|
|
||||||
direct_upload,
|
|
||||||
direct_download,
|
|
||||||
alias,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
|
@ -170,9 +170,12 @@ impl Media {
|
|||||||
|
|
||||||
pub fn delete(&self, conn: &Connection) -> Result<()> {
|
pub fn delete(&self, conn: &Connection) -> Result<()> {
|
||||||
if !self.is_remote {
|
if !self.is_remote {
|
||||||
if let Some(config) = &CONFIG.s3 {
|
if CONFIG.s3.is_some() {
|
||||||
config.get_bucket()
|
#[cfg(feature = "s3")]
|
||||||
|
CONFIG.s3.as_ref().unwrap().get_bucket()
|
||||||
.delete_object_blocking(&self.file_path)?;
|
.delete_object_blocking(&self.file_path)?;
|
||||||
|
#[cfg(not(feature="s3"))]
|
||||||
|
unreachable!();
|
||||||
} else {
|
} else {
|
||||||
fs::remove_file(self.file_path.as_str())?;
|
fs::remove_file(self.file_path.as_str())?;
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ use rocket::{
|
|||||||
http::{
|
http::{
|
||||||
hyper::header::{CacheControl, CacheDirective, ETag, EntityTag},
|
hyper::header::{CacheControl, CacheDirective, ETag, EntityTag},
|
||||||
uri::{FromUriParam, Query},
|
uri::{FromUriParam, Query},
|
||||||
ContentType, RawStr, Status,
|
RawStr, Status,
|
||||||
},
|
},
|
||||||
request::{self, FromFormValue, FromRequest, Request},
|
request::{self, FromFormValue, FromRequest, Request},
|
||||||
response::{self, Flash, NamedFile, Redirect, Responder, Response},
|
response::{self, Flash, NamedFile, Redirect, Responder, Response},
|
||||||
@ -21,6 +21,9 @@ use std::{
|
|||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[cfg(feature = "s3")]
|
||||||
|
use rocket::http::ContentType;
|
||||||
|
|
||||||
/// Special return type used for routes that "cannot fail", and instead
|
/// Special return type used for routes that "cannot fail", and instead
|
||||||
/// `Redirect`, or `Flash<Redirect>`, when we cannot deliver a `Ructe` Response
|
/// `Redirect`, or `Flash<Redirect>`, when we cannot deliver a `Ructe` Response
|
||||||
#[allow(clippy::large_enum_variant)]
|
#[allow(clippy::large_enum_variant)]
|
||||||
@ -207,6 +210,7 @@ pub mod well_known;
|
|||||||
#[derive(Responder)]
|
#[derive(Responder)]
|
||||||
enum FileKind {
|
enum FileKind {
|
||||||
Local(NamedFile),
|
Local(NamedFile),
|
||||||
|
#[cfg(feature = "s3")]
|
||||||
S3(Vec<u8>, ContentType),
|
S3(Vec<u8>, ContentType),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,18 +263,23 @@ pub fn plume_static_files(file: PathBuf, build_id: &RawStr) -> Option<CachedFile
|
|||||||
}
|
}
|
||||||
#[get("/static/media/<file..>")]
|
#[get("/static/media/<file..>")]
|
||||||
pub fn plume_media_files(file: PathBuf) -> Option<CachedFile> {
|
pub fn plume_media_files(file: PathBuf) -> Option<CachedFile> {
|
||||||
if let Some(config) = &CONFIG.s3 {
|
if CONFIG.s3.is_some() {
|
||||||
let ct = file.extension()
|
#[cfg(feature="s3")]
|
||||||
.and_then(|ext| ContentType::from_extension(&ext.to_string_lossy()))
|
{
|
||||||
.unwrap_or(ContentType::Binary);
|
let ct = file.extension()
|
||||||
|
.and_then(|ext| ContentType::from_extension(&ext.to_string_lossy()))
|
||||||
|
.unwrap_or(ContentType::Binary);
|
||||||
|
|
||||||
let data = config.get_bucket()
|
let data = CONFIG.s3.as_ref().unwrap().get_bucket()
|
||||||
.get_object_blocking(format!("plume-media/{}", file.to_string_lossy())).ok()?;
|
.get_object_blocking(format!("plume-media/{}", file.to_string_lossy())).ok()?;
|
||||||
|
|
||||||
Some(CachedFile {
|
Some(CachedFile {
|
||||||
inner: FileKind::S3 ( data.to_vec(), ct),
|
inner: FileKind::S3 ( data.to_vec(), ct),
|
||||||
cache_control: CacheControl(vec![CacheDirective::MaxAge(60 * 60 * 24 * 30)]),
|
cache_control: CacheControl(vec![CacheDirective::MaxAge(60 * 60 * 24 * 30)]),
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
#[cfg(not(feature="s3"))]
|
||||||
|
unreachable!();
|
||||||
} else {
|
} else {
|
||||||
NamedFile::open(Path::new(&CONFIG.media_directory).join(file))
|
NamedFile::open(Path::new(&CONFIG.media_directory).join(file))
|
||||||
.ok()
|
.ok()
|
||||||
|
Loading…
Reference in New Issue
Block a user