- With issues:
- Use the search tool before opening a new issue.
- Please provide source code and commit sha if you found a bug.
- Review existing issues and provide feedback or react to them.
Description
How to reproduce
package main
import (
"github.com/gin-gonic/gin"
)
func main() {
g := gin.Default()
g.GET("/_download", func(c *gin.Context) {
c.FileAttachment("C:\temp\file", "test.txt")
})
g.Run(":9000")
}
Expectations
Get http://localhost:9000/_download
Actual result
Get http://localhost:9000/_download
[GIN-debug] redirecting request 301: /_download --> /_download
[GIN] 2023/10/17 - 09:41:23 | 301 | 456.6µs | ::1 | GET "/_download"
[GIN-debug] redirecting request 301: /_download --> /_download
[GIN] 2023/10/17 - 09:41:23 | 301 | 412.9µs | ::1 | GET "/_download"
[GIN-debug] redirecting request 301: /_download --> /_download
Environment
- go version: go version go1.21.2 windows/amd64
- gin version (or commit ref): v1.9.1
- operating system: windows10
Comment From: shawn1251
In my experience, the 'redirecting request 301' error often occurs when only the directory path is provided instead of the full file path. Could you please double-check and ensure that the file path is specified?
The solution can be found in the documentation. The filename
argument in the FileAttachment
function is the name that will be used when the file is downloaded on the client side. It is important to provide the full file path instead of just the folder path.
Here is the relevant code snippet:
// FileAttachment writes the specified file into the body stream in an efficient way
// On the client side, the file will typically be downloaded with the given filename
func (c *Context) FileAttachment(filepath, filename string) {
if isASCII(filename) {
c.Writer.Header().Set("Content-Disposition", `attachment; filename="`+escapeQuotes(filename)+`"`)
} else {
c.Writer.Header().Set("Content-Disposition", `attachment; filename*=UTF-8''`+url.QueryEscape(filename))
}
http.ServeFile(c.Writer, c.Request, filepath)
}
Make sure to include the complete file path in the filepath
parameter for the function to work correctly.
Comment From: ergudu
Here is the relevant code snippet: if d.IsDir() { url := r.URL.Path // redirect if the directory name doesn't end in a slash if url == "" || url[len(url)-1] != '/' { localRedirect(w, r, path.Base(url)+"/") return } }
Therefore, the correct way to write it is to add "/":
package main
import ( "github.com/gin-gonic/gin" )
func main() { g := gin.Default() g.GET("/_download/", func(c *gin.Context) { c.FileAttachment("C:\temp\file", "test.txt") }) g.Run(":9000") }
GET http://localhost:9000/_download/