I'm currently adding vibe.d support to the dlang-requests package (see https://github.com/ikod/dlang-requests/pull/23). The main problem is implementing timeouts. I've used waitForData
for now, but I fear that this implementation is not completely correct:
if (!_sslStream.dataAvailableForRead) {
if (!_conn.waitForData(_readTimeout)) {
if (!_conn.connected) {
return 0;
}
throw new TimeoutException("Timeout receiving data");
}
}
if(_sslStream.empty) {
return 0;
}
auto chunk = min(_sslStream.leastSize, buff.length);
assert(chunk != 0);
_sslStream.read(cast(ubyte[])buff[0 .. chunk]);
return chunk;
What happens if waitForData
only reads SSL 'management' data? I guess then leastSize
will have to read from _conn
as it's not known yet whether there might be more data. But in this case there's no timeout enforced.
I know that .readTimeout
has slightly different semantics. But I think for dlang-requests the readTimeout
semantics (i.e. total time no data received != time since last .read call) should work fine. However, I do have to throw TimeoutException
s.
So what exactly happens when a readTimeout
occurs? The docs say the connection gets closed, but what happens if there's a pending read (possibly in a wrapped TLSStream)?
- Does the read throw an Exception?
- What Type of Exception?
- Is it possible to differentiate other errors from timeouts?
If there's no pending read
, can I simply call read
some time after a timeout and use the same error handling as above? If not, I guess I'd have to check the .connected
property. But AFAICS there's no way to know if the user explicitly closed a connection? So I'd have to add a manuallyClosed
flag somewhere in the wrapper. OTOH the docs say there can still be data in a closed
stream, so if I check connected
instead of empty I might miss some data?
TLDR;
I guess what I really want to know is how I can safely use .readTimeout
with a wrapper stream and make sure a TimeoutException
is thrown from my reading function:
- if the timeout occurs during a call to this function
- or if it occurred before.