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.

Artigos relacionados