## Summary
To prevent bad eyeballs and severs to be able to exhaust the quic
control flows we are adding the possibility of having a timeout
for a write operation to be acknowledged. This will prevent hanging
connections from exhausting the quic control flows, creating a DDoS.
In the streambased origin proxy flow (example ssh over access), there is
a chance when we do not flush on http.ResponseWriter writes. This PR
guarantees that the response writer passed to proxy stream has a flusher
embedded after writes. This means we write much more often back to the
ResponseWriter and are not waiting. Note, this is only something we do
when proxyHTTP-ing to a StreamBasedOriginProxy because we do not want to
have situations where we are not sending information that is needed by
the other side (eyeball).
This changes fixes a bug where cloudflared was not propagating errors
when proxying the body of an HTTP request.
In a situation where we already sent HTTP status code, the eyeball would
see the request as sucessfully when in fact it wasn't.
To solve this, we need to guarantee that we produce HTTP RST_STREAM
frames.
This change was applied to both http2 and quic transports.
ProxyHTTP now processes middleware Handler before executing the request.
A chain of handlers is now executed and appropriate response status
codes are sent.
This test was failing on Windows. We did not catch it before because our
TeamCity Windows builds were ignoring failed unit tests: TUN-6727
- the fix is implementing WriteString for mockSSERespWriter
- reason is because cfio.Copy was calling that, and not Write method,
thus not triggering the usage of the channel for the test to continue
- mockSSERespWriter was providing a valid implementation of WriteString
via ResponseRecorder, which it implements via the embedded mockHTTPRespWriter
- it is not clear why this only happened on Windows
- changed it to be a top-level test since it did not share any code
with other sub-tests in the same top-level test
For WARP routing the defaults for these new settings are 5 seconds for connect timeout and 30 seconds for keep-alive timeout. These values can be configured either remotely or locally. Local config lives under "warp-routing" section in config.yaml.
For websocket-based proxy, the defaults come from originConfig settings (either global or per-service) and use the same defaults as HTTP proxying.
The buffer size was big to support a compression feature that we don't
use anymore.
As such, we can now reduce this and be more efficient with memory usage.
Setting the body to nil was rendering cloudflared to crashing with
a SIGSEGV in the odd case where the hostname accessed maps to a
TCP origin (e.g. SSH/RDP/...) but the eyeball sends a plain HTTP
request that does not go through cloudflared access (thus not wrapped
in websocket as it should).
Instead, QUIC transport now sets http.noBody in that condition, which
deals with the situation gracefully.