You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2019/10/22 06:17:42 UTC

[camel] branch master updated: CAMEL-14029 default status code uses 204 when no content (#3271)

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 <Co...@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;