You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2017/08/09 18:15:14 UTC
[05/10] httpcomponents-core git commit: Request filters for classic
and asynchronous server side protocol handlers
Request filters for classic and asynchronous server side protocol handlers
Project: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/repo
Commit: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/commit/52b0d269
Tree: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/tree/52b0d269
Diff: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/diff/52b0d269
Branch: refs/heads/master
Commit: 52b0d2695dc0c4259bc1ab1a6fc709312d8d63e1
Parents: ee32600
Author: Oleg Kalnichevski <ol...@apache.org>
Authored: Tue Aug 1 18:55:34 2017 +0200
Committer: Oleg Kalnichevski <ol...@apache.org>
Committed: Wed Aug 9 15:00:27 2017 +0200
----------------------------------------------------------------------
.../hc/core5/testing/nio/EchoHandler.java | 7 -
.../hc/core5/http/io/HttpFilterChain.java | 57 +++++++
.../hc/core5/http/io/HttpFilterHandler.java | 49 ++++++
.../io/support/HttpServerExpectationFilter.java | 82 +++++++++
.../support/HttpServerFilterChainElement.java | 74 +++++++++
.../HttpServerFilterChainRequestHandler.java | 72 ++++++++
.../http/io/support/TerminalServerFilter.java | 75 +++++++++
.../hc/core5/http/nio/AsyncFilterChain.java | 61 +++++++
.../hc/core5/http/nio/AsyncFilterHandler.java | 51 ++++++
.../support/AsyncServerExpectationFilter.java | 85 ++++++++++
.../support/AsyncServerFilterChainElement.java | 79 +++++++++
...ServerFilterChainExchangeHandlerFactory.java | 165 +++++++++++++++++++
.../nio/support/TerminalAsyncServerFilter.java | 146 ++++++++++++++++
13 files changed, 996 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/52b0d269/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/EchoHandler.java
----------------------------------------------------------------------
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/EchoHandler.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/EchoHandler.java
index f7962cc..100c982 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/EchoHandler.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/EchoHandler.java
@@ -33,7 +33,6 @@ import java.util.List;
import org.apache.hc.core5.http.EntityDetails;
import org.apache.hc.core5.http.Header;
import org.apache.hc.core5.http.HttpException;
-import org.apache.hc.core5.http.HttpHeaders;
import org.apache.hc.core5.http.HttpRequest;
import org.apache.hc.core5.http.HttpResponse;
import org.apache.hc.core5.http.HttpStatus;
@@ -70,12 +69,6 @@ public class EchoHandler implements AsyncServerExchangeHandler {
final EntityDetails entityDetails,
final ResponseChannel responseChannel,
final HttpContext context) throws HttpException, IOException {
- if (entityDetails != null) {
- final Header h = request.getFirstHeader(HttpHeaders.EXPECT);
- if (h != null && "100-continue".equalsIgnoreCase(h.getValue())) {
- responseChannel.sendInformation(new BasicHttpResponse(HttpStatus.SC_CONTINUE));
- }
- }
final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_OK);
responseChannel.sendResponse(response, entityDetails);
}
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/52b0d269/httpcore5/src/main/java/org/apache/hc/core5/http/io/HttpFilterChain.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/io/HttpFilterChain.java b/httpcore5/src/main/java/org/apache/hc/core5/http/io/HttpFilterChain.java
new file mode 100644
index 0000000..f863307
--- /dev/null
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/io/HttpFilterChain.java
@@ -0,0 +1,57 @@
+/*
+ * ====================================================================
+ * 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.core5.http.io;
+
+import java.io.IOException;
+
+import org.apache.hc.core5.annotation.Contract;
+import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.http.ClassicHttpRequest;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.protocol.HttpContext;
+
+/**
+ * @since 5.0
+ */
+@Contract(threading = ThreadingBehavior.STATELESS)
+public interface HttpFilterChain {
+
+ interface ResponseTrigger {
+
+ void sendInformation(ClassicHttpResponse response) throws HttpException, IOException;
+
+ void submitResponse(ClassicHttpResponse response) throws HttpException, IOException;
+
+ }
+
+ void proceed(
+ ClassicHttpRequest request,
+ ResponseTrigger responseTrigger,
+ HttpContext context) throws HttpException, IOException;
+
+}
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/52b0d269/httpcore5/src/main/java/org/apache/hc/core5/http/io/HttpFilterHandler.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/io/HttpFilterHandler.java b/httpcore5/src/main/java/org/apache/hc/core5/http/io/HttpFilterHandler.java
new file mode 100644
index 0000000..4409784
--- /dev/null
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/io/HttpFilterHandler.java
@@ -0,0 +1,49 @@
+/*
+ * ====================================================================
+ * 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.core5.http.io;
+
+import java.io.IOException;
+
+import org.apache.hc.core5.annotation.Contract;
+import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.http.ClassicHttpRequest;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.protocol.HttpContext;
+
+/**
+ * @since 5.0
+ */
+@Contract(threading = ThreadingBehavior.STATELESS)
+public interface HttpFilterHandler {
+
+ void handle(
+ ClassicHttpRequest request,
+ HttpFilterChain.ResponseTrigger responseTrigger,
+ HttpContext context,
+ HttpFilterChain chain) throws HttpException, IOException;
+
+}
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/52b0d269/httpcore5/src/main/java/org/apache/hc/core5/http/io/support/HttpServerExpectationFilter.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/io/support/HttpServerExpectationFilter.java b/httpcore5/src/main/java/org/apache/hc/core5/http/io/support/HttpServerExpectationFilter.java
new file mode 100644
index 0000000..9b5aacf
--- /dev/null
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/io/support/HttpServerExpectationFilter.java
@@ -0,0 +1,82 @@
+/*
+ * ====================================================================
+ * 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.core5.http.io.support;
+
+import java.io.IOException;
+
+import org.apache.hc.core5.annotation.Contract;
+import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.http.ClassicHttpRequest;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HttpEntity;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.HttpHeaders;
+import org.apache.hc.core5.http.HttpResponse;
+import org.apache.hc.core5.http.HttpStatus;
+import org.apache.hc.core5.http.io.HttpFilterChain;
+import org.apache.hc.core5.http.io.HttpFilterHandler;
+import org.apache.hc.core5.http.message.BasicClassicHttpResponse;
+import org.apache.hc.core5.http.protocol.HttpContext;
+
+/**
+ * @since 5.0
+ */
+@Contract(threading = ThreadingBehavior.STATELESS)
+public class HttpServerExpectationFilter implements HttpFilterHandler {
+
+ protected boolean verify(final ClassicHttpRequest request, final HttpContext context) throws HttpException {
+ return true;
+ }
+
+ protected HttpEntity generateResponseContent(final HttpResponse expectationFailed) throws HttpException {
+ return null;
+ }
+
+ @Override
+ public final void handle(
+ final ClassicHttpRequest request,
+ final HttpFilterChain.ResponseTrigger responseTrigger,
+ final HttpContext context,
+ final HttpFilterChain chain) throws HttpException, IOException {
+ final Header expect = request.getFirstHeader(HttpHeaders.EXPECT);
+ final boolean expectContinue = expect != null && "100-continue".equalsIgnoreCase(expect.getValue());
+ if (expectContinue) {
+ final boolean verified = verify(request, context);
+ if (verified) {
+ responseTrigger.sendInformation(new BasicClassicHttpResponse(HttpStatus.SC_CONTINUE));
+ } else {
+ final ClassicHttpResponse expectationFailed = new BasicClassicHttpResponse(HttpStatus.SC_EXPECTATION_FAILED);
+ final HttpEntity responseContent = generateResponseContent(expectationFailed);
+ expectationFailed.setEntity(responseContent);
+ responseTrigger.submitResponse(expectationFailed);
+ return;
+ }
+ }
+ chain.proceed(request, responseTrigger, context);
+ }
+}
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/52b0d269/httpcore5/src/main/java/org/apache/hc/core5/http/io/support/HttpServerFilterChainElement.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/io/support/HttpServerFilterChainElement.java b/httpcore5/src/main/java/org/apache/hc/core5/http/io/support/HttpServerFilterChainElement.java
new file mode 100644
index 0000000..69d429f
--- /dev/null
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/io/support/HttpServerFilterChainElement.java
@@ -0,0 +1,74 @@
+/*
+ * ====================================================================
+ * 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.hc.core5.http.io.support;
+
+import java.io.IOException;
+
+import org.apache.hc.core5.http.ClassicHttpRequest;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.io.HttpFilterChain;
+import org.apache.hc.core5.http.io.HttpFilterHandler;
+import org.apache.hc.core5.http.protocol.HttpContext;
+
+public final class HttpServerFilterChainElement {
+
+ private final HttpFilterHandler handler;
+ private final HttpServerFilterChainElement next;
+ private final HttpFilterChain filterChain;
+
+ public HttpServerFilterChainElement(final HttpFilterHandler handler, final HttpServerFilterChainElement next) {
+ this.handler = handler;
+ this.next = next;
+ this.filterChain = new HttpFilterChain() {
+
+ @Override
+ public void proceed(
+ final ClassicHttpRequest request,
+ final ResponseTrigger responseTrigger,
+ final HttpContext context) throws HttpException, IOException {
+ next.handle(request, responseTrigger, context);
+ }
+ };
+ }
+
+ public void handle(
+ final ClassicHttpRequest request,
+ final HttpFilterChain.ResponseTrigger responseTrigger,
+ final HttpContext context) throws IOException, HttpException {
+ handler.handle(request, responseTrigger, context, filterChain);
+ }
+
+ @Override
+ public String toString() {
+ return "{" +
+ "handler=" + handler.getClass() +
+ ", next=" + (next != null ? next.handler.getClass() : "null") +
+ '}';
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/52b0d269/httpcore5/src/main/java/org/apache/hc/core5/http/io/support/HttpServerFilterChainRequestHandler.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/io/support/HttpServerFilterChainRequestHandler.java b/httpcore5/src/main/java/org/apache/hc/core5/http/io/support/HttpServerFilterChainRequestHandler.java
new file mode 100644
index 0000000..c6064b9
--- /dev/null
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/io/support/HttpServerFilterChainRequestHandler.java
@@ -0,0 +1,72 @@
+/*
+ * ====================================================================
+ * 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.hc.core5.http.io.support;
+
+import java.io.IOException;
+
+import org.apache.hc.core5.http.ClassicHttpRequest;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.io.HttpFilterChain;
+import org.apache.hc.core5.http.io.HttpServerRequestHandler;
+import org.apache.hc.core5.http.protocol.HttpContext;
+import org.apache.hc.core5.util.Args;
+
+/**
+ * @since 5.0
+ */
+public class HttpServerFilterChainRequestHandler implements HttpServerRequestHandler {
+
+ private final HttpServerFilterChainElement filterChain;
+
+ public HttpServerFilterChainRequestHandler(final HttpServerFilterChainElement filterChain) {
+ this.filterChain = Args.notNull(filterChain, "Filter chain");
+ }
+
+ @Override
+ public void handle(
+ final ClassicHttpRequest request,
+ final ResponseTrigger trigger,
+ final HttpContext context) throws HttpException, IOException {
+ filterChain.handle(request, new HttpFilterChain.ResponseTrigger() {
+
+ @Override
+ public void sendInformation(final ClassicHttpResponse response) throws HttpException, IOException {
+ trigger.sendInformation(response);
+ }
+
+ @Override
+ public void submitResponse(final ClassicHttpResponse response) throws HttpException, IOException {
+ trigger.submitResponse(response);
+
+ }
+
+ }, context);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/52b0d269/httpcore5/src/main/java/org/apache/hc/core5/http/io/support/TerminalServerFilter.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/io/support/TerminalServerFilter.java b/httpcore5/src/main/java/org/apache/hc/core5/http/io/support/TerminalServerFilter.java
new file mode 100644
index 0000000..a059f4c
--- /dev/null
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/io/support/TerminalServerFilter.java
@@ -0,0 +1,75 @@
+/*
+ * ====================================================================
+ * 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.core5.http.io.support;
+
+import java.io.IOException;
+
+import org.apache.hc.core5.annotation.Contract;
+import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.http.ClassicHttpRequest;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.HttpRequestMapper;
+import org.apache.hc.core5.http.HttpResponseFactory;
+import org.apache.hc.core5.http.HttpStatus;
+import org.apache.hc.core5.http.impl.io.DefaultClassicHttpResponseFactory;
+import org.apache.hc.core5.http.io.HttpFilterChain;
+import org.apache.hc.core5.http.io.HttpFilterHandler;
+import org.apache.hc.core5.http.io.HttpRequestHandler;
+import org.apache.hc.core5.http.protocol.HttpContext;
+import org.apache.hc.core5.util.Args;
+
+/**
+ * @since 5.0
+ */
+@Contract(threading = ThreadingBehavior.STATELESS)
+public final class TerminalServerFilter implements HttpFilterHandler {
+
+ private final HttpRequestMapper<HttpRequestHandler> handlerMapper;
+ private final HttpResponseFactory<ClassicHttpResponse> responseFactory;
+
+ public TerminalServerFilter(final HttpRequestMapper<HttpRequestHandler> handlerMapper, final HttpResponseFactory<ClassicHttpResponse> responseFactory) {
+ this.handlerMapper = Args.notNull(handlerMapper, "Handler mapper");
+ this.responseFactory = responseFactory != null ? responseFactory : DefaultClassicHttpResponseFactory.INSTANCE;
+ }
+
+ @Override
+ public final void handle(
+ final ClassicHttpRequest request,
+ final HttpFilterChain.ResponseTrigger responseTrigger,
+ final HttpContext context,
+ final HttpFilterChain chain) throws HttpException, IOException {
+ final ClassicHttpResponse response = responseFactory.newHttpResponse(HttpStatus.SC_OK);
+ final HttpRequestHandler handler = handlerMapper.resolve(request, context);
+ if (handler != null) {
+ handler.handle(request, response, context);
+ } else {
+ response.setCode(HttpStatus.SC_NOT_IMPLEMENTED);
+ }
+ responseTrigger.submitResponse(response);
+ }
+}
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/52b0d269/httpcore5/src/main/java/org/apache/hc/core5/http/nio/AsyncFilterChain.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/AsyncFilterChain.java b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/AsyncFilterChain.java
new file mode 100644
index 0000000..c2ef87d
--- /dev/null
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/AsyncFilterChain.java
@@ -0,0 +1,61 @@
+/*
+ * ====================================================================
+ * 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.core5.http.nio;
+
+import java.io.IOException;
+
+import org.apache.hc.core5.annotation.Contract;
+import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.http.EntityDetails;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.HttpRequest;
+import org.apache.hc.core5.http.HttpResponse;
+import org.apache.hc.core5.http.protocol.HttpContext;
+
+/**
+ * @since 5.0
+ */
+@Contract(threading = ThreadingBehavior.STATELESS)
+public interface AsyncFilterChain {
+
+ interface ResponseTrigger {
+
+ void sendInformation(HttpResponse response) throws HttpException, IOException;
+
+ void submitResponse(HttpResponse response, AsyncEntityProducer entityProducer) throws HttpException, IOException;
+
+ void pushPromise(HttpRequest promise, AsyncPushProducer responseProducer) throws HttpException, IOException;
+
+ }
+
+ AsyncDataConsumer proceed(
+ HttpRequest request,
+ EntityDetails entityDetails,
+ HttpContext context,
+ ResponseTrigger responseTrigger) throws HttpException, IOException;
+
+}
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/52b0d269/httpcore5/src/main/java/org/apache/hc/core5/http/nio/AsyncFilterHandler.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/AsyncFilterHandler.java b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/AsyncFilterHandler.java
new file mode 100644
index 0000000..83f0dea
--- /dev/null
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/AsyncFilterHandler.java
@@ -0,0 +1,51 @@
+/*
+ * ====================================================================
+ * 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.core5.http.nio;
+
+import java.io.IOException;
+
+import org.apache.hc.core5.annotation.Contract;
+import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.http.EntityDetails;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.HttpRequest;
+import org.apache.hc.core5.http.protocol.HttpContext;
+
+/**
+ * @since 5.0
+ */
+@Contract(threading = ThreadingBehavior.STATELESS)
+public interface AsyncFilterHandler {
+
+ AsyncDataConsumer handle(
+ HttpRequest request,
+ EntityDetails entityDetails,
+ HttpContext context,
+ AsyncFilterChain.ResponseTrigger responseTrigger,
+ AsyncFilterChain chain) throws HttpException, IOException;
+
+}
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/52b0d269/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/AsyncServerExpectationFilter.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/AsyncServerExpectationFilter.java b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/AsyncServerExpectationFilter.java
new file mode 100644
index 0000000..67ef9a3
--- /dev/null
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/AsyncServerExpectationFilter.java
@@ -0,0 +1,85 @@
+/*
+ * ====================================================================
+ * 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.core5.http.nio.support;
+
+import java.io.IOException;
+
+import org.apache.hc.core5.annotation.Contract;
+import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.http.EntityDetails;
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.HttpHeaders;
+import org.apache.hc.core5.http.HttpRequest;
+import org.apache.hc.core5.http.HttpResponse;
+import org.apache.hc.core5.http.HttpStatus;
+import org.apache.hc.core5.http.message.BasicHttpResponse;
+import org.apache.hc.core5.http.nio.AsyncDataConsumer;
+import org.apache.hc.core5.http.nio.AsyncEntityProducer;
+import org.apache.hc.core5.http.nio.AsyncFilterChain;
+import org.apache.hc.core5.http.nio.AsyncFilterHandler;
+import org.apache.hc.core5.http.protocol.HttpContext;
+
+/**
+ * @since 5.0
+ */
+@Contract(threading = ThreadingBehavior.STATELESS)
+public abstract class AsyncServerExpectationFilter implements AsyncFilterHandler {
+
+ protected boolean verify(final HttpRequest request, final HttpContext context) throws HttpException {
+ return true;
+ }
+
+ protected AsyncEntityProducer generateResponseContent(final HttpResponse expectationFailed) throws HttpException {
+ return null;
+ }
+
+ @Override
+ public AsyncDataConsumer handle(
+ final HttpRequest request,
+ final EntityDetails entityDetails,
+ final HttpContext context,
+ final AsyncFilterChain.ResponseTrigger responseTrigger,
+ final AsyncFilterChain chain) throws HttpException, IOException {
+ if (entityDetails != null) {
+ final Header h = request.getFirstHeader(HttpHeaders.EXPECT);
+ if (h != null && "100-continue".equalsIgnoreCase(h.getValue())) {
+ final boolean verified = verify(request, context);
+ if (verified) {
+ responseTrigger.sendInformation(new BasicHttpResponse(HttpStatus.SC_CONTINUE));
+ } else {
+ final HttpResponse expectationFailed = new BasicHttpResponse(HttpStatus.SC_EXPECTATION_FAILED);
+ final AsyncEntityProducer responseContentProducer = generateResponseContent(expectationFailed);
+ responseTrigger.submitResponse(expectationFailed, responseContentProducer);
+ return null;
+ }
+ }
+ }
+ return chain.proceed(request, entityDetails, context, responseTrigger);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/52b0d269/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/AsyncServerFilterChainElement.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/AsyncServerFilterChainElement.java b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/AsyncServerFilterChainElement.java
new file mode 100644
index 0000000..d423ecc
--- /dev/null
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/AsyncServerFilterChainElement.java
@@ -0,0 +1,79 @@
+/*
+ * ====================================================================
+ * 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.hc.core5.http.nio.support;
+
+import java.io.IOException;
+
+import org.apache.hc.core5.http.EntityDetails;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.HttpRequest;
+import org.apache.hc.core5.http.nio.AsyncDataConsumer;
+import org.apache.hc.core5.http.nio.AsyncFilterChain;
+import org.apache.hc.core5.http.nio.AsyncFilterHandler;
+import org.apache.hc.core5.http.protocol.HttpContext;
+
+public final class AsyncServerFilterChainElement {
+
+ private final AsyncFilterHandler handler;
+ private final AsyncServerFilterChainElement next;
+ private final AsyncFilterChain filterChain;
+
+ public AsyncServerFilterChainElement(final AsyncFilterHandler handler, final AsyncServerFilterChainElement next) {
+ this.handler = handler;
+ this.next = next;
+ this.filterChain = new AsyncFilterChain() {
+
+ @Override
+ public AsyncDataConsumer proceed(
+ final HttpRequest request,
+ final EntityDetails entityDetails,
+ final HttpContext context,
+ final ResponseTrigger responseTrigger) throws HttpException, IOException {
+ return next.handle(request, entityDetails, context, responseTrigger);
+ }
+
+ };
+ }
+
+ public AsyncDataConsumer handle(
+ final HttpRequest request,
+ final EntityDetails entityDetails,
+ final HttpContext context,
+ final AsyncFilterChain.ResponseTrigger responseTrigger) throws HttpException, IOException {
+ return handler.handle(request, entityDetails, context, responseTrigger, filterChain);
+ }
+
+ @Override
+ public String toString() {
+ return "{" +
+ "handler=" + handler.getClass() +
+ ", next=" + (next != null ? next.handler.getClass() : "null") +
+ '}';
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/52b0d269/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/AsyncServerFilterChainExchangeHandlerFactory.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/AsyncServerFilterChainExchangeHandlerFactory.java b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/AsyncServerFilterChainExchangeHandlerFactory.java
new file mode 100644
index 0000000..6c5da73
--- /dev/null
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/AsyncServerFilterChainExchangeHandlerFactory.java
@@ -0,0 +1,165 @@
+/*
+ * ====================================================================
+ * 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.hc.core5.http.nio.support;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.hc.core5.http.EntityDetails;
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.HttpRequest;
+import org.apache.hc.core5.http.HttpResponse;
+import org.apache.hc.core5.http.nio.AsyncDataConsumer;
+import org.apache.hc.core5.http.nio.AsyncEntityProducer;
+import org.apache.hc.core5.http.nio.AsyncFilterChain;
+import org.apache.hc.core5.http.nio.AsyncPushProducer;
+import org.apache.hc.core5.http.nio.AsyncResponseProducer;
+import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
+import org.apache.hc.core5.http.nio.BasicResponseProducer;
+import org.apache.hc.core5.http.nio.CapacityChannel;
+import org.apache.hc.core5.http.nio.DataStreamChannel;
+import org.apache.hc.core5.http.nio.HandlerFactory;
+import org.apache.hc.core5.http.nio.ResponseChannel;
+import org.apache.hc.core5.http.protocol.HttpContext;
+import org.apache.hc.core5.util.Args;
+import org.apache.hc.core5.util.Asserts;
+
+public final class AsyncServerFilterChainExchangeHandlerFactory implements HandlerFactory<AsyncServerExchangeHandler> {
+
+ private final AsyncServerFilterChainElement filterChain;
+
+ public AsyncServerFilterChainExchangeHandlerFactory(final AsyncServerFilterChainElement filterChain) {
+ this.filterChain = Args.notNull(filterChain, "Filter chain");
+ }
+
+ @Override
+ public AsyncServerExchangeHandler create(final HttpRequest request, final HttpContext context) throws HttpException {
+ return new AsyncServerExchangeHandler() {
+
+ private final AtomicReference<AsyncDataConsumer> dataConsumerRef = new AtomicReference<>();
+ private final AtomicReference<AsyncResponseProducer> responseProducerRef = new AtomicReference<>();
+
+ @Override
+ public void handleRequest(
+ final HttpRequest request,
+ final EntityDetails entityDetails,
+ final ResponseChannel responseChannel,
+ final HttpContext context) throws HttpException, IOException {
+ dataConsumerRef.set(filterChain.handle(request, entityDetails, context, new AsyncFilterChain.ResponseTrigger() {
+
+ @Override
+ public void sendInformation(
+ final HttpResponse response) throws HttpException, IOException {
+ responseChannel.sendInformation(response);
+ }
+
+ @Override
+ public void submitResponse(
+ final HttpResponse response,
+ final AsyncEntityProducer entityProducer) throws HttpException, IOException {
+ final AsyncResponseProducer responseProducer = new BasicResponseProducer(response, entityProducer);
+ responseProducerRef.set(responseProducer);
+ responseProducer.sendResponse(responseChannel);
+ }
+
+ @Override
+ public void pushPromise(final HttpRequest promise, final AsyncPushProducer responseProducer) throws HttpException, IOException {
+ responseChannel.pushPromise(promise, responseProducer);
+ }
+
+ }));
+ }
+
+ @Override
+ public void failed(final Exception cause) {
+ final AsyncResponseProducer handler = responseProducerRef.get();
+ if (handler != null) {
+ handler.failed(cause);
+ }
+ }
+
+ @Override
+ public void updateCapacity(final CapacityChannel capacityChannel) throws IOException {
+ final AsyncDataConsumer dataConsumer = dataConsumerRef.get();
+ if (dataConsumer != null) {
+ dataConsumer.updateCapacity(capacityChannel);
+ } else {
+ capacityChannel.update(Integer.MAX_VALUE);
+ }
+ }
+
+ @Override
+ public int consume(final ByteBuffer src) throws IOException {
+ final AsyncDataConsumer dataConsumer = dataConsumerRef.get();
+ if (dataConsumer != null) {
+ return dataConsumer.consume(src);
+ } else {
+ return Integer.MAX_VALUE;
+ }
+ }
+
+ @Override
+ public void streamEnd(final List<? extends Header> trailers) throws HttpException, IOException {
+ final AsyncDataConsumer dataConsumer = dataConsumerRef.get();
+ if (dataConsumer != null) {
+ dataConsumer.streamEnd(trailers);
+ }
+ }
+
+ @Override
+ public int available() {
+ final AsyncResponseProducer responseProducer = responseProducerRef.get();
+ Asserts.notNull(responseProducer, "Response producer");
+ return responseProducer.available();
+ }
+
+ @Override
+ public void produce(final DataStreamChannel channel) throws IOException {
+ final AsyncResponseProducer responseProducer = responseProducerRef.get();
+ Asserts.notNull(responseProducer, "Response producer");
+ responseProducer.produce(channel);
+ }
+
+ @Override
+ public void releaseResources() {
+ final AsyncDataConsumer dataConsumer = dataConsumerRef.getAndSet(null);
+ if (dataConsumer != null) {
+ dataConsumer.releaseResources();
+ }
+ final AsyncResponseProducer responseProducer = responseProducerRef.getAndSet(null);
+ if (responseProducer != null) {
+ responseProducer.releaseResources();
+ }
+ }
+ };
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/52b0d269/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/TerminalAsyncServerFilter.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/TerminalAsyncServerFilter.java b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/TerminalAsyncServerFilter.java
new file mode 100644
index 0000000..50762c0
--- /dev/null
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/TerminalAsyncServerFilter.java
@@ -0,0 +1,146 @@
+/*
+ * ====================================================================
+ * 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.core5.http.nio.support;
+
+import java.io.IOException;
+import java.util.Set;
+
+import org.apache.hc.core5.annotation.Contract;
+import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.http.EntityDetails;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.HttpRequest;
+import org.apache.hc.core5.http.HttpResponse;
+import org.apache.hc.core5.http.HttpStatus;
+import org.apache.hc.core5.http.message.BasicHttpResponse;
+import org.apache.hc.core5.http.nio.AsyncDataConsumer;
+import org.apache.hc.core5.http.nio.AsyncEntityProducer;
+import org.apache.hc.core5.http.nio.AsyncFilterChain;
+import org.apache.hc.core5.http.nio.AsyncFilterHandler;
+import org.apache.hc.core5.http.nio.AsyncPushProducer;
+import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
+import org.apache.hc.core5.http.nio.DataStreamChannel;
+import org.apache.hc.core5.http.nio.HandlerFactory;
+import org.apache.hc.core5.http.nio.ResponseChannel;
+import org.apache.hc.core5.http.nio.entity.BasicAsyncEntityProducer;
+import org.apache.hc.core5.http.protocol.HttpContext;
+import org.apache.hc.core5.util.Args;
+
+/**
+ * @since 5.0
+ */
+@Contract(threading = ThreadingBehavior.STATELESS)
+public final class TerminalAsyncServerFilter implements AsyncFilterHandler {
+
+ final private HandlerFactory<AsyncServerExchangeHandler> handlerFactory;
+
+ public TerminalAsyncServerFilter(final HandlerFactory<AsyncServerExchangeHandler> handlerFactory) {
+ this.handlerFactory = Args.notNull(handlerFactory, "Handler factory");
+ }
+
+ @Override
+ public AsyncDataConsumer handle(
+ final HttpRequest request,
+ final EntityDetails entityDetails,
+ final HttpContext context,
+ final AsyncFilterChain.ResponseTrigger responseTrigger,
+ final AsyncFilterChain chain) throws HttpException, IOException {
+ final AsyncServerExchangeHandler exchangeHandler = handlerFactory.create(request, context);
+ if (exchangeHandler != null) {
+ exchangeHandler.handleRequest(request, entityDetails, new ResponseChannel() {
+
+ @Override
+ public void sendInformation(final HttpResponse response) throws HttpException, IOException {
+ responseTrigger.sendInformation(response);
+ }
+
+ @Override
+ public void sendResponse(final HttpResponse response, final EntityDetails entityDetails) throws HttpException, IOException {
+ responseTrigger.submitResponse(response, entityDetails != null ? new AsyncEntityProducer() {
+
+ @Override
+ public void failed(final Exception cause) {
+ exchangeHandler.failed(cause);
+ }
+
+ @Override
+ public long getContentLength() {
+ return entityDetails.getContentLength();
+ }
+
+ @Override
+ public String getContentType() {
+ return entityDetails.getContentType();
+ }
+
+ @Override
+ public String getContentEncoding() {
+ return entityDetails.getContentEncoding();
+ }
+
+ @Override
+ public boolean isChunked() {
+ return entityDetails.isChunked();
+ }
+
+ @Override
+ public Set<String> getTrailerNames() {
+ return entityDetails.getTrailerNames();
+ }
+
+ @Override
+ public int available() {
+ return exchangeHandler.available();
+ }
+
+ @Override
+ public void produce(final DataStreamChannel channel) throws IOException {
+ exchangeHandler.produce(channel);
+ }
+
+ @Override
+ public void releaseResources() {
+ exchangeHandler.releaseResources();
+ }
+
+ } : null);
+ }
+
+ @Override
+ public void pushPromise(final HttpRequest promise, final AsyncPushProducer pushProducer) throws HttpException, IOException {
+ responseTrigger.pushPromise(promise, pushProducer);
+ }
+
+ }, context);
+ return exchangeHandler;
+ } else {
+ responseTrigger.submitResponse(new BasicHttpResponse(HttpStatus.SC_NOT_FOUND), new BasicAsyncEntityProducer("Not found"));
+ return null;
+ }
+ }
+
+}