Browse Source

refactor: Extract newClientWithTimeout helper to reduce code duplication

- Added newClientWithTimeout() helper method that creates a temporary
  http.Client with the specified timeout, reusing the TLS transport
- Updated uploadFileToFiler, fetchFileContent, DownloadFile, and
  isLikelyTextFile to use the new helper
- Improved error message in DownloadFile to include response body
  for better debuggability (consistent with fetchFileContent)
pull/7633/head
chrislu 5 days ago
parent
commit
a30067f7e7
  1. 40
      weed/admin/handlers/file_browser_handlers.go

40
weed/admin/handlers/file_browser_handlers.go

@ -48,6 +48,15 @@ func NewFileBrowserHandlers(adminServer *dash.AdminServer) *FileBrowserHandlers
}
}
// newClientWithTimeout creates a temporary http.Client with the specified timeout,
// reusing the TLS transport from the shared httpClient.
func (h *FileBrowserHandlers) newClientWithTimeout(timeout time.Duration) http.Client {
return http.Client{
Transport: h.httpClient.Client.Transport,
Timeout: timeout,
}
}
// ShowFileBrowser renders the file browser page
func (h *FileBrowserHandlers) ShowFileBrowser(c *gin.Context) {
// Get path from query parameter, default to root
@ -384,11 +393,8 @@ func (h *FileBrowserHandlers) uploadFileToFiler(filePath string, fileHeader *mul
// lgtm[go/ssrf]
// Safe: filerAddress validated by validateFilerAddress() to match configured filer
// Safe: cleanFilePath validated and cleaned by validateAndCleanFilePath() to prevent path traversal
clientWithTimeout := http.Client{
Transport: h.httpClient.Client.Transport,
Timeout: 60 * time.Second,
}
resp, err := clientWithTimeout.Do(req)
client := h.newClientWithTimeout(60 * time.Second)
resp, err := client.Do(req)
if err != nil {
return fmt.Errorf("failed to upload file: %w", err)
}
@ -496,11 +502,8 @@ func (h *FileBrowserHandlers) fetchFileContent(filePath string, timeout time.Dur
// lgtm[go/ssrf]
// Safe: filerAddress validated by validateFilerAddress() to match configured filer
// Safe: cleanFilePath validated and cleaned by validateAndCleanFilePath() to prevent path traversal
clientWithTimeout := http.Client{
Transport: h.httpClient.Client.Transport,
Timeout: timeout,
}
resp, err := clientWithTimeout.Get(fileURL)
client := h.newClientWithTimeout(timeout)
resp, err := client.Get(fileURL)
if err != nil {
return "", fmt.Errorf("failed to fetch file from filer: %w", err)
}
@ -560,11 +563,8 @@ func (h *FileBrowserHandlers) DownloadFile(c *gin.Context) {
// lgtm[go/ssrf]
// Safe: filerAddress validated by validateFilerAddress() to match configured filer
// Safe: cleanFilePath validated and cleaned by validateAndCleanFilePath() to prevent path traversal
clientWithTimeout := http.Client{
Transport: h.httpClient.Client.Transport,
Timeout: 5 * time.Minute, // Longer timeout for large file downloads
}
resp, err := clientWithTimeout.Get(downloadURL)
client := h.newClientWithTimeout(5 * time.Minute) // Longer timeout for large file downloads
resp, err := client.Get(downloadURL)
if err != nil {
c.JSON(http.StatusBadGateway, gin.H{"error": "Failed to fetch file from filer: " + err.Error()})
return
@ -572,7 +572,8 @@ func (h *FileBrowserHandlers) DownloadFile(c *gin.Context) {
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
c.JSON(resp.StatusCode, gin.H{"error": fmt.Sprintf("Filer returned status %d", resp.StatusCode)})
body, _ := io.ReadAll(resp.Body)
c.JSON(resp.StatusCode, gin.H{"error": fmt.Sprintf("Filer returned status %d: %s", resp.StatusCode, string(body))})
return
}
@ -993,11 +994,8 @@ func (h *FileBrowserHandlers) isLikelyTextFile(filePath string, maxCheckSize int
// lgtm[go/ssrf]
// Safe: filerAddress validated by validateFilerAddress() to match configured filer
// Safe: cleanFilePath validated and cleaned by validateAndCleanFilePath() to prevent path traversal
clientWithTimeout := http.Client{
Transport: h.httpClient.Client.Transport,
Timeout: 10 * time.Second,
}
resp, err := clientWithTimeout.Get(fileURL)
client := h.newClientWithTimeout(10 * time.Second)
resp, err := client.Get(fileURL)
if err != nil || resp.StatusCode != http.StatusOK {
return false
}

Loading…
Cancel
Save