duanjing7651 2017-11-15 08:38 采纳率: 0%
浏览 57
已采纳

在每个请求上使用不同的代理

As far as it is my understanding, the only way I can set a proxy for a request is to assign it to a client and then use that for a request. However, I also understand I should reuse the clients for my requests. Is there any way to individually assign proxies for each request whilst using the same client? Or any way to efficiently do a collection of requests with a different proxy for each request?

  • 写回答

1条回答 默认 最新

  • du42561 2017-11-15 09:29
    关注

    Creating of http.Client is not so expensive - its just a struct allocation that can be done for each request.

    You should create http.Client and transport objects yourself and set proxy directly there.

    proxyUrl, err := url.Parse("http://127.0.0.1:123")
    if err != nil {
        panic(err)
    }
    myClient := &http.Client{Transport: &http.Transport{Proxy: http.ProxyURL(proxyUrl)}}
    myClient.Get("http://www.google.com/")
    

    Tere is the other posibility to use always the same client with different proxies:

    http.ProxyURL call from the first example is function:

    // ProxyURL returns a proxy function (for use in a Transport)
    // that always returns the same URL.
    func ProxyURL(fixedURL *url.URL) func(*Request) (*url.URL, error) {
        return func(*Request) (*url.URL, error) {
            return fixedURL, nil
        }
    }
    

    You can extend it and chose proxy based on the information from request or implement some other logic.

    UPD: here is implementation how to use ProxyUrl with only one Client. But overehead of changing context is comparable with overhead on creating a client. I would use the first scenario.

    // We must write our own Get (or some other) request and add somewere the info that this is a proxy request. You can do it via context of request.

    func GetWithProxy(c *http.Client,proxyUrl *url.URL, url string) (resp *http.Response, err error) {
        req, err := http.NewRequest("GET", url, nil)
        if err != nil {
            return nil, err
        }
    
        if proxyUrl != nil {
            req = req.WithContext(context.WithValue(context.Background(),"proxy",proxyUrl))
        }
    
        return c.Do(req)
    }
    

    // Organize client that can use this information:

    proxyUrl, err := url.Parse("http://127.0.0.1:123")
    if err != nil {
        panic(err)
    }
    
    myClient := &http.Client{Transport: &http.Transport{Proxy: func(req *http.Request) (*url.URL, error) {
        currentProxy,_ := req.Context().Value("proxy").(*url.URL)
        return currentProxy, nil
    }}}
    

    Use it:

    GetWithProxy(myClient,nil,"http://www.google.com/")
    GetWithProxy(myClient,proxyUrl,"http://www.google.com/")
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 R语言单细胞测序 对seurat对象进行标准化时出现问题
  • ¥15 Anaconda navigator updateor一直更新
  • ¥15 请问如何在matlab里使用raven工具?
  • ¥100 关于ios手游充值到一定金额,再点充值提示公众号的问题。
  • ¥15 求一个stm32串口控制程序
  • ¥20 Windows 驱动开发版本疑问相关
  • ¥15 MAC 未能打开磁盘映像
  • ¥15 fastcap使用,二维导体输入问题
  • ¥15 hosts修改后不能访问
  • ¥15 关于化学反应速率C++编译问题/FLUENT