Skip to content

Commit 30b7f1b

Browse files
authored
Generalize S3HttpHandler request matching (#125670) (#125729)
The pattern-matching in `S3HttpHandler` is overly specific and carefully crafted to handle the exact requests that the AWS SDK v1 makes. It turns out that the AWS SDK v2 makes requests that are slightly different. This commit generalizes the pattern-matching to handle both SDKs.
1 parent ac96656 commit 30b7f1b

File tree

1 file changed

+24
-4
lines changed

1 file changed

+24
-4
lines changed

test/fixtures/s3-fixture/src/main/java/fixture/s3/S3HttpHandler.java

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ public void handle(final HttpExchange exchange) throws IOException {
149149
exchange.sendResponseHeaders(RestStatus.OK.getStatus(), response.length);
150150
exchange.getResponseBody().write(response);
151151

152-
} else if (Regex.simpleMatch("PUT /" + path + "/*?uploadId=*&partNumber=*", request)) {
152+
} else if (isUploadPartRequest(request)) {
153153
final Map<String, String> params = new HashMap<>();
154154
RestUtils.decodeQueryString(request, request.indexOf('?') + 1, params);
155155

@@ -212,7 +212,7 @@ public void handle(final HttpExchange exchange) throws IOException {
212212
exchange.getResponseHeaders().add("ETag", blob.v1());
213213
exchange.sendResponseHeaders(RestStatus.OK.getStatus(), -1);
214214

215-
} else if (Regex.simpleMatch("GET /" + bucket + "/?prefix=*", request)) {
215+
} else if (isListObjectsRequest(request)) {
216216
final Map<String, String> params = new HashMap<>();
217217
RestUtils.decodeQueryString(request, request.indexOf('?') + 1, params);
218218
if (params.get("list-type") != null) {
@@ -319,7 +319,7 @@ public void handle(final HttpExchange exchange) throws IOException {
319319
}
320320
exchange.sendResponseHeaders((deletions > 0 ? RestStatus.OK : RestStatus.NO_CONTENT).getStatus(), -1);
321321

322-
} else if (Regex.simpleMatch("POST /" + bucket + "/?delete", request)) {
322+
} else if (isMultiObjectDeleteRequest(request)) {
323323
final String requestBody = Streams.copyToString(new InputStreamReader(exchange.getRequestBody(), UTF_8));
324324

325325
final StringBuilder deletes = new StringBuilder();
@@ -341,16 +341,36 @@ public void handle(final HttpExchange exchange) throws IOException {
341341
exchange.getResponseBody().write(response);
342342

343343
} else {
344+
logger.error("unknown request: {}", request);
344345
exchange.sendResponseHeaders(RestStatus.INTERNAL_SERVER_ERROR.getStatus(), -1);
345346
}
347+
} catch (Exception e) {
348+
logger.error("exception in request " + request, e);
349+
throw e;
346350
} finally {
347351
exchange.close();
348352
}
349353
}
350354

355+
private boolean isUploadPartRequest(String request) {
356+
return Regex.simpleMatch("PUT /" + path + "/*?uploadId=*&partNumber=*", request)
357+
|| Regex.simpleMatch("PUT /" + path + "/*?partNumber=*&uploadId=*", request);
358+
}
359+
351360
private boolean isListMultipartUploadsRequest(String request) {
352361
return Regex.simpleMatch("GET /" + bucket + "/?uploads&prefix=*", request)
353-
|| Regex.simpleMatch("GET /" + bucket + "/?uploads&max-uploads=*&prefix=*", request);
362+
|| Regex.simpleMatch("GET /" + bucket + "/?uploads&max-uploads=*&prefix=*", request)
363+
|| Regex.simpleMatch("GET /" + bucket + "?uploads&prefix=*", request)
364+
|| Regex.simpleMatch("GET /" + bucket + "?uploads&max-uploads=*&prefix=*", request);
365+
}
366+
367+
private boolean isListObjectsRequest(String request) {
368+
return Regex.simpleMatch("GET /" + bucket + "/?prefix=*", request)
369+
|| Regex.simpleMatch("GET /" + bucket + "?list-type=2&*prefix=*", request);
370+
}
371+
372+
private boolean isMultiObjectDeleteRequest(String request) {
373+
return request.equals("POST /" + bucket + "/?delete") || request.equals("POST /" + bucket + "?delete");
354374
}
355375

356376
public Map<String, BytesReference> blobs() {

0 commit comments

Comments
 (0)