diff options
| author | chrislu <chris.lu@gmail.com> | 2022-06-05 11:54:04 -0700 |
|---|---|---|
| committer | chrislu <chris.lu@gmail.com> | 2022-06-05 11:54:04 -0700 |
| commit | ecef844dfc5bab7a28b34bbe1472d1c9585c7e41 (patch) | |
| tree | 82e05a80622c184062b651b4585fd3e0094bc955 /weed/server | |
| parent | 48cca4e54f0626e55dbe0f503098c23d1a950a2b (diff) | |
| download | seaweedfs-ecef844dfc5bab7a28b34bbe1472d1c9585c7e41.tar.xz seaweedfs-ecef844dfc5bab7a28b34bbe1472d1c9585c7e41.zip | |
stream read large files
Diffstat (limited to 'weed/server')
| -rw-r--r-- | weed/server/volume_server_handlers_read.go | 51 |
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) + }) + +} |
