f99010fae1
Desktop Artifacts / Desktop Build (Linux) (push) Waiting to run
Desktop Artifacts / Desktop Build (Windows) (push) Waiting to run
Desktop Artifacts / Desktop Build (Linux (arm64)) (push) Waiting to run
Desktop Artifacts (macOS) / Desktop Build (macOS (aarch64)) (push) Waiting to run
Desktop Artifacts (macOS) / Desktop Build (macOS (x86_64)) (push) Waiting to run
CI / lint (push) Failing after 1s
CI / frontend (push) Failing after 1s
CI / scripts (push) Failing after 1s
CI / Go Test (ubuntu-latest) (push) Failing after 0s
CI / frontend-node-25 (push) Failing after 1s
CI / docs (push) Failing after 0s
CI / coverage (push) Failing after 0s
CI / e2e (push) Failing after 0s
Docker / build-and-push (push) Failing after 1s
CI / integration (push) Failing after 4m43s
CI / Go Test (windows-latest) (push) Has been cancelled
CI / Desktop Unit Tests (Windows) (push) Has been cancelled
76 lines
1.6 KiB
Go
76 lines
1.6 KiB
Go
package server
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"time"
|
|
)
|
|
|
|
// jsonError is the standard JSON error response.
|
|
type jsonError struct {
|
|
Error string `json:"error"`
|
|
}
|
|
|
|
// withTimeout applies a write timeout to standard handlers.
|
|
// It uses http.TimeoutHandler but ensures the response is
|
|
// JSON with correct headers.
|
|
func (s *Server) withTimeout(
|
|
h http.HandlerFunc,
|
|
) http.Handler {
|
|
msgBytes, _ := json.Marshal(
|
|
jsonError{Error: "request timed out"},
|
|
)
|
|
msg := string(msgBytes)
|
|
|
|
inner := h
|
|
if s.handlerDelay > 0 {
|
|
delay := s.handlerDelay
|
|
inner = func(w http.ResponseWriter, r *http.Request) {
|
|
time.Sleep(delay)
|
|
h(w, r)
|
|
}
|
|
}
|
|
|
|
handler := http.TimeoutHandler(
|
|
inner, s.cfg.WriteTimeout, msg,
|
|
)
|
|
|
|
return http.HandlerFunc(
|
|
func(w http.ResponseWriter, r *http.Request) {
|
|
tw := &contentTypeWrapper{
|
|
ResponseWriter: w,
|
|
contentType: "application/json",
|
|
triggerStatus: http.StatusServiceUnavailable,
|
|
}
|
|
handler.ServeHTTP(tw, r)
|
|
},
|
|
)
|
|
}
|
|
|
|
// contentTypeWrapper intercepts WriteHeader to set Content-Type on specific status codes.
|
|
type contentTypeWrapper struct {
|
|
http.ResponseWriter
|
|
contentType string
|
|
triggerStatus int
|
|
wroteHeader bool
|
|
}
|
|
|
|
func (w *contentTypeWrapper) WriteHeader(code int) {
|
|
if !w.wroteHeader {
|
|
if code == w.triggerStatus {
|
|
if w.ResponseWriter.Header().Get("Content-Type") == "" {
|
|
w.ResponseWriter.Header().Set("Content-Type", w.contentType)
|
|
}
|
|
}
|
|
w.ResponseWriter.WriteHeader(code)
|
|
w.wroteHeader = true
|
|
}
|
|
}
|
|
|
|
func (w *contentTypeWrapper) Write(b []byte) (int, error) {
|
|
if !w.wroteHeader {
|
|
w.WriteHeader(http.StatusOK)
|
|
}
|
|
return w.ResponseWriter.Write(b)
|
|
}
|