MCPcopy
hub / github.com/caddyserver/caddy / ServeHTTP

Method ServeHTTP

modules/caddyhttp/intercept/intercept.go:128–201  ·  view source on GitHub ↗

EXPERIMENTAL: Subject to change or removal.

(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler)

Source from the content-addressed store, hash-verified

126
127// EXPERIMENTAL: Subject to change or removal.
128func (ir Intercept) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error {
129 buf := bufPool.Get().(*bytes.Buffer)
130 buf.Reset()
131 defer bufPool.Put(buf)
132
133 repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
134 rec := interceptedResponseHandler{replacer: repl}
135 rec.ResponseRecorder = caddyhttp.NewResponseRecorder(w, buf, func(status int, header http.Header) bool {
136 // see if any response handler is configured for this original response
137 for i, rh := range ir.HandleResponse {
138 if rh.Match != nil && !rh.Match.Match(status, header) {
139 continue
140 }
141 rec.handler = rh
142 rec.handlerIndex = i
143
144 // if configured to only change the status code,
145 // do that then stream
146 if statusCodeStr := rh.StatusCode.String(); statusCodeStr != "" {
147 sc, err := strconv.Atoi(repl.ReplaceAll(statusCodeStr, ""))
148 if err != nil {
149 rec.statusCode = http.StatusInternalServerError
150 } else {
151 rec.statusCode = sc
152 }
153 }
154
155 return rec.statusCode == 0
156 }
157
158 return false
159 })
160
161 if err := next.ServeHTTP(rec, r); err != nil {
162 return err
163 }
164 if !rec.Buffered() {
165 return nil
166 }
167
168 // set up the replacer so that parts of the original response can be
169 // used for routing decisions
170 for field, value := range rec.Header() {
171 repl.Set("http.intercept.header."+field, strings.Join(value, ","))
172 }
173 repl.Set("http.intercept.status_code", rec.Status())
174
175 if c := ir.logger.Check(zapcore.DebugLevel, "handling response"); c != nil {
176 c.Write(zap.Int("handler", rec.handlerIndex))
177 }
178
179 // response recorder doesn't create a new copy of the original headers, they're
180 // present in the original response writer
181 // create a new recorder to see if any response body from the new handler is present,
182 // if not, use the already buffered response body
183 recorder := caddyhttp.NewResponseRecorder(w, nil, nil)
184 if err := rec.handler.Routes.Compile(emptyHandler).ServeHTTP(recorder, r); err != nil {
185 return err

Callers

nothing calls this directly

Calls 15

StatusMethod · 0.95
SizeMethod · 0.95
NewResponseRecorderFunction · 0.92
ReplaceAllMethod · 0.80
GetMethod · 0.65
ResetMethod · 0.65
MatchMethod · 0.65
ServeHTTPMethod · 0.65
BufferedMethod · 0.65
ValueMethod · 0.45
StringMethod · 0.45
HeaderMethod · 0.45

Tested by

no test coverage detected