~emersion/public-inbox

This thread contains a patchset. You're looking at the original emails, but you may wish to use the patch review UI. Review patch
3 3

[PATCH kimchi v2] allow wildcard sites

Details
Message ID
<20201121013617.50735-1-slowjo@halmen.xyz>
DKIM signature
missing
Download raw message
Patch: +33 -1
closes: https://todo.sr.ht/~emersion/kimchi/14
---
This might not be the way you want this implemented, but with my limited
testing it seems to work.
v2 because i seem to have messed something up the first time around.

 directives.go | 34 +++++++++++++++++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/directives.go b/directives.go
index 96b153c..d56d42b 100644
--- a/directives.go
+++ b/directives.go
@@ -44,6 +44,11 @@ func parseConfig(srv *Server, cfg scfg.Block) error {

func parseSite(srv *Server, dir *scfg.Directive) error {
	for _, uriStr := range dir.Params {
		var wild bool
		if strings.Contains(uriStr, "*.") {
			uriStr = strings.Replace(uriStr, "*.", "", 1)
			wild = true
		}
		if !strings.Contains(uriStr, "//") {
			uriStr = "//" + uriStr
		}
@@ -114,11 +119,38 @@ func parseSite(srv *Server, dir *scfg.Directive) error {
			}
		}

		ln.Mux.Handle(pattern, handler)
		if wild {
			wildcard.Handle(ln, host, handler)
		} else {
			ln.Mux.Handle(pattern, handler)
		}
	}
	return nil
}

type wildcardHandler map[string]http.Handler

func (w wildcardHandler) Handle(ln *Listener, host string, handler http.Handler) {
	if len(w) == 0 {
		ln.Mux.Handle("/", w)
	}
	w[host] = handler
}

func (w wildcardHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
	if host, _, err := net.SplitHostPort(req.Host); err == nil {
		for pattern, handler := range w {
			if strings.HasSuffix(host, "." + pattern) {
				handler.ServeHTTP(rw, req)
				return
			}
		}
	}
	http.NotFound(rw, req)
}

var wildcard = wildcardHandler{}

type parseBackendFunc func(dir *scfg.Directive) (http.Handler, error)

var backends = map[string]parseBackendFunc{
-- 
2.29.2
Details
Message ID
<hfhnK4LD8iB7xH74lOris2CXgHDPz3OmPuMNqiZXwPuN7JSr1g6XljqaqluVGtZ96qaoIYNSADvowj2NsSuFYTx4ImDIg65suWb7RbuZPRE=@emersion.fr>
In-Reply-To
<20201121013617.50735-1-slowjo@halmen.xyz> (view parent)
DKIM signature
fail
Download raw message
DKIM signature: fail
> This might not be the way you want this implemented, but with my limited
> testing it seems to work.

Thanks for working on this, definitely something I'd like to get
merged.

Does this patch work? New entries get added to wildcard, but I don't
see where wildcard.ServeHTTP is called from?

Although I'd prefer to have your wildcardHandler handle all of the
host dispatching, ie. it would handle both wildcard and non-wildcard.
It would check for the Host header, then dispatch to the correct
http.Handler.

This would remove the need for a global variable, and probably handle
priorities better (by always trying to match a handler for
foo.example.org first, then fallback to *.example.org).
Details
Message ID
<C7BKETEP2WBD.3NTL8A7WJ2LA2@len>
In-Reply-To
<hfhnK4LD8iB7xH74lOris2CXgHDPz3OmPuMNqiZXwPuN7JSr1g6XljqaqluVGtZ96qaoIYNSADvowj2NsSuFYTx4ImDIg65suWb7RbuZPRE=@emersion.fr> (view parent)
DKIM signature
missing
Download raw message
On Tue Nov 24, 2020 at 2:07 PM CET, Simon Ser wrote:
> > This might not be the way you want this implemented, but with my limited
> > testing it seems to work.
>
> Thanks for working on this, definitely something I'd like to get
> merged.
>
> Does this patch work? New entries get added to wildcard, but I don't
> see where wildcard.ServeHTTP is called from?

I have not done extensive testing[0], but it does work.

The first time the wildcardHandler gets called, it adds itself to the
Listener.Mux with the matching pattern set to "/" in order to match
anything not specifically registered with the ServeMux already.

> (by always trying to match a handler for
> foo.example.org first, then fallback to *.example.org).

This is therefore already true for the current implementation.
A specifically registered foo.example.org will be found by the Mux and
called directly, a bar.example.org will be handled by the wildcard if it
has no own directive.

> Although I'd prefer to have your wildcardHandler handle all of the
> host dispatching, ie. it would handle both wildcard and non-wildcard.

I have thought of this as well, but not being proficient in Go I don't
yet know how to do this without reimplementing all of the ServeMux
logic.

> This would remove the need for a global variable

I agree that this is not a pretty solution. It currently also depends on
the listener always being the same one, as it only registers itself with
the first listener. Through my testing this seems to have always been
the case and created no problems. This might however change as kimchi
gains new features.


If you have any pointers on how to fix this properly, I'd be glad to
take another swing at it. Learning a new language is more fun if the
work is somewhat productive as well.


[0]: testing consisted of the following config file directives:
```
site http+insecure://*.what.local:8081 {
    file_server ../
    basic_auth why tho
}

site http+insecure://*.wow.local:8081 {
    file_server ../arbeit/mobrost/Dokumentation/_build/html/
    basic_auth wow yea
}
```

and the following lines added to /etc/hosts
```
127.0.0.1	what.local
127.0.0.1	who.what.local
127.0.0.1	where.what.local

127.0.0.1	wow.local
127.0.0.1	who.wow.local
127.0.0.1	where.wow.local
```

I tested that `what.local` and `wow.local` would return a 404, while
both `{who,where}.what.local` would point to the `../index.html` file,
and the `{who,where}.wow.local` would return the
`../arbeit/[..]/html/index.html`.
This worked correctly, including the basic_auth.
Jonathan Halmen
Details
Message ID
<C7BV2H88U8YS.1UZJIAR9Y8N6A@len>
In-Reply-To
<C7BKETEP2WBD.3NTL8A7WJ2LA2@len> (view parent)
DKIM signature
missing
Download raw message
> I have not done extensive testing[0], but it does work.

Ok, of course things aren't as simple as one wishes them to be. Things
start falling apart as soon as you have wildcards on multiple ports.

I looked into wrapping http.ServeMux into a wildServeMux. I'm not quite
sure about a few things, but it does look better
Reply to thread Export thread (mbox)