Documentation
¶
Overview ¶
Package proxy provides a simple proxy. The proxy can be protected with basic auth. It can also forward connections to a parent proxy, and authorize connections against that. Both local, and parent credentials can be set via environment variables. For local proxy credential, set `PROXY_CREDENTIAL`. For remote proxy credential, set `PROXY_PARENT_CREDENTIAL`.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( ErrFailedToStartProxy = customerror.NewFailedToError("start proxy", "", nil) ErrInvalidProxyHost = customerror.NewInvalidError("proxy host", "", nil) ErrInvalidProxyURL = customerror.NewInvalidError("proxy url", "", nil) )
Functions ¶
This section is empty.
Types ¶
type Proxy ¶
type Proxy struct {
// Credential is the basic authentication credential.
//
// See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#basic_authentication_scheme
Credential *credential.BasicAuth
// Host is the combination of the `Hostname`, and `Port`.
//
// See: https://developer.mozilla.org/en-US/docs/Web/API/URL/host
Host string `json:"hostname" validate:"required,gte=10,hostname_port"`
// ParentProxyURL is a valid URL to reach the parent proxy. Valid means:
// - Known scheme: http, https, socks, socks5, or quic
// - Some hostname: min 4 chars (x.io)
// - Port in a valid range: 80 - 65535.
ParentProxyURL string
// ParentProxyCredential is the basic authentication credential to authorize
// against the parent proxy.
//
// See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#basic_authentication_scheme
ParentProxyCredential *credential.BasicAuth
// contains filtered or unexported fields
}
Proxy connections. Proxy can be protected with basic auth. It can also forward connections to a parent proxy, and authorize connections against that.
func New ¶
func New( host, cred, parentProxyURL, parentProxyCredential string, loggingOptions *LoggingOptions, ) (*Proxy, error)
New is the Proxy factory. Errors can be introspected, and provide contextual information.
Example ¶
Demonstrates how to start a simple proxy. Flow: Client -> Proxy -> Target.
//////
// Target.
//////
// Mocked HTTP server.
testServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
res.WriteHeader(http.StatusOK)
if _, err := res.Write([]byte("body")); err != nil {
log.Fatalln("Failed to write body.", err)
}
}))
defer func() { testServer.Close() }()
// Give enough time to start, and be ready.
time.Sleep(1 * time.Second)
//////
// Proxy.
//////
proxyHost := "localhost:8080"
proxy, err := New(proxyHost, "", "", "", nil)
if err != nil {
//nolint:gocritic
log.Fatalln("Failed to create proxy.", err)
}
go proxy.Run()
// Give enough time to start, and be ready.
time.Sleep(1 * time.Second)
//////
// Client.
//////
proxyURL, err := url.Parse(fmt.Sprintf("http://%s", proxyHost))
if err != nil {
log.Fatalf("Invalid URL: %v", err)
}
// Client's proxy settings.
tr := &http.Transport{
Proxy: http.ProxyURL(proxyURL),
}
client := &http.Client{
Transport: tr,
}
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel()
request, err := http.NewRequestWithContext(ctx, http.MethodGet, testServer.URL, nil)
if err != nil {
log.Fatalf("Failed to create request: %v", err)
}
response, err := client.Do(request)
if err != nil {
log.Fatalf("Failed to execute request: %v", err)
}
defer response.Body.Close()
data, err := ioutil.ReadAll(response.Body)
if err != nil {
log.Fatalf("Failed to read body: %v", err)
}
if response.StatusCode != http.StatusOK {
log.Fatalf("Failed request, non-2xx code (%d): %s", response.StatusCode, data)
}
fmt.Println(response.StatusCode)
fmt.Println(string(data))
Output: 200 body