-
Notifications
You must be signed in to change notification settings - Fork 1
/
fallback_receive.go
84 lines (73 loc) · 2.48 KB
/
fallback_receive.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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package proxyprotocol
import (
"bufio"
"errors"
)
// StubHeaderParser always return nil Header
type StubHeaderParser struct{}
// NewStubHeaderParser construct StubHeaderParser
func NewStubHeaderParser() StubHeaderParser {
return StubHeaderParser{}
}
// Parse always return nil, nil
func (parser StubHeaderParser) Parse(*bufio.Reader) (*Header, error) {
return nil, nil
}
// FallbackHeaderParserBuilder build FallbackHeaderParser
type FallbackHeaderParserBuilder []HeaderParserBuilder
// NewFallbackHeaderParserBuilder construct FallbackHeaderParserBuilder
func NewFallbackHeaderParserBuilder(
headerParserBuilders ...HeaderParserBuilder,
) FallbackHeaderParserBuilder {
return FallbackHeaderParserBuilder(headerParserBuilders)
}
// Build FallbackHeaderParser from headerParserBuilders
func (headerParserBuilders FallbackHeaderParserBuilder) Build(logger Logger) HeaderParser {
headerParsers := make([]HeaderParser, 0, len(headerParserBuilders))
for _, headerParserBuilder := range headerParserBuilders {
headerParser := headerParserBuilder.Build(logger)
headerParsers = append(headerParsers, headerParser)
}
return FallbackHeaderParser{
Logger: logger,
HeaderParsers: headerParsers,
}
}
// ErrInvalidHeader returned by FallbackHeaderParser when all headerParsers return
// ErrInvalidSignature
var ErrInvalidHeader = errors.New("invalid header")
// FallbackHeaderParser iterate over HeaderParser until parser not return nil error.
type FallbackHeaderParser struct {
Logger Logger
HeaderParsers []HeaderParser
}
// NewFallbackHeaderParser create new instance of FallbackHeaderParser
func NewFallbackHeaderParser(logger Logger, headerParsers ...HeaderParser) FallbackHeaderParser {
return FallbackHeaderParser{
Logger: logger,
HeaderParsers: headerParsers,
}
}
// Parse iterate over headerParsers call Parse().
//
// If any parser return not nil or not ErrInvalidSignature error, then return its error.
//
// If any parser return nil error, then return header.
//
// If all parsers return error ErrInvalidSignature, then return ErrInvalidHeader.
func (parser FallbackHeaderParser) Parse(buf *bufio.Reader) (*Header, error) {
for _, headerParser := range parser.HeaderParsers {
header, err := headerParser.Parse(buf)
switch err {
case nil:
parser.Logger.Printf("Use header remote addr")
return header, nil
case ErrInvalidSignature:
continue
default:
parser.Logger.Printf("Parse header error: %s", err)
return nil, err
}
}
return nil, ErrInvalidHeader
}