Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 112 lines (95 sloc) 2.252 kB
d6108f2 initial public commit
Dave Grijalva authored
1 package compression
2
3 import (
4 "bytes"
5 "compress/flate"
8eb6578 updated to weekly 2012-01-20
Dave Grijalva authored
6 "compress/gzip"
ea30c44 @gnanderson golang: update to build against tip using vanilla go tools
gnanderson authored
7 "github.com/ngmoco/falcore"
8eb6578 updated to weekly 2012-01-20
Dave Grijalva authored
8 "io"
9 "net/http"
10 "strings"
d6108f2 initial public commit
Dave Grijalva authored
11 )
12
d3982a3 @dgrijalva fixed typo in default compression types
dgrijalva authored
13 var DefaultTypes = []string{"text/plain", "text/html", "application/json", "text/xml"}
d6108f2 initial public commit
Dave Grijalva authored
14
15 type Filter struct {
16 types []string
17 }
18
19 func NewFilter(types []string) *Filter {
20 f := new(Filter)
21 if types != nil {
22 f.types = types
23 } else {
24 f.types = DefaultTypes
25 }
26 return f
27 }
28
29 func (c *Filter) FilterResponse(request *falcore.Request, res *http.Response) {
30 req := request.HttpRequest
31 if accept := req.Header.Get("Accept-Encoding"); accept != "" {
32
33 // Is content an acceptable type for encoding?
34 var compress = false
35 var content_type = res.Header.Get("Content-Type")
36 for _, t := range c.types {
37 if content_type == t {
38 compress = true
39 break
40 }
41 }
42
43 // Is the content already compressed
44 if res.Header.Get("Content-Encoding") != "" {
45 compress = false
46 }
47
48 if !compress {
49 request.CurrentStage.Status = 1 // Skip
50 return
51 }
52
53 // Figure out which encoding to use
54 options := strings.Split(accept, ",")
55 var mode string
56 for _, opt := range options {
57 if m := strings.TrimSpace(opt); m == "gzip" || m == "deflate" {
58 mode = m
59 break
60 }
61 }
62
63 var compressor io.WriteCloser
64 var buf = bytes.NewBuffer(make([]byte, 0, 1024))
65 switch mode {
66 case "gzip":
86ffa90 @gnanderson compression/compression.go fix invalid return arg
gnanderson authored
67 compressor = gzip.NewWriter(buf)
d6108f2 initial public commit
Dave Grijalva authored
68 case "deflate":
10d4ff8 @gnanderson compression: update import for go build/install, handle deflate error
gnanderson authored
69 comp, err := flate.NewWriter(buf, -1)
70 if err != nil {
71 falcore.Error("Compression Error: %v", err)
72 request.CurrentStage.Status = 1 // Skip
73 return
74 }
75 compressor = comp
d6108f2 initial public commit
Dave Grijalva authored
76 default:
77 request.CurrentStage.Status = 1 // Skip
78 return
79 }
80
81 // Perform compression
82 r := make([]byte, 1024)
8eb6578 updated to weekly 2012-01-20
Dave Grijalva authored
83 var err error
d6108f2 initial public commit
Dave Grijalva authored
84 var i int
85 for err == nil {
86 i, err = res.Body.Read(r)
87 compressor.Write(r[0:i])
88 }
89 compressor.Close()
90 res.Body.Close()
91
92 res.ContentLength = int64(buf.Len())
93 res.Body = (*filteredBody)(buf)
94 res.Header.Set("Content-Encoding", mode)
95 } else {
96 request.CurrentStage.Status = 1 // Skip
97 }
98 }
99
100 // wrapper type for Response struct
101
102 type filteredBody bytes.Buffer
103
8eb6578 updated to weekly 2012-01-20
Dave Grijalva authored
104 func (b *filteredBody) Read(byt []byte) (int, error) {
d6108f2 initial public commit
Dave Grijalva authored
105 i, err := (*bytes.Buffer)(b).Read(byt)
106 return i, err
107 }
108
8eb6578 updated to weekly 2012-01-20
Dave Grijalva authored
109 func (b filteredBody) Close() error {
d6108f2 initial public commit
Dave Grijalva authored
110 return nil
111 }
Something went wrong with that request. Please try again.