使用go的HTTP PUT请求处理程序

时间:2019-06-07 20:46:10

标签: go put

请考虑以下示例Go代码段

package main

import (
        "fmt"
        "log"
        "net/http"
        "time"
)

func main() {
        listen_at := ":3114"
        go http.Handle("/", http.FileServer(http.Dir(".")))
        //go http.Handle("/max", http.FileServer(http.Dir("."))) <-- Fails
        go http.HandleFunc("/ping", ping_handler)
        log.Fatal(http.ListenAndServe(listen_at, nil))

}

func ping_handler(w http.ResponseWriter, r *http.Request) {
        a := time.Now()
        layout := "2006-01-02-03-04-05-000"

        fmt.Println("Got root!")
        fmt.Println("r is", r)
        fmt.Println("RemoteAddr is", r.RemoteAddr)
        send_this := "OK GOT ping! " + a.Format(layout)
        w.Write([]byte(send_this))
}

我有两个问题:

(1)如何更改FileServer使其服务于/max而不是/-我的尝试失败了,我得到了http://localhost:3114/max/http://localhost:3114/max的404。

(2)我希望接受对PUT的{​​{1}}请求-我该如何实现?

请为我指出正确的方向,谢谢!

编辑1

/max

我以package main import ( "fmt" "log" "net/http" ) func main() { go http.HandleFunc("/ping", hello) log.Fatal(http.ListenAndServe(":3114", nil)) } func hello(w http.ResponseWriter, r *http.Request) { fmt.Println("STarting hello!") log.Println("Got connection") if r.URL.Path != "/ping" { http.Error(w, "404 not found", http.StatusNotFound) return } log.Println("Method:", r.Method) switch r.Method { case "GET": send_this := "OK GOT ping! " w.Write([]byte(send_this)) case "PUT": fmt.Println("We got put!") err := r.ParseForm() checkErr(err) fmt.Println("r now", r) fmt.Println("r.Form", r.Form) fmt.Println("r.PostForm", r.PostForm) default: send_this := "Please dont!" w.Write([]byte(send_this)) fmt.Fprintf(w, "Unknown request!") } } func checkErr(err error) { if err != nil { fmt.Println("Error", err) } } 的形式发送PUT请求,它显示:

curl -k http://localhost:3114/ping -T /tmp/a.go  -v

如何找到实际数据以及从PUT输入的文件名?

1 个答案:

答案 0 :(得分:2)

来自https://golang.org/pkg/net/http/#ServeMux

  

模式名称固定的,已植根的路径,例如“ /favicon.ico”或已植根   子树,例如“ / images /”(注意斜杠)

这意味着/max(是固定的植根路径)将仅匹配/max和模式/max/(以植根)子树,将匹配/max/,以/max/开头的任何其他路径,默认情况下,它将也匹配/max

http.Handle("/max/", http.FileServer(http.Dir(".")))

根据.目录的布局,您可能需要使用https://golang.org/pkg/net/http/#StripPrefix

假设您的目录包含两个文件:

.
├── foo.txt
└── max
    └── bar.txt

鉴于上述处理程序,对/max/bar.txt的请求将返回bar.txt文件,而对/max/foo.txt/foo.txt的请求将返回404,否文件。

因此,如果您想通过/max/路径提供文件,但是您的.目录没有max子目录,则可以使用StripPrefix在将请求传递到/max之前,从请求的url路径中删除FileServer前缀。

http.Handle("/max/", http.StripPrefix("/max/", http.FileServer(http.Dir("."))))

要以相同的方式处理PUT请求,您需要一个自定义处理程序。

type myhandler struct {
    fs http.Handler
}

func (h myhandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    if r.Method != "PUT" {
        // business as usual
        h.fs.ServeHTTP(w, r)
        return
    }

    // handle PUT
    // ...
}

然后进行注册,请执行以下操作:

fs := http.StripPrefix("/max/", http.FileServer(http.Dir(".")))
http.Handle("/max/", myhandler{fs: fs})