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/01 19:07:04 UTC
[6/6] httpcomponents-core git commit: Improved request handler
mapping and registration (classic and asynchronous)
Improved request handler mapping and registration (classic and asynchronous)
Project: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/repo
Commit: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/commit/479ad348
Tree: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/tree/479ad348
Diff: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/diff/479ad348
Branch: refs/heads/master
Commit: 479ad3486882fb4ac56a3704016c63cf08dcd1a6
Parents: 41291fa
Author: Oleg Kalnichevski <ol...@apache.org>
Authored: Mon Jul 31 16:20:13 2017 +0200
Committer: Oleg Kalnichevski <ol...@apache.org>
Committed: Tue Aug 1 21:01:23 2017 +0200
----------------------------------------------------------------------
.../hc/core5/http/benchmark/SmokeTest.java | 6 +-
.../impl/nio/ClientPushHttp2StreamHandler.java | 2 +-
.../impl/nio/ServerHttp2StreamHandler.java | 2 +-
.../nio/bootstrap/H2RequesterBootstrap.java | 59 ++++----
.../impl/nio/bootstrap/H2ServerBootstrap.java | 74 +++++++---
.../http2/impl/nio/bootstrap/HandlerEntry.java | 41 ++++++
.../nio/support/AsyncPushConsumerRegistry.java | 103 --------------
.../DefaultAsyncPushConsumerFactory.java | 63 +++++++++
.../testing/classic/ClassicTestServer.java | 16 ++-
.../testing/framework/TestingFramework.java | 2 +-
.../hc/core5/testing/nio/Http1TestServer.java | 11 +-
.../hc/core5/testing/nio/Http2TestClient.java | 13 +-
.../hc/core5/testing/nio/Http2TestServer.java | 13 +-
.../core5/testing/nio/Http1IntegrationTest.java | 4 +-
.../http/examples/ClassicFileServerExample.java | 2 +-
.../examples/ClassicReverseProxyExample.java | 2 +-
.../org/apache/hc/core5/function/Factory.java | 39 ++++++
.../apache/hc/core5/http/HttpRequestMapper.java | 49 +++++++
.../impl/bootstrap/AsyncServerBootstrap.java | 76 +++++++----
.../core5/http/impl/bootstrap/HandlerEntry.java | 41 ++++++
.../http/impl/bootstrap/ServerBootstrap.java | 88 +++++++-----
.../hc/core5/http/impl/io/HttpService.java | 14 +-
.../http/impl/nio/ServerHttp1StreamHandler.java | 2 +-
.../core5/http/io/HttpRequestHandlerMapper.java | 53 --------
.../io/support/UriHttpRequestHandlerMapper.java | 122 -----------------
.../http/nio/AsyncServerRequestHandler.java | 2 +-
.../hc/core5/http/nio/HandlerFactory.java | 3 +-
.../AsyncServerExchangeHandlerRegistry.java | 107 ---------------
...aultAsyncResponseExchangeHandlerFactory.java | 64 +++++++++
.../http/protocol/RequestHandlerRegistry.java | 135 +++++++++++++++++++
.../hc/core5/http/protocol/UriPatternType.java | 49 +++++++
.../hc/core5/http/impl/io/TestHttpService.java | 16 +--
.../TestUriHttpRequestHandlerMapper.java | 108 ---------------
.../TestAsyncServerExchangeHandlerRegistry.java | 72 ----------
.../protocol/TestRequestHandlerRegistry.java | 92 +++++++++++++
35 files changed, 824 insertions(+), 721 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/479ad348/httpcore5-ab/src/test/java/org/apache/hc/core5/http/benchmark/SmokeTest.java
----------------------------------------------------------------------
diff --git a/httpcore5-ab/src/test/java/org/apache/hc/core5/http/benchmark/SmokeTest.java b/httpcore5-ab/src/test/java/org/apache/hc/core5/http/benchmark/SmokeTest.java
index 28b3559..cbe9684 100644
--- a/httpcore5-ab/src/test/java/org/apache/hc/core5/http/benchmark/SmokeTest.java
+++ b/httpcore5-ab/src/test/java/org/apache/hc/core5/http/benchmark/SmokeTest.java
@@ -52,7 +52,7 @@ public class SmokeTest {
@Before
public void setup() throws Exception {
server = ServerBootstrap.bootstrap()
- .registerHandler("/", new HttpRequestHandler() {
+ .register("/", new HttpRequestHandler() {
@Override
public void handle(
final ClassicHttpRequest request,
@@ -68,7 +68,9 @@ public class SmokeTest {
@After
public void shutdown() throws Exception {
- server.shutdown(ShutdownType.IMMEDIATE);
+ if (server != null) {
+ server.shutdown(ShutdownType.IMMEDIATE);
+ }
}
@Test
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/479ad348/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientPushHttp2StreamHandler.java
----------------------------------------------------------------------
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientPushHttp2StreamHandler.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientPushHttp2StreamHandler.java
index ffaabdc..106d88c 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientPushHttp2StreamHandler.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientPushHttp2StreamHandler.java
@@ -100,7 +100,7 @@ class ClientPushHttp2StreamHandler implements Http2StreamHandler {
final AsyncPushConsumer handler;
try {
- handler = pushHandlerFactory != null ? pushHandlerFactory.create(request) : null;
+ handler = pushHandlerFactory != null ? pushHandlerFactory.create(request, context) : null;
} catch (final ProtocolException ex) {
throw new H2StreamResetException(H2Error.PROTOCOL_ERROR, ex.getMessage());
}
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/479ad348/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttp2StreamHandler.java
----------------------------------------------------------------------
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttp2StreamHandler.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttp2StreamHandler.java
index e856218..bbd6a56 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttp2StreamHandler.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttp2StreamHandler.java
@@ -187,7 +187,7 @@ public class ServerHttp2StreamHandler implements Http2StreamHandler {
final AsyncServerExchangeHandler handler;
try {
- handler = exchangeHandlerFactory != null ? exchangeHandlerFactory.create(request) : null;
+ handler = exchangeHandlerFactory != null ? exchangeHandlerFactory.create(request, context) : null;
} catch (final ProtocolException ex) {
throw new H2StreamResetException(H2Error.PROTOCOL_ERROR, ex.getMessage());
}
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/479ad348/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2RequesterBootstrap.java
----------------------------------------------------------------------
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2RequesterBootstrap.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2RequesterBootstrap.java
index 4d1043f..6bba2d9 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2RequesterBootstrap.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2RequesterBootstrap.java
@@ -40,13 +40,15 @@ import org.apache.hc.core5.http.impl.nio.ClientHttp1StreamDuplexerFactory;
import org.apache.hc.core5.http.nio.AsyncPushConsumer;
import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
import org.apache.hc.core5.http.protocol.HttpProcessor;
+import org.apache.hc.core5.http.protocol.RequestHandlerRegistry;
+import org.apache.hc.core5.http.protocol.UriPatternType;
import org.apache.hc.core5.http2.HttpVersionPolicy;
import org.apache.hc.core5.http2.config.H2Config;
import org.apache.hc.core5.http2.impl.Http2Processors;
import org.apache.hc.core5.http2.impl.nio.ClientHttp2StreamMultiplexerFactory;
import org.apache.hc.core5.http2.impl.nio.ClientHttpProtocolNegotiatorFactory;
import org.apache.hc.core5.http2.impl.nio.Http2StreamListener;
-import org.apache.hc.core5.http2.nio.support.AsyncPushConsumerRegistry;
+import org.apache.hc.core5.http2.nio.support.DefaultAsyncPushConsumerFactory;
import org.apache.hc.core5.http2.ssl.H2ClientTlsStrategy;
import org.apache.hc.core5.pool.ConnPoolListener;
import org.apache.hc.core5.pool.ConnPoolPolicy;
@@ -63,8 +65,8 @@ import org.apache.hc.core5.util.TimeValue;
*/
public class H2RequesterBootstrap {
- private final List<PushConsumerEntry> pushConsumerList;
-
+ private final List<HandlerEntry<Supplier<AsyncPushConsumer>>> pushConsumerList;
+ private UriPatternType uriPatternType;
private IOReactorConfig ioReactorConfig;
private HttpProcessor httpProcessor;
private CharCodingConfig charCodingConfig;
@@ -209,18 +211,41 @@ public class H2RequesterBootstrap {
return this;
}
+ /**
+ * Assigns {@link UriPatternType} for handler registration.
+ */
+ public final H2RequesterBootstrap setUriPatternType(final UriPatternType uriPatternType) {
+ this.uriPatternType = uriPatternType;
+ return this;
+ }
+
+ /**
+ * Registers the given {@link AsyncPushConsumer} {@link Supplier} as a default handler for URIs
+ * matching the given pattern.
+ *
+ * @param uriPattern the pattern to register the handler for.
+ * @param supplier the handler supplier.
+ */
public final H2RequesterBootstrap register(final String uriPattern, final Supplier<AsyncPushConsumer> supplier) {
Args.notBlank(uriPattern, "URI pattern");
Args.notNull(supplier, "Supplier");
- pushConsumerList.add(new PushConsumerEntry(null, uriPattern, supplier));
+ pushConsumerList.add(new HandlerEntry<>(null, uriPattern, supplier));
return this;
}
- public final H2RequesterBootstrap register(final String hostname, final String uriPattern, final Supplier<AsyncPushConsumer> supplier) {
+ /**
+ * Registers the given {@link AsyncPushConsumer} {@link Supplier} as a handler for URIs
+ * matching the given host and the pattern.
+ *
+ * @param hostname the host name
+ * @param uriPattern the pattern to register the handler for.
+ * @param supplier the handler supplier.
+ */
+ public final H2RequesterBootstrap registerVirtual(final String hostname, final String uriPattern, final Supplier<AsyncPushConsumer> supplier) {
Args.notBlank(hostname, "Hostname");
Args.notBlank(uriPattern, "URI pattern");
Args.notNull(supplier, "Supplier");
- pushConsumerList.add(new PushConsumerEntry(hostname, uriPattern, supplier));
+ pushConsumerList.add(new HandlerEntry<>(hostname, uriPattern, supplier));
return this;
}
@@ -231,9 +256,9 @@ public class H2RequesterBootstrap {
timeToLive,
connPoolPolicy,
connPoolListener);
- final AsyncPushConsumerRegistry pushConsumerRegistry = new AsyncPushConsumerRegistry();
- for (final PushConsumerEntry entry: pushConsumerList) {
- pushConsumerRegistry.register(entry.hostname, entry.uriPattern, entry.supplier);
+ final RequestHandlerRegistry<Supplier<AsyncPushConsumer>> registry = new RequestHandlerRegistry<>(uriPatternType);
+ for (final HandlerEntry<Supplier<AsyncPushConsumer>> entry: pushConsumerList) {
+ registry.register(entry.hostname, entry.uriPattern, entry.handler);
}
final ClientHttp1StreamDuplexerFactory http1StreamHandlerFactory = new ClientHttp1StreamDuplexerFactory(
httpProcessor != null ? httpProcessor : HttpProcessors.client(),
@@ -242,7 +267,7 @@ public class H2RequesterBootstrap {
http1StreamListener);
final ClientHttp2StreamMultiplexerFactory http2StreamHandlerFactory = new ClientHttp2StreamMultiplexerFactory(
httpProcessor != null ? httpProcessor : Http2Processors.client(),
- pushConsumerRegistry,
+ new DefaultAsyncPushConsumerFactory(registry),
h2Config != null ? h2Config : H2Config.DEFAULT,
charCodingConfig != null ? charCodingConfig : CharCodingConfig.DEFAULT,
streamListener);
@@ -260,18 +285,4 @@ public class H2RequesterBootstrap {
tlsStrategy != null ? tlsStrategy : new H2ClientTlsStrategy());
}
- private static class PushConsumerEntry {
-
- final String hostname;
- final String uriPattern;
- final Supplier<AsyncPushConsumer> supplier;
-
- public PushConsumerEntry(final String hostname, final String uriPattern, final Supplier<AsyncPushConsumer> supplier) {
- this.hostname = hostname;
- this.uriPattern = uriPattern;
- this.supplier = supplier;
- }
-
- }
-
}
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/479ad348/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2ServerBootstrap.java
----------------------------------------------------------------------
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2ServerBootstrap.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2ServerBootstrap.java
index 288bb2a..0a25098 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2ServerBootstrap.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2ServerBootstrap.java
@@ -37,16 +37,19 @@ import org.apache.hc.core5.http.impl.DefaultConnectionReuseStrategy;
import org.apache.hc.core5.http.impl.DefaultContentLengthStrategy;
import org.apache.hc.core5.http.impl.Http1StreamListener;
import org.apache.hc.core5.http.impl.HttpProcessors;
-import org.apache.hc.core5.http.nio.support.AsyncServerExchangeHandlerRegistry;
import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncServer;
import org.apache.hc.core5.http.impl.nio.DefaultHttpRequestParserFactory;
import org.apache.hc.core5.http.impl.nio.DefaultHttpResponseWriterFactory;
import org.apache.hc.core5.http.impl.nio.ServerHttp1StreamDuplexerFactory;
import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
import org.apache.hc.core5.http.nio.AsyncServerRequestHandler;
+import org.apache.hc.core5.http.nio.HandlerFactory;
import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
import org.apache.hc.core5.http.nio.support.BasicServerExchangeHandler;
+import org.apache.hc.core5.http.nio.support.DefaultAsyncResponseExchangeHandlerFactory;
import org.apache.hc.core5.http.protocol.HttpProcessor;
+import org.apache.hc.core5.http.protocol.RequestHandlerRegistry;
+import org.apache.hc.core5.http.protocol.UriPatternType;
import org.apache.hc.core5.http2.HttpVersionPolicy;
import org.apache.hc.core5.http2.config.H2Config;
import org.apache.hc.core5.http2.impl.Http2Processors;
@@ -66,8 +69,9 @@ import org.apache.hc.core5.util.Args;
*/
public class H2ServerBootstrap {
- private final List<HandlerEntry> handlerList;
+ private final List<HandlerEntry<Supplier<AsyncServerExchangeHandler>>> handlerList;
private String canonicalHostName;
+ private UriPatternType uriPatternType;
private IOReactorConfig ioReactorConfig;
private HttpProcessor httpProcessor;
private CharCodingConfig charCodingConfig;
@@ -186,21 +190,51 @@ public class H2ServerBootstrap {
return this;
}
+ /**
+ * Assigns {@link UriPatternType} for handler registration.
+ */
+ public final H2ServerBootstrap setUriPatternType(final UriPatternType uriPatternType) {
+ this.uriPatternType = uriPatternType;
+ return this;
+ }
+
+ /**
+ * Registers the given {@link AsyncServerExchangeHandler} {@link Supplier} as a default handler for URIs
+ * matching the given pattern.
+ *
+ * @param uriPattern the pattern to register the handler for.
+ * @param supplier the handler supplier.
+ */
public final H2ServerBootstrap register(final String uriPattern, final Supplier<AsyncServerExchangeHandler> supplier) {
Args.notBlank(uriPattern, "URI pattern");
Args.notNull(supplier, "Supplier");
- handlerList.add(new HandlerEntry(null, uriPattern, supplier));
+ handlerList.add(new HandlerEntry<>(null, uriPattern, supplier));
return this;
}
+ /**
+ * Registers the given {@link AsyncServerExchangeHandler} {@link Supplier} as a handler for URIs
+ * matching the given host and the pattern.
+ *
+ * @param hostname the host name
+ * @param uriPattern the pattern to register the handler for.
+ * @param supplier the handler supplier.
+ */
public final H2ServerBootstrap registerVirtual(final String hostname, final String uriPattern, final Supplier<AsyncServerExchangeHandler> supplier) {
Args.notBlank(hostname, "Hostname");
Args.notBlank(uriPattern, "URI pattern");
Args.notNull(supplier, "Supplier");
- handlerList.add(new HandlerEntry(hostname, uriPattern, supplier));
+ handlerList.add(new HandlerEntry<>(hostname, uriPattern, supplier));
return this;
}
+ /**
+ * Registers the given {@link AsyncServerRequestHandler} as a default handler for URIs
+ * matching the given pattern.
+ *
+ * @param uriPattern the pattern to register the handler for.
+ * @param requestHandler the handler.
+ */
public final <T> H2ServerBootstrap register(
final String uriPattern,
final AsyncServerRequestHandler<T> requestHandler) {
@@ -215,6 +249,14 @@ public class H2ServerBootstrap {
return this;
}
+ /**
+ * Registers the given {@link AsyncServerRequestHandler} as a handler for URIs
+ * matching the given host and the pattern.
+ *
+ * @param hostname the host name
+ * @param uriPattern the pattern to register the handler for.
+ * @param requestHandler the handler.
+ */
public final <T> H2ServerBootstrap registerVirtual(
final String hostname,
final String uriPattern,
@@ -231,11 +273,13 @@ public class H2ServerBootstrap {
}
public HttpAsyncServer create() {
- final AsyncServerExchangeHandlerRegistry exchangeHandlerFactory = new AsyncServerExchangeHandlerRegistry(
- canonicalHostName != null ? canonicalHostName : InetAddressUtils.getCanonicalLocalHostName());
- for (final HandlerEntry entry: handlerList) {
- exchangeHandlerFactory.register(entry.hostname, entry.uriPattern, entry.supplier);
+ final RequestHandlerRegistry<Supplier<AsyncServerExchangeHandler>> registry = new RequestHandlerRegistry<>(
+ canonicalHostName != null ? canonicalHostName : InetAddressUtils.getCanonicalLocalHostName(),
+ uriPatternType);
+ for (final HandlerEntry<Supplier<AsyncServerExchangeHandler>> entry: handlerList) {
+ registry.register(entry.hostname, entry.uriPattern, entry.handler);
}
+ final HandlerFactory<AsyncServerExchangeHandler> exchangeHandlerFactory = new DefaultAsyncResponseExchangeHandlerFactory(registry);
final ServerHttp2StreamMultiplexerFactory http2StreamHandlerFactory = new ServerHttp2StreamMultiplexerFactory(
httpProcessor != null ? httpProcessor : Http2Processors.server(),
exchangeHandlerFactory,
@@ -261,18 +305,4 @@ public class H2ServerBootstrap {
return new HttpAsyncServer(ioEventHandlerFactory, ioReactorConfig, ioSessionDecorator, sessionListener);
}
- private static class HandlerEntry {
-
- final String hostname;
- final String uriPattern;
- final Supplier<AsyncServerExchangeHandler> supplier;
-
- public HandlerEntry(final String hostname, final String uriPattern, final Supplier<AsyncServerExchangeHandler> supplier) {
- this.hostname = hostname;
- this.uriPattern = uriPattern;
- this.supplier = supplier;
- }
-
- }
-
}
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/479ad348/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/HandlerEntry.java
----------------------------------------------------------------------
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/HandlerEntry.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/HandlerEntry.java
new file mode 100644
index 0000000..caf0e68
--- /dev/null
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/HandlerEntry.java
@@ -0,0 +1,41 @@
+/*
+ * ====================================================================
+ * 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.http2.impl.nio.bootstrap;
+
+final class HandlerEntry<T> {
+
+ final String hostname;
+ final String uriPattern;
+ final T handler;
+
+ public HandlerEntry(final String hostname, final String uriPattern, final T handler) {
+ this.hostname = hostname;
+ this.uriPattern = uriPattern;
+ this.handler = handler;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/479ad348/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/nio/support/AsyncPushConsumerRegistry.java
----------------------------------------------------------------------
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/nio/support/AsyncPushConsumerRegistry.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/nio/support/AsyncPushConsumerRegistry.java
deleted file mode 100644
index b44ccf4..0000000
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/nio/support/AsyncPushConsumerRegistry.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * ====================================================================
- * 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.http2.nio.support;
-
-import java.util.Locale;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-import org.apache.hc.core5.function.Supplier;
-import org.apache.hc.core5.http.HttpException;
-import org.apache.hc.core5.http.HttpRequest;
-import org.apache.hc.core5.http.nio.AsyncPushConsumer;
-import org.apache.hc.core5.http.nio.HandlerFactory;
-import org.apache.hc.core5.http.protocol.UriPatternMatcher;
-import org.apache.hc.core5.net.URIAuthority;
-import org.apache.hc.core5.util.Args;
-
-public class AsyncPushConsumerRegistry implements HandlerFactory<AsyncPushConsumer> {
-
- private final UriPatternMatcher<Supplier<AsyncPushConsumer>> primary;
- private final ConcurrentMap<String, UriPatternMatcher<Supplier<AsyncPushConsumer>>> hostMap;
-
- public AsyncPushConsumerRegistry() {
- this.primary = new UriPatternMatcher<>();
- this.hostMap = new ConcurrentHashMap<>();
- }
-
- private UriPatternMatcher<Supplier<AsyncPushConsumer>> getPatternMatcher(final String hostname) {
- if (hostname == null) {
- return primary;
- }
- final UriPatternMatcher<Supplier<AsyncPushConsumer>> hostMatcher = hostMap.get(hostname);
- if (hostMatcher != null) {
- return hostMatcher;
- }
- return primary;
- }
-
- @Override
- public AsyncPushConsumer create(final HttpRequest request) throws HttpException {
- final URIAuthority authority = request.getAuthority();
- final String key = authority != null ? authority.getHostName().toLowerCase(Locale.ROOT) : null;
- final UriPatternMatcher<Supplier<AsyncPushConsumer>> patternMatcher = getPatternMatcher(key);
- if (patternMatcher == null) {
- return null;
- }
- String path = request.getPath();
- final int i = path.indexOf("?");
- if (i != -1) {
- path = path.substring(0, i - 1);
- }
- final Supplier<AsyncPushConsumer> supplier = patternMatcher.lookup(path);
- if (supplier != null) {
- return supplier.get();
- }
- return null;
- }
-
- public void register(final String hostname, final String uriPattern, final Supplier<AsyncPushConsumer> supplier) {
- Args.notBlank(uriPattern, "URI pattern");
- Args.notNull(supplier, "Supplier");
- if (hostname == null) {
- primary.register(uriPattern, supplier);
- } else {
- final String key = hostname.toLowerCase(Locale.ROOT);
- UriPatternMatcher<Supplier<AsyncPushConsumer>> matcher = hostMap.get(key);
- if (matcher == null) {
- final UriPatternMatcher<Supplier<AsyncPushConsumer>> newMatcher = new UriPatternMatcher<>();
- matcher = hostMap.putIfAbsent(key, newMatcher);
- if (matcher == null) {
- matcher = newMatcher;
- }
- }
- matcher.register(uriPattern, supplier);
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/479ad348/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/nio/support/DefaultAsyncPushConsumerFactory.java
----------------------------------------------------------------------
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/nio/support/DefaultAsyncPushConsumerFactory.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/nio/support/DefaultAsyncPushConsumerFactory.java
new file mode 100644
index 0000000..2e76c23
--- /dev/null
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/nio/support/DefaultAsyncPushConsumerFactory.java
@@ -0,0 +1,63 @@
+/*
+ * ====================================================================
+ * 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.http2.nio.support;
+
+import org.apache.hc.core5.function.Supplier;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.HttpRequest;
+import org.apache.hc.core5.http.HttpRequestMapper;
+import org.apache.hc.core5.http.MisdirectedRequestException;
+import org.apache.hc.core5.http.nio.AsyncPushConsumer;
+import org.apache.hc.core5.http.nio.HandlerFactory;
+import org.apache.hc.core5.http.protocol.HttpContext;
+import org.apache.hc.core5.util.Args;
+
+/**
+ * @since 5.0
+ */
+public final class DefaultAsyncPushConsumerFactory implements HandlerFactory<AsyncPushConsumer> {
+
+ private final HttpRequestMapper<Supplier<AsyncPushConsumer>> mapper;
+
+ public DefaultAsyncPushConsumerFactory(final HttpRequestMapper<Supplier<AsyncPushConsumer>> mapper) {
+ this.mapper = Args.notNull(mapper, "Request handler mapper");
+ }
+
+ @Override
+ public AsyncPushConsumer create(final HttpRequest request, final HttpContext context) throws HttpException {
+ try {
+ final Supplier<AsyncPushConsumer> supplier = mapper.resolve(request, context);
+ if (supplier != null) {
+ return supplier.get();
+ } else {
+ return null;
+ }
+ } catch (final MisdirectedRequestException ex) {
+ return null;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/479ad348/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/classic/ClassicTestServer.java
----------------------------------------------------------------------
diff --git a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/classic/ClassicTestServer.java b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/classic/ClassicTestServer.java
index 323fd2d..84937dc 100644
--- a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/classic/ClassicTestServer.java
+++ b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/classic/ClassicTestServer.java
@@ -46,15 +46,15 @@ import org.apache.hc.core5.http.impl.io.DefaultClassicHttpResponseFactory;
import org.apache.hc.core5.http.impl.io.HttpService;
import org.apache.hc.core5.http.io.HttpExpectationVerifier;
import org.apache.hc.core5.http.io.HttpRequestHandler;
-import org.apache.hc.core5.http.io.support.UriHttpRequestHandlerMapper;
import org.apache.hc.core5.http.protocol.HttpProcessor;
+import org.apache.hc.core5.http.protocol.RequestHandlerRegistry;
import org.apache.hc.core5.io.ShutdownType;
public class ClassicTestServer {
private final SSLContext sslContext;
private final SocketConfig socketConfig;
- private final UriHttpRequestHandlerMapper registry;
+ private final RequestHandlerRegistry<HttpRequestHandler> registry;
private final AtomicReference<HttpServer> serverRef;
@@ -62,7 +62,7 @@ public class ClassicTestServer {
super();
this.sslContext = sslContext;
this.socketConfig = socketConfig != null ? socketConfig : SocketConfig.DEFAULT;
- this.registry = new UriHttpRequestHandlerMapper();
+ this.registry = new RequestHandlerRegistry<>();
this.serverRef = new AtomicReference<>(null);
}
@@ -74,10 +74,12 @@ public class ClassicTestServer {
this(null, null);
}
- public void registerHandler(
- final String pattern,
- final HttpRequestHandler handler) {
- this.registry.register(pattern, handler);
+ public void registerHandler(final String pattern, final HttpRequestHandler handler) {
+ this.registry.register(null, pattern, handler);
+ }
+
+ public void registerHandlerVirtual(final String hostname, final String pattern, final HttpRequestHandler handler) {
+ this.registry.register(hostname, pattern, handler);
}
public int getPort() {
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/479ad348/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/framework/TestingFramework.java
----------------------------------------------------------------------
diff --git a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/framework/TestingFramework.java b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/framework/TestingFramework.java
index ead8792..f5ffea9 100644
--- a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/framework/TestingFramework.java
+++ b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/framework/TestingFramework.java
@@ -231,7 +231,7 @@ public class TestingFramework {
final ServerBootstrap serverBootstrap = ServerBootstrap.bootstrap()
.setSocketConfig(socketConfig)
- .registerHandler("/*", requestHandler);
+ .register("/*", requestHandler);
server = serverBootstrap.create();
try {
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/479ad348/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/Http1TestServer.java
----------------------------------------------------------------------
diff --git a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/Http1TestServer.java b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/Http1TestServer.java
index 9960d6e..9193a05 100644
--- a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/Http1TestServer.java
+++ b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/Http1TestServer.java
@@ -38,23 +38,24 @@ import org.apache.hc.core5.http.config.CharCodingConfig;
import org.apache.hc.core5.http.config.H1Config;
import org.apache.hc.core5.http.impl.DefaultConnectionReuseStrategy;
import org.apache.hc.core5.http.impl.HttpProcessors;
-import org.apache.hc.core5.http.nio.support.AsyncServerExchangeHandlerRegistry;
import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
import org.apache.hc.core5.http.nio.AsyncServerRequestHandler;
import org.apache.hc.core5.http.nio.support.BasicServerExchangeHandler;
+import org.apache.hc.core5.http.nio.support.DefaultAsyncResponseExchangeHandlerFactory;
import org.apache.hc.core5.http.protocol.HttpProcessor;
+import org.apache.hc.core5.http.protocol.RequestHandlerRegistry;
import org.apache.hc.core5.reactor.IOEventHandlerFactory;
import org.apache.hc.core5.reactor.IOReactorConfig;
import org.apache.hc.core5.reactor.ListenerEndpoint;
public class Http1TestServer extends AsyncServer {
- private final AsyncServerExchangeHandlerRegistry handlerRegistry;
+ private final RequestHandlerRegistry<Supplier<AsyncServerExchangeHandler>> registry;
private final SSLContext sslContext;
public Http1TestServer(final IOReactorConfig ioReactorConfig, final SSLContext sslContext) throws IOException {
super(ioReactorConfig);
- this.handlerRegistry = new AsyncServerExchangeHandlerRegistry("localhost");
+ this.registry = new RequestHandlerRegistry<>();
this.sslContext = sslContext;
}
@@ -63,7 +64,7 @@ public class Http1TestServer extends AsyncServer {
}
public void register(final String uriPattern, final Supplier<AsyncServerExchangeHandler> supplier) {
- handlerRegistry.register(null, uriPattern, supplier);
+ registry.register(null, uriPattern, supplier);
}
public <T> void register(
@@ -89,7 +90,7 @@ public class Http1TestServer extends AsyncServer {
public InetSocketAddress start(final HttpProcessor httpProcessor, final H1Config h1Config) throws Exception {
return start(new InternalServerHttp1EventHandlerFactory(
httpProcessor,
- handlerRegistry,
+ new DefaultAsyncResponseExchangeHandlerFactory(registry),
h1Config,
CharCodingConfig.DEFAULT,
DefaultConnectionReuseStrategy.INSTANCE,
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/479ad348/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/Http2TestClient.java
----------------------------------------------------------------------
diff --git a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/Http2TestClient.java b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/Http2TestClient.java
index 1f2f2eb..df6a56c 100644
--- a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/Http2TestClient.java
+++ b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/Http2TestClient.java
@@ -40,10 +40,11 @@ import org.apache.hc.core5.http.config.CharCodingConfig;
import org.apache.hc.core5.http.config.H1Config;
import org.apache.hc.core5.http.nio.AsyncPushConsumer;
import org.apache.hc.core5.http.protocol.HttpProcessor;
+import org.apache.hc.core5.http.protocol.RequestHandlerRegistry;
import org.apache.hc.core5.http2.HttpVersionPolicy;
import org.apache.hc.core5.http2.config.H2Config;
import org.apache.hc.core5.http2.impl.Http2Processors;
-import org.apache.hc.core5.http2.nio.support.AsyncPushConsumerRegistry;
+import org.apache.hc.core5.http2.nio.support.DefaultAsyncPushConsumerFactory;
import org.apache.hc.core5.reactor.IOEventHandlerFactory;
import org.apache.hc.core5.reactor.IOReactorConfig;
import org.apache.hc.core5.reactor.IOSession;
@@ -53,12 +54,12 @@ import org.apache.hc.core5.util.TimeValue;
public class Http2TestClient extends AsyncRequester {
private final SSLContext sslContext;
- private final AsyncPushConsumerRegistry pushConsumerRegistry;
+ private final RequestHandlerRegistry<Supplier<AsyncPushConsumer>> registry;
public Http2TestClient(final IOReactorConfig ioReactorConfig, final SSLContext sslContext) throws IOException {
super(ioReactorConfig);
this.sslContext = sslContext;
- this.pushConsumerRegistry = new AsyncPushConsumerRegistry();
+ this.registry = new RequestHandlerRegistry<>();
}
public Http2TestClient() throws IOException {
@@ -68,7 +69,7 @@ public class Http2TestClient extends AsyncRequester {
public void register(final String uriPattern, final Supplier<AsyncPushConsumer> supplier) {
Args.notNull(uriPattern, "URI pattern");
Args.notNull(supplier, "Supplier");
- pushConsumerRegistry.register(null, uriPattern, supplier);
+ registry.register(null, uriPattern, supplier);
}
public void start(final IOEventHandlerFactory handlerFactory) throws IOException {
@@ -78,7 +79,7 @@ public class Http2TestClient extends AsyncRequester {
public void start(final HttpProcessor httpProcessor, final H2Config h2Config) throws IOException {
start(new InternalClientHttp2EventHandlerFactory(
httpProcessor,
- pushConsumerRegistry,
+ new DefaultAsyncPushConsumerFactory(registry),
HttpVersionPolicy.FORCE_HTTP_2,
h2Config,
H1Config.DEFAULT,
@@ -89,7 +90,7 @@ public class Http2TestClient extends AsyncRequester {
public void start(final HttpProcessor httpProcessor, final H1Config h1Config) throws IOException {
start(new InternalClientHttp2EventHandlerFactory(
httpProcessor,
- pushConsumerRegistry,
+ new DefaultAsyncPushConsumerFactory(registry),
HttpVersionPolicy.FORCE_HTTP_1,
H2Config.DEFAULT,
h1Config,
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/479ad348/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/Http2TestServer.java
----------------------------------------------------------------------
diff --git a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/Http2TestServer.java b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/Http2TestServer.java
index 7f7cb3f..171f9c0 100644
--- a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/Http2TestServer.java
+++ b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/Http2TestServer.java
@@ -37,11 +37,12 @@ import org.apache.hc.core5.function.Supplier;
import org.apache.hc.core5.http.config.CharCodingConfig;
import org.apache.hc.core5.http.config.H1Config;
import org.apache.hc.core5.http.impl.HttpProcessors;
-import org.apache.hc.core5.http.nio.support.AsyncServerExchangeHandlerRegistry;
import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
import org.apache.hc.core5.http.nio.AsyncServerRequestHandler;
import org.apache.hc.core5.http.nio.support.BasicServerExchangeHandler;
+import org.apache.hc.core5.http.nio.support.DefaultAsyncResponseExchangeHandlerFactory;
import org.apache.hc.core5.http.protocol.HttpProcessor;
+import org.apache.hc.core5.http.protocol.RequestHandlerRegistry;
import org.apache.hc.core5.http2.HttpVersionPolicy;
import org.apache.hc.core5.http2.config.H2Config;
import org.apache.hc.core5.http2.impl.Http2Processors;
@@ -52,12 +53,12 @@ import org.apache.hc.core5.reactor.ListenerEndpoint;
public class Http2TestServer extends AsyncServer {
private final SSLContext sslContext;
- private final AsyncServerExchangeHandlerRegistry handlerRegistry;
+ private final RequestHandlerRegistry<Supplier<AsyncServerExchangeHandler>> registry;
public Http2TestServer(final IOReactorConfig ioReactorConfig, final SSLContext sslContext) throws IOException {
super(ioReactorConfig);
this.sslContext = sslContext;
- this.handlerRegistry = new AsyncServerExchangeHandlerRegistry("localhost");
+ this.registry = new RequestHandlerRegistry<>();
}
public Http2TestServer() throws IOException {
@@ -65,7 +66,7 @@ public class Http2TestServer extends AsyncServer {
}
public void register(final String uriPattern, final Supplier<AsyncServerExchangeHandler> supplier) {
- handlerRegistry.register(null, uriPattern, supplier);
+ registry.register(null, uriPattern, supplier);
}
public <T> void register(
@@ -88,7 +89,7 @@ public class Http2TestServer extends AsyncServer {
public InetSocketAddress start(final HttpProcessor httpProcessor, final H2Config h2Config) throws Exception {
start(new InternalServerHttp2EventHandlerFactory(
httpProcessor,
- handlerRegistry,
+ new DefaultAsyncResponseExchangeHandlerFactory(registry),
HttpVersionPolicy.FORCE_HTTP_2,
h2Config,
H1Config.DEFAULT,
@@ -102,7 +103,7 @@ public class Http2TestServer extends AsyncServer {
public InetSocketAddress start(final HttpProcessor httpProcessor, final H1Config h1Config) throws Exception {
start(new InternalServerHttp2EventHandlerFactory(
httpProcessor,
- handlerRegistry,
+ new DefaultAsyncResponseExchangeHandlerFactory(registry),
HttpVersionPolicy.FORCE_HTTP_1,
H2Config.DEFAULT,
h1Config,
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/479ad348/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java
----------------------------------------------------------------------
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java
index 0bc01f2..825fb6f 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java
@@ -1348,7 +1348,9 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
new HandlerFactory<AsyncServerExchangeHandler>() {
@Override
- public AsyncServerExchangeHandler create(final HttpRequest request) throws HttpException {
+ public AsyncServerExchangeHandler create(
+ final HttpRequest request,
+ final HttpContext context) throws HttpException {
return new MessageExchangeHandler<String>(new StringAsyncEntityConsumer()) {
@Override
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/479ad348/httpcore5/src/examples/org/apache/hc/core5/http/examples/ClassicFileServerExample.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/examples/org/apache/hc/core5/http/examples/ClassicFileServerExample.java b/httpcore5/src/examples/org/apache/hc/core5/http/examples/ClassicFileServerExample.java
index 0202338..1f1d7cd 100644
--- a/httpcore5/src/examples/org/apache/hc/core5/http/examples/ClassicFileServerExample.java
+++ b/httpcore5/src/examples/org/apache/hc/core5/http/examples/ClassicFileServerExample.java
@@ -120,7 +120,7 @@ public class ClassicFileServerExample {
}
})
- .registerHandler("*", new HttpFileHandler(docRoot))
+ .register("*", new HttpFileHandler(docRoot))
.create();
server.start();
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/479ad348/httpcore5/src/examples/org/apache/hc/core5/http/examples/ClassicReverseProxyExample.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/examples/org/apache/hc/core5/http/examples/ClassicReverseProxyExample.java b/httpcore5/src/examples/org/apache/hc/core5/http/examples/ClassicReverseProxyExample.java
index b5f2c34..6bb04c5 100644
--- a/httpcore5/src/examples/org/apache/hc/core5/http/examples/ClassicReverseProxyExample.java
+++ b/httpcore5/src/examples/org/apache/hc/core5/http/examples/ClassicReverseProxyExample.java
@@ -173,7 +173,7 @@ public class ClassicReverseProxyExample {
}
})
- .registerHandler("*", new ProxyHandler(targetHost, requester))
+ .register("*", new ProxyHandler(targetHost, requester))
.create();
server.start();
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/479ad348/httpcore5/src/main/java/org/apache/hc/core5/function/Factory.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/function/Factory.java b/httpcore5/src/main/java/org/apache/hc/core5/function/Factory.java
new file mode 100644
index 0000000..ea9cb95
--- /dev/null
+++ b/httpcore5/src/main/java/org/apache/hc/core5/function/Factory.java
@@ -0,0 +1,39 @@
+/*
+ * ====================================================================
+ * 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.function;
+
+/**
+ * Abstract object factory.
+ *
+ * @since 5.0
+ */
+public interface Factory<T> {
+
+ T create();
+
+}
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/479ad348/httpcore5/src/main/java/org/apache/hc/core5/http/HttpRequestMapper.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/HttpRequestMapper.java b/httpcore5/src/main/java/org/apache/hc/core5/http/HttpRequestMapper.java
new file mode 100644
index 0000000..15431ba
--- /dev/null
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/HttpRequestMapper.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;
+
+import org.apache.hc.core5.http.protocol.HttpContext;
+
+/**
+ * This class can be used to resolve an object matching a particular {@link HttpRequest}.
+ * Usually the mapped object will be a request handler to process the request.
+ *
+ * @since 5.0
+ */
+public interface HttpRequestMapper<T> {
+
+ /**
+ * Resolves a handler matching the given request.
+ *
+ * @param request the request to map to a handler
+ * @return HTTP request handler or {@code null} if no match
+ * is found.
+ */
+ T resolve(HttpRequest request, HttpContext context) throws HttpException;
+
+}
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/479ad348/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncServerBootstrap.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncServerBootstrap.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncServerBootstrap.java
index 18c9064..8e5be10 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncServerBootstrap.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncServerBootstrap.java
@@ -46,9 +46,11 @@ import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
import org.apache.hc.core5.http.nio.AsyncServerRequestHandler;
import org.apache.hc.core5.http.nio.ssl.BasicServerTlsStrategy;
import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
-import org.apache.hc.core5.http.nio.support.AsyncServerExchangeHandlerRegistry;
import org.apache.hc.core5.http.nio.support.BasicServerExchangeHandler;
+import org.apache.hc.core5.http.nio.support.DefaultAsyncResponseExchangeHandlerFactory;
import org.apache.hc.core5.http.protocol.HttpProcessor;
+import org.apache.hc.core5.http.protocol.RequestHandlerRegistry;
+import org.apache.hc.core5.http.protocol.UriPatternType;
import org.apache.hc.core5.net.InetAddressUtils;
import org.apache.hc.core5.reactor.IOEventHandlerFactory;
import org.apache.hc.core5.reactor.IOReactorConfig;
@@ -61,8 +63,9 @@ import org.apache.hc.core5.util.Args;
*/
public class AsyncServerBootstrap {
- private final List<HandlerEntry> handlerList;
+ private final List<HandlerEntry<Supplier<AsyncServerExchangeHandler>>> handlerList;
private String canonicalHostName;
+ private UriPatternType uriPatternType;
private IOReactorConfig ioReactorConfig;
private H1Config h1Config;
private CharCodingConfig charCodingConfig;
@@ -83,8 +86,6 @@ public class AsyncServerBootstrap {
/**
* Sets canonical name (fully qualified domain name) of the server.
- *
- * @since 5.0
*/
public final AsyncServerBootstrap setCanonicalHostName(final String canonicalHostName) {
this.canonicalHostName = canonicalHostName;
@@ -165,21 +166,51 @@ public class AsyncServerBootstrap {
return this;
}
+ /**
+ * Assigns {@link UriPatternType} for handler registration.
+ */
+ public final AsyncServerBootstrap setUriPatternType(final UriPatternType uriPatternType) {
+ this.uriPatternType = uriPatternType;
+ return this;
+ }
+
+ /**
+ * Registers the given {@link AsyncServerExchangeHandler} {@link Supplier} as a default handler for URIs
+ * matching the given pattern.
+ *
+ * @param uriPattern the pattern to register the handler for.
+ * @param supplier the handler supplier.
+ */
public final AsyncServerBootstrap register(final String uriPattern, final Supplier<AsyncServerExchangeHandler> supplier) {
Args.notBlank(uriPattern, "URI pattern");
Args.notNull(supplier, "Supplier");
- handlerList.add(new HandlerEntry(null, uriPattern, supplier));
+ handlerList.add(new HandlerEntry<>(null, uriPattern, supplier));
return this;
}
+ /**
+ * Registers the given {@link AsyncServerExchangeHandler} {@link Supplier} as a handler for URIs
+ * matching the given host and the pattern.
+ *
+ * @param hostname the host name
+ * @param uriPattern the pattern to register the handler for.
+ * @param supplier the handler supplier.
+ */
public final AsyncServerBootstrap registerVirtual(final String hostname, final String uriPattern, final Supplier<AsyncServerExchangeHandler> supplier) {
Args.notBlank(hostname, "Hostname");
Args.notBlank(uriPattern, "URI pattern");
Args.notNull(supplier, "Supplier");
- handlerList.add(new HandlerEntry(hostname, uriPattern, supplier));
+ handlerList.add(new HandlerEntry<>(hostname, uriPattern, supplier));
return this;
}
+ /**
+ * Registers the given {@link AsyncServerRequestHandler} as a default handler for URIs
+ * matching the given pattern.
+ *
+ * @param uriPattern the pattern to register the handler for.
+ * @param requestHandler the handler.
+ */
public final <T> AsyncServerBootstrap register(
final String uriPattern,
final AsyncServerRequestHandler<T> requestHandler) {
@@ -194,6 +225,14 @@ public class AsyncServerBootstrap {
return this;
}
+ /**
+ * Registers the given {@link AsyncServerRequestHandler} as a handler for URIs
+ * matching the given host and the pattern.
+ *
+ * @param hostname the host name
+ * @param uriPattern the pattern to register the handler for.
+ * @param requestHandler the handler.
+ */
public final <T> AsyncServerBootstrap registerVirtual(
final String hostname,
final String uriPattern,
@@ -210,14 +249,15 @@ public class AsyncServerBootstrap {
}
public HttpAsyncServer create() {
- final AsyncServerExchangeHandlerRegistry exchangeHandlerFactory = new AsyncServerExchangeHandlerRegistry(
- canonicalHostName != null ? canonicalHostName : InetAddressUtils.getCanonicalLocalHostName());
- for (final HandlerEntry entry: handlerList) {
- exchangeHandlerFactory.register(entry.hostname, entry.uriPattern, entry.supplier);
+ final RequestHandlerRegistry<Supplier<AsyncServerExchangeHandler>> registry = new RequestHandlerRegistry<>(
+ canonicalHostName != null ? canonicalHostName : InetAddressUtils.getCanonicalLocalHostName(),
+ uriPatternType);
+ for (final HandlerEntry<Supplier<AsyncServerExchangeHandler>> entry: handlerList) {
+ registry.register(entry.hostname, entry.uriPattern, entry.handler);
}
final ServerHttp1StreamDuplexerFactory streamHandlerFactory = new ServerHttp1StreamDuplexerFactory(
httpProcessor != null ? httpProcessor : HttpProcessors.server(),
- exchangeHandlerFactory,
+ new DefaultAsyncResponseExchangeHandlerFactory(registry),
h1Config != null ? h1Config : H1Config.DEFAULT,
charCodingConfig != null ? charCodingConfig : CharCodingConfig.DEFAULT,
connStrategy != null ? connStrategy : DefaultConnectionReuseStrategy.INSTANCE,
@@ -232,18 +272,4 @@ public class AsyncServerBootstrap {
return new HttpAsyncServer(ioEventHandlerFactory, ioReactorConfig, ioSessionDecorator, sessionListener);
}
- private static class HandlerEntry {
-
- final String hostname;
- final String uriPattern;
- final Supplier<AsyncServerExchangeHandler> supplier;
-
- public HandlerEntry(final String hostname, final String uriPattern, final Supplier<AsyncServerExchangeHandler> supplier) {
- this.hostname = hostname;
- this.uriPattern = uriPattern;
- this.supplier = supplier;
- }
-
- }
-
}
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/479ad348/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HandlerEntry.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HandlerEntry.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HandlerEntry.java
new file mode 100644
index 0000000..f2f4f48
--- /dev/null
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HandlerEntry.java
@@ -0,0 +1,41 @@
+/*
+ * ====================================================================
+ * 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.impl.bootstrap;
+
+final class HandlerEntry<T> {
+
+ final String hostname;
+ final String uriPattern;
+ final T handler;
+
+ public HandlerEntry(final String hostname, final String uriPattern, final T handler) {
+ this.hostname = hostname;
+ this.uriPattern = uriPattern;
+ this.handler = handler;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/479ad348/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/ServerBootstrap.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/ServerBootstrap.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/ServerBootstrap.java
index 84b4516..4bdbba7 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/ServerBootstrap.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/ServerBootstrap.java
@@ -27,8 +27,8 @@
package org.apache.hc.core5.http.impl.bootstrap;
import java.net.InetAddress;
-import java.util.LinkedHashMap;
-import java.util.Map;
+import java.util.ArrayList;
+import java.util.List;
import javax.net.ServerSocketFactory;
import javax.net.ssl.SSLContext;
@@ -52,15 +52,20 @@ import org.apache.hc.core5.http.impl.io.HttpService;
import org.apache.hc.core5.http.io.HttpConnectionFactory;
import org.apache.hc.core5.http.io.HttpExpectationVerifier;
import org.apache.hc.core5.http.io.HttpRequestHandler;
-import org.apache.hc.core5.http.io.HttpRequestHandlerMapper;
-import org.apache.hc.core5.http.io.support.UriHttpRequestHandlerMapper;
import org.apache.hc.core5.http.protocol.HttpProcessor;
+import org.apache.hc.core5.http.protocol.RequestHandlerRegistry;
+import org.apache.hc.core5.http.protocol.UriPatternType;
+import org.apache.hc.core5.net.InetAddressUtils;
+import org.apache.hc.core5.util.Args;
/**
* @since 4.4
*/
public class ServerBootstrap {
+ private final List<HandlerEntry<HttpRequestHandler>> handlerList;
+ private String canonicalHostName;
+ private UriPatternType uriPatternType;
private int listenerPort;
private InetAddress localAddress;
private SocketConfig socketConfig;
@@ -69,8 +74,6 @@ public class ServerBootstrap {
private HttpProcessor httpProcessor;
private ConnectionReuseStrategy connStrategy;
private HttpResponseFactory<ClassicHttpResponse> responseFactory;
- private HttpRequestHandlerMapper handlerMapper;
- private Map<String, HttpRequestHandler> handlerMap;
private HttpExpectationVerifier expectationVerifier;
private ServerSocketFactory serverSocketFactory;
private SSLContext sslContext;
@@ -80,6 +83,7 @@ public class ServerBootstrap {
private Http1StreamListener streamListener;
private ServerBootstrap() {
+ this.handlerList = new ArrayList<>();
}
public static ServerBootstrap bootstrap() {
@@ -87,6 +91,16 @@ public class ServerBootstrap {
}
/**
+ * Sets canonical name (fully qualified domain name) of the server.
+ *
+ * @since 5.0
+ */
+ public final ServerBootstrap setCanonicalHostName(final String canonicalHostName) {
+ this.canonicalHostName = canonicalHostName;
+ return this;
+ }
+
+ /**
* Sets listener port number.
*/
public final ServerBootstrap setListenerPort(final int listenerPort) {
@@ -151,31 +165,40 @@ public class ServerBootstrap {
}
/**
- * Assigns {@link HttpRequestHandlerMapper} instance.
+ * Assigns {@link UriPatternType} for handler registration.
*/
- public final ServerBootstrap setHandlerMapper(final HttpRequestHandlerMapper handlerMapper) {
- this.handlerMapper = handlerMapper;
+ public final ServerBootstrap setUriPatternType(final UriPatternType uriPatternType) {
+ this.uriPatternType = uriPatternType;
return this;
}
/**
- * Registers the given {@link HttpRequestHandler} as a handler for URIs
+ * Registers the given {@link HttpRequestHandler} as a default handler for URIs
* matching the given pattern.
- * <p>
- * Please note this value can be overridden by the {@link #setHandlerMapper(
- *HttpRequestHandlerMapper)} method.
*
- * @param pattern the pattern to register the handler for.
- * @param handler the handler.
+ * @param uriPattern the pattern to register the handler for.
+ * @param requestHandler the handler.
*/
- public final ServerBootstrap registerHandler(final String pattern, final HttpRequestHandler handler) {
- if (pattern == null || handler == null) {
- return this;
- }
- if (handlerMap == null) {
- handlerMap = new LinkedHashMap<>();
- }
- handlerMap.put(pattern, handler);
+ public final ServerBootstrap register(final String uriPattern, final HttpRequestHandler requestHandler) {
+ Args.notBlank(uriPattern, "URI pattern");
+ Args.notNull(requestHandler, "Supplier");
+ handlerList.add(new HandlerEntry<>(null, uriPattern, requestHandler));
+ return this;
+ }
+
+ /**
+ * Registers the given {@link HttpRequestHandler} as a handler for URIs
+ * matching the given host and the pattern.
+ *
+ * @param hostname
+ * @param uriPattern the pattern to register the handler for.
+ * @param requestHandler the handler.
+ */
+ public final ServerBootstrap registerVirtual(final String hostname, final String uriPattern, final HttpRequestHandler requestHandler) {
+ Args.notBlank(hostname, "Hostname");
+ Args.notBlank(uriPattern, "URI pattern");
+ Args.notNull(requestHandler, "Supplier");
+ handlerList.add(new HandlerEntry<>(hostname, uriPattern, requestHandler));
return this;
}
@@ -240,23 +263,18 @@ public class ServerBootstrap {
}
public HttpServer create() {
+ final RequestHandlerRegistry<HttpRequestHandler> requestHandlerRegistry = new RequestHandlerRegistry<>(
+ canonicalHostName != null ? canonicalHostName : InetAddressUtils.getCanonicalLocalHostName(),
+ uriPatternType);
+ for (final HandlerEntry<HttpRequestHandler> entry: handlerList) {
+ requestHandlerRegistry.register(entry.hostname, entry.uriPattern, entry.handler);
+ }
HttpProcessor httpProcessorCopy = this.httpProcessor;
if (httpProcessorCopy == null) {
httpProcessorCopy = HttpProcessors.server();
}
- HttpRequestHandlerMapper handlerMapperCopy = this.handlerMapper;
- if (handlerMapperCopy == null) {
- final UriHttpRequestHandlerMapper reqistry = new UriHttpRequestHandlerMapper();
- if (handlerMap != null) {
- for (final Map.Entry<String, HttpRequestHandler> entry: handlerMap.entrySet()) {
- reqistry.register(entry.getKey(), entry.getValue());
- }
- }
- handlerMapperCopy = reqistry;
- }
-
ConnectionReuseStrategy connStrategyCopy = this.connStrategy;
if (connStrategyCopy == null) {
connStrategyCopy = DefaultConnectionReuseStrategy.INSTANCE;
@@ -268,7 +286,7 @@ public class ServerBootstrap {
}
final HttpService httpService = new HttpService(
- httpProcessorCopy, connStrategyCopy, responseFactoryCopy, handlerMapperCopy,
+ httpProcessorCopy, connStrategyCopy, responseFactoryCopy, requestHandlerRegistry,
this.expectationVerifier, this.streamListener);
ServerSocketFactory serverSocketFactoryCopy = this.serverSocketFactory;
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/479ad348/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/HttpService.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/HttpService.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/HttpService.java
index 216d1f4..ae6057f 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/HttpService.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/HttpService.java
@@ -40,6 +40,7 @@ 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.HttpRequestMapper;
import org.apache.hc.core5.http.HttpResponseFactory;
import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.core5.http.MethodNotSupportedException;
@@ -51,7 +52,6 @@ import org.apache.hc.core5.http.impl.DefaultConnectionReuseStrategy;
import org.apache.hc.core5.http.impl.Http1StreamListener;
import org.apache.hc.core5.http.io.HttpExpectationVerifier;
import org.apache.hc.core5.http.io.HttpRequestHandler;
-import org.apache.hc.core5.http.io.HttpRequestHandlerMapper;
import org.apache.hc.core5.http.io.HttpServerConnection;
import org.apache.hc.core5.http.io.entity.StringEntity;
import org.apache.hc.core5.http.protocol.HttpContext;
@@ -69,7 +69,7 @@ import org.apache.hc.core5.util.Args;
* individual {@link HttpRequestHandler}s are expected to implement
* application specific content generation and processing.
* <p>
- * {@code HttpService} uses {@link HttpRequestHandlerMapper} to map
+ * {@code HttpService} uses {@link HttpRequestMapper} to map
* matching request handler for a particular request URI of an incoming HTTP
* request.
* <p>
@@ -82,7 +82,7 @@ import org.apache.hc.core5.util.Args;
public class HttpService {
private final HttpProcessor processor;
- private final HttpRequestHandlerMapper handlerMapper;
+ private final HttpRequestMapper<HttpRequestHandler> handlerMapper;
private final ConnectionReuseStrategy connReuseStrategy;
private final HttpResponseFactory<ClassicHttpResponse> responseFactory;
private final HttpExpectationVerifier expectationVerifier;
@@ -105,7 +105,7 @@ public class HttpService {
final HttpProcessor processor,
final ConnectionReuseStrategy connReuseStrategy,
final HttpResponseFactory<ClassicHttpResponse> responseFactory,
- final HttpRequestHandlerMapper handlerMapper,
+ final HttpRequestMapper<HttpRequestHandler> handlerMapper,
final HttpExpectationVerifier expectationVerifier,
final Http1StreamListener streamListener) {
super();
@@ -135,7 +135,7 @@ public class HttpService {
final HttpProcessor processor,
final ConnectionReuseStrategy connReuseStrategy,
final HttpResponseFactory<ClassicHttpResponse> responseFactory,
- final HttpRequestHandlerMapper handlerMapper) {
+ final HttpRequestMapper<HttpRequestHandler> handlerMapper) {
this(processor, connReuseStrategy, responseFactory, handlerMapper, null, null);
}
@@ -148,7 +148,7 @@ public class HttpService {
* @since 4.3
*/
public HttpService(
- final HttpProcessor processor, final HttpRequestHandlerMapper handlerMapper) {
+ final HttpProcessor processor, final HttpRequestMapper<HttpRequestHandler> handlerMapper) {
this(processor, null, null, handlerMapper);
}
@@ -314,7 +314,7 @@ public class HttpService {
final HttpContext context) throws HttpException, IOException {
HttpRequestHandler handler = null;
if (this.handlerMapper != null) {
- handler = this.handlerMapper.lookup(request, context);
+ handler = this.handlerMapper.resolve(request, context);
}
if (handler != null) {
handler.handle(request, response, context);
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/479ad348/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamHandler.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamHandler.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamHandler.java
index 7b2b698..2dd95e7 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamHandler.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamHandler.java
@@ -238,7 +238,7 @@ class ServerHttp1StreamHandler implements ResourceHolder {
AsyncServerExchangeHandler handler;
try {
- handler = exchangeHandlerFactory.create(request);
+ handler = exchangeHandlerFactory.create(request, context);
} catch (final MisdirectedRequestException ex) {
handler = new ImmediateResponseExchangeHandler(HttpStatus.SC_MISDIRECTED_REQUEST, ex.getMessage());
} catch (final HttpException ex) {
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/479ad348/httpcore5/src/main/java/org/apache/hc/core5/http/io/HttpRequestHandlerMapper.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/io/HttpRequestHandlerMapper.java b/httpcore5/src/main/java/org/apache/hc/core5/http/io/HttpRequestHandlerMapper.java
deleted file mode 100644
index 4fc2c17..0000000
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/io/HttpRequestHandlerMapper.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * ====================================================================
- * 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 org.apache.hc.core5.http.HttpRequest;
-import org.apache.hc.core5.http.protocol.HttpContext;
-
-/**
- * HttpRequestHandlerMapper can be used to resolve an instance of
- * {@link HttpRequestHandler} matching a particular {@link HttpRequest}. Usually the
- * mapped request handler will be used to process the request.
- *
- * @since 4.3
- */
-public interface HttpRequestHandlerMapper {
-
- /**
- * Looks up a handler matching the given request.
- *
- * @param request the request to map to a handler
- * @return HTTP request handler or {@code null} if no match
- * is found.
- *
- * @since 5.0
- */
- HttpRequestHandler lookup(HttpRequest request, HttpContext context);
-
-}
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/479ad348/httpcore5/src/main/java/org/apache/hc/core5/http/io/support/UriHttpRequestHandlerMapper.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/io/support/UriHttpRequestHandlerMapper.java b/httpcore5/src/main/java/org/apache/hc/core5/http/io/support/UriHttpRequestHandlerMapper.java
deleted file mode 100644
index ec3d62c..0000000
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/io/support/UriHttpRequestHandlerMapper.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * ====================================================================
- * 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 org.apache.hc.core5.annotation.Contract;
-import org.apache.hc.core5.annotation.ThreadingBehavior;
-import org.apache.hc.core5.http.HttpRequest;
-import org.apache.hc.core5.http.io.HttpRequestHandler;
-import org.apache.hc.core5.http.io.HttpRequestHandlerMapper;
-import org.apache.hc.core5.http.protocol.HttpContext;
-import org.apache.hc.core5.http.protocol.LookupRegistry;
-import org.apache.hc.core5.http.protocol.UriPatternMatcher;
-import org.apache.hc.core5.util.Args;
-
-/**
- * Maintains a map of HTTP request handlers keyed by a request URI pattern.
- * <br>
- * Patterns may have three formats:
- * <ul>
- * <li>{@code *}</li>
- * <li>{@code *<uri>}</li>
- * <li>{@code <uri>*}</li>
- * </ul>
- * <br>
- * This class can be used to map an instance of
- * {@link HttpRequestHandler} matching a particular request URI. Usually the
- * mapped request handler will be used to process the request with the
- * specified request URI.
- *
- * @since 4.3
- */
-@Contract(threading = ThreadingBehavior.SAFE)
-public class UriHttpRequestHandlerMapper implements HttpRequestHandlerMapper {
-
- private final LookupRegistry<HttpRequestHandler> matcher;
-
- public UriHttpRequestHandlerMapper(final LookupRegistry<HttpRequestHandler> matcher) {
- super();
- this.matcher = Args.notNull(matcher, "Pattern matcher");
- }
-
- public UriHttpRequestHandlerMapper() {
- this(new UriPatternMatcher<HttpRequestHandler>());
- }
-
- /**
- * Registers the given {@link HttpRequestHandler} as a handler for URIs
- * matching the given pattern.
- *
- * @param pattern the pattern to register the handler for.
- * @param handler the handler.
- */
- public void register(final String pattern, final HttpRequestHandler handler) {
- Args.notNull(pattern, "Pattern");
- Args.notNull(handler, "Handler");
- matcher.register(pattern, handler);
- }
-
- /**
- * Removes registered handler, if exists, for the given pattern.
- *
- * @param pattern the pattern to unregister the handler for.
- */
- public void unregister(final String pattern) {
- matcher.unregister(pattern);
- }
-
- /**
- * Extracts request path from the given {@link HttpRequest}
- */
- protected String getRequestPath(final HttpRequest request) {
- String uriPath = request.getPath();
- int index = uriPath.indexOf("?");
- if (index != -1) {
- uriPath = uriPath.substring(0, index);
- } else {
- index = uriPath.indexOf("#");
- if (index != -1) {
- uriPath = uriPath.substring(0, index);
- }
- }
- return uriPath;
- }
-
- /**
- * Looks up a handler matching the given request URI.
- *
- * @param request the request
- * @return handler or {@code null} if no match is found.
- */
- @Override
- public HttpRequestHandler lookup(final HttpRequest request, final HttpContext context) {
- Args.notNull(request, "HTTP request");
- return matcher.lookup(getRequestPath(request));
- }
-
-}
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/479ad348/httpcore5/src/main/java/org/apache/hc/core5/http/nio/AsyncServerRequestHandler.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/AsyncServerRequestHandler.java b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/AsyncServerRequestHandler.java
index 91ed25a..a59471e 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/AsyncServerRequestHandler.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/AsyncServerRequestHandler.java
@@ -37,7 +37,7 @@ import org.apache.hc.core5.http.protocol.HttpContext;
/**
* @since 5.0
*/
-@Contract(threading = ThreadingBehavior.SAFE)
+@Contract(threading = ThreadingBehavior.STATELESS)
public interface AsyncServerRequestHandler<T> {
AsyncRequestConsumer<T> prepare(HttpRequest request, HttpContext context) throws HttpException;
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/479ad348/httpcore5/src/main/java/org/apache/hc/core5/http/nio/HandlerFactory.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/HandlerFactory.java b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/HandlerFactory.java
index a367dd7..abcbf8c 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/HandlerFactory.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/HandlerFactory.java
@@ -28,6 +28,7 @@ package org.apache.hc.core5.http.nio;
import org.apache.hc.core5.http.HttpException;
import org.apache.hc.core5.http.HttpRequest;
+import org.apache.hc.core5.http.protocol.HttpContext;
/**
* Abstract handler factory.
@@ -38,6 +39,6 @@ import org.apache.hc.core5.http.HttpRequest;
*/
public interface HandlerFactory<T extends ResourceHolder> {
- T create(HttpRequest request) throws HttpException;
+ T create(HttpRequest request, HttpContext context) throws HttpException;
}
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/479ad348/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/AsyncServerExchangeHandlerRegistry.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/AsyncServerExchangeHandlerRegistry.java b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/AsyncServerExchangeHandlerRegistry.java
deleted file mode 100644
index a37d8e7..0000000
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/AsyncServerExchangeHandlerRegistry.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * ====================================================================
- * 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.util.Locale;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-import org.apache.hc.core5.function.Supplier;
-import org.apache.hc.core5.http.HttpException;
-import org.apache.hc.core5.http.HttpRequest;
-import org.apache.hc.core5.http.HttpStatus;
-import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
-import org.apache.hc.core5.http.nio.HandlerFactory;
-import org.apache.hc.core5.http.protocol.UriPatternMatcher;
-import org.apache.hc.core5.net.URIAuthority;
-import org.apache.hc.core5.util.Args;
-
-public class AsyncServerExchangeHandlerRegistry implements HandlerFactory<AsyncServerExchangeHandler> {
-
- private final static String LOCALHOST = "localhost";
-
- private final String canonicalHostName;
- private final UriPatternMatcher<Supplier<AsyncServerExchangeHandler>> primary;
- private final ConcurrentMap<String, UriPatternMatcher<Supplier<AsyncServerExchangeHandler>>> virtualMap;
-
- public AsyncServerExchangeHandlerRegistry(final String canonicalHostName) {
- this.canonicalHostName = Args.notNull(canonicalHostName, "Canonical hostname").toLowerCase(Locale.ROOT);
- this.primary = new UriPatternMatcher<>();
- this.virtualMap = new ConcurrentHashMap<>();
- }
-
- private UriPatternMatcher<Supplier<AsyncServerExchangeHandler>> getPatternMatcher(final String hostname) {
- if (hostname == null) {
- return primary;
- }
- if (hostname.equals(canonicalHostName) || hostname.equals(LOCALHOST)) {
- return primary;
- }
- return virtualMap.get(hostname);
- }
-
- @Override
- public AsyncServerExchangeHandler create(final HttpRequest request) throws HttpException {
- final URIAuthority authority = request.getAuthority();
- final String key = authority != null ? authority.getHostName().toLowerCase(Locale.ROOT) : null;
- final UriPatternMatcher<Supplier<AsyncServerExchangeHandler>> patternMatcher = getPatternMatcher(key);
- if (patternMatcher == null) {
- return new ImmediateResponseExchangeHandler(HttpStatus.SC_MISDIRECTED_REQUEST, "Not authoritative");
- }
- String path = request.getPath();
- final int i = path.indexOf("?");
- if (i != -1) {
- path = path.substring(0, i);
- }
- final Supplier<AsyncServerExchangeHandler> supplier = patternMatcher.lookup(path);
- if (supplier != null) {
- return supplier.get();
- }
- return new ImmediateResponseExchangeHandler(HttpStatus.SC_NOT_FOUND, "Resource not found");
- }
-
- public void register(final String hostname, final String uriPattern, final Supplier<AsyncServerExchangeHandler> supplier) {
- Args.notBlank(uriPattern, "URI pattern");
- Args.notNull(supplier, "Supplier");
- final String key = hostname != null ? hostname.toLowerCase(Locale.ROOT) : null;
- if (hostname == null || hostname.equals(canonicalHostName) || hostname.equals(LOCALHOST)) {
- primary.register(uriPattern, supplier);
- } else {
- UriPatternMatcher<Supplier<AsyncServerExchangeHandler>> matcher = virtualMap.get(key);
- if (matcher == null) {
- final UriPatternMatcher<Supplier<AsyncServerExchangeHandler>> newMatcher = new UriPatternMatcher<>();
- matcher = virtualMap.putIfAbsent(key, newMatcher);
- if (matcher == null) {
- matcher = newMatcher;
- }
- }
- matcher.register(uriPattern, supplier);
- }
- }
-
-}