1
0
mirror of https://github.com/golang/go synced 2024-11-25 11:57:58 -07:00

httputil: move ReverseProxy out of http

http diet plan, continued.

R=golang-dev, adg
CC=golang-dev
https://golang.org/cl/5305090
This commit is contained in:
Brad Fitzpatrick 2011-11-03 15:54:08 -07:00
parent 46308d7d11
commit 54049767ae
5 changed files with 22 additions and 22 deletions

View File

@ -212,7 +212,6 @@ NOTEST+=\
net/dict\ net/dict\
net/http/pprof\ net/http/pprof\
net/http/httptest\ net/http/httptest\
net/http/httputil\
runtime/cgo\ runtime/cgo\
syscall\ syscall\
testing\ testing\

View File

@ -16,7 +16,6 @@ GOFILES=\
lex.go\ lex.go\
request.go\ request.go\
response.go\ response.go\
reverseproxy.go\
server.go\ server.go\
sniff.go\ sniff.go\
status.go\ status.go\

View File

@ -7,5 +7,6 @@ include ../../../../Make.inc
TARG=net/http/httputil TARG=net/http/httputil
GOFILES=\ GOFILES=\
persist.go\ persist.go\
reverseproxy.go\
include ../../../../Make.pkg include ../../../../Make.pkg

View File

@ -4,9 +4,10 @@
// HTTP reverse proxy handler // HTTP reverse proxy handler
package http package httputil
import ( import (
"http"
"io" "io"
"log" "log"
"net" "net"
@ -24,11 +25,11 @@ type ReverseProxy struct {
// the request into a new request to be sent // the request into a new request to be sent
// using Transport. Its response is then copied // using Transport. Its response is then copied
// back to the original client unmodified. // back to the original client unmodified.
Director func(*Request) Director func(*http.Request)
// The Transport used to perform proxy requests. // The transport used to perform proxy requests.
// If nil, DefaultTransport is used. // If nil, http.DefaultTransport is used.
Transport RoundTripper Transport http.RoundTripper
// FlushInterval specifies the flush interval, in // FlushInterval specifies the flush interval, in
// nanoseconds, to flush to the client while // nanoseconds, to flush to the client while
@ -54,7 +55,7 @@ func singleJoiningSlash(a, b string) string {
// target's path is "/base" and the incoming request was for "/dir", // target's path is "/base" and the incoming request was for "/dir",
// the target request will be for /base/dir. // the target request will be for /base/dir.
func NewSingleHostReverseProxy(target *url.URL) *ReverseProxy { func NewSingleHostReverseProxy(target *url.URL) *ReverseProxy {
director := func(req *Request) { director := func(req *http.Request) {
req.URL.Scheme = target.Scheme req.URL.Scheme = target.Scheme
req.URL.Host = target.Host req.URL.Host = target.Host
req.URL.Path = singleJoiningSlash(target.Path, req.URL.Path) req.URL.Path = singleJoiningSlash(target.Path, req.URL.Path)
@ -68,7 +69,7 @@ func NewSingleHostReverseProxy(target *url.URL) *ReverseProxy {
return &ReverseProxy{Director: director} return &ReverseProxy{Director: director}
} }
func copyHeader(dst, src Header) { func copyHeader(dst, src http.Header) {
for k, vv := range src { for k, vv := range src {
for _, v := range vv { for _, v := range vv {
dst.Add(k, v) dst.Add(k, v)
@ -76,13 +77,13 @@ func copyHeader(dst, src Header) {
} }
} }
func (p *ReverseProxy) ServeHTTP(rw ResponseWriter, req *Request) { func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
transport := p.Transport transport := p.Transport
if transport == nil { if transport == nil {
transport = DefaultTransport transport = http.DefaultTransport
} }
outreq := new(Request) outreq := new(http.Request)
*outreq = *req // includes shallow copies of maps, but okay *outreq = *req // includes shallow copies of maps, but okay
p.Director(outreq) p.Director(outreq)
@ -96,7 +97,7 @@ func (p *ReverseProxy) ServeHTTP(rw ResponseWriter, req *Request) {
// to us. This is modifying the same underlying map from req // to us. This is modifying the same underlying map from req
// (shallow copied above) so we only copy it if necessary. // (shallow copied above) so we only copy it if necessary.
if outreq.Header.Get("Connection") != "" { if outreq.Header.Get("Connection") != "" {
outreq.Header = make(Header) outreq.Header = make(http.Header)
copyHeader(outreq.Header, req.Header) copyHeader(outreq.Header, req.Header)
outreq.Header.Del("Connection") outreq.Header.Del("Connection")
} }
@ -108,7 +109,7 @@ func (p *ReverseProxy) ServeHTTP(rw ResponseWriter, req *Request) {
res, err := transport.RoundTrip(outreq) res, err := transport.RoundTrip(outreq)
if err != nil { if err != nil {
log.Printf("http: proxy error: %v", err) log.Printf("http: proxy error: %v", err)
rw.WriteHeader(StatusInternalServerError) rw.WriteHeader(http.StatusInternalServerError)
return return
} }
@ -129,7 +130,7 @@ func (p *ReverseProxy) ServeHTTP(rw ResponseWriter, req *Request) {
type writeFlusher interface { type writeFlusher interface {
io.Writer io.Writer
Flusher http.Flusher
} }
type maxLatencyWriter struct { type maxLatencyWriter struct {

View File

@ -4,10 +4,10 @@
// Reverse proxy tests. // Reverse proxy tests.
package http_test package httputil
import ( import (
. "http" "http"
"http/httptest" "http/httptest"
"io/ioutil" "io/ioutil"
"testing" "testing"
@ -17,7 +17,7 @@ import (
func TestReverseProxy(t *testing.T) { func TestReverseProxy(t *testing.T) {
const backendResponse = "I am the backend" const backendResponse = "I am the backend"
const backendStatus = 404 const backendStatus = 404
backend := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if len(r.TransferEncoding) > 0 { if len(r.TransferEncoding) > 0 {
t.Errorf("backend got unexpected TransferEncoding: %v", r.TransferEncoding) t.Errorf("backend got unexpected TransferEncoding: %v", r.TransferEncoding)
} }
@ -31,7 +31,7 @@ func TestReverseProxy(t *testing.T) {
t.Errorf("backend got Host header %q, want %q", g, e) t.Errorf("backend got Host header %q, want %q", g, e)
} }
w.Header().Set("X-Foo", "bar") w.Header().Set("X-Foo", "bar")
SetCookie(w, &Cookie{Name: "flavor", Value: "chocolateChip"}) http.SetCookie(w, &http.Cookie{Name: "flavor", Value: "chocolateChip"})
w.WriteHeader(backendStatus) w.WriteHeader(backendStatus)
w.Write([]byte(backendResponse)) w.Write([]byte(backendResponse))
})) }))
@ -44,11 +44,11 @@ func TestReverseProxy(t *testing.T) {
frontend := httptest.NewServer(proxyHandler) frontend := httptest.NewServer(proxyHandler)
defer frontend.Close() defer frontend.Close()
getReq, _ := NewRequest("GET", frontend.URL, nil) getReq, _ := http.NewRequest("GET", frontend.URL, nil)
getReq.Host = "some-name" getReq.Host = "some-name"
getReq.Header.Set("Connection", "close") getReq.Header.Set("Connection", "close")
getReq.Close = true getReq.Close = true
res, err := DefaultClient.Do(getReq) res, err := http.DefaultClient.Do(getReq)
if err != nil { if err != nil {
t.Fatalf("Get: %v", err) t.Fatalf("Get: %v", err)
} }