Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I serve image Content-types with Python BaseHTTPServerRequestHandler do_GET method?

I'm using BaseHTTPServer to serve web content. I can serve Content-types 'text/html' or 'text/css' or even 'text/js' and it renders on the browser side. But when I try to

self.send_header('Content-type', 'image/png')

for a .png file, it doesn't render at all.

Here is a sample:

                    if self.path.endswith(".js"):
                            f = open(curdir + sep + self.path)
                            self.send_response(200)
                            self.send_header('Content-type',        'text/javascript')
                            self.end_headers()
                            self.wfile.write(f.read())
                            f.close()
                            return

this works great for javascript

                    if self.path.endswith(".png"):
                            f=open(curdir + sep + self.path)
                            self.send_response(200)
                            self.send_header('Content-type',        'image/png')
                            self.end_headers()
                            self.wfile.write(f.read())
                            f.close()
                            return

this doesn't seem to render the image content when I mark it up for client side. It appears as a broken image.

Any ideas?

like image 979
Brandon Runyon Avatar asked Mar 13 '11 03:03

Brandon Runyon


3 Answers

You've opened the file in text mode instead of binary mode. Any newline characters are likely to get messed up. Use this instead:

f = open(curdir + sep + self.path, 'rb')
like image 160
Liquid_Fire Avatar answered Sep 18 '22 16:09

Liquid_Fire


Try to use SimpleHTTPServer

class MyHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
    """modify Content-type """
    def guess_type(self, path):
        mimetype = SimpleHTTPServer.SimpleHTTPRequestHandler.guess_type(
            self, path
            )
        if mimetype == 'application/octet-stream':
            if path.endswith('manifest'):
                mimetype = 'text/cache-manifest'
        return mimetype

see /usr/lib/python2.7/SimpleHTTPServer.py for more infomation.

like image 21
alswl Avatar answered Sep 18 '22 16:09

alswl


you can always open the file as binary ;-)

Maybe you could look at SimpleHTTPServer.py at this part of the code:

    ctype = self.guess_type(path)
    try:
        # Always read in binary mode. Opening files in text mode may cause
        # newline translations, making the actual size of the content
        # transmitted *less* than the content-length!
        f = open(path, 'rb')
    except IOError:
        self.send_error(404, "File not found")
        return None

Then if you look at def guess_type(self, path): its very simple, it use the file "extension" ;-)


    Return value is a string of the form type/subtype,
    usable for a MIME Content-type header.

    The default implementation looks the file's extension
    up in the table self.extensions_map, using application/octet-stream
    as a default; however it would be permissible (if
    slow) to look inside the data to make a better guess.

Just in case, the code is:


    base, ext = posixpath.splitext(path)
    if ext in self.extensions_map:
        return self.extensions_map[ext]
    ext = ext.lower()
    if ext in self.extensions_map:
        return self.extensions_map[ext]
    else:
        return self.extensions_map['']

like image 33
demontux Avatar answered Sep 20 '22 16:09

demontux