How to use Content-Encoding: gzip with Python SimpleHTTPServer
Asked Answered
H

6

15

I'm using python -m SimpleHTTPServer to serve up a directory for local testing in a web browser. Some of the content includes large data files. I would like to be able to gzip them and have SimpleHTTPServer serve them with Content-Encoding: gzip.

Is there an easy way to do this?

Harvester answered 8/3, 2012 at 18:41 Comment(0)
M
16

This is an old question, but it still ranks #1 in Google for me, so I suppose a proper answer might be of use to someone beside me.

The solution turns out to be very simple. in the do_GET(), do_POST, etc, you only need to add the following:

content = self.gzipencode(strcontent)
...your other headers, etc...
self.send_header("Content-length", str(len(str(content))))
self.send_header("Content-Encoding", "gzip")
self.end_headers()
self.wfile.write(content)
self.wfile.flush()

strcontent being your actual content (as in HTML, javascript or other HTML resources) and the gzipencode:

def gzipencode(self, content):
    import StringIO
    import gzip
    out = StringIO.StringIO()
    f = gzip.GzipFile(fileobj=out, mode='w', compresslevel=5)
    f.write(content)
    f.close()
    return out.getvalue()
Mellen answered 12/6, 2013 at 11:13 Comment(1)
Of course, the above were straight copy-pastes of that code. But then again, the above snippets say it all and the complete functioning code also serves as a JSON bridge which would kinda blur the purpouse of this question. Anyway, drop me a mail if you need more info or the code.Mellen
C
9

Since this was the top google result I figured I would post my simple modification to the script that got gzip to work.

https://github.com/ksmith97/GzipSimpleHTTPServer

Convene answered 9/2, 2014 at 4:37 Comment(0)
A
5

As so many others, I've been using python -m SimpleHTTPServer for local testing as well. This is still the top result on google and while https://github.com/ksmith97/GzipSimpleHTTPServer is a nice solution, it enforces gzip even if not requested and there's no flag to enable/disable it.

I decided to write a tiny cli tool that supports this. It's go, so the regular install procedure is simply:

go get github.com/rhardih/serve

If you already have $GOPATH added to $PATH, that's all you need. Now you have serve as a command.

https://github.com/rhardih/serve

Arachne answered 27/4, 2016 at 18:37 Comment(0)
L
3

This was a feature request but rejected due to wanting to keep the simple http server simple: https://bugs.python.org/issue30576

The issue author eventually released a standalone version for Python 3: https://github.com/PierreQuentel/httpcompressionserver

Latoya answered 19/6, 2021 at 5:13 Comment(2)
Just a heads up for others. httpcompressionserver did not automatically bind the address the same way as "http.server". For me it crashed. I had to start it with: python3 -m httpcompressionserver --bind 0.0.0.0 See: github.com/PierreQuentel/httpcompressionserver/issues/2Neurogenic
That should've been fixed on pypi. Contact the author if it hasn't.Latoya
M
2

Building on @velis answer above, here is how I do it. gZipping small data is not worth the time and can increase its size. Tested with Dalvik client.

def do_GET(self):
    ... get content
    self.send_response(returnCode)       # 200, 401, etc
    ...your other headers, etc...
    if len(content) > 100:                       # don't bother compressing small data
        if 'accept-encoding' in self.headers:    # case insensitive
            if 'gzip' in self.headers['accept-encoding']:
                content = gzipencode(content)    # gzipencode defined above in @velis answer
                self.send_header('content-encoding', 'gzip')
    self.send_header('content-length', len(content))
    self.end_headers()          # send a blank line
    self.wfile.write(content)
Mestas answered 19/9, 2014 at 21:21 Comment(0)
I
-1

From looking at SimpleHTTPServer's documentation, there is no way. However, I recommend lighttpd with the mod_compress module.

Infant answered 25/4, 2012 at 1:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.