Make timeouts configurable.

This commit is contained in:
Solderpunk 2025-02-08 19:05:48 +01:00
parent 89eeb5a55e
commit 308b8fe128
2 changed files with 13 additions and 9 deletions

View file

@ -22,6 +22,8 @@ type SysConfig struct {
SCGIPaths map[string]string
ReadMollyFiles bool
AllowTLS12 bool
ReadTimeout int
WriteTimeoutMinRate int
RateLimitEnable bool
RateLimitAverage int
RateLimitSoft int
@ -61,6 +63,8 @@ func getConfig(filename string) (SysConfig, UserConfig, error) {
sysConfig.SCGIPaths = make(map[string]string)
sysConfig.ReadMollyFiles = false
sysConfig.AllowTLS12 = true
sysConfig.ReadTimeout = 30
sysConfig.WriteTimeoutMinRate = 512
sysConfig.RateLimitEnable = false
sysConfig.RateLimitAverage = 1
sysConfig.RateLimitSoft = 10

View file

@ -67,7 +67,7 @@ func handleGeminiRequest(conn net.Conn, sysConfig SysConfig, config UserConfig,
}
// Read request
URL, err := readRequest(conn, &logEntry)
URL, err := readRequest(conn, &logEntry, sysConfig)
if err != nil {
return
}
@ -214,14 +214,14 @@ func handleGeminiRequest(conn net.Conn, sysConfig SysConfig, config UserConfig,
// Finally, serve a simple static file or directory
if info.IsDir() {
serveDirectory(URL, path, &logEntry, conn, config)
serveDirectory(URL, path, &logEntry, conn, config, sysConfig)
} else {
serveFile(path, info, &logEntry, conn, config)
serveFile(path, info, &logEntry, conn, config, sysConfig)
}
}
func readRequest(conn net.Conn, logEntry *LogEntry) (*url.URL, error) {
err := conn.SetReadDeadline(time.Now().Add(30 * time.Second))
func readRequest(conn net.Conn, logEntry *LogEntry, config SysConfig) (*url.URL, error) {
err := conn.SetReadDeadline(time.Now().Add(time.Duration(config.ReadTimeout) * time.Second))
if err != nil {
log.Println("Error setting read deadline: " + err.Error())
return nil, err
@ -303,7 +303,7 @@ func handleRedirectsInner(URL *url.URL, redirects map[string]string, status int,
}
}
func serveDirectory(URL *url.URL, path string, logEntry *LogEntry, conn net.Conn, config UserConfig) {
func serveDirectory(URL *url.URL, path string, logEntry *LogEntry, conn net.Conn, config UserConfig, sysConfig SysConfig) {
// Redirect to add trailing slash if missing
// (otherwise relative links don't work properly)
if !strings.HasSuffix(URL.Path, "/") {
@ -316,7 +316,7 @@ func serveDirectory(URL *url.URL, path string, logEntry *LogEntry, conn net.Conn
index_path := filepath.Join(path, "index."+config.GeminiExt)
index_info, err := os.Stat(index_path)
if err == nil && uint64(index_info.Mode().Perm())&0444 == 0444 {
serveFile(index_path, index_info, logEntry, conn, config)
serveFile(index_path, index_info, logEntry, conn, config, sysConfig)
// Serve a generated listing
} else if config.DirectoryListing {
listing, err := generateDirectoryListing(URL, path, config)
@ -335,7 +335,7 @@ func serveDirectory(URL *url.URL, path string, logEntry *LogEntry, conn net.Conn
}
}
func serveFile(path string, info os.FileInfo, logEntry *LogEntry, conn net.Conn, config UserConfig) {
func serveFile(path string, info os.FileInfo, logEntry *LogEntry, conn net.Conn, config UserConfig, sysConfig SysConfig) {
// Get MIME type of files
ext := filepath.Ext(path)
var mimeType string
@ -392,7 +392,7 @@ func serveFile(path string, info os.FileInfo, logEntry *LogEntry, conn net.Conn,
// Derive a maximum allowed download time from the filesyize.
// Assume non-malicious clients can manage an average of 0.5 KB/s or better.
// But always allow at least 30 seconds
allowedTime := int(info.Size() / 512)
allowedTime := int(info.Size() / int64(sysConfig.WriteTimeoutMinRate))
if allowedTime < 30 {
allowedTime = 30
}