Skip to content

Commit

Permalink
Add keepTrailingSlash option
Browse files Browse the repository at this point in the history
  • Loading branch information
juliens authored and traefiker committed Oct 17, 2018
1 parent 70fa42a commit 95d86d8
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 2 deletions.
1 change: 1 addition & 0 deletions configuration/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ type GlobalConfiguration struct {
RespondingTimeouts *RespondingTimeouts `description:"Timeouts for incoming requests to the Traefik instance" export:"true"`
ForwardingTimeouts *ForwardingTimeouts `description:"Timeouts for requests forwarded to the backend servers" export:"true"`
AllowMinWeightZero bool `description:"Allow weight to take 0 as minimum real value." export:"true"` // Deprecated
KeepTrailingSlash bool `description:"Do not remove trailing slash." export:"true"` // Deprecated
Web *WebCompatibility `description:"(Deprecated) Enable Web backend with default settings" export:"true"` // Deprecated
Docker *docker.Provider `description:"Enable Docker backend with default settings" export:"true"`
File *file.Provider `description:"Enable File backend with default settings" export:"true"`
Expand Down
26 changes: 26 additions & 0 deletions docs/configuration/commons.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@
#
# checkNewVersion = false

# Tells traefik whether it should keep the trailing slashes in the paths (e.g. /paths/) or redirect to the no trailing slash paths instead (/paths).
#
# Optional
# Default: false
#
# keepTrailingSlash = false

# Providers throttle duration.
#
# Optional
Expand Down Expand Up @@ -103,6 +110,25 @@ If you encounter 'too many open files' errors, you can either increase this valu
- `defaultEntryPoints`: Entrypoints to be used by frontends that do not specify any entrypoint.
Each frontend can specify its own entrypoints.

- `keepTrailingSlash`: Tells Træfik whether it should keep the trailing slashes that might be present in the paths of incoming requests (true), or if it should redirect to the slashless version of the URL (default behavior: false)

!!! note
Beware that the value of `keepTrailingSlash` can have a significant impact on the way your frontend rules are interpreted.
The table below tries to sum up several behaviors depending on requests/configurations.
The current default behavior is deprecated and kept for compatibility reasons.
As a consequence, we encourage you to set `keepTrailingSlash` to true.

| Incoming request | keepTrailingSlash | Path:{value} | Behavior
|----------------------|-------------------|--------------|----------------------------|
| http://foo.com/path/ | false | Path:/path/ | Proceeds with the request |
| http://foo.com/path/ | false | Path:/path | 301 to http://foo.com/path |
| http://foo.com/path | false | Path:/path/ | Proceeds with the request |
| http://foo.com/path | false | Path:/path | Proceeds with the request |
| http://foo.com/path/ | true | Path:/path/ | Proceeds with the request |
| http://foo.com/path/ | true | Path:/path | 404 |
| http://foo.com/path | true | Path:/path/ | 404 |
| http://foo.com/path | true | Path:/path | Proceeds with the request |


## Constraints

Expand Down
48 changes: 48 additions & 0 deletions integration/basic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -396,3 +396,51 @@ func (s *SimpleSuite) TestMultipleProviderSameBackendName(c *check.C) {
c.Assert(err, checker.IsNil)

}

func (s *SimpleSuite) TestDontKeepTrailingSlash(c *check.C) {
file := s.adaptFile(c, "fixtures/keep_trailing_slash.toml", struct {
KeepTrailingSlash bool
}{false})
defer os.Remove(file)

cmd, output := s.traefikCmd(withConfigFile(file))
defer output(c)

err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()

oldCheckRedirect := http.DefaultClient.CheckRedirect
http.DefaultClient.CheckRedirect = func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
}

err = try.GetRequest("http://127.0.0.1:8000/test/foo/", 1*time.Second, try.StatusCodeIs(http.StatusMovedPermanently))
c.Assert(err, checker.IsNil)

http.DefaultClient.CheckRedirect = oldCheckRedirect
}

func (s *SimpleSuite) TestKeepTrailingSlash(c *check.C) {
file := s.adaptFile(c, "fixtures/keep_trailing_slash.toml", struct {
KeepTrailingSlash bool
}{true})
defer os.Remove(file)

cmd, output := s.traefikCmd(withConfigFile(file))
defer output(c)

err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()

oldCheckRedirect := http.DefaultClient.CheckRedirect
http.DefaultClient.CheckRedirect = func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
}

err = try.GetRequest("http://127.0.0.1:8000/test/foo/", 1*time.Second, try.StatusCodeIs(http.StatusNotFound))
c.Assert(err, checker.IsNil)

http.DefaultClient.CheckRedirect = oldCheckRedirect
}
23 changes: 23 additions & 0 deletions integration/fixtures/keep_trailing_slash.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
defaultEntryPoints = ["http"]

keepTrailingSlash = {{ .KeepTrailingSlash }}
[entryPoints]
[entryPoints.http]
address = ":8000"

logLevel = "DEBUG"

[file]

# rules
[backends]
[backends.backend1]
[backends.backend1.servers.server1]
url = "http://172.17.0.2:80"
weight = 1

[frontends]
[frontends.frontend1]
backend = "backend1"
[frontends.frontend1.routes.test_1]
rule = "Path:/test/foo"
2 changes: 1 addition & 1 deletion server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -627,7 +627,7 @@ func buildProxyProtocolListener(entryPoint *configuration.EntryPoint, listener n

func (s *Server) buildInternalRouter(entryPointName string) *mux.Router {
internalMuxRouter := mux.NewRouter()
internalMuxRouter.StrictSlash(true)
internalMuxRouter.StrictSlash(!s.globalConfiguration.KeepTrailingSlash)
internalMuxRouter.SkipClean(true)

if entryPoint, ok := s.entryPoints[entryPointName]; ok && entryPoint.InternalRouter != nil {
Expand Down
2 changes: 1 addition & 1 deletion server/server_configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -633,7 +633,7 @@ func buildDefaultCertificate(defaultCertificate *traefiktls.Certificate) (*tls.C
func (s *Server) buildDefaultHTTPRouter() *mux.Router {
rt := mux.NewRouter()
rt.NotFoundHandler = s.wrapHTTPHandlerWithAccessLog(http.HandlerFunc(http.NotFound), "backend not found")
rt.StrictSlash(true)
rt.StrictSlash(!s.globalConfiguration.KeepTrailingSlash)
rt.SkipClean(true)
return rt
}
Expand Down

0 comments on commit 95d86d8

Please sign in to comment.