pomerium/internal/httputil/errors.go
Bobby DeSimone 5edfa7b03f
telemetry: add tracing
- telemetry/tace: add traces throughout code
- telemetry/metrics: nest metrics and trace under telemetry
- telemetry/tace: add service name span to HTTPMetricsHandler.
- telemetry/metrics: removed chain dependency middleware_tests.
- telemetry/metrics: wrap and encapsulate variatic view registration.
- telemetry/tace: add jaeger support for tracing.
- cmd/pomerium: move `parseOptions` to internal/config.
- cmd/pomerium: offload server handling to httputil and sub pkgs.
- httputil: standardize creation/shutdown of http listeners.
- httputil: prefer curve X25519 to P256 when negotiating TLS.
- fileutil: use standardized Getw

Signed-off-by: Bobby DeSimone <bobbydesimone@gmail.com>
2019-07-24 09:20:16 -07:00

67 lines
1.8 KiB
Go

package httputil // import "github.com/pomerium/pomerium/internal/httputil"
import (
"encoding/json"
"fmt"
"io"
"net/http"
"github.com/pomerium/pomerium/internal/log"
"github.com/pomerium/pomerium/internal/templates"
)
// Error reports an http error, its http status code, a custom message, and
// whether it is CanDebug.
type Error struct {
Message string
Code int
CanDebug bool
}
// Error fulfills the error interface, returning a string representation of the error.
func (h Error) Error() string {
return fmt.Sprintf("%d %s: %s", h.Code, http.StatusText(h.Code), h.Message)
}
// ErrorResponse renders an error page for errors given a message and a status code.
// If no message is passed, defaults to the text of the status code.
func ErrorResponse(rw http.ResponseWriter, r *http.Request, e *Error) {
var requestID string
if id, ok := log.IDFromRequest(r); ok {
requestID = id
}
if r.Header.Get("Accept") == "application/json" {
var response struct {
Error string `json:"error"`
}
response.Error = e.Message
writeJSONResponse(rw, e.Code, response)
} else {
rw.WriteHeader(e.Code)
t := struct {
Code int
Title string
Message string
RequestID string
CanDebug bool
}{
Code: e.Code,
Title: http.StatusText(e.Code),
Message: e.Message,
RequestID: requestID,
CanDebug: e.CanDebug,
}
templates.New().ExecuteTemplate(rw, "error.html", t)
}
}
// writeJSONResponse is a helper that sets the application/json header and writes a response.
func writeJSONResponse(rw http.ResponseWriter, code int, response interface{}) {
rw.Header().Set("Content-Type", "application/json")
rw.WriteHeader(code)
err := json.NewEncoder(rw).Encode(response)
if err != nil {
io.WriteString(rw, err.Error())
}
}