Allow overriding of the default response format (#7245)
Rather than hard-coding the default response format as HTML, allow the default to be overridden by an environment variable. For example, given a REST API endpoint that defaults to responding in JSON, you may wish to configure the error messages to be JSON by default as well.
This commit is contained in:
parent
9c22ba93b2
commit
e5e33051b9
1 changed files with 26 additions and 5 deletions
|
@ -62,6 +62,12 @@ const (
|
||||||
// ErrFilesPathVar is the name of the environment variable indicating
|
// ErrFilesPathVar is the name of the environment variable indicating
|
||||||
// the location on disk of files served by the handler.
|
// the location on disk of files served by the handler.
|
||||||
ErrFilesPathVar = "ERROR_FILES_PATH"
|
ErrFilesPathVar = "ERROR_FILES_PATH"
|
||||||
|
|
||||||
|
// DefaultFormatVar is the name of the environment variable indicating
|
||||||
|
// the default error MIME type that should be returned if either the
|
||||||
|
// client does not specify an Accept header, or the Accept header provided
|
||||||
|
// cannot be mapped to a file extension.
|
||||||
|
DefaultFormatVar = "DEFAULT_RESPONSE_FORMAT"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -75,7 +81,12 @@ func main() {
|
||||||
errFilesPath = os.Getenv(ErrFilesPathVar)
|
errFilesPath = os.Getenv(ErrFilesPathVar)
|
||||||
}
|
}
|
||||||
|
|
||||||
http.HandleFunc("/", errorHandler(errFilesPath))
|
defaultFormat := "text/html"
|
||||||
|
if os.Getenv(DefaultFormatVar) != "" {
|
||||||
|
defaultFormat = os.Getenv(DefaultFormatVar)
|
||||||
|
}
|
||||||
|
|
||||||
|
http.HandleFunc("/", errorHandler(errFilesPath, defaultFormat))
|
||||||
|
|
||||||
http.Handle("/metrics", promhttp.Handler())
|
http.Handle("/metrics", promhttp.Handler())
|
||||||
|
|
||||||
|
@ -86,10 +97,16 @@ func main() {
|
||||||
http.ListenAndServe(fmt.Sprintf(":8080"), nil)
|
http.ListenAndServe(fmt.Sprintf(":8080"), nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func errorHandler(path string) func(http.ResponseWriter, *http.Request) {
|
func errorHandler(path, defaultFormat string) func(http.ResponseWriter, *http.Request) {
|
||||||
|
defaultExts, err := mime.ExtensionsByType(defaultFormat)
|
||||||
|
if err != nil || len(defaultExts) == 0 {
|
||||||
|
panic("couldn't get file extension for default format")
|
||||||
|
}
|
||||||
|
defaultExt := defaultExts[0]
|
||||||
|
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
ext := "html"
|
ext := defaultExt
|
||||||
|
|
||||||
if os.Getenv("DEBUG") != "" {
|
if os.Getenv("DEBUG") != "" {
|
||||||
w.Header().Set(FormatHeader, r.Header.Get(FormatHeader))
|
w.Header().Set(FormatHeader, r.Header.Get(FormatHeader))
|
||||||
|
@ -105,14 +122,14 @@ func errorHandler(path string) func(http.ResponseWriter, *http.Request) {
|
||||||
|
|
||||||
format := r.Header.Get(FormatHeader)
|
format := r.Header.Get(FormatHeader)
|
||||||
if format == "" {
|
if format == "" {
|
||||||
format = "text/html"
|
format = defaultFormat
|
||||||
log.Printf("format not specified. Using %v", format)
|
log.Printf("format not specified. Using %v", format)
|
||||||
}
|
}
|
||||||
|
|
||||||
cext, err := mime.ExtensionsByType(format)
|
cext, err := mime.ExtensionsByType(format)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("unexpected error reading media type extension: %v. Using %v", err, ext)
|
log.Printf("unexpected error reading media type extension: %v. Using %v", err, ext)
|
||||||
format = "text/html"
|
format = defaultFormat
|
||||||
} else if len(cext) == 0 {
|
} else if len(cext) == 0 {
|
||||||
log.Printf("couldn't get media type extension. Using %v", ext)
|
log.Printf("couldn't get media type extension. Using %v", ext)
|
||||||
} else {
|
} else {
|
||||||
|
@ -131,6 +148,10 @@ func errorHandler(path string) func(http.ResponseWriter, *http.Request) {
|
||||||
if !strings.HasPrefix(ext, ".") {
|
if !strings.HasPrefix(ext, ".") {
|
||||||
ext = "." + ext
|
ext = "." + ext
|
||||||
}
|
}
|
||||||
|
// special case for compatibility
|
||||||
|
if ext == ".htm" {
|
||||||
|
ext = ".html"
|
||||||
|
}
|
||||||
file := fmt.Sprintf("%v/%v%v", path, code, ext)
|
file := fmt.Sprintf("%v/%v%v", path, code, ext)
|
||||||
f, err := os.Open(file)
|
f, err := os.Open(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Loading…
Reference in a new issue