Skip to content

Commit 46e71ac

Browse files
committed
Add a setting to disallow HTTP to HTTPS redirects
Mirrorbits doens't respect the incoming protocol *strictly*, instead the behavior is as such: - HTTPS request: HTTPS redirect - HTTP request: HTTP or HTTPS redirect So it doesn't try to respect the HTTP protocol, and is happy to redirect HTTP requests to HTTPS. Which makes sense if mirrorbits is meant to serve files downloaded from a web browser, where HTTPS is the norm. However for Linux distro, for a package repository, it's important to respect the incoming protocol. There are minimal systems that don't have HTTPS support out of the box. For Debian (and Debian-like), the standard Docker image doesn't have CA certificates pre-installed, and apt is configured to use HTTP repositories. The first command to run is `apt update`, and if ever that gets redirected to HTTPS, apt fails. With this commit, we can now change this behavior, and ask mirrorbits to respect the protocol strictly. As a bonus point, having it in mirrobits.conf allows to document a rather obscure (but important) aspect of mirrorbits behavior. Note that, by default, the setting is true, so the default behavior of mirrorbits is still the same: redirect HTTP to HTTPS is allowed.
1 parent c320c8d commit 46e71ac

File tree

3 files changed

+14
-2
lines changed

3 files changed

+14
-2
lines changed

config/config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ func defaultConfig() Configuration {
3737
OutputMode: "auto",
3838
ListenAddress: ":8080",
3939
Gzip: false,
40+
AllowHTTPToHTTPSRedirects: true,
4041
SameDownloadInterval: 600,
4142
RedisAddress: "127.0.0.1:6379",
4243
RedisPassword: "",
@@ -71,6 +72,7 @@ type Configuration struct {
7172
OutputMode string `yaml:"OutputMode"`
7273
ListenAddress string `yaml:"ListenAddress"`
7374
Gzip bool `yaml:"Gzip"`
75+
AllowHTTPToHTTPSRedirects bool `yaml:"AllowHTTPToHTTPSRedirects"`
7476
SameDownloadInterval int `yaml:"SameDownloadInterval"`
7577
RedisAddress string `yaml:"RedisAddress"`
7678
RedisPassword string `yaml:"RedisPassword"`

http/context.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import (
77
"net/http"
88
"net/url"
99
"strings"
10+
11+
. "github.com/etix/mirrorbits/config"
1012
)
1113

1214
// RequestType defines the type of the request
@@ -67,11 +69,14 @@ func NewContext(w http.ResponseWriter, r *http.Request, t Templates) *Context {
6769
}
6870

6971
// Check for HTTPS requirements
70-
proto := r.Header.Get("X-Forwarded-Proto")
71-
if strings.ToLower(proto) == "https" {
72+
proto := strings.ToLower(r.Header.Get("X-Forwarded-Proto"))
73+
if proto == "https" {
7274
c.secureOption = WITHTLS
75+
} else if proto == "http" && GetConfig().AllowHTTPToHTTPSRedirects == false {
76+
c.secureOption = WITHOUTTLS
7377
}
7478

79+
// Check if the query sets (thus overrides) HTTPS requirements
7580
v, ok := c.v["https"]
7681
if ok {
7782
if v[0] == "1" {

mirrorbits.conf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@
3030
## Enable Gzip compression
3131
# Gzip: false
3232

33+
## Allow redirecting HTTP requests to HTTPS mirrors. If ever a mirror supports
34+
## both, HTTPS is favored. In other words, this setting forces HTTPS when
35+
## possible, thus making the implicit assumption that the client supports it.
36+
# AllowHTTPToHTTPSRedirects: true
37+
3338
## Interval in seconds between which 2 range downloads of a given file
3439
## from a same origin (hashed (IP, user-agent) couple) are considered
3540
## to be the same download. In particular, download statistics are not

0 commit comments

Comments
 (0)