Raibek/requests-github-issues huggingface dataset:
make content-type's charset information case-insensitive

Fix bug described in https://github.com/requests/requests/issues/4748 .

# [Codecov](https://codecov.io/gh/requests/requests/pull/4749?src=pr&el=h1) Report
> Merging [#4749](https://codecov.io/gh/requests/requests/pull/4749?src=pr&el=desc) into [master](https://codecov.io/gh/requests/requests/commit/6686ac173011a302c26c4aedbd992f96d6e58357?src=pr&el=desc) will **not change** coverage.
> The diff coverage is `n/a`.

[![Impacted file tree graph](https://codecov.io/gh/requests/requests/pull/4749/graphs/tree.svg?src=pr&width=650&token=mZGswIiXLa&height=150)](https://codecov.io/gh/requests/requests/pull/4749?src=pr&el=tree)

```diff
@@           Coverage Diff           @@
##           master    #4749   +/-   ##
=======================================
  Coverage   66.79%   66.79%           
=======================================
  Files          15       15           
  Lines        1563     1563           
=======================================
  Hits         1044     1044           
  Misses        519      519
```



------

[Continue to review full report at Codecov](https://codecov.io/gh/requests/requests/pull/4749?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/requests/requests/pull/4749?src=pr&el=footer). Last update [6686ac1...907c927](https://codecov.io/gh/requests/requests/pull/4749?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).
case-insensitive charset handling

I get encoding issues when extracting text from some URLs, for example this [one](https://zuri.net/magazin/slang/33/thema_small-talk.htm). After some digging, it seems that although the `headers` dictionary is case-insensitive, the parsing of the content-type header entry is not. For example, if the server sends:

    text/html; Charset=UTF-8

Because of the uppercase `C`, `response.encoding` returns the default `ISO-8859-1` instead of `UTF-8`.

## Expected Result

`r.encoding` should return `utf-8`, as it is stated in the `content-type` header.

## Actual Result

`r.encoding` returns the default`ISO-8859-1`.

## Reproduction Steps

```python
import requests
resp = requests.get("https://zuri.net/magazin/slang/33/thema_small-talk.htm")
print(resp.encoding)
```

## System Information

    $ python -m requests.help

```
{
  "chardet": {
    "version": "3.0.4"
  },
  "cryptography": {
    "version": ""
  },
  "idna": {
    "version": "2.7"
  },
  "implementation": {
    "name": "CPython",
    "version": "3.6.5"
  },
  "platform": {
    "release": "17.6.0",
    "system": "Darwin"
  },
  "pyOpenSSL": {
    "openssl_version": "",
    "version": null
  },
  "requests": {
    "version": "2.19.1"
  },
  "system_ssl": {
    "version": "100020ff"
  },
  "urllib3": {
    "version": "1.23"
  },
  "using_pyopenssl": false
}
```

## Suggestion

The code responsible is in `utils.py`, method `_parse_content_type_header`. Here, either use a case-insensitive dictionary, or transform the keys to lowercase (`params_dict[key.lower()] = value`).

Hi @derlin, thanks for bringing this to our attention! This definitely looks like a miss on our part.

I think your suggestion of lower-casing is probably the better solution from an overhead perspective. That way we can avoid instantiating a new `CaseInsenstiveDict` every call when it's likely only going to contain a single value. Would you have any interest in providing a PR doing that?

+1 for .lower, in this instance.

@nateprewitt My pleasure. I'll do a pull request asap. 

Resolved in #4749.
urllib3 Retry and Response Hooks (Duplicates #4514)

Given you have a session, and have successfully attached the auth class and the response hooks accordingly; although you'd like to add the Retry class into the picture from urllib3.

## Expected Result

I'd expect the response hooks to be honoured - at the very least on the first response (not retry).

## Actual Result

The response hooks are ignored completely.

## Reproduction Steps

```python
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry

retry = Retry(total=1, read=1, connect=1, backoff_factor=0.5,
                      status_forcelist=(401, 500))

adapter = HTTPAdapter(max_retries=retry)

session = requests.Session()
session.hooks = {'response': response_hook}

session.mount('http://', adapter)
session.mount('https://', adapter)

def response_hook(response, *args, **kwargs):
    """
    Response hook

    :param response:
    :return:
    """
    if response.status_code == requests.codes.unauthorized:
       print('Your logic here')
```

## System Information

```
Python version: 3.5
Requests version: 2.11.0
OS: Ubuntu 16.04
```

Can anyone suggest a work around for this? (except for the standard flagging and re-doing what Retry does)

@belthaZornv can you share what part of our documentation misled you here?

`Retry` logic from urllib3 operates at a much lower level than the response hook(s). You have specified `401` as a status code to retry which means that Requests will never see it. It will be retried by urllib3 before we can execute the hook. I thought our documentation was clear that the Retry logic operated at a very low level and caused other parts of Requests to behave differently. If I'm mistaken, please point out where you saw differently.

@sigmavirus24 I'm not saying you or the documentation misled me or someone else, but otherwise I'm more interested in discussing what you'd expect, would you expect the response hook to execute? (Taking into consideration that not everyone knows requests inside out) I did, I expected the hook to execute at least once; but I might have been wrong in thinking so, so my question is, what is the ideal solution when someone wants to Retry but also wants a response hook to execute? More over I believe that unless urllib3 honours the hooks than there isn't much to add. 

Although for someone new to requests, one would expect hooks and auth classes to run as by default even in Retry, after knowing the structure beneath it all, yes, I fully agree it shouldn't or even can't.. but people are and will get lost over this.. and would be nice to find the ideal solution if any exist.

Just got bitten by the same thing myself too. I was assuming hooks would work, until I dug deeper.

For anyone here getting stuck on this, reread the reply from sigmavirus24. If your use case was like mine ( a reauth hook ) if the status code 401 or 403 is in your status_forcelist urllib3 will gobble the response that you may be trying to hook on. You may only want to retry on < 403

...Seems so obvious now.
urllib3 LocationParseError uncaught by requests

When accessing a page that is not redirecting properly (in this case, port is "-1", urllib3 LocationParseError is returned without being caught by requests. 
The URL _currently_ (Jul 23rd 2018) badly redirecting: https://www.fossil.com/us/en/account-dashboard/registered-products.html

## Expected Result

An exception raised by requests, like InvalidURL

## Actual Result

Exception from urllib3 is not masked

## Reproduction Steps

```python
import requests
test = requests.get("https://www.fossil.com/us/en/account-dashboard/registered-products.html")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/dist-packages/requests/api.py", line 72, in get
    return request('get', url, params=params, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/requests/api.py", line 58, in request
    return session.request(method=method, url=url, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 512, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 644, in send
    history = [resp for resp in gen] if allow_redirects else []
  File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 222, in resolve_redirects
    **adapter_kwargs
  File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 622, in send
    r = adapter.send(request, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/requests/adapters.py", line 410, in send
    conn = self.get_connection(request.url, proxies)
  File "/usr/local/lib/python2.7/dist-packages/requests/adapters.py", line 314, in get_connection
    conn = self.poolmanager.connection_from_url(url)
  File "/usr/local/lib/python2.7/dist-packages/urllib3/poolmanager.py", line 277, in connection_from_url
    u = parse_url(url)
  File "/usr/local/lib/python2.7/dist-packages/urllib3/util/url.py", line 199, in parse_url
    raise LocationParseError(url)
urllib3.exceptions.LocationParseError: Failed to parse: www.fossil.com:-1


```

## System Information

    $ python -m requests.help

```
{
  "chardet": {
    "version": "3.0.4"
  }, 
  "cryptography": {
    "version": "2.2.2"
  }, 
  "idna": {
    "version": "2.7"
  }, 
  "implementation": {
    "name": "CPython", 
    "version": "2.7.9"
  }, 
  "platform": {
    "release": "4.9.35-v7+", 
    "system": "Linux"
  }, 
  "pyOpenSSL": {
    "openssl_version": "1000114f", 
    "version": "18.0.0"
  }, 
  "requests": {
    "version": "2.19.1"
  }, 
  "system_ssl": {
    "version": "1000114f"
  }, 
  "urllib3": {
    "version": "1.23"
  }, 
  "using_pyopenssl": true
}

```



Thanks for bringing this to our attention @Arduous! We do appear to be leaking an exception when we're trying to pull a connection from the pool. We should try to identify what exceptions can be raised here and then add handling for at least `urllib3.exceptions.HTTPError`, and possibly more specific cases if appropriate.

Resolved with #4765.
Exceptions when using data=json.dumps(payload))

```
import json , requests 
r = requests.post(
      "http://httpbin.org/post",
      files={'image': open(filename, 'rb')},
      data=json.dumps({'wordPos': [86, 23]})
  )

```

**exceptions:** 

```
Traceback (most recent call last):
  File "D:\BaiduYunDownload\编程\Python\Project\EngkuDict\Utils.py", line 128, in <module>
    myOCR2()
  File "D:\BaiduYunDownload\编程\Python\Project\EngkuDict\Utils.py", line 116, in myOCR2
    data=json.dumps({'wordPos': [86, 23]})
  File "C:\Users\i\AppData\Local\Programs\Python\Python36-32\lib\site-packages\requests\api.py", line 112, in post
    return request('post', url, data=data, json=json, **kwargs)
  File "C:\Users\i\AppData\Local\Programs\Python\Python36-32\lib\site-packages\requests\api.py", line 58, in request
    return session.request(method=method, url=url, **kwargs)
  File "C:\Users\i\AppData\Local\Programs\Python\Python36-32\lib\site-packages\requests\sessions.py", line 498, in request
    prep = self.prepare_request(req)
  File "C:\Users\i\AppData\Local\Programs\Python\Python36-32\lib\site-packages\requests\sessions.py", line 441, in prepare_request
    hooks=merge_hooks(request.hooks, self.hooks),
  File "C:\Users\i\AppData\Local\Programs\Python\Python36-32\lib\site-packages\requests\models.py", line 312, in prepare
    self.prepare_body(data, files, json)
  File "C:\Users\i\AppData\Local\Programs\Python\Python36-32\lib\site-packages\requests\models.py", line 500, in prepare_body
    (body, content_type) = self._encode_files(files, data)
  File "C:\Users\i\AppData\Local\Programs\Python\Python36-32\lib\site-packages\requests\models.py", line 122, in _encode_files
    raise ValueError("Data must not be a string.")
ValueError: Data must not be a string.
```

@redstoneleo it's not clear how you would be hitting this code path. `_encode_files` is only triggered when the `files` parameter isn't False-y. The code you've provided doesn't seem to reproduce the issue either.

We'll need the information we initially asked for with this issue in order to do any further debugging, but at first glance, this looks like a local misconfiguration.

@nateprewitt Sorry for that , I've updated the test code

@redstoneleo, if you're passing both data and files, they need to be key-value pairs. When you serialize the dictionary into a string with `json.dumps` we lose the semantics of the dictionary and can't map to multipart/form-data correctly.

If you remove the `json.dumps` portion, things should work as expected.

Thanks, as far as I know , the documentation has not covered what you have said, it would be better to add in it.
BTW, since  `data` could accept `json.dumps()`, while `json.dumps()` is a `str `object , but [the doc](http://docs.python-requests.org/en/master/api/#requests.Response) has not mentioned the `data` parameter could accept  a `str `object, so I think this should also be added in 

The current description for `data` parameter 
> data – (optional) Dictionary, list of tuples, bytes, or file-like object to send in the body of the Request.
urllib3.exceptions.NewConnectionError

It seems like I'm getting an Exception from urllib3: urllib3.exceptions.NewConnectionError.

## Expected Result
I am expecting to catch the exception using requests.exceptions.RequestException

## Actual Result
The exception in not getting caught. 

## Reproduction Steps

```python
import requests

try:
  response = requests.post('http://0.0.0.0:8080', data = {'token': 'some_token'})
  if response.status_code == 200:
    data = json.loads(response.text)
    if ('user' in data):
      user = User.objects.get(username=data['user']['username'])
except requests.exceptions.RequestException as e:
  result = {"error": e}
```

## System Information

    $ python -m requests.help

```
{
  "chardet": {
    "version": "3.0.4"
  },
  "cryptography": {
    "version": ""
  },
  "idna": {
    "version": "2.6"
  },
  "implementation": {
    "name": "CPython",
    "version": "3.6.4"
  },
  "platform": {
    "release": "17.5.0",
    "system": "Darwin"
  },
  "pyOpenSSL": {
    "openssl_version": "",
    "version": null
  },
  "requests": {
    "version": "2.19.1"
  },
  "system_ssl": {
    "version": "100020ef"
  },
  "urllib3": {
    "version": "1.22"
  },
  "using_pyopenssl": false
}
```


Hi @pinkynrg, can we please get the full stack trace you’re seeing and a minimum viable reproduction?

A simplified version of what you’ve supplied returns a `requests.exception.ConnectionError` which wraps the `NewConnectionError`.

```python
import requests

requests.post(‘http://0.0.0.0:8080’, data={‘test’: ‘data’})
```

Closing due to lack of information or ability to reproduce.
Link to donate for requests for py3 isn't working

Summary.

link to support requests for py3 isn't working at the top of 
http://docs.python-requests.org/en/master/
leads to https://www.kennethreitz.org/requests3

What you expected.

a website

What happened instead.

404

```python
import requests

```

## System Information

    $ python -m requests.help

```
404
```

Thanks


@kennethreitz this is a bug in your website redesign and URL routing

Need to bring the death clock back — or remove the banner entirely.

Sent from my iPhone

> On Jul 20, 2018, at 11:09 AM, Ian Stapleton Cordasco <notifications@github.com> wrote:
> 
> @kennethreitz this is a bug in your website redesign and URL routing
> 
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub, or mute the thread.


@kennethreitz #4767 because people are still looking for that page. I've also received emails asking for updates on the progress and spend of that money. I can't answer to either of those. Please either bring the page back and add updates or figure something else out.
Response.content returns the gzip compressed file


Response.content has not been unzip

Response.content has not been unzip
Hello, please ask a question, other website requests are basically decompressed, but when you request this URL(https://www.betburger.com/users/sigin_in), you return the compressed string.
=======================code============================
# coding=utf-8

import requests

url = 'https://www.betburger.com/users/sign_in'
headers = {
    'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
    'accept-encoding': 'gzip, deflate, br',
    'accept-language': 'zh-CN,zh;q=0.9',
    'cookie': '__cfduid=dc9505fc253be4d1f40fc6158900b6cb11531922677; cookieconsent_dismissed=yes; abb_web_session=7a9d700e75ad796a695cfad024c93989; _ga=GA1.2.1097857175.1531980113; _gid=GA1.2.765234195.1531980113; _gat_UA-113146417-2=1; _gat_UA-35300177-2=1',
    'referer': 'https://www.betburger.com/',
    'upgrade-insecure-requests': '1',
    'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'
}
rp = requests.get(url, headers=headers)
print rp.content
================================================

sos

Hi there! Thanks for opening this issue. Unfortunately, it seems this is a request for help instead of a report of a defect in the project. Please use [StackOverflow](https://stackoverflow.com) for general usage questions instead and only report defects here.

@sigmavirus24 The response header content(content encoding:gzip) is missing
Construct a request by requests moudle,the response header is : 
{
    "Server":"nginx",
    "Date":"Mon, 19 Nov 2018 07:10:00 GMT",
    "Content-Type":"text/html; charset=UTF-8",
    "Transfer-Encoding":"chunked",
    "Connection":"keep-alive",
    "Vary":"Accept-Encoding",
    "Access-Control-Allow-Origin":"http://runapi.showdoc.cc"
}

but,The original response header is : 
HTTP/1.1 200 OK
Server: nginx
Date: Mon, 19 Nov 2018 07:15:20 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
Access-Control-Allow-Origin: http://runapi.showdoc.cc
Access-Control-Allow-Credentials : true
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Content-Encoding: gzip

Content-Encoding:gizp  is missing,The gzip file cannot be decompressed automatically,so   response.text  is garbage characters
Proxy password contains square bracket "[" will failed with error "Invalid IPv6 URL" from urllib3

Summary.

## Expected Result

When I have passed a proxy with square bracket "[" in the password, the request session should work.

## Actual Result

There will be error "Invalid IPv6 URL" generated by urllib3 which requests is based on.

## Reproduction Steps

```python
from requests import Request, Session

proxies = {
    'http': 'http://username:passw[ord@proxy-server.8080',
    'https': 'http://username:passw[ord@proxy-server:8081',
    }

s = Session()

req = Request('POST', auth_url, data=login_data)
prepped = s.prepare_request(req)
resp = s.send(prepped, proxies=proxies)
print(resp.cookies)


======The error message======
    resp = s.send(prepped, proxies=proxies)
  File "/usr/local/lib/python3.7/site-packages/requests/sessions.py", line 622, in send
    r = adapter.send(request, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/requests/adapters.py", line 410, in send
    conn = self.get_connection(request.url, proxies)
  File "/usr/local/lib/python3.7/site-packages/requests/adapters.py", line 303, in get_connection
    proxy = prepend_scheme_if_needed(proxy, 'http')
  File "/usr/local/lib/python3.7/site-packages/requests/utils.py", line 894, in prepend_scheme_if_needed
    scheme, netloc, path, params, query, fragment = urlparse(url, new_scheme)
  File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/urllib/parse.py", line 368, in urlparse
    splitresult = urlsplit(url, scheme, allow_fragments)
  File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/urllib/parse.py", line 417, in urlsplit
    raise ValueError("Invalid IPv6 URL")
ValueError: Invalid IPv6 URL
======End of the error message======
```



## System Information

    $ python -m requests.help

```
{
  "chardet": {
    "version": "3.0.4"
  },
  "cryptography": {
    "version": "2.2.2"
  },
  "idna": {
    "version": "2.7"
  },
  "implementation": {
    "name": "CPython",
    "version": "3.7.0"
  },
  "platform": {
    "release": "17.5.0",
    "system": "Darwin"
  },
  "pyOpenSSL": {
    "openssl_version": "1010008f",
    "version": "18.0.0"
  },
  "requests": {
    "version": "2.19.1"
  },
  "system_ssl": {
    "version": "100020ff"
  },
  "urllib3": {
    "version": "1.23"
  },
  "using_pyopenssl": true
}
```

This command is only available on Requests v2.16.4 and greater. Otherwise,
please provide some basic information about your system (Python version,
operating system, &c).


Hi @Hugh----, the stacktrace you provided shows this error is from the standard library `urllib` module rather than urllib3. [RFC 3986](https://tools.ietf.org/html/rfc3986#section-3.2.1) states the allowable ABNF for a URI's authority component which doesn't include gen-delims (i.e. square brackets).

You'll need to percent-encode the password before using it in the URI  in order to get things working as expected.
Cant't get correct response (post multipart/form-data including file)

URL=“http://recognition.image.myqcloud.com/ocr/general”

When I used postman(Uploading screenshot file failed multiple times):
headers
    Authorization:my_key
form-data:
    appid:1257121697
    image:local_file(File Type)
It's working! But when I used requests:
headers = {
    "Host": 'recognition.image.myqcloud.com',
    "Content-type": 'multipart/form-data',
    "Authorization": my_key ,
}

data = {
    "appid": "1257121697",
}

files = {'image': (img_file, open(img_file, 'rb'))}

response = requests.post(URL, data=data, headers=headers, files=files)
response status_code is 400.
Add Status Code Constants As A Module

It would be nice if requests had a module that housed all the possible status codes for an HTTP request in the package. That way users can utilize the constants defined in the module instead of hard coding magic numbers for testing/status code checking/etc. The django rest framework library has a similar feature to this, http://www.django-rest-framework.org/api-guide/status-codes/

This could be called something like `requests.status`, with the `status` module providing human-readable names for the different status codes:

```python
HTTP_OK = 200
HTTP_NOT_FOUND = 404
HTTP_SERVER_ERROR = 500
# You get the idea
``` 

`requests.codes`.

Thanks @kennethreitz I didn't know that was a thing
no_proxy is not compatible with urls without hostname

The `no_proxy` environment variable causes an exception when a url without a hostname is used.
This happens with conda local file system adapter for instance. 

## Reproduction Steps

Consider the following example:

```python
import requests
from requests.models import Response
from requests.adapters import BaseAdapter


class LocalFSAdapter(BaseAdapter):
    """Simplified version of
    'conda.gateways.connection.adapters.localfs.LocalFSAdapter'.
    """

    def send(self, request, **kwargs):
        _, pathname = request.url.split('file://')
        resp = Response()
        resp.raw = open(pathname, "rb")
        return resp

    def close(self):
        pass


with requests.Session() as s:
    s.mount("file://", LocalFSAdapter())
    print(s.get('file:///tmp/test').text)
```

Running with the `no_proxy` environment variable set:
```bash
$ no_proxy=nope python test.py
```

## Expected Result

```
<the content of '/tmp/test'>
```

## Actual Result

```python
Traceback (most recent call last):
  File "test.py", line 23, in <module>
    print(s.get('file:///tmp/test').text)
  File "/home/vimiche/miniconda/lib/python3.6/site-packages/requests/sessions.py", line 525, in get
    return self.request('GET', url, **kwargs)
  File "/home/vimiche/miniconda/lib/python3.6/site-packages/requests/sessions.py", line 503, in request
    prep.url, proxies, stream, verify, cert
  File "/home/vimiche/miniconda/lib/python3.6/site-packages/requests/sessions.py", line 676, in merge_environment_settings
    env_proxies = get_environ_proxies(url, no_proxy=no_proxy)
  File "/home/vimiche/miniconda/lib/python3.6/site-packages/requests/utils.py", line 760, in get_environ_proxies
    if should_bypass_proxies(url, no_proxy=no_proxy):
  File "/home/vimiche/miniconda/lib/python3.6/site-packages/requests/utils.py", line 716, in should_bypass_proxies
    if is_ipv4_address(parsed.hostname):
  File "/home/vimiche/miniconda/lib/python3.6/site-packages/requests/utils.py", line 640, in is_ipv4_address
    socket.inet_aton(string_ip)
TypeError: inet_aton() argument 1 must be str, not None
```

## System Information

    $ python -m requests.help

```json
{
  "chardet": {
    "version": "3.0.4"
  },
  "cryptography": {
    "version": "2.2.2"
  },
  "idna": {
    "version": "2.7"
  },
  "implementation": {
    "name": "CPython",
    "version": "3.6.6"
  },
  "platform": {
    "release": "4.15.0-24-generic",
    "system": "Linux"
  },
  "pyOpenSSL": {
    "openssl_version": "100020ff",
    "version": "18.0.0"
  },
  "requests": {
    "version": "2.19.1"
  },
  "system_ssl": {
    "version": "100020ff"
  },
  "urllib3": {
    "version": "1.23"
  },
  "using_pyopenssl": true
}
```

Hi @vxgmichel, we have an initial proposal in #4723 to resolve this. We’re still reviewing options to address the problem, but are aiming to have the issue resolved within the next week or so.

Resolved with #4723.
Add field "last_response" in Session object.

I want to create logger for pytest in my project. And logging last response from session. This field is necessary for me ;)

# [Codecov](https://codecov.io/gh/requests/requests/pull/4735?src=pr&el=h1) Report
> Merging [#4735](https://codecov.io/gh/requests/requests/pull/4735?src=pr&el=desc) into [master](https://codecov.io/gh/requests/requests/commit/4499401a55dedea27831fd9b3c6249b9679f3a2d?src=pr&el=desc) will **increase** coverage by `0.08%`.
> The diff coverage is `80%`.

[![Impacted file tree graph](https://codecov.io/gh/requests/requests/pull/4735/graphs/tree.svg?height=150&width=650&token=mZGswIiXLa&src=pr)](https://codecov.io/gh/requests/requests/pull/4735?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master    #4735      +/-   ##
==========================================
+ Coverage   66.79%   66.87%   +0.08%     
==========================================
  Files          15       15              
  Lines        1563     1567       +4     
==========================================
+ Hits         1044     1048       +4     
  Misses        519      519
```


| [Impacted Files](https://codecov.io/gh/requests/requests/pull/4735?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [requests/sessions.py](https://codecov.io/gh/requests/requests/pull/4735/diff?src=pr&el=tree#diff-cmVxdWVzdHMvc2Vzc2lvbnMucHk=) | `76.61% <80%> (+0.34%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/requests/requests/pull/4735?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/requests/requests/pull/4735?src=pr&el=footer). Last update [4499401...c3dc892](https://codecov.io/gh/requests/requests/pull/4735?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Quoting [our feature request documentation](https://github.com/requests/requests/blob/4499401a55dedea27831fd9b3c6249b9679f3a2d/.github/ISSUE_TEMPLATE/Feature_request.md)

> Requests is not accepting feature requests at this time.
Why does Python not use the system certs?

I've seen https://github.com/requests/requests/issues/4463 but I'm wondering why the system level certs are not used.  I know it has "never" done it, but why?  Is the problem related to supporting multiple platforms, or is there another reason?

I've just run into a problem where the IT dept was doing a MITM on their workers, and had loaded a cert that Chrome was using.  I could export that cert and put it in a linux vm pretty easily and fix CURL, but putting that same cert into the certifi file generated errors about the issuer and serial number.

This might be an question for a different package, if so, just let me know and I'll happily quiz them.  I'm torn as to whether this is a urllib3 issue or a requests issue.

https://github.com/requests/requests/issues/2966
fix cookie management bug

Even I used custom cookie jar class to manage cookie values, redirecting link only used default `RequestCookieJar` class and it seemed there was not work around.

# [Codecov](https://codecov.io/gh/requests/requests/pull/4733?src=pr&el=h1) Report
> Merging [#4733](https://codecov.io/gh/requests/requests/pull/4733?src=pr&el=desc) into [master](https://codecov.io/gh/requests/requests/commit/4499401a55dedea27831fd9b3c6249b9679f3a2d?src=pr&el=desc) will **not change** coverage.
> The diff coverage is `n/a`.

[![Impacted file tree graph](https://codecov.io/gh/requests/requests/pull/4733/graphs/tree.svg?width=650&height=150&src=pr&token=mZGswIiXLa)](https://codecov.io/gh/requests/requests/pull/4733?src=pr&el=tree)

```diff
@@           Coverage Diff           @@
##           master    #4733   +/-   ##
=======================================
  Coverage   66.79%   66.79%           
=======================================
  Files          15       15           
  Lines        1563     1563           
=======================================
  Hits         1044     1044           
  Misses        519      519
```


| [Impacted Files](https://codecov.io/gh/requests/requests/pull/4733?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [requests/sessions.py](https://codecov.io/gh/requests/requests/pull/4733/diff?src=pr&el=tree#diff-cmVxdWVzdHMvc2Vzc2lvbnMucHk=) | `76.27% <ø> (ø)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/requests/requests/pull/4733?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/requests/requests/pull/4733?src=pr&el=footer). Last update [4499401...d44d8d4](https://codecov.io/gh/requests/requests/pull/4733?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Hi @fx-kirin, thanks for contributing to Requests! Could we get a test for this so we don’t accidentally regress it in the future?

We're going to close this out since it's been pending feedback for quite some time. I think the idea is correct long term but may be breaking as the current interface always returns a RequestsCookieJar which may be relied on. Feel free to open an issue to track this if you'd like.
help.py get a error  when i run it alone

Summary.

## Expected Result
```
{
  "chardet":{
    "version":"3.0.4"
  },
  "cryptography":{
    "version":"2.1.4"
  },
  "idna":{
    "version":"2.6"
  },
  "implementation":{
    "name":"CPython",
    "version":"3.6.4"
  },
  "platform":{
    "release":"4.15.0-24-generic",
    "system":"Linux"
  },
  "pyOpenSSL":{
    "openssl_version":"100020df",
    "version":"17.5.0"
  },
  "requests":{
    "version":{

    }
  },
  "system_ssl":{
    "version":"100020ff"
  },
  "urllib3":{
    "version":"1.22"
  },
  "using_pyopenssl":true
}
```
## Actual Result

```
Traceback (most recent call last):
  File "/home/songyingxin/Code/Github/requests/requests/help.py", line 119, in <module>
    main()
  File "/home/songyingxin/Code/Github/requests/requests/help.py", line 115, in main
    print(json.dumps(info(), sort_keys=True, indent=2))
  File "/home/songyingxin/anaconda3/lib/python3.6/json/__init__.py", line 238, in dumps
    **kw).encode(obj)
  File "/home/songyingxin/anaconda3/lib/python3.6/json/encoder.py", line 201, in encode
    chunks = list(chunks)
  File "/home/songyingxin/anaconda3/lib/python3.6/json/encoder.py", line 430, in _iterencode
    yield from _iterencode_dict(o, _current_indent_level)
  File "/home/songyingxin/anaconda3/lib/python3.6/json/encoder.py", line 404, in _iterencode_dict
    yield from chunks
  File "/home/songyingxin/anaconda3/lib/python3.6/json/encoder.py", line 404, in _iterencode_dict
    yield from chunks
  File "/home/songyingxin/anaconda3/lib/python3.6/json/encoder.py", line 437, in _iterencode
    o = _default(o)
  File "/home/songyingxin/anaconda3/lib/python3.6/json/encoder.py", line 180, in default
    o.__class__.__name__)
TypeError: Object of type 'module' is not JSON serializable
```

## Reproduction Steps
the error is because the json , when i change it as `import ujson as json` , everything is ok. I think there maybe some bug in different platform .  my OS is 'Linux' ,  'Ubuntu16.04", python-version: "Cpython", "3.6.4". 


Hi @songyingxin, it looks like you may have a file named requests.py in your project that is hijacking the namespace we’re expecting. Alternatively, you may have two different versions of requests installed, one of which is older and doesn’t support help.

Also, what does "run it alone" mean?

No information provided for reproduction. Closing.
socket.timeout: timed out

Traceback (most recent call last):
  File "E:/Python-Code/crawler/okex/Client.py", line 20, in <module>
    print (okcoinSpot.ticker('btc_usdt'))
  File "E:\Python-Code\crawler\okex\OkcoinSpotAPI.py", line 19, in ticker
    return httpGet(self.__url,TICKER_RESOURCE,params)
  File "E:\Python-Code\crawler\okex\HttpMD5Util.py", line 22, in httpGet
    conn.request("GET", resource + '?' + params)
  File "D:\Program Files (x86)\Python\Lib\httplib.py", line 1042, in request
    self._send_request(method, url, body, headers)
  File "D:\Program Files (x86)\Python\Lib\httplib.py", line 1082, in _send_request
    self.endheaders(body)
  File "D:\Program Files (x86)\Python\Lib\httplib.py", line 1038, in endheaders
    self._send_output(message_body)
  File "D:\Program Files (x86)\Python\Lib\httplib.py", line 882, in _send_output
    self.send(msg)
  File "D:\Program Files (x86)\Python\Lib\httplib.py", line 844, in send
    self.connect()
  File "D:\Program Files (x86)\Python\Lib\httplib.py", line 1255, in connect
    HTTPConnection.connect(self)
  File "D:\Program Files (x86)\Python\Lib\httplib.py", line 821, in connect
    self.timeout, self.source_address)
  File "D:\Program Files (x86)\Python\Lib\socket.py", line 575, in create_connection
    raise err
socket.timeout: timed out
Header string values are changed to lower-case even though required to be case-sensitive by RFC-2017

Summary.

To create a redirect resource within a Fedora4 Common repository (https://wiki.duraspace.org/display/FEDORA4x/RESTful+HTTP+API#RESTfulHTTPAPI-external-content) you'll have to use a PUT header involving  Content-Type header "message/external-body" (defined in  https://tools.ietf.org/html/rfc2017).
Request changes the character case of the Content-Type header "message/external-body". The URL Parameters must be send in upper-case form but request changes it to lower-case.

## Expected Result

Header will be send as _stated_:
{'Content-Type': 'message/external-body; access-type=URL; URL="http://example.com"'}

## Actual Result

The string "URL=" in the header has been changed to "url=":
_Server Response_

Invalid Content Type message/external-body;access-type=URL;url="http://example.com"

## Reproduction Steps

```python
import requests

 headers = {  
  'Content-Type': 'message/external-body; access-type=URL; URL="http://example.com"' 
 }


```

## System Information

    $ python -m requests.help

```
{
  "chardet": {
    "version": "3.0.4"
  },
  "cryptography": {
    "version": ""
  },
  "idna": {
    "version": "2.7"
  },
  "implementation": {
    "name": "CPython",
    "version": "3.5.2"
  },
  "platform": {
    "release": "4.4.0-124-generic",
    "system": "Linux"
  },
  "pyOpenSSL": {
    "openssl_version": "",
    "version": null
  },
  "requests": {
    "version": "2.19.1"
  },
  "system_ssl": {
    "version": "1000207f"
  },
  "urllib3": {
    "version": "1.23"
  },
  "using_pyopenssl": false
}

```

Hi @klindt,

I don't believe this is the product of Requests. We shouldn't be doing any mutating of the header values, only keys which is allowable for normalization.

Here's a simple repro showing we maintain the casing:
```python
import requests

headers = {
    'Content-Type': 'message/external-body; access-type=URL; URL="http://example.com"'
}
r = requests.get('https://httpbin.org/get', headers=headers)
print(r.json()['headers']['Content-Type'])
```

My guess would be that you either have a proxy between you and your target server which is manipulating the request, or something else in your code base is tampering with the values. Without other information pointing towards a defect in Requests, I don't know if we can go much further here.
Fix an invalid escape sequence

Fix errors like this:
```
$ python -W error -c 'import requests'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/Users/yen/Projects/requests/requests/__init__.py", line 114, in <module>
    from .models import Request, Response, PreparedRequest
  File "/Users/yen/Projects/requests/requests/models.py", line 43, in <module>
    from .status_codes import codes
  File "/Users/yen/Projects/requests/requests/status_codes.py", line 18
    """
SyntaxError: invalid escape sequence \o
```
Context: the [buildbot](https://github.com/buildbot/buildbot) test suite treats all warnings as errors.

# [Codecov](https://codecov.io/gh/requests/requests/pull/4728?src=pr&el=h1) Report
> Merging [#4728](https://codecov.io/gh/requests/requests/pull/4728?src=pr&el=desc) into [master](https://codecov.io/gh/requests/requests/commit/ef88b9faa6d73bc83a07ddebc424c551d2ee671c?src=pr&el=desc) will **not change** coverage.
> The diff coverage is `0%`.

[![Impacted file tree graph](https://codecov.io/gh/requests/requests/pull/4728/graphs/tree.svg?token=mZGswIiXLa&src=pr&width=650&height=150)](https://codecov.io/gh/requests/requests/pull/4728?src=pr&el=tree)

```diff
@@           Coverage Diff           @@
##           master    #4728   +/-   ##
=======================================
  Coverage   66.79%   66.79%           
=======================================
  Files          15       15           
  Lines        1563     1563           
=======================================
  Hits         1044     1044           
  Misses        519      519
```


| [Impacted Files](https://codecov.io/gh/requests/requests/pull/4728?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [requests/status\_codes.py](https://codecov.io/gh/requests/requests/pull/4728/diff?src=pr&el=tree#diff-cmVxdWVzdHMvc3RhdHVzX2NvZGVzLnB5) | `0% <0%> (ø)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/requests/requests/pull/4728?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/requests/requests/pull/4728?src=pr&el=footer). Last update [ef88b9f...b1a360c](https://codecov.io/gh/requests/requests/pull/4728?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).
Session.verify is ignored when REQUESTS_CA_BUNDLE is set in environment

Trying to use a Session object to have a common TLS verify option for a bunch of calls in a CI environment for test with self signed certificates.

This works all right when no environment variable is set, but once REQUESTS_CA_BUNDLE or the equivalent curl var is set up, it fails.

This probably happens due to the logic in `merge_environment_settings()` and the merge logic for settings. 

## Expected Result

Verify works, the explicitly configured ca path on the Session object is used.
<Response [200]>

## Actual Result

Verify fails, the implicitly configured environment setting overrides the explicit setting on the Session.

SSLError: HTTPSConnectionPool(host='example.org', port=8443): Max retries exceeded with url: /login (Caused by SSLError(SSLError(1, u'[SSL: CERTIFICATE_VERIFY_FAILED]

## Reproduction Steps

```python
import requests, os
# One of the many linux default locations for a ca bundle
os.environ['REQUESTS_CA_BUNDLE'] = '/etc/ssl/certs/ca-bundle.crt'
ca = "/home/schlenk/sqlite/certs/ca.crt"
print requests.get('https://myhost.example.org:8443/', verify=ca)
# This gives a <Response [200]>
# Now try with Session
s = requests.Session()
s.verify = ca
s.get('https://myhost.example.org:8443/')
# This throws an SSLError exception
# SSLError: HTTPSConnectionPool(host='myhost.example.org', port=8443): Max retries exceeded with url:  / (Caused by SSLError(SSLError(1, u'[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:726)'),))
# But this works just fine
s.get('https://myhost.example.org:8443/', verify=ca)
<Response [200]>
```

## System Information

    $ python -m requests.help

```
d:\code\trunk64>win32\debug\img\python.exe -m requests.help
{
  "chardet": {
    "version": "3.0.4"
  },
  "cryptography": {
    "version": "2.2.2"
  },
  "idna": {
    "version": "2.6"
  },
  "implementation": {
    "name": "CPython",
    "version": "2.7.15"
  },
  "platform": {
    "release": "2012ServerR2",
    "system": "Windows"
  },
  "pyOpenSSL": {
    "openssl_version": "100020df",
    "version": "18.0.0"
  },
  "requests": {
    "version": "2.18.4"
  },
  "system_ssl": {
    "version": "100020ff"
  },
  "urllib3": {
    "version": "1.22"
  },
  "using_pyopenssl": true
}
```

Same issue happens on Linux with identical versions.


In the future, please search **closed and** open issues before creating new ones that are duplicates.
Getting response content starting with  b

Summary.
In output of content of a response , it is getting printed with starting as **b**
## Expected Result
No **b** at the starting of output
What you expected.
No **b** at the starting of output
## Actual Result
output without **b** at the beginning
What happened instead.
![image](https://user-images.githubusercontent.com/29581152/42371314-bbf171b2-812c-11e8-8eb6-cf48850c16e0.png)

## Reproduction Steps
Just print any output like : response.content
```python
import requests

```

## System Information

Linux Ubuntu 18.06
python version:3.6.5

This command is only available on Requests v2.16.4 and greater. Otherwise,
please provide some basic information about your system (Python version,
operating system, &c).


You likely want `response.text` then if you don't want the content as raw bytes but instead as a string.

This is not a bug.

ohh, i see.. I thought that it's showing improper response.
Thanks for correcting my issue @sigmavirus24
Fixed pep8 issues in tests/test_help.py

Fixed pep8 issues below: 

test_help.py:10:47: E231 missing whitespace after ','
test_help.py:10:80: E501 line too long (83 > 79 characters)
test_help.py:18:42: E231 missing whitespace after ','
test_help.py:38:80: E501 line too long (81 > 79 characters)


# [Codecov](https://codecov.io/gh/requests/requests/pull/4722?src=pr&el=h1) Report
> Merging [#4722](https://codecov.io/gh/requests/requests/pull/4722?src=pr&el=desc) into [master](https://codecov.io/gh/requests/requests/commit/ef88b9faa6d73bc83a07ddebc424c551d2ee671c?src=pr&el=desc) will **not change** coverage.
> The diff coverage is `n/a`.

[![Impacted file tree graph](https://codecov.io/gh/requests/requests/pull/4722/graphs/tree.svg?width=650&height=150&src=pr&token=mZGswIiXLa)](https://codecov.io/gh/requests/requests/pull/4722?src=pr&el=tree)

```diff
@@           Coverage Diff           @@
##           master    #4722   +/-   ##
=======================================
  Coverage   66.79%   66.79%           
=======================================
  Files          15       15           
  Lines        1563     1563           
=======================================
  Hits         1044     1044           
  Misses        519      519
```



------

[Continue to review full report at Codecov](https://codecov.io/gh/requests/requests/pull/4722?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/requests/requests/pull/4722?src=pr&el=footer). Last update [ef88b9f...8be665a](https://codecov.io/gh/requests/requests/pull/4722?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


This project doesn't use pep8, flake8 or any of those style guide tools. We appreciate the effort you've spent on this, but we're not going to accept this pull request. Searching past issues and pull requests point out that this is a consistent standpoint.
Session baseUrl?

"Requests is not accepting feature requests at this time." I see.

But really guys, would it be too much to ask to get this implemented into the Sessions? I could submit a PR. Axios and many other libraries support this already, and it comes it really handy.

I know there are workarounds, subclass it and what not but that is so ugly when it could be built into the module with ~5 lines of code.

Please 💯 
Thanks

In the future, please search **closed and** open issues before creating new ones that are duplicates.

I am aware there have been [previous requests](https://github.com/requests/requests/issues/133), but obviously, they *haven't been answered*... Hence me opening a new issue. 

There wasn't even a discussion, that thread was killed instantly, kind of like **this** one.

~~I get that hooks can be used, but~~ It seems like `baseUrl` would be much cleaner and much more readable.

Actually, after further testing it, `hooks` cannot be used like in the above issue. From what I have seen, you now can only hook the `response`, but not the `args`. 

http://docs.python-requests.org/en/master/user/advanced/#event-hooks

Hi @NoahCardoza, I believe what @sigmavirus24 is pointing out is that we've already done the work for this and it's freely available in the [Requests toolbelt](https://github.com/requests/toolbelt/blob/master/requests_toolbelt/sessions.py#L6) as detailed in those other issues.

We cannot feasibly support every possible knob and whistle people want in Requests, so we provided the ability to either implement them yourself, or use our implementations of them in the toolbelt. We have dozens of messages discussing this topic, so I'm not sure what you feel is unanswered here.

Further, there's more than just one issue discussing this. Others have had full discussions. You're not so special as to receive that precious time of mine or Nate's to have another full discussion.