`no_proxy` implementation is too greedy

The implementation of `no_proxy` environment just checks that the hostname ends with some host present in the `no_proxy` variable. Although there is no clear specification for `no_proxy`, this behavior is very unexpected and even dangerous.

- It prevents you from bypassing only one domain and not its subdomains.
- If `no_proxy` is set for `requests.com`, `attacker-requests.com` is also whitelisted. Not sure it's really really bad, but huh, it's definitely not good.

## Expected Result

- `no_proxy=gle.com` should bypass ONLY the domain `gle.com` (optionally its subdomains, but I don't think it's desirable)
- `no_proxy=www.gle.com` should bypass ONLY the domain `www.gle.com` (optionally its subdomains, but I don't think it's desirable)
- `no_proxy=.google.com` should bypass ONLY subdomains of `google.com` (and optionally `google.com`, but I don't think it's desirable)

## Actual Result

`no_proxy=gle.com` bypasses any domain that ends with `gle.com`, including:
- `google.com`
- `www.google.com`
- `foo.gle.com`
- `foo.bar.gle.com`

## Reproduction Steps

```
$ http_proxy=http://no-proxy-here/ no_proxy=gle.com python -c "import requests; print(requests.get('http://www.google.com'))"     
<Response [200]>
```

## System Information

    $ python -m requests.help

```
{
  "chardet": {
    "version": "3.0.4"
  },
  "cryptography": {
    "version": ""
  },
  "idna": {
    "version": "2.7"
  },
  "implementation": {
    "name": "CPython",
    "version": "3.7.0"
  },
  "platform": {
    "release": "4.18.7-arch1-1-ARCH",
    "system": "Linux"
  },
  "pyOpenSSL": {
    "openssl_version": "",
    "version": null
  },
  "requests": {
    "version": "2.19.1"
  },
  "system_ssl": {
    "version": "1010100f"
  },
  "urllib3": {
    "version": "1.23"
  },
  "using_pyopenssl": false
}
```

I can prepare a PR if needed.

Hi @gilbsgilbs, thanks for bringing this to our attention. NO_PROXY is a variable that unfortunately doesn't have a clear spec and has be reimplemented slightly differently in many different clients. This is a case where we've tried to follow curl for most of our implementation details. For reference, this thread was one of the more recent discussions on the curl issue tracker which has a lot of useful information (https://github.com/curl/curl/issues/1208).

I agree we're being too greedy here, and want to make sure we're scoping domains correctly for the bypass. It looks like curl's [current documentation](https://curl.haxx.se/docs/manual.html) specifies this as the definition of the NO_PROXY variable (emphasis mine):
> If the host name matches one of these strings, or the host is within the
  domain of one of these strings, transactions with that node will not be
  proxied. **When a domain is used, it needs to start with a period.** A user can
  specify that both www.example.com and foo.example.com should not uses a
  proxy by setting NO_PROXY to ".example.com". By including the full name you
  can exclude specific host names, so to make www.example.com not use a proxy
  but still have foo.example.com do it, set NO_PROXY to "www.example.com"

I think our best bet for solving this is to append the leading dot in our proxy_bypass handling if the user doesn't pass it. That means `gle.com` would be treated as `.gle.com` preventing the domain hijacking issue. We'd probably use this same method when comparing user requested domains without a leading subdomain (e.g. http://google.com).

Hi @nateprewitt, thanks for replying.

> NO_PROXY is a variable that unfortunately doesn't have a clear spec and has be reimplemented slightly differently in many different clients.

Unfortunately…

> I think our best bet for solving this is to append the leading dot in our proxy_bypass handling if the user doesn't pass it. That means gle.com would be treated as .gle.com preventing the domain hijacking issue. We'd probably use this same method when comparing user requested domains without a leading subdomain (e.g. http://google.com).

This happens to work thanks to the [`proxy_bypass` function from urllib](https://github.com/python/cpython/blob/9df100286b35f1f9fa85976d573981f558805b3f/Lib/urllib/request.py#L2487) which is [delegated by requests](https://github.com/requests/requests/blob/a6cd380c640087218695bc7c62311a4843777e43/requests/utils.py#L748). I don't know the exact story behind the current implementation (why some things are inferred by requests itself and some others are delegated to urllib), but if prepending `.` to the host (if not already present) sounds like a good fix to you, I could submit a PR sometimes.

Thanks.