Add a new generic container registry client via a new `container` package. Use this to create a command line utility as well as a new upload target for container registries. The code uses the github.com/containers/* project and packages to interact with container registires that is also used by skopeo, podman et al. One if the dependencies is `proglottis/gpgme` that is using cgo to bind libgpgme, so we have to add the corresponding devel package to the BuildRequires as well as installing it on CI. Checks will follow later via an integration test.
149 lines
3.6 KiB
Go
149 lines
3.6 KiB
Go
// Copyright 2011 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
// Package proxy provides support for a variety of protocols to proxy network
|
|
// data.
|
|
package proxy // import "golang.org/x/net/proxy"
|
|
|
|
import (
|
|
"errors"
|
|
"net"
|
|
"net/url"
|
|
"os"
|
|
"sync"
|
|
)
|
|
|
|
// A Dialer is a means to establish a connection.
|
|
// Custom dialers should also implement ContextDialer.
|
|
type Dialer interface {
|
|
// Dial connects to the given address via the proxy.
|
|
Dial(network, addr string) (c net.Conn, err error)
|
|
}
|
|
|
|
// Auth contains authentication parameters that specific Dialers may require.
|
|
type Auth struct {
|
|
User, Password string
|
|
}
|
|
|
|
// FromEnvironment returns the dialer specified by the proxy-related
|
|
// variables in the environment and makes underlying connections
|
|
// directly.
|
|
func FromEnvironment() Dialer {
|
|
return FromEnvironmentUsing(Direct)
|
|
}
|
|
|
|
// FromEnvironmentUsing returns the dialer specify by the proxy-related
|
|
// variables in the environment and makes underlying connections
|
|
// using the provided forwarding Dialer (for instance, a *net.Dialer
|
|
// with desired configuration).
|
|
func FromEnvironmentUsing(forward Dialer) Dialer {
|
|
allProxy := allProxyEnv.Get()
|
|
if len(allProxy) == 0 {
|
|
return forward
|
|
}
|
|
|
|
proxyURL, err := url.Parse(allProxy)
|
|
if err != nil {
|
|
return forward
|
|
}
|
|
proxy, err := FromURL(proxyURL, forward)
|
|
if err != nil {
|
|
return forward
|
|
}
|
|
|
|
noProxy := noProxyEnv.Get()
|
|
if len(noProxy) == 0 {
|
|
return proxy
|
|
}
|
|
|
|
perHost := NewPerHost(proxy, forward)
|
|
perHost.AddFromString(noProxy)
|
|
return perHost
|
|
}
|
|
|
|
// proxySchemes is a map from URL schemes to a function that creates a Dialer
|
|
// from a URL with such a scheme.
|
|
var proxySchemes map[string]func(*url.URL, Dialer) (Dialer, error)
|
|
|
|
// RegisterDialerType takes a URL scheme and a function to generate Dialers from
|
|
// a URL with that scheme and a forwarding Dialer. Registered schemes are used
|
|
// by FromURL.
|
|
func RegisterDialerType(scheme string, f func(*url.URL, Dialer) (Dialer, error)) {
|
|
if proxySchemes == nil {
|
|
proxySchemes = make(map[string]func(*url.URL, Dialer) (Dialer, error))
|
|
}
|
|
proxySchemes[scheme] = f
|
|
}
|
|
|
|
// FromURL returns a Dialer given a URL specification and an underlying
|
|
// Dialer for it to make network requests.
|
|
func FromURL(u *url.URL, forward Dialer) (Dialer, error) {
|
|
var auth *Auth
|
|
if u.User != nil {
|
|
auth = new(Auth)
|
|
auth.User = u.User.Username()
|
|
if p, ok := u.User.Password(); ok {
|
|
auth.Password = p
|
|
}
|
|
}
|
|
|
|
switch u.Scheme {
|
|
case "socks5", "socks5h":
|
|
addr := u.Hostname()
|
|
port := u.Port()
|
|
if port == "" {
|
|
port = "1080"
|
|
}
|
|
return SOCKS5("tcp", net.JoinHostPort(addr, port), auth, forward)
|
|
}
|
|
|
|
// If the scheme doesn't match any of the built-in schemes, see if it
|
|
// was registered by another package.
|
|
if proxySchemes != nil {
|
|
if f, ok := proxySchemes[u.Scheme]; ok {
|
|
return f(u, forward)
|
|
}
|
|
}
|
|
|
|
return nil, errors.New("proxy: unknown scheme: " + u.Scheme)
|
|
}
|
|
|
|
var (
|
|
allProxyEnv = &envOnce{
|
|
names: []string{"ALL_PROXY", "all_proxy"},
|
|
}
|
|
noProxyEnv = &envOnce{
|
|
names: []string{"NO_PROXY", "no_proxy"},
|
|
}
|
|
)
|
|
|
|
// envOnce looks up an environment variable (optionally by multiple
|
|
// names) once. It mitigates expensive lookups on some platforms
|
|
// (e.g. Windows).
|
|
// (Borrowed from net/http/transport.go)
|
|
type envOnce struct {
|
|
names []string
|
|
once sync.Once
|
|
val string
|
|
}
|
|
|
|
func (e *envOnce) Get() string {
|
|
e.once.Do(e.init)
|
|
return e.val
|
|
}
|
|
|
|
func (e *envOnce) init() {
|
|
for _, n := range e.names {
|
|
e.val = os.Getenv(n)
|
|
if e.val != "" {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
// reset is used by tests
|
|
func (e *envOnce) reset() {
|
|
e.once = sync.Once{}
|
|
e.val = ""
|
|
}
|