go-chi / go-chi/chi

Matching parameters containing the delimiter

Open
#781 9 comments 4 reactions 0 assignees View on GitHub
v6
Dominant language
Go
Stars
22.8k
Forks
1.2k
Avg merge
5h 17m
Merged PRs (30d)
10

Description

Example:
```go
r.Get("/{name}.json", ...)

// Request: GET /1.0.json
```

This fails because of (how I think) the routing algorithm works. For `{name}.json` the first character after the placeholder is saved as "tail delimiter". The route search now resolves the placeholder by searching for the delimiter in the string. For `/test.json` this searches for `.` and the result is `test`. However if the request is `/1.0.json` this logic fails to resolve the correct value because the delimiter `.` is contained in the value. The result is `1` instead of the expected `1.0`.

A possible fix would be to search for the whole non-placeholder-suffix `.json`. That would still fail for something like `{name}.` or `{name}.{extension}`.
Another fix would be to make the search greedy and read the value until the last occurence of the delimiter. As this works now fine for my case it fails for `{name}.{other}.json` even without the delimiter inside the values. Still I think the greedy matching is more often what you would expect.

Greedy example:
```diff
// serially loop through each node grouped by the tail delimiter
for idx := 0; idx < len(nds); idx++ {
xn = nds[idx]

+ segmentlen := strings.IndexByte(xsearch, '/')
+ if segmentlen == -1 {
+ segmentlen = len(xsearch)
+ } else {
+ segmentlen += 1 // just keep the old code working
+ }

// label for param nodes is the delimiter byte
- p := strings.IndexByte(xsearch, xn.tail)
+ p := strings.LastIndexByte(xsearch[:segmentlen], xn.tail)

if p < 0 {
if xn.tail == '/' {
```

Contributor guide

Open the contributing guide

Research direction

Start by locating the route-search loop that resolves parameter nodes using the tail delimiter and reproduce the `{name}.json` examples with values such as `1.0`. Compare the current behavior with the proposed greedy cases, including `{name}.{other}.json`; done means parameter values are resolved consistently without breaking slash-delimited routes.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
api, backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.