// Handle writes the error from the context into the HttpResponseWriter with a // 500 http.StatusInternalServerError status code. func (h *DefaultErrorHandler) Handle(ctx context.Context) (stop bool, err error) { var handlerError HandlerError = ctx.Data().Get(DataKeyForError).Data().(HandlerError) hostname, _ := os.Hostname() w := ctx.HttpResponseWriter() // write the error out w.Header().Set("Content-Type", "text/html") w.WriteHeader(http.StatusInternalServerError) w.Write([]byte("<!DOCTYPE html><html><head>")) w.Write([]byte("<style>")) w.Write([]byte("h1 { font-size: 17px }")) w.Write([]byte("h1 strong {text-decoration:underline}")) w.Write([]byte("h2 { background-color: #ffd; padding: 20px }")) w.Write([]byte("footer { margin-top: 20px; border-top:1px solid black; padding:10px; font-size:0.9em }")) w.Write([]byte("</style>")) w.Write([]byte("</head><body>")) w.Write([]byte(fmt.Sprintf("<h1>Error in <code>%s</code></h1><h2>%s</h2>", handlerError.Handler, handlerError))) w.Write([]byte(fmt.Sprintf("<h3><code>%s</code> error in Handler <code>%v</code></h3> <code><pre>%s</pre></code>", reflect.TypeOf(handlerError.OriginalError), &handlerError.Handler, handlerError.Handler))) w.Write([]byte(fmt.Sprintf("on %s", hostname))) w.Write([]byte("<footer>Learn more about <a href='http://github.com/stretchr/goweb' target='_blank'>Goweb</a></footer>")) w.Write([]byte("</body></html>")) // responses are actually ignored return false, nil }
// WillHandle checks whether this handler will be used to handle the specified // request or not. func (p *PathMatchHandler) WillHandle(c context.Context) (bool, error) { // check each matcher func matcherFuncMatches := true matcherFuncDecisionMade := false for _, matcherFunc := range p.MatcherFuncs { decision, matcherFuncErr := matcherFunc(c) if matcherFuncErr != nil { return false, matcherFuncErr } switch decision { case NoMatch: matcherFuncMatches = false matcherFuncDecisionMade = true break case Match: matcherFuncMatches = true matcherFuncDecisionMade = true break } if matcherFuncDecisionMade { break } } // check HTTP methods var httpMethodMatch bool = false if len(p.HttpMethods) == 0 { // no specific HTTP methods httpMethodMatch = true } else { for _, httpMethod := range p.HttpMethods { if httpMethod == c.MethodString() { httpMethodMatch = true break } } } // cancel early if we didn't get an HTTP Method match if !httpMethodMatch { return false, nil } // check path match pathMatch := p.PathPattern.GetPathMatch(c.Path()) var allMatch bool if matcherFuncDecisionMade { allMatch = matcherFuncMatches } else { allMatch = pathMatch.Matches } if allMatch { // save the match parameters for later c.Data().Set(context.DataKeyPathParameters, pathMatch.Parameters) } return allMatch, nil }