Beispiel #1
0
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
}
Beispiel #2
0
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)
	}
}