From e86beb23d04c85045221c5f5cc856dc5f5af1b5d Mon Sep 17 00:00:00 2001 From: surdeus Date: Wed, 10 Jan 2024 21:19:23 +0300 Subject: [PATCH] feat: added way to serve single files and fixed the redirecting relative path problems. --- api.go | 4 ++++ cmd/test/main.go | 17 +++++++++++------ context.go | 18 +++++++++++++++++- index.html | 10 ++++++++++ path.go | 2 +- root.go | 2 ++ short.go | 2 +- static.go | 14 ++++++++++++-- 8 files changed, 58 insertions(+), 11 deletions(-) create mode 100644 index.html diff --git a/api.go b/api.go index 7a039f2..799c0ee 100644 --- a/api.go +++ b/api.go @@ -16,9 +16,13 @@ func (fn Func) Handle(c *Context) { // The wrapper for the standard http.Handler(s). type Wrap struct { + UseRelUrl bool HttpHandler } func (w Wrap) Handle(c *Context) { + if w.UseRelUrl { + c.R.URL = c.RelUrl + } w.ServeHTTP(c.W, c.R) } diff --git a/cmd/test/main.go b/cmd/test/main.go index fd6bc25..51e3551 100644 --- a/cmd/test/main.go +++ b/cmd/test/main.go @@ -15,14 +15,12 @@ type GetNotesOptions struct { var root = bond.Root(bond.Path(). Def( "", - bond.Func(func(c *bond.Context) { - c.W.Write([]byte("This is the index page")) - }), + bond.StaticFile("index.html"), ).Def( "hello", bond.Path().Def( // Using the relative redirect to force us to the en. - "", bond.Redirect("/hello/en", statuses.SeeOther), + "", bond.Redirect("en", statuses.Found), ).Def( "en", bond.Func(func(c *bond.Context) { c.Printf("Hello, World!") @@ -33,14 +31,21 @@ Def( }), ), ).Def( - "web", bond.Static("./static"), + "google", bond.Redirect("https://google.com", statuses.Found), +).Def( + "web", bond.StaticDir("./static"), ).Def( "test", bond.Func(func(c *bond.Context) { c.SetContentType(contents.Plain) c.Printf( + "AbsPath: %q\n" + + "Prefix: %q\n" + "Path: %q\n"+ "Content-Type: %q\n", - c.Path(), c.ContentType(), + c.AbsPath(), + c.PathPrefix(), + c.Path(), + c.ContentType(), ) c.Printf("Query:\n") for k, vs := range c.Query() { diff --git a/context.go b/context.go index bc37c7b..c5e6426 100644 --- a/context.go +++ b/context.go @@ -11,6 +11,7 @@ import ( type Context struct { R *Request + RelUrl *url.URL W ResponseWriter // Custom data to store stuff. Data any @@ -87,10 +88,20 @@ func (c *Context) ScanErr() error { return c.scanErr } -func (c *Context) Path() string { +func (c *Context) AbsPath() string { return c.R.URL.Path } +func (c *Context) PathPrefix() string { + pth := c.AbsPath() + rpth := c.Path() + return pth[:len(pth)-len(rpth)] +} + +func (c *Context) Path() string { + return c.RelUrl.Path +} + func (c *Context) NotFound() { http.NotFound(c.W, c.R) } @@ -104,5 +115,10 @@ func (c *Context) Query() url.Values { } func (c *Context) Redirect(u string, status Status) { + pth := c.AbsPath() + if len(pth) > 0 && pth[len(pth)-1] != '/' { + pth += "/" + } + c.R.URL.Path = pth http.Redirect(c.W, c.R, u, int(status)) } diff --git a/index.html b/index.html new file mode 100644 index 0000000..5c911a6 --- /dev/null +++ b/index.html @@ -0,0 +1,10 @@ + + + +

+ This is the index page! +

+
English Hello
+
Русский Привет
+
Static files directory
+ diff --git a/path.go b/path.go index baed553..ffdd5c8 100644 --- a/path.go +++ b/path.go @@ -59,7 +59,7 @@ func (router *PathRouter) Handle(c *Context) { return } - c.R.URL.Path = rest + c.RelUrl.Path = rest handler.Handle(c) } diff --git a/root.go b/root.go index 29d02f0..204c146 100644 --- a/root.go +++ b/root.go @@ -23,5 +23,7 @@ func (router *RootRouter) ServeHTTP(w ResponseWriter, r *Request) { ctx := Context{} ctx.W = w ctx.R = r + u := *r.URL + ctx.RelUrl = &u router.handler.Handle(&ctx) } diff --git a/short.go b/short.go index afbdcf8..e505c18 100644 --- a/short.go +++ b/short.go @@ -1,6 +1,6 @@ package bond -type RedirectRouter string +// Returns the handler that redirects to the specified URL (u) func Redirect(u string, status Status) Handler { return Func(func(c *Context){ c.Redirect(u, status) diff --git a/static.go b/static.go index 76961e5..f424d52 100644 --- a/static.go +++ b/static.go @@ -4,7 +4,17 @@ import ( "net/http" ) -func Static(pth string) Handler { - return Wrap{http.FileServer(http.Dir(pth))} +func StaticDir(pth string) Handler { + return Wrap{ + UseRelUrl: true, + HttpHandler: http.FileServer(http.Dir(pth)), + } } +func StaticFile(pth string) Handler { + return Wrap{ + HttpHandler: HttpHandlerFunc(func(w ResponseWriter, r *Request){ + http.ServeFile(w, r, pth) + }), + } +}