Documentation
¶
Overview ¶
Package httpsproxy provides an http serve mux that can work as an HTTPS proxy for a site with self-signed https certificate.
The main user of this library is blynk-proxy, please refer to that project for context and examples: https://github.com/fishy/blynk-proxy
Example ¶
package main import ( "log" "net/url" "os" "time" "go.yhsif.com/httpsproxy" ) func main() { target := "https://self-signed.badssl.com/" targetURL, err := url.Parse(target) if err != nil { log.Fatal(err) } // Get it by the following command: // openssl s_client -showcerts -connect self-signed.badssl.com:443 </dev/null cert := `-----BEGIN CERTIFICATE----- MIIE8DCCAtigAwIBAgIJAM28Wkrsl2exMA0GCSqGSIb3DQEBCwUAMH8xCzAJBgNV BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNp c2NvMQ8wDQYDVQQKDAZCYWRTU0wxMjAwBgNVBAMMKUJhZFNTTCBJbnRlcm1lZGlh dGUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTE2MDgwODIxMTcwNVoXDTE4MDgw ODIxMTcwNVowgagxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYw FAYDVQQHDA1TYW4gRnJhbmNpc2NvMTYwNAYDVQQKDC1CYWRTU0wgRmFsbGJhY2su IFVua25vd24gc3ViZG9tYWluIG9yIG5vIFNOSS4xNDAyBgNVBAMMK2JhZHNzbC1m YWxsYmFjay11bmtub3duLXN1YmRvbWFpbi1vci1uby1zbmkwggEiMA0GCSqGSIb3 DQEBAQUAA4IBDwAwggEKAoIBAQDCBOz4jO4EwrPYUNVwWMyTGOtcqGhJsCK1+ZWe sSssdj5swEtgTEzqsrTAD4C2sPlyyYYC+VxBXRMrf3HES7zplC5QN6ZnHGGM9kFC xUbTFocnn3TrCp0RUiYhc2yETHlV5NFr6AY9SBVSrbMo26r/bv9glUp3aznxJNEx tt1NwMT8U7ltQq21fP6u9RXSM0jnInHHwhR6bCjqN0rf6my1crR+WqIW3GmxV0Tb ChKr3sMPR3RcQSLhmvkbk+atIgYpLrG6SRwMJ56j+4v3QHIArJII2YxXhFOBBcvm /mtUmEAnhccQu3Nw72kYQQdFVXz5ZD89LMOpfOuTGkyG0cqFAgMBAAGjRTBDMAkG A1UdEwQCMAAwNgYDVR0RBC8wLYIrYmFkc3NsLWZhbGxiYWNrLXVua25vd24tc3Vi ZG9tYWluLW9yLW5vLXNuaTANBgkqhkiG9w0BAQsFAAOCAgEAsuFs0K86D2IB20nB QNb+4vs2Z6kECmVUuD0vEUBR/dovFE4PfzTr6uUwRoRdjToewx9VCwvTL7toq3dd oOwHakRjoxvq+lKvPq+0FMTlKYRjOL6Cq3wZNcsyiTYr7odyKbZs383rEBbcNu0N c666/ozs4y4W7ufeMFrKak9UenrrPlUe0nrEHV3IMSF32iV85nXm95f7aLFvM6Lm EzAGgWopuRqD+J0QEt3WNODWqBSZ9EYyx9l2l+KI1QcMalG20QXuxDNHmTEzMaCj 4Zl8k0szexR8rbcQEgJ9J+izxsecLRVp70siGEYDkhq0DgIDOjmmu8ath4yznX6A pYEGtYTDUxIvsWxwkraBBJAfVxkp2OSg7DiZEVlMM8QxbSeLCz+63kE/d5iJfqde cGqX7rKEsVW4VLfHPF8sfCyXVi5sWrXrDvJm3zx2b3XToU7EbNONO1C85NsUOWy4 JccoiguV8V6C723IgzkSgJMlpblJ6FVxC6ZX5XJ0ZsMI9TIjibM2L1Z9DkWRCT6D QjuKbYUeURhScofQBiIx73V7VXnFoc1qHAUd/pGhfkCUnUcuBV1SzCEhjiwjnVKx HJKvc9OYjJD0ZuvZw9gBrY7qKyBX8g+sglEGFNhruH8/OhqrV8pBXX/EWY0fUZTh iywmc6GTT7X94Ze2F7iB45jh7WQ= -----END CERTIFICATE-----` certPool, failed, err := httpsproxy.NewCertPool(cert) if err != nil { log.Printf("WARNING: Cannot get system cert pool: %v", err) } if len(failed) > 0 { log.Printf("WARNING: Failed to add cert(s) to pool: %v", failed) } selfURL, err := url.Parse("https://my-proxy.com") if err != nil { log.Printf("WARNING: Cannot get parse self URL: %v", err) } mux := httpsproxy.Mux( httpsproxy.DefaultHTTPClient( certPool, 30*time.Second, httpsproxy.NoRedirCheckRedirectFunc, ), targetURL, selfURL, nil, // logger ) port := os.Getenv("PORT") if port == "" { port = "8080" log.Printf("Defaulting to port %s", port) } log.Printf("Listening on port %s", port) // Start serving with: // log.Fatal(http.ListenAndServe(":"+port, mux)) _ = mux }
Output:
Index ¶
- func CheckError(logger *log.Logger, w http.ResponseWriter, err error) bool
- func CopyRequestHeaders(from, to *http.Request, headers []string)
- func DefaultHTTPClient(certPool *x509.CertPool, timeout time.Duration, ...) *http.Client
- func Mux(client *http.Client, targetURL, selfURL *url.URL, logger *log.Logger) *http.ServeMux
- func NewCertPool(pemCerts ...string) (certPool *x509.CertPool, failedCerts []string, sysCertPoolErr error)
- func NoRedirCheckRedirectFunc(*http.Request, []*http.Request) error
- func ProxyRootHandler(client *http.Client, targetURL, selfURL *url.URL, logger *log.Logger) func(w http.ResponseWriter, r *http.Request)
- func RewriteURL(logger *log.Logger, origURL, targetHost string, selfURL *url.URL) string
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CheckError ¶
CheckError checks error. If error is non-nil, it writes HTTP status code 502 (bad gateway) and the error message to the response and returns true.
func CopyRequestHeaders ¶
CopyRequestHeaders copies specified headers from one http.Request to another.
func DefaultHTTPClient ¶
func DefaultHTTPClient( certPool *x509.CertPool, timeout time.Duration, checkRedirectFunc func(*http.Request, []*http.Request) error, ) *http.Client
DefaultHTTPClient returns an http client that can be used in Mux function with:
certPool: the x509 cert pool to trust.
timeout: the http timeout.
checkRedirectFunc: the function to handle 3xx redirects, could be nil which means default behavior.
func Mux ¶
Mux creates an http serve mux to do the proxy job.
The returned mux contains a single handler for "/" to the handler generated by ProxyRootHandler to do the proxy. You can add your own handlers to handle cases like health check.
Refer to the doc of ProxyRootHandler for the more detailed explanations of the args.
func NewCertPool ¶
func NewCertPool(pemCerts ...string) ( certPool *x509.CertPool, failedCerts []string, sysCertPoolErr error, )
NewCertPool creates a new cert pool.
It tries to get the system cert pool first, then append new pemCerts into the pool.
Any new certs failed to append to the pool will be returned via failedCerts.
If for any reason it's unable to get the system cert pool, the error will be returned by sysCertPoolErr and the returned certPool will only have successfully added new certs.
func NoRedirCheckRedirectFunc ¶
NoRedirCheckRedirectFunc is a CheckRedirect function implemention can be used in http.Client. It does not follow any redirections.
func ProxyRootHandler ¶
func ProxyRootHandler( client *http.Client, targetURL, selfURL *url.URL, logger *log.Logger, ) func(w http.ResponseWriter, r *http.Request)
ProxyRootHandler generates the http handler function to be used to serve root ("/") in http mux.
client is the http client to use. You can either use DefaultHTTPClient function to get a default implementation, or refer to its code to create your own. You migh also find go.yhsif.com/badcerts package useful when creating your own client.
targetURL is the target URL this mux proxies to. Only its scheme and host will be used.
selfURL is for 3xx redirect rewrite. It could be nil, which means this mux won't rewrite any 3xx responses.
logger is the logger to log errors. It could be nil, which means no errors will be logged.
Types ¶
This section is empty.