paulcwarren/spring-content

If-Match HTTP header gets ignored by a concurrent PUT after DELETE on the content of an entity

Closed this issue · 1 comments

Describe the bug
The application uses optimistic locking with Etags.
User A wants to delete content of an entity and uses the current Etag in the If-Match HTTP header.
User B wants to update content of the same entity and uses the same Etag as user A in the If-Match HTTP header.

The request of user A gets handled before the request of user B.

This results in a 204 No Content for user A and in a 201 Created for user B.

Expected behavior
User A gets a 204 No Content and user B gets a 412 Precondition Failed.

To Reproduce

@Test
void canHandleConcurrentContentPutAfterContentDelete() throws Exception {
    mockMvc.perform(put("/invoices/{id}/content", invoiceNumber).header("If-Match", "\"0\"").contentType("text/plain").content("Hello world!"))
        .andExpect(status().is2xxSuccessful());  // Content created
    mockMvc.perform(delete("/invoices/{id}/content", invoiceNumber).header("If-Match", "\"1\""))
        .andExpect(status().is2xxSuccessful());  // User A
    mockMvc.perform(put("/invoices/{id}/content", invoiceNumber).header("If-Match", "\"1\"").contentType("text/plain").content("foo bar"))
        .andExpect(status().isPreconditionFailed());  // User B
}

Additional context
The application responds correctly when the request of user of user B gets handled before request of user A.

Thanks @NielsCW. Will take a look soonest.