web.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. package web
  2. import (
  3. "bytes"
  4. "fmt"
  5. "log"
  6. "net/http"
  7. "github.com/kellegous/go/context"
  8. "github.com/syndtr/goleveldb/leveldb"
  9. )
  10. // Serve a bundled asset over HTTP.
  11. func serveAsset(w http.ResponseWriter, r *http.Request, name string) {
  12. n, err := AssetInfo(name)
  13. if err != nil {
  14. http.NotFound(w, r)
  15. return
  16. }
  17. a, err := Asset(name)
  18. if err != nil {
  19. http.NotFound(w, r)
  20. return
  21. }
  22. http.ServeContent(w, r, n.Name(), n.ModTime(), bytes.NewReader(a))
  23. }
  24. // The default handler responds to most requests. It is responsible for the
  25. // shortcut redirects and for sending unmapped shortcuts to the edit page.
  26. func getDefault(ctx *context.Context, w http.ResponseWriter, r *http.Request) {
  27. p := parseName("/", r.URL.Path)
  28. if p == "" {
  29. http.Redirect(w, r, "/edit/", http.StatusTemporaryRedirect)
  30. return
  31. }
  32. rt, err := ctx.Get(p)
  33. if err == leveldb.ErrNotFound {
  34. http.Redirect(w, r,
  35. fmt.Sprintf("/edit/%s", cleanName(p)),
  36. http.StatusTemporaryRedirect)
  37. return
  38. } else if err != nil {
  39. log.Panic(err)
  40. }
  41. http.Redirect(w, r,
  42. rt.URL,
  43. http.StatusTemporaryRedirect)
  44. }
  45. // ListenAndServe sets up all web routes, binds the port and handles incoming
  46. // web requests.
  47. func ListenAndServe(addr string, admin bool, version string, ctx *context.Context) error {
  48. mux := http.NewServeMux()
  49. mux.HandleFunc("/api/url/", func(w http.ResponseWriter, r *http.Request) {
  50. apiURL(ctx, w, r)
  51. })
  52. mux.HandleFunc("/api/urls/", func(w http.ResponseWriter, r *http.Request) {
  53. apiURLs(ctx, w, r)
  54. })
  55. mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
  56. getDefault(ctx, w, r)
  57. })
  58. mux.HandleFunc("/edit/", func(w http.ResponseWriter, r *http.Request) {
  59. serveAsset(w, r, "index.html")
  60. })
  61. mux.HandleFunc("/s/", func(w http.ResponseWriter, r *http.Request) {
  62. serveAsset(w, r, r.URL.Path[len("/s/"):])
  63. })
  64. mux.HandleFunc("/:version", func(w http.ResponseWriter, r *http.Request) {
  65. fmt.Fprintln(w, version)
  66. })
  67. mux.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
  68. fmt.Fprintln(w, "OK")
  69. })
  70. if admin {
  71. mux.Handle("/admin/", &adminHandler{ctx})
  72. }
  73. return http.ListenAndServe(addr, mux)
  74. }