-
Notifications
You must be signed in to change notification settings - Fork 21
/
Copy pathproxy.go
77 lines (63 loc) · 1.92 KB
/
proxy.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
package proxy
import (
"context"
"errors"
"io"
"melody/config"
)
// Namespace to be used in extra config
const Namespace = "melody_proxy"
var (
// ErrNoBackends is the error returned when an endpoint has no backends defined
ErrNoBackends = errors.New("all endpoints must have at least one backend")
// ErrTooManyBackends is the error returned when an endpoint has too many backends defined
ErrTooManyBackends = errors.New("too many backends for this proxy")
// ErrTooManyProxies is the error returned when a middleware has too many proxies defined
ErrTooManyProxies = errors.New("too many proxies for this proxy middleware")
// ErrNotEnoughProxies is the error returned when an endpoint has not enough proxies defined
ErrNotEnoughProxies = errors.New("not enough proxies for this endpoint")
)
// Proxy 定义了代理
// 输入: context, request
// 出入: response, error
type Proxy func(context.Context, *Request) (*Response, error)
type BackendFactory func(backend *config.Backend) Proxy
// Metadata 包含了response header 和 response code
type Metadata struct {
Headers map[string][]string
StatusCode int
}
// Response 作为proxy的输出
type Response struct {
Data map[string]interface{}
IsComplete bool
Io io.Reader
Metadata Metadata
}
type Middleware func(...Proxy) Proxy
func EmptyMiddleware(next ...Proxy) Proxy {
if len(next) > 1 {
panic(ErrTooManyProxies)
}
return next[0]
}
type readCloserWrapper struct {
ctx context.Context
rc io.ReadCloser
}
func (r readCloserWrapper) Read(p []byte) (n int, err error) {
return r.rc.Read(p)
}
func (r readCloserWrapper) closeWhenCancel() {
<-r.ctx.Done()
r.rc.Close()
}
func NewReadCloserWrapper(ctx context.Context, reader io.ReadCloser) io.Reader {
wrapper := readCloserWrapper{
ctx: ctx,
rc: reader,
}
go wrapper.closeWhenCancel()
return wrapper
}
func NoopProxy(_ context.Context, _ *Request) (*Response, error) { return nil, nil }