-
Notifications
You must be signed in to change notification settings - Fork 2.7k
/
lineparser.go
105 lines (88 loc) · 2.37 KB
/
lineparser.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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// SPDX-License-Identifier: Apache-2.0
// Copyright 2018 Authors of Cilium
package testparsers
import (
"bytes"
. "github.com/cilium/cilium/proxylib/proxylib"
log "github.com/sirupsen/logrus"
)
//
// Line parser used for testing
//
type LineParserFactory struct{}
var lineParserFactory *LineParserFactory
func init() {
log.Debug("init(): Registering lineParserFactory")
RegisterParserFactory("test.lineparser", lineParserFactory)
}
type LineParser struct {
connection *Connection
inserted bool
}
func (p *LineParserFactory) Create(connection *Connection) interface{} {
log.Debugf("LineParserFactory: Create: %v", connection)
return &LineParser{connection: connection}
}
func getLine(data [][]byte) ([]byte, bool) {
var line bytes.Buffer
for i, s := range data {
index := bytes.IndexByte(s, '\n')
if index < 0 {
line.Write(s)
} else {
log.Debugf("getLine: unit: %d length: %d index: %d", i, len(s), index)
line.Write(s[:index+1])
return line.Bytes(), true
}
}
return line.Bytes(), false
}
//
// Parses individual lines that must start with one of:
// "PASS" the line is passed
// "DROP" the line is dropped
// "INJECT" the line is injected in reverse direction
// "INSERT" the line is injected in current direction
//
func (p *LineParser) OnData(reply, endStream bool, data [][]byte) (OpType, int) {
line, ok := getLine(data)
line_len := len(line)
if p.inserted {
p.inserted = false
return DROP, line_len
}
if !reply {
log.Debugf("LineParser: Request: %s", line)
} else {
log.Debugf("LineParser: Response: %s", line)
}
if !ok {
if line_len > 0 {
// Partial line received, but no newline, ask for more
return MORE, 1
} else {
// Nothing received, don't know if more will be coming; do nothing
return NOP, 0
}
}
if bytes.HasPrefix(line, []byte("PASS")) {
return PASS, line_len
}
if bytes.HasPrefix(line, []byte("DROP")) {
return DROP, line_len
}
if bytes.HasPrefix(line, []byte("INJECT")) {
// Inject line in the reverse direction
p.connection.Inject(!reply, []byte(line))
// Drop the INJECT line in the current direction
return DROP, line_len
}
if bytes.HasPrefix(line, []byte("INSERT")) {
// Inject the line in the current direction
p.connection.Inject(reply, []byte(line))
// Drop the INJECT line in the current direction
p.inserted = true
return INJECT, line_len
}
return ERROR, int(ERROR_INVALID_FRAME_TYPE)
}