File: gzipfilter.py

package info (click to toggle)
libapache2-mod-python 3.5.0%2Bgit20211031.e6458ec-1%2Bdeb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 2,016 kB
  • sloc: python: 7,467; ansic: 7,037; makefile: 295; lex: 246; sh: 171
file content (71 lines) | stat: -rw-r--r-- 1,613 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#
# Usage:
#   <Directory /where/ever>
#     PythonOutputFilter gzipfilter
#     SetOutputFilter gzipfilter
#   </Directory>

from mod_python import apache

import os
import sys
import gzip
import cStringIO
from   mod_python import apache

def compress(s):
    sio = cStringIO.StringIO()
    f = gzip.GzipFile(mode='wb',  fileobj=sio)
    f.write(s)
    f.close()
    return sio.getvalue()

def accepts_gzip(req):
    if req.headers_in.has_key('accept-encoding'):
        encodings = req.headers_in['accept-encoding']
        return (encodings.find("gzip") != -1)
    return 0

###
### main filter function
###
def outputfilter(filter):

    if (filter.req.main or
        not accepts_gzip(filter.req)):
        
        # Presense of filter.req.main tells us that
        # we are in a subrequest. We don't want to compress
        # the data more than once, so we pass_on() in
        # subrequests. We also pass_on() if the client
        # does not accept gzip encoding, of course.

        filter.pass_on()
    else:
        
        if not filter.req.sent_bodyct:

            # the above test allows us to set the encoding once
            # rather than every time the filter is invoked
            
            filter.req.headers_out['content-encoding'] = 'gzip'

        # loop through content, compressing

        s = filter.read()

        while s:
            s = compress(s)
            filter.write(s)
            s = filter.read()

        if s is None:

            # this means we received an EOS, so we pass it on
            # by closing the filter
            
            filter.close()