gin-gonic/gin

Redirect from POST ends in 404, even if the endpoint exists

tscolari opened this issue · 9 comments

I've made a sample code to explain what's happening:

package main

import (
    "net/http"

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

func main() {
    r := gin.Default()
    r.RedirectTrailingSlash = true
    r.RedirectFixedPath = true

    r.GET("/login", func(c *gin.Context) {
        form := "<form method='POST' action='/login/do'><input type='submit' /></form>"
        c.Header("Content-Type", "text/html")
        c.String(http.StatusOK, form)
    })

    r.POST("/login/do", func(c *gin.Context) {
        c.Redirect(http.StatusTemporaryRedirect, "/welcome")
    })

    r.GET("/welcome", func(c *gin.Context) {
        c.String(http.StatusOK, "Welcome")
    })

    r.Run(":8888")
}

When it tries to redirect from a POST to /login/do to /welcome the result is 404 (404 page not found).
But if I try to go directly to /welcome everything works fine.

Am I doing something wrong?

Obs: Moving status to 301 solved the issue.

Instead of a 301, I think a 302 http.StatusFound is more appropriate in this case.

Yeah, I agree, both (301, 302) work.
I'm going to close it, not sure if it makes sense 307 to return a 404 after the redirect, but maybe it is an intended behaviour.

It is intended behaviour. To quote httpstatus.es, a 307 tells the client to "connect again to different URI as provided". Since the original request was a POST request, the client will try to connect again using a POST request.

badkk commented

Same problem, but both(301, 302) does not work~
My case is posting form-data <file> to server using redirect, code is like:

func (pins *PinsController) PostFile(c *gin.Context) {
	fileSize := c.Request.ContentLength

	// 1. Look up for the most freespace node
	node, err := services.GetFreeNode(fileSize)
	HandleError(err)

	// 2. Redirect to that node
	redirectUrl := fmt.Sprintf("http://%s/", node.Address)
	fmt.Println(redirectUrl)

	c.Redirect(http.StatusTemporaryRedirect, redirectUrl)
}

And I got 404 using httpie

~  http -f POST :8080/api/v1/ name='file' file@~/Documents/Learning/java --follow
HTTP/1.1 404 Not Found
Content-Length: 18
Content-Type: text/plain
Date: Mon, 15 Apr 2019 14:07:59 GMT
Proxy-Connection: keep-alive

404 page not found

I try every 30X status code, found 308 works fine.
But when I post file bigger than 2MB, this Redirect function goes failed again, shows error below:

~ http -f POST :8080/api/v1/ name='file' file@~/Documents/Learning/kotlin-docs.pdf --all

http: error: ConnectionError: ('Connection aborted.', BrokenPipeError(32, 'Broken pipe')) while doing POST request to URL: http://localhost:8080/api/v1/

Anybody can help me~~~ 🤒

@zikunfan

Maybe you should change http.StatusTemporaryRedirect to http.StatusFound
https://golang.org/pkg/net/http/#pkg-constants

Same problem, but both(301, 302) does not work~ My case is posting form-data <file> to server using redirect, code is like:

func (pins *PinsController) PostFile(c *gin.Context) {
	fileSize := c.Request.ContentLength

	// 1. Look up for the most freespace node
	node, err := services.GetFreeNode(fileSize)
	HandleError(err)

	// 2. Redirect to that node
	redirectUrl := fmt.Sprintf("http://%s/", node.Address)
	fmt.Println(redirectUrl)

	c.Redirect(http.StatusTemporaryRedirect, redirectUrl)
}

And I got 404 using httpie

~  http -f POST :8080/api/v1/ name='file' file@~/Documents/Learning/java --follow
HTTP/1.1 404 Not Found
Content-Length: 18
Content-Type: text/plain
Date: Mon, 15 Apr 2019 14:07:59 GMT
Proxy-Connection: keep-alive

404 page not found

I try every 30X status code, found 308 works fine. But when I post file bigger than 2MB, this Redirect function goes failed again, shows error below:

~ http -f POST :8080/api/v1/ name='file' file@~/Documents/Learning/kotlin-docs.pdf --all

http: error: ConnectionError: ('Connection aborted.', BrokenPipeError(32, 'Broken pipe')) while doing POST request to URL: http://localhost:8080/api/v1/

Anybody can help me~~~ 🤒

I meet the same problem
I use @tscolari 's cdde and I am sure the code is 302
but when I request in postman or by go, it will return 404

tscolari this problem is solved ? I am meeting this problem

Im sorry but I haven’t used this library in a while, so I can’t comment.
But #444 (comment) this makes sense to me as a intended behaviour. I’m just not sure why the 301/302 status are not working for some, if did for me back then 🤔