finalizeResponse prepares and copies the response.
( rw http.ResponseWriter, req *http.Request, res *http.Response, repl *caddy.Replacer, start time.Time, logger *zap.Logger, )
| 1208 | |
| 1209 | // finalizeResponse prepares and copies the response. |
| 1210 | func (h *Handler) finalizeResponse( |
| 1211 | rw http.ResponseWriter, |
| 1212 | req *http.Request, |
| 1213 | res *http.Response, |
| 1214 | repl *caddy.Replacer, |
| 1215 | start time.Time, |
| 1216 | logger *zap.Logger, |
| 1217 | ) error { |
| 1218 | // deal with 101 Switching Protocols responses: (WebSocket, h2c, etc) |
| 1219 | if res.StatusCode == http.StatusSwitchingProtocols { |
| 1220 | var wg sync.WaitGroup |
| 1221 | h.handleUpgradeResponse(logger, &wg, rw, req, res) |
| 1222 | wg.Wait() |
| 1223 | return nil |
| 1224 | } |
| 1225 | |
| 1226 | removeConnectionHeaders(res.Header) |
| 1227 | |
| 1228 | for _, h := range hopHeaders { |
| 1229 | res.Header.Del(h) |
| 1230 | } |
| 1231 | |
| 1232 | // delete our Server header and use Via instead (see #6275) |
| 1233 | rw.Header().Del("Server") |
| 1234 | var protoPrefix string |
| 1235 | if !strings.HasPrefix(strings.ToUpper(res.Proto), "HTTP/") { |
| 1236 | protoPrefix = res.Proto[:strings.Index(res.Proto, "/")+1] |
| 1237 | } |
| 1238 | rw.Header().Add("Via", fmt.Sprintf("%s%d.%d Caddy", protoPrefix, res.ProtoMajor, res.ProtoMinor)) |
| 1239 | |
| 1240 | // apply any response header operations |
| 1241 | if h.Headers != nil && h.Headers.Response != nil { |
| 1242 | if h.Headers.Response.Require == nil || |
| 1243 | h.Headers.Response.Require.Match(res.StatusCode, res.Header) { |
| 1244 | h.Headers.Response.ApplyTo(res.Header, repl) |
| 1245 | } |
| 1246 | } |
| 1247 | |
| 1248 | copyHeader(rw.Header(), res.Header) |
| 1249 | |
| 1250 | // The "Trailer" header isn't included in the Transport's response, |
| 1251 | // at least for *http.Transport. Build it up from Trailer. |
| 1252 | announcedTrailers := len(res.Trailer) |
| 1253 | if announcedTrailers > 0 { |
| 1254 | trailerKeys := make([]string, 0, len(res.Trailer)) |
| 1255 | for k := range res.Trailer { |
| 1256 | trailerKeys = append(trailerKeys, k) |
| 1257 | } |
| 1258 | rw.Header().Add("Trailer", strings.Join(trailerKeys, ", ")) |
| 1259 | } |
| 1260 | |
| 1261 | rw.WriteHeader(res.StatusCode) |
| 1262 | if h.VerboseLogs { |
| 1263 | logger.Debug("wrote header") |
| 1264 | } |
| 1265 | |
| 1266 | err := h.copyResponse(rw, res.Body, h.flushInterval(req, res), logger) |
| 1267 | errClose := res.Body.Close() // close now, instead of defer, to populate res.Trailer |
no test coverage detected