Skip to content

Commit f2834a1

Browse files
DaveCTurneromricohenn
authored andcommitted
Generalize S3HttpHandler request matching (elastic#125670)
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 ad61c3c commit f2834a1

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
@@ -150,7 +150,7 @@ public void handle(final HttpExchange exchange) throws IOException {
150150
exchange.sendResponseHeaders(RestStatus.OK.getStatus(), response.length);
151151
exchange.getResponseBody().write(response);
152152

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

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

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

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

321321
final StringBuilder deletes = new StringBuilder();
@@ -337,16 +337,36 @@ public void handle(final HttpExchange exchange) throws IOException {
337337
exchange.getResponseBody().write(response);
338338

339339
} else {
340+
logger.error("unknown request: {}", request);
340341
exchange.sendResponseHeaders(RestStatus.INTERNAL_SERVER_ERROR.getStatus(), -1);
341342
}
343+
} catch (Exception e) {
344+
logger.error("exception in request " + request, e);
345+
throw e;
342346
} finally {
343347
exchange.close();
344348
}
345349
}
346350

351+
private boolean isUploadPartRequest(String request) {
352+
return Regex.simpleMatch("PUT /" + path + "/*?uploadId=*&partNumber=*", request)
353+
|| Regex.simpleMatch("PUT /" + path + "/*?partNumber=*&uploadId=*", request);
354+
}
355+
347356
private boolean isListMultipartUploadsRequest(String request) {
348357
return Regex.simpleMatch("GET /" + bucket + "/?uploads&prefix=*", request)
349-
|| Regex.simpleMatch("GET /" + bucket + "/?uploads&max-uploads=*&prefix=*", request);
358+
|| Regex.simpleMatch("GET /" + bucket + "/?uploads&max-uploads=*&prefix=*", request)
359+
|| Regex.simpleMatch("GET /" + bucket + "?uploads&prefix=*", request)
360+
|| Regex.simpleMatch("GET /" + bucket + "?uploads&max-uploads=*&prefix=*", request);
361+
}
362+
363+
private boolean isListObjectsRequest(String request) {
364+
return Regex.simpleMatch("GET /" + bucket + "/?prefix=*", request)
365+
|| Regex.simpleMatch("GET /" + bucket + "?list-type=2&*prefix=*", request);
366+
}
367+
368+
private boolean isMultiObjectDeleteRequest(String request) {
369+
return request.equals("POST /" + bucket + "/?delete") || request.equals("POST /" + bucket + "?delete");
350370
}
351371

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

0 commit comments

Comments
 (0)