@@ -133,36 +133,6 @@ type ReverseProxy struct {
133
133
// At most one of Rewrite or Director may be set.
134
134
Rewrite func (* ProxyRequest )
135
135
136
- // Director is a function which modifies
137
- // the request into a new request to be sent
138
- // using Transport. Its response is then copied
139
- // back to the original client unmodified.
140
- // Director must not access the provided Request
141
- // after returning.
142
- //
143
- // By default, the X-Forwarded-For header is set to the
144
- // value of the client IP address. If an X-Forwarded-For
145
- // header already exists, the client IP is appended to the
146
- // existing values. As a special case, if the header
147
- // exists in the Request.Header map but has a nil value
148
- // (such as when set by the Director func), the X-Forwarded-For
149
- // header is not modified.
150
- //
151
- // To prevent IP spoofing, be sure to delete any pre-existing
152
- // X-Forwarded-For header coming from the client or
153
- // an untrusted proxy.
154
- //
155
- // Hop-by-hop headers are removed from the request after
156
- // Director returns, which can remove headers added by
157
- // Director. Use a Rewrite function instead to ensure
158
- // modifications to the request are preserved.
159
- //
160
- // Unparsable query parameters are removed from the outbound
161
- // request if Request.Form is set after Director returns.
162
- //
163
- // At most one of Rewrite or Director may be set.
164
- Director func (* http.Request )
165
-
166
136
// The transport used to perform proxy requests.
167
137
// If nil, http.DefaultTransport is used.
168
138
Transport http.RoundTripper
@@ -210,6 +180,88 @@ type ReverseProxy struct {
210
180
// If nil, the default is to log the provided error and return
211
181
// a 502 Status Bad Gateway response.
212
182
ErrorHandler func (http.ResponseWriter , * http.Request , error )
183
+
184
+ // Director is deprecated. Use Rewrite instead.
185
+ //
186
+ // This function is insecure:
187
+ //
188
+ // - Hop-by-hop headers are removed from the request after Director
189
+ // returns, which can remove headers added by Director.
190
+ // A client can designate headers as hop-by-hop by listing them
191
+ // in the Connection header, so this permits a malicious client
192
+ // to remove any headers that may be added by Director.
193
+ //
194
+ // - X-Forwarded-For, X-Forwarded-Host, and X-Forwarded-Proto
195
+ // headers in inbound requests are preserved by default,
196
+ // which can permit IP spoofing if the Director function is
197
+ // not careful to remove these headers.
198
+ //
199
+ // Rewrite addresses these issues.
200
+ //
201
+ // As an example of converting a Director function to Rewrite:
202
+ //
203
+ // // ReverseProxy with a Director function.
204
+ // proxy := &httputil.ReverseProxy{
205
+ // Director: func(req *http.Request) {
206
+ // req.URL.Scheme = "https"
207
+ // req.URL.Host = proxyHost
208
+ //
209
+ // // A malicious client can remove this header.
210
+ // req.Header.Set("Some-Header", "some-header-value")
211
+ //
212
+ // // X-Forwarded-* headers sent by the client are preserved,
213
+ // // since Director did not remove them.
214
+ // },
215
+ // }
216
+ //
217
+ // // ReverseProxy with a Rewrite function.
218
+ // proxy := &httputil.ReverseProxy{
219
+ // Rewrite: func(preq *httputil.ProxyRequest) {
220
+ // // See also ProxyRequest.SetURL.
221
+ // preq.Out.URL.Scheme = "https"
222
+ // preq.Out.URL.Host = proxyHost
223
+ //
224
+ // // This header cannot be affected by a malicious client.
225
+ // preq.Out.Header.Set("Some-Header", "some-header-value")
226
+ //
227
+ // // X-Forwarded- headers sent by the client have been
228
+ // // removed from preq.Out.
229
+ // // ProxyRequest.SetXForwarded optionally adds new ones.
230
+ // preq.SetXForwarded()
231
+ // },
232
+ // }
233
+ //
234
+ // Director is a function which modifies
235
+ // the request into a new request to be sent
236
+ // using Transport. Its response is then copied
237
+ // back to the original client unmodified.
238
+ // Director must not access the provided Request
239
+ // after returning.
240
+ //
241
+ // By default, the X-Forwarded-For header is set to the
242
+ // value of the client IP address. If an X-Forwarded-For
243
+ // header already exists, the client IP is appended to the
244
+ // existing values. As a special case, if the header
245
+ // exists in the Request.Header map but has a nil value
246
+ // (such as when set by the Director func), the X-Forwarded-For
247
+ // header is not modified.
248
+ //
249
+ // To prevent IP spoofing, be sure to delete any pre-existing
250
+ // X-Forwarded-For header coming from the client or
251
+ // an untrusted proxy.
252
+ //
253
+ // Hop-by-hop headers are removed from the request after
254
+ // Director returns, which can remove headers added by
255
+ // Director. Use a Rewrite function instead to ensure
256
+ // modifications to the request are preserved.
257
+ //
258
+ // Unparsable query parameters are removed from the outbound
259
+ // request if Request.Form is set after Director returns.
260
+ //
261
+ // At most one of Rewrite or Director may be set.
262
+ //
263
+ // Deprecated: Use Rewrite instead.
264
+ Director func (* http.Request )
213
265
}
214
266
215
267
// A BufferPool is an interface for getting and returning temporary
@@ -259,6 +311,10 @@ func joinURLPath(a, b *url.URL) (path, rawpath string) {
259
311
//
260
312
// NewSingleHostReverseProxy does not rewrite the Host header.
261
313
//
314
+ // For backwards compatibility reasons, NewSingleHostReverseProxy
315
+ // returns a ReverseProxy using the deprecated Director function.
316
+ // This proxy preserves X-Forwarded-* headers sent by the client.
317
+ //
262
318
// To customize the ReverseProxy behavior beyond what
263
319
// NewSingleHostReverseProxy provides, use ReverseProxy directly
264
320
// with a Rewrite function. The ProxyRequest SetURL method
0 commit comments