Skip to content

Issues with wildcard routes and trailing path separator #80

@antoooon

Description

@antoooon

I'm having issues with wildcard routes and trailing path separators.

Example routes:
/common/this/*substr
/common/that/:param/*substr

Testing on paths ending with a trailing slash will:

  1. Succeed when not expected
  2. Include parts of the path before the wildcard in the result.

Full example:

package main
    
import (
    "github.com/husobee/vestigo"
    "net/http"
    "fmt"
    "net/http/httptest"
)

func testrouter(router *vestigo.Router, method string, url string, expected string) {
    w := httptest.NewRecorder()
    req, _ := http.NewRequest(method, url, nil)
    handler := router.Find(req)
    handler(w, req)
    reply := w.Body.String()
    fmt.Println("\n* Testing:", url)
    fmt.Println("- reply:", reply)
    fmt.Println("- expected:", expected)
    if reply == expected { fmt.Println("OK") } else { fmt.Println("FAILED") }
}

func main() {
    router := vestigo.NewRouter()

    router.Get("/unique/*substr", func(w http.ResponseWriter, r *http.Request) {
        substr := vestigo.Param(r, "_name")
        fmt.Fprintf(w, `"%s"`, substr)
    })

    router.Get("/common/this/*substr", func(w http.ResponseWriter, r *http.Request) {
        substr := vestigo.Param(r, "_name")
        fmt.Fprintf(w, `"%s"`, substr)
    })

    router.Get("/common/that/:param/*substr", func(w http.ResponseWriter, r *http.Request) {
        param := vestigo.Param(r, "param")
        substr := vestigo.Param(r, "_name")
        fmt.Fprintf(w, `"%s", "%s"`, param, substr)
    })

    testrouter(router, "GET", "/unique/",                 `""`)
    testrouter(router, "GET", "/unique/abc",              `"abc"`)
    testrouter(router, "GET", "/common/this/",            `""`)
    testrouter(router, "GET", "/common/this/abc",         `"abc"`)
    testrouter(router, "GET", "/common/this/abc/",        `"abc/"`)
    testrouter(router, "GET", "/common/this/abc/def",     `"abc/def"`)
    testrouter(router, "GET", "/common/that/",            `Not Found`)
    testrouter(router, "GET", "/common/that/abc/",        `"abc", ""`)
    testrouter(router, "GET", "/common/that/abc/def",     `"abc", "def"`)
    testrouter(router, "GET", "/common/that/abc/def/",    `"abc", "def/"`)
    testrouter(router, "GET", "/common/that/abc/def/ghi", `"abc", "def/ghi"`)
}

Output:

* Testing: /unique/
- reply: "unique/"
- expected: ""
FAILED

* Testing: /unique/abc
- reply: "abc"
- expected: "abc"
OK

* Testing: /common/this/
- reply: "is/"
- expected: ""
FAILED

* Testing: /common/this/abc
- reply: "abc"
- expected: "abc"
OK

* Testing: /common/this/abc/
- reply: "abc/"
- expected: "abc/"
OK

* Testing: /common/this/abc/def
- reply: "abc/def"
- expected: "abc/def"
OK

* Testing: /common/that/
- reply: "at", "/"
- expected: Not Found
FAILED

* Testing: /common/that/abc/
- reply: "abc", "/"
- expected: "abc", ""
FAILED

* Testing: /common/that/abc/def
- reply: "abc", "def"
- expected: "abc", "def"
OK

* Testing: /common/that/abc/def/
- reply: "abc", "def/"
- expected: "abc", "def/"
OK

* Testing: /common/that/abc/def/ghi
- reply: "abc", "def/ghi"
- expected: "abc", "def/ghi"
OK

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions