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. 4 5// Command server serves get.golang.org, redirecting users to the appropriate 6// getgo installer based on the request path. 7package main 8 9import ( 10 "fmt" 11 "net/http" 12 "os" 13 "strings" 14 "time" 15) 16 17const ( 18 base = "https://dl.google.com/go/getgo/" 19 windowsInstaller = base + "installer.exe" 20 linuxInstaller = base + "installer_linux" 21 macInstaller = base + "installer_darwin" 22) 23 24// substring-based redirects. 25var 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, 30} 31 32func main() { 33 http.HandleFunc("/", handler) 34 35 port := os.Getenv("PORT") 36 if port == "" { 37 port = "8080" 38 fmt.Printf("Defaulting to port %s", port) 39 } 40 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) 44 } 45} 46 47func handler(w http.ResponseWriter, r *http.Request) { 48 if containsIgnoreCase(r.URL.Path, "installer.exe") { 49 // cache bust 50 http.Redirect(w, r, windowsInstaller+cacheBust(), http.StatusFound) 51 return 52 } 53 54 for match, redirect := range stringMatch { 55 if containsIgnoreCase(r.URL.Path, match) { 56 http.Redirect(w, r, redirect, http.StatusFound) 57 return 58 } 59 } 60 61 http.NotFound(w, r) 62} 63 64func containsIgnoreCase(s, substr string) bool { 65 return strings.Contains( 66 strings.ToLower(s), 67 strings.ToLower(substr), 68 ) 69} 70 71func cacheBust() string { 72 return fmt.Sprintf("?%d", time.Now().Nanosecond()) 73} 74