full diff: https://github.com/docker/go-connections/compare/v0.6.0...v0.7.0 Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
61 lines
1.6 KiB
Go
61 lines
1.6 KiB
Go
package nat
|
||
|
||
import (
|
||
"errors"
|
||
"fmt"
|
||
"strconv"
|
||
"strings"
|
||
)
|
||
|
||
// ParsePortRange parses and validates the specified string as a port range (e.g., "8000-9000").
|
||
func ParsePortRange(ports string) (startPort, endPort uint64, _ error) {
|
||
start, end, err := parsePortRange(ports)
|
||
return uint64(start), uint64(end), err
|
||
}
|
||
|
||
// parsePortRange parses and validates the specified string as a port range (e.g., "8000-9000").
|
||
func parsePortRange(ports string) (startPort, endPort int, _ error) {
|
||
if ports == "" {
|
||
return 0, 0, errors.New("empty string specified for ports")
|
||
}
|
||
start, end, ok := strings.Cut(ports, "-")
|
||
|
||
startPort, err := parsePortNumber(start)
|
||
if err != nil {
|
||
return 0, 0, fmt.Errorf("invalid start port '%s': %w", start, err)
|
||
}
|
||
if !ok || start == end {
|
||
return startPort, startPort, nil
|
||
}
|
||
|
||
endPort, err = parsePortNumber(end)
|
||
if err != nil {
|
||
return 0, 0, fmt.Errorf("invalid end port '%s': %w", end, err)
|
||
}
|
||
if endPort < startPort {
|
||
return 0, 0, errors.New("invalid port range: " + ports)
|
||
}
|
||
return startPort, endPort, nil
|
||
}
|
||
|
||
// parsePortNumber parses rawPort into an int, unwrapping strconv errors
|
||
// and returning a single "out of range" error for any value outside 0–65535.
|
||
func parsePortNumber(rawPort string) (int, error) {
|
||
if rawPort == "" {
|
||
return 0, errors.New("value is empty")
|
||
}
|
||
port, err := strconv.ParseInt(rawPort, 10, 0)
|
||
if err != nil {
|
||
var numErr *strconv.NumError
|
||
if errors.As(err, &numErr) {
|
||
err = numErr.Err
|
||
}
|
||
return 0, err
|
||
}
|
||
if port < 0 || port > 65535 {
|
||
return 0, errors.New("value out of range (0–65535)")
|
||
}
|
||
|
||
return int(port), nil
|
||
}
|