英文:
Go http panic serving
问题
我得到了这个错误信息:
C:\Users\loow\Desktop\USBWebserver v8.5\duplicate_submissions>go run server.go
2015/10/23 13:00:39 http: panic serving [::1]:63867: runtime error: invalid memo
ry address or nil pointer dereference
goroutine 5 [running]:
net/http.(*conn).serve.func1(0xc0820a1810, 0x3b55b8, 0xc082024040)
c:/go/src/net/http/server.go:1287 +0xbc
main.login(0x2990058, 0xc0820d4000, 0xc0820be1c0)
C:/Users/loow/Desktop/USBWebserver v8.5/duplicate_submissions/server.go:
27 +0x5a5
net/http.HandlerFunc.ServeHTTP(0x8326a8, 0x2990058, 0xc0820d4000, 0xc0820be1c0)
c:/go/src/net/http/server.go:1422 +0x41
net/http.(*ServeMux).ServeHTTP(0xc082062360, 0x2990058, 0xc0820d4000, 0xc0820be1
c0)
c:/go/src/net/http/server.go:1699 +0x184
net/http.serverHandler.ServeHTTP(0xc08200c360, 0x2990058, 0xc0820d4000, 0xc0820b
e1c0)
c:/go/src/net/http/server.go:1862 +0x1a5
net/http.(*conn).serve(0xc0820a1810)
c:/go/src/net/http/server.go:1361 +0xbf5
created by net/http.(*Server).Serve
c:/go/src/net/http/server.go:1910 +0x3fd
2015/10/23 13:00:39 http: panic serving [::1]:63868: runtime error: invalid memo
ry address or nil pointer dereference
goroutine 33 [running]:
net/http.(*conn).serve.func1(0xc082114000, 0x3b55b8, 0xc082112000)
c:/go/src/net/http/server.go:1287 +0xbc
main.login(0x2990058, 0xc0821140b0, 0xc0821200e0)
C:/Users/loow/Desktop/USBWebserver v8.5/duplicate_submissions/server.go:
27 +0x5a5
net/http.HandlerFunc.ServeHTTP(0x8326a8, 0x2990058, 0xc0821140b0, 0xc0821200e0)
c:/go/src/net/http/server.go:1422 +0x41
net/http.(*ServeMux).ServeHTTP(0xc082062360, 0x2990058, 0xc0821140b0, 0xc0821200
e0)
c:/go/src/net/http/server.go:1699 +0x184
net/http.serverHandler.ServeHTTP(0xc08200c360, 0x2990058, 0xc0821140b0, 0xc08212
00e0)
c:/go/src/net/http/server.go:1862 +0x1a5
net/http.(*conn).serve(0xc082114000)
c:/go/src/net/http/server.go:1361 +0xbf5
created by net/http.(*Server).Serve
c:/go/src/net/http/server.go:1910 +0x3fd
exit status 2
这是你的代码:
package main
import(
"fmt"
"net/http"
"html/template"
"log"
"time"
"crypto/md5"
"io"
"strconv"
)
func loginForm(w http.ResponseWriter, r *http.Request){
}
func login(w http.ResponseWriter, r *http.Request){
fmt.Println(r.Method)
if r.Method == "GET"{
cruTime := time.Now().Unix()
h := md5.New()
io.WriteString(h,strconv.FormatInt(cruTime,10))
token := fmt.Sprintf("%x", h.Sum(nil))
fmt.Println(token)
t, err := template.ParseFiles("templates/index.gtpl")
fmt.Println(err.Error())
err = t.Execute(w, token)
fmt.Println(err.Error())
} else{
r.ParseForm()
token := r.Form.Get("token")
if token != ""{
fmt.Println(token)
} else{
fmt.Println("There is no token")
}
fmt.Println("username length: ", len(r.Form["username"][0]))
fmt.Println("username: ", template.HTMLEscapeString(r.Form.Get("username")))
fmt.Println("password: ", template.HTMLEscapeString(r.Form.Get("password")))
template.HTMLEscape(w, []byte(r.Form.Get("username")))
}
}
func main(){
http.HandleFunc("/", loginForm)
http.HandleFunc("/login", login)
err := http.ListenAndServe(":9090", nil)
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
这是模板文件:
<input type="checkbox" name="interest" value="football">Football
<input type="checkbox" name="interest" value="basketball">Basketball
<input type="checkbox" name="interest" value="tennis">Tennis
Username: <input type="text" name="username">
Password: <input type="password" name="password">
<input type="hidden" name="token" value="{{.}}">
<input type="submit" value="Login">
我无法修复它,我尝试了在stackoverflow上找到的所有方法。问题是什么?没有错误,但是panic显示问题出在t, err := template.ParseFiles("templates/index.gtpl")
这一行。
英文:
I got this panic:
C:\Users\loow\Desktop\USBWebserver v8.5\duplicate_submissions>go run server.go
2015/10/23 13:00:39 http: panic serving [::1]:63867: runtime error: invalid memo
ry address or nil pointer dereference
goroutine 5 [running]:
net/http.(*conn).serve.func1(0xc0820a1810, 0x3b55b8, 0xc082024040)
c:/go/src/net/http/server.go:1287 +0xbc
main.login(0x2990058, 0xc0820d4000, 0xc0820be1c0)
C:/Users/loow/Desktop/USBWebserver v8.5/duplicate_submissions/server.go:
27 +0x5a5
net/http.HandlerFunc.ServeHTTP(0x8326a8, 0x2990058, 0xc0820d4000, 0xc0820be1c0)
c:/go/src/net/http/server.go:1422 +0x41
net/http.(*ServeMux).ServeHTTP(0xc082062360, 0x2990058, 0xc0820d4000, 0xc0820be1
c0)
c:/go/src/net/http/server.go:1699 +0x184
net/http.serverHandler.ServeHTTP(0xc08200c360, 0x2990058, 0xc0820d4000, 0xc0820b
e1c0)
c:/go/src/net/http/server.go:1862 +0x1a5
net/http.(*conn).serve(0xc0820a1810)
c:/go/src/net/http/server.go:1361 +0xbf5
created by net/http.(*Server).Serve
c:/go/src/net/http/server.go:1910 +0x3fd
2015/10/23 13:00:39 http: panic serving [::1]:63868: runtime error: invalid memo
ry address or nil pointer dereference
goroutine 33 [running]:
net/http.(*conn).serve.func1(0xc082114000, 0x3b55b8, 0xc082112000)
c:/go/src/net/http/server.go:1287 +0xbc
main.login(0x2990058, 0xc0821140b0, 0xc0821200e0)
C:/Users/loow/Desktop/USBWebserver v8.5/duplicate_submissions/server.go:
27 +0x5a5
net/http.HandlerFunc.ServeHTTP(0x8326a8, 0x2990058, 0xc0821140b0, 0xc0821200e0)
c:/go/src/net/http/server.go:1422 +0x41
net/http.(*ServeMux).ServeHTTP(0xc082062360, 0x2990058, 0xc0821140b0, 0xc0821200
e0)
c:/go/src/net/http/server.go:1699 +0x184
net/http.serverHandler.ServeHTTP(0xc08200c360, 0x2990058, 0xc0821140b0, 0xc08212
00e0)
c:/go/src/net/http/server.go:1862 +0x1a5
net/http.(*conn).serve(0xc082114000)
c:/go/src/net/http/server.go:1361 +0xbf5
created by net/http.(*Server).Serve
c:/go/src/net/http/server.go:1910 +0x3fd
exit status 2
Whit this code:
package main
import(
"fmt"
"net/http"
"html/template"
"log"
"time"
"crypto/md5"
"io"
"strconv"
)
func loginForm(w http.ResponseWriter, r *http.Request){
}
func login(w http.ResponseWriter, r *http.Request){
fmt.Println(r.Method)
if r.Method == "GET"{
cruTime := time.Now().Unix()
h := md5.New()
io.WriteString(h,strconv.FormatInt(cruTime,10))
token := fmt.Sprintf("%x", h.Sum(nil))
fmt.Println(token)
t, err := template.ParseFiles("templates/index.gtpl")
fmt.Println(err.Error())
err = t.Execute(w, token)
fmt.Println(err.Error())
} else{
r.ParseForm()
token := r.Form.Get("token")
if token != ""{
fmt.Println(token)
} else{
fmt.Println("There is no token")
}
fmt.Println("username length: ", len(r.Form["username"][0]))
fmt.Println("username: ", template.HTMLEscapeString(r.Form.Get("username")))
fmt.Println("password: ", template.HTMLEscapeString(r.Form.Get("password")))
template.HTMLEscape(w, []byte(r.Form.Get("username")))
}
}
func main(){
http.HandleFunc("/", loginForm)
http.HandleFunc("/login", login)
err := http.ListenAndServe(":9090", nil)
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
I cant fix it, I tried everything what I found in the stackoverflow. What is the problem? There is no error, and the panic said that the problem in t, err := template.ParseFiles("templates/index.gtpl")..
There is the template file:
<input type="checkbox" name="interest" value="football">Football
<input type="checkbox" name="interest" value="basketball">Basketball
<input type="checkbox" name="interest" value="tennis">Tennis
Username: <input type="text" name="username">
Password: <input type="password" name="password">
<input type="hidden" name="token" value="{{.}}">
<input type="submit" value="Login">
答案1
得分: 6
恐慌堆栈跟踪提供了以下信息:
2015/10/23 13:00:39 http: panic serving [::1]:63868: runtime error: invalid memory address or nil pointer dereference goroutine 33 [running]:
这意味着您正在尝试访问不存在的内容(nil指针)。
然后,来自您的文件的第一行是:
v8.5/duplicate_submissions/server.go:27
它在这里:
26: t, err := template.ParseFiles("templates/index.gtpl")
27: fmt.Println(err.Error())
28: err = t.Execute(w, token)
这意味着err是nil。
解决方案
如果出现错误,您无法继续进程。这就是为什么您不能只是打印出错误的原因。为了优雅地停止进程,您需要返回一个HTTP状态码,然后返回。对于上面的情况,您可以返回一个500代码(内部服务器错误)。
t, err := template.ParseFiles("templates/index.gtpl")
if err != nil {
fmt.Println(err) // 丑陋的调试输出
w.WriteHeader(http.StatusInternalServerError) // 正确的HTTP响应
return
}
对于template.ParseFiles和t.Execute也需要这样做。
顺便说一下,这被称为“comma ok”模式。
英文:
The panic stacktrace gives you this info :
2015/10/23 13:00:39 http: panic serving [::1]:63868: runtime error: invalid memory address or nil pointer dereference goroutine 33 [running]:
It means you're trying to access something that does not exist (nil pointer).
Then the first line that comes from your file is this one :
v8.5/duplicate_submissions/server.go:27
Which is there :
26: t, err := template.ParseFiles("templates/index.gtpl")
27: fmt.Println(err.Error())
28: err = t.Execute(w, token)
It means err is nil.
Solution
If you get the error, you cannot continue the process. That's the reason why you cannot just print out the error. In order to stop gracefully the process, you need to return an HTTP status code and then return. For the case above, you can return a code 500 (internal server error).
t, err := template.ParseFiles("templates/index.gtpl")
if err != nil {
fmt.Println(err) // Ugly debug output
w.WriteHeader(http.StatusInternalServerError) // Proper HTTP response
return
}
That has to be done for a template.ParseFiles and t.Execute too.
By the way, that is called the "comma ok" pattern
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论