This code is for an HTTPS server using blocking sockets:
request := '';
start := gettickcount;
repeat
if SSL_pending(ssl) > 0 then
begin
bytesin := SSL_read(ssl, buffer, sizeof(buffer)-1);
if bytesin > 0 then
begin
buffer[bytesin] := #0;
request := request + buffer;
end
else break; // read failed
end; // pending
until (gettickcount - start) > LARGETIMEOUT;
// "request" is ready, though possibly empty
SSL_pending() always returns zero and the SSL_read() is never reached. If the SSL_pending() call is removed, SSL_read() is executed. Why doesn't SSL_pending() indicate how many bytes are available?
Note that if you call SSL_read() and the number of bytes returned is less than your buffer size, you've read everything and are done.
If the incoming data is larger than your buffer size, the first SSL_read() call fills the buffer, and you can repeat calling SSL_read() until you can't fill the buffer.
BUT if the incoming data is an exact multiple of your buffer size, the last chunk of data fills the buffer. If you attempt another SSL_read() thinking there might be more data on a blocking socket, it hangs indefinitely. Hence the desire to check SSL_pending() first. Yet that doesn't appear to work.
How do you avoid hanging on a final SSL_read()? (I can't imagine the answer is to go non-blocking, since that means you could never use SSL_read with blocking.)
UPDATE: The following works. Apparently SSL_pending() doesn't work until after the first SSL_read():
request := '';
repeat
bytesin := SSL_read(ssl, buffer, sizeof(buffer)-1);
if bytesin > 0 then
begin
buffer[bytesin] := #0;
request := request + buffer;
end
else break; // read failed
until SSL_pending(ssl) <= 0;
// "request" is ready, though possibly empty
You are using SSL_pending()
the completely wrong way. OpenSSL uses a state machine, where SSL_pending()
indicates if the state machine has any pending bytes that have been buffered and are awaiting processing. Since you are never calling SSL_read()
, you are never buffering any data or advancing the state machine.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With