forked from sohlich/nats-proxy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
request.go
114 lines (96 loc) · 2.03 KB
/
request.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
106
107
108
109
110
111
112
113
114
package natsproxy
import (
"bytes"
"errors"
"io"
"net/http"
"sync"
"github.com/gogo/protobuf/proto"
"github.com/nats-io/nuid"
)
func (r *Request) GetHeader() Variables {
if r != nil {
return Variables(r.Header)
}
return nil
}
func (r *Request) GetForm() Variables {
if r != nil {
return Variables(r.Form)
}
return nil
}
// UnmarshallFrom unmarshal the request from
// bytes, that usually come from proxy.
func (r *Request) UnmarshallFrom(requestData []byte) error {
if err := proto.Unmarshal(requestData, r); err != nil {
return err
}
return nil
}
func (r *Request) IsWebSocket() bool {
return r.WebSocketID != ""
}
func (r *Request) GetWebSocketID() string {
return r.WebSocketID
}
func (r *Request) FromHTTP(req *http.Request) error {
if req == nil {
return errors.New("natsproxy: Request cannot be nil")
}
isWebSock := IsWebSocketRequest(req)
wsID := ""
if isWebSock {
wsID = nuid.Next()
}
buf := bytes.NewBuffer(r.Body)
buf.Reset()
if req.Body != nil {
if _, err := io.Copy(buf, req.Body); err != nil {
return err
}
if err := req.Body.Close(); err != nil {
return err
}
}
headerMap := copyMap(map[string][]string(req.Header))
r.URL = req.URL.String()
r.Method = req.Method
r.Header = headerMap
r.RemoteAddr = req.RemoteAddr
r.WebSocketID = wsID
r.Body = buf.Bytes()
return nil
}
func NewRequest() *Request {
return &Request{
Header: make(map[string]*Values),
Form: make(map[string]*Values),
Body: make([]byte, 4096),
}
}
func (req *Request) reset() {
req.Header = make(map[string]*Values)
req.Form = make(map[string]*Values)
req.Method = req.Method[0:0]
req.Body = req.Body[0:0]
req.RemoteAddr = req.RemoteAddr[0:0]
req.URL = req.URL[0:0]
}
type RequestPool struct {
sync.Pool
}
func (r *RequestPool) GetRequest() *Request {
request, _ := r.Get().(*Request)
return request
}
func (r *RequestPool) PutRequest(req *Request) {
req.reset()
r.Put(req)
}
func NewRequestPool() RequestPool {
return RequestPool{
sync.Pool{
New: func() interface{} { return NewRequest() },
}}
}