Gitlab Community Edition Instance

Commit 356de2d0 authored by mhellka's avatar mhellka
Browse files

Fix: Conditional requests fail for PUT on missing files

parent e73ad4c4
Pipeline #115126 passed with stages
in 8 minutes and 8 seconds
......@@ -149,10 +149,10 @@ public class FileEndpoint implements RestBlueprint {
if (fileExists) {
file = archive.getFile(fileName);
checkMatch(ctx, etag(file));
checkConditional(ctx, etag(file));
file.truncate(0);
} else {
checkMatch(ctx, "no-file"); // Not even a valid etag
checkConditional(ctx, null);
file = archive.createFile(fileName);
}
......@@ -187,15 +187,20 @@ public class FileEndpoint implements RestBlueprint {
* Throw a `412 PreconditionFailed` {@link ErrorResponse} if the given ETag does
* not pass the If-Match or If-None-Match tests (if any).
*/
private void checkMatch(RestContext ctx, String etag) throws ErrorResponse {
final String ifNoneMatch = ctx.getHeader("If-None-Match");
private void checkConditional(RestContext ctx, String etag) throws ErrorResponse {
final String ifMatch = ctx.getHeader("If-Match");
if (ifMatch != null && !ifMatch.equals("*") && !ifMatch.equals(etag))
if (ifMatch != null && !matchEtag(ifMatch, etag))
throw new ErrorResponse(412, "PreconditionFailed", "If-Match condition not satisfied.");
if (ifNoneMatch != null && (ifNoneMatch.equals("*") || ifNoneMatch.equals(etag)))
final String ifNoneMatch = ctx.getHeader("If-None-Match");
if (ifNoneMatch != null && matchEtag(ifNoneMatch, etag))
throw new ErrorResponse(412, "PreconditionFailed", "If-None-Match condition not satisfied.");
}
private boolean matchEtag(String header, String etag) {
return etag != null && (header.equals("*") || header.equals(etag));
}
/**
* Return a proper ETag header value (including quotes) for a given file.
*/
......@@ -226,7 +231,7 @@ public class FileEndpoint implements RestBlueprint {
}
// Handle DELETE of entire file
checkMatch(ctx, etag(file));
checkConditional(ctx, etag(file));
file.remove();
SessionHelper.commitOrSuspend(ctx);
......
......@@ -83,5 +83,24 @@ public class CrudFileTest extends BaseRestTest {
assertEquals(2, getJsonLong("file_count"));
}
@Test
public void testPreventOverwrite() {
final String id = makeArchive();
target("/v3/test/", id, "/test").request().header("If-None-Match", "*").put(Entity.text(""));
assertStatus(Status.CREATED);
target("/v3/test/", id, "/test").request().header("If-None-Match", "*").put(Entity.text(""));
assertError(Status.PRECONDITION_FAILED, "PreconditionFailed");
}
@Test
public void testRequireOverwrite() {
final String id = makeArchive();
target("/v3/test/", id, "/test").request().header("If-Match", "*").put(Entity.text(""));
assertError(Status.PRECONDITION_FAILED, "PreconditionFailed");
target("/v3/test/", id, "/test").request().put(Entity.text(""));
assertStatus(Status.CREATED);
target("/v3/test/", id, "/test").request().header("If-Match", "*").put(Entity.text(""));
assertStatus(Status.OK);
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment