如何通过代理本地测试 GAE Golang 的 urlfetch?

huangapple go评论90阅读模式
英文:

How to local test gae golang urlfetch through proxy?

问题

我的urlfetch客户端在部署到appspot时工作正常。但是在本地通过代理进行测试(使用dev_appserver.py)时出现问题。我找不到任何设置urlfetch.Transport代理的方法。

你如何在本地测试urlfetch在代理后面的情况?

英文:

My urlfetch client works fine when deployed to appspot. But local testing (dev_appserver.py) through proxy has issue. I can't find any way to set proxy for urlfetch.Transport.

How do you test urlfetch behind proxy locally?

答案1

得分: 5

http.DefaultTransport和http.DefaultClient在App Engine中不可用。请参阅https://developers.google.com/appengine/docs/go/urlfetch/overview

在测试PayPal OAuth时,在GAE dev_appserver.py上收到此错误消息(在编译后的生产环境中工作)

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和http.DefaultClient在App Engine中不可用。" +
        "请参阅https://developers.google.com/appengine/docs/go/urlfetch/overview")
}

func init() {
    // http.DefaultTransport在生产环境中不起作用,因此显式地破坏它
    // 这样它在开发和生产环境中都会以相同的方式失败
    // (并提供有用的错误消息)
    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")
英文:

> http.DefaultTransport and http.DefaultClient are not available in App Engine. See https://developers.google.com/appengine/docs/go/urlfetch/overview

Got this error message when testing PayPal OAuth on GAE dev_appserver.py (works in production when compiled)

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)

As you can see, Go App Engine breaks http.DefaultTransport
(GAE_SDK/goroot/src/pkg/appengine_internal/internal.go, line 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{}
}

This solved it to me with 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")

答案2

得分: 0

这只是一个猜测,但你是否尝试过设置代理变量

> 在Unix或Windows环境中,在启动Python解释器之前,将http_proxy或ftp_proxy环境变量设置为标识代理服务器的URL。例如('%'是命令提示符):
>
> % http_proxy="http://www.someproxy.com:3128"
>
> % export http_proxy

英文:

This is just a guess, but did you try setting the proxy variables

> In a Unix or Windows environment, set the http_proxy, or ftp_proxy
> environment variables to a URL that identifies the proxy server before
> starting the Python interpreter. For example (the '%' is the command
> prompt):
>
> % http_proxy="http://www.someproxy.com:3128"
>
> % export http_proxy

答案3

得分: 0

如果您正在使用默认代理,则传输是这样实现的:

var DefaultTransport RoundTripper = &Transport{Proxy: ProxyFromEnvironment}

在启动Go时设置环境变量应该解决问题。

另请参阅以下问题:
https://stackoverflow.com/questions/10383299/how-do-i-configure-go-to-use-a-proxy

英文:

if you are using the default proxy then the transport is implemented as

var DefaultTransport RoundTripper = &Transport{Proxy: ProxyFromEnvironment} 

setting the environment variable when launching go should solve the problem.

See also this other question:
https://stackoverflow.com/questions/10383299/how-do-i-configure-go-to-use-a-proxy

答案4

得分: 0

urlfetch包本身不会遵守代理设置,即使在开发环境中也是如此,因为它实际上并不执行URL获取操作:它向(可能是开发)应用服务器发送请求,并要求其执行获取操作。我手头没有dev_appserver.py的源代码,但它应该遵守标准的代理变量设置:

export http_proxy='http://user:pass@1.2.3.4:3210/'

如果在启动dev_appserver.py之前执行此操作,它可能会正常工作。

如果上述方法不起作用,您应该提交问题,然后使用以下解决方法:

func client(ctx *appengine.Context) *http.Client {
    if appengine.IsDevAppServer() {
        return http.DefaultClient
    }
    return urlfetch.Client(ctx)
}

这将在生产应用服务器上使用urlfetch API,但在其他情况下使用标准的net/http客户端,后者会遵守http_proxy环境变量。

英文:

The urlfetch package itself does not honor proxy settings, even in development, because it's not actually doing the URL fetch itself: it sends a request to the (possibly development) app server and asks it to do the fetch. I don't have the source of dev_appserver.py handy, but it should honor the standard proxy variables:

export http_proxy='http://user:pass@1.2.3.4:3210/'

If you do that before you start dev_appserver.py, it will probably just work.

If the above does not work, you should file an issue and then use the following workaround:

func client(ctx *appengine.Context) *http.Client {
    if appengine.IsDevAppServer() {
        return http.DefaultClient
    }
    return urlfetch.Client(ctx)
}

This will use the urlfetch API on the production appserver but use the standard net/http client otherwise, which does honor the http_proxy environment variable.

huangapple
  • 本文由 发表于 2012年11月9日 05:38:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/13298264.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定