大佬教程收集整理的这篇文章主要介绍了golang server.go 处理head请求的一个小坑,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
虽然是个小坑,可是trace了一个星期,浪费了不少时间,解决方案很简单,思考的过程却是很值得借鉴:)
http web完整代码在:https://github.com/philsong/golang_samples/tree/master/src/emvdecoder
emvdecoder中问题代码片段如下:
func checkError(w http.ResponseWriter,err error) { if err != nil { fmt.Fprintf(w,"Fatal error ",err.Error()) os.Exit(1) } } func index(w http.ResponseWriter,r *http.request) { r.ParseForm() t,err := template.ParseFiles("index.html") checkError(w,err) err = t.Execute(w,emvdecoder) checkError(w,err) }
用nohupemvdecoder&运行后,似乎运行良好了(稍后就知道这是巧合。。。),于是发一微博
继续测试发现其实无论用&, nohup还是setsid, 父进程已经变成了init了,所以效果其实一样,于是猜测是代码的bug(其实又是自己的问题...),但是奇怪为什么没打印出来呢
philsong@compiler:~$ cd go/src/emvdecoder/
philsong@compiler:~/go/src/emvdecoder$ emvdecoder&
[1] 22908
philsong@compiler:~/go/src/emvdecoder$ ps
PID TTY TIME CMD
22729 pts/2 00:00:01 bash
22908 pts/2 00:00:00 emvdecoder
22911 pts/2 00:00:00 ps
philsong@compiler:~/go/src/emvdecoder$ pstree -ps 22908
init(1)---sshd(702)---sshd(22703)---sshd(22728)---bash(22729)---emvdecoder(22908)-+-{emvdecoder}(22909)
`-{emvdecoder}(22910)
断开ssh后,
philsong@compiler:~$ pstree -ps 22908
init(1)---emvdecoder(22908)-+-{emvdecoder}(22909)
|-{emvdecoder}(22910)
|-{emvdecoder}(22916)
`-{emvdecoder}(22917)
,
fuck代码发现
func checkError(w http.ResponseWriter,err.Error()) os.Exit(1) } }
fmt.Fprintf(w由于copy时默认打印到http 的w句柄,并没有打印道控制台,囧啊,改为
fmt.Println("
继续log大法,并打印堆栈
import "runtime/debug"
debug.PrintStack()
func checkError(w http.ResponseWriter,err error) { fmt.Println("error: ") if err != nil { fmt.Println("Fatal error ",err.Error()) debug.PrintStack() os.Exit(1) } } func index(w http.ResponseWriter,r *http.request) { println("request ",r.URl.Path," from ",r.RemoteAddr) // path := r.URl.Path[1:] path := "." + r.URl.Path fmt.Println("path",path) if path == "./favicon.ico" { http.NotFound(w,r) return } r.ParseForm() t,err) }
request / from 208.94.145.109:22492
path ./
error:
error:
Fatal error template: index.html:1:0: execuTing "index.html" at <"<!DOCTYPE HTML>\r\n...>: http: request method or response status code does not allow body
/home/philsong/go/src/emvdecoder/emvdecoder.go:47 (0x8048d50)
checkError: debug.PrintStack()
/home/philsong/go/src/emvdecoder/emvdecoder.go:69 (0x80490a5)
index: checkError(w,err)
/usr/local/go/src/pkg/net/http/server.go:1149 (0x809936C)
HandlerFunc.Servehttp: f(w,r)
/usr/local/go/src/pkg/net/http/server.go:1416 (0x809a39d)
(*ServeMuX).Servehttp: h.Servehttp(w,r)
/usr/local/go/src/pkg/net/http/server.go:1517 (0x809aa21)
serverHandler.Servehttp: handler.Servehttp(rw,req)
/usr/local/go/src/pkg/net/http/server.go:1096 (0x8099073)
(*conn).serve: serverHandler{C.server}.Servehttp(w,w.req)
/usr/local/go/src/pkg/runtime/proc.c:1223 (0x805fd60)
goexit: runtime路goexit(void)
The error is self-explaining:
request method or response status code does not allow body
A HEAD request only allows http headers to be sent BACk as response.
899 func (w *responsE) Write(data []bytE) (n int,err error) { 900 if w.conn.hijacked() { 901 log.Print("http: response.Write on hijacked connection") 902 return 0,ErrHijacked 903 } 904 if !w.wroteHeader { 905 w.WriteHeader(StatusOK) 906 } 907 if len(data) == 0 { 908 return 0,nil 909 } 910 if !w.bodyAllowed() { 911 return 0,ErrBodyNotAllowed 912 } 913 914 w.written += int64(len(data)) // ignoring errors,for errorKludge 915 if w.contentLength != -1 && w.written > w.contentLength { 916 return 0,ErrContentLength 917 } 918 return w.w.Write(data) 919 }猜测是发起的head请求,不是正常的get和post请求,怪不得,直接用浏览器访问时无法重现这个bug,于是用
以上是大佬教程为你收集整理的golang server.go 处理head请求的一个小坑全部内容,希望文章能够帮你解决golang server.go 处理head请求的一个小坑所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。