301 on PUT drops body

When receiving a 301 redirect to an HTTP PUT, the second request is also a PUT but the body has been dropped.

## Expected Result

Either the request is converted to a GET (form reply redirect), or the body is retained (full retry redirect).

## Actual Result

```
DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): myapp.redacted:80
send: b'PUT /api/2/devices/208395 HTTP/1.1\r\nHost: myapp.redacted\r\nUser-Agent: python-requests/2.25.0\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nConnection: keep-alive\r\nContent-Type: application/json\r\nContent-Length: 5773\r\nAuthorization: Basic <redacted base64 blob>\r\n\r\n'
send: b'<redacted json blob>'
reply: 'HTTP/1.1 301 Moved Permanently\r\n'
header: Server: nginx/1.14.0 (Ubuntu)
header: Date: Wed, 09 Dec 2020 18:42:52 GMT
header: Content-Type: text/html
header: Content-Length: 194
header: Connection: keep-alive
header: Location: https://myapp.redacted/api/2/devices/208395
DEBUG:urllib3.connectionpool:http://myapp.redacted:80 "PUT /api/2/devices/208395 HTTP/1.1" 301 194
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): myapp.redacted:443
send: b'PUT /api/2/devices/208395 HTTP/1.1\r\nHost: myapp.redacted\r\nContent-Length: 0\r\nUser-Agent: python-requests/2.25.0\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nConnection: keep-alive\r\nAuthorization: Basic <redacted base64 blob>\r\n\r\n'
reply: 'HTTP/1.1 500 INTERNAL SERVER ERROR\r\n'
header: Server: nginx/1.14.0 (Ubuntu)
header: Date: Wed, 09 Dec 2020 18:42:52 GMT
header: Content-Type: application/json
header: Content-Length: 43
header: Connection: keep-alive
header: Set-Cookie: myapp_session=9b25161f-c9d8-48a7-b72e-e564fffc38b3; Domain=dev.purestorage.com; Expires=Sat, 09-Jan-2021 18:42:52 GMT; Secure; HttpOnly; Path=/
```

Notice that in the second request, `Content-Length` is 0 and no body is sent.

## Reproduction Steps

Private library code.

## System Information

```
{
  "chardet": {
    "version": "3.0.4"
  },
  "cryptography": {
    "version": ""
  },
  "idna": {
    "version": "2.10"
  },
  "implementation": {
    "name": "CPython",
    "version": "3.8.5"
  },
  "platform": {
    "release": "19.6.0",
    "system": "Darwin"
  },
  "pyOpenSSL": {
    "openssl_version": "",
    "version": null
  },
  "requests": {
    "version": "2.25.0"
  },
  "system_ssl": {
    "version": "1010108f"
  },
  "urllib3": {
    "version": "1.26.2"
  },
  "using_pyopenssl": false
}
```


This is expected for compatibility reasons, see: https://tools.ietf.org/html/rfc7231#section-6.4.4
The HTTP status should be 308 for permanent redirects that don't change the request method.

Ok, then you should either:

* Convert to a GET completely
* Keep it a PUT and retain the body

This "Issue a PUT but drop the body" is just _bad_.

>Note: For historical reasons, a user agent MAY change the request method from POST to GET for the subsequent request.  If this behavior is undesired, the 307 (Temporary Redirect) status code can be used instead.

If we extend "POST" to mean "anything not GET" (I am doing a PUT not a POST), then you should still be changing the method (which you are not doing).

If you opt not to follow the historical behavior, then you should be including the request body in the second request.

Hi @AstraLuma, we're aware of the current behavior. It's discussed in a handful of issues if you search the tracker. We actually merged a fix (#3757) for this issue way back in 2016 for the 3.0 branch. It's unfortunately a breaking change so we're kind of stuck with the current functionality.

To be clear, PUT shouldn't be redirected to a GET, so that behavior is inline with what we'd expect. The problem is we indiscriminately strip bodies for security concerns, rather than only for POSTs.