バグ: PyDrive で RedirectMissingLocation 例外が発生する（Python/Colaboratory）

Colaboratory から、大きなサイズのファイルを、`PyDrive` を使って Google ドライブにアップロードしようとすると、`RedirectMissingLocation` 例外が発生して失敗する。
回避方法は[こちら](#原因と回避方法)。

#問題の詳細
サンプルコードは以下のリンクを参照。
[外部データ: ローカル ファイル、ドライブ、スプレッドシート、Cloud Storage - Colaboratory](https://colab.research.google.com/notebooks/io.ipynb)
\> Google ドライブ > PyDrive

```Python
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive
from google.colab import auth
from oauth2client.client import GoogleCredentials

auth.authenticate_user()
gauth = GoogleAuth()
gauth.credentials = GoogleCredentials.get_application_default()
drive = GoogleDrive(gauth)
```

なお、投稿時点（2021.7.17）でインストールされていた `PyDrive` のバージョンは `1.3.1`（[詳細](#バージョンの詳細)）。
Colaboratory 上にあるファイルを Google ドライブにアップロードするには、次のようにする。

```Python
dfile = drive.CreateFile()
dfile.SetContentFile("path.to.large.file")
dfile.Upload()
```

ここで `path.to.large.file` のファイルサイズが大きいと、`RedirectMissingLocation` 例外が発生して失敗する（[詳細](#例外の詳細)）。

```
RedirectMissingLocation: Redirected but the response is missing a Location: header.
```

#原因と回避方法
原因は `PyDrive` が依存している `httplib2` のバグのようである。
詳細は以下の issue を参照。
[httplib2 v0.16.0 breaks the library · Issue #803 · googleapis/google-api-python-client · GitHub](https://github.com/googleapis/google-api-python-client/issues/803)

この issue に書かれているように、`httplib2` をダウングレードすることで回避できる可能性がある。
なお、投稿時点でインストールされていた `httplib2` のバージョンは `0.17.4`（[詳細](#バージョンの詳細)）。

```
pip install -U httplib2==0.15.0
```
ダウングレードが終わったら、ランタイムを再起動すること。

---
#例外の詳細
```

---------------------------------------------------------------------------
 
RedirectMissingLocation                   Traceback (most recent call last)
 
<ipython-input-34-d2b7f6f09d2e> in <module>()
      1 dfile = drive.CreateFile()
      2 dfile.SetContentFile("path.to.large.file")
----> 3 dfile.Upload()
 
10 frames
 
/usr/local/lib/python3.7/dist-packages/pydrive/files.py in Upload(self, param)
    283         self._FilesPatch(param=param)
    284     else:
--> 285       self._FilesInsert(param=param)
    286 
    287   def Trash(self, param=None):
 
/usr/local/lib/python3.7/dist-packages/pydrive/auth.py in _decorated(self, *args, **kwargs)
     73       self.http = self.auth.Get_Http_Object()
     74 
---> 75     return decoratee(self, *args, **kwargs)
     76   return _decorated
     77 
 
/usr/local/lib/python3.7/dist-packages/pydrive/files.py in _FilesInsert(self, param)
    367         param['media_body'] = self._BuildMediaBody()
    368       metadata = self.auth.service.files().insert(**param).execute(
--> 369         http=self.http)
    370     except errors.HttpError as error:
    371       raise ApiRequestError(error)
 
/usr/local/lib/python3.7/dist-packages/googleapiclient/_helpers.py in positional_wrapper(*args, **kwargs)
    132                 elif positional_parameters_enforcement == POSITIONAL_WARNING:
    133                     logger.warning(message)
--> 134             return wrapped(*args, **kwargs)
    135 
    136         return positional_wrapper
 
/usr/local/lib/python3.7/dist-packages/googleapiclient/http.py in execute(self, http, num_retries)
    877             body = None
    878             while body is None:
--> 879                 _, body = self.next_chunk(http=http, num_retries=num_retries)
    880             return body
    881 
 
/usr/local/lib/python3.7/dist-packages/googleapiclient/_helpers.py in positional_wrapper(*args, **kwargs)
    132                 elif positional_parameters_enforcement == POSITIONAL_WARNING:
    133                     logger.warning(message)
--> 134             return wrapped(*args, **kwargs)
    135 
    136         return positional_wrapper
 
/usr/local/lib/python3.7/dist-packages/googleapiclient/http.py in next_chunk(self, http, num_retries)
   1056             try:
   1057                 resp, content = http.request(
-> 1058                     self.resumable_uri, method="PUT", body=data, headers=headers
   1059                 )
   1060             except:
 
/usr/local/lib/python3.7/dist-packages/oauth2client/transport.py in new_request(uri, method, body, headers, redirections, connection_type)
    173         resp, content = request(orig_request_method, uri, method, body,
    174                                 clean_headers(headers),
--> 175                                 redirections, connection_type)
    176 
    177         # A stored token may expire between the time it is retrieved and
 
/usr/local/lib/python3.7/dist-packages/oauth2client/transport.py in request(http, uri, method, body, headers, redirections, connection_type)
    280     return http_callable(uri, method=method, body=body, headers=headers,
    281                          redirections=redirections,
--> 282                          connection_type=connection_type)
    283 
    284 
 
/usr/local/lib/python3.7/dist-packages/httplib2/__init__.py in request(self, uri, method, body, headers, redirections, connection_type)
   1989                         headers,
   1990                         redirections,
-> 1991                         cachekey,
   1992                     )
   1993         except Exception as e:
 
/usr/local/lib/python3.7/dist-packages/httplib2/__init__.py in _request(self, conn, host, absolute_uri, request_uri, method, body, headers, redirections, cachekey)
   1688                             ),
   1689                             response,
-> 1690                             content,
   1691                         )
   1692                     # Fix-up relative redirects (which violate an RFC 2616 MUST)
 
RedirectMissingLocation: Redirected but the response is missing a Location: header.
```

#バージョンの詳細
```
PyDrive==1.3.1
  - google-api-python-client [required: >=1.2, installed: 1.12.8]
    - google-api-core [required: >=1.21.0,<2dev, installed: 1.26.3]
      - google-auth [required: >=1.21.1,<2.0dev, installed: 1.32.1]
        - cachetools [required: >=2.0.0,<5.0, installed: 4.2.2]
        - pyasn1-modules [required: >=0.2.1, installed: 0.2.8]
          - pyasn1 [required: >=0.4.6,<0.5.0, installed: 0.4.8]
        - rsa [required: >=3.1.4,<5, installed: 4.7.2]
          - pyasn1 [required: >=0.1.3, installed: 0.4.8]
        - setuptools [required: >=40.3.0, installed: 57.2.0]
        - six [required: >=1.9.0, installed: 1.15.0]
      - googleapis-common-protos [required: >=1.6.0,<2.0dev, installed: 1.53.0]
        - protobuf [required: >=3.12.0, installed: 3.17.3]
          - six [required: >=1.9, installed: 1.15.0]
      - packaging [required: >=14.3, installed: 21.0]
        - pyparsing [required: >=2.0.2, installed: 2.4.7]
      - protobuf [required: >=3.12.0, installed: 3.17.3]
        - six [required: >=1.9, installed: 1.15.0]
      - pytz [required: Any, installed: 2018.9]
      - requests [required: >=2.18.0,<3.0.0dev, installed: 2.23.0]
        - certifi [required: >=2017.4.17, installed: 2021.5.30]
        - chardet [required: >=3.0.2,<4, installed: 3.0.4]
        - idna [required: >=2.5,<3, installed: 2.10]
        - urllib3 [required: >=1.21.1,<1.26,!=1.25.1,!=1.25.0, installed: 1.24.3]
      - setuptools [required: >=40.3.0, installed: 57.2.0]
      - six [required: >=1.13.0, installed: 1.15.0]
    - google-auth [required: >=1.16.0, installed: 1.32.1]
      - cachetools [required: >=2.0.0,<5.0, installed: 4.2.2]
      - pyasn1-modules [required: >=0.2.1, installed: 0.2.8]
        - pyasn1 [required: >=0.4.6,<0.5.0, installed: 0.4.8]
      - rsa [required: >=3.1.4,<5, installed: 4.7.2]
        - pyasn1 [required: >=0.1.3, installed: 0.4.8]
      - setuptools [required: >=40.3.0, installed: 57.2.0]
      - six [required: >=1.9.0, installed: 1.15.0]
    - google-auth-httplib2 [required: >=0.0.3, installed: 0.0.4]
      - google-auth [required: Any, installed: 1.32.1]
        - cachetools [required: >=2.0.0,<5.0, installed: 4.2.2]
        - pyasn1-modules [required: >=0.2.1, installed: 0.2.8]
          - pyasn1 [required: >=0.4.6,<0.5.0, installed: 0.4.8]
        - rsa [required: >=3.1.4,<5, installed: 4.7.2]
          - pyasn1 [required: >=0.1.3, installed: 0.4.8]
        - setuptools [required: >=40.3.0, installed: 57.2.0]
        - six [required: >=1.9.0, installed: 1.15.0]
      - httplib2 [required: >=0.9.1, installed: 0.17.4]
      - six [required: Any, installed: 1.15.0]
    - httplib2 [required: >=0.15.0,<1dev, installed: 0.17.4]
    - six [required: >=1.13.0,<2dev, installed: 1.15.0]
    - uritemplate [required: >=3.0.0,<4dev, installed: 3.0.1]
  - oauth2client [required: >=4.0.0, installed: 4.1.3]
    - httplib2 [required: >=0.9.1, installed: 0.17.4]
    - pyasn1 [required: >=0.1.7, installed: 0.4.8]
    - pyasn1-modules [required: >=0.0.5, installed: 0.2.8]
      - pyasn1 [required: >=0.4.6,<0.5.0, installed: 0.4.8]
    - rsa [required: >=3.1.4, installed: 4.7.2]
      - pyasn1 [required: >=0.1.3, installed: 0.4.8]
    - six [required: >=1.6.1, installed: 1.15.0]
  - PyYAML [required: >=3.0, installed: 3.13]
```