(ctx *context, perr *proxyError)
| 2014 | } |
| 2015 | |
| 2016 | func (p *Proxy) makeErrorResponse(ctx *context, perr *proxyError) { |
| 2017 | ctx.response = &http.Response{ |
| 2018 | Header: http.Header{}, |
| 2019 | } |
| 2020 | |
| 2021 | if len(perr.additionalHeader) > 0 { |
| 2022 | copyHeader(ctx.response.Header, perr.additionalHeader) |
| 2023 | } |
| 2024 | addBranding(ctx.response.Header) |
| 2025 | ctx.response.Header.Set("Content-Type", "text/plain; charset=utf-8") |
| 2026 | ctx.response.Header.Set("X-Content-Type-Options", "nosniff") |
| 2027 | |
| 2028 | code := http.StatusInternalServerError |
| 2029 | switch { |
| 2030 | case perr == errRouteLookupFailed: |
| 2031 | code = p.defaultHTTPStatus |
| 2032 | case perr.code == -1: |
| 2033 | // -1 == dial connection refused |
| 2034 | code = http.StatusBadGateway |
| 2035 | case perr.code != 0: |
| 2036 | code = perr.code |
| 2037 | if perr.code == 499 { |
| 2038 | // https://github.com/zalando/skipper/issues/4060 |
| 2039 | // readTimeout() hit and because of |
| 2040 | // https://github.com/golang/go/issues/70834 |
| 2041 | // we need to close the underlying connection |
| 2042 | ctx.response.Header.Set("Connection", "close") |
| 2043 | } |
| 2044 | } |
| 2045 | |
| 2046 | text := http.StatusText(code) + "\n" |
| 2047 | ctx.response.Header.Set("Content-Length", strconv.Itoa(len(text))) |
| 2048 | ctx.response.StatusCode = code |
| 2049 | |
| 2050 | ctx.response.Body = io.NopCloser(bytes.NewBufferString(text)) |
| 2051 | } |
| 2052 | |
| 2053 | // errorHandlerFilter is an opt-in for filters to get called |
| 2054 | // Response(ctx) in case of errors. |
no test coverage detected