httputil: remove Transport constructors aware of environment
Each of the servers has slightly different needs for configuring their
outbound HTTP transport. A little copying is better than a little
dependency.
Notably, the configuration logic in gddo-server is now consistent with
the rest of the configuration-gathering logic.
Change-Id: Ibe7d287a102e20e6e13d97e8a6483d9febab6442
Reviewed-on: https://go-review.googlesource.com/69291
Reviewed-by: Tuo Shan <shantuo@google.com>
diff --git a/gddo-server/client.go b/gddo-server/client.go
index af557a6..2761ac2 100644
--- a/gddo-server/client.go
+++ b/gddo-server/client.go
@@ -23,7 +23,7 @@
func newHTTPClient(v *viper.Viper) *http.Client {
requestTimeout := v.GetDuration(ConfigRequestTimeout)
- t := &http.Transport{
+ var t http.RoundTripper = &http.Transport{
Proxy: http.ProxyFromEnvironment,
Dial: (&net.Dialer{
Timeout: v.GetDuration(ConfigDialTimeout),
@@ -32,18 +32,22 @@
ResponseHeaderTimeout: requestTimeout / 2,
TLSHandshakeTimeout: requestTimeout / 2,
}
-
- var rt http.RoundTripper
if addr := v.GetString(ConfigMemcacheAddr); addr != "" {
ct := httpcache.NewTransport(memcache.New(addr))
ct.Transport = t
- rt = httputil.NewAuthTransport(ct)
- } else {
- rt = httputil.NewAuthTransport(t)
+ t = ct
}
+ t = &httputil.AuthTransport{
+ Base: t,
+
+ UserAgent: v.GetString(ConfigUserAgent),
+ GithubToken: v.GetString(ConfigGithubToken),
+ GithubClientID: v.GetString(ConfigGithubClientID),
+ GithubClientSecret: v.GetString(ConfigGithubClientSecret),
+ }
+ t = trace.Transport{Base: t}
return &http.Client{
- // Wrap the cached transport with GitHub authentication.
- Transport: trace.Transport{Base: rt},
+ Transport: t,
Timeout: requestTimeout,
}
}
diff --git a/gddo-server/config.go b/gddo-server/config.go
index a1d15a8..07845a2 100644
--- a/gddo-server/config.go
+++ b/gddo-server/config.go
@@ -18,6 +18,11 @@
const (
gaeProjectEnvVar = "GCLOUD_PROJECT"
gaAccountEnvVar = "GA_ACCOUNT"
+
+ userAgentEnvVar = "USER_AGENT"
+ githubTokenEnvVar = "GITHUB_TOKEN"
+ githubClientIDEnvVar = "GITHUB_CLIENT_ID"
+ githubClientSecretEnvVar = "GITHUB_CLIENT_SECRET"
)
const (
@@ -54,6 +59,12 @@
// Trace Config
ConfigTraceSamplerFraction = "trace_fraction"
ConfigTraceSamplerMaxQPS = "trace_max_qps"
+
+ // Outbound HTTP Config
+ ConfigUserAgent = "user_agent"
+ ConfigGithubToken = "github_token"
+ ConfigGithubClientID = "github_client_id"
+ ConfigGithubClientSecret = "github_client_secret"
)
func loadConfig(ctx context.Context, args []string) (*viper.Viper, error) {
@@ -67,6 +78,10 @@
if metadata.OnGCE() {
gceProjectAttributeDefault(ctx, v, ConfigGAAccount, "ga-account")
gceProjectAttributeDefault(ctx, v, ConfigGCELogName, "gce-log-name")
+ gceProjectAttributeDefault(ctx, v, ConfigUserAgent, "user-agent")
+ gceProjectAttributeDefault(ctx, v, ConfigGithubToken, "github-token")
+ gceProjectAttributeDefault(ctx, v, ConfigGithubClientID, "github-client-id")
+ gceProjectAttributeDefault(ctx, v, ConfigGithubClientSecret, "github-client-secret")
if id, err := metadata.ProjectID(); err != nil {
log.Warn(ctx, "failed to retrieve project ID", "error", err)
} else {
@@ -89,6 +104,10 @@
v.AutomaticEnv()
v.BindEnv(ConfigProject, gaeProjectEnvVar)
v.BindEnv(ConfigGAAccount, gaAccountEnvVar)
+ v.BindEnv(ConfigUserAgent, userAgentEnvVar)
+ v.BindEnv(ConfigGithubToken, githubTokenEnvVar)
+ v.BindEnv(ConfigGithubClientID, githubClientIDEnvVar)
+ v.BindEnv(ConfigGithubClientSecret, githubClientSecretEnvVar)
// Read from config.
if err := readViperConfig(ctx, v); err != nil {
diff --git a/gosrc/print.go b/gosrc/print.go
index 260592a..55e930f 100644
--- a/gosrc/print.go
+++ b/gosrc/print.go
@@ -16,6 +16,7 @@
"fmt"
"log"
"net/http"
+ "os"
"strings"
"github.com/golang/gddo/gosrc"
@@ -45,7 +46,13 @@
gosrc.SetLocalDevMode(*local)
}
c := &http.Client{
- Transport: httputil.NewAuthTransport(&http.Transport{}),
+ Transport: &httputil.AuthTransport{
+ Base: http.DefaultTransport,
+ UserAgent: os.Getenv("USER_AGENT"),
+ GithubToken: os.Getenv("GITHUB_TOKEN"),
+ GithubClientID: os.Getenv("GITHUB_CLIENT_ID"),
+ GithubClientSecret: os.Getenv("GITHUB_CLIENT_SECRET"),
+ },
}
dir, err := gosrc.Get(c, path, *etag)
if e, ok := err.(gosrc.NotFoundError); ok && e.Redirect != "" {
diff --git a/httputil/transport.go b/httputil/transport.go
index b41fe59..fdad3b4 100644
--- a/httputil/transport.go
+++ b/httputil/transport.go
@@ -10,12 +10,8 @@
package httputil
import (
- "log"
"net/http"
"net/url"
- "os"
-
- "cloud.google.com/go/compute/metadata"
)
// AuthTransport is an implementation of http.RoundTripper that authenticates
@@ -23,45 +19,11 @@
//
// When both a token and client credentials are set, the latter is preferred.
type AuthTransport struct {
- UserAgent string
- Token string
- ClientID string
- ClientSecret string
- Base http.RoundTripper
-}
-
-// NewAuthTransport gives new AuthTransport created with GitHub credentials
-// read from GCE metadata when the metadata server is accessible (we're on GCE)
-// or read from environment varialbes otherwise.
-func NewAuthTransport(base http.RoundTripper) *AuthTransport {
- if metadata.OnGCE() {
- return NewAuthTransportFromMetadata(base)
- }
- return NewAuthTransportFromEnvironment(base)
-}
-
-// NewAuthTransportFromEnvironment gives new AuthTransport created with GitHub
-// credentials read from environment variables.
-func NewAuthTransportFromEnvironment(base http.RoundTripper) *AuthTransport {
- return &AuthTransport{
- UserAgent: os.Getenv("USER_AGENT"),
- Token: os.Getenv("GITHUB_TOKEN"),
- ClientID: os.Getenv("GITHUB_CLIENT_ID"),
- ClientSecret: os.Getenv("GITHUB_CLIENT_SECRET"),
- Base: base,
- }
-}
-
-// NewAuthTransportFromMetadata gives new AuthTransport created with GitHub
-// credentials read from GCE metadata.
-func NewAuthTransportFromMetadata(base http.RoundTripper) *AuthTransport {
- return &AuthTransport{
- UserAgent: gceAttr("user-agent"),
- Token: gceAttr("github-token"),
- ClientID: gceAttr("github-client-id"),
- ClientSecret: gceAttr("github-client-secret"),
- Base: base,
- }
+ UserAgent string
+ GithubToken string
+ GithubClientID string
+ GithubClientSecret string
+ Base http.RoundTripper
}
// RoundTrip implements the http.RoundTripper interface.
@@ -73,20 +35,20 @@
}
if req.URL.Host == "api.github.com" && req.URL.Scheme == "https" {
switch {
- case t.ClientID != "" && t.ClientSecret != "":
+ case t.GithubClientID != "" && t.GithubClientSecret != "":
if reqCopy == nil {
reqCopy = copyRequest(req)
}
if reqCopy.URL.RawQuery == "" {
- reqCopy.URL.RawQuery = "client_id=" + t.ClientID + "&client_secret=" + t.ClientSecret
+ reqCopy.URL.RawQuery = "client_id=" + t.GithubClientID + "&client_secret=" + t.GithubClientSecret
} else {
- reqCopy.URL.RawQuery += "&client_id=" + t.ClientID + "&client_secret=" + t.ClientSecret
+ reqCopy.URL.RawQuery += "&client_id=" + t.GithubClientID + "&client_secret=" + t.GithubClientSecret
}
- case t.Token != "":
+ case t.GithubToken != "":
if reqCopy == nil {
reqCopy = copyRequest(req)
}
- reqCopy.Header.Set("Authorization", "token "+t.Token)
+ reqCopy.Header.Set("Authorization", "token "+t.GithubToken)
}
}
if reqCopy != nil {
@@ -112,15 +74,6 @@
return http.DefaultTransport
}
-func gceAttr(name string) string {
- s, err := metadata.ProjectAttributeValue(name)
- if err != nil {
- log.Printf("error querying metadata for %q: %s", name, err)
- return ""
- }
- return s
-}
-
func copyRequest(req *http.Request) *http.Request {
req2 := new(http.Request)
*req2 = *req
diff --git a/httputil/transport_test.go b/httputil/transport_test.go
index 2980d97..4b36118 100644
--- a/httputil/transport_test.go
+++ b/httputil/transport_test.go
@@ -87,9 +87,9 @@
query = r.URL.Query()
authHeader = r.Header.Get("Authorization")
}),
- Token: test.token,
- ClientID: test.clientID,
- ClientSecret: test.clientSecret,
+ GithubToken: test.token,
+ GithubClientID: test.clientID,
+ GithubClientSecret: test.clientSecret,
},
}
_, err := client.Get(test.url)
diff --git a/lintapp/main.go b/lintapp/main.go
index f4b686b..e77de4a 100644
--- a/lintapp/main.go
+++ b/lintapp/main.go
@@ -49,7 +49,6 @@
"timeago": timeagoFn,
"contactEmail": contactEmailFn,
}
- github = httputil.NewAuthTransportFromEnvironment(nil)
)
func parseTemplate(fnames ...string) *template.Template {
@@ -114,11 +113,11 @@
c := appengine.NewContext(r)
return &http.Client{
Transport: &httputil.AuthTransport{
- Token: github.Token,
- ClientID: github.ClientID,
- ClientSecret: github.ClientSecret,
- Base: &urlfetch.Transport{Context: c},
- UserAgent: fmt.Sprintf("%s (+http://%s/-/bot)", appengine.AppID(c), r.Host),
+ GithubToken: os.Getenv("GITHUB_TOKEN"),
+ GithubClientID: os.Getenv("GITHUB_CLIENT_ID"),
+ GithubClientSecret: os.Getenv("GITHUB_CLIENT_SECRET"),
+ Base: &urlfetch.Transport{Context: c},
+ UserAgent: fmt.Sprintf("%s (+http://%s/-/bot)", appengine.AppID(c), r.Host),
},
}
}
diff --git a/talksapp/main.go b/talksapp/main.go
index 5b15445..1cf85ac 100644
--- a/talksapp/main.go
+++ b/talksapp/main.go
@@ -41,6 +41,10 @@
// used for mocking in tests
getPresentation = gosrc.GetPresentation
playCompileURL = "https://play.golang.org/compile"
+
+ githubToken = os.Getenv("GITHUB_TOKEN")
+ githubClientID = os.Getenv("GITHUB_CLIENT_ID")
+ githubClientSecret = os.Getenv("GITHUB_CLIENT_SECRET")
)
func init() {
@@ -52,12 +56,13 @@
contactEmail = s
}
- if appengine.IsDevAppServer() {
- return
- }
- github := httputil.NewAuthTransportFromEnvironment(nil)
- if github.Token == "" || github.ClientID == "" || github.ClientSecret == "" {
- panic("missing GitHub metadata, follow the instructions on README.md")
+ if !appengine.IsDevAppServer() {
+ if githubToken == "" && githubClientID == "" && githubClientSecret == "" {
+ panic("missing GitHub metadata, follow the instructions on README.md")
+ }
+ if githubToken != "" && (githubClientID != "" || githubClientSecret != "") {
+ panic("GitHub token and client secret given, follow the instructions on README.md")
+ }
}
}
@@ -126,15 +131,14 @@
func httpClient(r *http.Request) *http.Client {
ctx, _ := context.WithTimeout(appengine.NewContext(r), 10*time.Second)
- github := httputil.NewAuthTransportFromEnvironment(nil)
return &http.Client{
Transport: &httputil.AuthTransport{
- Token: github.Token,
- ClientID: github.ClientID,
- ClientSecret: github.ClientSecret,
- Base: &urlfetch.Transport{Context: ctx},
- UserAgent: fmt.Sprintf("%s (+http://%s/-/bot)", appengine.AppID(ctx), r.Host),
+ GithubToken: githubToken,
+ GithubClientID: githubClientID,
+ GithubClientSecret: githubClientSecret,
+ Base: &urlfetch.Transport{Context: ctx},
+ UserAgent: fmt.Sprintf("%s (+http://%s/-/bot)", appengine.AppID(ctx), r.Host),
},
}
}