MCPcopy Create free account
hub / github.com/erpc/erpc / ServeHTTP

Method ServeHTTP

erpc/http_timeout.go:36–143  ·  view source on GitHub ↗
(w http.ResponseWriter, r *http.Request)

Source from the content-addressed store, hash-verified

34}
35
36func (h *timeoutHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
37 ctx, cancelCtx := context.WithTimeoutCause(r.Context(), h.dt, ErrHandlerTimeout)
38 defer func() {
39 cancelCtx()
40 }()
41 r = r.WithContext(ctx)
42 done := make(chan struct{})
43 tw := &timeoutWriter{
44 logger: h.logger,
45 w: w,
46 h: make(http.Header),
47 req: r,
48 wbuf: util.BorrowBuf(),
49 }
50 panicChan := make(chan any, 1)
51 go func() {
52 defer func() {
53 if p := recover(); p != nil {
54 telemetry.MetricUnexpectedPanicTotal.WithLabelValues(
55 "timeout-handler",
56 "",
57 common.ErrorFingerprint(p),
58 ).Inc()
59 h.logger.Error().
60 Interface("panic", p).
61 Str("stack", string(debug.Stack())).
62 Msgf("unexpected panic on timeout handler")
63 panicChan <- p
64 }
65 }()
66 h.handler.ServeHTTP(tw, r)
67 close(done)
68 }()
69 select {
70 case p := <-panicChan:
71 panic(p)
72 case <-done:
73 tw.mu.Lock()
74 defer tw.mu.Unlock()
75 if err := ctx.Err(); err != nil {
76 h.logger.Debug().Err(err).Msg("context canceled before writing response")
77 util.ReturnBuf(tw.wbuf)
78 tw.wbuf = nil
79 return
80 }
81 dst := w.Header()
82 for k, vv := range tw.h {
83 dst[k] = vv
84 }
85 if !tw.wroteHeader {
86 tw.code = http.StatusOK
87 }
88 w.WriteHeader(tw.code)
89 _, err := w.Write(tw.wbuf.Bytes())
90 util.ReturnBuf(tw.wbuf)
91 tw.wbuf = nil
92 if err != nil {
93 if common.IsClientDisconnect(err) {

Calls 12

BorrowBufFunction · 0.92
ErrorFingerprintFunction · 0.92
ReturnBufFunction · 0.92
IsClientDisconnectFunction · 0.92
ContextMethod · 0.80
WriteHeaderMethod · 0.80
WithLabelValuesMethod · 0.65
ErrorMethod · 0.65
LockMethod · 0.65
UnlockMethod · 0.65
HeaderMethod · 0.45
WriteMethod · 0.45