-
Notifications
You must be signed in to change notification settings - Fork 21
/
urlFilter.go
60 lines (50 loc) · 1.69 KB
/
urlFilter.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
// SPDX-FileCopyrightText: 2017 Comcast Cable Communications Management, LLC
// SPDX-License-Identifier: Apache-2.0
package main
import (
"errors"
"fmt"
"strings"
)
var (
ErrorURLSchemeNotAllowed = errors.New("url scheme not allowed")
)
// URLFilter represents a strategy for validating and possibly mutating URLs from devices.
type URLFilter interface {
// Filter accepts a URL and performs validation on it. This method can return
// a different URL, if the internal configuration requires it. For example, if the
// supplied URL has no scheme, this method may prepend one.
Filter(string) (string, error)
}
// urlFilter is the internal URLFilter implementation
type urlFilter struct {
defaultScheme string
allowedSchemes map[string]bool
}
// NewURLFilter returns a URLFilter using the supplied configuration. If defaultScheme is empty,
// DefaultAssumeScheme is used. If allowedSchemes is empty, the DefaultAllowedScheme is
// used as the sole allowed scheme. An error is returned if the defaultScheme is not present
// in the allowedSchemes.
func NewURLFilter(o *Outbounder) (URLFilter, error) {
uf := &urlFilter{
defaultScheme: o.defaultScheme(),
allowedSchemes: o.allowedSchemes(),
}
if !uf.allowedSchemes[uf.defaultScheme] {
return nil, fmt.Errorf(
"Allowed schemes %v do not include the default scheme %s", uf.allowedSchemes, uf.defaultScheme,
)
}
return uf, nil
}
func (uf *urlFilter) Filter(v string) (string, error) {
position := strings.Index(v, "://")
if position < 0 {
return (uf.defaultScheme + "://" + v), nil
}
scheme := v[:position]
if !uf.allowedSchemes[v[:position]] {
return "", fmt.Errorf("%w: %s", ErrorURLSchemeNotAllowed, scheme)
}
return v, nil
}