Version up to 23.8.0. Changed arav.top to arav.su. Fixed templates. Deleted pre-compiled ones.
This commit is contained in:
parent
29b6d179be
commit
4a49bf30a3
2
LICENSE
2
LICENSE
@ -1,4 +1,4 @@
|
|||||||
Copyright (c) 2022 Alexander "Arav" Andreev <me@arav.top>
|
Copyright (c) 2022,2023 Alexander "Arav" Andreev <me@arav.su>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
@ -1,21 +1,21 @@
|
|||||||
# Maintainer: Alexander "Arav" Andreev <me@arav.top>
|
# Maintainer: Alexander "Arav" Andreev <me@arav.su>
|
||||||
pkgname=dwelling-upload
|
pkgname=dwelling-upload
|
||||||
pkgver=22.31.0
|
pkgver=23.8.0
|
||||||
pkgrel=1
|
pkgrel=1
|
||||||
pkgdesc="Arav's Dwelling / Upload"
|
pkgdesc="Arav's Dwelling / Upload"
|
||||||
arch=('i686' 'x86_64' 'arm' 'armv6h' 'armv7h' 'aarch64')
|
arch=('i686' 'x86_64' 'arm' 'armv6h' 'armv7h' 'aarch64')
|
||||||
url="https://git.arav.top/Arav/dwelling-upload"
|
url="https://git.arav.su/Arav/dwelling-upload"
|
||||||
license=('MIT')
|
license=('MIT')
|
||||||
groups=()
|
groups=()
|
||||||
depends=()
|
depends=()
|
||||||
makedepends=('git' 'go')
|
makedepends=('go')
|
||||||
provides=('dwelling-upload')
|
provides=('dwelling-upload')
|
||||||
conflicts=('dwelling-upload')
|
conflicts=('dwelling-upload')
|
||||||
replaces=()
|
replaces=()
|
||||||
backup=('etc/dwelling/upload.yaml')
|
backup=('etc/dwelling/upload.yaml')
|
||||||
options=()
|
options=()
|
||||||
install=
|
install=
|
||||||
source=('dwelling-upload::git+https://git.arav.top/Arav/dwelling-upload.git')
|
source=('https://git.arav.top/Arav/dwelling-upload/archive/23.8.0.tar.gz')
|
||||||
noextract=()
|
noextract=()
|
||||||
md5sums=('SKIP')
|
md5sums=('SKIP')
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ func main() {
|
|||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
if *showVersion {
|
if *showVersion {
|
||||||
fmt.Println("dwelling-upload-clean Ver. 22.24.1\nCopyright (c) 2022 Alexander \"Arav\" Andreev <me@arav.top>")
|
fmt.Println("dwelling-upload-clean Ver. 23.8.0\nCopyright (c) 2022,2023 Alexander \"Arav\" Andreev <me@arav.su>")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ func main() {
|
|||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
if *showVersion {
|
if *showVersion {
|
||||||
fmt.Println("dwelling-upload Ver. 22.26.0\nCopyright (c) 2022 Alexander \"Arav\" Andreev <me@arav.top>")
|
fmt.Println("dwelling-upload Ver. 23.8.0\nCopyright (c) 2022,2023 Alexander \"Arav\" Andreev <me@arav.su>")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# Sets network type (could be tcp{,4,6}, unix)
|
# Sets network type (could be tcp{,4,6}, unix)
|
||||||
# and address:port or /path/to/unix.sock to
|
# and address:port or /path/to/unix.sock to
|
||||||
# listen on.
|
# listen on.
|
||||||
listen_on: "unix /var/run/dwelling-upload/u.sock"
|
listen_on: "unix /var/run/dwelling-upload/sock"
|
||||||
# Salt for hash of uploaded files.
|
# Salt for hash of uploaded files.
|
||||||
# Aim is to make links bruteforcing useless.
|
# Aim is to make links bruteforcing useless.
|
||||||
hash_salt: "iyP3oZWHI3xO3XBF7s78Vg"
|
hash_salt: "iyP3oZWHI3xO3XBF7s78Vg"
|
||||||
|
@ -3,11 +3,11 @@ server {
|
|||||||
listen 8094; # Tor
|
listen 8094; # Tor
|
||||||
listen 127.0.0.1:8114; # I2P
|
listen 127.0.0.1:8114; # I2P
|
||||||
|
|
||||||
server_name upload.arav.top upload.arav.i2p;
|
server_name upload.arav.su upload.arav.i2p;
|
||||||
access_log /var/log/nginx/dwelling/upload.log main if=$nolog;
|
access_log /var/log/nginx/dwelling/upload.log main if=$nolog;
|
||||||
|
|
||||||
ssl_certificate /etc/letsencrypt/live/arav.top/fullchain.pem;
|
ssl_certificate /etc/letsencrypt/live/arav.su/fullchain.pem;
|
||||||
ssl_certificate_key /etc/letsencrypt/live/arav.top/privkey.pem;
|
ssl_certificate_key /etc/letsencrypt/live/arav.su/privkey.pem;
|
||||||
|
|
||||||
|
|
||||||
add_header Content-Security-Policy "default-src 'self'; script-src 'none'; style-src 'self' 'unsafe-inline'; img-src 'self'; media-src 'self'; object-src 'none'; frame-src 'none'; frame-ancestors 'none'; font-src 'self'; form-action 'self'";
|
add_header Content-Security-Policy "default-src 'self'; script-src 'none'; style-src 'self' 'unsafe-inline'; img-src 'self'; media-src 'self'; object-src 'none'; frame-src 'none'; frame-ancestors 'none'; font-src 'self'; form-action 'self'";
|
||||||
@ -19,7 +19,7 @@ server {
|
|||||||
|
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
proxy_pass http://unix:/var/run/dwelling-upload/u.sock;
|
proxy_pass http://unix:/var/run/dwelling-upload/sock;
|
||||||
proxy_buffering off;
|
proxy_buffering off;
|
||||||
|
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
|
@ -12,7 +12,7 @@ func MainSite(host string) string {
|
|||||||
return "http://[300:a98d:d6d0:8a08::f]"
|
return "http://[300:a98d:d6d0:8a08::f]"
|
||||||
}
|
}
|
||||||
|
|
||||||
return "https://arav.top"
|
return "https://arav.su"
|
||||||
}
|
}
|
||||||
|
|
||||||
// NetworkType detects network based on host suffix,
|
// NetworkType detects network based on host suffix,
|
||||||
|
@ -1,28 +0,0 @@
|
|||||||
// Code generated by "jade.go"; DO NOT EDIT.
|
|
||||||
|
|
||||||
package web
|
|
||||||
|
|
||||||
import (
|
|
||||||
"html"
|
|
||||||
"io"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
error404__0 = `<!DOCTYPE html><html lang="en"><head><title>Arav's dwelling / Upload</title><meta charset="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><meta name="viewport" content="width=device-width, initial-scale=1.0"/><meta name="theme-color" content="#cd2682"/><meta name="description" content="File upload service for ya."/><link rel="icon" href="/assets/img/favicon.svg" sizes="any" type="image/svg+xml"/><link href="/assets/css/main.css" rel="stylesheet"/><style type="text/css"> #error {
|
|
||||||
font-size: 3.5rem;
|
|
||||||
line-height: 5rem;
|
|
||||||
text-align: center;
|
|
||||||
margin: 6rem 0; }
|
|
||||||
|
|
||||||
#error h1 { font-size: 8rem; }
|
|
||||||
</style></head><body><header><svg id="logo" viewBox="0 -25 216 40"><text class="logo">Arav's dwelling</text><text class="under" y="11">Welcome to my sacred place, wanderer</text></svg><nav><a href="`
|
|
||||||
error404__1 = `" title="Arav's dwelling">Back to main website</a><h1>404</h1></nav></header><footer>2022 Arav <<a href="mailto:me@arav.top">me@arav.top</a>></footer></body></html>`
|
|
||||||
)
|
|
||||||
|
|
||||||
func Error404(mainSite string, wr io.Writer) {
|
|
||||||
buffer := &WriterAsBuffer{wr}
|
|
||||||
|
|
||||||
buffer.WriteString(error404__0)
|
|
||||||
buffer.WriteString(html.EscapeString(mainSite))
|
|
||||||
buffer.WriteString(error404__1)
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
// Code generated by "jade.go"; DO NOT EDIT.
|
|
||||||
|
|
||||||
package web
|
|
||||||
|
|
||||||
import (
|
|
||||||
"html"
|
|
||||||
"io"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
index__0 = `<!DOCTYPE html><html lang="en"><head><title>Arav's dwelling / Upload</title><meta charset="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><meta name="viewport" content="width=device-width, initial-scale=1.0"/><meta name="theme-color" content="#cd2682"/><meta name="description" content="File upload service for ya."/><link rel="icon" href="/assets/img/favicon.svg" sizes="any" type="image/svg+xml"/><link href="/assets/css/main.css" rel="stylesheet"/></head><body><header><svg id="logo" viewBox="0 -25 216 40"><text class="logo">Arav's dwelling</text><text class="under" y="11">Welcome to my sacred place, wanderer</text></svg><nav><a href="`
|
|
||||||
index__1 = `" title="Arav's dwelling">Back to main website</a><h1>Upload</h1></nav></header><section id="rules" class="center"><h2>Rules</h2><ul><li>Max. file size is `
|
|
||||||
index__2 = `.</li><li>It will be kept for `
|
|
||||||
index__3 = ` hours.</li><li>Anything you upload should comply with Russian Federation's law. Generally speaking, anything illegal, like CP, extremist literature etc., is forbidden.</li></ul></section><section id="used-space" class="center"><h2>Free space</h2><div><span>`
|
|
||||||
index__4 = `</span><progress value="`
|
|
||||||
index__5 = `" max="`
|
|
||||||
index__6 = `"></progress><span>`
|
|
||||||
index__7 = `</span></div><div>`
|
|
||||||
index__8 = `</div></section><section id="upload" class="center"><h2>Upload</h2><form action="/" method="POST" enctype="multipart/form-data"><input type="file" name="file"/><button type="submit">Upload</button></form></section><section class="center"><p>You can use cURL to upload a file: <code>curl -F 'file=@somefile.ext' https://upload.arav.top</code></p><p>Over I2P: <code>curl --proxy 127.0.0.1:4444 -F 'file=@somefile.ext' http://upload.arav.i2p</code></p><p>A resulted link looks like this: <code>/f/base64rawURL(sha256)/filename.ext</code>.</p><p>filename.ext is mandatory. It is a name the file will be retrieved with.</p></section><section class="center"><h2>Delete</h2><form action="/delete" method="POST"><input type="text" name="hash" placeholder="File hash goes here" minlength="43" maxlength="43" size="43" required=""/><button type="submit">Delete</button></form></section><section class="center"><p>You can delete a file using cURL: <code>curl -XDELETE https://upload.arav.top/<hash></code></p><p>Over I2P: <code>curl --proxy 127.0.0.1:4444 -XDELETE http://upload.arav.i2p/<hash></code></p></section><section><h2>Privacy statements</h2><p>I WILL cooperate with law enforcements and provide them with logs, guess I shouldn't clarify why. Abuses should be sent to <a href="mailto:admin@arav.top">admin@arav.top</a>.</p><p>Upload logs include: access time, IP-address, name of a file it was uploaded with, a SHA-256 hash of the file, download name*, size of the file in bytes, User-Agent.</p><p>Each download and deletion are also being logged and include: access time, IP-address, name of a file it was requested with, download name*, User-Agent.</p><p>*Download name is a salted SHA-256 hash of the file encoded using base64 raw URL encoding. The hash is being salted to make useless any attempt of bruteforcing.</p></section><footer>2022 Arav <<a href="mailto:me@arav.top">me@arav.top</a>></footer></body></html>`
|
|
||||||
)
|
|
||||||
|
|
||||||
func Index(mainSite string, storageCapacity, storageUsed int64, keepForHours int, fileMaxSize, storageUsedStr, storageCapacityStr, storageAvailableStr string, wr io.Writer) {
|
|
||||||
buffer := &WriterAsBuffer{wr}
|
|
||||||
|
|
||||||
buffer.WriteString(index__0)
|
|
||||||
buffer.WriteString(html.EscapeString(mainSite))
|
|
||||||
buffer.WriteString(index__1)
|
|
||||||
buffer.WriteString(html.EscapeString(fileMaxSize))
|
|
||||||
buffer.WriteString(index__2)
|
|
||||||
buffer.WriteString(html.EscapeString(strconv.FormatInt(int64(keepForHours), 10)))
|
|
||||||
buffer.WriteString(index__3)
|
|
||||||
buffer.WriteString(html.EscapeString(storageUsedStr))
|
|
||||||
buffer.WriteString(index__4)
|
|
||||||
buffer.WriteString(html.EscapeString(strconv.FormatInt(storageUsed, 10)))
|
|
||||||
buffer.WriteString(index__5)
|
|
||||||
buffer.WriteString(html.EscapeString(strconv.FormatInt(storageCapacity, 10)))
|
|
||||||
buffer.WriteString(index__6)
|
|
||||||
buffer.WriteString(html.EscapeString(storageCapacityStr))
|
|
||||||
buffer.WriteString(index__7)
|
|
||||||
buffer.WriteString(html.EscapeString(storageAvailableStr))
|
|
||||||
buffer.WriteString(index__8)
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
// Code generated by "jade.go"; DO NOT EDIT.
|
|
||||||
|
|
||||||
package web
|
|
||||||
|
|
||||||
import (
|
|
||||||
"html"
|
|
||||||
"io"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
nospace__0 = `<!DOCTYPE html><html lang="en"><head><title>Arav's dwelling / Upload</title><meta charset="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><meta name="viewport" content="width=device-width, initial-scale=1.0"/><meta name="theme-color" content="#cd2682"/><meta name="description" content="File upload service for ya."/><link rel="icon" href="/assets/img/favicon.svg" sizes="any" type="image/svg+xml"/><link href="/assets/css/main.css" rel="stylesheet"/><style type="text/css"> #error {
|
|
||||||
font-size: 3.5rem;
|
|
||||||
line-height: 5rem;
|
|
||||||
text-align: center;
|
|
||||||
margin: 6rem 0; }
|
|
||||||
|
|
||||||
#error h1 { font-size: 6rem; }
|
|
||||||
</style></head><body><header><svg id="logo" viewBox="0 -25 216 40"><text class="logo">Arav's dwelling</text><text class="under" y="11">Welcome to my sacred place, wanderer</text></svg><nav><a href="`
|
|
||||||
nospace__1 = `" title="Arav's dwelling">Back to main website</a><h1>:(</h1></nav></header><footer>2022 Arav <<a href="mailto:me@arav.top">me@arav.top</a>></footer></body></html>`
|
|
||||||
)
|
|
||||||
|
|
||||||
func ErrorNoSpace(mainSite string, wr io.Writer) {
|
|
||||||
buffer := &WriterAsBuffer{wr}
|
|
||||||
|
|
||||||
buffer.WriteString(nospace__0)
|
|
||||||
buffer.WriteString(html.EscapeString(mainSite))
|
|
||||||
buffer.WriteString(nospace__1)
|
|
||||||
|
|
||||||
}
|
|
@ -20,4 +20,4 @@ html(lang="en")
|
|||||||
block header
|
block header
|
||||||
block body
|
block body
|
||||||
footer
|
footer
|
||||||
| 2022 Arav <#[a(href="mailto:me@arav.top") me@arav.top]>
|
| 2022,2023 Arav <#[a(href="mailto:me@arav.su") me@arav.su]>
|
@ -1,6 +1,6 @@
|
|||||||
:go:func Error404(mainSite string)
|
:go:func Error404(mainSite string)
|
||||||
|
|
||||||
include base.jade
|
extends base.jade
|
||||||
|
|
||||||
block append head
|
block append head
|
||||||
style(type="text/css").
|
style(type="text/css").
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
:go:func Index(mainSite string, storageCapacity, storageUsed int64, keepForHours int, fileMaxSize, storageUsedStr, storageCapacityStr, storageAvailableStr string)
|
:go:func Index(mainSite string, storageCapacity, storageUsed int64, keepForHours int, fileMaxSize, storageUsedStr, storageCapacityStr, storageAvailableStr string)
|
||||||
|
|
||||||
include base.jade
|
extends base.jade
|
||||||
|
|
||||||
block append header
|
block append header
|
||||||
h1 Upload
|
h1 Upload
|
||||||
@ -26,7 +26,7 @@ block body
|
|||||||
input(type="file" name="file" multiple=false)
|
input(type="file" name="file" multiple=false)
|
||||||
button(type="submit") Upload
|
button(type="submit") Upload
|
||||||
section.center
|
section.center
|
||||||
p You can use cURL to upload a file: #[code curl -F 'file=@somefile.ext' https://upload.arav.top]
|
p You can use cURL to upload a file: #[code curl -F 'file=@somefile.ext' https://upload.arav.su]
|
||||||
p Over I2P: #[code curl --proxy 127.0.0.1:4444 -F 'file=@somefile.ext' http://upload.arav.i2p]
|
p Over I2P: #[code curl --proxy 127.0.0.1:4444 -F 'file=@somefile.ext' http://upload.arav.i2p]
|
||||||
p A resulted link looks like this: #[code /f/base64rawURL(sha256)/filename.ext].
|
p A resulted link looks like this: #[code /f/base64rawURL(sha256)/filename.ext].
|
||||||
p filename.ext is mandatory. It is a name the file will be retrieved with.
|
p filename.ext is mandatory. It is a name the file will be retrieved with.
|
||||||
@ -36,11 +36,11 @@ block body
|
|||||||
input(type="text", name="hash" placeholder="File hash goes here" minlength="43" maxlength="43" size="43" required="")
|
input(type="text", name="hash" placeholder="File hash goes here" minlength="43" maxlength="43" size="43" required="")
|
||||||
button(type="submit") Delete
|
button(type="submit") Delete
|
||||||
section.center
|
section.center
|
||||||
p You can delete a file using cURL: #[code curl -XDELETE https://upload.arav.top/<hash>]
|
p You can delete a file using cURL: #[code curl -XDELETE https://upload.arav.su/<hash>]
|
||||||
p Over I2P: #[code curl --proxy 127.0.0.1:4444 -XDELETE http://upload.arav.i2p/<hash>]
|
p Over I2P: #[code curl --proxy 127.0.0.1:4444 -XDELETE http://upload.arav.i2p/<hash>]
|
||||||
section
|
section
|
||||||
h2 Privacy statements
|
h2 Privacy statements
|
||||||
p I WILL cooperate with law enforcements and provide them with logs, guess I shouldn't clarify why. Abuses should be sent to #[a(href="mailto:admin@arav.top") admin@arav.top].
|
p I WILL cooperate with law enforcements and provide them with logs, guess I shouldn't clarify why. Abuses should be sent to #[a(href="mailto:admin@arav.su") admin@arav.su].
|
||||||
p Upload logs include: access time, IP-address, name of a file it was uploaded with, a SHA-256 hash of the file, download name*, size of the file in bytes, User-Agent.
|
p Upload logs include: access time, IP-address, name of a file it was uploaded with, a SHA-256 hash of the file, download name*, size of the file in bytes, User-Agent.
|
||||||
p Each download and deletion are also being logged and include: access time, IP-address, name of a file it was requested with, download name*, User-Agent.
|
p Each download and deletion are also being logged and include: access time, IP-address, name of a file it was requested with, download name*, User-Agent.
|
||||||
p *Download name is a salted SHA-256 hash of the file encoded using base64 raw URL encoding. The hash is being salted to make useless any attempt of bruteforcing.
|
p *Download name is a salted SHA-256 hash of the file encoded using base64 raw URL encoding. The hash is being salted to make useless any attempt of bruteforcing.
|
@ -1,6 +1,6 @@
|
|||||||
:go:func ErrorNoSpace(mainSite string)
|
:go:func ErrorNoSpace(mainSite string)
|
||||||
|
|
||||||
include base.jade
|
extends base.jade
|
||||||
|
|
||||||
block append head
|
block append head
|
||||||
style(type="text/css").
|
style(type="text/css").
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
:go:func Uploaded(mainSite, site, downloadLink string, keepForHours int)
|
:go:func Uploaded(mainSite, site, downloadLink string, keepForHours int)
|
||||||
|
|
||||||
include base.jade
|
extends base.jade
|
||||||
|
|
||||||
block append header
|
block append header
|
||||||
h1 Upload
|
h1 Upload
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
// Code generated by "jade.go"; DO NOT EDIT.
|
|
||||||
|
|
||||||
package web
|
|
||||||
|
|
||||||
import (
|
|
||||||
"html"
|
|
||||||
"io"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
uploaded__0 = `<!DOCTYPE html><html lang="en"><head><title>Arav's dwelling / Upload</title><meta charset="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><meta name="viewport" content="width=device-width, initial-scale=1.0"/><meta name="theme-color" content="#cd2682"/><meta name="description" content="File upload service for ya."/><link rel="icon" href="/assets/img/favicon.svg" sizes="any" type="image/svg+xml"/><link href="/assets/css/main.css" rel="stylesheet"/></head><body><header><svg id="logo" viewBox="0 -25 216 40"><text class="logo">Arav's dwelling</text><text class="under" y="11">Welcome to my sacred place, wanderer</text></svg><nav><a href="`
|
|
||||||
uploaded__1 = `" title="Arav's dwelling">Back to main website</a><h1>Upload</h1></nav></header><section id="file"><h2>Your link</h2><center><a href="`
|
|
||||||
uploaded__2 = `">`
|
|
||||||
uploaded__3 = `</a></center><center>It will be available for next `
|
|
||||||
uploaded__4 = ` hours.</center><center><a href="/">Back to index page</a></center></section><footer>2022 Arav <<a href="mailto:me@arav.top">me@arav.top</a>></footer></body></html>`
|
|
||||||
)
|
|
||||||
|
|
||||||
func Uploaded(mainSite, site, downloadLink string, keepForHours int, wr io.Writer) {
|
|
||||||
buffer := &WriterAsBuffer{wr}
|
|
||||||
|
|
||||||
buffer.WriteString(uploaded__0)
|
|
||||||
buffer.WriteString(html.EscapeString(mainSite))
|
|
||||||
buffer.WriteString(uploaded__1)
|
|
||||||
buffer.WriteString(html.EscapeString(downloadLink))
|
|
||||||
buffer.WriteString(uploaded__2)
|
|
||||||
buffer.WriteString(html.EscapeString(site))
|
|
||||||
buffer.WriteString(html.EscapeString(downloadLink))
|
|
||||||
buffer.WriteString(uploaded__3)
|
|
||||||
buffer.WriteString(html.EscapeString(strconv.FormatInt(int64(keepForHours), 10)))
|
|
||||||
buffer.WriteString(uploaded__4)
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user