44 lines
974 B
Go
44 lines
974 B
Go
|
|
package netproxy
|
||
|
|
|
||
|
|
import (
|
||
|
|
"fmt"
|
||
|
|
"net/http"
|
||
|
|
"net/url"
|
||
|
|
"strings"
|
||
|
|
)
|
||
|
|
|
||
|
|
func origin(u *url.URL) string {
|
||
|
|
port := u.Port()
|
||
|
|
if port == "" {
|
||
|
|
if strings.EqualFold(u.Scheme, "https") {
|
||
|
|
port = "443"
|
||
|
|
} else {
|
||
|
|
port = "80"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return strings.ToLower(u.Scheme) + "://" + strings.ToLower(u.Hostname()) + ":" + port
|
||
|
|
}
|
||
|
|
|
||
|
|
// CredentialSafeClient retains client settings, while never forwarding custom
|
||
|
|
// authentication headers or POST bodies to a different origin via redirects.
|
||
|
|
func CredentialSafeClient(client *http.Client) *http.Client {
|
||
|
|
if client == nil {
|
||
|
|
client = http.DefaultClient
|
||
|
|
}
|
||
|
|
next := *client
|
||
|
|
previous := next.CheckRedirect
|
||
|
|
next.CheckRedirect = func(req *http.Request, via []*http.Request) error {
|
||
|
|
if len(via) >= 10 {
|
||
|
|
return fmt.Errorf("too many redirects")
|
||
|
|
}
|
||
|
|
if len(via) > 0 && origin(req.URL) != origin(via[0].URL) {
|
||
|
|
return http.ErrUseLastResponse
|
||
|
|
}
|
||
|
|
if previous != nil {
|
||
|
|
return previous(req, via)
|
||
|
|
}
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
return &next
|
||
|
|
}
|