Files
wehub-resource-sync 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
chore: import upstream snapshot with attribution
2026-07-13 12:30:36 +08:00

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)
}