新手在这里。我正在尝试使用RESTful API构建一个Web服务器,以便我可以测试文件上传的curl命令。我能够创建Web服务器和文件上传端点。
这是我的上传终结点:
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,
},
}
答案 0 :(得分:0)
使用curl -f -s -S -T /path/to/file/foo.tar.gz http://localhost:8080/upload
而没有任何其他可以设置内容类型的选项,如果有这样的选项(我不确定,我的卷曲知识几乎不存在),你发送的请求包含最少的标题,它们都没有表明内容的类型。
例如,记录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
处理程序不知道要上载的文件的名称和类型,您必须生成随机名称或时间戳名称或其他任何东西,以便能够创建和存储多个文件。
您还可以在查询参数中传递一些文件信息(名称,类型),但我不确定这是否满足您的要求。 E.g。
curl -f -s -S -T /path/to/file/foo.tar.gz http://localhost:8080/upload?name=foo.tar.gz