curl - 用于文件上传但不使用 ParseMultipartForm 的 GO REST 端点

标签 curl go

这里是新手。我正在尝试使用 RESTful API 构建一个 Web 服务器,以便我可以测试用于文件上传的 curl 命令。我能够创建网络服务器和文件上传端点。

这是我的上传端点:

func Upload(w http.ResponseWriter, r *http.Request) {
    if err := r.ParseMultipartForm(MAX_MEMORY); err != nil {
        log.Println(err)
        http.Error(w, err.Error(), http.StatusForbidden)
    }

    fmt.Println("Endpoint hit: Upload")

    for key, value := range r.MultipartForm.Value {
        fmt.Fprintf(w, "%s:%s ", key, value)
        log.Printf("%s:%s", key, value)
    }

    for _, fileHeaders := range r.MultipartForm.File {
        for _, fileHeader := range fileHeaders {
            file, _ := fileHeader.Open()
            path := fmt.Sprintf("files/%s", fileHeader.Filename)
            buf, _ := ioutil.ReadAll(file)
            ioutil.WriteFile(path, buf, os.ModePerm)
            log.Println(http.StatusOK, fmt.Sprintf("file %s has been uploaded", fileHeader.Filename))
        }
    }
}

此端点适用于以下 curl 命令:

curl -F 'data=@/path/to/file/foo.tar.gz' localhost:8080/upload

但是,这个 curl 命令不会:

curl -f -s -S -T /path/to/file/foo.tar.gz http://localhost:8080/upload
curl: (22) The requested URL returned error: 405 Method Not Allowed

我需要帮助创建一个端点来接受

curl -f -s -S -T /path/to/file/foo.tar.gz http://localhost:8080/upload

谢谢。

编辑:这是我的 routes.go 文件。

package main

import (
    "net/http"
    "github.com/gorilla/mux"
)

type Route struct {
    Name        string
    Method      string
    Pattern     string
    HandlerFunc http.HandlerFunc
}

type Routes []Route

func NewRouter() *mux.Router {
    router := mux.NewRouter().StrictSlash(true)
    for _, route := range routes {
        router.
        Methods(route.Method).
        Path(route.Pattern).
        Name(route.Name).
        Handler(route.HandlerFunc)
    }

    return router
}


var routes = Routes{
    Route{
        "Index",
        "GET",
        "/",
        Index,
    },
    Route{
        "Upload",
        "POST",
        "/upload",
        Upload,
    },
}

最佳答案

使用 curl -f -s -S -T/path/to/file/foo.tar.gz http://localhost:8080/upload 没有任何额外的选项来设置内容type,如果有这样的选项(我不确定,我的 curl 知识几乎不存在),您发送的请求带有最少的 header ,没有一个 header 指示内容的类型。

例如,记录 r.Header 将打印如下内容:

map[Accept:[*/*] Content-Length:[18] Expect:[100-continue] User-Agent:[curl/7.54.0]]

这意味着您的 Upload 处理程序中的所有多部分代码都不是必需的。


正文的内容是您想要的,因此您可以使用io.Copy 将该正文存储到文件中。

func Upload(w http.ResponseWriter, r *http.Request) {
    f, err := os.Create("filename")
    if err != nil {
        panic(err)
    }
    defer f.Close()

    if _, err := io.Copy(f, r.Body); err != nil {
        panic(err)
    }
    if err := f.Sync(); err != nil {
        panic(err)
    }
    fmt.Fprintln(w, "upload done...")
}

由于您使用的是 curl -f -s -S -T ... Upload 处理程序不知道上传的名称和类型正在上传的文件是,您将必须生成一个随机名称、时间戳名称或任何其他名称,以便能够创建和存储多个文件。

您还可以在查询参数中传递一些文件信息(名称、类型),但我不确定这是否满足您的要求。例如

curl -f -s -S -T /path/to/file/foo.tar.gz http://localhost:8080/upload?name=foo.tar.gz

关于curl - 用于文件上传但不使用 ParseMultipartForm 的 GO REST 端点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47414940/

相关文章:

php - Mac OS X 10.9 连接到的未知 SSL 协议(protocol)错误

xml - 如何将混合元素的 xml 序列映射到 go 结构?

go - 从访问 token 获取 Google 登录个人资料信息 - Golang

go - 有没有一种方法可以在不使用自定义结构的情况下检索实体?

go - 如何从远程机器连接到kubernetes pod?

linux - 能不能不安装直接复制curl包在linux上运行

php - cURL 使用字符串发布多个值

curl - 如何修复libeay32.dll找不到错误

c# - C# 中带标志的 cURL 调用

go - Logrus条目没有“缓冲区”字段