From bb94208cfb4e460d212ceb2e5058682f16bc9601 Mon Sep 17 00:00:00 2001 From: Bruno Silva Date: Mon, 20 Apr 2020 12:35:08 -0300 Subject: [PATCH] Fix ProxyExchange to Support bodies in delete requests (#1666) Fixes gh-825 --- .../cloud/gateway/mvc/ProxyExchange.java | 4 +- .../mvc/ProductionConfigurationTests.java | 50 +++++++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/spring-cloud-gateway-mvc/src/main/java/org/springframework/cloud/gateway/mvc/ProxyExchange.java b/spring-cloud-gateway-mvc/src/main/java/org/springframework/cloud/gateway/mvc/ProxyExchange.java index 65541bdf..b2f71704 100644 --- a/spring-cloud-gateway-mvc/src/main/java/org/springframework/cloud/gateway/mvc/ProxyExchange.java +++ b/spring-cloud-gateway-mvc/src/main/java/org/springframework/cloud/gateway/mvc/ProxyExchange.java @@ -322,8 +322,8 @@ public class ProxyExchange { } public ResponseEntity delete() { - RequestEntity requestEntity = headers( - (BodyBuilder) RequestEntity.delete(uri)).build(); + RequestEntity requestEntity = headers( + (BodyBuilder) RequestEntity.delete(uri)).body(body()); return exchange(requestEntity); } diff --git a/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/ProductionConfigurationTests.java b/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/ProductionConfigurationTests.java index d7d53fe0..669d6205 100644 --- a/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/ProductionConfigurationTests.java +++ b/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/ProductionConfigurationTests.java @@ -37,13 +37,16 @@ import org.springframework.cloud.gateway.mvc.ProductionConfigurationTests.TestAp import org.springframework.cloud.gateway.mvc.ProductionConfigurationTests.TestApplication.Bar; import org.springframework.cloud.gateway.mvc.ProductionConfigurationTests.TestApplication.Foo; import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.RequestEntity; import org.springframework.http.ResponseEntity; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.util.LinkedMultiValueMap; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; @@ -245,6 +248,27 @@ public class ProductionConfigurationTests { assertThat(foo.getName()).isEqualTo("hello"); } + @Test + public void deleteWithoutBody() throws Exception { + ResponseEntity deleteResponse = rest.exchange("/proxy/{id}/no-body", + HttpMethod.DELETE, null, Void.TYPE, + Collections.singletonMap("id", "123")); + assertThat(deleteResponse.getStatusCode()).isEqualTo(HttpStatus.OK); + } + + @Test + public void deleteWithBody() throws Exception { + Foo foo = new Foo("to-be-deleted"); + ParameterizedTypeReference> returnType = new ParameterizedTypeReference>() { + }; + ResponseEntity> deleteResponse = rest.exchange("/proxy/{id}", + HttpMethod.DELETE, new HttpEntity(foo), returnType, + Collections.singletonMap("id", "123")); + assertThat(deleteResponse.getStatusCode()).isEqualTo(HttpStatus.OK); + assertThat(deleteResponse.getBody().get("deleted")) + .isEqualToComparingFieldByField(foo); + } + @Test @SuppressWarnings({ "Duplicates", "unchecked" }) public void headers() throws Exception { @@ -386,6 +410,21 @@ public class ProductionConfigurationTests { return proxy.uri(home.toString() + "/foos").post(); } + @DeleteMapping("/proxy/{id}/no-body") + public ResponseEntity deleteWithoutBody(@PathVariable Integer id, + ProxyExchange proxy) throws Exception { + return proxy.uri(home.toString() + "/foos/" + id + "/no-body").delete(); + } + + @DeleteMapping("/proxy/{id}") + public ResponseEntity deleteWithBody(@PathVariable Integer id, + @RequestBody Foo foo, ProxyExchange proxy) throws Exception { + return proxy.uri(home.toString() + "/foos/" + id).body(foo) + .delete(response -> ResponseEntity + .status(response.getStatusCode()) + .headers(response.getHeaders()).body(response.getBody())); + } + @GetMapping("/forward/**") public void forward(ProxyExchange proxy) throws Exception { String path = proxy.path("/forward"); @@ -459,6 +498,17 @@ public class ProductionConfigurationTests { return new Foo(id == 1 ? "foo" : custom != null ? custom : "bye"); } + @DeleteMapping("/foos/{id}/no-body") + public ResponseEntity deleteFoo(@PathVariable Integer id) { + return ResponseEntity.ok().build(); + } + + @DeleteMapping("/foos/{id}") + public ResponseEntity deleteFoo(@PathVariable Integer id, + @RequestBody Foo foo) { + return ResponseEntity.ok().body(Collections.singletonMap("deleted", foo)); + } + @PostMapping("/bars") public List bars(@RequestBody List foos, @RequestHeader HttpHeaders headers) {