Fix possible CHECKSUM_DOESNT_MATCH during replicated fetches

Previously HTTP server does not tries to send exception if something had
been written to the client already, but after rewriting to "zero-copy"
HTTP implementation (back in #19516) this got broken, and you can get
pretty "dangerous" at least at first glance errors, like:
- Malformed chunked encoding
- or most likely to CHECKSUM_DOESNT_MATCH error

This is not crucial because it will never pass checksum checks, but
still icky. So let's fix it.

Signed-off-by: Azat Khuzhin <a.khuzhin@semrush.com>
This commit is contained in:
Azat Khuzhin 2024-04-25 16:45:59 +02:00
parent 478ba92ddd
commit cf1451ecde
2 changed files with 14 additions and 1 deletions

View File

@ -62,6 +62,7 @@ std::shared_ptr<WriteBufferFromPocoSocket> HTTPServerResponse::send()
stream = std::make_shared<WriteBufferFromPocoSocket>(session.socket(), write_event);
}
send_started = true;
return stream;
}
@ -96,9 +97,16 @@ std::pair<std::shared_ptr<WriteBufferFromPocoSocket>, std::shared_ptr<WriteBuffe
else
stream = std::make_shared<WriteBufferFromPocoSocket>(session.socket(), write_event);
send_started = true;
return std::make_pair(header_stream, stream);
}
void HTTPServerResponse::beginWrite(std::ostream & ostr) const
{
HTTPResponse::beginWrite(ostr);
send_started = true;
}
void HTTPServerResponse::sendBuffer(const void * buffer, std::size_t length)
{
setContentLength(static_cast<int>(length));

View File

@ -209,6 +209,10 @@ public:
/// or redirect() has been called.
std::pair<std::shared_ptr<WriteBufferFromPocoSocket>, std::shared_ptr<WriteBufferFromPocoSocket>> beginSend();
/// Override to correctly mark that the data send had been started for
/// zero-copy response (i.e. replicated fetches).
void beginWrite(std::ostream & ostr) const;
/// Sends the response header to the client, followed
/// by the contents of the given buffer.
///
@ -229,7 +233,7 @@ public:
/// according to the given realm.
/// Returns true if the response (header) has been sent.
bool sent() const { return !!stream; }
bool sent() const { return send_started; }
/// Sets the status code, which must be one of
/// HTTP_MOVED_PERMANENTLY (301), HTTP_FOUND (302),
@ -251,6 +255,7 @@ private:
ProfileEvents::Event write_event;
std::shared_ptr<WriteBufferFromPocoSocket> stream;
std::shared_ptr<WriteBufferFromPocoSocket> header_stream;
mutable bool send_started = false;
};
}