Feature: ability to force / remove any header to a request

Hi,
I use requests more and more to test the behavior of my app that runs on Nginx.

I was also planning into using requests to test the behavior when using incorrect HTTP headers, to assert that Nginx does the right thing.

Unfortunately it's impossible to specify Content-Length: '' (I would expect Content-Length: \r\n), or Content-Length: None (or False) (the header shouldn't be in the request at all)
When using the POST interface.

Maybe there is a non obvious way to do that with requests, which I haven't found in the doc ?

For now I will probably end up using a raw socket connection, but it's too bad it's not possible to use requests for those "expected failure" tests.


Couldn't you just modify the headers dictionary when creating a request object?
http://docs.python-requests.org/en/latest/user/advanced/#request-and-response-objects
http://docs.python-requests.org/en/latest/api/#lower-level-classes

Note: For Content-Length, it might be set when you prepare the request (actually I'm pretty sure this is true), but it should be sent if you're posting data and you can determine the length beforehand. Could you elaborate more on your usecase?


@theaeolianmachine is right, Content-Length is set when you prepare the request based on the body. This is reasonable, Requests shouldn't let you set this incorrectly unless you _really_ want to.

However, it sounds like you do. With that in mind, you can interfere with this process in a few ways. The easiest way is likely to be to subclass the `HTTPConnectionAdapter` like so:

``` python
from requests import adapters.HTTPConnectionAdapter

class BrokenAdapter(HTTPConnectionAdapter):
    def send(self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None):
        request.headers['Content-Length'] = ''
        super(BrokenAdapter, self).send(request, stream, timeout, verify, cert, proxies)
```

Then attach your new adapter as follows:

``` python
import requests

s = requests.Session()
s.mount('http://your/nginx/hostname/here', BrokenAdapter())
```

Any requests through that session to your nginx host should now have their Content-Length forcibly set to the empty string. If you want more intelligent behaviour, note that the `send` method takes a `PreparedRequest`, so any data available on a `PreparedRequest` is available to you to modify your behaviour.

NB: I have not tested the above code, I just wrote it in the browser. There may be typos or some minor syntax errors. In general, however, it should work.


If someone provides their own Content-Length, we shouldn't be setting it.


also @mtourne, you should look into PreparedRequest. It's built for exactly this.


@kennethreitz I'll check why we set it if they set it themselves.


@mtourne I for one really think the PreparedRequest is what you should be using in this instance the more I think about it.

``` python
import requests

session = requests.Session()
request = requests.Request('GET', 'http://localhost:8080/foo').prepare()
request.headers['Content-Length'] = '100'
response = session.send(request)
```

It's a bit of extra code, but it isn't too bad and it gives you far more control over the request to mess with as you please.


This regressed the fix for #1096. I opened a new issue for the regression: #1215.