func main() { if os.Getenv("ACCESS_TOKEN") == "" { log.Fatal("ACCESS_TOKEN was not found. Read http://progrium.viewdocs.io/viewdocs/development/ for more info") } port := getenv("PORT", "8888") doNotCache := getenv("USE_CACHE", "true") == "false" lru := cache.NewLRUCache(CacheCapacity) resp, err := http.Get("https://raw.github.com/progrium/viewdocs/master/docs/template.html") if err != nil || resp.StatusCode == 404 { log.Fatal("Unable to fetch default template") } body, err := ioutil.ReadAll(resp.Body) resp.Body.Close() if err != nil { log.Fatal(err) } DefaultTemplate = string(body) http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { if r.RequestURI == "/favicon.ico" { return } switch r.Method { case "GET": user, repo, ref, doc := parseRequest(r) redirected := handleRedirects(w, r, user, repo, ref, doc) if redirected { return } log.Printf("Building docs for '%s/%s' (ref: %s)", user, repo, ref) key := user + ":" + repo + ":" + doc + ":" + ref value, ok := lru.Get(key) var output string if !ok || doNotCache { output, err = fetchAndRenderDoc(user, repo, ref, doc) if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) return } lru.Set(key, &CacheValue{output, time.Now().Unix()}) log.Println("CACHE MISS:", key, lru.StatsJSON()) } else { output = value.(*CacheValue).Value if time.Now().Unix()-value.(*CacheValue).CreatedAt > CacheTTL { lru.Delete(key) } } w.Write([]byte(output)) default: w.WriteHeader(http.StatusMethodNotAllowed) } }) log.Println("Listening on port " + port) log.Fatal(http.ListenAndServe(":"+port, nil)) }
func main() { if getenv("ACCESS_TOKEN", "") == "" { log.Fatal("ACCESS_TOKEN was not found. Read http://progrium.viewdocs.io/viewdocs/development/ for more info") } port := getenv("PORT", "8888") lru := cache.NewLRUCache(CacheCapacity) resp, err := http.Get("https://raw.github.com/progrium/viewdocs/master/docs/template.html") if err != nil || resp.StatusCode == 404 { log.Fatal("Unable to fetch default template") } body, err := ioutil.ReadAll(resp.Body) resp.Body.Close() if err != nil { log.Fatal(err) } DefaultTemplate = string(body) http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { if r.RequestURI == "/favicon.ico" { return } switch r.Method { case "GET": user, repo, ref, doc := parseRequest(r) config, _ := getRepositoryConfig(lru, user, repo, ref) redirected := handleRedirects(w, r, config, user, repo, ref, doc) if redirected { return } log.Printf("Building docs for '%s/%s' (ref: %s)", user, repo, ref) key := user + ":" + repo + ":" + doc + ":" + ref output, err := cacheKey(lru, key, func() (string, error) { return fetchAndRenderDoc(user, repo, ref, doc) }) if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) return } w.Write([]byte(output)) default: w.WriteHeader(http.StatusMethodNotAllowed) } }) log.Println("Listening on port " + port) log.Fatal(http.ListenAndServe(":"+port, nil)) }