fix: 3.0 ipv4|ipv6|auto -genconfig
This commit is contained in:
49
CHANGELOG.md
49
CHANGELOG.md
@ -3,42 +3,35 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
- Initial creation of a comprehensive changelog.
|
||||
|
||||
---
|
||||
|
||||
## [2.8-Stable] - 2026-05-01
|
||||
|
||||
### Added
|
||||
|
||||
### Added (2.8)
|
||||
- Version check history for improved tracking.
|
||||
- Enhanced ClamAV scanning with concurrent workers.
|
||||
|
||||
### Changed
|
||||
|
||||
### Changed (2.8)
|
||||
- Improved ISO-based storage for specialized use cases.
|
||||
- Auto-scaling workers for optimized performance.
|
||||
|
||||
### Fixed
|
||||
|
||||
### Fixed (2.8)
|
||||
- Minor issues in worker thread adjustments under high load.
|
||||
|
||||
---
|
||||
|
||||
## [2.7] - 2026-02-10
|
||||
|
||||
### Added
|
||||
|
||||
### Added (2.7)
|
||||
- Concurrency improvements and auto-scaling worker enhancements
|
||||
- Cleanup and removal of unused parameters in sorting functions
|
||||
|
||||
### Changed
|
||||
|
||||
### Changed (2.7)
|
||||
- Additional logging for file scanning operations
|
||||
|
||||
### Fixed
|
||||
|
||||
### Fixed (2.7)
|
||||
- Minor stability issues related to ISO container mounting
|
||||
- Fixed dual stack for upload (IPv4/IPv6)
|
||||
|
||||
@ -46,20 +39,17 @@ All notable changes to this project will be documented in this file.
|
||||
|
||||
## [2.6-Stable] - 2025-12-01
|
||||
|
||||
### Added
|
||||
|
||||
### Added (2.6)
|
||||
- Deduplication support (removes duplicate files).
|
||||
- ISO Container management.
|
||||
- Dynamic worker scaling based on CPU & memory.
|
||||
- PreCaching feature for faster file access.
|
||||
|
||||
### Changed
|
||||
|
||||
### Changed (2.6)
|
||||
- Worker pool scaling strategies for better performance.
|
||||
- Enhanced logging with rotating logs using lumberjack.
|
||||
|
||||
### Fixed
|
||||
|
||||
### Fixed (2.6)
|
||||
- Temporary file handling issues causing "Unsupported file type" warnings.
|
||||
- MIME type checks for file extension mismatches.
|
||||
|
||||
@ -67,44 +57,37 @@ All notable changes to this project will be documented in this file.
|
||||
|
||||
## [2.5] - 2025-09-15
|
||||
|
||||
### Added
|
||||
|
||||
### Added (2.5)
|
||||
- Redis caching integration for file metadata.
|
||||
- ClamAV scanning for virus detection before finalizing uploads.
|
||||
|
||||
### Changed
|
||||
|
||||
### Changed (2.5)
|
||||
- Extended the default chunk size for chunked uploads.
|
||||
- Updated official documentation links.
|
||||
|
||||
### Fixed
|
||||
|
||||
### Fixed (2.5)
|
||||
- Edge case with versioning causing file rename conflicts.
|
||||
|
||||
---
|
||||
|
||||
## [2.0] - 2025-06-01
|
||||
|
||||
### Added
|
||||
|
||||
### Added (2.0)
|
||||
- Chunked file uploads and downloads.
|
||||
- Resumable upload support with partial file retention.
|
||||
|
||||
### Changed
|
||||
|
||||
### Changed (2.0)
|
||||
- Moved configuration management to Viper.
|
||||
- Default Prometheus metrics for tracking memory & CPU usage.
|
||||
|
||||
### Fixed
|
||||
|
||||
### Fixed (2.0)
|
||||
- Race conditions in file locking under heavy concurrency.
|
||||
|
||||
---
|
||||
|
||||
## [1.0] - 2025-01-01
|
||||
|
||||
### Added
|
||||
|
||||
### Added (1.0)
|
||||
- Initial release with HMAC-based authentication.
|
||||
- Basic file upload/download endpoints.
|
||||
- Logging and fundamental configuration using .toml files.
|
||||
|
@ -423,8 +423,30 @@ func main() {
|
||||
|
||||
var configFile string
|
||||
flag.StringVar(&configFile, "config", "./config.toml", "Path to configuration file \"config.toml\".")
|
||||
var genConfig bool
|
||||
var genConfigPath string
|
||||
flag.BoolVar(&genConfig, "genconfig", false, "Print example configuration and exit.")
|
||||
flag.StringVar(&genConfigPath, "genconfig-path", "", "Write example configuration to the given file and exit.")
|
||||
flag.Parse()
|
||||
|
||||
if genConfig {
|
||||
printExampleConfig()
|
||||
os.Exit(0)
|
||||
}
|
||||
if genConfigPath != "" {
|
||||
f, err := os.Create(genConfigPath)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Failed to create file: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
defer f.Close()
|
||||
w := bufio.NewWriter(f)
|
||||
fmt.Fprint(w, getExampleConfigString())
|
||||
w.Flush()
|
||||
fmt.Printf("Example config written to %s\n", genConfigPath)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
// Initialize Viper
|
||||
viper.SetConfigType("toml")
|
||||
|
||||
@ -622,9 +644,16 @@ func main() {
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to initialize network protocol: %v", err)
|
||||
}
|
||||
// Enhanced dual-stack HTTP client for robust IPv4/IPv6 and resource management
|
||||
// See: https://pkg.go.dev/net/http#Transport for details on these settings
|
||||
dualStackClient = &http.Client{
|
||||
Transport: &http.Transport{
|
||||
DialContext: dialer.DialContext,
|
||||
DialContext: dialer.DialContext,
|
||||
IdleConnTimeout: 90 * time.Second, // Close idle connections after 90s
|
||||
MaxIdleConns: 100, // Max idle connections across all hosts
|
||||
MaxIdleConnsPerHost: 10, // Max idle connections per host
|
||||
TLSHandshakeTimeout: 10 * time.Second, // Timeout for TLS handshake
|
||||
ResponseHeaderTimeout: 15 * time.Second, // Timeout for reading response headers
|
||||
},
|
||||
}
|
||||
|
||||
@ -776,6 +805,98 @@ version = "2.9-Stable"
|
||||
`)
|
||||
}
|
||||
|
||||
func getExampleConfigString() string {
|
||||
return `
|
||||
[server]
|
||||
bind_ip = "0.0.0.0"
|
||||
listenport = "8080"
|
||||
unixsocket = false
|
||||
storagepath = "./uploads"
|
||||
logfile = "/var/log/hmac-file-server.log"
|
||||
metricsenabled = true
|
||||
metricsport = "9090"
|
||||
minfreebytes = "100MB"
|
||||
filettl = "8760h"
|
||||
filettlenabled = true
|
||||
autoadjustworkers = true
|
||||
networkevents = true
|
||||
pidfilepath = "/var/run/hmacfileserver.pid"
|
||||
cleanuponexit = true
|
||||
precaching = true
|
||||
deduplicationenabled = true
|
||||
globalextensions = [".txt", ".pdf", ".png", ".jpg", ".jpeg", ".gif", ".bmp", ".tiff", ".svg", ".webp"]
|
||||
# FileNaming options: "HMAC", "None"
|
||||
filenaming = "HMAC"
|
||||
forceprotocol = "auto"
|
||||
|
||||
[logging]
|
||||
level = "info"
|
||||
file = "/var/log/hmac-file-server.log"
|
||||
max_size = 100
|
||||
max_backups = 7
|
||||
max_age = 30
|
||||
compress = true
|
||||
|
||||
[deduplication]
|
||||
enabled = true
|
||||
directory = "./deduplication"
|
||||
|
||||
[iso]
|
||||
enabled = true
|
||||
size = "1GB"
|
||||
mountpoint = "/mnt/iso"
|
||||
charset = "utf-8"
|
||||
containerfile = "/mnt/iso/container.iso"
|
||||
|
||||
[timeouts]
|
||||
readtimeout = "4800s"
|
||||
writetimeout = "4800s"
|
||||
idletimeout = "4800s"
|
||||
|
||||
[security]
|
||||
secret = "changeme"
|
||||
|
||||
[versioning]
|
||||
enableversioning = false
|
||||
maxversions = 1
|
||||
|
||||
[uploads]
|
||||
resumableuploadsenabled = true
|
||||
chunkeduploadsenabled = true
|
||||
chunksize = "8192"
|
||||
allowedextensions = [".txt", ".pdf", ".png", ".jpg", ".jpeg", ".gif", ".bmp", ".tiff", ".svg", ".webp"]
|
||||
|
||||
[downloads]
|
||||
resumabledownloadsenabled = true
|
||||
chunkeddownloadsenabled = true
|
||||
chunksize = "8192"
|
||||
allowedextensions = [".txt", ".pdf", ".png", ".jpg", ".jpeg", ".gif", ".bmp", ".tiff", ".svg", ".webp"]
|
||||
|
||||
[clamav]
|
||||
clamavenabled = true
|
||||
clamavsocket = "/var/run/clamav/clamd.ctl"
|
||||
numscanworkers = 2
|
||||
scanfileextensions = [".txt", ".pdf", ".png", ".jpg", ".jpeg", ".gif", ".bmp", ".tiff", ".svg", ".webp"]
|
||||
|
||||
[redis]
|
||||
redisenabled = true
|
||||
redisdbindex = 0
|
||||
redisaddr = "localhost:6379"
|
||||
redispassword = ""
|
||||
redishealthcheckinterval = "120s"
|
||||
|
||||
[workers]
|
||||
numworkers = 4
|
||||
uploadqueuesize = 50
|
||||
|
||||
[file]
|
||||
# Add file-specific configurations here
|
||||
|
||||
[build]
|
||||
version = "2.9-Stable"
|
||||
`
|
||||
}
|
||||
|
||||
func max(a, b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
@ -1876,6 +1997,8 @@ func handleUpload(w http.ResponseWriter, r *http.Request, absFilename, fileStore
|
||||
err = createFile(tempFilename, r)
|
||||
if err != nil {
|
||||
log.WithFields(logrus.Fields{
|
||||
|
||||
|
||||
"filename": finalFilename,
|
||||
}).WithError(err).Error("Error creating temp file")
|
||||
http.Error(w, "Error writing temp file", http.StatusInternalServerError)
|
||||
|
39
test/server_flags_test.go
Normal file
39
test/server_flags_test.go
Normal file
@ -0,0 +1,39 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// TestGenConfigFlag runs the server with --genconfig and checks output for expected config keys
|
||||
func TestGenConfigFlag(t *testing.T) {
|
||||
cmd := exec.Command("go", "run", "../cmd/server/main.go", "--genconfig")
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil && !strings.Contains(string(output), "[server]") {
|
||||
t.Fatalf("Failed to run with --genconfig: %v\nOutput: %s", err, output)
|
||||
}
|
||||
if !strings.Contains(string(output), "[server]") || !strings.Contains(string(output), "bind_ip") {
|
||||
t.Errorf("Example config missing expected keys. Output: %s", output)
|
||||
}
|
||||
}
|
||||
|
||||
// TestIPv4IPv6Flag runs the server with forceprotocol=ipv4 and ipv6 and checks for startup errors
|
||||
func TestIPv4IPv6Flag(t *testing.T) {
|
||||
for _, proto := range []string{"ipv4", "ipv6", "auto"} {
|
||||
cmd := exec.Command("go", "run", "../cmd/server/main.go", "--config", "../cmd/server/config.toml")
|
||||
cmd.Env = append(os.Environ(), "FORCEPROTOCOL="+proto)
|
||||
// Set Go module cache environment variables if not already set
|
||||
if os.Getenv("GOMODCACHE") == "" {
|
||||
cmd.Env = append(cmd.Env, "GOMODCACHE="+os.Getenv("HOME")+"/go/pkg/mod")
|
||||
}
|
||||
if os.Getenv("GOPATH") == "" {
|
||||
cmd.Env = append(cmd.Env, "GOPATH="+os.Getenv("HOME")+"/go")
|
||||
}
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil && !strings.Contains(string(output), "Configuration loaded successfully") {
|
||||
t.Errorf("Server failed to start with forceprotocol=%s: %v\nOutput: %s", proto, err, output)
|
||||
}
|
||||
}
|
||||
}
|
36
wiki.md
36
wiki.md
@ -697,6 +697,23 @@ To set up a reverse proxy for the HMAC File Server, you can use either Apache2 o
|
||||
|
||||
---
|
||||
|
||||
### Proxy Best Practices & Recommendations
|
||||
|
||||
For production deployments, consider the following reverse proxy best practices:
|
||||
|
||||
- **Timeouts**: Set reasonable timeouts (e.g., `proxy_read_timeout 300;` in Nginx) to avoid hanging connections.
|
||||
- **Buffer Sizes**: Increase buffer sizes for large file uploads/downloads if needed (e.g., `client_max_body_size 2G;` in Nginx).
|
||||
- **Headers**: Always set security headers (`X-Content-Type-Options`, `X-Frame-Options`, `X-XSS-Protection`).
|
||||
- **Forwarded Headers**: Ensure `X-Forwarded-For` and `X-Forwarded-Proto` are set for correct client IP and protocol logging.
|
||||
- **HTTP/2**: Enable HTTP/2 for better performance if supported by your proxy and clients.
|
||||
- **SSL/TLS**: Terminate SSL at the proxy and use strong ciphers. Redirect HTTP to HTTPS.
|
||||
- **Health Checks**: Configure health checks for the backend server to enable automatic failover or alerting.
|
||||
- **Access Controls**: Restrict access to the management endpoints (e.g., `/metrics`) to trusted IPs only.
|
||||
|
||||
See the official Nginx and Apache documentation for more advanced tuning options.
|
||||
|
||||
---
|
||||
|
||||
#### 3. ejabberd Configuration
|
||||
|
||||
```yaml
|
||||
@ -944,6 +961,12 @@ curl -O "$BASE_URL/download/$FILENAME?ts=$TIMESTAMP&sig=$SIGNATURE"
|
||||
### GitHub Actions Example
|
||||
|
||||
```yaml
|
||||
name: Build and Upload to HMAC
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "main" ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
@ -964,10 +987,14 @@ jobs:
|
||||
|
||||
## Optional Features
|
||||
|
||||
- **TTL**: Auto-delete artifacts after a set time
|
||||
- **Deduplication**: Only store unique files
|
||||
- **Versioning**: Track changes to files over time
|
||||
- **Virus Scanning**: Integrate with ClamAV
|
||||
- **TTL**
|
||||
Auto-delete artifacts after a set time.
|
||||
- **Deduplication**
|
||||
Only store unique files.
|
||||
- **Versioning**
|
||||
Track changes to files over time.
|
||||
- **Virus Scanning**
|
||||
Integrate with ClamAV to scan uploaded files.
|
||||
|
||||
---
|
||||
|
||||
@ -978,6 +1005,7 @@ The HMAC File Server provides a built-in monitoring interface to track system pe
|
||||
### System Data
|
||||
|
||||
The monitoring interface displays key system metrics, including:
|
||||
|
||||
- **CPU Usage**: Current CPU usage percentage.
|
||||
- **Memory Usage**: Current memory usage percentage.
|
||||
- **CPU Cores**: Number of CPU cores available.
|
||||
|
Reference in New Issue
Block a user