web.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /*
  2. The Kurz Web UI exposes HTTP routes for browsers, route names to access them, and types for the requests.
  3. These routes are exposed by running SetupRoutes(listenAddress), which is enough to
  4. configure the Kurz domain API. Be sure to also configure the domain SPI to have
  5. a complete application.
  6. */
  7. package web
  8. import (
  9. "html/template"
  10. "net/http"
  11. "net/url"
  12. "path/filepath"
  13. "github.com/gorilla/mux"
  14. )
  15. // Route names.
  16. const (
  17. RouteGetRoot = "kurz.web.get_root"
  18. RouteGetShort = "kurz.web.get_short"
  19. RoutePostTarget = "kurz.web.post_target"
  20. )
  21. // Content types.
  22. const (
  23. // HtmlType is the MIME HTML type.
  24. HtmlType = "text/html"
  25. // HtmlTypeRegex is a regex matching the MIME HTML type anywhere
  26. HtmlTypeRegex = HtmlType
  27. )
  28. type Globals struct {
  29. AssetsBaseURL string
  30. AssetsVersion int
  31. AssetsPath string
  32. SiteBaseURL string
  33. RefreshDelay int
  34. SiteName string
  35. }
  36. var globals Globals
  37. var tmpl *template.Template
  38. // SetupRoutes() configures Web UI routes on the passed mux.Router.
  39. func SetupRoutes(router *mux.Router, configSiteBaseURL, configAssetsBaseURL, configAssetsPath string) {
  40. const assetsPrefix = "/public"
  41. absAssetsDir, err := filepath.Abs(configAssetsPath)
  42. if err != nil {
  43. panic(err)
  44. }
  45. fs := http.FileServer(http.Dir(absAssetsDir))
  46. router.PathPrefix(assetsPrefix).Handler(http.StripPrefix(assetsPrefix, fs))
  47. router.Handle("/favicon.ico", fs)
  48. // BUG(fgm): improve Accept header matchers once https://github.com/golang/go/issues/19307 is completed.
  49. router.HandleFunc("/{short}", func(w http.ResponseWriter, r *http.Request) {
  50. handleGetShort(w, r, router)
  51. }).
  52. Methods("GET", "HEAD").
  53. Name(RouteGetShort)
  54. router.HandleFunc("/", handlePostTarget).
  55. HeadersRegexp("Accept", HtmlTypeRegex).
  56. Headers("Content-Type", HtmlType).
  57. Methods("POST").
  58. Name(RoutePostTarget)
  59. router.HandleFunc("/", handleGetRoot).
  60. Methods("GET", "HEAD").
  61. Name(RouteGetRoot)
  62. base, _ := filepath.Abs(configAssetsPath + "/../templates/")
  63. layout := base + "/layout"
  64. tmpl = template.Must(template.ParseFiles(
  65. base+"/201.gohtml",
  66. base+"/404.gohtml",
  67. base+"/home.gohtml",
  68. layout+"/analytics.gohtml",
  69. layout+"/footer.gohtml",
  70. layout+"/inlinecss.gohtml",
  71. ))
  72. }
  73. func BuildGlobals(c map[string]interface{}) {
  74. // Note: keys in viper are lower-cased.
  75. globals = Globals{
  76. AssetsBaseURL: c["assetsbaseurl"].(string),
  77. AssetsPath: c["assetspath"].(string),
  78. AssetsVersion: c["assetsversion"].(int),
  79. RefreshDelay: c["refreshdelay"].(int),
  80. SiteBaseURL: c["sitebaseurl"].(string),
  81. SiteName: c["sitename"].(string),
  82. }
  83. }
  84. /*
  85. URLFromRoute generates absolute URLs for named routes.
  86. To build URLs for assets, use URLForAsset().
  87. - ns: the assets namespace. One of "js", "css', "images".
  88. - path: the asset path relative to the project root
  89. */
  90. func URLFromRoute(router mux.Router, name string, params map[string]string) string {
  91. return ""
  92. }
  93. /*
  94. URLFromRoute generates absolute URLs for assets.
  95. To build URLs for routes, use URLFromRoute().
  96. - ns: the assets namespace. One of "js", "css', "images".
  97. - path: the asset path relative to the project root
  98. */
  99. func URLForAsset(ns string, path string) string {
  100. base, err := url.Parse(globals.AssetsBaseURL)
  101. if err != nil {
  102. panic(err)
  103. }
  104. base.Path = path
  105. res := base.String()
  106. return res
  107. }