[Twisted-Python] web.client.readBody

Cory Benfield cory at lukasa.co.uk
Mon Apr 4 02:03:24 MDT 2016


> On 3 Apr 2016, at 14:35, John Aherne <johnaherne at rocs.co.uk> wrote:
> 
> I have been using deliverBody to process in responses but decided that readBody might be a better fit.
> 
> So far it works with http, but as soon as I switch to https it fails.
> 
> I get a response http code 200 OK but no data.
> 
> I've puzzled over this but can't see what the problem is.
> 
> Has anyone else seen this problem and found out what the solution is.
> 
> Thanks

The problem is an interaction in readBody. Your logs actually contain the key clue:

> LENGTH twisted.web.iweb.UNKNOWN_LENGTH

This indicates that the remote server (which, while your logs don’t outright say it, is clearly a Google server) is doing something particularly stupid: that is, they’re sending a response that is neither chunked nor content-length-delimited. This means that message completion can only be signalled by the closing of the connection once the response is complete.

Twisted, correctly, gets a bit nervous about this: it’s very difficult to tell the actual completion of the response from any number of error conditions where the connection gets abruptly torn down. For this reason, the docstring of IResponse.deliverBody says that in a case like this: "The protocol's connectionLost method will be called with: PotentialDataLoss, which indicates that it cannot be determined if the entire response body has been delivered.”

When readBody’s protocol connectionLost method is called with PotentialDataLoss, it calls the errback with PartialDownloadError, which is what you’re seeing. The body of the response is available on the PartialDownloadError as PartialDownloadError.response, so if you’re interested in continuing to use readBody you’ll probably want to register an errback on the deferred that checks for this error and handles it appropriately: in your case, probably by converting the error to a safe response and then calling the callback!

In this instance, I’d *also* recommend that you reach out to whatever Google service is sending this response. RFC 7230 says that a server SHOULD send a Content-Length header if not sending a Transfer-Encoding: chunked header, and points out that not doing so exists primarily for backward compatibility with HTTP/1.0.

I hope that all helps!

Cory

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: </pipermail/twisted-python/attachments/20160404/79109fd3/attachment.sig>


More information about the Twisted-Python mailing list