提交 28add654 编写于 作者: M Mislav Marohnić

Reimplement HUB_TEST_HOST support using a custom http.Transport

In testing, we want to redirect all requests to a local test server
pretending to be GitHub API, but we want them to preserve their original
"Host" header. A good place to do that transparently is the `RoundTrip`
method that handles every request for this http.Client instance.
上级 26255a05
......@@ -463,23 +463,10 @@ func (client *Client) newOctokitClient(auth octokit.AuthMethod) *octokit.Client
host = client.Host.Host
}
host = normalizeHost(host)
apiHostURL := client.absolute(host)
apiHost := host
hubTestHost := os.Getenv("HUB_TEST_HOST")
if hubTestHost != "" {
apiHost = hubTestHost
}
hostURL := client.absolute(host)
apiHostURL := client.absolute(apiHost)
httpClient := newHttpClient(os.Getenv("HUB_VERBOSE") != "")
httpClient := newHttpClient(os.Getenv("HUB_TEST_HOST"), os.Getenv("HUB_VERBOSE") != "")
c := octokit.NewClientWith(apiHostURL.String(), UserAgent, auth, httpClient)
if hubTestHost != "" {
// if it's in test, make sure host name is in the header
c.Header.Set("Host", host)
c.Header.Set("X-Original-Scheme", hostURL.Scheme)
}
return c
}
......
......@@ -3,7 +3,6 @@ package github
import (
"fmt"
"net/http"
"os"
"testing"
"github.com/bmizerany/assert"
......@@ -22,13 +21,6 @@ func TestClient_newOctokitClient(t *testing.T) {
c = NewClient("http://github.corporate.com")
cc = c.newOctokitClient(nil)
assert.Equal(t, "http://github.corporate.com", cc.Endpoint.String())
os.Setenv("HUB_TEST_HOST", "http://127.0.0.1")
defer os.Setenv("HUB_TEST_HOST", "")
c = NewClient("github.corporate.com")
cc = c.newOctokitClient(nil)
assert.Equal(t, "http://127.0.0.1", cc.Endpoint.String())
assert.Equal(t, "github.corporate.com", cc.Header.Get("Host"))
}
func TestClient_FormatError(t *testing.T) {
......
......@@ -15,8 +15,9 @@ import (
)
type verboseTransport struct {
Transport *http.Transport
Verbose bool
Transport *http.Transport
Verbose bool
OverrideURL *url.URL
}
func (t *verboseTransport) RoundTrip(req *http.Request) (resp *http.Response, err error) {
......@@ -24,6 +25,13 @@ func (t *verboseTransport) RoundTrip(req *http.Request) (resp *http.Response, er
t.dumpRequest(req)
}
if t.OverrideURL != nil {
req = cloneRequest(req)
req.Header.Set("X-Original-Scheme", req.URL.Scheme)
req.URL.Scheme = t.OverrideURL.Scheme
req.URL.Host = t.OverrideURL.Host
}
resp, err = t.Transport.RoundTrip(req)
if err == nil && t.Verbose {
......@@ -33,8 +41,19 @@ func (t *verboseTransport) RoundTrip(req *http.Request) (resp *http.Response, er
return
}
func cloneRequest(req *http.Request) *http.Request {
dup := new(http.Request)
*dup = *req
dup.URL, _ = url.Parse(req.URL.String())
dup.Header = make(http.Header)
for k, s := range req.Header {
dup.Header[k] = s
}
return dup
}
func (t *verboseTransport) dumpRequest(req *http.Request) {
info := fmt.Sprintf("> %s %s://%s%s", req.Method, req.Header.Get("X-Original-Scheme"), req.Host, req.URL.Path)
info := fmt.Sprintf("> %s %s://%s%s", req.Method, req.URL.Scheme, req.Host, req.URL.Path)
t.verbosePrintln(info)
t.dumpHeaders(req.Header, ">")
body := t.dumpBody(req.Body)
......@@ -100,10 +119,15 @@ func (t *verboseTransport) verbosePrintln(msg string) {
fmt.Fprintln(os.Stderr, msg)
}
func newHttpClient(verbose bool) *http.Client {
func newHttpClient(testHost string, verbose bool) *http.Client {
var testURL *url.URL
if testHost != "" {
testURL, _ = url.Parse(testHost)
}
tr := &verboseTransport{
Transport: &http.Transport{Proxy: proxyFromEnvironment},
Verbose: verbose,
Transport: &http.Transport{Proxy: proxyFromEnvironment},
Verbose: verbose,
OverrideURL: testURL,
}
return &http.Client{Transport: tr}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册