Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const fullWildcardRegexpValue = ".*"

// Experimental: this symbol is exported to allow users adding new values, but may be removed in the feature.
// TODO: there is nothing in the Go stdlib to find the default port associated with a protocol.
// Let's just replace values for protocols in specialSchemeList for now.
// Let's just replace values for protocols in specialSchemeSet for now.
// This list could be completed using https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers
var DefaultPorts = map[string]string{
"http": "80",
Expand Down
42 changes: 27 additions & 15 deletions urlpattern.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,13 @@ var (
)

// https://url.spec.whatwg.org/#special-scheme
var specialSchemeList = []string{"ftp", "http", "https", "ws", "wss"}
var specialSchemeSet = map[string]struct{}{
"ftp": {},
"http": {},
"https": {},
"ws": {},
"wss": {},
}
Comment thread
dunglas marked this conversation as resolved.

type URLPatternResult struct {
Inputs []string
Expand Down Expand Up @@ -100,7 +106,7 @@ type component struct {

// https://urlpattern.spec.whatwg.org/#protocol-component-matches-a-special-scheme
func (c *component) protocolComponentMatchesSpecialScheme() bool {
for _, scheme := range specialSchemeList {
for scheme := range specialSchemeSet {
if c.regularExpression.MatchString(scheme) {
return true
}
Expand Down Expand Up @@ -165,10 +171,18 @@ func (init *URLPatternInit) New(opt *Options) (*URLPattern, error) {
}

var emptyString string
for _, s := range specialSchemeList {
if *processedInit.Protocol == s && *processedInit.Port == DefaultPorts[s] {
// Only clear the port when the protocol is a WHATWG special scheme; the
// exported DefaultPorts map is user-extendable, so keying off it alone
// would quietly apply the behaviour to arbitrary user-added protocols.
//
// In "pattern" mode processedInit.Protocol is not canonicalized, so
// lowercase it for the comparison: the protocol component is compiled
// with canonicalizeProtocol (which lowercases), so the effective pattern
// is the lowercase form.
canonicalProtocol := strings.ToLower(*processedInit.Protocol)
if _, isSpecial := specialSchemeSet[canonicalProtocol]; isSpecial {
if dp, ok := DefaultPorts[canonicalProtocol]; ok && *processedInit.Port == dp {
processedInit.Port = &emptyString
break
}
}

Expand All @@ -191,13 +205,15 @@ func (init *URLPatternInit) New(opt *Options) (*URLPattern, error) {

// If the result running hostname pattern is an IPv6 address given processedInit["hostname"] is true, then set urlPattern’s hostname component to the result of compiling a component given processedInit["hostname"], canonicalize an IPv6 hostname, and hostname options.

protocolMatchesSpecialScheme := urlPattern.protocol.protocolComponentMatchesSpecialScheme()

hostnameOptions := options{delimiterCodePoint: '.'}
if hostnamePatternIsIPv6Address(*processedInit.Hostname) {
urlPattern.hostname, err = compileComponent(*processedInit.Hostname, canonicalizeIPv6Hostname, hostnameOptions)
if err != nil {
return nil, err
}
} else if urlPattern.protocol.protocolComponentMatchesSpecialScheme() || *processedInit.Protocol == "*" {
} else if protocolMatchesSpecialScheme || *processedInit.Protocol == "*" {
urlPattern.hostname, err = compileComponent(*processedInit.Hostname, canonicalizeDomainName, hostnameOptions)
if err != nil {
return nil, err
Expand All @@ -219,7 +235,7 @@ func (init *URLPatternInit) New(opt *Options) (*URLPattern, error) {

pathnameOptions := options{'/', '/', false}

if urlPattern.protocol.protocolComponentMatchesSpecialScheme() {
if protocolMatchesSpecialScheme {
pathCompileOptions := pathnameOptions
pathCompileOptions.ignoreCase = opt.IgnoreCase

Expand Down Expand Up @@ -629,10 +645,8 @@ func processHostnameForInit(value, protocolValue, uType string) (string, error)
return canonicalizeDomainName(value)
}

for _, s := range specialSchemeList {
if protocolValue == s {
return canonicalizeDomainName(value)
}
if _, ok := specialSchemeSet[protocolValue]; ok {
return canonicalizeDomainName(value)
}

return canonicalizeHostname(value, protocolValue)
Expand All @@ -657,10 +671,8 @@ func processPathnameForInit(pathnameValue, protocolValue, ptype string) (string,
return canonicalizePathname(pathnameValue)
}

for _, ss := range specialSchemeList {
if protocolValue == ss {
return canonicalizePathname(pathnameValue)
}
if _, ok := specialSchemeSet[protocolValue]; ok {
return canonicalizePathname(pathnameValue)
}

return canonicalizeOpaquePathname(pathnameValue)
Expand Down
Loading