ProxyHTTPRequest proxies requests of underlying type http and websocket to the origin service.
( w connection.ResponseWriter, tr *tracing.TracedHTTPRequest, httpService ingress.HTTPOriginProxy, isWebsocket bool, disableChunkedEncoding bool, logger *zerolog.Logger, )
| 184 | |
| 185 | // ProxyHTTPRequest proxies requests of underlying type http and websocket to the origin service. |
| 186 | func (p *Proxy) proxyHTTPRequest( |
| 187 | w connection.ResponseWriter, |
| 188 | tr *tracing.TracedHTTPRequest, |
| 189 | httpService ingress.HTTPOriginProxy, |
| 190 | isWebsocket bool, |
| 191 | disableChunkedEncoding bool, |
| 192 | logger *zerolog.Logger, |
| 193 | ) error { |
| 194 | roundTripReq := tr.Request |
| 195 | if isWebsocket { |
| 196 | roundTripReq = tr.Clone(tr.Context()) |
| 197 | roundTripReq.Header.Set("Connection", "Upgrade") |
| 198 | roundTripReq.Header.Set("Upgrade", "websocket") |
| 199 | roundTripReq.Header.Set("Sec-Websocket-Version", "13") |
| 200 | roundTripReq.ContentLength = 0 |
| 201 | roundTripReq.Body = nil |
| 202 | } else { |
| 203 | // Support for WSGI Servers by switching transfer encoding from chunked to gzip/deflate |
| 204 | if disableChunkedEncoding { |
| 205 | roundTripReq.TransferEncoding = []string{"gzip", "deflate"} |
| 206 | cLength, err := strconv.Atoi(tr.Header.Get("Content-Length")) |
| 207 | if err == nil { |
| 208 | roundTripReq.ContentLength = int64(cLength) |
| 209 | } |
| 210 | } |
| 211 | // Request origin to keep connection alive to improve performance |
| 212 | roundTripReq.Header.Set("Connection", "keep-alive") |
| 213 | } |
| 214 | |
| 215 | // Set the User-Agent as an empty string if not provided to avoid inserting golang default UA |
| 216 | if roundTripReq.Header.Get("User-Agent") == "" { |
| 217 | roundTripReq.Header.Set("User-Agent", "") |
| 218 | } |
| 219 | |
| 220 | _, ttfbSpan := tr.Tracer().Start(tr.Context(), "ttfb_origin") |
| 221 | resp, err := httpService.RoundTrip(roundTripReq) |
| 222 | if err != nil { |
| 223 | tracing.EndWithErrorStatus(ttfbSpan, err) |
| 224 | if err := roundTripReq.Context().Err(); err != nil { |
| 225 | return errors.Wrap(err, "Incoming request ended abruptly") |
| 226 | } |
| 227 | return errors.Wrap(err, "Unable to reach the origin service. The service may be down or it may not be responding to traffic from cloudflared") |
| 228 | } |
| 229 | |
| 230 | tracing.EndWithStatusCode(ttfbSpan, resp.StatusCode) |
| 231 | defer func() { _ = resp.Body.Close() }() |
| 232 | |
| 233 | headers := make(http.Header, len(resp.Header)) |
| 234 | // copy headers |
| 235 | for k, v := range resp.Header { |
| 236 | headers[k] = v |
| 237 | } |
| 238 | |
| 239 | // Add spans to response header (if available) |
| 240 | tr.AddSpans(headers) |
| 241 | |
| 242 | err = w.WriteRespHeaders(resp.StatusCode, headers) |
| 243 | if err != nil { |
no test coverage detected