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

value.tsr cause wrong redirect #2843

Closed
Zeahow opened this issue Aug 24, 2021 · 9 comments
Closed

value.tsr cause wrong redirect #2843

Zeahow opened this issue Aug 24, 2021 · 9 comments
Labels
Milestone

Comments

@Zeahow
Copy link

Zeahow commented Aug 24, 2021

Version: v1.7.4

After upgrading the version from v1.7.2 to v1.7.4, the logic of value.tsr has changed. Some cases that should return false will return true now.

image

I register a handler with path logout, while path login is handled in NoRouter handler. Only login will be handled in NoRouter. NoRouter will return 404 if path is login/.

In v1.7.2 login will enter NoRouter, and it will be handled. But in v1.7.4, value.tsr will be true so that the request will be rediredcted to login/ which will return 404.

image

@qm012
Copy link
Contributor

qm012 commented Aug 25, 2021

Could you provide an example?
In some cases panic can occur

prefix[len(path)] // panic  

@Zeahow
Copy link
Author

Zeahow commented Aug 25, 2021

Could you provide an example?
In some cases panic can occur

prefix[len(path)] // panic  

It won't panic.

The code in screenshot is to determine whether a leaf exists for the same URL with an external trailing slash. For example, for path login, it will got true, if there exists a leaf with path login/. But in v1.7.4, it will got true too, if there exists a logout leaf , and even if there not exists a login/ leaf. It will got true as long as there exists any leaf with a 6-char(6=len("login"+1)) path.

@qm012
Copy link
Contributor

qm012 commented Aug 25, 2021

Could you provide an example?

Something like this

package main

import (
	"fmt"
	"log"
	"net/http"

	"github.com/gin-gonic/gin"
)

func main() {
	router := gin.New()
	fmt.Println(gin.Version)

	server := &http.Server{
		Addr:    ":8080",
		Handler: router,
	}

	router.GET("/", func(c *gin.Context) {
		c.String(200, c.ClientIP())
	})

	err := server.ListenAndServe()
	if err != nil {
		log.Fatal(err)
	}
}

When I changed the code, I removed it because there was a panic. But I did not record the problem of panic. -_ -

@Zeahow
Copy link
Author

Zeahow commented Aug 25, 2021

Could you provide an example?

Something like this

package main

import (
	"fmt"
	"log"
	"net/http"

	"github.com/gin-gonic/gin"
)

func main() {
	router := gin.New()
	fmt.Println(gin.Version)

	server := &http.Server{
		Addr:    ":8080",
		Handler: router,
	}

	router.GET("/", func(c *gin.Context) {
		c.String(200, c.ClientIP())
	})

	err := server.ListenAndServe()
	if err != nil {
		log.Fatal(err)
	}
}

When I changed the code, I removed it because there was a panic. But I did not record the problem of panic. -_ -

package main

import (
	"fmt"
	"log"
	"net/http"

	"github.com/gin-gonic/gin"
)

func main() {
	router := gin.New()
	fmt.Println(gin.Version)

	server := &http.Server{
		Addr:    ":8080",
		Handler: router,
	}

	router.NoRoute(func(c *gin.Context) {
		if c.Request.RequestURI == "/login" {
			c.String(200, "Enter NoRoute. Path: login")
		}
	})

	router.GET("/logout", func(c *gin.Context) {
		c.String(200, "logout")
	})

	err := server.ListenAndServe()
	if err != nil {
		log.Fatal(err)
	}
}

Visit localhost:8080/login in brower:
v1.7.4: 404 page not found
v1.7.2: Enter NoRoute. Path: login

Tip: Clean brower cache or open a private windows, after switching v1.7.4 to v1.7.2

In addition, I could not understand how prefix[len(path)] panic. Its previous condition len(prefix) == len(path)+1 promises that prefix is longger than path.

@qm012
Copy link
Contributor

qm012 commented Aug 26, 2021

Ok, thank you for the example you provided. I am a little busy these two days, so I will test it on Sunday 💗

@luchuanbing123
Copy link

image
Agree with @Zeahow , path == prefix[:len(prefix)-1] can't be deleted.
Otherwise, /login will be redirct to /login/(not exsit), because len("/logout") == len("/login") +1

@appleboy appleboy added the bug label Aug 26, 2021
@appleboy appleboy added this to the v1.7.5 milestone Aug 26, 2021
@qm012
Copy link
Contributor

qm012 commented Aug 29, 2021

@Zeahow Yes, there will be a suffix '/' at the end of the match, can you submit a PR to fix this problem? And add test example, thanks.

@citizen233
Copy link
Contributor

@appleboy @qm012 I fixed this question and submitted pr

@appleboy
Copy link
Member

fixed in #2847

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

No branches or pull requests

5 participants