diff --git a/handlers.go b/handlers.go index 535fdeb..4a5d0e9 100644 --- a/handlers.go +++ b/handlers.go @@ -9,22 +9,19 @@ import ( "net/http" "net/url" "regexp" - "strconv" "strings" "time" - "unicode" "github.com/mozilla-services/go-bouncer/bouncer" ) const ( - DefaultLang = "en-US" - DefaultOS = "win" - firefoxSHA1ESRAliasSuffix = "sha1" - fxPre2024LastNightly = "firefox-nightly-pre2024" - fxPre2024LastBeta = "127.0b9" - fxPre2024LastRelease = "127.0" - esr115Product = "firefox-esr115-latest-ssl" + defaultLang = "en-US" + defaultOS = "win" + fxPre2024LastNightly = "firefox-nightly-pre2024" + fxPre2024LastBeta = "127.0b9" + fxPre2024LastRelease = "127.0" + esr115Product = "firefox-esr115-latest-ssl" ) type xpRelease struct { @@ -32,8 +29,6 @@ type xpRelease struct { } var ( - // detects Windows XP and Vista clients - windowsXPRegex = regexp.MustCompile(`Windows (?:NT 5\.1|XP|NT 5\.2|NT 6\.0)`) // detects windows 7/8/8.1 clients windowsRegexForESR115 = regexp.MustCompile(`Windows (?:NT 6\.(1|2|3))`) // this is used to verify the referer header @@ -44,13 +39,6 @@ var ( win64Regex = regexp.MustCompile(`Win64|WOW64`) ) -var tBirdWinXPLastRelease = xpRelease{"38.5.0"} -var tBirdWinXPLastBeta = xpRelease{"43.0b1"} - -func isWindowsXPUserAgent(userAgent string) bool { - return windowsXPRegex.MatchString(userAgent) -} - func isUserAgentOnlyCompatibleWithESR115(userAgent string) bool { return windowsRegexForESR115.MatchString(userAgent) } @@ -63,133 +51,8 @@ func isWin64UserAgent(userAgent string) bool { return win64Regex.MatchString(userAgent) } -func isNotNumber(r rune) bool { - return !unicode.IsNumber(r) -} - -// a < b = -1 -// a == b = 0 -// a > b = 1 -func compareVersions(a, b string) int { - if a == b { - return 0 - } - aParts := strings.Split(a, ".") - bParts := strings.Split(b, ".") - - for i, verA := range aParts { - if len(bParts) <= i { - return 1 - } - verB := bParts[i] - - aInt, err := strconv.Atoi(strings.TrimRightFunc(verA, isNotNumber)) - if err != nil { - aInt = 0 - } - bInt, err := strconv.Atoi(strings.TrimRightFunc(verB, isNotNumber)) - if err != nil { - bInt = 0 - } - - if aInt > bInt { - return 1 - } - if aInt < bInt { - return -1 - } - } - return 0 -} - -func tBirdSha1Product(productSuffix string) string { - switch productSuffix { - case "beta", "beta-latest": - return tBirdWinXPLastBeta.Version - case "ssl": - return tBirdWinXPLastRelease.Version + "-ssl" - case "latest": - return tBirdWinXPLastRelease.Version - } - - productSuffixParts := strings.SplitN(productSuffix, "-", 2) - ver := productSuffixParts[0] - - possibleVersion := tBirdWinXPLastRelease - if strings.Contains(ver, ".0b") { - possibleVersion = tBirdWinXPLastBeta - } - - if compareVersions(ver, possibleVersion.Version) == -1 { - return productSuffix - } - - if len(productSuffixParts) == 1 { - return possibleVersion.Version - } - - if productSuffixParts[1] == "ssl" { - return possibleVersion.Version + "-ssl" - } - - return productSuffix -} - -func firefoxSha1Product(productSuffix string) string { - // Example list of products: - // Firefox-48.0-Complete - // Firefox-48.0build1-Complete - // Firefox-48.0 - // Firefox-48.0-SSL - // Firefox-48.0-stub - // Firefox-48.0build1-Partial-47.0build3 - // Firefox-48.0build1-Partial-47.0.1build1 - // Firefox-48.0build1-Partial-48.0b10build1 - // Firefox-48.0-Partial-47.0 - // Firefox-48.0-Partial-47.0.1 - // Firefox-48.0-Partial-48.0b10 - - // Example list of aliases: - // firefox-beta-latest - // firefox-beta-sha1 - // Firefox-beta-stub - // firefox-esr-latest - // firefox-esr-sha1 - // firefox-latest - // firefox-sha1 - // Firefox-stub - - // Do not touch products ending with "sha1" - if strings.HasSuffix(productSuffix, "-sha1") { - return productSuffix - } - - // Do not touch completes and partials - if strings.HasSuffix(productSuffix, "-complete") || strings.Contains(productSuffix, "-partial-") { - return productSuffix - } - return firefoxSHA1ESRAliasSuffix -} - -func sha1Product(product string) string { - productParts := strings.SplitN(product, "-", 2) - if len(productParts) == 1 { - return product - } - - if productParts[0] == "firefox" { - return "firefox-" + firefoxSha1Product(productParts[1]) - } - - if productParts[0] == "thunderbird" { - return "thunderbird-" + tBirdSha1Product(productParts[1]) - } - - return product -} - -// detect stub installers that pin the "DigiCert SHA2 Assured ID Code Signing CA" intermediate - +// isPre2024StubUserAgent is used to detect stub installers that pin the +// "DigiCert SHA2 Assured ID Code Signing CA" intermediate. func isPre2024StubUserAgent(userAgent string) bool { return "NSIS InetBgDL (Mozilla)" == userAgent } @@ -272,7 +135,7 @@ func (h *HealthHandler) check() *HealthResult { return result } -func (h *HealthHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { +func (h *HealthHandler) ServeHTTP(w http.ResponseWriter, _ *http.Request) { if h.CacheTime > 0 { w.Header().Set("Cache-Control", fmt.Sprintf("max-age=%d", h.CacheTime/time.Second)) } @@ -291,7 +154,7 @@ type BouncerHandler struct { db *bouncer.DB CacheTime time.Duration - PinHttpsHeaderName string + PinHTTPSHeaderName string PinnedBaseURLHttp string PinnedBaseURLHttps string StubRootURL string @@ -299,7 +162,7 @@ type BouncerHandler struct { // URL returns the final redirect URL given a lang, os and product // if the string is == "", no mirror or location was found -func (b *BouncerHandler) URL(pinHttps bool, lang, os, product string) (string, error) { +func (b *BouncerHandler) URL(pinHTTPS bool, lang, os, product string) (string, error) { product, err := b.db.AliasFor(product) if err != nil { return "", err @@ -331,7 +194,7 @@ func (b *BouncerHandler) URL(pinHttps bool, lang, os, product string) (string, e locationPath = strings.Replace(locationPath, ":lang", lang, -1) mirrorBaseURL := "http://" + b.PinnedBaseURLHttp - if pinHttps || sslOnly { + if pinHTTPS || sslOnly { mirrorBaseURL = "https://" + b.PinnedBaseURLHttps } @@ -349,27 +212,27 @@ func (b *BouncerHandler) stubAttributionURL(reqParams *BouncerParams) string { return b.StubRootURL + "?" + query.Encode() } -func (b *BouncerHandler) shouldPinHttps(req *http.Request) bool { - if b.PinHttpsHeaderName == "" { +func (b *BouncerHandler) shouldPinHTTPS(req *http.Request) bool { + if b.PinHTTPSHeaderName == "" { return false } - return req.Header.Get(b.PinHttpsHeaderName) == "https" + return req.Header.Get(b.PinHTTPSHeaderName) == "https" } -func fromRTAMO(attribution_code string) bool { +func fromRTAMO(attributionCode string) bool { // base64 decode the attribution_code value to see if it matches the RTAMO regex // This uses '.' as padding because Bedrock is using this library to encode the values: // https://pypi.org/project/querystringsafe-base64/ var base64Decoder = base64.URLEncoding.WithPadding('.') - sDec, err := base64Decoder.DecodeString(attribution_code) + sDec, err := base64Decoder.DecodeString(attributionCode) if err != nil { - log.Printf("Error decoding %s: %s ", attribution_code, err.Error()) + log.Printf("Error decoding %s: %s ", attributionCode, err.Error()) return false } q, err := url.ParseQuery(string(sDec)) if err != nil { - log.Printf("Error parsing the attribution_code query parameters: %s", err.Error()) + log.Printf("Error parsing the attribution_code query parameter: %s", err.Error()) return false } @@ -439,14 +302,20 @@ func (b *BouncerHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { } if reqParams.OS == "" { - reqParams.OS = DefaultOS + reqParams.OS = defaultOS } + if reqParams.Lang == "" { - reqParams.Lang = DefaultLang + reqParams.Lang = defaultLang + } + + // If attribution_code is set, redirect to the stub service. + if b.shouldAttribute(reqParams) { + stubURL := b.stubAttributionURL(reqParams) + http.Redirect(w, req, stubURL, 302) + return } - isWinXpClient := isWindowsXPUserAgent(req.UserAgent()) - isPre2024Stub := isPre2024StubUserAgent(req.UserAgent()) // We want to return ESR115 when... the product is for Firefox shouldReturnESR115 := strings.HasPrefix(reqParams.Product, "firefox-") && // and the product is _not_ an MSI build @@ -461,18 +330,6 @@ func (b *BouncerHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { // and the request doesn't come from mozilla.org !hasMozorgReferrer(reqParams.Referer) - // If the client is not WinXP and attribution_code is set, redirect to the stub service - if b.shouldAttribute(reqParams) && !isWinXpClient { - stubURL := b.stubAttributionURL(reqParams) - http.Redirect(w, req, stubURL, 302) - return - } - - // HACKS - // If the user is coming from windows xp or vista, send a sha1 signed product. - if reqParams.OS == "win" && isWinXpClient { - reqParams.Product = sha1Product(reqParams.Product) - } // Send the latest compatible ESR product if we detect that this is the best option for the client. if shouldReturnESR115 { // Override the OS if we detect a x64 client that attempts to get a stub installer. @@ -481,12 +338,13 @@ func (b *BouncerHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { } reqParams.Product = esr115Product } + // If the user is an "old" stub installer, send a pre-2024-cert-rotation product. - if isPre2024Stub { + if isPre2024StubUserAgent(req.UserAgent()) { reqParams.Product = pre2024Product(reqParams.Product) } - url, err := b.URL(b.shouldPinHttps(req), reqParams.Lang, reqParams.OS, reqParams.Product) + url, err := b.URL(b.shouldPinHTTPS(req), reqParams.Lang, reqParams.OS, reqParams.Product) if err != nil { http.Error(w, "Internal Server Error.", http.StatusInternalServerError) log.Println(err) diff --git a/handlers_test.go b/handlers_test.go index c8926d6..17aa5ee 100644 --- a/handlers_test.go +++ b/handlers_test.go @@ -26,7 +26,7 @@ func init() { bouncerHandler = &BouncerHandler{ db: testDB, StubRootURL: "https://stub/", - PinHttpsHeaderName: "X-Forwarded-Proto", + PinHTTPSHeaderName: "X-Forwarded-Proto", PinnedBaseURLHttp: "download.cdn.mozilla.net/pub", PinnedBaseURLHttps: "download-installer.cdn.mozilla.net/pub", } @@ -34,7 +34,7 @@ func init() { db: testDB, PinnedBaseURLHttp: "download-sha1.cdn.mozilla.net/pub", PinnedBaseURLHttps: "download-sha1.cdn.mozilla.net/pub", - PinHttpsHeaderName: "X-Forwarded-Proto", + PinHTTPSHeaderName: "X-Forwarded-Proto", } } @@ -217,23 +217,23 @@ func TestBouncerHandlerParams(t *testing.T) { } func TestBouncerShouldPinHttps(t *testing.T) { - bouncerHandler.PinHttpsHeaderName = "" + bouncerHandler.PinHTTPSHeaderName = "" req, err := http.NewRequest("GET", "http://test/?product=firefox-latest&os=osx&lang=en-US", nil) assert.NoError(t, err) - assert.Equal(t, false, bouncerHandler.shouldPinHttps(req)) + assert.Equal(t, false, bouncerHandler.shouldPinHTTPS(req)) req.Header.Set("X-Forwarded-Proto", "https") - assert.Equal(t, false, bouncerHandler.shouldPinHttps(req)) + assert.Equal(t, false, bouncerHandler.shouldPinHTTPS(req)) - bouncerHandler.PinHttpsHeaderName = "X-Forwarded-Proto" + bouncerHandler.PinHTTPSHeaderName = "X-Forwarded-Proto" - assert.Equal(t, true, bouncerHandler.shouldPinHttps(req)) + assert.Equal(t, true, bouncerHandler.shouldPinHTTPS(req)) req.Header.Set("X-Forwarded-Proto", "http") - assert.Equal(t, false, bouncerHandler.shouldPinHttps(req)) + assert.Equal(t, false, bouncerHandler.shouldPinHTTPS(req)) req.Header.Del("X-Forwarded-Proto") - assert.Equal(t, false, bouncerHandler.shouldPinHttps(req)) + assert.Equal(t, false, bouncerHandler.shouldPinHTTPS(req)) } func TestBouncerHandlerPrintQuery(t *testing.T) { @@ -247,38 +247,6 @@ func TestBouncerHandlerPrintQuery(t *testing.T) { assert.Equal(t, "http://download.cdn.mozilla.net/pub/firefox/releases/39.0/mac/en-US/Firefox%2039.0.dmg", w.Body.String()) } -func TestBouncerHandlerPinnedValid(t *testing.T) { - defaultUA := "Mozilla/5.0 (Windows NT 7.0; rv:10.0) Gecko/20100101 Firefox/43.0" - testRequests := []struct { - URL string - ExpectedLocation string - UserAgent string - XForwardedProto string - }{ - {"http://test/?product=firefox-latest&os=osx&lang=en-US", "http://download-sha1.cdn.mozilla.net/pub/firefox/releases/39.0/mac/en-US/Firefox%2039.0.dmg", defaultUA, "http"}, - {"http://test/?product=firefox-latest&os=win64&lang=en-US", "http://download-sha1.cdn.mozilla.net/pub/firefox/releases/39.0/win64/en-US/Firefox%20Setup%2039.0.exe", defaultUA, "http"}, - {"http://test/?product=firefox-latest&os=win64&lang=en-US", "https://download-sha1.cdn.mozilla.net/pub/firefox/releases/39.0/win64/en-US/Firefox%20Setup%2039.0.exe", defaultUA, "https"}, - {"http://test/?product=Firefox-SSL&os=win64&lang=en-US", "https://download-sha1.cdn.mozilla.net/pub/firefox/releases/39.0/win64/en-US/Firefox%20Setup%2039.0.exe", defaultUA, "http"}, - {"http://test/?product=Firefox-SSL&os=win&lang=en-US", "https://download-sha1.cdn.mozilla.net/pub/firefox/releases/43.0.1/win32/en-US/Firefox%20Setup%2043.0.1.exe", "Mozilla/5.0 (Windows; U; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)", "http"}, // Windows XP - {"http://test/?product=Firefox-SSL&os=win&lang=en-US", "https://download-sha1.cdn.mozilla.net/pub/firefox/releases/43.0.1/win32/en-US/Firefox%20Setup%2043.0.1.exe", "Mozilla/5.0 (Windows; U; MSIE 6.0; Windows NT 6.0; SV1; .NET CLR 2.0.50727)", "http"}, // Windows Vista - {"http://test/?product=Firefox-SSL&os=win64&lang=en-US", "https://download-sha1.cdn.mozilla.net/pub/firefox/releases/39.0/win64/en-US/Firefox%20Setup%2039.0.exe", "Mozilla/5.0 (Windows; U; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)", "http"}, // Windows XP 64 bit - should get normal win64 build - {"http://test/?product=Firefox-stub&os=win&lang=en-US", "https://download-sha1.cdn.mozilla.net/pub/firefox/releases/43.0.1/win32/en-US/Firefox%20Setup%2043.0.1.exe", "Mozilla/5.0 (Windows; U; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)", "http"}, // Windows XP no stub - } - - for _, testRequest := range testRequests { - w := httptest.NewRecorder() - req, err := http.NewRequest("GET", testRequest.URL, nil) - req.Header.Set("X-Forwarded-Proto", testRequest.XForwardedProto) - assert.NoError(t, err, "url: %v ua: %v", testRequest.URL, testRequest.UserAgent) - - req.Header.Set("User-Agent", testRequest.UserAgent) - - bouncerHandlerPinned.ServeHTTP(w, req) - assert.Equal(t, 302, w.Code, "url: %v ua: %v", testRequest.URL, testRequest.UserAgent) - assert.Equal(t, testRequest.ExpectedLocation, w.HeaderMap.Get("Location"), "url: %v ua: %v", testRequest.URL, testRequest.UserAgent) - } -} - func TestBouncerHandlerValid(t *testing.T) { defaultUA := "Mozilla/5.0 (Windows NT 7.0; rv:10.0) Gecko/20100101 Firefox/43.0" testRequests := []struct { @@ -289,10 +257,6 @@ func TestBouncerHandlerValid(t *testing.T) { {"http://test/?product=firefox-latest&os=osx&lang=en-US", "http://download.cdn.mozilla.net/pub/firefox/releases/39.0/mac/en-US/Firefox%2039.0.dmg", defaultUA}, {"http://test/?product=firefox-latest&os=win64&lang=en-US", "http://download.cdn.mozilla.net/pub/firefox/releases/39.0/win64/en-US/Firefox%20Setup%2039.0.exe", defaultUA}, {"http://test/?product=Firefox-SSL&os=win64&lang=en-US", "https://download-installer.cdn.mozilla.net/pub/firefox/releases/39.0/win64/en-US/Firefox%20Setup%2039.0.exe", defaultUA}, - {"http://test/?product=Firefox-SSL&os=win&lang=en-US", "https://download-installer.cdn.mozilla.net/pub/firefox/releases/43.0.1/win32/en-US/Firefox%20Setup%2043.0.1.exe", "Mozilla/5.0 (Windows; U; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)"}, // Windows XP - {"http://test/?product=Firefox-SSL&os=win&lang=en-US", "https://download-installer.cdn.mozilla.net/pub/firefox/releases/43.0.1/win32/en-US/Firefox%20Setup%2043.0.1.exe", "Mozilla/5.0 (Windows; U; MSIE 6.0; Windows NT 6.0; SV1; .NET CLR 2.0.50727)"}, // Windows Vista - {"http://test/?product=Firefox-SSL&os=win64&lang=en-US", "https://download-installer.cdn.mozilla.net/pub/firefox/releases/39.0/win64/en-US/Firefox%20Setup%2039.0.exe", "Mozilla/5.0 (Windows; U; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)"}, // Windows XP 64 bit - should get normal win64 build - {"http://test/?product=Firefox-stub&os=win&lang=en-US", "https://download-installer.cdn.mozilla.net/pub/firefox/releases/43.0.1/win32/en-US/Firefox%20Setup%2043.0.1.exe", "Mozilla/5.0 (Windows; U; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)"}, // Windows XP no stub {"http://test/?product=Firefox-nightly-latest-ssl&os=win&lang=en-US", "https://download-installer.cdn.mozilla.net/pub/firefox/nightly/2024/05/2024-05-06-09-48-55-mozilla-central-l10n/firefox-127.0a1.en-US.win32.installer.exe", "NSIS InetBgDL (Mozilla)"}, // old stub {"http://test/?product=Firefox-nightly-latest-ssl&os=win&lang=en-US", "https://download-installer.cdn.mozilla.net/pub/firefox/nightly/latest-mozilla-central/firefox-128.0a1.en-US.win32.installer.exe", "NSIS InetBgDL (Mozilla 2024)"}, // new stub {"http://test/?product=Firefox-nightly-latest-ssl&os=win&lang=en-US", "https://download-installer.cdn.mozilla.net/pub/firefox/nightly/latest-mozilla-central/firefox-128.0a1.en-US.win32.installer.exe", defaultUA}, @@ -357,116 +321,6 @@ func TestBouncerHandlerPre2024(t *testing.T) { } } -func TestIsWindowsXPUserAgent(t *testing.T) { - uas := []struct { - UA string - IsXP bool - }{ - {"Mozilla/5.0 (Windows NT 5.1; rv:31.0) Gecko/20100101 Firefox/31.0", true}, // firefox XP - {"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:31.0) Gecko/20130401 Firefox/31.0", false}, // firefox non-XP - {"Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2224.3 Safari/537.36", true}, // Chrome XP - {"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2225.0 Safari/537.36", false}, // Chrome non-XP - {"Mozilla/5.0 (Windows; U; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)", true}, // IE XP - {"Mozilla/4.0 (compatible; MSIE 6.1; Windows XP)", true}, // IE XP - {"Mozilla/5.0 (Windows; U; MSIE 7.0; Windows NT 6.0; en-US)", true}, // IE Vista - {"Mozilla/5.0 (Windows; U; MSIE 7.0; Windows NT 6.1; en-US)", false}, // IE non-XP - } - for _, ua := range uas { - assert.Equal(t, ua.IsXP, isWindowsXPUserAgent(ua.UA), "ua: %v", ua.UA) - } -} - -func TestSha1Product(t *testing.T) { - // Ignore products ending with sha1 - assert.Equal(t, "firefox-something-sha1", sha1Product("firefox-something-sha1")) - assert.Equal(t, "firefox-45.0-sha1", sha1Product("firefox-45.0-sha1")) - assert.Equal(t, "firefox-45.0.2-sha1", sha1Product("firefox-45.0.2-sha1")) - assert.Equal(t, "firefox-49.0b1-sha1", sha1Product("firefox-49.0b1-sha1")) - assert.Equal(t, "firefox-49.0b2-sha1", sha1Product("firefox-49.0b2-sha1")) - assert.Equal(t, "firefox-45.0esr-sha1", sha1Product("firefox-45.0esr-sha1")) - assert.Equal(t, "firefox-45.0.2esr-sha1", sha1Product("firefox-45.0.2esr-sha1")) - assert.Equal(t, "firefox-45.1.0esr-sha1", sha1Product("firefox-45.1.0esr-sha1")) - assert.Equal(t, "firefox-45.1.2esr-sha1", sha1Product("firefox-45.1.2esr-sha1")) - - // Ignore partials and completes - assert.Equal(t, "firefox-42.0.0-complete", sha1Product("firefox-42.0.0-complete")) - assert.Equal(t, "firefox-48.0-partial-41.0.2build1", sha1Product("firefox-48.0-partial-41.0.2build1")) - assert.Equal(t, "firefox-43.0.2-complete", sha1Product("firefox-43.0.2-complete")) - assert.Equal(t, "firefox-44.0-complete", sha1Product("firefox-44.0-complete")) - assert.Equal(t, "firefox-45.0b1-complete", sha1Product("firefox-45.0b1-complete")) - assert.Equal(t, "firefox-48.0-partial-42.0b1", sha1Product("firefox-48.0-partial-42.0b1")) - assert.Equal(t, "firefox-48.0b9-partial-48.0b1", sha1Product("firefox-48.0b9-partial-48.0b1")) - - // ignore product wihtout dashes - assert.Equal(t, "firefox", sha1Product("firefox")) - - // Aliases with no version specified - assert.Equal(t, "firefox-sha1", sha1Product("firefox-latest")) - assert.Equal(t, "firefox-sha1", sha1Product("firefox-stub")) - assert.Equal(t, "firefox-sha1", sha1Product("firefox-beta-latest")) - assert.Equal(t, "firefox-sha1", sha1Product("firefox-beta-stub")) - assert.Equal(t, "firefox-sha1", sha1Product("firefox-esr-latest")) - assert.Equal(t, "firefox-sha1", sha1Product("firefox-esr-stub")) - - // Aurora is special a bit - assert.Equal(t, "firefox-sha1", sha1Product("firefox-aurora")) - assert.Equal(t, "firefox-sha1", sha1Product("firefox-aurora-stub")) - - // Beta versions - assert.Equal(t, "firefox-sha1", sha1Product("firefox-48.0b1")) - assert.Equal(t, "firefox-sha1", sha1Product("firefox-49.0b8")) - assert.Equal(t, "firefox-sha1", sha1Product("firefox-48.0b1-stub")) - assert.Equal(t, "firefox-sha1", sha1Product("firefox-49.0b8-stub")) - assert.Equal(t, "firefox-sha1", sha1Product("firefox-48.0b1-ssl")) - assert.Equal(t, "firefox-sha1", sha1Product("firefox-49.0b8-ssl")) - - // ESR - assert.Equal(t, "firefox-sha1", sha1Product("firefox-45.0esr")) - assert.Equal(t, "firefox-sha1", sha1Product("firefox-45.0.1esr")) - assert.Equal(t, "firefox-sha1", sha1Product("firefox-45.3.0esr")) - assert.Equal(t, "firefox-sha1", sha1Product("firefox-45.3.1esr")) - assert.Equal(t, "firefox-sha1", sha1Product("firefox-45.0esr-stub")) - assert.Equal(t, "firefox-sha1", sha1Product("firefox-45.0.1esr-stub")) - assert.Equal(t, "firefox-sha1", sha1Product("firefox-45.3.0esr-stub")) - assert.Equal(t, "firefox-sha1", sha1Product("firefox-45.3.1esr-stub")) - assert.Equal(t, "firefox-sha1", sha1Product("firefox-45.0esr-ssl")) - assert.Equal(t, "firefox-sha1", sha1Product("firefox-45.0.1esr-ssl")) - assert.Equal(t, "firefox-sha1", sha1Product("firefox-45.3.0esr-ssl")) - assert.Equal(t, "firefox-sha1", sha1Product("firefox-45.3.1esr-ssl")) - - // Everything else starting with firefox should go to firefox-sha1 - assert.Equal(t, "firefox-sha1", sha1Product("firefox-42.0.0")) - assert.Equal(t, "firefox-sha1", sha1Product("firefox-48.0")) - assert.Equal(t, "firefox-sha1", sha1Product("firefox-48.0.1")) - assert.Equal(t, "firefox-sha1", sha1Product("firefox-8.0")) - assert.Equal(t, "firefox-sha1", sha1Product("firefox-8.0.4")) - assert.Equal(t, "firefox-sha1", sha1Product("firefox-42.0.0-stub")) - assert.Equal(t, "firefox-sha1", sha1Product("firefox-48.0-stub")) - assert.Equal(t, "firefox-sha1", sha1Product("firefox-48.0.1-stub")) - assert.Equal(t, "firefox-sha1", sha1Product("firefox-8.0-stub")) - assert.Equal(t, "firefox-sha1", sha1Product("firefox-8.0.4-stub")) - assert.Equal(t, "firefox-sha1", sha1Product("firefox-42.0.0-ssl")) - assert.Equal(t, "firefox-sha1", sha1Product("firefox-48.0-ssl")) - assert.Equal(t, "firefox-sha1", sha1Product("firefox-48.0.1-ssl")) - assert.Equal(t, "firefox-sha1", sha1Product("firefox-8.0-ssl")) - assert.Equal(t, "firefox-sha1", sha1Product("firefox-8.0.4-ssl")) - assert.Equal(t, "firefox-sha1", sha1Product("firefox-42.0.0-something-new")) - assert.Equal(t, "firefox-sha1", sha1Product("firefox-48.0-ssl-something-new")) - assert.Equal(t, "firefox-sha1", sha1Product("firefox-48.0.1-ssl-something-new")) - assert.Equal(t, "firefox-sha1", sha1Product("firefox-8.0-something-old")) - assert.Equal(t, "firefox-sha1", sha1Product("firefox-8.0.4-ssl-something-old")) - - assert.Equal(t, "thunderbird-38.5.0", sha1Product("thunderbird-38.6.0")) - assert.Equal(t, "thunderbird-38.5.0", sha1Product("thunderbird-39.0.0")) - - assert.Equal(t, "thunderbird-38.4.0", sha1Product("thunderbird-38.4.0")) - - assert.Equal(t, "thunderbird-43.0b1", sha1Product("thunderbird-43.0b2")) - assert.Equal(t, "thunderbird-43.0b1", sha1Product("thunderbird-44.0b1")) - - assert.Equal(t, "thunderbird-42.0b1", sha1Product("thunderbird-42.0b1")) -} - func TestIsUserAgentOnlyCompatibleWithESR115(t *testing.T) { uas := []struct { UA string @@ -632,13 +486,6 @@ func TestBouncerHandlerForWindowsOnlyCompatibleWithESR115WithMozorgReferrer(t *t assert.Equal(t, expectedLocation, w.HeaderMap.Get("Location")) } -func BenchmarkSha1Product(b *testing.B) { - for i := 0; i < b.N; i++ { - sha1Product("firefox-43.0.0") - sha1Product("firefox-44.0b1") - } -} - func TestHealthHandler(t *testing.T) { testDB, err := bouncer.NewDB(testDSN) if err != nil { diff --git a/main.go b/main.go index 59a781e..d28afab 100644 --- a/main.go +++ b/main.go @@ -65,7 +65,7 @@ func main() { app.RunAndExitOnError() } -func versionHandler(w http.ResponseWriter, req *http.Request) { +func versionHandler(w http.ResponseWriter, _ *http.Request) { versionFile, err := ioutil.ReadFile(versionFilePath) if err != nil { http.Error(w, "Could not read version file.", http.StatusNotFound) @@ -95,7 +95,7 @@ func Main(c *cli.Context) { bouncerHandler := &BouncerHandler{ db: db, CacheTime: time.Duration(c.Int("cache-time")) * time.Second, - PinHttpsHeaderName: c.String("pin-https-header-name"), + PinHTTPSHeaderName: c.String("pin-https-header-name"), PinnedBaseURLHttp: c.String("pinned-baseurl-http"), PinnedBaseURLHttps: c.String("pinned-baseurl-https"), StubRootURL: c.String("stub-root-url"),