发生了 HTTP 服务崩溃。

huangapple go评论104阅读模式
英文:

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&gt;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(
	&quot;fmt&quot;
	&quot;net/http&quot;
	&quot;html/template&quot;
	&quot;log&quot;
	&quot;time&quot;
	&quot;crypto/md5&quot;
	&quot;io&quot;
	&quot;strconv&quot;
)

func loginForm(w http.ResponseWriter, r *http.Request){

}

func login(w http.ResponseWriter, r *http.Request){
	fmt.Println(r.Method)
	if r.Method == &quot;GET&quot;{
		cruTime := time.Now().Unix()
		h := md5.New()
		io.WriteString(h,strconv.FormatInt(cruTime,10))
		token := fmt.Sprintf(&quot;%x&quot;, h.Sum(nil))
		fmt.Println(token)
		t, err := template.ParseFiles(&quot;templates/index.gtpl&quot;)
		fmt.Println(err.Error())
		err = t.Execute(w, token)
		fmt.Println(err.Error())
	} else{
		r.ParseForm()
		token := r.Form.Get(&quot;token&quot;)
		if token != &quot;&quot;{
			fmt.Println(token)
		} else{
			fmt.Println(&quot;There is no token&quot;)
		}
		fmt.Println(&quot;username length: &quot;, len(r.Form[&quot;username&quot;][0]))
		fmt.Println(&quot;username: &quot;, template.HTMLEscapeString(r.Form.Get(&quot;username&quot;)))
		fmt.Println(&quot;password: &quot;, template.HTMLEscapeString(r.Form.Get(&quot;password&quot;)))
		template.HTMLEscape(w, []byte(r.Form.Get(&quot;username&quot;)))

	}
}

func main(){
	http.HandleFunc(&quot;/&quot;, loginForm)
	http.HandleFunc(&quot;/login&quot;, login)
	err := http.ListenAndServe(&quot;:9090&quot;, nil)
	if err != nil {
		log.Fatal(&quot;ListenAndServe: &quot;, 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:

&lt;input type=&quot;checkbox&quot; name=&quot;interest&quot; value=&quot;football&quot;&gt;Football
&lt;input type=&quot;checkbox&quot; name=&quot;interest&quot; value=&quot;basketball&quot;&gt;Basketball
&lt;input type=&quot;checkbox&quot; name=&quot;interest&quot; value=&quot;tennis&quot;&gt;Tennis
Username: &lt;input type=&quot;text&quot; name=&quot;username&quot;&gt;
Password: &lt;input type=&quot;password&quot; name=&quot;password&quot;&gt;
&lt;input type=&quot;hidden&quot; name=&quot;token&quot; value=&quot;{{.}}&quot;&gt;
&lt;input type=&quot;submit&quot; value=&quot;Login&quot;&gt;

答案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.ParseFilest.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(&quot;templates/index.gtpl&quot;)
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(&quot;templates/index.gtpl&quot;)
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

huangapple
  • 本文由 发表于 2015年10月23日 19:07:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/33300868.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定