ServeHTTP returns the response from the orig file system, compressed if possible.
(w http.ResponseWriter, r *http.Request)
| 172 | |
| 173 | // ServeHTTP returns the response from the orig file system, compressed if possible. |
| 174 | func (c *Compressor) ServeHTTP(w http.ResponseWriter, r *http.Request) { |
| 175 | encoding := c.selectEncoder(r.Header) |
| 176 | |
| 177 | // we can only serve a cached response if all the following: |
| 178 | // 1. they requested an encoding we support |
| 179 | // 2. they are requesting the whole file, not a range |
| 180 | // 3. the method is GET |
| 181 | if encoding == "" || r.Header.Get("Range") != "" || r.Method != "GET" { |
| 182 | http.FileServer(c.orig).ServeHTTP(w, r) |
| 183 | return |
| 184 | } |
| 185 | |
| 186 | // Whether we should serve a cached response also depends in a fairly complex way on the path and request |
| 187 | // headers. In particular, we don't need a cached response for non-existing files/directories, and should not serve |
| 188 | // a cached response if the correct Etag for the file is provided. This logic is all handled by the http.FileServer, |
| 189 | // and we don't want to reimplement it here. So, what we'll do is send a HEAD request to the http.FileServer to see |
| 190 | // what it would do. |
| 191 | headReq := r.Clone(r.Context()) |
| 192 | headReq.Method = http.MethodHead |
| 193 | headRW := &compressResponseWriter{ |
| 194 | w: io.Discard, |
| 195 | headers: make(http.Header), |
| 196 | } |
| 197 | // deep-copy the headers already set on the response. This includes things like ETags. |
| 198 | for key, values := range w.Header() { |
| 199 | for _, value := range values { |
| 200 | headRW.headers.Add(key, value) |
| 201 | } |
| 202 | } |
| 203 | http.FileServer(c.orig).ServeHTTP(headRW, headReq) |
| 204 | if headRW.code != http.StatusOK { |
| 205 | // again, fall back to the file server. This is often a 404 Not Found, or a 304 Not Modified if they provided |
| 206 | // the correct ETag. |
| 207 | http.FileServer(c.orig).ServeHTTP(w, r) |
| 208 | return |
| 209 | } |
| 210 | |
| 211 | cref := c.getRef(encoding, r) |
| 212 | c.serveRef(w, r, headRW.headers, cref) |
| 213 | } |
| 214 | |
| 215 | func (c *Compressor) serveRef(w http.ResponseWriter, r *http.Request, headers http.Header, cref ref) { |
| 216 | select { |