浏览代码

Remove useless API config, Web setup parameters. Assets no longer need /public/.

Frederic G. MARAND 6 年之前
父节点
当前提交
747196b58f
共有 3 个文件被更改,包括 34 次插入25 次删除
  1. 1 3
      cmd/kurzd/dist.config.yml
  2. 10 13
      cmd/kurzd/serve.go
  3. 23 9
      web/web.go

+ 1 - 3
cmd/kurzd/dist.config.yml

@@ -1,5 +1,3 @@
-api:
-  listenAddress: ":8000"
 database:
 database:
   # Code likely not to work on another engine because it adds ?parseTime=true
   # Code likely not to work on another engine because it adds ?parseTime=true
   driver: mysql
   driver: mysql
@@ -16,5 +14,5 @@ web:
   # Used to build absolute URLs.
   # Used to build absolute URLs.
   siteBaseURL: &sbu http://localhost:3000
   siteBaseURL: &sbu http://localhost:3000
   siteName: "Kurz"
   siteName: "Kurz"
-  # Lines needs to be below siteBaseURL for the YAML reference to work.
+  # Config line needs to be below siteBaseURL for the YAML reference to work.
   assetsBaseURL: *sbu
   assetsBaseURL: *sbu

+ 10 - 13
cmd/kurzd/serve.go

@@ -3,7 +3,6 @@ package main
 import (
 import (
 	"context"
 	"context"
 	"database/sql"
 	"database/sql"
-	"fmt"
 	"log"
 	"log"
 	"net/http"
 	"net/http"
 	"os"
 	"os"
@@ -69,38 +68,36 @@ func serveHandler(_ *cobra.Command, args []string) {
 	if err != nil {
 	if err != nil {
 		panic(err)
 		panic(err)
 	}
 	}
-	fmt.Printf("Server initializing in %s\n", cwd)
+	log.Printf("Server initializing in %s\n", cwd)
 
 
+	// Set up globals from configuration, providing a few defaults.
+	siteBaseURL := viper.Get("web.siteBaseUrl").(string)
 	// This default is the relative position of the assets from the project root during development.
 	// This default is the relative position of the assets from the project root during development.
 	viper.SetDefault("web.assetsPath", "web/public")
 	viper.SetDefault("web.assetsPath", "web/public")
 	assetsPath := viper.Get("web.assetsPath").(string)
 	assetsPath := viper.Get("web.assetsPath").(string)
-
-	siteBaseURL := viper.Get("web.siteBaseUrl").(string)
-
-	viper.SetDefault("web.assetsBaseURL", siteBaseURL)
-	assetsBaseURL := viper.Get("web.assetsBaseUrl").(string)
-
 	webConfig := viper.Get("web").(map[string]interface{})
 	webConfig := viper.Get("web").(map[string]interface{})
+	web.SetupGlobals(webConfig)
+
+	// Set up Web API and UI routes.
 	router := mux.NewRouter()
 	router := mux.NewRouter()
 	api.SetupRoutes(router)
 	api.SetupRoutes(router)
-	web.SetupRoutes(router, siteBaseURL, assetsBaseURL, assetsPath)
-	web.BuildGlobals(webConfig)
+	web.SetupUI(router, assetsPath)
 	http.Handle("/", router)
 	http.Handle("/", router)
 
 
-	listenAddress := viper.Get("web.listenAddress").(string)
-
 	// Start a server that can handle a SIGINT to shutdown.
 	// Start a server that can handle a SIGINT to shutdown.
 	stop := make(chan os.Signal, 1)
 	stop := make(chan os.Signal, 1)
 	signal.Notify(stop, os.Interrupt)
 	signal.Notify(stop, os.Interrupt)
 
 
+	listenAddress := viper.Get("web.listenAddress").(string)
 	server := &http.Server{Addr: listenAddress, Handler: router}
 	server := &http.Server{Addr: listenAddress, Handler: router}
 	go func() {
 	go func() {
-		log.Printf("Listening on %s, exposed on %s", listenAddress, siteBaseURL)
+		log.Printf("Listening on %s, exposed as %s", listenAddress, siteBaseURL)
 		err := server.ListenAndServe()
 		err := server.ListenAndServe()
 		log.Fatal(err)
 		log.Fatal(err)
 	}()
 	}()
 	<-stop
 	<-stop
 
 
+	// Shutdown cleanly.
 	log.Println("Shutting down server")
 	log.Println("Shutting down server")
 	ctx, _ := context.WithTimeout(context.Background(), 1*time.Second)
 	ctx, _ := context.WithTimeout(context.Background(), 1*time.Second)
 	server.Shutdown(ctx)
 	server.Shutdown(ctx)

+ 23 - 9
web/web.go

@@ -1,7 +1,7 @@
 /*
 /*
 The Kurz Web UI exposes HTTP routes for browsers, route names to access them, and types for the requests.
 The Kurz Web UI exposes HTTP routes for browsers, route names to access them, and types for the requests.
 
 
-These routes are exposed by running SetupRoutes(listenAddress), which is enough to
+These routes are exposed by running SetupUI(listenAddress), which is enough to
 configure the Kurz domain API. Be sure to also configure the domain SPI to have
 configure the Kurz domain API. Be sure to also configure the domain SPI to have
 a complete application.
 a complete application.
 */
 */
@@ -9,13 +9,14 @@ package web
 
 
 import (
 import (
 	"errors"
 	"errors"
-	"fmt"
 	"github.com/gorilla/mux"
 	"github.com/gorilla/mux"
 	"html/template"
 	"html/template"
+	"log"
 	"net/http"
 	"net/http"
 	"net/url"
 	"net/url"
 	"path"
 	"path"
 	"path/filepath"
 	"path/filepath"
+	"strconv"
 )
 )
 
 
 // Route names.
 // Route names.
@@ -46,17 +47,28 @@ type Globals struct {
 var globals Globals
 var globals Globals
 var tmpl *template.Template
 var tmpl *template.Template
 
 
-// SetupRoutes() configures Web UI routes on the passed mux.Router.
-func SetupRoutes(router *mux.Router, configSiteBaseURL, configAssetsBaseURL, configAssetsPath string) {
-	const assetsPrefix = "/public"
+// SetupUI() configures Web UI routes on the passed mux.Router.
+func SetupUI(router *mux.Router, configAssetsPath string) {
+	// Set up asset routes first, for them to have priority over possibly matching short URLs.
+	setupAssetRoutes(configAssetsPath, router)
+	setupControllerRoutes(router)
+	setupTemplates(configAssetsPath)
+}
+
+func setupAssetRoutes(configAssetsPath string, router *mux.Router) {
 	absAssetsDir, err := filepath.Abs(configAssetsPath)
 	absAssetsDir, err := filepath.Abs(configAssetsPath)
 	if err != nil {
 	if err != nil {
 		panic(err)
 		panic(err)
 	}
 	}
+	log.Printf("Serving assets from %s\n", absAssetsDir)
 	fs := http.FileServer(http.Dir(absAssetsDir))
 	fs := http.FileServer(http.Dir(absAssetsDir))
-	router.PathPrefix(assetsPrefix).Handler(http.StripPrefix(assetsPrefix, fs))
 	router.Handle("/favicon.ico", fs)
 	router.Handle("/favicon.ico", fs)
+	for _, prefix := range []string{"css", "js", "images"} {
+		router.PathPrefix("/" + prefix).Handler(fs)
+	}
+}
 
 
+func setupControllerRoutes(router *mux.Router) {
 	// BUG(fgm): improve Accept header matchers once https://github.com/golang/go/issues/19307 is completed.
 	// BUG(fgm): improve Accept header matchers once https://github.com/golang/go/issues/19307 is completed.
 	router.HandleFunc("/{short}", func(w http.ResponseWriter, r *http.Request) {
 	router.HandleFunc("/{short}", func(w http.ResponseWriter, r *http.Request) {
 		handleGetShort(w, r, router)
 		handleGetShort(w, r, router)
@@ -71,7 +83,9 @@ func SetupRoutes(router *mux.Router, configSiteBaseURL, configAssetsBaseURL, con
 	router.HandleFunc("/", handleGetRoot).
 	router.HandleFunc("/", handleGetRoot).
 		Methods("GET", "HEAD").
 		Methods("GET", "HEAD").
 		Name(RouteGetRoot)
 		Name(RouteGetRoot)
+}
 
 
+func setupTemplates(configAssetsPath string) {
 	base, _ := filepath.Abs(configAssetsPath + "/../templates/")
 	base, _ := filepath.Abs(configAssetsPath + "/../templates/")
 	layout := base + "/layout"
 	layout := base + "/layout"
 	funcMap := template.FuncMap{
 	funcMap := template.FuncMap{
@@ -89,7 +103,7 @@ func SetupRoutes(router *mux.Router, configSiteBaseURL, configAssetsBaseURL, con
 		))
 		))
 }
 }
 
 
-func BuildGlobals(c map[string]interface{}) {
+func SetupGlobals(c map[string]interface{}) {
 	// Note: keys in viper are lower-cased.
 	// Note: keys in viper are lower-cased.
 	globals = Globals{
 	globals = Globals{
 		AssetsBaseURL: c["assetsbaseurl"].(string),
 		AssetsBaseURL: c["assetsbaseurl"].(string),
@@ -132,10 +146,10 @@ func URLForAsset(ns string, assetPath string) (string, error) {
 		panic(err)
 		panic(err)
 	}
 	}
 	// Handles "" cleanly, and doesn't use a "\" on windows, unlike filepath.Join.
 	// Handles "" cleanly, and doesn't use a "\" on windows, unlike filepath.Join.
-	base.Path = path.Join(ns, assetPath)
+	base.Path = path.Join(base.Path, ns, assetPath)
 
 
 	// No need to url.QueryEscape() since this format is query-clean by construction.
 	// No need to url.QueryEscape() since this format is query-clean by construction.
-	base.RawQuery = fmt.Sprintf("v=%d", version)
+	base.RawQuery = "v=" + strconv.Itoa(version)
 
 
 	res := base.String()
 	res := base.String()
 	return res, nil
 	return res, nil