aboutsummaryrefslogtreecommitdiff
path: root/weed/server
diff options
context:
space:
mode:
authorchrislu <chris.lu@gmail.com>2022-06-05 11:54:04 -0700
committerchrislu <chris.lu@gmail.com>2022-06-05 11:54:04 -0700
commitecef844dfc5bab7a28b34bbe1472d1c9585c7e41 (patch)
tree82e05a80622c184062b651b4585fd3e0094bc955 /weed/server
parent48cca4e54f0626e55dbe0f503098c23d1a950a2b (diff)
downloadseaweedfs-ecef844dfc5bab7a28b34bbe1472d1c9585c7e41.tar.xz
seaweedfs-ecef844dfc5bab7a28b34bbe1472d1c9585c7e41.zip
stream read large files
Diffstat (limited to 'weed/server')
-rw-r--r--weed/server/volume_server_handlers_read.go51
1 files changed, 48 insertions, 3 deletions
diff --git a/weed/server/volume_server_handlers_read.go b/weed/server/volume_server_handlers_read.go
index b9213a15d..eb5b2be5a 100644
--- a/weed/server/volume_server_handlers_read.go
+++ b/weed/server/volume_server_handlers_read.go
@@ -127,6 +127,7 @@ func (vs *VolumeServer) GetOrHeadHandler(w http.ResponseWriter, r *http.Request)
var count int
var needleSize types.Size
+ readOption.AttemptMetaOnly, readOption.MustMetaOnly = shouldAttemptStreamWrite(hasVolume, ext, r)
onReadSizeFn := func(size types.Size) {
needleSize = size
atomic.AddInt64(&vs.inFlightDownloadDataSize, int64(needleSize))
@@ -218,11 +219,31 @@ func (vs *VolumeServer) GetOrHeadHandler(w http.ResponseWriter, r *http.Request)
}
}
- rs := conditionallyResizeImages(bytes.NewReader(n.Data), ext, r)
+ if !readOption.IsMetaOnly {
+ rs := conditionallyResizeImages(bytes.NewReader(n.Data), ext, r)
+ if e := writeResponseContent(filename, mtype, rs, w, r); e != nil {
+ glog.V(2).Infoln("response write error:", e)
+ }
+ } else {
+ vs.streamWriteResponseContent(filename, mtype, volumeId, n, w, r, readOption)
+ }
+}
- if e := writeResponseContent(filename, mtype, rs, w, r); e != nil {
- glog.V(2).Infoln("response write error:", e)
+func shouldAttemptStreamWrite(hasLocalVolume bool, ext string, r *http.Request) (shouldAttempt bool, mustMetaOnly bool) {
+ if !hasLocalVolume {
+ return false, false
+ }
+ if len(ext) > 0 {
+ ext = strings.ToLower(ext)
+ }
+ if r.Method == "HEAD" {
+ return true, true
+ }
+ _, _, _, shouldResize := shouldResizeImages(ext, r)
+ if shouldResize {
+ return false, false
}
+ return true, false
}
func (vs *VolumeServer) tryHandleChunkedFile(n *needle.Needle, fileName string, ext string, w http.ResponseWriter, r *http.Request) (processed bool) {
@@ -318,3 +339,27 @@ func writeResponseContent(filename, mimeType string, rs io.ReadSeeker, w http.Re
})
return nil
}
+
+func (vs *VolumeServer) streamWriteResponseContent(filename string, mimeType string, volumeId needle.VolumeId, n *needle.Needle, w http.ResponseWriter, r *http.Request, readOption *storage.ReadOption) {
+ totalSize := int64(n.DataSize)
+ if mimeType == "" {
+ if ext := filepath.Ext(filename); ext != "" {
+ mimeType = mime.TypeByExtension(ext)
+ }
+ }
+ if mimeType != "" {
+ w.Header().Set("Content-Type", mimeType)
+ }
+ w.Header().Set("Accept-Ranges", "bytes")
+ adjustPassthroughHeaders(w, r, filename)
+
+ if r.Method == "HEAD" {
+ w.Header().Set("Content-Length", strconv.FormatInt(totalSize, 10))
+ return
+ }
+
+ processRangeRequest(r, w, totalSize, mimeType, func(writer io.Writer, offset int64, size int64) error {
+ return vs.store.ReadVolumeNeedleDataInto(volumeId, n, readOption, writer, offset, size)
+ })
+
+}