提交 8ad11414 作者: Jeromy

fixup panic catching in http handler funcs

License: MIT
Signed-off-by: 's avatarJeromy <jeromyj@gmail.com>
上级 2f9c894b
......@@ -6,8 +6,7 @@ import (
"io"
"net/http"
"net/url"
"os"
"runtime"
"runtime/debug"
"strconv"
"strings"
"sync"
......@@ -92,7 +91,7 @@ func skipAPIHeader(h string) bool {
}
}
func NewHandler(ctx cmds.Context, root *cmds.Command, cfg *ServerConfig) *Handler {
func NewHandler(ctx cmds.Context, root *cmds.Command, cfg *ServerConfig) http.Handler {
if cfg == nil {
panic("must provide a valid ServerConfig")
}
......@@ -114,14 +113,33 @@ func (i internalHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
defer func() {
if r := recover(); r != nil {
log.Error("A panic has occurred in the commands handler!")
log.Error(r)
buf := make([]byte, 4096)
n := runtime.Stack(buf, false)
fmt.Fprintln(os.Stderr, string(buf[:n]))
debug.PrintStack()
}
}()
// get the node's context to pass into the commands.
node, err := i.ctx.GetNode()
if err != nil {
s := fmt.Sprintf("cmds/http: couldn't GetNode(): %s", err)
http.Error(w, s, http.StatusInternalServerError)
return
}
ctx, cancel := context.WithCancel(node.Context())
defer cancel()
if cn, ok := w.(http.CloseNotifier); ok {
go func() {
select {
case <-cn.CloseNotify():
case <-ctx.Done():
}
cancel()
}()
}
if !allowOrigin(r, i.cfg) || !allowReferer(r, i.cfg) {
w.WriteHeader(http.StatusForbidden)
w.Write([]byte("403 - Forbidden"))
......@@ -140,29 +158,9 @@ func (i internalHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
return
}
// get the node's context to pass into the commands.
node, err := i.ctx.GetNode()
if err != nil {
s := fmt.Sprintf("cmds/http: couldn't GetNode(): %s", err)
http.Error(w, s, http.StatusInternalServerError)
return
}
//ps: take note of the name clash - commands.Context != context.Context
req.SetInvocContext(i.ctx)
ctx, cancel := context.WithCancel(node.Context())
defer cancel()
if cn, ok := w.(http.CloseNotifier); ok {
go func() {
select {
case <-cn.CloseNotify():
case <-ctx.Done():
}
cancel()
}()
}
err = req.SetRootContext(ctx)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
......
......@@ -6,6 +6,7 @@ import (
"io"
"net/http"
gopath "path"
"runtime/debug"
"strings"
"time"
......@@ -55,6 +56,14 @@ func (i *gatewayHandler) newDagFromReader(r io.Reader) (*dag.Node, error) {
// TODO(btc): break this apart into separate handlers using a more expressive muxer
func (i *gatewayHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
defer func() {
if r := recover(); r != nil {
log.Error("A panic occurred in the gateway handler!")
log.Error(r)
debug.PrintStack()
}
}()
if i.config.Writable {
switch r.Method {
case "POST":
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论