mirror of https://github.com/rwf2/Rocket.git
Use 'RelativePathBuf' as 'Config.temp_dir' type.
This makes a relative 'temp_dir' declared in a config file relative to the config file itself.
This commit is contained in:
parent
c3ee34e295
commit
76ec847a58
|
@ -46,7 +46,7 @@ atomic = "0.5"
|
|||
parking_lot = "0.11"
|
||||
ubyte = {version = "0.10", features = ["serde"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
figment = { version = "0.10.4", features = ["toml", "env"] }
|
||||
figment = { version = "0.10.6", features = ["toml", "env"] }
|
||||
rand = "0.8"
|
||||
either = "1"
|
||||
pin-project-lite = "0.2"
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
use std::path::PathBuf;
|
||||
use std::net::{IpAddr, Ipv4Addr};
|
||||
|
||||
use figment::{Figment, Profile, Provider, Metadata, error::Result};
|
||||
use figment::providers::{Serialized, Env, Toml, Format};
|
||||
use figment::value::{Map, Dict};
|
||||
use figment::value::{Map, Dict, magic::RelativePathBuf};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use yansi::Paint;
|
||||
|
||||
|
@ -87,7 +86,8 @@ pub struct Config {
|
|||
pub secret_key: SecretKey,
|
||||
/// Directory to store temporary files in. **(default:
|
||||
/// [`std::env::temp_dir()`])**
|
||||
pub temp_dir: PathBuf,
|
||||
#[serde(serialize_with = "RelativePathBuf::serialize_relative")]
|
||||
pub temp_dir: RelativePathBuf,
|
||||
/// Max level to log. **(default: _debug_ `normal` / _release_ `critical`)**
|
||||
pub log_level: LogLevel,
|
||||
/// Graceful shutdown configuration. **(default: [`Shutdown::default()`])**
|
||||
|
@ -167,7 +167,7 @@ impl Config {
|
|||
ident: Ident::default(),
|
||||
#[cfg(feature = "secrets")]
|
||||
secret_key: SecretKey::zero(),
|
||||
temp_dir: std::env::temp_dir(),
|
||||
temp_dir: std::env::temp_dir().into(),
|
||||
log_level: LogLevel::Normal,
|
||||
shutdown: Shutdown::default(),
|
||||
cli_colors: true,
|
||||
|
@ -335,7 +335,7 @@ impl Config {
|
|||
}
|
||||
}
|
||||
|
||||
launch_info_!("temp dir: {}", Paint::default(&self.temp_dir.display()).bold());
|
||||
launch_info_!("temp dir: {}", Paint::default(&self.temp_dir.relative().display()).bold());
|
||||
launch_info_!("log level: {}", Paint::default(self.log_level).bold());
|
||||
launch_info_!("cli colors: {}", Paint::default(&self.cli_colors).bold());
|
||||
launch_info_!("shutdown: {}", Paint::default(&self.shutdown).bold());
|
||||
|
@ -369,6 +369,7 @@ impl Config {
|
|||
}
|
||||
}
|
||||
|
||||
/// Associated constants for default profiles.
|
||||
impl Config {
|
||||
/// The default debug profile: `debug`.
|
||||
pub const DEBUG_PROFILE: Profile = Profile::const_new("debug");
|
||||
|
@ -386,6 +387,7 @@ impl Config {
|
|||
|
||||
}
|
||||
|
||||
/// Associated constants for stringy versions of configuration parameters.
|
||||
impl Config {
|
||||
/// The stringy parameter name for setting/extracting [`Config::profile`].
|
||||
///
|
||||
|
@ -421,6 +423,9 @@ impl Config {
|
|||
|
||||
/// The stringy parameter name for setting/extracting [`Config::shutdown`].
|
||||
pub const SHUTDOWN: &'static str = "shutdown";
|
||||
|
||||
/// The stringy parameter name for setting/extracting [`Config::cli_colors`].
|
||||
pub const CLI_COLORS: &'static str = "cli_colors";
|
||||
}
|
||||
|
||||
impl Provider for Config {
|
||||
|
|
|
@ -45,7 +45,7 @@ use either::Either;
|
|||
///
|
||||
/// | Name | Default | Description |
|
||||
/// |--------------------|---------------------|-----------------------------------------|
|
||||
/// | `temp_dir` | [`env::temp_dir()`] | Directory files are temporarily stored. |
|
||||
/// | `temp_dir` | [`env::temp_dir()`] | Directory for temporary file storage. |
|
||||
/// | `limits.file` | 1MiB | Default limit for all file extensions. |
|
||||
/// | `limits.file/$ext` | _N/A_ | Limit for files with extension `$ext`. |
|
||||
///
|
||||
|
@ -451,7 +451,7 @@ impl<'v> TempFile<'v> {
|
|||
.or_else(|| req.limits().get("file"))
|
||||
.unwrap_or(Limits::FILE);
|
||||
|
||||
let temp_dir = req.rocket().config().temp_dir.clone();
|
||||
let temp_dir = req.rocket().config().temp_dir.relative();
|
||||
let file = tokio::task::spawn_blocking(move || {
|
||||
NamedTempFile::new_in(temp_dir)
|
||||
}).await.map_err(|_| {
|
||||
|
|
|
@ -182,7 +182,7 @@ impl Rocket<Build> {
|
|||
/// let config = Config {
|
||||
/// port: 7777,
|
||||
/// address: Ipv4Addr::new(18, 127, 0, 1).into(),
|
||||
/// temp_dir: PathBuf::from("/tmp/config-example"),
|
||||
/// temp_dir: "/tmp/config-example".into(),
|
||||
/// ..Config::debug_default()
|
||||
/// };
|
||||
///
|
||||
|
@ -190,7 +190,7 @@ impl Rocket<Build> {
|
|||
/// let rocket = rocket::custom(&config).ignite().await?;
|
||||
/// assert_eq!(rocket.config().port, 7777);
|
||||
/// assert_eq!(rocket.config().address, Ipv4Addr::new(18, 127, 0, 1));
|
||||
/// assert_eq!(rocket.config().temp_dir, Path::new("/tmp/config-example"));
|
||||
/// assert_eq!(rocket.config().temp_dir.relative(), Path::new("/tmp/config-example"));
|
||||
///
|
||||
/// // Create a new figment which modifies _some_ keys the existing figment:
|
||||
/// let figment = rocket.figment().clone()
|
||||
|
@ -203,7 +203,7 @@ impl Rocket<Build> {
|
|||
///
|
||||
/// assert_eq!(rocket.config().port, 8888);
|
||||
/// assert_eq!(rocket.config().address, Ipv4Addr::new(171, 64, 200, 10));
|
||||
/// assert_eq!(rocket.config().temp_dir, Path::new("/tmp/config-example"));
|
||||
/// assert_eq!(rocket.config().temp_dir.relative(), Path::new("/tmp/config-example"));
|
||||
/// # Ok(())
|
||||
/// # });
|
||||
/// ```
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
use std::env;
|
||||
|
||||
use rocket::{Request, Route, Catcher, route, catcher};
|
||||
use rocket::data::{Data, ToByteUnit};
|
||||
use rocket::http::{Status, Method::{Get, Post}};
|
||||
|
@ -43,7 +41,8 @@ fn upload<'r>(req: &'r Request, data: Data<'r>) -> route::BoxFuture<'r> {
|
|||
return route::Outcome::failure(Status::BadRequest);
|
||||
}
|
||||
|
||||
let file = File::create(env::temp_dir().join("upload.txt")).await;
|
||||
let path = req.rocket().config().temp_dir.relative().join("upload.txt");
|
||||
let file = File::create(path).await;
|
||||
if let Ok(file) = file {
|
||||
if let Ok(n) = data.open(2.mebibytes()).stream_to(file).await {
|
||||
return route::Outcome::from(req, format!("OK: {} bytes uploaded.", n));
|
||||
|
@ -59,7 +58,8 @@ fn upload<'r>(req: &'r Request, data: Data<'r>) -> route::BoxFuture<'r> {
|
|||
}
|
||||
|
||||
fn get_upload<'r>(req: &'r Request, _: Data<'r>) -> route::BoxFuture<'r> {
|
||||
route::Outcome::from(req, std::fs::File::open(env::temp_dir().join("upload.txt")).ok()).pin()
|
||||
let path = req.rocket().config().temp_dir.relative().join("upload.txt");
|
||||
route::Outcome::from(req, std::fs::File::open(path).ok()).pin()
|
||||
}
|
||||
|
||||
fn not_found_handler<'r>(_: Status, req: &'r Request) -> catcher::BoxFuture<'r> {
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
|
||||
use std::{io, env};
|
||||
|
||||
use rocket::tokio::fs;
|
||||
|
||||
use rocket::Config;
|
||||
use rocket::data::Capped;
|
||||
use rocket::fs::{NamedFile, TempFile};
|
||||
use rocket::tokio::fs;
|
||||
|
||||
// Upload your `big_file.dat` by POSTing it to /upload.
|
||||
// try `curl --data-binary @file.txt http://127.0.0.1:8000/stream/file`
|
||||
|
@ -17,19 +17,19 @@ const FILENAME: &str = "big_file.dat";
|
|||
|
||||
// This is a *raw* file upload, _not_ a multipart upload!
|
||||
#[post("/file", data = "<file>")]
|
||||
async fn upload(mut file: Capped<TempFile<'_>>) -> io::Result<String> {
|
||||
file.persist_to(env::temp_dir().join(FILENAME)).await?;
|
||||
async fn upload(mut file: Capped<TempFile<'_>>, config: &Config) -> io::Result<String> {
|
||||
file.persist_to(config.temp_dir.relative().join(FILENAME)).await?;
|
||||
Ok(format!("{} bytes at {}", file.n.written, file.path().unwrap().display()))
|
||||
}
|
||||
|
||||
#[get("/file")]
|
||||
async fn file() -> Option<NamedFile> {
|
||||
NamedFile::open(env::temp_dir().join(FILENAME)).await.ok()
|
||||
async fn file(config: &Config) -> Option<NamedFile> {
|
||||
NamedFile::open(config.temp_dir.relative().join(FILENAME)).await.ok()
|
||||
}
|
||||
|
||||
#[delete("/file")]
|
||||
async fn delete() -> Option<()> {
|
||||
fs::remove_file(env::temp_dir().join(FILENAME)).await.ok()
|
||||
async fn delete(config: &Config) -> Option<()> {
|
||||
fs::remove_file(config.temp_dir.relative().join(FILENAME)).await.ok()
|
||||
}
|
||||
|
||||
/***************************** `Stream` Responder *****************************/
|
||||
|
|
Loading…
Reference in New Issue