Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DRAFT: contrib/dimfeld/httptreemux.v5: fix resource name for 301 redirects #14

Closed
wants to merge 1 commit into from

Conversation

devillecodes
Copy link
Collaborator

DO NOT MERGE.

return "", false
// TODO: what about the other two router.RedirectBehavior cases?
if lr.StatusCode == http.StatusMovedPermanently && router.RedirectBehavior == httptreemux.Redirect301 {
if strings.HasSuffix(route, "/") {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is for the original case where:

  • request URL: GET /api/example/ (with trailing slash)
  • matched handler: GET /api/example (without trailing slash)

if !found {
return "", false
}
} else {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is for the other possible case where:

  • request URL: GET /api/example (without trailing slash)
  • matched handler: GET /api/example/ (with trailing slash)

routeLen := len(route)
trailingSlash := route[routeLen-1] == '/' && routeLen > 1
if trailingSlash {
route = strings.TrimSuffix(route, "/")
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is to standardize the resource name.

For handler GET /api/example both of these cases will now have the same resource name:

  • GET /api/example (without trailing slash)
  • GET /api/example/ (with trailing slash)

Without this change you can end up with a scenario where you have two different resources in Datadog:

  1. GET /api/example (without trailing slash)
  2. GET /api/example/ (with trailing slash)

I believe this is a safe change to make because the router panics if you try and register two handlers with the same path with only the trailing slash being the difference, i.e.:

router := New()
router.GET("/api/example", handler200)
// this panics
router.GET("/api/example/", handler200)

func handler200(w http.ResponseWriter, _ *http.Request, _ map[string]string) {
	w.Write([]byte("OK\n"))
}

Comment on lines 131 to 139
// if the route does not have a trailing slash, retry lookup without trailing slash
rReq := req.Clone(req.Context())
rReq.RequestURI = rReq.RequestURI + "/"
rReq.URL.Path = rReq.URL.Path + "/"

lr, found = router.Lookup(w, rReq)
if !found {
return "", false
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a little confused by this. The comment says if the route does not have a trailing slash, to retry the lookup without the trailing slash, but this code looks like it's adding the slash

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eep! Yep. That's definitely a typo. Thanks for pointing it out!

@devillecodes devillecodes force-pushed the dv/remove-trailing-slash-in-resource-name branch 4 times, most recently from c339239 to 83c7e7c Compare April 18, 2024 23:02
The httptreemux router has a set of redirect behaviours that is invoked
when a request URL and matched route only differs in a trailing slash.
The default behaviour is to respond with a 301 (moved permanently) to
redirect the client to the exact path of the matched handler. We
previously patched one of the two scenarios where this occurs in DataDog#2332.
The changes in this commit addresses the other scenario.

We also standardize the resource name in the event that there is a
trailing slash missmatch between request URL and matched handler. We
always truncate the trailing slash in the resource name.

Fixes DataDog#2663
@devillecodes devillecodes force-pushed the dv/remove-trailing-slash-in-resource-name branch from 83c7e7c to d5ec356 Compare April 18, 2024 23:35
@devillecodes
Copy link
Collaborator Author

Closing this draft in favour of the upstream PR: DataDog#2664.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants