return step.nextState;
}
- IOState tryRead(PacketBuffer& buffer, size_t& pos, size_t toRead) override
+ IOState tryRead(PacketBuffer& buffer, size_t& pos, size_t toRead, bool allowIncomplete=false) override
{
auto step = getStep();
BOOST_REQUIRE_EQUAL(step.request, !d_client ? ExpectedStep::ExpectedRequest::readFromClient : ExpectedStep::ExpectedRequest::readFromBackend);
{
}
- size_t read(void* buffer, size_t bufferSize, const struct timeval&readTimeout, const struct timeval& totalTimeout={0,0}) override
+ size_t read(void* buffer, size_t bufferSize, const struct timeval&readTimeout, const struct timeval& totalTimeout={0,0}, bool allowIncomplete=false) override
{
return 0;
}
return len;
}
-size_t readn2WithTimeout(int fd, void* buffer, size_t len, const struct timeval& idleTimeout, const struct timeval& totalTimeout)
+size_t readn2WithTimeout(int fd, void* buffer, size_t len, const struct timeval& idleTimeout, const struct timeval& totalTimeout, bool allowIncomplete)
{
size_t pos = 0;
struct timeval start{0,0};
ssize_t got = read(fd, (char *)buffer + pos, len - pos);
if (got > 0) {
pos += (size_t) got;
+ if (allowIncomplete) {
+ break;
+ }
}
else if (got == 0) {
throw runtime_error("EOF while reading message");
size_t writen2(int fd, const void *buf, size_t count);
inline size_t writen2(int fd, const std::string &s) { return writen2(fd, s.data(), s.size()); }
size_t readn2(int fd, void* buffer, size_t len);
-size_t readn2WithTimeout(int fd, void* buffer, size_t len, const struct timeval& idleTimeout, const struct timeval& totalTimeout={0,0});
+size_t readn2WithTimeout(int fd, void* buffer, size_t len, const struct timeval& idleTimeout, const struct timeval& totalTimeout={0,0}, bool allowIncomplete=false);
size_t writen2WithTimeout(int fd, const void * buffer, size_t len, const struct timeval& timeout);
void toLowerInPlace(string& str);
return IOState::Done;
}
- IOState tryRead(PacketBuffer& buffer, size_t& pos, size_t toRead) override
+ IOState tryRead(PacketBuffer& buffer, size_t& pos, size_t toRead, bool allowIncomplete) override
{
do {
int res = SSL_read(d_conn.get(), reinterpret_cast<char *>(&buffer.at(pos)), static_cast<int>(toRead - pos));
}
else {
pos += static_cast<size_t>(res);
+ if (allowIncomplete) {
+ break;
+ }
}
}
while (pos < toRead);
return IOState::Done;
}
- size_t read(void* buffer, size_t bufferSize, const struct timeval& readTimeout, const struct timeval& totalTimeout) override
+ size_t read(void* buffer, size_t bufferSize, const struct timeval& readTimeout, const struct timeval& totalTimeout, bool allowIncomplete) override
{
size_t got = 0;
struct timeval start = {0, 0};
}
else {
got += static_cast<size_t>(res);
+ if (allowIncomplete) {
+ break;
+ }
}
if (totalTimeout.tv_sec != 0 || totalTimeout.tv_usec != 0) {
return IOState::Done;
}
- IOState tryRead(PacketBuffer& buffer, size_t& pos, size_t toRead) override
+ IOState tryRead(PacketBuffer& buffer, size_t& pos, size_t toRead, bool allowIncomplete) override
{
if (!d_handshakeDone) {
/* As opposed to OpenSSL, GnuTLS will not transparently finish the handshake for us,
}
else if (res > 0) {
pos += static_cast<size_t>(res);
+ if (allowIncomplete) {
+ break;
+ }
}
else if (res < 0) {
if (gnutls_error_is_fatal(res)) {
return IOState::Done;
}
- size_t read(void* buffer, size_t bufferSize, const struct timeval& readTimeout, const struct timeval& totalTimeout) override
+ size_t read(void* buffer, size_t bufferSize, const struct timeval& readTimeout, const struct timeval& totalTimeout, bool allowIncomplete) override
{
size_t got = 0;
struct timeval start{0,0};
}
else if (res > 0) {
got += static_cast<size_t>(res);
+ if (allowIncomplete) {
+ break;
+ }
}
else if (res < 0) {
if (gnutls_error_is_fatal(res)) {
virtual IOState tryConnect(bool fastOpen, const ComboAddress& remote) = 0;
virtual void connect(bool fastOpen, const ComboAddress& remote, const struct timeval& timeout) = 0;
virtual IOState tryHandshake() = 0;
- virtual size_t read(void* buffer, size_t bufferSize, const struct timeval& readTimeout, const struct timeval& totalTimeout={0,0}) = 0;
+ virtual size_t read(void* buffer, size_t bufferSize, const struct timeval& readTimeout, const struct timeval& totalTimeout={0,0}, bool allowIncomplete=false) = 0;
virtual size_t write(const void* buffer, size_t bufferSize, const struct timeval& writeTimeout) = 0;
virtual IOState tryWrite(const PacketBuffer& buffer, size_t& pos, size_t toWrite) = 0;
- virtual IOState tryRead(PacketBuffer& buffer, size_t& pos, size_t toRead) = 0;
+ virtual IOState tryRead(PacketBuffer& buffer, size_t& pos, size_t toRead, bool allowIncomplete=false) = 0;
virtual bool hasBufferedData() const = 0;
virtual std::string getServerNameIndication() const = 0;
virtual LibsslTLSVersion getTLSVersion() const = 0;
return IOState::Done;
}
- size_t read(void* buffer, size_t bufferSize, const struct timeval& readTimeout, const struct timeval& totalTimeout = {0,0})
+ size_t read(void* buffer, size_t bufferSize, const struct timeval& readTimeout, const struct timeval& totalTimeout = {0,0}, bool allowIncomplete=false)
{
if (d_conn) {
- return d_conn->read(buffer, bufferSize, readTimeout, totalTimeout);
+ return d_conn->read(buffer, bufferSize, readTimeout, totalTimeout, allowIncomplete);
} else {
- return readn2WithTimeout(d_socket, buffer, bufferSize, readTimeout, totalTimeout);
+ return readn2WithTimeout(d_socket, buffer, bufferSize, readTimeout, totalTimeout, allowIncomplete);
}
}
return Done when toRead bytes have been read, needRead or needWrite if the IO operation
would block.
*/
- IOState tryRead(PacketBuffer& buffer, size_t& pos, size_t toRead)
+ IOState tryRead(PacketBuffer& buffer, size_t& pos, size_t toRead, bool allowIncomplete=false)
{
if (buffer.size() < toRead || pos >= toRead) {
throw std::out_of_range("Calling tryRead() with a too small buffer (" + std::to_string(buffer.size()) + ") for a read of " + std::to_string(toRead - pos) + " bytes starting at " + std::to_string(pos));
}
if (d_conn) {
- return d_conn->tryRead(buffer, pos, toRead);
+ return d_conn->tryRead(buffer, pos, toRead, allowIncomplete);
}
do {
}
pos += static_cast<size_t>(res);
+ if (allowIncomplete) {
+ break;
+ }
}
while (pos < toRead);