feat: use ContentType to control HTML extension
This commit is contained in:
+19
-2
@@ -130,9 +130,12 @@ func runPostDownload(
|
|||||||
fmt.Fprintf(os.Stderr, "Warning: failed to close writer: %v\n", cerr)
|
fmt.Fprintf(os.Stderr, "Warning: failed to close writer: %v\n", cerr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust extension: append .html to HTML files without extension
|
// Adjust extension: append .html to HTML files without extension.
|
||||||
|
// When ContentType is available (WebDAV, Gopher), only apply to
|
||||||
|
// text/html responses. When ContentType is empty (HTTP legacy
|
||||||
|
// path), preserve the existing wget-compatible behaviour.
|
||||||
if *f.AdjustExt && *f.Output != "" {
|
if *f.AdjustExt && *f.Output != "" {
|
||||||
if filepath.Ext(*f.Output) == "" {
|
if filepath.Ext(*f.Output) == "" && isHTMLContentType(result.ContentType) {
|
||||||
newPath := *f.Output + ".html"
|
newPath := *f.Output + ".html"
|
||||||
if err := os.Rename(*f.Output, newPath); err == nil {
|
if err := os.Rename(*f.Output, newPath); err == nil {
|
||||||
*f.Output = newPath
|
*f.Output = newPath
|
||||||
@@ -289,6 +292,20 @@ func runPostDownload(
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// isHTMLContentType returns true when ct indicates HTML content.
|
||||||
|
// An empty string is treated as HTML for backward compatibility with
|
||||||
|
// protocol handlers that do not populate ContentType (e.g. HTTP).
|
||||||
|
func isHTMLContentType(ct string) bool {
|
||||||
|
if ct == "" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// Strip parameters (charset, boundary, …).
|
||||||
|
if i := strings.IndexByte(ct, ';'); i >= 0 {
|
||||||
|
ct = ct[:i]
|
||||||
|
}
|
||||||
|
return strings.TrimSpace(ct) == "text/html"
|
||||||
|
}
|
||||||
|
|
||||||
// splitCommand splits a shell-like command string into tokens respecting double quotes.
|
// splitCommand splits a shell-like command string into tokens respecting double quotes.
|
||||||
// Used to parse --on-complete and --on-complete-url without invoking a shell.
|
// Used to parse --on-complete and --on-complete-url without invoking a shell.
|
||||||
func splitCommand(raw string) []string {
|
func splitCommand(raw string) []string {
|
||||||
|
|||||||
@@ -103,6 +103,7 @@ type DownloadResult struct {
|
|||||||
Parallel bool
|
Parallel bool
|
||||||
ChunksCount int
|
ChunksCount int
|
||||||
HTTPStatusCode int // HTTP status code from response
|
HTTPStatusCode int // HTTP status code from response
|
||||||
|
ContentType string // Content-Type from response (if available)
|
||||||
TraceTimings *TraceTimings // HTTP tracing breakdown
|
TraceTimings *TraceTimings // HTTP tracing breakdown
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -209,9 +209,22 @@ func (p *Protocol) downloadText(ctx context.Context, reader *bufio.Reader, req *
|
|||||||
IPVersion: 4,
|
IPVersion: 4,
|
||||||
Speed: speed,
|
Speed: speed,
|
||||||
OutputPath: req.Output,
|
OutputPath: req.Output,
|
||||||
|
ContentType: gopherContentType(firstType),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// gopherContentType returns the MIME content type for a gopher item type.
|
||||||
|
func gopherContentType(t byte) string {
|
||||||
|
switch t {
|
||||||
|
case typeHTML:
|
||||||
|
return "text/html"
|
||||||
|
case typeTextFile, typeInformation:
|
||||||
|
return "text/plain"
|
||||||
|
default:
|
||||||
|
return "application/octet-stream"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// downloadDirectory formats a directory listing as readable text.
|
// downloadDirectory formats a directory listing as readable text.
|
||||||
func (p *Protocol) downloadDirectory(reader *bufio.Reader, req *core.DownloadRequest, startTime time.Time) (*core.DownloadResult, error) {
|
func (p *Protocol) downloadDirectory(reader *bufio.Reader, req *core.DownloadRequest, startTime time.Time) (*core.DownloadResult, error) {
|
||||||
var writer io.Writer
|
var writer io.Writer
|
||||||
@@ -261,6 +274,7 @@ func (p *Protocol) downloadDirectory(reader *bufio.Reader, req *core.DownloadReq
|
|||||||
IPVersion: 4,
|
IPVersion: 4,
|
||||||
Speed: speed,
|
Speed: speed,
|
||||||
OutputPath: req.Output,
|
OutputPath: req.Output,
|
||||||
|
ContentType: "text/plain",
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -313,6 +327,7 @@ func (p *Protocol) downloadBinary(ctx context.Context, reader *bufio.Reader, req
|
|||||||
IPVersion: 4,
|
IPVersion: 4,
|
||||||
Speed: speed,
|
Speed: speed,
|
||||||
OutputPath: req.Output,
|
OutputPath: req.Output,
|
||||||
|
ContentType: "application/octet-stream",
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -680,6 +680,7 @@ func (p *Protocol) downloadFile(ctx context.Context, req *core.DownloadRequest,
|
|||||||
OutputPath: req.Output,
|
OutputPath: req.Output,
|
||||||
Resumed: resumed,
|
Resumed: resumed,
|
||||||
ChunksCount: 1,
|
ChunksCount: 1,
|
||||||
|
ContentType: resp.Header.Get("Content-Type"),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user