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/")
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 求螺旋焊缝的图像处理
  • ¥15 blast算法(相关搜索:数据库)
  • ¥15 请问有人会紧聚焦相关的matlab知识嘛?
  • ¥15 网络通信安全解决方案
  • ¥50 yalmip+Gurobi
  • ¥20 win10修改放大文本以及缩放与布局后蓝屏无法正常进入桌面
  • ¥15 itunes恢复数据最后一步发生错误
  • ¥15 关于#windows#的问题:2024年5月15日的win11更新后资源管理器没有地址栏了顶部的地址栏和文件搜索都消失了
  • ¥100 H5网页如何调用微信扫一扫功能?
  • ¥15 讲解电路图,付费求解