gallery.py: Use HTTPError.content (not .message) for custom responses
authorW. Trevor King <wking@tremily.us>
Mon, 9 Dec 2013 05:02:28 +0000 (21:02 -0800)
committerW. Trevor King <wking@tremily.us>
Mon, 9 Dec 2013 05:07:04 +0000 (21:07 -0800)
.message should only hold the standard reason phrase from RFC 2616
[1].

[1]: http://tools.ietf.org/html/rfc2616#section-6.1

posts/gallery/gallery.py

index b97835ca52f4df32e4cfcd8339462bfbef91e26d..c938c8a5775b29ba6f78b93763754ca9e4002358 100755 (executable)
@@ -66,7 +66,9 @@ VIDEO_EXTENSIONS = ['.mov', '.mp4', '.ogv']
 STREAMING_TYPES = ['video/ogg']
 RESPONSES = {  # httplib takes half a second to load
     200: 'OK',
+    400: 'Bad Request',
     404: 'Not Found',
+    500: 'Internal Server Error',
     }
 
 LOG = _logging.getLogger('gallery.py')
@@ -93,6 +95,8 @@ class HTTPError(Exception):
     def __init__(self, status, message=None, content=None):
         if message is None:
             message = RESPONSES[status]
+        if content is None:
+            content = message
         super(HTTPError, self).__init__('{} {}'.format(status, message))
         self.status = status
         self.message = message
@@ -218,7 +222,7 @@ class CGIGalleryServer (object):
                     raise HTTPError(404)
             else:
                 if not _os_path.isfile(path):
-                    raise HTTPError(404, 'nonexistent file')
+                    raise HTTPError(404, content='nonexistent file')
 
     def serve(self, url=None, page=0, stream=None):
         LOG.info('serving url {} (page {})'.format(url, page))
@@ -235,7 +239,7 @@ class CGIGalleryServer (object):
                 else:
                     self.validate_url(url=url, exists=False, directory=True)
                     self.page(url=url, page=page, stream=stream)
-                raise HTTPError(404, 'unexpected URL type')
+                raise HTTPError(404, content='unexpected URL type')
             except HTTPError as e:
                 LOG.error(e.message)
                 self._error(e.status, content=e.content, stream=stream)
@@ -265,9 +269,9 @@ class CGIGalleryServer (object):
         if url is None:
             return url
         if not url.startswith(self._base_url):
-            message = 'cannot convert {} to a relative URL of {}'.format(
+            content = 'cannot convert {} to a relative URL of {}'.format(
                 url, self._base_url)
-            raise HTTPError(404, message)
+            raise HTTPError(404, content=content)
         if url == self._base_url:
             return None
         return url[len(self._base_url):]
@@ -331,12 +335,14 @@ class CGIGalleryServer (object):
             try:
                 root,width,height = base.rsplit('-', 2)
             except ValueError:
-                raise HTTPError(404, 'missing width/height in {}'.format(base))
+                raise HTTPError(
+                    400, content='missing width/height in {}'.format(base))
             try:
                 width = int(width)
                 height = int(height)
             except ValueError as e:
-                raise HTTPError(404, 'invalid width/height: {}'.format(e))
+                raise HTTPError(
+                    400, content='invalid width/height: {}'.format(e))
             return (
                 root + '.jpg',
                 self._thumb, 
@@ -349,7 +355,7 @@ class CGIGalleryServer (object):
                 getattr(self, '_{}'.format(extension), None),
                 {},
                 )
-        raise HTTPError(404, 'no original URL for {}'.format(url))
+        raise HTTPError(400, content='no original URL for {}'.format(url))
 
     def _thumb(self, image, max_width=None, max_height=None):
         if not _os_path.exists(self._cache_path):
@@ -365,7 +371,8 @@ class CGIGalleryServer (object):
         thumb_path = _os_path.join(cache_dir, thumb_filename)
         image_path = _os_path.join(self._base_path, image)
         if not _os_path.isfile(image_path):
-            raise HTTPError(404, 'image path for thumbnail does not exist')
+            raise HTTPError(
+                404, content='image path for thumbnail does not exist')
         if (not _os_path.isfile(thumb_path)
             or _os_path.getmtime(image_path) > _os_path.getmtime(thumb_path)):
             invoke(['convert', '-format', 'png', '-strip', '-quality', '95',
@@ -376,7 +383,8 @@ class CGIGalleryServer (object):
 
     def _mp4(self, video, *args):
         if not video.endswith('.mov'):
-            raise HTTPError(404, "can't translate {} to MPEGv4".format(video))
+            raise HTTPError(
+                500, content="can't translate {} to MPEGv4".format(video))
         dirname,filename = _os_path.split(video)
         mp4_filename = image_base(filename) + '.mp4'
         reldir = _os_path.relpath(dirname, self._base_path)
@@ -386,7 +394,7 @@ class CGIGalleryServer (object):
         mp4_url = _os_path.join(dirname, mp4_filename)
         mp4_path = _os_path.join(cache_dir, mp4_filename)
         if not _os_path.isfile(video):
-            raise HTTPError(404, 'source video path does not exist')
+            raise HTTPError(404, content='source video path does not exist')
         if (not _os_path.isfile(mp4_path)
             or _os_path.getmtime(video) > _os_path.getmtime(mp4_path)):
             arg = ['ffmpeg', '-i', video, '-acodec', 'libfaac', '-aq', '200',
@@ -533,7 +541,8 @@ class CGIGalleryServer (object):
         LOG.debug('retrieving possibly cached item')
         mime = _mimetypes.guess_type(url)[0]
         if mime is None:
-            raise HTTPError(404, 'unknown mime type for {}'.format(url))
+            raise HTTPError(
+                500, content='unknown mime type for {}'.format(url))
         cache_path = _os_path.join(self._cache_path, url)
         original_path = _os_path.join(self._base_path, url)
         path = None
@@ -555,8 +564,8 @@ class CGIGalleryServer (object):
             content = open(path, 'rb')
         except IOError as e:
             LOG.error(e)
-            raise HTTPError(404, 'item not found {}'.format(url))
-        header = self._http_header(mime=mime)
+            raise HTTPError(404, content='item not found {}'.format(url))
+        headers = self._http_headers(mime=mime)
         if mime in STREAMING_TYPES:
             self._response_stream(
                 header=header, content=content, stream=stream)
@@ -566,7 +575,8 @@ class CGIGalleryServer (object):
     def page(self, url, page=0, stream=None):
         LOG.debug('HTML page {} {}'.format(url, page))
         if not url.endswith('/'):
-            raise HTTPError(404, 'HTML page URLs must end with a slash')
+            raise HTTPError(
+                404, content='HTML page URLs must end with a slash')
         abspath = _os_path.join(self._base_path, url)
         if _os_path.isdir(abspath):
             self._directory(path=abspath, page=page, stream=stream)
@@ -574,7 +584,7 @@ class CGIGalleryServer (object):
             file_path = abspath[:-1] + extension
             if _os_path.isfile(file_path):
                 self._page(path=file_path, stream=stream)
-        raise HTTPError(404, 'unknown HTML page {}'.format(url))
+        raise HTTPError(404, content='unknown HTML page {}'.format(url))
 
     def _directory_header(self, path):
         relpath = _os_path.relpath(path, self._base_path)
@@ -659,8 +669,9 @@ class CGIGalleryServer (object):
         if page < 0 or page >= pages:
             raise HTTPError(
                 404,
-                'page out of bounds for this gallery 0 <= {:d} < {:d}'.format(
-                    page, pages))
+                content=(
+                    'page out of bounds for this gallery 0 <= {:d} < {:d}'
+                    ).format(page, pages))
         first_image = images_per_page * page
         images = images[first_image:first_image+images_per_page]
         content = []
@@ -732,7 +743,7 @@ def serve_scgi(server, host='localhost', port=4000):
                 try:
                     url = server.relative_url(url=url)
                 except HTTPError as e:
-                    LOG.error(e.message)
+                    LOG.error(e.content)
                     server._error(e.status, content=e.content, stream=output)
             except ProcessingComplete:
                 pass