|
|
|
@ -439,8 +439,30 @@ func (s3a *S3ApiServer) streamFromVolumeServers(w http.ResponseWriter, r *http.R |
|
|
|
rangeSpec := rangeHeader[6:] |
|
|
|
parts := strings.Split(rangeSpec, "-") |
|
|
|
if len(parts) == 2 { |
|
|
|
startOffset := int64(0) |
|
|
|
endOffset := totalSize - 1 |
|
|
|
var startOffset, endOffset int64 |
|
|
|
|
|
|
|
// Handle different Range formats:
|
|
|
|
// 1. "bytes=0-499" - first 500 bytes (parts[0]="0", parts[1]="499")
|
|
|
|
// 2. "bytes=500-" - from byte 500 to end (parts[0]="500", parts[1]="")
|
|
|
|
// 3. "bytes=-500" - last 500 bytes (parts[0]="", parts[1]="500")
|
|
|
|
|
|
|
|
if parts[0] == "" && parts[1] != "" { |
|
|
|
// Suffix range: bytes=-N (last N bytes)
|
|
|
|
if suffixLen, err := strconv.ParseInt(parts[1], 10, 64); err == nil { |
|
|
|
if suffixLen > totalSize { |
|
|
|
suffixLen = totalSize |
|
|
|
} |
|
|
|
startOffset = totalSize - suffixLen |
|
|
|
endOffset = totalSize - 1 |
|
|
|
} else { |
|
|
|
w.WriteHeader(http.StatusRequestedRangeNotSatisfiable) |
|
|
|
w.Header().Set("Content-Range", fmt.Sprintf("bytes */%d", totalSize)) |
|
|
|
return fmt.Errorf("invalid suffix range") |
|
|
|
} |
|
|
|
} else { |
|
|
|
// Regular range or open-ended range
|
|
|
|
startOffset = 0 |
|
|
|
endOffset = totalSize - 1 |
|
|
|
|
|
|
|
if parts[0] != "" { |
|
|
|
if parsed, err := strconv.ParseInt(parts[0], 10, 64); err == nil { |
|
|
|
@ -454,16 +476,23 @@ func (s3a *S3ApiServer) streamFromVolumeServers(w http.ResponseWriter, r *http.R |
|
|
|
} |
|
|
|
|
|
|
|
// Validate range
|
|
|
|
if startOffset < 0 || startOffset >= totalSize || endOffset < startOffset { |
|
|
|
if startOffset < 0 || startOffset >= totalSize { |
|
|
|
w.WriteHeader(http.StatusRequestedRangeNotSatisfiable) |
|
|
|
w.Header().Set("Content-Range", fmt.Sprintf("bytes */%d", totalSize)) |
|
|
|
return fmt.Errorf("invalid range") |
|
|
|
return fmt.Errorf("invalid range start") |
|
|
|
} |
|
|
|
|
|
|
|
if endOffset >= totalSize { |
|
|
|
endOffset = totalSize - 1 |
|
|
|
} |
|
|
|
|
|
|
|
if endOffset < startOffset { |
|
|
|
w.WriteHeader(http.StatusRequestedRangeNotSatisfiable) |
|
|
|
w.Header().Set("Content-Range", fmt.Sprintf("bytes */%d", totalSize)) |
|
|
|
return fmt.Errorf("invalid range: end before start") |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
offset = startOffset |
|
|
|
size = endOffset - startOffset + 1 |
|
|
|
isRangeRequest = true |
|
|
|
|