mirror of
https://github.com/elastic/elasticsearch.git
synced 2025-06-28 09:28:55 -04:00
Fix UploadPartCopy
source handling (#127442)
The leading `/` on the `x-amz-copy-source` header is optional; SDKv1 includes it but SDKv2 does not. Today we handle its omission when handling a `CopyObject` request but we must do the same for the `UploadPartCopy` path. Closes #127436
This commit is contained in:
parent
3057168ede
commit
9772b5e005
2 changed files with 22 additions and 12 deletions
|
@ -447,9 +447,6 @@ tests:
|
|||
- class: org.elasticsearch.xpack.esql.qa.single_node.PushQueriesIT
|
||||
method: testPushCaseInsensitiveEqualityOnDefaults
|
||||
issue: https://github.com/elastic/elasticsearch/issues/127431
|
||||
- class: org.elasticsearch.repositories.blobstore.testkit.analyze.S3RepositoryAnalysisRestIT
|
||||
method: testRepositoryAnalysis
|
||||
issue: https://github.com/elastic/elasticsearch/issues/127436
|
||||
|
||||
# Examples:
|
||||
#
|
||||
|
|
|
@ -158,9 +158,9 @@ public class S3HttpHandler implements HttpHandler {
|
|||
exchange.sendResponseHeaders(RestStatus.NOT_FOUND.getStatus(), -1);
|
||||
} else {
|
||||
// CopyPart is UploadPart with an x-amz-copy-source header
|
||||
final var sourceBlobName = exchange.getRequestHeaders().get("X-amz-copy-source");
|
||||
if (sourceBlobName != null) {
|
||||
var sourceBlob = blobs.get(sourceBlobName.getFirst());
|
||||
final var copySource = copySourceName(exchange);
|
||||
if (copySource != null) {
|
||||
var sourceBlob = blobs.get(copySource);
|
||||
if (sourceBlob == null) {
|
||||
exchange.sendResponseHeaders(RestStatus.NOT_FOUND.getStatus(), -1);
|
||||
} else {
|
||||
|
@ -230,12 +230,10 @@ public class S3HttpHandler implements HttpHandler {
|
|||
exchange.sendResponseHeaders((upload == null ? RestStatus.NOT_FOUND : RestStatus.NO_CONTENT).getStatus(), -1);
|
||||
|
||||
} else if (request.isPutObjectRequest()) {
|
||||
// a copy request is a put request with a copy source header
|
||||
final var copySources = exchange.getRequestHeaders().get("X-amz-copy-source");
|
||||
if (copySources != null) {
|
||||
final var copySource = copySources.getFirst();
|
||||
final var prefix = copySource.length() > 0 && copySource.charAt(0) == '/' ? "" : "/";
|
||||
var sourceBlob = blobs.get(prefix + copySource);
|
||||
// a copy request is a put request with an X-amz-copy-source header
|
||||
final var copySource = copySourceName(exchange);
|
||||
if (copySource != null) {
|
||||
var sourceBlob = blobs.get(copySource);
|
||||
if (sourceBlob == null) {
|
||||
exchange.sendResponseHeaders(RestStatus.NOT_FOUND.getStatus(), -1);
|
||||
} else {
|
||||
|
@ -516,6 +514,21 @@ public class S3HttpHandler implements HttpHandler {
|
|||
}
|
||||
}
|
||||
|
||||
@Nullable // if no X-amz-copy-source header present
|
||||
private static String copySourceName(final HttpExchange exchange) {
|
||||
final var copySources = exchange.getRequestHeaders().get("X-amz-copy-source");
|
||||
if (copySources != null) {
|
||||
if (copySources.size() != 1) {
|
||||
throw new AssertionError("multiple X-amz-copy-source headers found: " + copySources);
|
||||
}
|
||||
final var copySource = copySources.get(0);
|
||||
// SDKv1 uses format /bucket/path/blob whereas SDKv2 omits the leading / so we must add it back in
|
||||
return copySource.length() > 0 && copySource.charAt(0) == '/' ? copySource : ("/" + copySource);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static HttpHeaderParser.Range parsePartRange(final HttpExchange exchange) {
|
||||
final var sourceRangeHeaders = exchange.getRequestHeaders().get("X-amz-copy-source-range");
|
||||
if (sourceRangeHeaders == null) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue