如何使用 Swag golang 库下载文件?

How to download files using Swag golang library?

我正在尝试使用 golang[=] 中的 gin-gonic 创建一个 REST API 36=],它从 GET 请求和 下载 该文件中获取一些路径参数。

curl 命令可以正常工作。 但是,当我添加 swagger UI 文档时,如果下载的文件是文本或图像,它只是显示在该网页中,但我看不到任何下载选项.此外,如果我输入视频文件的路径,浏览器会挂起。

此外,要下载的文件的 MIME 类型由 gin-gonic 正确确定。但是,要通过 swagger UI 接口 下载文件,我使用的是硬编码 @Accept & @Produce swagger UI 评论注释。理想情况下,它应该自动确定 MIME 类型。

目前,响应类型列为下拉列表,我可以在其中获得各种选项。 我需要它来自动检测正确的 MIME 类型并在可能的情况下显示 下载 按钮

我的 GET 请求代码是:

// DownloadObject godoc
// @Summary Download object
// @Description Download object
// @Produce application/json
// @Produce text/plain
// @Produce application/octet-stream
// @Produce video/mp4
// @Produce image/png
// @Produce image/jpeg
// @Produce image/gif
// @Param rootPath path string true "Root Path"
// @Param filePath path string true "File Path"
// @Header 200 {string} Token "qwerty"
// @Router /transfer/{rootPath}/{filePath} [get]
func DownloadObject(c *gin.Context) {

    // Get rootPath & filePath from GET request
    rootPath := c.Param("rootPath")
    filePath := c.Param("filePath")


    // Some code to get an io.Reader object "download"

    _, err = io.Copy(c.Writer, download)
    if err != nil {
        c.Status(http.StatusInternalServerError)
        log.Print(err)
        return
    }

    err = download.Close()
    if err != nil {
        c.Status(http.StatusInternalServerError)
        log.Print(err)
        return
    }
    
    c.Writer.Header().Add("Content-Disposition", fmt.Sprintf("attachment; filename=%", filePath))
    c.Writer.Header().Add("Content-Type", c.GetHeader("Content-Type"))
    // Object download completed & closed successfully

}

我是不是漏掉了什么?

您要在浏览器收到文件后添加 headers,将它们移到 io.Copy 之前才能生效。此外,您在 fmt.Sprintf 调用中有一个错误的格式动词(只是 %),请使用 %q:

func DownloadObject(c *gin.Context) {

    // Get rootPath & filePath from GET request
    rootPath := c.Param("rootPath")
    filePath := c.Param("filePath")

    // ...

    // Add headers to the response
    c.Writer.Header().Add("Content-Disposition", fmt.Sprintf("attachment; filename=%q", filePath))
    c.Writer.Header().Add("Content-Type", c.GetHeader("Content-Type"))


    _, err = io.Copy(c.Writer, download)
    if err != nil {
        c.Status(http.StatusInternalServerError)
        log.Print(err)
        return
    }

    err = download.Close()
    if err != nil {
        c.Status(http.StatusInternalServerError)
        log.Print(err)
        return
    }
    
}