forked from bfenetworks/bfe
-
Notifications
You must be signed in to change notification settings - Fork 0
/
request.go
184 lines (143 loc) · 4.75 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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
// Copyright (c) 2019 The BFE Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Internal data structure for http request
package bfe_basic
import (
"net"
"net/url"
)
import (
"github.com/bfenetworks/bfe/bfe_balance/backend"
"github.com/bfenetworks/bfe/bfe_http"
)
type BackendInfo struct {
ClusterName string // name of cluster
SubclusterName string // name of sub-cluster
BackendAddr string // backend ip address
BackendPort uint32 // backend's port
BackendName string // backend name
}
type RedirectInfo struct {
Url string // URL
Code int // HTTP status code
Header bfe_http.Header // Extra header
}
type RequestRoute struct {
Error error // error in request-route
HostTag string // tags
Product string // name of product
ClusterName string // clustername req should route to
}
type RequestTags struct {
Error error // error in request-tag
TagTable map[string][]string // type-tags pairs
}
type RequestTransport struct {
Backend *backend.BfeBackend // destination backend for request
Transport bfe_http.RoundTripper // transport to backend
}
// Request is a wrapper of HTTP request
type Request struct {
Connection net.Conn
Session *Session
RemoteAddr *net.TCPAddr // address of remote peer
ClientAddr *net.TCPAddr // address of real client. Maybe nil if request is from
// upstream proxy but without a valid Clientip header
HttpRequest *bfe_http.Request // incoming request
OutRequest *bfe_http.Request // forwarded request
HttpResponse *bfe_http.Response // corresponding response
CookieMap bfe_http.CookieMap // cookie map
Query url.Values // save url query
LogId string // log id for each request
ReqBody []byte // req body, size is limited
ReqBodyPeeked bool // whether req body has been peeked
Route RequestRoute // for get backend cluster based on host/path/query/header/...
Tags RequestTags // request tag info
Trans RequestTransport // request transport
BfeStatusCode int // request directly return by bfe
ErrCode error // error code for handling request
ErrMsg string // additional error msg
Stat *RequestStat // time, data length, etc.
RetryTime int // times of retry
Backend BackendInfo // backend info
Redirect RedirectInfo // redirect info
SvrDataConf ServerDataConfInterface // interface for ServerDataConf
// User context associated with this request
Context map[interface{}]interface{}
}
// NewRequest creates and initializes a new request.
func NewRequest(request *bfe_http.Request, conn net.Conn, stat *RequestStat,
session *Session, svrDataConf ServerDataConfInterface) *Request {
fReq := new(Request)
fReq.ErrCode = nil
fReq.Connection = conn
fReq.HttpRequest = request
fReq.Stat = stat
fReq.Session = session
fReq.Context = make(map[interface{}]interface{})
fReq.Tags.TagTable = make(map[string][]string)
if session != nil {
fReq.RemoteAddr = session.RemoteAddr
}
fReq.SvrDataConf = svrDataConf
return fReq
}
func (req *Request) CachedQuery() url.Values {
if req.Query == nil {
req.Query = req.HttpRequest.URL.Query()
}
return req.Query
}
func (req *Request) CachedCookie() bfe_http.CookieMap {
// parse all cookies if needed
if req.CookieMap == nil {
cookies := req.HttpRequest.Cookies()
req.CookieMap = bfe_http.CookieMapGet(cookies)
}
return req.CookieMap
}
func (req *Request) Cookie(name string) (*bfe_http.Cookie, bool) {
if req.CookieMap == nil {
req.CachedCookie() // lazily parse cookie
}
return req.CookieMap.Get(name)
}
func (req *Request) SetRequestTransport(backend *backend.BfeBackend,
transport bfe_http.RoundTripper) {
req.Trans.Backend = backend
req.Trans.Transport = transport
}
func (req *Request) Protocol() string {
if req.Session.IsSecure {
return req.Session.Proto
}
return req.HttpRequest.Proto
}
func (req *Request) AddTags(name string, ntags []string) {
if len(ntags) == 0 {
return
}
tags := req.Tags.TagTable[name]
tags = append(tags, ntags...)
req.Tags.TagTable[name] = tags
}
func (req *Request) GetTags(name string) []string {
return req.Tags.TagTable[name]
}
func (req *Request) SetContext(key, val interface{}) {
req.Context[key] = val
}
func (req *Request) GetContext(key interface{}) interface{} {
return req.Context[key]
}