4
votes

I'm using the Mux package from the Golang Gorilla Toolkit for my routes.

Consider the following routes:

m.HandleFunc("/admin/install", installHandler).Methods("GET")
m.HandleFunc("/admin/^((?!install).)*$", adminHandler).Methods("GET")
m.HandleFunc("/admin", adminHandler).Methods("GET")

The problem is with the regex of the middle route - it is not interpreted, so the route will not work!

m.HandleFunc("/admin/{^((?!install).)*$}", adminHandler).Methods("GET")

With the {} curly brackets doesn't work either. It is just ignored, and treated as /admin/

Neither does:

m.HandleFunc("/admin/{_dummy:^((?!install).)*$}", adminHandler).Methods("GET")

In short, what I'm trying to achieve here is to first match the /admin/install route, and that exact route I then want to exclude from the route below, using the regex, but it doesn't work.

Is there some way to use regex with the gorilla mux package?

2
That's not the syntax for matching a path in gorrila/mux: [paths] are defined using the format {name} or {name:pattern}. gorillatoolkit.org/pkg/muxJimB
Heh I edited the post before I saw your comment, but I have of course tested with the following two ways as well: 1) Curly brackets doesn't work with my "exclude" regex. 2) neither does {_dummy: regex}Dac0d3r
that's also not supported syntax for a Go regexp. You don't need to exclude install, as it would be matched by the first route.JimB
I have some logic in the admin handler which only works, and only should hit the server, if the user is logged in and the user is set in the request context, so that's my reasoning for wanting to make an exception and exclude the /admin/install route and include all others. :) I know I can code my way around it inside the admin, handler, but it would have been sweet if this would have worked I think :-)Dac0d3r
You have selected the wrong answer: [^install] is not the same as "not followed by the word install".VonC

2 Answers

5
votes

It is actually possible to do this:

m.HandleFunc(`/{_dummy:admin\/([^install]*).*}`, adminHandler).Methods("GET")

Edit:

As my answer to VonC's comment above, here a sample go app: https://play.golang.org/p/nYWNADK7Sr

Run it on your local pc. Try the following routes:

http://localhost:8080/admin/ - (returns "adminHandler")
http://localhost:8080/admin/something - (returns "adminHandler")
http://localhost:8080/admin/install - (returns "installHandler")

So yes VonC, it does solve the specific problem:

"to first match the /admin/install route, and that exact route I then want to exclude from the route below"

But it is correct that it doesn't mean "not followed by the word, install" - this is just an alternative approach which is possible within the bounds of the re2 syntax. To simply "ignore" or exclude the word install, if it happens to show up in the url.

1
votes

It doesn't work because golang regexp follows the re2 syntax, which doesn't support lookahead or lookbehind.

You might need to define an handler for /admin/install first.
Then all others /admin/xxx would be for other routes (ie not /admin/install)

Actually, the OP SK84 adds in the comments:

Even if admin/install is defined first, /admin/ will also be executed. That's what I wanted to avoid.

I guess I need to code around it inside the admin handler then - easy, but not as pretty as this would have been if it had worked.