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 PADS Logic 原理图
  • ¥15 PADS Logic 图标
  • ¥15 电脑和power bi环境都是英文如何将日期层次结构转换成英文
  • ¥20 气象站点数据求取中~
  • ¥15 如何获取APP内弹出的网址链接
  • ¥15 wifi 图标不见了 不知道怎么办 上不了网 变成小地球了
  • ¥50 STM32单片机传感器读取错误
  • ¥15 (关键词-阻抗匹配,HFSS,RFID标签天线)
  • ¥15 机器人轨迹规划相关问题
  • ¥15 word样式右侧翻页键消失