分享页面

隧道代理 Go 语言接入指南

发布时间:2023-04-13 10:55

概述

本文档将指引你进行隧道代理的接入,在此文档中使用到的术语将会在下方进行列出。

术语 解释
隧道 自动更换代理 IP 的代理服务
固定时长 服务器将在固定时长后自动切换IP,例如1分钟
通道 使用多个通道同时发起请求,每个通道的IP不同

隧道代理有多种使用方式,具体行为取决于套餐及模式。

  • 普通模式

每次请求都自动切换IP

  • 普通模式打标记

普通模式下,希望多个HTTP请求保证代理IP相同,可以给多个请求的代理协议打上相同的标记,并标记这个代理IP的存活时间(不主动设置存活时间则默认为10秒)

  • 固定时长多通道模式

服务器定时切换IP,可同时使用多个通道发起请求,即可以同时使用多个IP

前置知识

在 go 语言中,通常使用 http.Client 进行 http/s 代理的设定与请求的发送,使用 http.NewRequest 进行请求的构建。

Proxy Url Scheme

由协议、用户名、密码、域名、端口几部分组成

例如 http 协议的代理 url

  1. http://[user:password@]hostname:port

使用 GO 接入

以下内容假设读者具备基本的 Go 语言编程能力和对网络协议具有一定的了解。

生成 url

普通模式

  1. link := fmt.Sprintf("http://%s:%s@%s", authKey, password, proxyServer)
  2. proxyURL, _ := url.Parse(link)

普通模式打标记

  1. link := fmt.Sprintf("http://%s:%s:%s:%d@%s", authKey, password, "channel-1", 20, proxyServer)
  2. proxyURL, _ := url.Parse(link)

固定时长多通道模式

  1. link := fmt.Sprintf("http://%s:%s:%s@%s", authKey, password, "channel-1", proxyServer)
  2. proxyURL, _ := url.Parse(link)

构建 Client

后续将使用该 client 发起 request

  1. client := http.Client{
  2. Transport: &http.Transport{
  3. Proxy: http.ProxyURL(proxyURL),
  4. },
  5. }

构建 HTTP/s GET 请求

https://api.ipify.org 为例。

因为已确认参数合法,因此构建不会发生错误,无需处理错误。

  1. request, _ := http.NewRequest("GET", "https://test.ipw.cn", nil)
  2. // 如果上面目标站不可用,请使用ip.sb、ipinfo.io、ip-api.com、64.ipcheck.ing

执行已构建的 HTTP/s 请求

  1. response, err := client.Do(request)
  2. if err != nil {
  3. panic(err)
  4. }
  5. defer response.Body.Close()

读取响应实体

response.Body 是 io.Reader 类型,需要手动进行读取

  1. body, err := io.ReadAll(response.Body)
  2. if err != nil {
  3. panic(err)
  4. }
  5. fmt.Println(string(body))

示例代码

  1. package main
  2. import (
  3. "fmt"
  4. "io"
  5. "log"
  6. "net/http"
  7. "net/url"
  8. )
  9. const (
  10. authKey = ""
  11. password = ""
  12. server = ""
  13. channel = "channel-1"
  14. )
  15. func main() {
  16. var link string
  17. if channel == "" {
  18. link = fmt.Sprintf("http://%s:%s@%s", authKey, password, server)
  19. } else {
  20. link = fmt.Sprintf("http://%s:%s:%s@%s", authKey, password, channel, server)
  21. }
  22. proxyURL, _ := url.Parse(link)
  23. client := http.Client{
  24. Transport: &http.Transport{
  25. Proxy: http.ProxyURL(proxyURL),
  26. },
  27. }
  28. request, _ := http.NewRequest("GET", "https://test.ipw.cn", nil)
  29. // 如果上面目标站不可用,请使用ip.sb、ipinfo.io、ip-api.com、64.ipcheck.ing
  30. response, err := client.Do(request)
  31. if err != nil {
  32. panic(err)
  33. }
  34. defer response.Body.Close()
  35. body, err := io.ReadAll(response.Body)
  36. if err != nil {
  37. panic(err)
  38. }
  39. log.Println("response body", string(body))
  40. }