httpdl/cli: drop --auto-split; classify errors by type, not message text
Two Pike cleanups. --auto-split was a third connection-count policy (beside -x and -s) that added an extra knob rather than keeping the model minimal. Removing it also retires the now-dead autoConns/maxAutoConns and the per-host transport cap that existed only to scale for it; min(split, M*-x) is the sole policy again. main's exit-code mapping fell back to substring-matching third-party error text (strings.Contains "connection refused"/"timeout"/...), which rots when a dependency rewords a message. The typed checks (errors.Is on the syscall errno, *net.DNSError, net.Error.Timeout, context.DeadlineExceeded) already cover the real stdlib errors -- verified end to end: refused -> 6, bad host -> 19. The two cases that genuinely needed the text match are our own errors, now typed sentinels: httpdl.ErrTimeout (idle timeout) and the bt metadata timeout wrapping context.DeadlineExceeded.
This commit is contained in:
34
main.go
34
main.go
@@ -530,7 +530,6 @@ func httpConfig(opts *cli.Options, single bool, overallDL *rate.Limiter) httpdl.
|
||||
Split: opts.Int("split"),
|
||||
MaxConnPerServer: opts.Int("max-connection-per-server"),
|
||||
MinSplit: opts.Size("min-split-size"),
|
||||
AutoSplit: opts.Bool("auto-split"),
|
||||
Tries: opts.Int("max-tries"),
|
||||
Timeout: time.Duration(opts.Int("timeout")) * time.Second,
|
||||
FileAlloc: opts.Str("file-allocation"),
|
||||
@@ -717,42 +716,29 @@ func exitCode(err error) int {
|
||||
|
||||
// isNameResolution reports whether err is (or wraps) a DNS lookup failure —
|
||||
// "name resolution failed" (19), which usually points at the user's own
|
||||
// network or resolver rather than a dead remote.
|
||||
// network or resolver rather than a dead remote. The stdlib reports every such
|
||||
// failure (no-such-host, server-misbehaving) as *net.DNSError.
|
||||
func isNameResolution(err error) bool {
|
||||
var de *net.DNSError
|
||||
if errors.As(err, &de) {
|
||||
return true
|
||||
}
|
||||
msg := strings.ToLower(err.Error())
|
||||
return strings.Contains(msg, "no such host") || strings.Contains(msg, "server misbehaving")
|
||||
return errors.As(err, &de)
|
||||
}
|
||||
|
||||
// isNetwork reports whether err is a connection-level failure — refused, reset,
|
||||
// or an unreachable host/network — a "network problem" (6).
|
||||
// or an unreachable host/network — a "network problem" (6). A dial error from
|
||||
// net/http wraps the syscall errno, so the typed check sees through it.
|
||||
func isNetwork(err error) bool {
|
||||
if errors.Is(err, syscall.ECONNREFUSED) || errors.Is(err, syscall.ECONNRESET) ||
|
||||
errors.Is(err, syscall.ENETUNREACH) || errors.Is(err, syscall.EHOSTUNREACH) {
|
||||
return true
|
||||
}
|
||||
msg := strings.ToLower(err.Error())
|
||||
return strings.Contains(msg, "connection refused") ||
|
||||
strings.Contains(msg, "connection reset") ||
|
||||
strings.Contains(msg, "network is unreachable") ||
|
||||
strings.Contains(msg, "no route to host")
|
||||
return errors.Is(err, syscall.ECONNREFUSED) || errors.Is(err, syscall.ECONNRESET) ||
|
||||
errors.Is(err, syscall.ENETUNREACH) || errors.Is(err, syscall.EHOSTUNREACH)
|
||||
}
|
||||
|
||||
// isTimeout reports whether err is (or wraps) a timeout: a deadline exceeded, a
|
||||
// net.Error that timed out, or an idle-read timeout reported as such.
|
||||
// net.Error that timed out, or our own idle-read timeout (httpdl.ErrTimeout).
|
||||
func isTimeout(err error) bool {
|
||||
if errors.Is(err, context.DeadlineExceeded) {
|
||||
if errors.Is(err, context.DeadlineExceeded) || errors.Is(err, httpdl.ErrTimeout) {
|
||||
return true
|
||||
}
|
||||
var ne net.Error
|
||||
if errors.As(err, &ne) && ne.Timeout() {
|
||||
return true
|
||||
}
|
||||
msg := strings.ToLower(err.Error())
|
||||
return strings.Contains(msg, "timeout") || strings.Contains(msg, "timed out")
|
||||
return errors.As(err, &ne) && ne.Timeout()
|
||||
}
|
||||
|
||||
// saveSession writes the sources of every download that did not finish to path,
|
||||
|
||||
Reference in New Issue
Block a user