1 // Copyright 2017 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // Command server serves get.golang.org, redirecting users to the appropriate
6 // getgo installer based on the request path.
18 base = "https://dl.google.com/go/getgo/"
19 windowsInstaller = base + "installer.exe"
20 linuxInstaller = base + "installer_linux"
21 macInstaller = base + "installer_darwin"
24 // substring-based redirects.
25 var stringMatch = map[string]string{
26 // via uname, from bash
27 "MINGW": windowsInstaller, // Reported as MINGW64_NT-10.0 in git bash
28 "Linux": linuxInstaller,
29 "Darwin": macInstaller,
33 http.HandleFunc("/", handler)
35 port := os.Getenv("PORT")
38 fmt.Printf("Defaulting to port %s", port)
41 fmt.Printf("Listening on port %s", port)
42 if err := http.ListenAndServe(fmt.Sprintf(":%s", port), nil); err != nil {
43 fmt.Fprintf(os.Stderr, "http.ListenAndServe: %v", err)
47 func handler(w http.ResponseWriter, r *http.Request) {
48 if containsIgnoreCase(r.URL.Path, "installer.exe") {
50 http.Redirect(w, r, windowsInstaller+cacheBust(), http.StatusFound)
54 for match, redirect := range stringMatch {
55 if containsIgnoreCase(r.URL.Path, match) {
56 http.Redirect(w, r, redirect, http.StatusFound)
64 func containsIgnoreCase(s, substr string) bool {
65 return strings.Contains(
67 strings.ToLower(substr),
71 func cacheBust() string {
72 return fmt.Sprintf("?%d", time.Now().Nanosecond())