1
//go:generate mockgen -source=api.go -destination=mocks/mock_api.go -package=mocks
2
package shared
3

            
4
type HeadersStatus int32
5

            
6
const (
7
	// '2' is preserved for ContinueAndDontEndStream and is not exposed here.
8

            
9
	// HeadersStatusContinue indicates that the headers can continue to be processed by
10
	// next plugin in the chain and nothing will be stopped.
11
	HeadersStatusContinue HeadersStatus = 0
12
	// HeadersStatusStop indicates that the headers processing should stop at this plugin.
13
	// And when the body or trailers are received, the onRequestBody or onRequestTrailers
14
	// of this plugin will be called. And the filter chain will continue or still hang
15
	// based on the returned status of onRequestBody or onRequestTrailers.
16
	// Of course the continueRequestStream or continueResponseStream can be called to continue
17
	// the processing manually.
18
	HeadersStatusStop HeadersStatus = 1
19
	// HeadersStatusStopAndBuffer indicates that the headers processing should stop at this plugin.
20
	// And even if the body or trailers are received, the onRequestBody or onRequestTrailers
21
	// of this plugin will NOT be called and the body will be buffered. The only way to continue
22
	// the processing is to call continueRequestStream or continueResponseStream manually.
23
	// This is useful when you want to wait a certain condition to be met before continuing
24
	// the processing (For example, waiting for the result of an asynchronous operation).
25
	HeadersStatusStopAllAndBuffer HeadersStatus = 3
26
	// Similar to HeadersStatusStopAllAndBuffer. But when there are too big body data buffered,
27
	// the HeadersStatusStopAllAndBuffer will result in 413 (Payload Too Large) response to the
28
	// client. But with this status, the watermarking will be used to disable reading from client
29
	// or server.
30
	HeadersStatusStopAllAndWatermark HeadersStatus = 4
31
	HeadersStatusDefault             HeadersStatus = HeadersStatusContinue
32
)
33

            
34
type BodyStatus int32
35

            
36
const (
37
	// BodyStatusContinue indicates that the body can continue to be processed by next plugin
38
	// in the chain. And if the onRequestHeaders or onResponseHeaders of this plugin returned
39
	// HeadersStatusStop before, the headers processing will continue.
40
	BodyStatusContinue BodyStatus = 0
41
	// BodyStatusStopAndBuffer indicates that the body processing should stop at this plugin.
42
	// And the body will be buffered.
43
	BodyStatusStopAndBuffer BodyStatus = 1
44
	// BodyStatusStopAndWatermark indicates that the body processing should stop at this plugin.
45
	// And watermarking will be used to disable reading from client or server if there are too
46
	// big body data buffered.
47
	BodyStatusStopAndWatermark BodyStatus = 2
48
	// BodyStatusStopNoBuffer indicates that the body processing should stop at this plugin.
49
	// No body data will be buffered.
50
	BodyStatusStopNoBuffer BodyStatus = 3
51
	BodyStatusDefault      BodyStatus = BodyStatusContinue
52
)
53

            
54
type TrailersStatus int32
55

            
56
const (
57
	// TrailersStatusContinue indicates that the trailers can continue to be processed by next plugin
58
	// in the chain. And if the onRequestHeaders, onResponseHeaders, onRequestBody or onResponseBody
59
	// of this plugin have returned stop status before, the processing will continue after this.
60
	TrailersStatusContinue TrailersStatus = 0
61
	// TrailersStatusStop indicates that the trailers processing should stop at this plugin. The
62
	// only way to continue the processing is to call continueRequestStream or continueResponseStream
63
	// manually.
64
	TrailersStatusStop    TrailersStatus = 1
65
	TrailersStatusDefault TrailersStatus = TrailersStatusContinue
66
)
67

            
68
// HttpFilter is the interface to implement your own plugin logic. This is a simplified version and could
69
// not implement flexible stream control. But it should be enough for most of the use cases.
70
type HttpFilter interface {
71
	// OnRequestHeaders will be called when the request headers are received.
72
	// @Param headers the request headers.
73
	// @Param endOfStream whether this is the end of the stream.
74
	// @Return HeadersStatus the status to control the plugin chain processing.
75
	OnRequestHeaders(headers HeaderMap, endOfStream bool) HeadersStatus
76

            
77
	// OnRequestBody will be called when the request body are received. This may be called multiple times.
78
	// @Param body the request body.
79
	// @Param endOfStream whether this is the end of the stream.
80
	// @Return BodyStatus the status to control the plugin chain processing.
81
	OnRequestBody(body BodyBuffer, endOfStream bool) BodyStatus
82

            
83
	// OnRequestTrailers will be called when the request trailers are received.
84
	// @Param trailers the request trailers.
85
	// @Return TrailersStatus the status to control the plugin chain processing.
86
	OnRequestTrailers(trailers HeaderMap) TrailersStatus
87

            
88
	// OnResponseHeaders will be called when the response headers are received.
89
	// @Param headers the response headers.
90
	// @Param endOfStream whether this is the end of the stream.
91
	// @Return HeadersStatus the status to control the plugin chain processing.
92
	OnResponseHeaders(headers HeaderMap, endOfStream bool) HeadersStatus
93

            
94
	// OnResponseBody will be called when the response body is received. This may be called multiple
95
	// times.
96
	// @Param body the response body.
97
	// @Param endOfStream whether this is the end of the stream.
98
	// @Return BodyStatus the status to control the plugin chain processing.
99
	OnResponseBody(body BodyBuffer, endOfStream bool) BodyStatus
100

            
101
	// OnResponseTrailers will be called when the response trailers are received.
102
	// @Param trailers the response trailers.
103
	// @Return TrailersStatus the status to control the plugin chain processing.
104
	OnResponseTrailers(trailers HeaderMap) TrailersStatus
105

            
106
	// OnStreamComplete is called when the stream processing is complete and before access logs
107
	// are flushed.
108
	// This is a good place to do any final processing or cleanup before the request is fully
109
	// completed.
110
	OnStreamComplete()
111

            
112
	// OnDestroy is called when the HTTP filter instance is being destroyed. This is called
113
	// after OnStreamComplete and access logs are flushed. This is a good place to release
114
	// any per-stream resources.
115
	OnDestroy()
116
}
117

            
118
type EmptyHttpFilter struct {
119
}
120

            
121
func (p *EmptyHttpFilter) OnRequestHeaders(headers HeaderMap, endOfStream bool) HeadersStatus {
122
	return HeadersStatusDefault
123
}
124

            
125
func (p *EmptyHttpFilter) OnRequestBody(body BodyBuffer, endOfStream bool) BodyStatus {
126
	return BodyStatusDefault
127
}
128

            
129
func (p *EmptyHttpFilter) OnRequestTrailers(trailers HeaderMap) TrailersStatus {
130
	return TrailersStatusDefault
131
}
132

            
133
func (p *EmptyHttpFilter) OnResponseHeaders(headers HeaderMap, endOfStream bool) HeadersStatus {
134
	return HeadersStatusDefault
135
}
136

            
137
func (p *EmptyHttpFilter) OnResponseBody(body BodyBuffer, endOfStream bool) BodyStatus {
138
	return BodyStatusDefault
139
}
140

            
141
func (p *EmptyHttpFilter) OnResponseTrailers(trailers HeaderMap) TrailersStatus {
142
	return TrailersStatusDefault
143
}
144

            
145
func (p *EmptyHttpFilter) OnStreamComplete() {
146
}
147

            
148
func (p *EmptyHttpFilter) OnDestroy() {
149
}
150

            
151
// HttpFilterFactory is the factory interface for creating stream plugins.
152
// This is used to create instances of the stream plugin at runtime when a new request is received.
153
// The implementation of this interface should be thread-safe and hold the parsed configuration.
154
type HttpFilterFactory interface {
155
	// Create creates a HttpFilter instance.
156
	Create(handle HttpFilterHandle) HttpFilter
157

            
158
	// OnDestroy is called when the factory is being destroyed. This is a good place to clean up any
159
	// resources. This usually happens when the configuration is updated and all existing streams
160
	// using this factory are closed.
161
	OnDestroy()
162
}
163

            
164
type EmptyHttpFilterFactory struct {
165
}
166

            
167
func (f *EmptyHttpFilterFactory) Create(handle HttpFilterHandle) HttpFilter {
168
	return &EmptyHttpFilter{}
169
}
170

            
171
func (f *EmptyHttpFilterFactory) OnDestroy() {
172
}
173

            
174
// HttpFilterConfigFactory is the factory interface for creating stream plugin configurations.
175
// This is used to create
176
// PluginConfig based on the unparsed configuration. The HttpFilterConfigFactory should parse the unparsedConfig
177
// and create a PluginFactory instance.
178
// The implementation of this interface should be thread-safe and be stateless in most cases.
179
type HttpFilterConfigFactory interface {
180
	// Create creates a HttpFilterFactory based on the unparsed configuration.
181
	Create(handle HttpFilterConfigHandle, unparsedConfig []byte) (HttpFilterFactory, error)
182

            
183
	// CreatePerRoute creates a per-route configuration based on the unparsed configuration.
184
	CreatePerRoute(unparsedConfig []byte) (any, error)
185
}
186

            
187
type EmptyHttpFilterConfigFactory struct {
188
}
189

            
190
func (f *EmptyHttpFilterConfigFactory) Create(handle HttpFilterConfigHandle,
191
	unparsedConfig []byte) (HttpFilterFactory, error) {
192
	return &EmptyHttpFilterFactory{}, nil
193
}
194

            
195
func (f *EmptyHttpFilterConfigFactory) CreatePerRoute(unparsedConfig []byte) (any, error) {
196
	return nil, nil
197
}