mirror of
https://github.com/stefanprodan/podinfo.git
synced 2026-02-28 17:10:19 +00:00
If enabled it will still delay randomly between 0-5 seconds. However, the functionality to fine grain this is added. Both seconds and milliseconds are supported now. Moreover, min/max values for random delay can be condigured through pflag params
112 lines
2.8 KiB
Go
112 lines
2.8 KiB
Go
package api
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"math/rand"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/stefanprodan/podinfo/pkg/version"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
func randomErrorMiddleware(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
rand.Seed(time.Now().Unix())
|
|
if rand.Int31n(3) == 0 {
|
|
|
|
errors := []int{http.StatusInternalServerError, http.StatusBadRequest, http.StatusConflict}
|
|
w.WriteHeader(errors[rand.Intn(len(errors))])
|
|
return
|
|
}
|
|
next.ServeHTTP(w, r)
|
|
})
|
|
}
|
|
|
|
func versionMiddleware(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
r.Header.Set("X-API-Version", version.VERSION)
|
|
r.Header.Set("X-API-Revision", version.REVISION)
|
|
|
|
next.ServeHTTP(w, r)
|
|
})
|
|
}
|
|
|
|
// TODO: use Istio tracing package
|
|
// https://github.com/istio/istio/blob/master/pkg/tracing/config.go
|
|
func copyTracingHeaders(from *http.Request, to *http.Request) {
|
|
headers := []string{
|
|
"x-request-id",
|
|
"x-b3-traceid",
|
|
"x-b3-spanid",
|
|
"x-b3-parentspanid",
|
|
"x-b3-sampled",
|
|
"x-b3-flags",
|
|
"x-ot-span-context",
|
|
}
|
|
|
|
for i := range headers {
|
|
headerValue := from.Header.Get(headers[i])
|
|
if len(headerValue) > 0 {
|
|
to.Header.Set(headers[i], headerValue)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (s *Server) JSONResponse(w http.ResponseWriter, r *http.Request, result interface{}) {
|
|
body, err := json.Marshal(result)
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
s.logger.Error("JSON marshal failed", zap.Error(err))
|
|
return
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
|
w.Header().Set("X-Content-Type-Options", "nosniff")
|
|
w.WriteHeader(http.StatusOK)
|
|
w.Write(prettyJSON(body))
|
|
}
|
|
|
|
func (s *Server) JSONResponseCode(w http.ResponseWriter, r *http.Request, result interface{}, responseCode int) {
|
|
body, err := json.Marshal(result)
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
s.logger.Error("JSON marshal failed", zap.Error(err))
|
|
return
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
|
w.Header().Set("X-Content-Type-Options", "nosniff")
|
|
w.WriteHeader(responseCode)
|
|
w.Write(prettyJSON(body))
|
|
}
|
|
|
|
func (s *Server) ErrorResponse(w http.ResponseWriter, r *http.Request, error string, code int) {
|
|
data := struct {
|
|
Code int `json:"code"`
|
|
Message string `json:"message"`
|
|
}{
|
|
Code: code,
|
|
Message: error,
|
|
}
|
|
|
|
body, err := json.Marshal(data)
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
s.logger.Error("JSON marshal failed", zap.Error(err))
|
|
return
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
|
w.Header().Set("X-Content-Type-Options", "nosniff")
|
|
w.WriteHeader(http.StatusOK)
|
|
w.Write(prettyJSON(body))
|
|
}
|
|
|
|
func prettyJSON(b []byte) []byte {
|
|
var out bytes.Buffer
|
|
json.Indent(&out, b, "", " ")
|
|
return out.Bytes()
|
|
}
|