mirror of
https://github.com/phishingclub/phishingclub.git
synced 2026-07-12 06:56:37 +02:00
07c8adaf76
Signed-off-by: Ronni Skansing <rskansing@gmail.com>
101 lines
1.9 KiB
Go
101 lines
1.9 KiB
Go
package httpcommon
|
|
|
|
import (
|
|
"maps"
|
|
"sort"
|
|
"strings"
|
|
"sync"
|
|
)
|
|
|
|
type Header map[string][]string
|
|
|
|
var lock = sync.RWMutex{}
|
|
|
|
const (
|
|
HeaderOrderKey = "Header-Order:"
|
|
PHeaderOrderKey = "PHeader-Order:"
|
|
)
|
|
|
|
func (h Header) Clone() Header { return maps.Clone(h) }
|
|
|
|
type headerKeyValues struct {
|
|
Key string
|
|
Values []string
|
|
}
|
|
|
|
type headerSorter struct {
|
|
kvs []headerKeyValues
|
|
order map[string]int
|
|
}
|
|
|
|
var headerSorterPool = sync.Pool{
|
|
New: func() any { return new(headerSorter) },
|
|
}
|
|
|
|
func (s *headerSorter) Len() int { return len(s.kvs) }
|
|
func (s *headerSorter) Swap(i, j int) { s.kvs[i], s.kvs[j] = s.kvs[j], s.kvs[i] }
|
|
func (s *headerSorter) Less(i, j int) bool {
|
|
// If the order isn't defined, sort lexicographically.
|
|
if s.order == nil {
|
|
return s.kvs[i].Key < s.kvs[j].Key
|
|
}
|
|
|
|
idxi, iok := s.order[strings.ToLower(s.kvs[i].Key)]
|
|
idxj, jok := s.order[strings.ToLower(s.kvs[j].Key)]
|
|
if !iok && !jok {
|
|
return s.kvs[i].Key < s.kvs[j].Key
|
|
} else if !iok && jok {
|
|
return false
|
|
} else if iok && !jok {
|
|
return true
|
|
}
|
|
|
|
return idxi < idxj
|
|
}
|
|
|
|
func (h Header) SortedKeyValues(exclude map[string]bool) (kvs []headerKeyValues, hs *headerSorter) {
|
|
hs = headerSorterPool.Get().(*headerSorter)
|
|
if cap(hs.kvs) < len(h) {
|
|
hs.kvs = make([]headerKeyValues, 0, len(h))
|
|
}
|
|
|
|
kvs = hs.kvs[:0]
|
|
for k, vv := range h {
|
|
lock.RLock()
|
|
if !exclude[k] {
|
|
kvs = append(kvs, headerKeyValues{k, vv})
|
|
}
|
|
lock.RUnlock()
|
|
}
|
|
|
|
hs.kvs = kvs
|
|
sort.Sort(hs)
|
|
|
|
return kvs, hs
|
|
}
|
|
|
|
func (h Header) SortedKeyValuesBy(
|
|
order map[string]int,
|
|
exclude map[string]bool,
|
|
) (kvs []headerKeyValues, hs *headerSorter) {
|
|
hs = headerSorterPool.Get().(*headerSorter)
|
|
if cap(hs.kvs) < len(h) {
|
|
hs.kvs = make([]headerKeyValues, 0, len(h))
|
|
}
|
|
|
|
kvs = hs.kvs[:0]
|
|
for k, vv := range h {
|
|
lock.RLock()
|
|
if !exclude[k] {
|
|
kvs = append(kvs, headerKeyValues{k, vv})
|
|
}
|
|
lock.RUnlock()
|
|
}
|
|
|
|
hs.kvs = kvs
|
|
hs.order = order
|
|
sort.Sort(hs)
|
|
|
|
return kvs, hs
|
|
}
|