2

We have some custom module where we have redefined open, seek, read, tell functions to read only a part of file according to the arguments.

But, this logic overrides the default tell and python requests is trying to calculate the content-length which involves using tell(), which then redirects to our custom tell function and the logic is somewhere buggy and returns a wrong value. And I tried some changes, it throws error.

Found the following from models.py of requests:

 def prepare_content_length(self, body):
        if hasattr(body, 'seek') and hasattr(body, 'tell'):
            body.seek(0, 2)
            self.headers['Content-Length'] = builtin_str(body.tell())
            body.seek(0, 0)
        elif body is not None:
            l = super_len(body)
            if l:
                self.headers['Content-Length'] = builtin_str(l)
        elif (self.method not in ('GET', 'HEAD')) and (self.headers.get('Content-Length') is None):
            self.headers['Content-Length'] = '0'

For now, I am not able to figure out where's the bug and stressed out to investigate more and fix it. And everything else work except content-length calculation by python requests.

So, I have created my own definition for finding content-length. And I have included the value in requests header. But, the request is still preparing the content-length and throwing error.

How can I restrict not preparing content-length and use the specified content-length?

GP92
  • 433
  • 1
  • 12
  • 30
  • 1
    Well, you are changing standard functions and methods. How can you expect things to work correctly? – Andrea Corbellini Apr 06 '16 at 17:52
  • @AndreaCorbellini Hi, Yes, you are right. But, this is required for us to split a file into multiple parts and upload. Well, it's been there for so long. And recently, we have switched from urllib2 to requests, so we came across this error now. – GP92 Apr 06 '16 at 17:55

1 Answers1

7

Requests lets you modify a request before sending. See Prepared Requests.

For example:

from requests import Request, Session

s = Session()

req = Request('POST', url, data=data, headers=headers)
prepped = req.prepare()

# do something with prepped.headers
prepped.headers['Content-Length'] = your_custom_content_length_calculation()

resp = s.send(prepped, ...)

If your session has its own configuration (like cookie persistence or connection-pooling), then you should use s.prepare_request(req) instead of req.prepare().

D Malan
  • 10,272
  • 3
  • 25
  • 50
nofinator
  • 2,906
  • 21
  • 25