main.go (3124B)
1 package main 2 3 import ( 4 "bufio" 5 "fmt" 6 "net/http" 7 "os" 8 "strings" 9 ) 10 11 const ( 12 ListenAddr = "127.0.0.1:8082" 13 ReposFile = "/etc/reprose.txt" 14 Title = "zakaria's golang repo" 15 Host = "go.zakaria.org" 16 DefaultRedirect = "https://git.zakaria.org/" 17 Head = `<meta charset="utf-8"><meta content="width=device-width,initial-scale=1" name="viewport"><style> 18 pre { line-height: calc(100% * 1.1618); font-size: 100% } 19 body { margin: 1rem auto; max-width: 50rem; font-size: 100%; line-height: calc(100% * 1.618) } 20 </style>` 21 ) 22 23 type Repo struct { 24 Git string 25 Http string 26 } 27 28 var Repos map[string]Repo 29 30 func readRepos() error { 31 Repos = make(map[string]Repo) 32 f, err := os.Open(ReposFile) 33 if err != nil { 34 return err 35 } 36 37 scanner := bufio.NewScanner(f) 38 for scanner.Scan() { 39 line := scanner.Text() 40 41 // skip comments 42 if strings.HasPrefix(line, "#") { 43 continue 44 } 45 46 // split on whitespace 47 split := strings.Fields(line) 48 if len(split) < 2 { 49 return fmt.Errorf("error parsing repos file") 50 } 51 52 // if separate http redirect is specified, use it 53 // otherwise, use the git url for redirect 54 if len(split) == 3 { 55 Repos[split[0]] = Repo{split[1], split[2]} 56 } else { 57 Repos[split[0]] = Repo{split[1], split[1]} 58 } 59 } 60 return nil 61 } 62 63 func isGoGet(req *http.Request) bool { 64 q := req.URL.Query() 65 goget := q.Get("go-get") 66 if len(goget) == 0 { 67 return false 68 } 69 if goget == "1" { 70 return true 71 } 72 return false 73 } 74 75 func printRepo(base string, repo Repo) string { 76 return fmt.Sprintf("<a href=\"/%s\" title=\"%s/%s -> %s\">%s/%s</a> ", base, Host, base, repo.Http, Host, base) 77 } 78 79 func main() { 80 readRepos() 81 mux := http.NewServeMux() 82 mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { 83 if req.URL.Path == "/" { 84 w.Header().Set("Content-Type", "text/html; charset=utf-8") 85 fmt.Fprintf(w, "<html><head>") 86 fmt.Fprintf(w, "<title>%s</title>", Title) 87 fmt.Fprintf(w, "%s", Head) 88 fmt.Fprintf(w, "</head><body>") 89 fmt.Fprintf(w, "<pre>%s\n\n", Title) 90 fmt.Fprintf(w, "Packages:\n") 91 for basename, repo := range Repos { 92 fmt.Fprintf(w, "• %s\n", printRepo(basename, repo)) 93 } 94 fmt.Fprintf(w, "</pre>") 95 fmt.Fprintf(w, "</body></html>") 96 97 return 98 } 99 100 for basename, repo := range Repos { 101 if req.URL.Path == "/"+basename { 102 // if go-get header is not present redirect to http 103 if !isGoGet(req) { 104 http.Redirect(w, req, repo.Http, http.StatusPermanentRedirect) 105 return 106 } 107 108 w.Header().Set("Content-Type", "text/html; charset=utf-8") 109 fmt.Fprintf(w, "<html><head>") 110 fmt.Fprintf(w, "<title>%s</title>", basename) 111 fmt.Fprintf(w, "<meta name=\"go-import\" content=\"%s/%s git %s\">", Host, basename, repo.Git) 112 // fmt.Fprintf(w, "<meta name=\"go-source\" content=\"%s/%s _ %s/tree{/dir} %s/tree{/dir}/{file}#n{line}\">", Host, basename, url, url) 113 fmt.Fprintf(w, "</head>") 114 fmt.Fprintf(w, "<body>go get %s/%s</body>", Host, basename) 115 fmt.Fprintf(w, "</html>") 116 return 117 } 118 } 119 }) 120 http.ListenAndServe(ListenAddr, mux) 121 }