Add config option to change prefix for Content-Disposition filename. Defaults to backup.

This commit is contained in:
eleksir
2026-03-27 09:50:51 +03:00
parent 607922be19
commit 565e40c9be
9 changed files with 53 additions and 6 deletions

View File

@@ -181,6 +181,7 @@ Config is JSON (HJSON with comments supported). Default path depends on OS:
| backup_timeout | `60` | Stream timeout in minutes (1-1440) |
| compression_level | `9` | Gzip level (1-9) |
| exclude_patterns | `[]` | Regex patterns to exclude from backup |
| filename_prefix | `backup` | Prefix for backup filename in Content-Disposition header |
## Architecture & Key Patterns
@@ -278,4 +279,3 @@ Init scripts provided in `contrib/`:
See `TODO.org` for current backlog:
- Consider alternative compression algorithms (bz2, xz, lzo, lz4)
- Configurable filename prefix for `Content-Disposition` header

View File

@@ -56,6 +56,7 @@ AI suggests to fill this section with useful information, despite that all optio
| backup_timeout | 60 | Timeout in minutes for backup streaming operations. | If a backup takes longer than this, the connection will be terminated. Useful for large backups. Range: 1-1440 minutes (1 day max). |
| compression_level | 9 | Gzip compression level for tar.gz archives. | 1 (fastest) to 9 (best compression). Higher values produce smaller files but take longer to compress. |
| exclude_patterns | [] | Regex patterns to exclude from backup. | E.g., `[".*\\.tmp$", "/node_modules/"]`. Files matching any pattern are skipped. |
| filename_prefix | "backup" | Prefix for backup filename in Content-Disposition header. | E.g., "mybackup" produces `mybackup-20260325-092341.tar.gz`. |
## Best practices

View File

@@ -9,6 +9,6 @@
- [ ] lz4 for speed, xz for better compression
- [ ] Add compression_algorithm config option
** TODO Configurable filename prefix
- [ ] Move "backup" prefix to config (currently hardcoded in newServer.go)
- [ ] Default: "backup", e.g., "backup-20260325-092341.tar.gz"
** DONE Configurable filename prefix
- [X] Move "backup" prefix to config (currently hardcoded in newServer.go)
- [X] Default: "backup", e.g., "backup-20260325-092341.tar.gz"

View File

@@ -33,5 +33,17 @@
"directories": [
"/path/to/directory1",
"/path/to/directory2"
]
],
/* Backup streaming timeout in minutes. */
"backup_timeout": 60,
/* Gzip compression level (1-9, where 9 is best compression). */
"compression_level": 9,
/* Regex patterns to exclude from backup. */
"exclude_patterns": [],
/* Prefix for backup filename in Content-Disposition header. */
"filename_prefix": "backup"
}

View File

@@ -128,6 +128,13 @@ func LoadConfig(path string) error {
return errors.New("Option password is not set")
}
// FilenamePrefix: default.
if C.FilenamePrefix == "" {
C.FilenamePrefix = "backup"
log.Warnf("Config option filename_prefix is not set, fallback to %s", C.FilenamePrefix)
}
// Compile exclude patterns.
excludePatterns = make([]*regexp.Regexp, 0, len(C.ExcludePatterns))

View File

@@ -170,6 +170,27 @@ func TestLoadConfigNoHTTPS(t *testing.T) {
}
}
// TestLoadConfigFilenamePrefixCustom tests custom filename prefix.
func TestLoadConfigFilenamePrefixCustom(t *testing.T) {
config := `{
"user": "test",
"password": "test",
"directories": ["../../test_data/test1/foo"],
"nohttps": true,
"filename_prefix": "mybackup"
}`
tmpFile := writeTempConfig(t, config)
err := LoadConfig(tmpFile)
if err != nil {
t.Errorf("Expected no error, got %v", err)
}
if C.FilenamePrefix != "mybackup" {
t.Errorf("C.FilenamePrefix should be mybackup, got %s", C.FilenamePrefix)
}
}
// TestLoadConfigDefaultValues tests default values are set correctly.
func TestLoadConfigDefaultValues(t *testing.T) {
config := `{
@@ -201,6 +222,10 @@ func TestLoadConfigDefaultValues(t *testing.T) {
if C.LogLevel != "info" {
t.Errorf("C.LogLevel should default to info, got %s", C.LogLevel)
}
if C.FilenamePrefix != "backup" {
t.Errorf("C.FilenamePrefix should default to backup, got %s", C.FilenamePrefix)
}
}
// writeTempConfig is a helper to write a temp config file for testing.

View File

@@ -82,7 +82,7 @@ func NewServer(configPath string) (*http.Server, error) {
}()
timestamp := time.Now().Format("20060102-150405")
filename := fmt.Sprintf("backup-%s.tar.gz", timestamp)
filename := fmt.Sprintf("%s-%s.tar.gz", C.FilenamePrefix, timestamp)
w.Header().Set("Content-Disposition", "attachment; filename="+filename)
w.Header().Set("Content-Type", "application/octet-stream")

View File

@@ -17,6 +17,7 @@ type (
BackupTimeout int `json:"backup_timeout"` // Timeout in minutes for backup streaming.
CompressionLevel int `json:"compression_level"` // Gzip compression level (1-9, default 9).
ExcludePatterns []string `json:"exclude_patterns"` // Regex patterns to exclude from backup.
FilenamePrefix string `json:"filename_prefix"` // Prefix for backup filename (default: "backup").
}
)

View File

@@ -61,6 +61,7 @@ curl -u user:pass https://server:8086/archive -o backup.tar.gz
| backup_timeout | 60 | Stream timeout in minutes (1-1440) |
| compression_level | 9 | Gzip level (1-9) |
| exclude_patterns | [] | Regex patterns to exclude from backup |
| filename_prefix | backup | Prefix for backup filename in Content-Disposition header |
## Key Patterns