Coder Social home page Coder Social logo

gorilla / mux Goto Github PK

View Code? Open in Web Editor NEW
20.1K 311.0 1.8K 506 KB

Package gorilla/mux is a powerful HTTP router and URL matcher for building Go web servers with ๐Ÿฆ

Home Page: https://gorilla.github.io

License: BSD 3-Clause "New" or "Revised" License

Go 99.56% Makefile 0.44%
mux go gorilla router http middleware golang gorilla-web-toolkit

mux's People

Contributors

bgaifullin avatar bign8 avatar blasteralex avatar brocaar avatar burrbd avatar chrishines avatar coreydaley avatar djgilcrease avatar dmitshur avatar ejholmes avatar elithrar avatar fharding1 avatar kimmachinegun avatar kisielk avatar kushmansingh avatar moraes avatar mtso avatar muesli avatar nickhudkins avatar nmiyake avatar owenthereal avatar pschlump avatar roobre avatar seriousben avatar shanesaww avatar shkw avatar sqs avatar ttencate avatar tumdum avatar vivekv96 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mux's Issues

StrictSlash Redirect Still Executes Original Controller

I'm not sure how yet, but if I have a router with StrictSlash turned on, and I send a request to, say

/some/path

it will correctly redirect to

/some/path/

but in the process it also seems to call the original handler bound to the route. I'm planning on investigating some more tomorrow and seeing if I can figure out what's causing this, or at least get you a minimal repro example, but before I start in on that I'd appreciate it if you could confirm for me that it's not actually intended behavior?

HTTP status code will always be set to 404

I have the following test project:

func main() {
    router := mux.NewRouter()
    router.HandleFunc("/", someHandler).Methods("GET")

    http.Handle("/", router)
    http.ListenAndServeTLS(":9000", "cert.pem", "key.pem", nil)
}

func someHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "test")
}

I then use curl https://localhost:9000 -k -I to interact with the web server. The result is the following:

HTTP/1.1 404 Not Found
Content-Type: text/plain; charset=utf-8
Date: Sat, 14 Jun 2014 13:32:30 GMT
Content-Length: 19

The body of the request, however, is set to test. If I attempt to override the HTTP status code with w.WriteHeader(200), it does not work either. This also happens if I use a regular ListenAndServe() call. Here's my go version: go1.2.2 darwin/amd64. I use the latest master of gorilla/mux.

It would appear that HTTP status code handling is completely broken.

Optionally Match trailing slash in the URL and HTTP Method based matching

Lets say we have a URL like

http://www.hostname/upload/

Considering that the user types in

http://www.hostname/upload (note no trailing slash)

Possibly we can redirect the user from the no-slash one to the slashed one by registering different handlers.StrictSlash does this. But is there a way to match both of them?

we use mux like this

package main
import (
       "fmt"
       "github.com/gorilla/mux"
       "net/http"
)
func uploadHandler(w http.ResponseWriter, r * Request){
        fmt.Fprintf(w,"Upload page")
}

func main(){
    routes := mux.NewRouter()
    routes.HandleFunc("/upload",uploadHandler) //this doesnot match the trailing slash case
    http.Handle("/",routes)
    http.ListenAndServe("0.0.0.0:8081",nil)
}

How do we write the matching condition so that it accepts both http://www.hostname/upload/ and http://www.hostname/upload ?

Another question. How do we execute different handlers based on the request method?

e.g., the GET request to upload can be handled by different handler and POST can be handled by another function.

I already know that we can check request.Method in the handler and do different things accordingly. But is there a way to do such HTTP method based matching?

Subroutes using PathPrefix don't redirect on POST

Looking at #31 looks like it's a similar issue with POST though.

Using

bookRoute := router.PathPrefix("/book").Subrouter()
bookRoute.Handle("/", createBookHandler).Methods("POST")

Will only POST to /book/ and not /book without the trailing slash
Trying to append StrictSlash(true) to the Subrouter() has no effect.

Is there something I'm missing in the setup?

In addition, maybe this is stupid here, but when I POST to the GET route it responds properly. So the following would both succeed, but obviously supports GET requests as well.

bookRoute := router.PathPrefix("/book").Subrouter()
get := router.Methods("GET").Subrouter()

get.Handle("/book", createBookHandler) // Handles both GET and POST
bookRoute.Handle("/", createBookHandler).Methods("POST")

If I remove the bookRoute there would only be a 404.

matching headers - accept

I've been trying to match a header:

r := mux.NewRouter()
r.HandleFunc("/getdata", getdata_handler).
    Host("localhost").
    Methods("GET").
    Headers("Accept", "text/json")

The source of the transaction is a jQuery(1.9.1) $.ajax() call.

$.ajax({
    url: 'http://localhost:3000/getdata?callback=?',
    type: 'GET',
    timeout: 10*1000,
    accepts :{json:"text/json", jsonp:"text/json"},
    jsonp: 'callback',
    dataType: 'jsonp',
    success: function(data) {
        console.log(data);
    },
    error: function(  jqXHR,  textStatus,  errorThrown) { console.log('error', textStatus, errorThrown); },
});

I have been playing with ?headers?, ?accept? and ?sendBefore?. Debugging this has been nearly impossibly. But after reviewing the gorilla code and reading this comment:

"Funny enough, even doing this the Accept header you will send will be something like "application/json, /; q=0.01", so take care on the server."
-- (http://forum.jquery.com/topic/ajax-accepts-setting-not-creating-accept-header)

The Match() code is looking for a string match instead of a substring match. Take a loog at the expressjs code. My recollection from the doc is that they do some fuzzy matching instead of exact.

deleting routes

Last night I read all of the stdlib net/http code in order to determine whether or not it was possible to delete a route once it was added and it seems that while you can add handlers at runtime you cannot delete them. Looking at the Gorilla Mux documentation I see much of the same. Is there any particular use-case against being able to delete routes?

Can't create "root" route on a subrouter

r := mux.NewRouter()
sr := r.PathPrefix("/foo")
sr.Path("/").HandlerFunc(...)

// GET /foo/ -> OK
// GET /foo -> 404 Not Found

I can't find a way to get the second request to work. I thought StrictSlash might help, but it doesn't. Any suggestions?

Having trouble importing mux: package appears to have no public members

I have a very simple go file, and when I try to build, i get this:

go build
# _/home/matt/projects/goprojects/muxHello
./main.go:10: undefined: mux.HandleFunc
./main.go:14: undefined: mux.DefaultRoute

here is my code:

package main

import (
    "fmt"
    "github.com/gorilla/mux"
    "net/http"
)

func main() {
    mux.HandleFunc("/", func(w http.ResponseWriter, r http.Request) {
        fmt.Fprint(w, "Hello")
    })

    http.Handle("/", mux.DefaultRoute)
    http.ListenAndServe(":10000", nil)
}

I set my GOPATH to /home/matt/projects/goprojects/muxHello
then do

go get github.com/gorilla/mux

and the folders show up in

/home/matt/projects/goprojects/muxHello/src/github.com/gorilla/mux
/home/matt/projects/goprojects/muxHello/src/github.com/gorilla/context

I've tried other imports and they have worked. for instance, https://code.google.com/p/goauth2/ and https://github.com/eaigner/jet both work using the exact same steps I took with gorilla/mux.

It's like it is finding the package; but the package isn't exporting anything.

here is the output of "go env"

GOARCH="amd64"
GOBIN=""
GOCHAR="6"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/matt/projects/goprojects/muxHello"
GORACE=""
GOROOT="/home/matt/go"
GOTOOLDIR="/home/matt/go/pkg/tool/linux_amd64"
CC="gcc"
GOGCCFLAGS="-g -O2 -fPIC -m64 -pthread"
CGO_ENABLED="1"

I installed go from source. I used the release branch of go 1.1.

 go version go1.1 linux/amd64

I am building a restful api as my first go project. I apologize in advance if this is because of a mistake I've made or if this isn't the right "forum" for this. I have spent several hours trying to make sure everything is setup correctly. I don't know what else to do. I created an issue because I feel like I've done everything correctly, I followed the directions on the gorilla/mux site and I haven't had this issue with other libraries.

Catch root of subrouter

The route below matches /

router := mux.NewRouter()
router.Methods("GET").Path("/").HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
    res.Write([]byte("/"))
})

If I want to match /subroute, shouldn't I be able to use this? It currently does not seem to work. Is this by design or a mistake?

subrouter := router.PathPrefix("/subroute").Subrouter()
subrouter.Methods("GET").Path("/").HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
    res.Write([]byte("/subroute"))
})

Response redirect drops query string

If you have http://localhost//api/status?abc=def and you have a handler for /api/status
the code in mux.go will do a redirect to http://localhost/api/status and drop the ?abc=def. This is the same as issue http://code.google.com/p/go/issues/detail?id=5252, fixed in go 1.2 rc 4. I am trying to figure out how to do a pull requet as
I have fixed and tested this. You can look at my fork of mux.go lines 70 to 77.
https://github.com/pschlump/mux.git Code is modified from the 1.2rc4 fix.

DELETE and PUT methods don't work with some browsers

When some browsers (i.e. current version of chrome and firefox) are making Delete or Put requests via ajax, they actually make the METHOD=POST and change the header to "HTTP_X_HTTP_METHOD" to "DELETE" or "PUT".

When this occurs, mux fails to properly detect a DELETE or PUT request.

Route.URL creates incorrect URL when PathPrefix is in use

Maybe I'm misunderstanding but if I have a Route with a defined path prefix, on making use of Route.URL the prefix is appended, rather than prepended. Sample code:

package main

import (
    "fmt"
    "github.com/gorilla/mux"
)

func main() {
    r := mux.NewRouter()
    route := r.Path("/testpath").PathPrefix("/prefix/")
    url, _ := route.URL()
    fmt.Println(url)
}

The Println outputs /testpath/prefix/

Regexp parentheses matching overwrites mux-defined keys

NOTE: This may be similar / duplicate to issue #11.

Use case - avoiding duplication of

r.HandleFunc("/user/view/{id:[0-9]+}", user.GetViewPage).Methods("GET")
r.HandleFunc("/user/{id:[0-9]+}", user.GetViewPage).Methods("GET")

With something like

r.HandleFunc("/user/{_:(view/)?}{id:[0-9]+}", user.GetViewPage).Methods("GET")

Results:

/user/5
2014/03/15 12:20:47 map[_: id:]
/user/view/5
2014/03/15 12:20:39 map[_:view/ id:view/]

As you can see, the regex matching view/ is somehow being assigned to id. The docs state that name:pattern matches a regexp pattern - as you can see above, this does not seem to be occurring properly.

URL encoded parameters not working

if you have sth like
Router.HandleFunc("/bla/{foo}", someHandler)

the "foo" parameter cant be an URL-encoded string like "hmm%2Fstrange"

Can't use path variables in subrouter

In the following application I expected a request to /foo/bar/11 and /foo/11 to both return the same response; Vars: map[id:11]. But it turns out that /foo/bar/11 instead returns a 404 error.

package main

import (
    "fmt"
    "github.com/gorilla/mux"
    "net/http"
)

func Test(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Vars: %v", mux.Vars(r))
}

func main() {
    root := mux.NewRouter()
    foo := root.Path("/foo/").Subrouter()
    foobar := foo.Path("/bar/").Subrouter()

    foo.HandleFunc("/{id}", Test).Name("foo")
    foobar.HandleFunc("/{id}", Test).Name("bar")

    http.Handle("/", foo)

    http.ListenAndServe(":8080", nil)
}

Document how to make custom matcher functions

Hey,

As far as I can see, despite great documentation in general there's nothing on how to make custom matcher functions or anything on the RouteMatch struct. Does that exist somewhere, and if not, could someone either explain to me how they work so that I can add documentation or just add material to the docs and let me know?

Thanks,

Site down?

I'm trying to access the site in order to take a look at the documentation and it's giving me a 500 error.

how to bind 2 URLs on 1 function

Hi,

I want to bind 2 URLs to 1 function. like below.

router.HandleFunc("/_Users", controller.AddResource)
router.HandleFunc("/Resources/{resourceName}", controller.AddResource)

the controller.AddResource is a global function. the code like below:

function AddResource(req *http.Request, w http.ResponseWriter){
    vars := mux.Vars(req)
    resourceName := vars["resourceName"]
    data = request.Body
    AddDataToResource(resourceName, data)
}

so how can i set the vars(resourceName='_User') in the first router?

thanks...

Is mux supposed to work with WebSocket?

Hi,

I am using mux together with WebSocket in my app and I am constantly getting 404. When I replace mux with http.ServeMux, everything starts working. I register the handler with

r.Handle("/ws", ws.Handler(s.handleWSConnection))

and

mx := http.NewServeMux()
mx.Handle("/", r)
mx.Handle("/ws", ws.Handler(s.handleWSConnection))

is the working code.

I am asking because I saw people using it on the internet, so I don't know if it broke recently or so...

Thanks for the reply!

Regards,
Ondra Kupka

mux.Vars is empty - and shoudn't be

I bet it's just me doing something wrong - but then I would ask to improve the docs.
Here is what I am trying:

router := mux.NewRouter()
http.Handle("/", handler.LoggingInterceptor(handler.AuthenticationInterceptor(router)))
router.HandleFunc("/project/{project:[0-9a-zA-Z]+}", handler.PutProject).Methods("PUT")

With the interceptors along the lines of:

func AuthenticationInterceptor(router http.Handler) http.Handler {
  return http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
    vars := mux.Vars(req)
    glog.Infof("Vars: [%q] but %s", vars, req.URL.Path)
    router.ServeHTTP(res, req)
  })
}

and

func LoggingInterceptor(router http.Handler) http.Handler {
  return http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
    router.ServeHTTP(res, req)
  })
}

Pretty straight forward. But somehow the variables are empty inside the interceptor.

Vars: [map[]] but /project/test

As you can see from the logs the request does get matched correctly and the request uri looks OK - but there is no var "project".

What am I missing here?

Return a 405 when HTTP method is not supported

What steps will reproduce the problem?

  1. Register a URL & handler with r.HandleFunc("/foo", myHandlerFunc).Methods("POST")
  2. Using a web browser, or cURL, hit the endpoint using an HTTP GET request

What is the expected output? What do you see instead?
Ideally, a 405 Method Not Allowed status should be returned, but the response status is a 404 File Not Found.

(issue moved from Google Code: http://code.google.com/p/gorilla/issues/detail?id=50)

If a route is matched by everything except the method, router should return a 405 listing the available methods

I have some routes that I only allow certain methods for. When I try another method for the same URI, I get a 404. As per the HTTP 1.1 spec, I should get a 405 with the proper Allow header listing the allowed methods.

Reference: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.6

UPDATE:
I also noticed that seemingly unexpected behavior occurs when routes don't match on headers or on queries. On queries I'd think you'd want to return a 400 with some information about how certain queries aren't allowed. On headers it might be harder as it seems depending on the header you might want to return a 406, 412, 415, 416, or a 417? I'm not sure with that one.

Feedback is appreciated. When I get some time, if you guys like the idea, I might make a pull request and do it myself.

Schemes() if not matching my test

// this code does not work

r := mux.NewRouter()
r.HandleFunc("/getdata", getdata_handler).
    Host("localhost").
    Methods("GET").
    Headers("Accept", "text/json").
    Schemes("http").
    Name("getdata")

// this code works

r := mux.NewRouter()
r.HandleFunc("/getdata", getdata_handler).
    Host("localhost").
    Methods("GET").
    Headers("Accept", "text/json").
    Name("getdata")

Here is the test:

        $.ajax({
            url: 'http://localhost:3000/getdata?callback=?',
            //headers: { "Accept": "text/json" },
            type: 'GET',
            dataType: 'json',
            jsonp: 'callback',
            success: function(data) {
                console.log(data);
                template = $('#tabletemplate').clone().html();
                console.log(template);
                snippet = Mustache.render(template, data);
                console.log(snippet);
                $('#workspace').empty().append(snippet);
            },
            error: function(  jqXHR,  textStatus,  errorThrown) { console.log('error', textStatus, errorThrown); },
            beforeSend: function(jqXHR){ jqXHR.setRequestHeader("Accept", "text/json"); }
        });

cleanPath() causing a change in the URL should not necessarily cause a redirect

Say I have an API with a URL structure as follows: http://example.com/library/$BOOKID/chapters

If someone hits the URL http://example.com/library//chapters (Fails to provide a bookID), the client will receive a 301 to a location which doesn't exist (301 -> follow -> 404)

In my opinion, this behaviour should be optional, the problem is of course that path.Clean() is called, and (As per documentation) // 1. Replace multiple slashes with a single slash. is performed.

Most my reasoning for not wanting this behaviour is based on me not wanting my routing library to redirect my clients when I'm not explicitly asking it to.

What are others thoughts on this?

Cheers,

project layout in github

when you look at the sum of the gorilla project code it's not all that much, however, having separate repos for each subproject feels less than optimum. In the coming days I plan to fork the code so I can make some changes, however, I expect some of the dependencies to get in the way and so hacking those are going to make the task of pulling changesets more difficult. This is just my intuition so feel free to tell me I'm wrong.

Document Usage Of Router.NotFoundHandler

Right now on the website there isn't any documentation on how to handle 404 errors. Documentation should be added for this, because the functionality is included in the library and I'm sure a lot of people will use it! :)

Thank you,

Evan

Attach subrouter to router.

Hi,

I am coming from Martini and with Martini you can handle subrouters like so,

package main

import (
    "github.com/go-martini/martini"
    "net/http"
)

func main() {
    m := martini.Classic()
    m.Group("/user", users.GetRouter)
    m.Group("/posts", posts.GetRouter)

    http.Handle("/", m)
}
package users
func GetRouter(r martini.Router) {
    r.Get("/{id}", GetBooks)
    r.Post("/new", NewBook)
    r.Put("/update/{id}", UpdateBook)
    r.Delete("/delete/{id}", DeleteBook)
}


func GetBooks(res http.ResponseWriter, req *http.Request) {
 //DO stuff here.
})
package posts
func GetRouter(r martini.Router) {
    r.Get("/{id}", GetPosts)
    r.Post("/new", NewPost)
..
..
..

How can I achieve the same structure with Gorilla Mux? I did read through the Gorilla Mux's GoDocs and I can't seem to find a way to handle this.

The problem I have is that it seems like you can only create subrouters for a parent route with Gorilla Mux, so I was considering this solution:

package main

import (
    "code.google.com/p/gorilla/mux"
    "fmt"
    "net/http"
)

func main() {

    r := mux.NewRouter()

    users.SetRoutes(r.PathPrefix("/users").Subrouter())
    posts.SetRoutes(r.PathPrefix("/posts").Subrouter())

    http.Handle("/", r)

}
package users

import (
    "code.google.com/p/gorilla/mux"
)

func SetRoutes(r mux.Router) {
    r.HandleFunc("/{id}", GetBook)
}


func GetBook(res http.ResponseWriter, req *http.Request) {
 //DO stuff here.
})
package posts

import (
    "code.google.com/p/gorilla/mux"
)

func SetRoutes(r mux.Router) {
    r.HandleFunc("/{id}", GetPost)
}

.

But that is not really clean and it looks backwards in the sense that the subpackage is consuming the main package, instead of the other way around.
I was hopping for solution like this:

func main() {

    r := mux.NewRouter()

    r.PathPrefix("/users").Attach(users.GetRoutes)
    r.PathPrefix("/posts").Attach(posts.GetRoutes)

    http.Handle("/", r)

}
package users

import (
    "code.google.com/p/gorilla/mux"
)

func GetRoutes(r mux.Router)  {
    r.HandleFunc("/{id}", GetBook)
}


func GetBook(res http.ResponseWriter, req *http.Request) {
 //DO stuff here.
})
package posts

import (
    "code.google.com/p/gorilla/mux"
)

func GetRoutes(r mux.Router ) {

    r.HandleFunc("/{id}", GetPost)
}

Queries() matches against non-exactly-matching queries.

At the master branch, (r *Router) Queries(pairs ...string) looks have a probmems.
It matches querystrings which are not exactly matched.

When you set r.Queries("foo","bar"), this router matches queries like "fffoo=barrrrrr".
I think that any problem is in Regexp.

Following test fails accidently.

    {                                                                                                                                                                                                                                                                         
      title:       "Queries route, bad submatch",                                                                                                                                                                                                                             
      route:       new(Route).Queries("foo", "bar", "baz", "ding"),                                                                                                                                                                                                           
      request:     newRequest("GET", "http://localhost?fffoo=bar&baz=dingggg"),                                                                                                                                                                                               
      vars:        map[string]string{},                                                                                                                                                                                                                                       
      host:        "",                                                                                                                                                                                                                                                        
      path:        "",                                                                                                                                                                                                                                                        
      shouldMatch: false,                                                                                                                                                                                                                                                     
    },

mux headers do not support regex

since accept headers can be complex with all sorts of version information embedded it would be better if it supported regex in the value portion of the pair.

Gracefull shutdown

Hi there, I'm kind of a noob in go so may be I'm asking this in the wrong place.

Is there someway to tell the mux to shutdown gracefully ?

May be I could use manners or graceful as a proxy ?

Header constraint not working

Hi everyone!

I'm developing a small webserver and I've tried to limit access only to Cloudfront, by ensuring the header 'User-Agent' is set to 'Amazon Cloudfront'. I know it's not the safest thing in the world, but at least avoids unintentional requests.

However, I haven't managed to apply this constraint. This is my code so far:

r := mux.NewRouter()

// Constraints
s := r.Headers("User-Agent", "Amazon Cloudfront").PathPrefix("/{connection_id}").Subrouter()

// Routes
s.HandleFunc("/product-images/{model_id}", ProductImagesHandler)
s.HandleFunc("/product-images/{model_id}/{max_dimension:[0-9]+}", ProductImagesHandler)
s.HandleFunc("/nav-item-images/{model_id}", NavItemImagesHandler)
s.HandleFunc("/nav-item-images/{model_id}/{max_dimension:[0-9]+}", NavItemImagesHandler)
http.Handle("/", s)

// Keep listening
http.ListenAndServe(":3000", s)

However, all the requests go through. Is this a bug? Am I missing something?

I'm using latest Go (1.4.2).

Thanks in advance! ;)

getNamedRoutes not exported

For debugging purposes it would be nice to get all routes, but the getNamedRoutes function is not exported. Is there any reason for that?

Debugging output

It would be really helpful if I could set a debug flag on a router and have it spit out log messages telling me what it's doing when it's asking to handle a request. As it is, debugging routing failures requires a lot of guess work.

I'd be happy to work on a PR if you could give me some guidance on the API.

API compatibility with http.ServeMux

The API of mux#Router.HandleFunc is slightly different which makes it really hard to write libraries which can use both github.com/gorilla/mux Router and http.ServeMux.

cannot use r.PathPrefix("/api/v1/").Subrouter() (type *mux.Router) as type sleepy.APIMux in function argument:
*mux.Router does not implement sleepy.APIMux (wrong type for HandleFunc method)
have HandleFunc(string, func(http.ResponseWriter, *http.Request)) *mux.Route
want HandleFunc(string, func(http.ResponseWriter, *http.Request))

So the difference is the return value of HandleFunc. I see no real value of returning the Router again. What are the reasons - i suggest that the return value is removed to get API compatibility.

Problem parsing % as a pattern in URL

Having defined a mux Handler as:
r.HandleFunc("/info/{name:[A-Za-z0-9._%-]+}/", getInfo).Methods("GET")

It doesn't handle URLs containing any percentage symbol. For example I get:
GET http://127.0.0.1:8081/info/sample%20name/ 404 (Not Found)

Is there a way of defining a pattern for parsing % symbols or spaces coded as %20?

Version tags

Hi, would you mind create version tag (0.1 or even 1.0)? So we can use gopkg.in versioning system for installing stable(or though reproducible) mux versions. Also it can be good for all gorilla packages.
Thank you.

URL variables bug for multiple patterns with relatively complex regexp

Hi,

There's a bug with URL variable with a relatively complex regexp.
For example, let's take the regexp a|(b/c) which should match a or b/c.

If I use the regexp in a path with one pattern, it works. You can test it with these routeTests:

tests := []routeTest{
  {
    title:       "Path route with single pattern with pipe, match",
    route:       new(Route).Path("/{category:a|(b/c)}"),
    request:     newRequest("GET", "http://localhost/a"),
    vars:        map[string]string{"category": "a"},
    host:        "",
    path:        "/a",
    shouldMatch: true,
  },
  {
    title:       "Path route with single pattern with pipe, match",
    route:       new(Route).Path("/{category:a|(b/c)}"),
    request:     newRequest("GET", "http://localhost/b/c"),
    vars:        map[string]string{"category": "b/c"},
    host:        "",
    path:        "/b/c",
    shouldMatch: true,
  },
}

But if I try to use it in a path with multiple patterns, it produces weird results.

This test...

tests := []routeTest{
  {
    title:       "Path route with multiple patterns with pipe, match",
    route:       new(Route).Path("/{category:a|(b/c)}/{product}/{id:[0-9]+}"),
    request:     newRequest("GET", "http://localhost/a/product_name/1"),
    vars:        map[string]string{"category": "a", "product": "product_name", "id": "1"},
    host:        "",
    path:        "/a/product_name/1",
    shouldMatch: true,
  },
}

...fails because the variables don't match:

$ go test
--- FAIL: TestPath (0.00 seconds)
    mux_test.go:810: (Path route with multiple patterns with pipe, match) Vars not equal:
    expected map[category:a product:product_name id:1],
    got      map[category:a product: id:product_name]

And this test...

tests := []routeTest{
  {
    title:       "Path route with multiple patterns with pipe, match",
    route:       new(Route).Path("/{category:a|(b/c)}/{product}/{id:[0-9]+}"),
    request:     newRequest("GET", "http://localhost/b/c/product_name/1"),
    vars:        map[string]string{"category": "b/c", "product": "product_name", "id": "1"},
    host:        "",
    path:        "/b/c/product_name/1",
    shouldMatch: true,
  },
}

...also fails because the variables don't match either (but in a different way):

$ go test
--- FAIL: TestPath (0.00 seconds)
    mux_test.go:810: (Path route with multiple patterns with pipe, match) Vars not equal:
    expected map[category:b/c product:product_name id:1],
    got      map[category:b/c product:b/c id:product_name]

EDIT: Fix manual editing mistakes (category_name instead of product_name)

Add examples of applications

Requested on IRC, we don't have any fully-fledged examples of using mux, which would probably be handy to answer some commonly-asked questions.

Host() with a port fails to match when the host is supplied in the HTTP Host: header

Old issue: http://code.google.com/p/gorilla/issues/detail?id=51

According to section 14.23 of RFC 2616 the Host header can include the port number if the default value of 80 is not used.

See https://github.com/gorilla/mux/blob/master/mux_test.go#L119 for a commented-out test case that fails.

Potential fix is editing getHost() https://github.com/gorilla/mux/blob/master/regexp.go#L237 so it has a flag as to whether to strip off the port information. A new field would need to be probably need to be added somewhere such as routeRegexp.

The main reason I was using Host() match with a port in the first place is for trying to build reverse routes that include the absolute path as opposed to a relative one.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.