Running requests in parallel from a zip archive can create race condition when unpacking the cacerts.pem file

We ran into a really crazy case and I understand this is a edge case but it might be worth fixing.

We started to see this backtrace in our CI:

```
[2019-10-08T08:01:13.655Z]   File "/data/jenkins/postproc-asustor/204934530/conan/lib/conan-1.4.4-66-linux-py36.pyz/requests/api.py", line 75, in get
[2019-10-08T08:01:13.655Z]   File "/data/jenkins/postproc-asustor/204934530/conan/lib/conan-1.4.4-66-linux-py36.pyz/requests/api.py", line 60, in request
[2019-10-08T08:01:13.655Z]   File "/data/jenkins/postproc-asustor/204934530/conan/lib/conan-1.4.4-66-linux-py36.pyz/requests/sessions.py", line 533, in request
[2019-10-08T08:01:13.655Z]   File "/data/jenkins/postproc-asustor/204934530/conan/lib/conan-1.4.4-66-linux-py36.pyz/requests/sessions.py", line 646, in send
[2019-10-08T08:01:13.655Z]   File "/data/jenkins/postproc-asustor/204934530/conan/lib/conan-1.4.4-66-linux-py36.pyz/requests/adapters.py", line 416, in send
[2019-10-08T08:01:13.655Z]   File "/data/jenkins/postproc-asustor/204934530/conan/lib/conan-1.4.4-66-linux-py36.pyz/requests/adapters.py", line 224, in cert_verify
[2019-10-08T08:01:13.655Z]   File "/data/jenkins/postproc-asustor/204934530/conan/lib/conan-1.4.4-66-linux-py36.pyz/requests/utils.py", line 254, in extract_zipped_paths
[2019-10-08T08:01:13.655Z]   File "/usr/local/pyenv/versions/3.6.4/lib/python3.6/zipfile.py", line 1484, in extract
[2019-10-08T08:01:13.655Z]     return self._extract_member(member, path, pwd)
[2019-10-08T08:01:13.655Z]   File "/usr/local/pyenv/versions/3.6.4/lib/python3.6/zipfile.py", line 1547, in _extract_member
[2019-10-08T08:01:13.655Z]     os.makedirs(upperdirs)
[2019-10-08T08:01:13.655Z]   File "/usr/local/pyenv/versions/3.6.4/lib/python3.6/os.py", line 220, in makedirs
[2019-10-08T08:01:13.655Z]     mkdir(name, mode)
[2019-10-08T08:01:13.655Z] FileExistsError: [Errno 17] File exists: '/data/jenkins/postproc-asustor/204934530/_temp/certifi'
```

After a lot of confusion I think I understand this bug now. We distribute our python dependencies (including requests) as a pyz (created with zipapp) and the consumer in this case calls request inside a `ThreadPool`. requests then have logic to unpack `cacerts.pem` into the temp directory, but there is no race protection. So our parallel threads stepped on each other toes here when unpacking this file.

We solved this by a simple get call before starting the parallel invocation. But I think it might be worth fixing because it's very confusing.

## Expected Result

Not having the cacert being overwritten :)

## Actual Result

Exception above

## Reproduction Steps

create a pyz with zipapp of requests and it's dependencies (certifi)

```python
import requests                                                                                                                                                                                         from concurrent.futures import ThreadPoolExecutor

urls = ("https://github.com", "https://github.com", "https://github.com", "https://github.com")

def get(url):
    print(f"Getting {url}")
    requests.get(url)

with ThreadPoolExecutor(5) as pool:
      pool.map(get, urls)
```

note that since it's a race it can trigger or not trigger a lot.

## System Information

    $ python -m requests.help

```
{
  "chardet": {
    "version": "3.0.4"
  },
  "cryptography": {
    "version": "2.1.4"
  },
  "idna": {
    "version": "2.8"
  },
  "implementation": {
    "name": "CPython",
    "version": "3.6.8"
  },
  "platform": {
    "release": "4.19.72-microsoft-standard",
    "system": "Linux"
  },
  "pyOpenSSL": {
    "openssl_version": "1010100f",
    "version": "17.5.0"
  },
  "requests": {
    "version": "2.22.0"
  },
  "system_ssl": {
    "version": "1010100f"
  },
  "urllib3": {
    "version": "1.25.6"
  },
  "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).


This can be reproduced with running pip in parallel too.

Genuinely, it'd be best if there was a way not have to extract `cacerts.pem` from the zip file at all and be able to clean it up simply but that just doesn't exist. I've taken multiple approaches trying to fix this, and it's just not that simple to fix.

To be more specific:

- We could attempt to extract on first use to a unique directory, but if we end up in a `multiprocessing` situation or threaded situation that could mean N copies on disk for N parallel workers
- We could extract per-request which just is awful
- We could try doing it at import time and then cleaning up with `atexit` but that's horribly unreliable and could leave resources lying around
- We could add a dependency on a lockfile library and use that to prevent any two workers from extracting to the same directory at the same time, or trying to overwrite what's being written. This last one seems most reasonable but last I checked there was no good, well-maintained lockfile library for Python that we could trust to be secure and up-to-date.

What about using an application data folder to extract this (no cleanup), and do the writing in parallel safe manner (mkdir with exist ok)? This is how virtualenv handles this and no one - complained yet for adding a  few kb files in application data folder).

We've had multiple complaints just about the fact that we write to a directory. I think previously we used a more predictable (between python interpreters) directory and that got people riled up too. In general, people don't want us creating files at all. The 100% best solution is the standard library `ssl` module accepting strings rather than requiring files on the system to verify certificates.

Also, can you clarify *your* definition of "application data folder" here? I think it's what we've done before and it opens us up to another utility in the user's space changing the file thus allowing something to corrupt the trust store (which is very bad)

A user write able temp folder is almost as easy to exploit as a user write able temp folder we have now. That being said I think for this issue the easiest solution is to put the extract operation in a try catch and silently swallow the exception if the file already exist. The race condition would no longer throw an exception and everything would work as expected. 

https://github.com/psf/requests/pull/5707 works around the issue by keeping the current solution but without the racing condition imposed by the os makedirs.

@sigmavirus24 alternatively we can export this into a context manager handled temporary file on a per ``send`` call basis, what do you think? Though that can get messy with session connections.