github.com/searKing/golang/go@v1.2.117/net/http/httpproxy/proxy.go (about) 1 // Copyright 2022 The searKing Author. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package httpproxy 6 7 import ( 8 "context" 9 "fmt" 10 "net/url" 11 12 "github.com/searKing/golang/go/net/resolver" 13 ) 14 15 // unique type to prevent assignment. 16 type proxyContextKey struct{} 17 18 // Proxy specifies ProxyUrl and ProxyTarget to return a dynamic proxy. 19 type Proxy struct { 20 // ProxyUrl is proxy's url, like socks5://127.0.0.1:8080 21 ProxyUrl string 22 // ProxyTarget is as like gRPC Naming for proxy service discovery, with Host in ProxyUrl replaced if not empty. 23 ProxyTarget string 24 25 // ProxyAddrResolved is the proxy's addr resolved and picked from resolver. 26 ProxyAddrResolved resolver.Address 27 } 28 29 // ContextProxy returns the Proxy associated with the 30 // provided context. If none, it returns nil. 31 func ContextProxy(ctx context.Context) *Proxy { 32 proxy, _ := ctx.Value(proxyContextKey{}).(*Proxy) 33 return proxy 34 } 35 36 // WithProxy returns a new context based on the provided parent 37 // ctx. HTTP client requests made with the returned context will use 38 // the provided proxy hooks 39 func WithProxy(ctx context.Context, proxy *Proxy) context.Context { 40 if proxy == nil { 41 panic("nil proxy") 42 } 43 return context.WithValue(ctx, proxyContextKey{}, proxy) 44 } 45 46 func ParseProxyUrl(proxy string) (*url.URL, error) { 47 if proxy == "" { 48 return nil, nil 49 } 50 51 proxyURL, err := url.Parse(proxy) 52 if err != nil || 53 (proxyURL.Scheme != "http" && 54 proxyURL.Scheme != "https" && 55 proxyURL.Scheme != "socks5") { 56 // proxy was bogus. Try prepending "http://" to it and 57 // see if that parses correctly. If not, we fall 58 // through and complain about the original one. 59 if proxyURL, err := url.Parse("http://" + proxy); err == nil { 60 return proxyURL, nil 61 } 62 } 63 if err != nil { 64 return nil, fmt.Errorf("invalid proxy address %q: %v", proxy, err) 65 } 66 return proxyURL, nil 67 }