This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/master by this push: new d86e4e7 CAMEL-14029 default status code uses 204 when no content (#3271) d86e4e7 is described below commit d86e4e7af5361f30141c711eb7114dd85add38c9 Author: Mike Barlotta <codesm...@users.noreply.github.com> AuthorDate: Tue Oct 22 02:17:30 2019 -0400 CAMEL-14029 default status code uses 204 when no content (#3271) --- .../camel/http/common/DefaultHttpBinding.java | 34 ++++- .../jetty/JettySwitchingStatusCode204Test.java | 144 +++++++++++++++++++++ .../undertow/DefaultUndertowHttpBinding.java | 1 - 3 files changed, 172 insertions(+), 7 deletions(-) diff --git a/components/camel-http-common/src/main/java/org/apache/camel/http/common/DefaultHttpBinding.java b/components/camel-http-common/src/main/java/org/apache/camel/http/common/DefaultHttpBinding.java index 5bdcc36..7eb8e2d 100644 --- a/components/camel-http-common/src/main/java/org/apache/camel/http/common/DefaultHttpBinding.java +++ b/components/camel-http-common/src/main/java/org/apache/camel/http/common/DefaultHttpBinding.java @@ -386,17 +386,15 @@ public class DefaultHttpBinding implements HttpBinding { @Override public void doWriteFaultResponse(Message message, HttpServletResponse response, Exchange exchange) throws IOException { - message.setHeader(Exchange.HTTP_RESPONSE_CODE, HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + //message.setHeader(Exchange.HTTP_RESPONSE_CODE, HttpServletResponse.SC_INTERNAL_SERVER_ERROR); doWriteResponse(message, response, exchange); } @Override public void doWriteResponse(Message message, HttpServletResponse response, Exchange exchange) throws IOException { - // set the status code in the response. Default is 200. - if (message.getHeader(Exchange.HTTP_RESPONSE_CODE) != null) { - int code = message.getHeader(Exchange.HTTP_RESPONSE_CODE, Integer.class); - response.setStatus(code); - } + int statusCode = determineResponseCode(exchange, exchange.getMessage().getBody()); + response.setStatus(statusCode); + // set the content type in the response. String contentType = MessageHelper.getContentType(message); if (contentType != null) { @@ -429,6 +427,30 @@ public class DefaultHttpBinding implements HttpBinding { } } + /* + * set the HTTP status code + * NOTE: this is similar to the Netty-Http and Undertow approach + * TODO: we may want to refactor this class so that + * the status code is determined in one place + */ + private int determineResponseCode(Exchange camelExchange, Object body) { + boolean failed = camelExchange.isFailed(); + int defaultCode = failed ? 500 : 200; + + Message message = camelExchange.getMessage(); + Integer currentCode = message.getHeader(Exchange.HTTP_RESPONSE_CODE, Integer.class); + int codeToUse = currentCode == null ? defaultCode : currentCode; + + if (codeToUse != 500) { + if ((body == null) || (body instanceof String && ((String) body).trim().isEmpty())) { + // no content + codeToUse = currentCode == null ? 204 : currentCode; + } + } + + return codeToUse; + } + protected String convertHeaderValueToString(Exchange exchange, Object headerValue) { if ((headerValue instanceof Date || headerValue instanceof Locale) && convertDateAndLocaleLocally(exchange)) { diff --git a/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettySwitchingStatusCode204Test.java b/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettySwitchingStatusCode204Test.java new file mode 100644 index 0000000..a3543c3 --- /dev/null +++ b/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettySwitchingStatusCode204Test.java @@ -0,0 +1,144 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.jetty; + +import org.apache.camel.Exchange; +import org.apache.camel.builder.RouteBuilder; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.util.EntityUtils; +import org.junit.Test; + +public class JettySwitchingStatusCode204Test extends BaseJettyTest { + + @Test + public void testSwitchNoBodyTo204ViaHttp() throws Exception { + HttpUriRequest request = new HttpGet("http://localhost:" + getPort() + "/bar"); + HttpClient httpClient = HttpClientBuilder.create().build(); + HttpResponse httpResponse = httpClient.execute(request); + + assertEquals(204, httpResponse.getStatusLine().getStatusCode()); + assertNull(httpResponse.getEntity()); + } + + @Test + public void testSwitchingNoBodyTo204HttpViaCamel() throws Exception { + Exchange inExchange = this.createExchangeWithBody("Hello World"); + Exchange outExchange = template.send("http://localhost:{{port}}/bar", inExchange); + + assertEquals(204, outExchange.getMessage().getHeader(Exchange.HTTP_RESPONSE_CODE)); + assertEquals(null, outExchange.getMessage().getBody(String.class)); + } + + @Test + public void testSwitchingNoBodyTo204ViaCamelRoute() throws Exception { + Exchange inExchange = this.createExchangeWithBody("Hello World"); + Exchange outExchange = template.send("direct:bar", inExchange); + + assertEquals(204, outExchange.getMessage().getHeader(Exchange.HTTP_RESPONSE_CODE)); + assertEquals(null, outExchange.getMessage().getBody(String.class)); + } + + @Test + public void testNoSwitchingNoCodeViaHttp() throws Exception { + HttpUriRequest request = new HttpGet("http://localhost:" + getPort() + "/foo"); + HttpClient httpClient = HttpClientBuilder.create().build(); + HttpResponse httpResponse = httpClient.execute(request); + + assertEquals(200, httpResponse.getStatusLine().getStatusCode()); + assertNotNull(httpResponse.getEntity()); + assertEquals("No Content", EntityUtils.toString(httpResponse.getEntity())); + } + + @Test + public void testNoSwitchingNoCodeHttpViaCamel() throws Exception { + Exchange inExchange = this.createExchangeWithBody("Hello World"); + Exchange outExchange = template.send("http://localhost:{{port}}/foo", inExchange); + + assertEquals(200, outExchange.getMessage().getHeader(Exchange.HTTP_RESPONSE_CODE)); + assertEquals("No Content", outExchange.getMessage().getBody(String.class)); + } + + @Test + public void testNoSwitchingNoCodeViaCamelRoute() throws Exception { + Exchange inExchange = this.createExchangeWithBody("Hello World"); + Exchange outExchange = template.send("direct:foo", inExchange); + + assertEquals(200, outExchange.getMessage().getHeader(Exchange.HTTP_RESPONSE_CODE)); + assertEquals("No Content", outExchange.getMessage().getBody(String.class)); + } + + @Test + public void testNoSwitchingNoBodyViaHttp() throws Exception { + HttpUriRequest request = new HttpGet("http://localhost:" + getPort() + "/foobar"); + HttpClient httpClient = HttpClientBuilder.create().build(); + HttpResponse httpResponse = httpClient.execute(request); + + assertEquals(200, httpResponse.getStatusLine().getStatusCode()); + assertNotNull(httpResponse.getEntity()); + assertEquals("", EntityUtils.toString(httpResponse.getEntity())); + } + + @Test + public void testNoSwitchingNoBodyHttpViaCamel() throws Exception { + Exchange inExchange = this.createExchangeWithBody("Hello World"); + Exchange outExchange = template.send("http://localhost:{{port}}/foobar", inExchange); + + assertEquals(200, outExchange.getMessage().getHeader(Exchange.HTTP_RESPONSE_CODE)); + assertEquals("", outExchange.getMessage().getBody(String.class)); + } + + @Test + public void testNoSwitchingNoBodyViaCamelRoute() throws Exception { + Exchange inExchange = this.createExchangeWithBody("Hello World"); + Exchange outExchange = template.send("direct:foobar", inExchange); + + assertEquals(200, outExchange.getMessage().getHeader(Exchange.HTTP_RESPONSE_CODE)); + assertEquals("", outExchange.getMessage().getBody(String.class)); + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + from("jetty:http://localhost:{{port}}/bar") + .setBody().constant(""); + + from("direct:bar") + .to("http://localhost:{{port}}/bar"); + + from("jetty:http://localhost:{{port}}/foo") + .setBody().constant("No Content"); + + from("direct:foo") + .to("http://localhost:{{port}}/foo"); + + from("jetty:http://localhost:{{port}}/foobar") + .setHeader(Exchange.HTTP_RESPONSE_CODE, constant(200)) + .setBody().constant(""); + + from("direct:foobar") + .to("http://localhost:{{port}}/foobar"); + + } + }; + } +} \ No newline at end of file diff --git a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/DefaultUndertowHttpBinding.java b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/DefaultUndertowHttpBinding.java index 328a80c..2d91f74 100644 --- a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/DefaultUndertowHttpBinding.java +++ b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/DefaultUndertowHttpBinding.java @@ -42,7 +42,6 @@ import io.undertow.util.HeaderMap; import io.undertow.util.Headers; import io.undertow.util.HttpString; import io.undertow.util.Methods; -import io.undertow.util.StatusCodes; import org.apache.camel.Exchange; import org.apache.camel.Message;