mirror of
https://github.com/imgproxy/imgproxy.git
synced 2025-09-28 20:43:54 +02:00
Fix handing 206 responses from source with full Content-Range
This commit is contained in:
@@ -4,6 +4,9 @@
|
|||||||
### Added
|
### Added
|
||||||
- Add [IMGPROXY_BASE64_URL_INCLUDES_FILENAME](https://docs.imgproxy.net/latest/configuration/options#IMGPROXY_BASE64_URL_INCLUDES_FILENAME) config.
|
- Add [IMGPROXY_BASE64_URL_INCLUDES_FILENAME](https://docs.imgproxy.net/latest/configuration/options#IMGPROXY_BASE64_URL_INCLUDES_FILENAME) config.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Treat 206 (Partial Content) responses from a source server as 200 (OK) when they contain a full content range.
|
||||||
|
|
||||||
## [3.27.2] - 2025-01-27
|
## [3.27.2] - 2025-01-27
|
||||||
### Fixed
|
### Fixed
|
||||||
- Fix preventing requests to `0.0.0.0` when imgproxy is configured to deny loopback addresses.
|
- Fix preventing requests to `0.0.0.0` when imgproxy is configured to deny loopback addresses.
|
||||||
|
@@ -7,6 +7,8 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/cookiejar"
|
"net/http/cookiejar"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -38,6 +40,8 @@ var (
|
|||||||
"Last-Modified",
|
"Last-Modified",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
contentRangeRe = regexp.MustCompile(`^bytes ((\d+)-(\d+)|\*)/(\d+|\*)$`)
|
||||||
|
|
||||||
// For tests
|
// For tests
|
||||||
redirectAllRequestsTo string
|
redirectAllRequestsTo string
|
||||||
)
|
)
|
||||||
@@ -225,8 +229,46 @@ func requestImage(ctx context.Context, imageURL string, opts DownloadOptions) (*
|
|||||||
return nil, func() {}, &ErrorNotModified{Message: "Not Modified", Headers: headersToStore(res)}
|
return nil, func() {}, &ErrorNotModified{Message: "Not Modified", Headers: headersToStore(res)}
|
||||||
}
|
}
|
||||||
|
|
||||||
if res.StatusCode != 200 {
|
// If the source responds with 206, check if the response contains entire image.
|
||||||
body, _ := io.ReadAll(res.Body)
|
// If not, return an error.
|
||||||
|
if res.StatusCode == http.StatusPartialContent {
|
||||||
|
contentRange := res.Header.Get("Content-Range")
|
||||||
|
rangeParts := contentRangeRe.FindStringSubmatch(contentRange)
|
||||||
|
if len(rangeParts) == 0 {
|
||||||
|
res.Body.Close()
|
||||||
|
reqCancel()
|
||||||
|
return nil, func() {}, ierrors.New(404, "Partial response with invalid Content-Range header", msgSourceImageIsUnreachable)
|
||||||
|
}
|
||||||
|
|
||||||
|
if rangeParts[1] == "*" || rangeParts[2] != "0" {
|
||||||
|
res.Body.Close()
|
||||||
|
reqCancel()
|
||||||
|
return nil, func() {}, ierrors.New(404, "Partial response with incomplete content", msgSourceImageIsUnreachable)
|
||||||
|
}
|
||||||
|
|
||||||
|
contentLengthStr := rangeParts[4]
|
||||||
|
if contentLengthStr == "*" {
|
||||||
|
contentLengthStr = res.Header.Get("Content-Length")
|
||||||
|
}
|
||||||
|
|
||||||
|
contentLength, _ := strconv.Atoi(contentLengthStr)
|
||||||
|
rangeEnd, _ := strconv.Atoi(rangeParts[3])
|
||||||
|
|
||||||
|
if contentLength <= 0 || rangeEnd != contentLength-1 {
|
||||||
|
res.Body.Close()
|
||||||
|
reqCancel()
|
||||||
|
return nil, func() {}, ierrors.New(404, "Partial response with incomplete content", msgSourceImageIsUnreachable)
|
||||||
|
}
|
||||||
|
} else if res.StatusCode != http.StatusOK {
|
||||||
|
var msg string
|
||||||
|
|
||||||
|
if strings.HasPrefix(res.Header.Get("Content-Type"), "text/") {
|
||||||
|
body, _ := io.ReadAll(io.LimitReader(res.Body, 1024))
|
||||||
|
msg = fmt.Sprintf("Status: %d; %s", res.StatusCode, string(body))
|
||||||
|
} else {
|
||||||
|
msg = fmt.Sprintf("Status: %d", res.StatusCode)
|
||||||
|
}
|
||||||
|
|
||||||
res.Body.Close()
|
res.Body.Close()
|
||||||
reqCancel()
|
reqCancel()
|
||||||
|
|
||||||
@@ -235,7 +277,6 @@ func requestImage(ctx context.Context, imageURL string, opts DownloadOptions) (*
|
|||||||
status = 500
|
status = 500
|
||||||
}
|
}
|
||||||
|
|
||||||
msg := fmt.Sprintf("Status: %d; %s", res.StatusCode, string(body))
|
|
||||||
return nil, func() {}, ierrors.New(status, msg, msgSourceImageIsUnreachable)
|
return nil, func() {}, ierrors.New(status, msg, msgSourceImageIsUnreachable)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user