Skip to content

Commit

Permalink
feat: add rustypaste; deploy on athena
Browse files Browse the repository at this point in the history
  • Loading branch information
diogotcorreia committed Feb 2, 2025
1 parent 2a08220 commit 4caf692
Show file tree
Hide file tree
Showing 5 changed files with 410 additions and 0 deletions.
1 change: 1 addition & 0 deletions hosts/athena/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
services.nginx.common
services.reposilite
services.resumos-legacy
services.rustypaste
services.ssh
services.stalwart-mail
services.umami
Expand Down
156 changes: 156 additions & 0 deletions overlays/rustypaste/0001-allow-upload-without-filename.diff
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
diff --git a/src/header.rs b/src/header.rs
index e9726af..844cbae 100644
--- a/src/header.rs
+++ b/src/header.rs
@@ -59,14 +59,14 @@ impl ContentDisposition {
}

/// Parses the file name from parameters if it exists.
- pub fn get_file_name(&self) -> Result<&str, ActixError> {
+ pub fn get_file_name(&self) -> &str {
self.inner
.parameters
.iter()
.find(|param| param.is_filename())
.and_then(|param| param.as_filename())
.filter(|file_name| !file_name.is_empty())
- .ok_or_else(|| error::ErrorBadRequest("file data not present"))
+ .unwrap_or("file")
}
}

@@ -89,7 +89,7 @@ mod tests {
let content_disposition = ContentDisposition::from(actix_content_disposition);
assert!(content_disposition.has_form_field("file"));
assert!(!content_disposition.has_form_field("test"));
- assert_eq!("x.txt", content_disposition.get_file_name()?);
+ assert_eq!("x.txt", content_disposition.get_file_name());

let actix_content_disposition = ActixContentDisposition {
disposition: DispositionType::Attachment,
@@ -97,7 +97,7 @@ mod tests {
};
let content_disposition = ContentDisposition::from(actix_content_disposition);
assert!(!content_disposition.has_form_field("file"));
- assert!(content_disposition.get_file_name().is_err());
+ assert_eq!("file", content_disposition.get_file_name());
Ok(())
}

diff --git a/src/server.rs b/src/server.rs
index 8cc55bd..04976e2 100644
--- a/src/server.rs
+++ b/src/server.rs
@@ -281,7 +281,7 @@ async fn upload(
.read()
.map_err(|_| error::ErrorInternalServerError("cannot acquire config"))?;
paste.store_file(
- content.get_file_name()?,
+ content.get_file_name(),
expiry_date,
header_filename,
&config,
@@ -319,6 +319,13 @@ async fn upload(
return Err(error::ErrorBadRequest("invalid form field"));
}
}
+ if urls.len() == 1 {
+ if let Some(first_url) = urls.first().map(|s| s.trim().to_string()) {
+ return Ok(HttpResponse::Found()
+ .insert_header((actix_web::http::header::LOCATION, first_url))
+ .body(urls.join("")));
+ }
+ }
Ok(HttpResponse::Ok().body(urls.join("")))
}

@@ -856,7 +863,7 @@ mod tests {
get_multipart_request(&timestamp, "file", file_name).to_request(),
)
.await;
- assert_eq!(StatusCode::OK, response.status());
+ assert_eq!(StatusCode::FOUND, response.status());
assert_body(
response.into_body(),
&format!("http://localhost:8080/{file_name}\n"),
@@ -906,7 +913,7 @@ mod tests {
.to_request(),
)
.await;
- assert_eq!(StatusCode::OK, response.status());
+ assert_eq!(StatusCode::FOUND, response.status());
assert_body(
response.into_body(),
&format!("http://localhost:8080/{header_filename}\n"),
@@ -956,7 +963,7 @@ mod tests {
.to_request(),
)
.await;
- assert_eq!(StatusCode::OK, response.status());
+ assert_eq!(StatusCode::FOUND, response.status());
assert_body(
response.into_body(),
&format!("http://localhost:8080/{header_filename}\n"),
@@ -1010,7 +1017,7 @@ mod tests {
get_multipart_request("test", "file", "x").to_request(),
)
.await;
- assert_eq!(StatusCode::OK, response.status());
+ assert_eq!(StatusCode::FOUND, response.status());
let body = response.into_body();
let first_body_bytes = actix_web::body::to_bytes(body).await?;

@@ -1019,7 +1026,7 @@ mod tests {
get_multipart_request("test", "file", "x").to_request(),
)
.await;
- assert_eq!(StatusCode::OK, response.status());
+ assert_eq!(StatusCode::FOUND, response.status());
let body = response.into_body();
let second_body_bytes = actix_web::body::to_bytes(body).await?;

@@ -1055,7 +1062,7 @@ mod tests {
.to_request(),
)
.await;
- assert_eq!(StatusCode::OK, response.status());
+ assert_eq!(StatusCode::FOUND, response.status());
assert_body(
response.into_body(),
&format!("http://localhost:8080/{file_name}\n"),
@@ -1117,7 +1124,7 @@ mod tests {
.to_request(),
)
.await;
- assert_eq!(StatusCode::OK, response.status());
+ assert_eq!(StatusCode::FOUND, response.status());
assert_body(
response.into_body().boxed(),
&format!("http://localhost:8080/{file_name}\n"),
@@ -1171,7 +1178,7 @@ mod tests {
get_multipart_request(env!("CARGO_PKG_HOMEPAGE"), "url", "").to_request(),
)
.await;
- assert_eq!(StatusCode::OK, response.status());
+ assert_eq!(StatusCode::FOUND, response.status());
assert_body(response.into_body(), "http://localhost:8080/url\n").await?;

let serve_request = TestRequest::get().uri("/url").to_request();
@@ -1213,7 +1220,7 @@ mod tests {
get_multipart_request(&timestamp, "oneshot", file_name).to_request(),
)
.await;
- assert_eq!(StatusCode::OK, response.status());
+ assert_eq!(StatusCode::FOUND, response.status());
assert_body(
response.into_body(),
&format!("http://localhost:8080/{file_name}\n"),
@@ -1278,7 +1285,7 @@ mod tests {
.to_request(),
)
.await;
- assert_eq!(StatusCode::OK, response.status());
+ assert_eq!(StatusCode::FOUND, response.status());
assert_body(
response.into_body(),
&format!("http://localhost:8080/{}\n", oneshot_url_suffix),
21 changes: 21 additions & 0 deletions overlays/rustypaste/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Apply patches to rustypaste
{...}: final: prev: {
rustypaste = prev.rustypaste.overrideAttrs (oldAttrs: {
patches = [
# Allow uploading without a filename, so that an HTML
# form can upload from a textarea.
./0001-allow-upload-without-filename.diff
];

passthru =
(oldAttrs.passthrough or {})
// {
homePage =
prev.runCommand "index.html" {
nativeBuildInputs = [prev.minify];
} ''
minify -o "$out" ${./index.html}
'';
};
});
}
92 changes: 92 additions & 0 deletions overlays/rustypaste/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<!DOCTYPE html>
<html>

<head>
<style>
html {
background: #2e3440;
color: #e5e9f0;
font-family: sans-serif;
}

textarea {
background: transparent;
color: inherit;
width: 100%;
height: 100%;
height: calc(100% - 1em);
border: none;
outline: none;
font-family: monospace;
resize: none;
}

#buttons {
position: absolute;
top: 1em;
right: 1em;
}

button {
border: none;
background: #8fbcbb;
cursor: pointer;
font-size: 1.2rem;
}

button.help {
margin-left: 0.3em;
background: #5e81ac;
}

#help {
background: #3b4252;
color: #eceff4;
border-color: #eceff4;
max-width: 600px;
max-width: min(600px, 90%);
max-height: 90vh;
}

a {
color: #88c0d0;
}
</style>
<title>rustypaste</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>

<body>
<form method="post" action="/" enctype="multipart/form-data">
<textarea name="file" autofocus spellcheck="false"></textarea>
<div id="buttons">
<button type="submit">Upload</button>
<button type="button" class="help" popovertarget="help">?</button>
</div>
</form>

<div popover id="help">
<p>
Welcome to dtc's <a href="https://github.com/orhun/rustypaste" target="_blank"
rel="noreferer noopener">rustypaste</a> instance.
</p>
<p>
The best way to interact with this application is through the command line, but
the submission form on this page is provided as convenience.
</p>
<ul>
<li>Upload a file:<br> <code>curl -F "file=@code.txt" "@siteUrl@"</code></li>
<li>Shorten URL:<br> <code>curl -F "url=https://example.com" "@siteUrl@"</code></li>
<li>Oneshot file:<br> <code>curl -F "oneshot=@code.txt" "@siteUrl@"</code></li>
<li>Oneshot URL:<br> <code>curl -F "oneshot_url=https://example.com" "@siteUrl@"</code></li>
<li>Set expiry:<br> add header <code>-H "expire:10min"</code></li>
</ul>
<p>
By default, submissions do not expire, but might be deleted at any time.
Upload size is limited.
</p>
</div>
</body>

</html>
Loading

0 comments on commit 4caf692

Please sign in to comment.