2020-10-31 21:50:31 -04:00
|
|
|
package httpproxy
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
2023-04-12 10:18:16 +00:00
|
|
|
"fmt"
|
2020-10-31 21:50:31 -04:00
|
|
|
"net/http"
|
|
|
|
|
"sync"
|
|
|
|
|
"time"
|
|
|
|
|
)
|
|
|
|
|
|
2021-09-23 16:58:21 +00:00
|
|
|
func newHandler(ctx context.Context, wg *sync.WaitGroup, logger Logger,
|
2020-10-31 21:50:31 -04:00
|
|
|
stealth, verbose bool, username, password string) http.Handler {
|
2020-11-21 01:26:02 +00:00
|
|
|
const httpTimeout = 24 * time.Hour
|
2020-10-31 21:50:31 -04:00
|
|
|
return &handler{
|
2021-02-15 14:40:51 +01:00
|
|
|
ctx: ctx,
|
|
|
|
|
wg: wg,
|
|
|
|
|
client: &http.Client{
|
|
|
|
|
Timeout: httpTimeout,
|
|
|
|
|
CheckRedirect: returnRedirect},
|
2020-11-21 01:26:02 +00:00
|
|
|
logger: logger,
|
|
|
|
|
verbose: verbose,
|
|
|
|
|
stealth: stealth,
|
|
|
|
|
username: username,
|
|
|
|
|
password: password,
|
2020-10-31 21:50:31 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type handler struct {
|
2022-02-26 13:49:53 +00:00
|
|
|
ctx context.Context //nolint:containedctx
|
2020-10-31 21:50:31 -04:00
|
|
|
wg *sync.WaitGroup
|
|
|
|
|
client *http.Client
|
2021-09-23 16:58:21 +00:00
|
|
|
logger Logger
|
2020-10-31 21:50:31 -04:00
|
|
|
verbose, stealth bool
|
|
|
|
|
username, password string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *handler) ServeHTTP(responseWriter http.ResponseWriter, request *http.Request) {
|
2020-12-01 22:29:31 -05:00
|
|
|
if !h.isAccepted(responseWriter, request) {
|
2020-10-31 21:50:31 -04:00
|
|
|
return
|
|
|
|
|
}
|
2020-12-01 22:29:31 -05:00
|
|
|
if !h.isAuthorized(responseWriter, request) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
request.Header.Del("Proxy-Connection")
|
|
|
|
|
request.Header.Del("Proxy-Authenticate")
|
|
|
|
|
request.Header.Del("Proxy-Authorization")
|
2020-10-31 21:50:31 -04:00
|
|
|
switch request.Method {
|
|
|
|
|
case http.MethodConnect:
|
|
|
|
|
h.handleHTTPS(responseWriter, request)
|
|
|
|
|
default:
|
|
|
|
|
h.handleHTTP(responseWriter, request)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html
|
|
|
|
|
var hopHeaders = [...]string{ //nolint:gochecknoglobals
|
|
|
|
|
"Connection",
|
|
|
|
|
"Keep-Alive",
|
|
|
|
|
"Proxy-Authenticate",
|
|
|
|
|
"Proxy-Authorization",
|
|
|
|
|
"Te", // canonicalized version of "TE"
|
|
|
|
|
"Trailers",
|
|
|
|
|
"Transfer-Encoding",
|
|
|
|
|
"Upgrade",
|
|
|
|
|
}
|
2021-02-15 14:40:51 +01:00
|
|
|
|
|
|
|
|
// Do not follow redirect, but directly return the redirect response.
|
2023-04-12 08:36:58 +00:00
|
|
|
func returnRedirect(*http.Request, []*http.Request) error {
|
2023-04-12 10:18:16 +00:00
|
|
|
return fmt.Errorf("%w", http.ErrUseLastResponse)
|
2021-02-15 14:40:51 +01:00
|
|
|
}
|