Skip to content

Commit

Permalink
split Corpus into base array and spill slice
Browse files Browse the repository at this point in the history
  • Loading branch information
jub0bs committed Jan 31, 2025
1 parent ddc8552 commit f6f9023
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 18 deletions.
2 changes: 1 addition & 1 deletion config.go
Original file line number Diff line number Diff line change
Expand Up @@ -862,7 +862,7 @@ func newConfig(icfg *internalConfig) *Config {
var cfg Config

// origins
if icfg.corpus == nil {
if icfg.corpus.IsEmpty() {
cfg.Origins = []string{"*"}
} else {
cfg.Origins = icfg.corpus.Elems()
Expand Down
62 changes: 49 additions & 13 deletions internal/origins/corpus.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,39 +9,75 @@ import (
// A Corpus represents a set of allowed (tuple) [Web origins].
//
// [Web origins]: https://developer.mozilla.org/en-US/docs/Glossary/Origin
type Corpus []Root
type Corpus struct {
base [4]Root
spill []Root
next int
}

type Root struct {
scheme string
tree radix.Tree
}

func (c *Corpus) IsEmpty() bool {
return c.next == 0
}

// Add augments c with all Web origins encompassed by pattern.
func (c *Corpus) Add(pattern *Pattern) {
i := slices.IndexFunc(*c, func(r Root) bool { return r.scheme == pattern.Scheme })
if i < 0 {
var tree radix.Tree
tree.Insert(pattern.Value, pattern.Port)
root := Root{scheme: pattern.Scheme, tree: tree}
*c = append(*c, root)
// search array first
for i := range c.next {
if c.base[i].scheme == pattern.Scheme {
c.base[i].tree.Insert(pattern.Value, pattern.Port)
return
}
}
if c.next < len(c.base) {
c.base[c.next].scheme = pattern.Scheme
c.base[c.next].tree.Insert(pattern.Value, pattern.Port)
c.next++
return
}
(*c)[i].tree.Insert(pattern.Value, pattern.Port)
// search slice
for i := range c.spill {
if c.spill[i].scheme == pattern.Scheme {
c.spill[i].tree.Insert(pattern.Value, pattern.Port)
return
}
}
var tree radix.Tree
tree.Insert(pattern.Value, pattern.Port)
root := Root{scheme: pattern.Scheme, tree: tree}
c.spill = append(c.spill, root)
}

// Contains reports whether c contains origin o.
func (c Corpus) Contains(o *Origin) bool {
i := slices.IndexFunc(c, func(r Root) bool { return r.scheme == o.Scheme })
if i < 0 {
return false
for i := range c.next {
if c.base[i].scheme == o.Scheme {
return c.base[i].tree.Contains(o.Value, o.Port)
}
}
return c[i].tree.Contains(o.Value, o.Port)
for i := range c.spill {
if c.spill[i].scheme == o.Scheme {
return c.spill[i].tree.Contains(o.Value, o.Port)
}
}
return false
}

// Elems returns a slice containing textual representations of c's elements.
func (c Corpus) Elems() []string {
var res []string
for _, root := range c {
for _, root := range c.base {
elems := root.tree.Elems()
for i := range elems {
elems[i] = root.scheme + "://" + elems[i]
}
res = append(res, elems...)
}
for _, root := range c.spill {
elems := root.tree.Elems()
for i := range elems {
elems[i] = root.scheme + "://" + elems[i]
Expand Down
8 changes: 4 additions & 4 deletions middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ func (icfg *internalConfig) handleNonCORS(resHdrs http.Header, isOPTIONS bool) {
if icfg.privateNetworkAccessNoCors {
return
}
if icfg.corpus != nil {
if !icfg.corpus.IsEmpty() {
// See https://fetch.spec.whatwg.org/#cors-protocol-and-http-caches.
// Note that we deliberately list "Origin" in the Vary header of responses
// to actual requests even in cases where a single origin is allowed,
Expand Down Expand Up @@ -293,7 +293,7 @@ func (icfg *internalConfig) processOriginForPreflight(
if !ok {
return false
}
if !icfg.credentialed && icfg.corpus == nil {
if !icfg.credentialed && icfg.corpus.IsEmpty() {
buf[headers.ACAO] = headers.WildcardSgl
return true
}
Expand Down Expand Up @@ -347,11 +347,11 @@ func (icfg *internalConfig) handleCORSActual(
case isOPTIONS:
// see the implementation comment in handleCORSPreflight
resHdrs.Add(headers.Vary, headers.ValueVaryOptions)
case icfg.corpus != nil:
case !icfg.corpus.IsEmpty():
// See https://fetch.spec.whatwg.org/#cors-protocol-and-http-caches.
resHdrs.Add(headers.Vary, headers.Origin)
}
if !icfg.credentialed && icfg.corpus == nil {
if !icfg.credentialed && icfg.corpus.IsEmpty() {
// See the last paragraph in
// https://fetch.spec.whatwg.org/#cors-protocol-and-http-caches.
// Note that we deliberately list "Origin" in the Vary header of responses
Expand Down

0 comments on commit f6f9023

Please sign in to comment.