func zipFileOpenFast(originlReader io.ReaderAt, zf *zip.File, sizeLimit uint64) (io.ReadCloser, error) { if zf.UncompressedSize64 > sizeLimit { return zf.Open() } off, err := zf.DataOffset() if err != nil { return nil, err } buf := make([]byte, zf.CompressedSize64) _, err = originlReader.ReadAt(buf, off) if err != nil { return nil, err } buf = js.Global.Get("$github.com/oov/psdtool/js/psd$").Call("inflate", buf).Interface().([]byte) if buf == nil { return nil, errors.New("psd: error occurred in inflate") } return ioutil.NopCloser(bytes.NewReader(buf)), nil }
func serveDeflate(w http.ResponseWriter, r *http.Request, f *zip.File, readerAt io.ReaderAt) { acceptEncoding := r.Header.Get("Accept-Encoding") // TODO: need to parse the accept header to work out if the // client is explicitly forbidding deflate (ie deflate;q=0) acceptsDeflate := strings.Contains(acceptEncoding, "deflate") if !acceptsDeflate { // client will not accept deflate, so serve as identity serveIdentity(w, r, f) return } contentLength := int64(f.CompressedSize64) if contentLength == 0 { contentLength = int64(f.CompressedSize) } w.Header().Set("Content-Encoding", "deflate") w.Header().Set("Content-Length", fmt.Sprintf("%d", contentLength)) if r.Method == "HEAD" { return } var written int64 remaining := contentLength offset, err := f.DataOffset() if err != nil { internalServerError(w, r, err) return } // re-use buffers to reduce stress on GC buf := bufPool.Get() defer bufPool.Free(buf) // loop to write the raw deflated content to the client for remaining > 0 { size := len(buf) if int64(size) > remaining { size = int(remaining) } // Note that we read into a different slice than was // obtained from bufPool.Get. The reason for this is that // we want to be able to give back the original slice // so that it can be re-used. b := buf[:size] _, err := readerAt.ReadAt(b, offset) if err != nil { if written == 0 { // have not written anything to the client yet, so we can send an error internalServerError(w, r, err) } return } if _, err := w.Write(b); err != nil { // Cannot write an error to the client because, er, we just // failed to write to the client. return } written += int64(size) remaining -= int64(size) offset += int64(size) } }