Compare commits

...

3 Commits

Author SHA1 Message Date
hgw
345236b2d9
URL length and expiry on POST request PR #2 2023-12-13 09:42:53 +00:00
hgw
4dcf1f37a3
Update .gitignore 2023-12-13 09:42:09 +00:00
hgw
02483f896c
Update readme to include curl enhancements 2023-12-13 09:41:55 +00:00
3 changed files with 92 additions and 19 deletions

3
.gitignore vendored
View File

@ -1,2 +1,3 @@
files/ files/
*.db *.db
hardfiles

View File

@ -20,7 +20,7 @@ HardFiles is built on the principle of flexibility. If you choose to run your ow
This is necessary even when using the Docker image as the image does not contain the HardFiles frontend. This is necessary even when using the Docker image as the image does not contain the HardFiles frontend.
``` ```shell
git clone https://git.supernets.org/supernets/hardfiles.git git clone https://git.supernets.org/supernets/hardfiles.git
``` ```
@ -32,21 +32,25 @@ Start by adjusting the necessary configuration variables in `config.toml`.
##### Bare Metal: ##### Bare Metal:
Execute the following commands to build and initiate HardFiles: Execute the following commands to build and initiate HardFiles:
``` ```shell
go build -o hardfiles main.go go build -o hardfiles main.go
mkdir files
./hardfiles ./hardfiles
``` ```
##### Docker Compose: ##### Docker Compose:
Execute the following commands to build and initiate HardFiles in Docker: Execute the following commands to build and initiate HardFiles in Docker:
``` ```shell
docker compose up -d docker compose up -d
``` ```
#### 3. Default Port: #### 3. Web Server Configuration:
By default, HardFiles listens on port `5000`. For production environments, it's recommended to use a robust web server like Nginx or Apache to proxy traffic to this port.
By default, HardFiles listens on port `5000`. For production environments, it's recommended to use a robust web server like Nginx or Caddy to proxy traffic to this port.
For obtaining the Let's Encrypt certificates, you can use tools like `certbot` that automatically handle the certification process for you. If you elect to use Caddy, in most circumstances it is able to handle certificates for you using Let's Encrypt.
Remember, by using a reverse proxy, you can run HardFiles without needing root privileges and maintain a more secure environment.
###### Using Nginx as a Reverse Proxy: ###### Using Nginx as a Reverse Proxy:
@ -73,25 +77,48 @@ server {
Replace `your_domain.com` with your actual domain name. Save this configuration to a file, say `hardfiles.conf`, inside the `/etc/nginx/sites-available/` directory, and then create a symbolic link to `/etc/nginx/sites-enabled/`. Restart Nginx after this setup. Replace `your_domain.com` with your actual domain name. Save this configuration to a file, say `hardfiles.conf`, inside the `/etc/nginx/sites-available/` directory, and then create a symbolic link to `/etc/nginx/sites-enabled/`. Restart Nginx after this setup.
For obtaining the Let's Encrypt certificates, you can use tools like `certbot` that automatically handle the certification process for you. ###### Using Caddy as a Reverse Proxy:
Remember, by using a reverse proxy, you can run HardFiles without needing root privileges and maintain a more secure environment. Append the following to the Caddyfile, replacing your_domain.com with your chosen domain.
## cURL Uploads & Bash Alias ```caddy
your_domain.com {
reverse_proxy localhost:5000
}
```
## cURL Uploads
You can upload files using cURL like so:
```shell
curl -F file=@$1 https://hardfiles.org/
```
Additionally, you can append some extra options to modify the expiry time or file name length. Currently the file expiry time must be provided in seconds and is limited to 5 days maximum. The file name length is limited to 128 characters. The following example will return a file that expires in 48 hours rather than the default 24 and a file name length of 64 characters:
```shell
curl -F file=@$1 -F expiry=172800 -F url_len=64 https://hardfiles.org/
```
### Bash Alias
If you frequently upload files to HardFiles via the command line, you can streamline the process by setting up a bash alias. This allows you to use a simple command, like `upload`, to push your files to HardFiles using `curl`. If you frequently upload files to HardFiles via the command line, you can streamline the process by setting up a bash alias. This allows you to use a simple command, like `upload`, to push your files to HardFiles using `curl`.
#### Setting Up: #### Setting Up:
1. **Edit your `.bashrc` file:** Open your `~/.bashrc` file in a text editor. You can use `nano` or `vim` for this purpose: 1. **Edit your `.bashrc` file:** Open your `~/.bashrc` file in a text editor. You can use `nano` or `vim` for this purpose:
```shell ```shell
nano ~/.bashrc nano ~/.bashrc
``` ```
2. **Add the `upload` function:** At the end of the `.bashrc` file, append the following function (replace the domain if you are running your own instance): 2. **Add the `upload` function:** At the end of the `.bashrc` file, append the following function (replace the domain if you are running your own instance):
```shell ```shell
upload() { upload() {
curl -F file=@$1 https://hardfiles.org/ curl -F file=@$1 https://hardfiles.org/
} }
``` ```
3. Reload your .bashrc file: To make the new function available in your current session, reload your .bashrc: 3. Reload your .bashrc file: To make the new function available in your current session, reload your .bashrc:
```shell ```shell
source ~/.bashrc source ~/.bashrc
@ -99,6 +126,7 @@ source ~/.bashrc
#### Usage: #### Usage:
Now, you can easily upload files to HardFiles using the upload command followed by the path to your file. For example: Now, you can easily upload files to HardFiles using the upload command followed by the path to your file. For example:
```shell ```shell
upload /path/to/your/file.jpg upload /path/to/your/file.jpg
``` ```
@ -106,7 +134,7 @@ upload /path/to/your/file.jpg
This will upload the specified file to HardFiles and return a direct link to the file. This will upload the specified file to HardFiles and return a direct link to the file.
## Roadmap ## Roadmap
- Idea - Uploads stored on a remotely mounted drive, isolating them from the actual service server. Multiple mirrored instances behind a round robin reading from the same remote mount for scaling. - Idea - Uploads stored on a remotely mounted drive or S3 compatible volume, isolating them from the actual service server. Multiple mirrored instances behind a round robin reading from the same remote mount for scaling.
- Random wallpapers as an optional extra, kept simple without javascript. Maybe a local shell script that modifies the index.html on a timer. - Random wallpapers as an optional extra, kept simple without javascript. Maybe a local shell script that modifies the index.html on a timer.
- Fix index wallpaper alignment on smartphones. - Fix index wallpaper alignment on smartphones.
- Clean up CSS. - Clean up CSS.
@ -116,7 +144,7 @@ This will upload the specified file to HardFiles and return a direct link to the
## Credits ## Credits
- 🚀 **delorean**, our Senior Director of IRC Diplomacy & SuperNets Brand Strategy 🌐 for developing hardfiles. - 🚀 **delorean**, our Senior Director of IRC Diplomacy & SuperNets Brand Strategy 🌐 for developing hardfiles.
- 🤝 **hgw7**, our Principal Designer of Digital Aquariums & Rare Fish Showcases 🐠 for branding the product. - 🤝 **hgw**, our Principal Designer of Digital Aquariums & Rare Fish Showcases 🐠 for branding the product.
- 💼 **acidvegas**, our Global Director of IRC Communications 💬 for funding the project 💰. - 💼 **acidvegas**, our Global Director of IRC Communications 💬 for funding the project 💰.
___ ___

58
main.go
View File

@ -96,12 +96,12 @@ func Zeros(path string, size int64) error {
return nil return nil
} }
func NameGen() string { func NameGen(fileNameLength int) string {
const chars = "abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ0123456789" const chars = "abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ0123456789-_"
ll := len(chars) ll := len(chars)
b := make([]byte, conf.FileLen) b := make([]byte, fileNameLength)
rand.Read(b) // generates len(b) random bytes rand.Read(b) // generates len(b) random bytes
for i := int64(0); i < int64(conf.FileLen); i++ { for i := int64(0); i < int64(fileNameLength); i++ {
b[i] = chars[int(b[i])%ll] b[i] = chars[int(b[i])%ll]
} }
return string(b) return string(b)
@ -116,7 +116,12 @@ func Exists(path string) bool {
func UploadHandler(w http.ResponseWriter, r *http.Request) { func UploadHandler(w http.ResponseWriter, r *http.Request) {
// expiry time // expiry time
ttl := int64(conf.TTLSeconds) var name string
var ttl int64
var fileNameLength int
fileNameLength = 0
ttl = 0
file, _, err := r.FormFile("file") file, _, err := r.FormFile("file")
if err != nil { if err != nil {
@ -132,10 +137,49 @@ func UploadHandler(w http.ResponseWriter, r *http.Request) {
} }
file.Seek(0, 0) file.Seek(0, 0)
// Check if expiry time is present and length is too long
if r.PostFormValue("expiry") != "" {
ttl, err = strconv.ParseInt(r.PostFormValue("expiry"), 10, 64)
if err != nil {
log.Error().Err(err).Msg("expiry could not be parsed")
} else {
// 5 days max
if ttl < 1 || ttl > 432000 {
w.WriteHeader(http.StatusBadRequest)
return
}
}
}
// Default to conf if not present
if ttl == 0 {
ttl = int64(conf.TTLSeconds)
}
// Check if the file length parameter exists and also if it's too long
if r.PostFormValue("url_len") != "" {
fileNameLength, err = strconv.Atoi(r.PostFormValue("url_len"))
if err != nil {
log.Error().Err(err).Msg("url_len could not be parsed")
} else {
// if the length is < 3 and > 128 return error
if fileNameLength < 3 || fileNameLength > 128 {
w.WriteHeader(http.StatusBadRequest)
return
}
}
}
// Default to conf if not present
if fileNameLength == 0 {
fileNameLength = conf.FileLen
}
// generate + check name // generate + check name
var name string
for { for {
id := NameGen() id := NameGen(fileNameLength)
name = id + mtype.Extension() name = id + mtype.Extension()
if !Exists(conf.FileFolder + "/" + name) { if !Exists(conf.FileFolder + "/" + name) {
break break