Configure um proxy próprio para um cliente HTTP em Go
Clone o transporte padrão do Go, defina ProxyURL para o IP escolhido e evite mudar o comportamento de outros clientes.
O transporte do cliente HTTP do Go escolhe o proxy. Clone o transporte padrão antes de alterá-lo para que outros usuários do cliente padrão mantenham suas rotas atuais.
package main
import (
"fmt"
"io"
"log"
"net/http"
"net/url"
"time"
)
func main() {
proxyURL, err := url.Parse("http://203.0.113.10:8080")
if err != nil {
log.Fatal(err)
}
transport := http.DefaultTransport.(*http.Transport).Clone()
transport.Proxy = http.ProxyURL(proxyURL)
defer transport.CloseIdleConnections()
client := &http.Client{
Transport: transport,
Timeout: 15 * time.Second,
}
response, err := client.Get("https://example.com/")
if err != nil {
log.Fatal(err)
}
defer response.Body.Close()
fmt.Println(response.StatusCode)
if _, err := io.Copy(io.Discard, response.Body); err != nil {
log.Fatal(err)
}
}
O endereço é um exemplo de documentação. Substitua-o pelo IP e pela porta de um proxy HTTP real, como um candidato da lista de proxies HTTP. O exemplo usa apenas a biblioteca padrão do Go; essa requisição via proxy HTTP não precisa de um pacote SOCKS nem de uma variável de ambiente para todo o processo.
Por que não alterar DefaultTransport diretamente?
O transporte padrão é compartilhado. Alterá-lo pode mudar o comportamento de código que nunca pediu para usar seu proxy, e fazer isso enquanto requisições o utilizam cria problemas de concorrência evitáveis. Um transporte dedicado torna a rota parte da configuração desse cliente.
http.ProxyURL retorna um seletor que sempre escolhe a URL fornecida. Isso difere do seletor de ambiente padrão, que considera variáveis de proxy e regras de exclusão. Se você quer testar uma entrada específica da lista HTTP, o seletor explícito elimina essa fonte de ambiguidade.
Feche a resposta e reutilize o cliente
O exemplo lê todo o corpo da resposta e o fecha. A leitura completa ajuda o transporte a reutilizar uma conexão quando possível. Em um programa que faz várias requisições pelo mesmo proxy, mantenha o cliente e o transporte em vez de criar um par novo a cada requisição.
O tempo limite do cliente cobre mais que a abertura do socket; ele também limita o ciclo da requisição, incluindo a leitura do corpo da resposta. Erros de leitura ainda precisam ser tratados depois que Get retorna. Um status como 403 não é um erro do transporte do Go; por isso, verifique StatusCode separadamente de err.