diff options
author | Jesse Hallam <jesse.hallam@gmail.com> | 2018-06-21 14:31:51 -0400 |
---|---|---|
committer | Christopher Speller <crspeller@gmail.com> | 2018-06-21 11:31:51 -0700 |
commit | dd35ad43caab407cc70ef3b153b3f94d57242ed9 (patch) | |
tree | 67afe0fb6ad784e740d8b2a99d5de5c04342661c /app | |
parent | 46f969e5ddbe4404dbc82dbe78ab2fa101d9922e (diff) | |
download | chat-dd35ad43caab407cc70ef3b153b3f94d57242ed9.tar.gz chat-dd35ad43caab407cc70ef3b153b3f94d57242ed9.tar.bz2 chat-dd35ad43caab407cc70ef3b153b3f94d57242ed9.zip |
MM-10370: serve subpath (#8968)
* factor out GetSubpathFromConfig
* mv web/subpath.go to utils/subpath.go
* serve up web, api and ws on /subpath if configured
* pass config to utils.RenderWeb(App)?Error
This allows the methods to extract the configured subpath and redirect
to the appropriate `/subpath/error` handler.
* ensure GetSubpathFromConfig returns trailing slashes deterministically
* fix error 404 handling
* redirect /subpath to /subpath/
This is necessary for the static handler to match, otherwise none of the
registered routes find anything. This also makes it no longer necessary
to add trailing slashes in the root router.
Diffstat (limited to 'app')
-rw-r--r-- | app/app.go | 22 | ||||
-rw-r--r-- | app/server.go | 17 |
2 files changed, 31 insertions, 8 deletions
diff --git a/app/app.go b/app/app.go index 3f70974cf..2041a24fe 100644 --- a/app/app.go +++ b/app/app.go @@ -9,6 +9,7 @@ import ( "html/template" "net" "net/http" + "path" "reflect" "strings" "sync" @@ -108,10 +109,12 @@ func New(options ...Option) (outApp *App, outErr error) { panic("Only one App should exist at a time. Did you forget to call Shutdown()?") } + rootRouter := mux.NewRouter() + app := &App{ goroutineExitSignal: make(chan struct{}, 1), Srv: &Server{ - Router: mux.NewRouter(), + RootRouter: rootRouter, }, sessionCache: utils.NewLru(model.SESSION_CACHE_SIZE), configFile: "config.json", @@ -206,10 +209,21 @@ func New(options ...Option) (outApp *App, outErr error) { app.initJobs() - app.initBuiltInPlugins() + subpath, err := utils.GetSubpathFromConfig(app.Config()) + if err != nil { + return nil, errors.Wrap(err, "failed to parse SiteURL subpath") + } + app.Srv.Router = app.Srv.RootRouter.PathPrefix(subpath).Subrouter() app.Srv.Router.HandleFunc("/plugins/{plugin_id:[A-Za-z0-9\\_\\-\\.]+}", app.ServePluginRequest) app.Srv.Router.HandleFunc("/plugins/{plugin_id:[A-Za-z0-9\\_\\-\\.]+}/{anything:.*}", app.ServePluginRequest) + // If configured with a subpath, redirect 404s at the root back into the subpath. + if subpath != "/" { + app.Srv.RootRouter.NotFoundHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + r.URL.Path = path.Join(subpath, r.URL.Path) + http.Redirect(w, r, r.URL.String(), http.StatusFound) + }) + } app.Srv.Router.NotFoundHandler = http.HandlerFunc(app.Handle404) app.Srv.WebSocketRouter = &WebSocketRouter{ @@ -217,6 +231,8 @@ func New(options ...Option) (outApp *App, outErr error) { handlers: make(map[string]webSocketHandler), } + app.initBuiltInPlugins() + return app, nil } @@ -510,7 +526,7 @@ func (a *App) Handle404(w http.ResponseWriter, r *http.Request) { mlog.Debug(fmt.Sprintf("%v: code=404 ip=%v", r.URL.Path, utils.GetIpAddress(r))) - utils.RenderWebAppError(w, r, err, a.AsymmetricSigningKey()) + utils.RenderWebAppError(a.Config(), w, r, err, a.AsymmetricSigningKey()) } // This function migrates the default built in roles from code/config to the database. diff --git a/app/server.go b/app/server.go index 7d229201d..d71a884d2 100644 --- a/app/server.go +++ b/app/server.go @@ -29,10 +29,17 @@ import ( type Server struct { Store store.Store WebSocketRouter *WebSocketRouter - Router *mux.Router - Server *http.Server - ListenAddr *net.TCPAddr - RateLimiter *RateLimiter + + // RootRouter is the starting point for all HTTP requests to the server. + RootRouter *mux.Router + + // Router is the starting point for all web, api4 and ws requests to the server. It differs + // from RootRouter only if the SiteURL contains a /subpath. + Router *mux.Router + + Server *http.Server + ListenAddr *net.TCPAddr + RateLimiter *RateLimiter didFinishListen chan struct{} } @@ -99,7 +106,7 @@ func redirectHTTPToHTTPS(w http.ResponseWriter, r *http.Request) { func (a *App) StartServer() error { mlog.Info("Starting Server...") - var handler http.Handler = &CorsWrapper{a.Config, a.Srv.Router} + var handler http.Handler = &CorsWrapper{a.Config, a.Srv.RootRouter} if *a.Config().RateLimitSettings.Enable { mlog.Info("RateLimiter is enabled") |