Repository: imageio/imageio

Issue:
UnsupportedOperation seek while reading HTTP uri
I am using imageio for a while, but since I upgraded to python 3.6, I have problems loading an image from an online location

```
imageio.imread(url)
---------------------------------------------------------------------------
UnsupportedOperation                      Traceback (most recent call last)
<ipython-input-33-cd9354e362f7> in <module>()
----> 1 imageio.imread(url)

/usr/local/lib/python3.6/site-packages/imageio/core/functions.py in imread(uri, format, **kwargs)
    185     reader = read(uri, format, 'i', **kwargs)
    186     with reader:
--> 187         return reader.get_data(0)
    188
    189

/usr/local/lib/python3.6/site-packages/imageio/core/format.py in get_data(self, index, **kwargs)
    330             self._checkClosed()
    331             self._BaseReaderWriter_last_index = index
--> 332             im, meta = self._get_data(index, **kwargs)
    333             return Image(im, meta)  # Image tests im and meta
    334

/usr/local/lib/python3.6/site-packages/imageio/plugins/pillow.py in _get_data(self, index)
    300
    301         def _get_data(self, index):
--> 302             im, info = PillowFormat.Reader._get_data(self, index)
    303
    304             # Handle exif

/usr/local/lib/python3.6/site-packages/imageio/plugins/pillow.py in _get_data(self, index)
    113                     i += 1
    114                     self._seek(i)
--> 115             self._im.getdata()[0]
    116             im = pil_get_frame(self._im, self._grayscale)
    117             return im, self._im.info

/usr/local/lib/python3.6/site-packages/PIL/Image.py in getdata(self, band)
   1151         """
   1152
-> 1153         self.load()
   1154         if band is not None:
   1155             return self.im.getband(band)

/usr/local/lib/python3.6/site-packages/PIL/ImageFile.py in load(self)
    193                 decoder = Image._getdecoder(self.mode, decoder_name,
    194                                       args, self.decoderconfig)
--> 195                 seek(offset)
    196                 try:
    197                     decoder.setimage(self.im, extents)

UnsupportedOperation: seek

In [34]:
```

while a direct import would work:
```

import requests
from PIL import Image
url ='https://raw.githubusercontent.com/bicv/SLIP/master/database/serre07_targets/B_N107001.jpg'
im = Image.open(requests.get(url, stream=True).raw)
im.show()

```

my config is:

```
Python	3.6.0 64bit [GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.42.1)]
IPython	5.1.0
OS	Darwin 16.3.0 x86_64 i386 64bit
numpy	1.12.0rc2
scipy	0.18.1
pillow	4.1.0.dev0
imageio	2.1.1dev
```

Discussion:

Patch:
diff --git a/imageio/core/request.py b/imageio/core/request.py
index 42185bb..bc07b25 100644
--- a/imageio/core/request.py
+++ b/imageio/core/request.py
@@ -326,6 +326,7 @@ class Request(object):
         elif self._uri_type in [URI_HTTP or URI_FTP]:
             assert not want_to_write  # This should have been tested in init
             self._file = urlopen(self.filename, timeout=5)
+            fix_HTTPResponse(self._file)
         
         return self._file
     
@@ -458,3 +459,35 @@ def read_n_bytes(f, N):
             break
         bb += extra_bytes
     return bb
+
+
+def fix_HTTPResponse(f):
+    """This fixes up an HTTPResponse object so that it can tell(), and also
+    seek() will work if its effectively a no-op. This allows tools like Pillow
+    to use the file object.
+    """
+    count = [0]
+    
+    def read(n=None):
+        res = ori_read(n)
+        count[0] += len(res)
+        return res
+    
+    def tell():
+        return count[0]
+    
+    def seek(i, mode=0):
+        if not (mode == 0 and i == count[0]):
+            ori_seek(i, mode)
+    
+    def fail_seek(i, mode=0):
+        raise RuntimeError('No seeking allowed!')
+    
+    # Note, there is currently no protection from wrapping an object more than
+    # once, it will (probably) work though, because closures.
+    ori_read = f.read
+    ori_seek = f.seek if hasattr(f, 'seek') else fail_seek
+    
+    f.read = read
+    f.tell = tell
+    f.seek = seek


Test patch:
diff --git a/tests/test_pillow.py b/tests/test_pillow.py
index d2e4668..5bb5931 100644
--- a/tests/test_pillow.py
+++ b/tests/test_pillow.py
@@ -147,7 +147,15 @@ def test_png():
     assert s2 < s1
     im2 = imageio.imread(fnamebase + '1.png')
     assert im2.dtype == np.uint16
-    
+
+
+def test_png_remote():
+    # issue #202
+    need_internet()
+    im = imageio.imread('https://raw.githubusercontent.com/imageio/' +
+                        'imageio-binaries/master/images/astronaut.png')
+    assert im.shape == (512, 512, 3)
+
 
 def test_jpg():