1
0
Fork 0
photos/cmd/proxy/proxy.go

97 lines
2.2 KiB
Go

// This is honestly terrible. It only exists to replace the AWS S3 website hosting feature missing in minio
package main
import (
"log"
"net"
"net/http"
"net/http/httputil"
"os"
"strings"
"time"
internal_s3utils "git.makerforce.io/photos/photos/internal/s3utils"
"github.com/miekg/dns"
)
var endpoint string
var endpointSecure bool
var domain string
var behindProxy bool
func main() {
// Read configuration
endpoint = os.Getenv("MINIO_ENDPOINT")
endpointSecure = os.Getenv("MINIO_ENDPOINT_SECURE") == "true"
domain = os.Getenv("MINIO_DOMAIN")
behindProxy = os.Getenv("BEHIND_PROXY") == "true"
server := &http.Server{
Addr: ":80",
ReadTimeout: 5 * time.Second,
WriteTimeout: 10 * time.Second,
Handler: &httputil.ReverseProxy{Director: director},
}
err := server.ListenAndServe()
if err != nil {
panic(err)
}
}
func director(req *http.Request) {
// Validate host
host, port, err := net.SplitHostPort(req.Host)
if err != nil {
// Assumption: IsDomainName will handle other cases
host = req.Host
}
if _, ok := dns.IsDomainName(host); !ok {
req.URL.Scheme = ""
return
}
// Rewrite URL
req.URL.Scheme = "http"
if endpointSecure {
req.URL.Scheme = "https"
}
req.URL.Host = endpoint
if len(domain) < 1 {
// If we are using domains, rewrite the host into path
req.URL.Path = internal_s3utils.PathFromHost(mapPath(*req), host)
} else {
// If we are using subdomains, set the host header
req.URL.Path = mapPath(*req)
req.Header.Set("Host", host)
}
// Prevent MINIO from issuing redirects
userAgent := req.Header.Get("User-Agent")
userAgent = strings.ReplaceAll(userAgent, "Mozilla", "M-o-z-i-l-l-a")
req.Header.Set("User-Agent", userAgent)
if !behindProxy {
// Clear existing unsafe headers
req.Header.Del("Forwarded")
req.Header.Del("X-Forwarded-For")
// Unnecessary, but might as well
req.Header.Set("X-Forwarded-Proto", req.URL.Scheme)
req.Header.Set("X-Forwarded-Host", host)
req.Header.Set("X-Forwarded-Port", port)
}
log.Println(req.Header.Get("Host"), req.URL)
}
func mapPath(req http.Request) string {
path := req.URL.Path
if req.FormValue("list-type") == "2" {
return path
}
if strings.HasSuffix(path, "/") {
path += "index.html"
}
return path
}