From e1aa19f1e8c4a68b43add79374d6dfeae8bd9921 Mon Sep 17 00:00:00 2001 From: tjpcc Date: Thu, 19 Jan 2023 16:03:52 -0700 Subject: New sharedhost contrib package. ReplaceTilde simply replaces a leading ~ in the URL. Fixes #9. --- contrib/sharedhost/replacement.go | 46 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 contrib/sharedhost/replacement.go (limited to 'contrib/sharedhost/replacement.go') diff --git a/contrib/sharedhost/replacement.go b/contrib/sharedhost/replacement.go new file mode 100644 index 0000000..1fb2a0d --- /dev/null +++ b/contrib/sharedhost/replacement.go @@ -0,0 +1,46 @@ +package sharedhost + +import ( + "context" + "crypto/tls" + "net/url" + + "tildegit.org/tjp/gus" +) + +// ReplaceTilde builds a middleware which substitutes a leading '~' in the request path. +// +// It makes the alteration to a copy of the request which is then passed into the +// wrapped Handler. This way middlewares outside of this one inspecting the request +// afterwards will see the original URL. +// +// Typically the replacement should end with a "/", so that the ~ ends up mapping to a +// particular directory on the filesystem. For instance with a replacement string of +// "users/", "domain.com/~jim/index.gmi" maps to "domain.com/users/jim/index.gmi". +func ReplaceTilde(replacement string) gus.Middleware { + return func(inner gus.Handler) gus.Handler { + return func(ctx context.Context, request *gus.Request) *gus.Response { + if len(request.Path) > 1 && request.Path[0] == '/' && request.Path[1] == '~' { + request = cloneRequest(request) + request.Path = "/" + replacement + request.Path[2:] + } + + return inner(ctx, request) + } + } +} + +func cloneRequest(start *gus.Request) *gus.Request { + next := &gus.Request{} + *next = *start + + next.URL = &url.URL{} + *next.URL = *start.URL + + if start.TLSState != nil { + next.TLSState = &tls.ConnectionState{} + *next.TLSState = *start.TLSState + } + + return next +} -- cgit v1.2.3