Author martin.panter
Recipients SilentGhost, Wiktor Niesiobedzki, martin.panter, r.david.murray
Date 2016-01-10.23:07:47
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1452467268.03.0.797432098365.issue25919@psf.upfronthosting.co.za>
In-reply-to
Content
Sorry for making a seemingly easy problem harder :)

Your version of test_ssl_renegotiation() would actually be harder to fix IMO, since that would require the client to receive response data (the “H”) and continue to transmit request data concurrently. It would probably require sending and receiving in separate coroutines or threads, like asyncio.

There may still be a way to avoid that if we don’t need to send and receive HTTP data at the same time. We only need the low-level SSL messages to work properly. The following might work:

self.sock.setblocking(False)
try:
    ...  # Get chunks of request body to send
    while datablock:
        select((self._reader,), (self.sock,), (), self._timeout)
        if self._reader.peek():
            ...  # Early response received
        try:
            amount = self.sock.send(datablock)
        except (BlockingIOError, SSLWantRead, SSLWantWrite):
            continue
        datablock = datablock[amount:]
finally:
    self.sock.settimeout(self.timeout)

This might require the following problems investigated and fixed first:

* Need to maintain the buffered socket reader of self.sock.makefile(), before the response is actually read. Could use my patch for Issue 23377.

* Allow a buffered socket reader to be non-blocking without upsetting its buffer. The documentation <https://docs.python.org/release/3.4.3/library/socket.html#socket.socket.makefile> disallows non-blocking mode, but I suspect that is just a Python 2 relic and there is no restriction in the Python 3 implementation. I thought there was a bug open for this but I can only find mentions in other bugs.

* Allow using BufferedReader.peek() to see if data is ready to be read. The current documentation does not guarantee it will return any bytes (Issue 5811), but I understand the implementation normally does return ≥ 1 byte.

* Clarify what peek() should do if no non-blocking data is available. Currently I think it returns b"", but that is inconsistent with other APIs, and does not differentiate from EOF. I proposed to change peek() to return None in Issue 13322.
History
Date User Action Args
2016-01-10 23:07:48martin.pantersetrecipients: + martin.panter, r.david.murray, SilentGhost, Wiktor Niesiobedzki
2016-01-10 23:07:48martin.pantersetmessageid: <1452467268.03.0.797432098365.issue25919@psf.upfronthosting.co.za>
2016-01-10 23:07:48martin.panterlinkissue25919 messages
2016-01-10 23:07:47martin.pantercreate