【发布时间】:2012-11-08 21:38:24
【问题描述】:
我的 urlfetch 客户端在部署到 apppot 时工作正常。但是通过代理进行本地测试(dev_appserver.py)有问题。我找不到为 urlfetch.Transport 设置代理的任何方法。
如何在本地代理后面的 urlfetch 测试?
【问题讨论】:
标签: google-app-engine proxy localhost go urlfetch
我的 urlfetch 客户端在部署到 apppot 时工作正常。但是通过代理进行本地测试(dev_appserver.py)有问题。我找不到为 urlfetch.Transport 设置代理的任何方法。
如何在本地代理后面的 urlfetch 测试?
【问题讨论】:
标签: google-app-engine proxy localhost go urlfetch
http.DefaultTransport 和 http.DefaultClient 在 App Engine 中不可用。见https://developers.google.com/appengine/docs/go/urlfetch/overview
在 GAE dev_appserver.py 上测试 PayPal OAuth 时收到此错误消息(编译后可用于生产)
const url string = "https://api.sandbox.paypal.com/v1/oauth2/token"
const username string = "EOJ2S-Z6OoN_le_KS1d75wsZ6y0SFdVsY9183IvxFyZp"
const password string = "EClusMEUk8e9ihI7ZdVLF5cZ6y0SFdVsY9183IvxFyZp"
client := &http.Client{}
req, _ := http.NewRequest("POST", url, strings.NewReader("grant_type=client_credentials"))
req.SetBasicAuth(username, password)
req.Header.Set("Accept", "application/json")
req.Header.Set("Accept-Language", "en_US")
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
resp, err := client.Do(req)
如您所见,Go App Engine 中断了 http.DefaultTransport (GAE_SDK/goroot/src/pkg/appengine_internal/internal.go,第 142 行,GAE 1.7.5)
type failingTransport struct{}
func (failingTransport) RoundTrip(*http.Request) (*http.Response, error) {
return nil, errors.New("http.DefaultTransport and http.DefaultClient are not available in App Engine. " +
"See https://developers.google.com/appengine/docs/go/urlfetch/overview")
}
func init() {
// http.DefaultTransport doesn't work in production so break it
// explicitly so it fails the same way in both dev and prod
// (and with a useful error message)
http.DefaultTransport = failingTransport{}
}
Go App Engine 1.7.5 解决了我的问题
transport := http.Transport{}
client := &http.Client{
Transport: &transport,
}
req, _ := http.NewRequest("POST", url, strings.NewReader("grant_type=client_credentials"))
req.SetBasicAuth(username, password)
req.Header.Set("Accept", "application/json")
req.Header.Set("Accept-Language", "en_US")
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
【讨论】:
这只是一个猜测,但你试过setting the proxy variables
在 Unix 或 Windows 环境中,设置 http_proxy 或 ftp_proxy 环境变量到之前标识代理服务器的 URL 启动 Python 解释器。例如('%' 是命令 提示):
% http_proxy="http://www.someproxy.com:3128"
% 导出 http_proxy
【讨论】:
如果您使用默认代理,则传输实现为
var DefaultTransport RoundTripper = &Transport{Proxy: ProxyFromEnvironment}
在启动 go 时设置环境变量应该可以解决问题。
另请参阅其他问题: How do I configure Go to use a proxy?
【讨论】:
urlfetch 包本身不支持代理设置,即使在开发中也是如此,因为它实际上并没有自己进行 URL 提取:它向(可能是开发的)应用服务器发送请求并要求它进行提取。我手边没有dev_appserver.py 的来源,但它应该尊重标准代理变量:
export http_proxy='http://user:pass@1.2.3.4:3210/'
如果您在开始 dev_appserver.py 之前这样做,它可能会起作用。
如果上述方法不起作用,您应该file an issue,然后使用以下解决方法:
func client(ctx *appengine.Context) *http.Client {
if appengine.IsDevAppServer() {
return http.DefaultClient
}
return urlfetch.Client(ctx)
}
这将使用生产应用服务器上的 urlfetch API,但使用标准 net/http 客户端,否则 does honor http_proxy 环境变量。
【讨论】: