Add autoredirect for http to https connections (browser-only) (#648, #652)

This commit is contained in:
Igor Chubin 2021-11-01 12:27:27 +01:00
parent b9c8f38726
commit 85d7d029a2
2 changed files with 71 additions and 3 deletions

View file

@ -14,6 +14,10 @@ import (
func processRequest(r *http.Request) responseWithHeader {
var response responseWithHeader
if response, ok := redirectInsecure(r); ok {
return *response
}
if dontCache(r) {
return get(r)
}
@ -120,8 +124,56 @@ func dontCache(req *http.Request) bool {
// dont cache cyclic requests
loc := strings.Split(req.RequestURI, "?")[0]
if strings.Contains(loc, ":") {
return true
return strings.Contains(loc, ":")
}
// redirectInsecure returns redirection response, and bool value, if redirection was needed,
// if the query comes from a browser, and it is insecure.
//
// Insecure queries are marked by the frontend web server
// with X-Forwarded-Proto header:
//
// proxy_set_header X-Forwarded-Proto $scheme;
//
//
func redirectInsecure(req *http.Request) (*responseWithHeader, bool) {
if isPlainTextAgent(req.Header.Get("User-Agent")) {
return nil, false
}
if strings.ToLower(req.Header.Get("X-Forwarded-Proto")) == "https" {
return nil, false
}
target := "https://" + req.Host + req.URL.Path
if len(req.URL.RawQuery) > 0 {
target += "?" + req.URL.RawQuery
}
body := []byte(fmt.Sprintf(`<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="%s">here</A>.
</BODY></HTML>
`, target))
return &responseWithHeader{
InProgress: false,
Expires: time.Now().Add(time.Duration(randInt(1000, 1500)) * time.Second),
Body: body,
Header: http.Header{"Location": []string{target}},
StatusCode: 301,
}, true
}
// isPlainTextAgent returns true if userAgent is a plain-text agent
func isPlainTextAgent(userAgent string) bool {
userAgentLower := strings.ToLower(userAgent)
for _, signature := range plainTextAgents {
if strings.Contains(userAgentLower, signature) {
return true
}
}
return false
}

View file

@ -2,6 +2,7 @@ package main
import (
"context"
"fmt"
"log"
"net"
"net/http"
@ -10,11 +11,26 @@ import (
lru "github.com/hashicorp/golang-lru"
)
const serverPort = 8083
const uplinkSrvAddr = "127.0.0.1:9002"
const uplinkTimeout = 30
const prefetchInterval = 300
const lruCacheSize = 12800
// plainTextAgents contains signatures of the plain-text agents
var plainTextAgents = []string{
"curl",
"httpie",
"lwp-request",
"wget",
"python-requests",
"openbsd ftp",
"powershell",
"fetch",
"aiohttp",
"http_get",
}
var lruCache *lru.Cache
type responseWithHeader struct {
@ -65,5 +81,5 @@ func main() {
w.Write(response.Body)
})
log.Fatal(http.ListenAndServe(":8082", nil))
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", serverPort), nil))
}