forked from neri/datatrash
cache index.html and auth-hide.js in static directory
This commit is contained in:
parent
6b60399c5f
commit
424af11918
|
@ -25,13 +25,16 @@ docker-compose up -d --build
|
||||||
|
|
||||||
## running & config
|
## running & config
|
||||||
|
|
||||||
- The static files directory needs to be next to the binary.
|
- The `static` files directory needs to be next to the binary.
|
||||||
|
- The `static` directory needs to be writable
|
||||||
|
- On startup the `index.html` will be generated based on the config
|
||||||
- The maximum filename length is 255
|
- The maximum filename length is 255
|
||||||
|
|
||||||
### General configuration
|
### General configuration
|
||||||
|
|
||||||
| environment variable | default value |
|
| environment variable | default value |
|
||||||
| -------------------- | -------------- |
|
| -------------------- | -------------- |
|
||||||
|
| STATIC_DIR | ./static |
|
||||||
| FILES_DIR | ./files |
|
| FILES_DIR | ./files |
|
||||||
| UPLOAD_MAX_BYTES | 8388608 (8MiB) |
|
| UPLOAD_MAX_BYTES | 8388608 (8MiB) |
|
||||||
| BIND_ADDRESS | 0.0.0.0:8000 |
|
| BIND_ADDRESS | 0.0.0.0:8000 |
|
||||||
|
|
|
@ -6,4 +6,4 @@
|
||||||
<br />
|
<br />
|
||||||
<input id="password" name="password" type="password" />
|
<input id="password" name="password" type="password" />
|
||||||
</div>
|
</div>
|
||||||
<script src="/assets/auth-hide.js" lang="javascript"></script>
|
<script src="/static/auth-hide.js" lang="javascript"></script>
|
||||||
|
|
|
@ -5,6 +5,7 @@ use chrono::Duration;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
|
pub static_dir: PathBuf,
|
||||||
pub files_dir: PathBuf,
|
pub files_dir: PathBuf,
|
||||||
pub max_file_size: Option<u64>,
|
pub max_file_size: Option<u64>,
|
||||||
pub no_auth_limits: Option<NoAuthLimits>,
|
pub no_auth_limits: Option<NoAuthLimits>,
|
||||||
|
@ -25,6 +26,8 @@ pub async fn get_config() -> Config {
|
||||||
.unwrap_or(8 * 1024 * 1024);
|
.unwrap_or(8 * 1024 * 1024);
|
||||||
let max_file_size = (max_file_size != 0).then(|| max_file_size);
|
let max_file_size = (max_file_size != 0).then(|| max_file_size);
|
||||||
|
|
||||||
|
let static_dir =
|
||||||
|
PathBuf::from(env::var("STATIC_DIR").unwrap_or_else(|_| "./static".to_owned()));
|
||||||
let files_dir = PathBuf::from(env::var("FILES_DIR").unwrap_or_else(|_| "./files".to_owned()));
|
let files_dir = PathBuf::from(env::var("FILES_DIR").unwrap_or_else(|_| "./files".to_owned()));
|
||||||
fs::create_dir_all(&files_dir)
|
fs::create_dir_all(&files_dir)
|
||||||
.await
|
.await
|
||||||
|
@ -33,6 +36,7 @@ pub async fn get_config() -> Config {
|
||||||
let no_auth_limits = get_no_auth_limits();
|
let no_auth_limits = get_no_auth_limits();
|
||||||
|
|
||||||
Config {
|
Config {
|
||||||
|
static_dir,
|
||||||
files_dir,
|
files_dir,
|
||||||
max_file_size,
|
max_file_size,
|
||||||
no_auth_limits,
|
no_auth_limits,
|
||||||
|
@ -55,7 +59,9 @@ fn get_no_auth_limits() -> Option<NoAuthLimits> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
(None, None, None, None) => None,
|
(None, None, None, None) => None,
|
||||||
_ => panic!("Incomplete NO_AUTH configuration: All environment variables must be specified")
|
_ => {
|
||||||
|
panic!("Incomplete NO_AUTH configuration: All environment variables must be specified")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ mod deleter;
|
||||||
mod download;
|
mod download;
|
||||||
mod file_kind;
|
mod file_kind;
|
||||||
mod multipart;
|
mod multipart;
|
||||||
|
mod template;
|
||||||
mod upload;
|
mod upload;
|
||||||
|
|
||||||
use actix_files::Files;
|
use actix_files::Files;
|
||||||
|
@ -39,6 +40,8 @@ async fn main() -> std::io::Result<()> {
|
||||||
config.files_dir.clone(),
|
config.files_dir.clone(),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
template::write_prefillable_templates(&config).await;
|
||||||
|
|
||||||
HttpServer::new({
|
HttpServer::new({
|
||||||
move || {
|
move || {
|
||||||
App::new()
|
App::new()
|
||||||
|
@ -52,9 +55,6 @@ async fn main() -> std::io::Result<()> {
|
||||||
web::resource(["/upload/{id}", "/upload/{id}/{name}"])
|
web::resource(["/upload/{id}", "/upload/{id}/{name}"])
|
||||||
.route(web::get().to(upload::uploaded)),
|
.route(web::get().to(upload::uploaded)),
|
||||||
)
|
)
|
||||||
.service(
|
|
||||||
web::resource("/assets/auth-hide.js").route(web::get().to(upload::auth_hide)),
|
|
||||||
)
|
|
||||||
.service(Files::new("/static", "static").disable_content_disposition())
|
.service(Files::new("/static", "static").disable_content_disposition())
|
||||||
.service(
|
.service(
|
||||||
web::resource([
|
web::resource([
|
||||||
|
|
|
@ -0,0 +1,139 @@
|
||||||
|
use std::cmp;
|
||||||
|
|
||||||
|
use actix_web::web;
|
||||||
|
use chrono::Duration;
|
||||||
|
|
||||||
|
use crate::config::Config;
|
||||||
|
|
||||||
|
const INDEX_HTML: &str = include_str!("../template/index.html");
|
||||||
|
const AUTH_HIDE_JS: &str = include_str!("../template/auth-hide.js");
|
||||||
|
const AUTH_SNIPPET_HTML: &str = include_str!("../snippet/auth.html.snippet");
|
||||||
|
const MAX_SIZE_SNIPPET_HTML: &str = include_str!("../snippet/max_size.html.snippet");
|
||||||
|
|
||||||
|
pub async fn write_prefillable_templates(config: &Config) {
|
||||||
|
let index_html = build_index_html(config);
|
||||||
|
let auth_hide_js = build_auth_hide_js(config);
|
||||||
|
let index_path = config.static_dir.join("index.html");
|
||||||
|
let auth_hide_path = config.static_dir.join("auth-hide.js");
|
||||||
|
|
||||||
|
async_std::fs::write(index_path, index_html)
|
||||||
|
.await
|
||||||
|
.expect("could not write index.html to static folder");
|
||||||
|
if let Some(auth_hide_js) = auth_hide_js {
|
||||||
|
async_std::fs::write(auth_hide_path, auth_hide_js)
|
||||||
|
.await
|
||||||
|
.expect("could not write auth-hide.js to static folder");
|
||||||
|
} else if auth_hide_path.exists().await {
|
||||||
|
async_std::fs::remove_file(auth_hide_path)
|
||||||
|
.await
|
||||||
|
.expect("could not delete auth-hide.js from static folder");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_index_html(config: &Config) -> String {
|
||||||
|
let auth_snippet = config
|
||||||
|
.no_auth_limits
|
||||||
|
.as_ref()
|
||||||
|
.map_or("", |_| AUTH_SNIPPET_HTML);
|
||||||
|
let max_size_snippet = config
|
||||||
|
.max_file_size
|
||||||
|
.as_ref()
|
||||||
|
.map_or("", |_| MAX_SIZE_SNIPPET_HTML);
|
||||||
|
INDEX_HTML
|
||||||
|
.replace("{max_size_snippet}", max_size_snippet)
|
||||||
|
.replace(
|
||||||
|
"{max_size}",
|
||||||
|
&render_file_size(config.max_file_size.unwrap_or(0)),
|
||||||
|
)
|
||||||
|
.replace("{auth_snippet}", auth_snippet)
|
||||||
|
.replace(
|
||||||
|
"{auth_time}",
|
||||||
|
&config
|
||||||
|
.no_auth_limits
|
||||||
|
.as_ref()
|
||||||
|
.map(|limit| limit.max_time)
|
||||||
|
.map_or("".into(), render_duration),
|
||||||
|
)
|
||||||
|
.replace(
|
||||||
|
"{auth_large_time}",
|
||||||
|
&config
|
||||||
|
.no_auth_limits
|
||||||
|
.as_ref()
|
||||||
|
.map(|limit| limit.large_file_max_time)
|
||||||
|
.map_or("".into(), render_duration),
|
||||||
|
)
|
||||||
|
.replace(
|
||||||
|
"{auth_large_size}",
|
||||||
|
&config
|
||||||
|
.no_auth_limits
|
||||||
|
.as_ref()
|
||||||
|
.map(|limit| limit.large_file_size)
|
||||||
|
.map_or("".into(), render_file_size),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_file_size(size: u64) -> String {
|
||||||
|
let magnitude = cmp::min((size as f64).log(1024.0) as u32, 5);
|
||||||
|
let prefix = ["", "ki", "Mi", "Gi", "Ti", "Pi"][magnitude as usize];
|
||||||
|
let value = size / (1024_u64.pow(magnitude));
|
||||||
|
format!("{}{}B", value, prefix)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_duration(duration: Duration) -> String {
|
||||||
|
let days = duration.num_days();
|
||||||
|
let hours = duration.num_hours() % 24;
|
||||||
|
let minutes = duration.num_minutes() % 60;
|
||||||
|
let seconds = duration.num_seconds() % 60;
|
||||||
|
let mut elements = vec![];
|
||||||
|
if let Some(name) = pluralize(days, "tag", "e") {
|
||||||
|
elements.push(name);
|
||||||
|
}
|
||||||
|
if let Some(name) = pluralize(hours, "stunde", "n") {
|
||||||
|
elements.push(name);
|
||||||
|
}
|
||||||
|
if let Some(name) = pluralize(minutes, "minute", "n") {
|
||||||
|
elements.push(name);
|
||||||
|
}
|
||||||
|
if let Some(name) = pluralize(seconds, "sekunde", "n") {
|
||||||
|
elements.push(name);
|
||||||
|
}
|
||||||
|
elements.join("+")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pluralize(number: i64, word: &str, suffix: &str) -> Option<String> {
|
||||||
|
match number {
|
||||||
|
0 => None,
|
||||||
|
1 => Some(format!("{} {}", number, word)),
|
||||||
|
_ => Some(format!("{} {}{}", number, word, suffix)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_auth_hide_js(config: &Config) -> Option<String> {
|
||||||
|
if let Some(no_auth_limits) = &config.no_auth_limits {
|
||||||
|
let auth_hide_js = AUTH_HIDE_JS
|
||||||
|
.replace(
|
||||||
|
"{no_auth_max_time}",
|
||||||
|
&no_auth_limits.max_time.num_seconds().to_string(),
|
||||||
|
)
|
||||||
|
.replace(
|
||||||
|
"{no_auth_large_file_max_time}",
|
||||||
|
&no_auth_limits.large_file_max_time.num_seconds().to_string(),
|
||||||
|
)
|
||||||
|
.replace(
|
||||||
|
"{no_auth_large_file_size}",
|
||||||
|
&no_auth_limits.large_file_size.to_string(),
|
||||||
|
);
|
||||||
|
Some(auth_hide_js)
|
||||||
|
// Ok(HttpResponse::Ok()
|
||||||
|
// .content_type("application/javascript")
|
||||||
|
// .body(auth_hide_js))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
// Err(error::ErrorNotFound("file not found"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_host_url(req: &web::HttpRequest) -> String {
|
||||||
|
let conn = req.connection_info();
|
||||||
|
format!("{}://{}", conn.scheme(), conn.host())
|
||||||
|
}
|
134
src/upload.rs
134
src/upload.rs
|
@ -1,10 +1,10 @@
|
||||||
use std::io::ErrorKind;
|
use std::io::ErrorKind;
|
||||||
use std::{cmp, vec};
|
|
||||||
|
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::file_kind::FileKind;
|
use crate::file_kind::FileKind;
|
||||||
use crate::multipart;
|
|
||||||
use crate::multipart::UploadConfig;
|
use crate::multipart::UploadConfig;
|
||||||
|
use crate::{multipart, template};
|
||||||
|
use actix_files::NamedFile;
|
||||||
use actix_multipart::Multipart;
|
use actix_multipart::Multipart;
|
||||||
use actix_web::{error, web, Error, HttpResponse};
|
use actix_web::{error, web, Error, HttpResponse};
|
||||||
use async_std::{
|
use async_std::{
|
||||||
|
@ -12,132 +12,21 @@ use async_std::{
|
||||||
fs::{self, OpenOptions},
|
fs::{self, OpenOptions},
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
};
|
};
|
||||||
use chrono::Duration;
|
|
||||||
use rand::prelude::SliceRandom;
|
use rand::prelude::SliceRandom;
|
||||||
use sqlx::postgres::PgPool;
|
use sqlx::postgres::PgPool;
|
||||||
|
|
||||||
const INDEX_HTML: &str = include_str!("../template/index.html");
|
|
||||||
const AUTH_HIDE_JS: &str = include_str!("../template/auth-hide.js");
|
|
||||||
const UPLOAD_HTML: &str = include_str!("../template/upload.html");
|
const UPLOAD_HTML: &str = include_str!("../template/upload.html");
|
||||||
const AUTH_SNIPPET_HTML: &str = include_str!("../snippet/auth.html.snippet");
|
|
||||||
const MAX_SIZE_SNIPPET_HTML: &str = include_str!("../snippet/max_size.html.snippet");
|
|
||||||
|
|
||||||
const ID_CHARS: &[char] = &[
|
const ID_CHARS: &[char] = &[
|
||||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k', 'm', 'n', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k', 'm', 'n', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
||||||
'w', 'x', 'y', 'z', '1', '2', '3', '4', '5', '6', '7', '8', '9',
|
'w', 'x', 'y', 'z', '1', '2', '3', '4', '5', '6', '7', '8', '9',
|
||||||
];
|
];
|
||||||
|
|
||||||
pub async fn index(
|
pub async fn index(config: web::Data<Config>) -> Result<NamedFile, Error> {
|
||||||
req: web::HttpRequest,
|
NamedFile::open(config.static_dir.join("index.html")).map_err(|file_err| {
|
||||||
config: web::Data<Config>,
|
log::error!("index.html could not be read {:?}", file_err);
|
||||||
) -> Result<HttpResponse, Error> {
|
error::ErrorInternalServerError("this file should be here but could not be found")
|
||||||
let filled_index_html = fill_index_html(req, config);
|
})
|
||||||
Ok(HttpResponse::Ok()
|
|
||||||
.content_type("text/html")
|
|
||||||
.body(filled_index_html))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fill_index_html(req: web::HttpRequest, config: web::Data<Config>) -> String {
|
|
||||||
let upload_url = format!("{}/upload", get_host_url(&req));
|
|
||||||
let auth_snippet = config
|
|
||||||
.no_auth_limits
|
|
||||||
.as_ref()
|
|
||||||
.map_or("", |_| AUTH_SNIPPET_HTML);
|
|
||||||
let max_size_snippet = config
|
|
||||||
.max_file_size
|
|
||||||
.as_ref()
|
|
||||||
.map_or("", |_| MAX_SIZE_SNIPPET_HTML);
|
|
||||||
INDEX_HTML
|
|
||||||
.replace("{max_size_snippet}", max_size_snippet)
|
|
||||||
.replace(
|
|
||||||
"{max_size}",
|
|
||||||
&render_file_size(config.max_file_size.unwrap_or(0)),
|
|
||||||
)
|
|
||||||
.replace("{auth_snippet}", auth_snippet)
|
|
||||||
.replace(
|
|
||||||
"{auth_time}",
|
|
||||||
&config
|
|
||||||
.no_auth_limits
|
|
||||||
.as_ref()
|
|
||||||
.map(|limit| limit.max_time)
|
|
||||||
.map_or("".into(), render_duration),
|
|
||||||
)
|
|
||||||
.replace(
|
|
||||||
"{auth_large_time}",
|
|
||||||
&config
|
|
||||||
.no_auth_limits
|
|
||||||
.as_ref()
|
|
||||||
.map(|limit| limit.large_file_max_time)
|
|
||||||
.map_or("".into(), render_duration),
|
|
||||||
)
|
|
||||||
.replace(
|
|
||||||
"{auth_large_size}",
|
|
||||||
&config
|
|
||||||
.no_auth_limits
|
|
||||||
.as_ref()
|
|
||||||
.map(|limit| limit.large_file_size)
|
|
||||||
.map_or("".into(), render_file_size),
|
|
||||||
)
|
|
||||||
.replace("{upload_url}", upload_url.as_str())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render_file_size(size: u64) -> String {
|
|
||||||
let magnitude = cmp::min((size as f64).log(1024.0) as u32, 5);
|
|
||||||
let prefix = ["", "ki", "Mi", "Gi", "Ti", "Pi"][magnitude as usize];
|
|
||||||
let value = size / (1024_u64.pow(magnitude));
|
|
||||||
format!("{}{}B", value, prefix)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render_duration(duration: Duration) -> String {
|
|
||||||
let days = duration.num_days();
|
|
||||||
let hours = duration.num_hours() % 24;
|
|
||||||
let minutes = duration.num_minutes() % 60;
|
|
||||||
let seconds = duration.num_seconds() % 60;
|
|
||||||
let mut elements = vec![];
|
|
||||||
if let Some(name) = pluralize(days, "tag", "e") {
|
|
||||||
elements.push(name);
|
|
||||||
}
|
|
||||||
if let Some(name) = pluralize(hours, "stunde", "n") {
|
|
||||||
elements.push(name);
|
|
||||||
}
|
|
||||||
if let Some(name) = pluralize(minutes, "minute", "n") {
|
|
||||||
elements.push(name);
|
|
||||||
}
|
|
||||||
if let Some(name) = pluralize(seconds, "sekunde", "n") {
|
|
||||||
elements.push(name);
|
|
||||||
}
|
|
||||||
elements.join("+")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pluralize(number: i64, word: &str, suffix: &str) -> Option<String> {
|
|
||||||
match number {
|
|
||||||
0 => None,
|
|
||||||
1 => Some(format!("{} {}", number, word)),
|
|
||||||
_ => Some(format!("{} {}{}", number, word, suffix)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn auth_hide(config: web::Data<Config>) -> Result<HttpResponse, Error> {
|
|
||||||
if let Some(no_auth_limits) = &config.no_auth_limits {
|
|
||||||
let auth_hide_js = AUTH_HIDE_JS
|
|
||||||
.replace(
|
|
||||||
"{no_auth_max_time}",
|
|
||||||
&no_auth_limits.max_time.num_seconds().to_string(),
|
|
||||||
)
|
|
||||||
.replace(
|
|
||||||
"{no_auth_large_file_max_time}",
|
|
||||||
&no_auth_limits.large_file_max_time.num_seconds().to_string(),
|
|
||||||
)
|
|
||||||
.replace(
|
|
||||||
"{no_auth_large_file_size}",
|
|
||||||
&no_auth_limits.large_file_size.to_string(),
|
|
||||||
);
|
|
||||||
Ok(HttpResponse::Ok()
|
|
||||||
.content_type("application/javascript")
|
|
||||||
.body(auth_hide_js))
|
|
||||||
} else {
|
|
||||||
Err(error::ErrorNotFound("file not found"))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn upload(
|
pub async fn upload(
|
||||||
|
@ -250,17 +139,12 @@ fn gen_file_id() -> String {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_host_url(req: &web::HttpRequest) -> String {
|
|
||||||
let conn = req.connection_info();
|
|
||||||
format!("{}://{}", conn.scheme(), conn.host())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_file_url(req: &web::HttpRequest, id: &str, name: Option<&str>) -> String {
|
fn get_file_url(req: &web::HttpRequest, id: &str, name: Option<&str>) -> String {
|
||||||
if let Some(name) = name {
|
if let Some(name) = name {
|
||||||
let encoded_name = urlencoding::encode(name);
|
let encoded_name = urlencoding::encode(name);
|
||||||
format!("{}/{}/{}", get_host_url(req), id, encoded_name)
|
format!("{}/{}/{}", template::get_host_url(req), id, encoded_name)
|
||||||
} else {
|
} else {
|
||||||
format!("{}/{}", get_host_url(req), id)
|
format!("{}/{}", template::get_host_url(req), id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de-DE">
|
||||||
|
<head>
|
||||||
|
<title>datatrash</title>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<meta name="description" content="Temporärer Dateiaustausch" />
|
||||||
|
<link href="/static/index.css" rel="stylesheet" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<main>
|
||||||
|
<h1>datatrash</h1>
|
||||||
|
<form action="/upload" method="POST" enctype="multipart/form-data">
|
||||||
|
<label for="file-upload">datei (maximal 8MiB)
|
||||||
|
</label>
|
||||||
|
<br />
|
||||||
|
<input id="file-upload" type="file" name="file" />
|
||||||
|
<br />
|
||||||
|
<label for="text-upload">oder asciitrash</label>
|
||||||
|
<br />
|
||||||
|
<textarea id="text-upload" name="text" cols="120"></textarea>
|
||||||
|
<br />
|
||||||
|
<label for="keep_for">gültig für</label>
|
||||||
|
<select id="keep_for" name="keep_for">
|
||||||
|
<option value="1800">30 minuten</option>
|
||||||
|
<option value="3600">60 minuten</option>
|
||||||
|
<option value="43200">12 stunden</option>
|
||||||
|
<option value="86400">24 stunden</option>
|
||||||
|
<option value="604800">eine woche</option>
|
||||||
|
<option value="2678400">einen monat</option>
|
||||||
|
</select>
|
||||||
|
<br />
|
||||||
|
<input
|
||||||
|
id="delete_on_download"
|
||||||
|
type="checkbox"
|
||||||
|
name="delete_on_download"
|
||||||
|
/>
|
||||||
|
<label for="delete_on_download">nach einem download löschen</label>
|
||||||
|
<br />
|
||||||
|
<input class="main button" type="submit" value="hochladen" />
|
||||||
|
</form>
|
||||||
|
<details class="usage">
|
||||||
|
<summary>nutzung als api</summary>
|
||||||
|
<pre>
|
||||||
|
datei hochladen
|
||||||
|
curl -F 'file=@yourfile.rs' <domain>/upload
|
||||||
|
|
||||||
|
text hochladen
|
||||||
|
curl -F 'text=your text' <domain>/upload
|
||||||
|
|
||||||
|
zeitbegrenzung setzen
|
||||||
|
curl -F 'text=your text' -F 'keep_for=1800' <domain>/upload
|
||||||
|
|
||||||
|
nach einem download löschen
|
||||||
|
curl -F 'text=your text' -F 'delete_on_download=true' <domain>/upload
|
||||||
|
|
||||||
|
authentifizieren
|
||||||
|
curl -F 'text=your text' -F 'password=…' <domain>/upload</pre
|
||||||
|
>
|
||||||
|
</details>
|
||||||
|
</main>
|
||||||
|
<footer>
|
||||||
|
<a
|
||||||
|
class="repo"
|
||||||
|
href="https://repos.ctdo.de/neri/datatrash"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
repo
|
||||||
|
</a>
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -42,19 +42,19 @@
|
||||||
<summary>nutzung als api</summary>
|
<summary>nutzung als api</summary>
|
||||||
<pre>
|
<pre>
|
||||||
datei hochladen
|
datei hochladen
|
||||||
curl -F 'file=@yourfile.rs' {upload_url}
|
curl -F 'file=@yourfile.rs' <domain>/upload
|
||||||
|
|
||||||
text hochladen
|
text hochladen
|
||||||
curl -F 'text=your text' {upload_url}
|
curl -F 'text=your text' <domain>/upload
|
||||||
|
|
||||||
zeitbegrenzung setzen
|
zeitbegrenzung setzen
|
||||||
curl -F 'text=your text' -F 'keep_for=1800' {upload_url}
|
curl -F 'text=your text' -F 'keep_for=1800' <domain>/upload
|
||||||
|
|
||||||
nach einem download löschen
|
nach einem download löschen
|
||||||
curl -F 'text=your text' -F 'delete_on_download=true' {upload_url}
|
curl -F 'text=your text' -F 'delete_on_download=true' <domain>/upload
|
||||||
|
|
||||||
authentifizieren
|
authentifizieren
|
||||||
curl -F 'text=your text' -F 'password=…' {upload_url}</pre
|
curl -F 'text=your text' -F 'password=…' <domain>/upload</pre
|
||||||
>
|
>
|
||||||
</details>
|
</details>
|
||||||
</main>
|
</main>
|
||||||
|
|
Loading…
Reference in New Issue