请考虑以下示例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输入的文件名?
答案 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})