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 2007/02/11 00:46:16 UTC
svn commit: r505797 - in /jakarta/httpcomponents/httpcore/trunk: ./
module-nio/src/examples/org/apache/http/nio/ module-niossl/
module-niossl/src/ module-niossl/src/examples/
module-niossl/src/examples/org/ module-niossl/src/examples/org/apache/
module...
Author: olegk
Date: Sat Feb 10 15:46:14 2007
New Revision: 505797
URL: http://svn.apache.org/viewvc?view=rev&rev=505797
Log:
Initial commit of the NIO SSL extensions
Added:
jakarta/httpcomponents/httpcore/trunk/module-niossl/
jakarta/httpcomponents/httpcore/trunk/module-niossl/pom.xml (with props)
jakarta/httpcomponents/httpcore/trunk/module-niossl/src/
jakarta/httpcomponents/httpcore/trunk/module-niossl/src/examples/
jakarta/httpcomponents/httpcore/trunk/module-niossl/src/examples/org/
jakarta/httpcomponents/httpcore/trunk/module-niossl/src/examples/org/apache/
jakarta/httpcomponents/httpcore/trunk/module-niossl/src/examples/org/apache/http/
jakarta/httpcomponents/httpcore/trunk/module-niossl/src/examples/org/apache/http/examples/
jakarta/httpcomponents/httpcore/trunk/module-niossl/src/examples/org/apache/http/examples/nio/
jakarta/httpcomponents/httpcore/trunk/module-niossl/src/examples/org/apache/http/examples/nio/NHttpSSLServer.java (with props)
jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/
jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/
jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/
jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/
jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/
jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/
jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/nio/
jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/nio/reactor/
jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/nio/reactor/SSLClientIOEventDispatch.java (with props)
jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/nio/reactor/SSLIOSession.java (with props)
jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/nio/reactor/SSLServerIOEventDispatch.java (with props)
jakarta/httpcomponents/httpcore/trunk/module-niossl/src/test/
jakarta/httpcomponents/httpcore/trunk/module-niossl/src/test/java/
jakarta/httpcomponents/httpcore/trunk/module-niossl/src/test/java/org/
jakarta/httpcomponents/httpcore/trunk/module-niossl/src/test/java/org/apache/
jakarta/httpcomponents/httpcore/trunk/module-niossl/src/test/java/org/apache/http/
jakarta/httpcomponents/httpcore/trunk/module-niossl/src/test/java/org/apache/http/impl/
jakarta/httpcomponents/httpcore/trunk/module-niossl/src/test/java/org/apache/http/impl/nio/
jakarta/httpcomponents/httpcore/trunk/module-niossl/src/test/java/org/apache/http/impl/nio/reactor/
jakarta/httpcomponents/httpcore/trunk/module-niossl/src/test/resources/
jakarta/httpcomponents/httpcore/trunk/module-niossl/src/test/resources/test.keystore (with props)
Removed:
jakarta/httpcomponents/httpcore/trunk/module-nio/src/examples/org/apache/http/nio/
Modified:
jakarta/httpcomponents/httpcore/trunk/pom.xml
Added: jakarta/httpcomponents/httpcore/trunk/module-niossl/pom.xml
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-niossl/pom.xml?view=auto&rev=505797
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-niossl/pom.xml (added)
+++ jakarta/httpcomponents/httpcore/trunk/module-niossl/pom.xml Sat Feb 10 15:46:14 2007
@@ -0,0 +1,131 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ $HeadURL$
+ $Revision$
+ $Date$
+
+ ====================================================================
+ 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/>.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpcore</artifactId>
+ <version>4.0-alpha4-SNAPSHOT</version>
+ </parent>
+ <artifactId>jakarta-httpcore-niossl</artifactId>
+ <name>HttpCore (NIO SSL extensions module)</name>
+ <inceptionYear>2005</inceptionYear>
+ <description>
+ HttpComponents Core (NIO SSL extensions)
+ </description>
+ <url>http://jakarta.apache.org/httpcomponents/httpcore</url>
+ <packaging>jar</packaging>
+
+ <licenses>
+ <license>
+ <name>Apache License</name>
+ <url>../LICENSE.txt</url>
+ <distribution>repo</distribution>
+ </license>
+ </licenses>
+
+ <scm>
+ <connection>scm:svn:http://svn.apache.org/repos/asf/jakarta/httpcomponents/httpcore/trunk/module-niossl</connection>
+ <developerConnection>scm:svn:http://svn.apache.org/repos/asf/jakarta/httpcomponents/httpcore/trunk/module-niossl</developerConnection>
+ <url>http://svn.apache.org/repos/asf/jakarta/httpcomponents/httpcore/trunk/module-niossl</url>
+ </scm>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>jakarta-httpcore</artifactId>
+ <version>${pom.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>jakarta-httpcore-nio</artifactId>
+ <version>${pom.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <properties>
+ <maven.compile.source>1.5</maven.compile.source>
+ <maven.compile.target>1.5</maven.compile.target>
+ <maven.compile.optimize>true</maven.compile.optimize>
+ <maven.compile.deprecation>true</maven.compile.deprecation>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>${maven.compile.source}</source>
+ <target>${maven.compile.target}</target>
+ <optimize>${maven.compile.optimize}</optimize>
+ <showDeprecations>${maven.compile.deprecation}</showDeprecations>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>**/TestAll.java</include>
+ </includes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <reporting>
+ <plugins>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-project-info-reports-plugin</artifactId>
+ <reportSets>
+ <reportSet>
+ <reports>
+ <report>dependencies</report>
+ <report>issue-tracking</report>
+ <report>scm</report>
+ </reports>
+ </reportSet>
+ </reportSets>
+ </plugin>
+
+ </plugins>
+ </reporting>
+
+</project>
Propchange: jakarta/httpcomponents/httpcore/trunk/module-niossl/pom.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/httpcomponents/httpcore/trunk/module-niossl/pom.xml
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: jakarta/httpcomponents/httpcore/trunk/module-niossl/pom.xml
------------------------------------------------------------------------------
svn:mime-type = text/xml
Added: jakarta/httpcomponents/httpcore/trunk/module-niossl/src/examples/org/apache/http/examples/nio/NHttpSSLServer.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-niossl/src/examples/org/apache/http/examples/nio/NHttpSSLServer.java?view=auto&rev=505797
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-niossl/src/examples/org/apache/http/examples/nio/NHttpSSLServer.java (added)
+++ jakarta/httpcomponents/httpcore/trunk/module-niossl/src/examples/org/apache/http/examples/nio/NHttpSSLServer.java Sat Feb 10 15:46:14 2007
@@ -0,0 +1,247 @@
+/*
+ * $HeadURL$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ * 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.http.examples.nio;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.security.KeyStore;
+
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpEntityEnclosingRequest;
+import org.apache.http.HttpException;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.MethodNotSupportedException;
+import org.apache.http.entity.ContentProducer;
+import org.apache.http.entity.EntityTemplate;
+import org.apache.http.entity.FileEntity;
+import org.apache.http.impl.DefaultConnectionReuseStrategy;
+import org.apache.http.impl.DefaultHttpResponseFactory;
+import org.apache.http.impl.params.DefaultHttpParams;
+import org.apache.http.impl.nio.reactor.DefaultListeningIOReactor;
+import org.apache.http.impl.nio.reactor.SSLServerIOEventDispatch;
+import org.apache.http.nio.protocol.EventListener;
+import org.apache.http.nio.protocol.BufferingHttpServiceHandler;
+import org.apache.http.nio.reactor.IOEventDispatch;
+import org.apache.http.nio.reactor.ListeningIOReactor;
+import org.apache.http.params.HttpConnectionParams;
+import org.apache.http.params.HttpParams;
+import org.apache.http.params.HttpProtocolParams;
+import org.apache.http.protocol.BasicHttpProcessor;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpRequestHandler;
+import org.apache.http.protocol.HttpRequestHandlerRegistry;
+import org.apache.http.protocol.ResponseConnControl;
+import org.apache.http.protocol.ResponseContent;
+import org.apache.http.protocol.ResponseDate;
+import org.apache.http.protocol.ResponseServer;
+import org.apache.http.util.EntityUtils;
+
+public class NHttpSSLServer {
+
+ public static void main(String[] args) throws Exception {
+ if (args.length < 1) {
+ System.err.println("Please specify document root directory");
+ System.exit(1);
+ }
+
+ ClassLoader cl = NHttpSSLServer.class.getClassLoader();
+ URL url = cl.getResource("test.keystore");
+ KeyStore keystore = KeyStore.getInstance("jks");
+ keystore.load(url.openStream(), "nopassword".toCharArray());
+ KeyManagerFactory kmfactory = KeyManagerFactory.getInstance(
+ KeyManagerFactory.getDefaultAlgorithm());
+ kmfactory.init(keystore, "nopassword".toCharArray());
+ KeyManager[] keymanagers = kmfactory.getKeyManagers();
+ SSLContext sslcontext = SSLContext.getInstance("TLS");
+ sslcontext.init(keymanagers, null, null);
+
+ HttpParams params = new DefaultHttpParams(null);
+ params
+ .setIntParameter(HttpConnectionParams.SO_TIMEOUT, 5000)
+ .setIntParameter(HttpConnectionParams.SOCKET_BUFFER_SIZE, 8 * 1024)
+ .setBooleanParameter(HttpConnectionParams.STALE_CONNECTION_CHECK, false)
+ .setBooleanParameter(HttpConnectionParams.TCP_NODELAY, true)
+ .setParameter(HttpProtocolParams.ORIGIN_SERVER, "Jakarta-HttpComponents-NIO/1.1");
+
+ BasicHttpProcessor httpproc = new BasicHttpProcessor();
+ httpproc.addInterceptor(new ResponseDate());
+ httpproc.addInterceptor(new ResponseServer());
+ httpproc.addInterceptor(new ResponseContent());
+ httpproc.addInterceptor(new ResponseConnControl());
+
+ BufferingHttpServiceHandler handler = new BufferingHttpServiceHandler(
+ httpproc,
+ new DefaultHttpResponseFactory(),
+ new DefaultConnectionReuseStrategy(),
+ params);
+
+ // Set up request handlers
+ HttpRequestHandlerRegistry reqistry = new HttpRequestHandlerRegistry();
+ reqistry.register("*", new HttpFileHandler(args[0]));
+
+ handler.setHandlerResolver(reqistry);
+
+ // Provide an event logger
+ handler.setEventListener(new EventLogger());
+
+ IOEventDispatch ioEventDispatch = new SSLServerIOEventDispatch(
+ handler,
+ sslcontext,
+ params);
+
+ ListeningIOReactor ioReactor = new DefaultListeningIOReactor(2, params);
+ try {
+ ioReactor.listen(new InetSocketAddress(8080));
+ ioReactor.execute(ioEventDispatch);
+ } catch (InterruptedIOException ex) {
+ System.err.println("Interrupted");
+ } catch (IOException e) {
+ System.err.println("I/O error: " + e.getMessage());
+ }
+ System.out.println("Shutdown");
+ }
+
+ static class HttpFileHandler implements HttpRequestHandler {
+
+ private final String docRoot;
+
+ public HttpFileHandler(final String docRoot) {
+ super();
+ this.docRoot = docRoot;
+ }
+
+ public void handle(
+ final HttpRequest request,
+ final HttpResponse response,
+ final HttpContext context) throws HttpException, IOException {
+
+ String method = request.getRequestLine().getMethod().toUpperCase();
+ if (!method.equals("GET") && !method.equals("HEAD") && !method.equals("POST")) {
+ throw new MethodNotSupportedException(method + " method not supported");
+ }
+
+ if (request instanceof HttpEntityEnclosingRequest) {
+ HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity();
+ byte[] entityContent = EntityUtils.toByteArray(entity);
+ System.out.println("Incoming entity content (bytes): " + entityContent.length);
+ }
+
+ String target = request.getRequestLine().getUri();
+ final File file = new File(this.docRoot, URLDecoder.decode(target, "UTF-8"));
+ if (!file.exists()) {
+
+ response.setStatusCode(HttpStatus.SC_NOT_FOUND);
+ EntityTemplate body = new EntityTemplate(new ContentProducer() {
+
+ public void writeTo(final OutputStream outstream) throws IOException {
+ OutputStreamWriter writer = new OutputStreamWriter(outstream, "UTF-8");
+ writer.write("<html><body><h1>");
+ writer.write("File ");
+ writer.write(file.getPath());
+ writer.write(" not found");
+ writer.write("</h1></body></html>");
+ writer.flush();
+ }
+
+ });
+ body.setContentType("text/html; charset=UTF-8");
+ response.setEntity(body);
+ System.out.println("File " + file.getPath() + " not found");
+
+ } else if (!file.canRead() || file.isDirectory()) {
+
+ response.setStatusCode(HttpStatus.SC_FORBIDDEN);
+ EntityTemplate body = new EntityTemplate(new ContentProducer() {
+
+ public void writeTo(final OutputStream outstream) throws IOException {
+ OutputStreamWriter writer = new OutputStreamWriter(outstream, "UTF-8");
+ writer.write("<html><body><h1>");
+ writer.write("Access denied");
+ writer.write("</h1></body></html>");
+ writer.flush();
+ }
+
+ });
+ body.setContentType("text/html; charset=UTF-8");
+ response.setEntity(body);
+ System.out.println("Cannot read file " + file.getPath());
+
+ } else {
+
+ response.setStatusCode(HttpStatus.SC_OK);
+ FileEntity body = new FileEntity(file, "text/html");
+ response.setEntity(body);
+ System.out.println("Serving file " + file.getPath());
+
+ }
+ }
+
+ }
+
+ static class EventLogger implements EventListener {
+
+ public void connectionOpen(final InetAddress address) {
+ System.out.println("Connection open: " + address);
+ }
+
+ public void connectionTimeout(final InetAddress address) {
+ System.out.println("Connection timed out: " + address);
+ }
+
+ public void connectionClosed(InetAddress address) {
+ System.out.println("Connection closed: " + address);
+ }
+
+ public void fatalIOException(IOException ex) {
+ System.err.println("I/O error: " + ex.getMessage());
+ }
+
+ public void fatalProtocolException(HttpException ex) {
+ System.err.println("HTTP error: " + ex.getMessage());
+ }
+
+ }
+
+}
Propchange: jakarta/httpcomponents/httpcore/trunk/module-niossl/src/examples/org/apache/http/examples/nio/NHttpSSLServer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/httpcomponents/httpcore/trunk/module-niossl/src/examples/org/apache/http/examples/nio/NHttpSSLServer.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: jakarta/httpcomponents/httpcore/trunk/module-niossl/src/examples/org/apache/http/examples/nio/NHttpSSLServer.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/nio/reactor/SSLClientIOEventDispatch.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/nio/reactor/SSLClientIOEventDispatch.java?view=auto&rev=505797
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/nio/reactor/SSLClientIOEventDispatch.java (added)
+++ jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/nio/reactor/SSLClientIOEventDispatch.java Sat Feb 10 15:46:14 2007
@@ -0,0 +1,156 @@
+/*
+ * $HeadURL$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ * 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.http.impl.nio.reactor;
+
+import java.io.IOException;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLException;
+
+import org.apache.http.impl.DefaultHttpResponseFactory;
+import org.apache.http.impl.nio.DefaultNHttpClientConnection;
+import org.apache.http.nio.NHttpClientHandler;
+import org.apache.http.nio.reactor.IOEventDispatch;
+import org.apache.http.nio.reactor.IOSession;
+import org.apache.http.params.HttpParams;
+
+public class SSLClientIOEventDispatch implements IOEventDispatch {
+
+ private static final String NHTTP_CONN = "NHTTP_CONN";
+ private static final String SSL_SESSION = "SSL_SESSION";
+
+ private final NHttpClientHandler handler;
+ private final HttpParams params;
+ private final SSLContext sslcontext;
+
+ public SSLClientIOEventDispatch(
+ final NHttpClientHandler handler,
+ final SSLContext sslcontext,
+ final HttpParams params) {
+ super();
+ if (handler == null) {
+ throw new IllegalArgumentException("HTTP client handler may not be null");
+ }
+ if (sslcontext == null) {
+ throw new IllegalArgumentException("SSL context may not be null");
+ }
+ if (params == null) {
+ throw new IllegalArgumentException("HTTP parameters may not be null");
+ }
+ this.handler = handler;
+ this.params = params;
+ this.sslcontext = sslcontext;
+ }
+
+ public void connected(final IOSession session) {
+
+ SSLIOSession sslSession = new SSLIOSession(
+ session,
+ this.sslcontext);
+
+ DefaultNHttpClientConnection conn = new DefaultNHttpClientConnection(
+ sslSession,
+ new DefaultHttpResponseFactory(),
+ this.params);
+
+ session.setAttribute(NHTTP_CONN, conn);
+ session.setAttribute(SSL_SESSION, sslSession);
+
+ Object attachment = session.getAttribute(IOSession.ATTACHMENT_KEY);
+ this.handler.connected(conn, attachment);
+
+ try {
+ sslSession.initialize(true);
+ } catch (SSLException ex) {
+ this.handler.exception(conn, ex);
+ sslSession.shutdown();
+ }
+ }
+
+ public void disconnected(final IOSession session) {
+ DefaultNHttpClientConnection conn = (DefaultNHttpClientConnection) session.getAttribute(
+ NHTTP_CONN);
+
+ this.handler.closed(conn);
+ }
+
+ public void inputReady(final IOSession session) {
+ DefaultNHttpClientConnection conn = (DefaultNHttpClientConnection) session.getAttribute(
+ NHTTP_CONN);
+ SSLIOSession sslSession = (SSLIOSession) session.getAttribute(
+ SSL_SESSION);
+ try {
+ synchronized (sslSession) {
+ while (sslSession.isAppInputReady()) {
+ conn.consumeInput(this.handler);
+ }
+ sslSession.inboundTransport();
+ }
+ } catch (IOException ex) {
+ this.handler.exception(conn, ex);
+ sslSession.shutdown();
+ }
+ }
+
+ public void outputReady(final IOSession session) {
+ DefaultNHttpClientConnection conn = (DefaultNHttpClientConnection) session.getAttribute(
+ NHTTP_CONN);
+ SSLIOSession sslSession = (SSLIOSession) session.getAttribute(
+ SSL_SESSION);
+ try {
+ synchronized (sslSession) {
+ if (sslSession.isAppOutputReady()) {
+ conn.produceOutput(this.handler);
+ }
+ sslSession.outboudTransport();
+ }
+ } catch (IOException ex) {
+ this.handler.exception(conn, ex);
+ sslSession.shutdown();
+ }
+ }
+
+ public void timeout(final IOSession session) {
+ DefaultNHttpClientConnection conn = (DefaultNHttpClientConnection) session.getAttribute(
+ NHTTP_CONN);
+ SSLIOSession sslSession = (SSLIOSession) session.getAttribute(
+ SSL_SESSION);
+ this.handler.timeout(conn);
+ synchronized (sslSession) {
+ if (sslSession.isOutboundDone() && !sslSession.isInboundDone()) {
+ // The session failed to terminate cleanly
+ sslSession.shutdown();
+ }
+ }
+ }
+
+}
Propchange: jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/nio/reactor/SSLClientIOEventDispatch.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/nio/reactor/SSLClientIOEventDispatch.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/nio/reactor/SSLClientIOEventDispatch.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/nio/reactor/SSLIOSession.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/nio/reactor/SSLIOSession.java?view=auto&rev=505797
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/nio/reactor/SSLIOSession.java (added)
+++ jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/nio/reactor/SSLIOSession.java Sat Feb 10 15:46:14 2007
@@ -0,0 +1,430 @@
+/*
+ * $HeadURL$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ * 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.http.impl.nio.reactor;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.ByteChannel;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLEngineResult.HandshakeStatus;
+import javax.net.ssl.SSLEngineResult.Status;
+
+import org.apache.http.nio.reactor.EventMask;
+import org.apache.http.nio.reactor.IOSession;
+import org.apache.http.nio.reactor.SessionBufferStatus;
+
+/**
+ * A decorator class intended to transparently extend an {@link IOSession}
+ * with transport layer security capabilities based on the SSL/TLS protocol.
+ *
+ * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
+ */
+public class SSLIOSession implements IOSession, SessionBufferStatus {
+
+ private final IOSession session;
+ private final SSLEngine sslEngine;
+ private final ByteBuffer inEncrypted;
+ private final ByteBuffer outEncrypted;
+ private final ByteBuffer inPlain;
+ private final ByteBuffer outPlain;
+ private final InternalByteChannel channel;
+
+ private int appEventMask;
+ private SessionBufferStatus appBufferStatus;
+
+ private volatile boolean closed;
+
+ public SSLIOSession(
+ final IOSession session,
+ final SSLContext sslContext) {
+ super();
+ if (session == null) {
+ throw new IllegalArgumentException("IO session may not be null");
+ }
+ if (sslContext == null) {
+ throw new IllegalArgumentException("SSL context may not be null");
+ }
+ this.session = session;
+ this.appEventMask = session.getEventMask();
+ this.channel = new InternalByteChannel();
+
+ // Override the status buffer interface
+ this.session.setBufferStatus(this);
+
+ SocketAddress address = session.getRemoteAddress();
+ if (address instanceof InetSocketAddress) {
+ String hostname = ((InetSocketAddress) address).getHostName();
+ int port = ((InetSocketAddress) address).getPort();
+ this.sslEngine = sslContext.createSSLEngine(hostname, port);
+ } else {
+ this.sslEngine = sslContext.createSSLEngine();
+ }
+
+ // Allocate buffers for network (encrypted) data
+ int netBuffersize = this.sslEngine.getSession().getPacketBufferSize();
+ this.inEncrypted = ByteBuffer.allocateDirect(netBuffersize);
+ this.outEncrypted = ByteBuffer.allocateDirect(netBuffersize);
+
+ // Allocate buffers for application (unencrypted) data
+ int appBuffersize = this.sslEngine.getSession().getApplicationBufferSize();
+ this.inPlain = ByteBuffer.allocateDirect(appBuffersize);
+ this.outPlain = ByteBuffer.allocateDirect(appBuffersize);
+ }
+
+ public synchronized void initialize(boolean clientMode) throws SSLException {
+ this.sslEngine.setUseClientMode(clientMode);
+ this.sslEngine.beginHandshake();
+ doHandshake();
+ }
+
+ private void doHandshake() throws SSLException {
+ boolean handshaking = true;
+
+ SSLEngineResult result;
+ while (handshaking) {
+ switch (this.sslEngine.getHandshakeStatus()) {
+ case NEED_WRAP:
+ // Generate outgoing handshake data
+ this.outPlain.flip();
+ result = this.sslEngine.wrap(this.outPlain, this.outEncrypted);
+ this.outPlain.compact();
+ if (result.getStatus() != Status.OK) {
+ handshaking = false;
+ }
+ if (result.getStatus() == Status.CLOSED) {
+ this.closed = true;
+ }
+ break;
+ case NEED_UNWRAP:
+ // Process incoming handshake data
+ this.inEncrypted.flip();
+ result = this.sslEngine.unwrap(this.inEncrypted, this.inPlain);
+ this.inEncrypted.compact();
+ if (result.getStatus() != Status.OK) {
+ handshaking = false;
+ }
+ if (result.getStatus() == Status.CLOSED) {
+ this.closed = true;
+ }
+ break;
+ case NEED_TASK:
+ Runnable r = this.sslEngine.getDelegatedTask();
+ r.run();
+ break;
+ case NOT_HANDSHAKING:
+ handshaking = false;
+ break;
+ }
+ }
+ }
+
+ private void updateEventMask() {
+ // Need to toggle the event mask for this channel?
+ int oldMask = this.session.getEventMask();
+ int newMask = oldMask;
+ switch (this.sslEngine.getHandshakeStatus()) {
+ case NEED_WRAP:
+ newMask = EventMask.READ_WRITE;
+ break;
+ case NEED_UNWRAP:
+ newMask = EventMask.READ;
+ break;
+ case NOT_HANDSHAKING:
+ newMask = this.appEventMask;
+ break;
+ }
+
+ // Do we have encrypted data ready to be sent?
+ if (this.outEncrypted.position() > 0) {
+ newMask = newMask | EventMask.WRITE;
+ }
+
+ // Update the mask if necessary
+ if (oldMask != newMask) {
+ this.session.setEventMask(newMask);
+ }
+ }
+
+ private int sendEncryptedData() throws IOException {
+ this.outEncrypted.flip();
+ int bytesWritten = this.session.channel().write(this.outEncrypted);
+ this.outEncrypted.compact();
+
+ if (this.sslEngine.isInboundDone() && this.sslEngine.isOutboundDone()) {
+ this.session.close();
+ }
+ return bytesWritten;
+ }
+
+ private int receiveEncryptedData() throws IOException {
+ int bytesRead = this.session.channel().read(this.inEncrypted);
+ if (bytesRead == -1) {
+ this.session.close();
+ }
+ if (this.sslEngine.isInboundDone() && this.sslEngine.isOutboundDone()) {
+ this.session.close();
+ }
+ return bytesRead;
+ }
+
+ private boolean decryptData() throws SSLException {
+ boolean decrypted = false;
+ if (this.inEncrypted.position() > 0) {
+ this.inEncrypted.flip();
+ SSLEngineResult result = this.sslEngine.unwrap(this.inEncrypted, this.inPlain);
+ this.inEncrypted.compact();
+ if (result.getStatus() == Status.CLOSED) {
+ this.closed = true;
+ }
+ if (result.getStatus() == Status.OK) {
+ decrypted = true;
+ }
+ }
+ return decrypted;
+ }
+
+ public synchronized boolean isAppInputReady() throws IOException {
+ int bytesRead = receiveEncryptedData();
+ if (bytesRead == -1) {
+ return false;
+ }
+ doHandshake();
+ decryptData();
+ return this.inPlain.position() > 0;
+ }
+
+ public synchronized boolean isAppOutputReady() throws IOException {
+ return !this.closed
+ && this.sslEngine.getHandshakeStatus() == HandshakeStatus.NOT_HANDSHAKING;
+ }
+
+ public synchronized void inboundTransport() throws IOException {
+ updateEventMask();
+ }
+
+ public synchronized void outboudTransport() throws IOException {
+ sendEncryptedData();
+ doHandshake();
+ updateEventMask();
+ }
+
+ private synchronized int wrap(final ByteBuffer src) throws SSLException {
+ if (src == null) {
+ throw new IllegalArgumentException("Byte buffer may not be null");
+ }
+ if (this.closed) {
+ return -1;
+ }
+ if (this.outPlain.position() > 0) {
+ this.outPlain.flip();
+ this.sslEngine.wrap(this.outPlain, this.outEncrypted);
+ this.outPlain.compact();
+ }
+ if (this.outPlain.position() == 0) {
+ SSLEngineResult result = this.sslEngine.wrap(src, this.outEncrypted);
+ if (result.getStatus() == Status.CLOSED) {
+ this.closed = true;
+ }
+ return result.bytesConsumed();
+ } else {
+ return 0;
+ }
+ }
+
+ private synchronized int unwrap(final ByteBuffer dst) throws SSLException {
+ if (dst == null) {
+ throw new IllegalArgumentException("Byte buffer may not be null");
+ }
+ if (this.closed) {
+ return -1;
+ }
+ if (this.inPlain.position() > 0) {
+ this.inPlain.flip();
+ int n = Math.min(this.inPlain.remaining(), dst.remaining());
+ for (int i = 0; i < n; i++) {
+ dst.put(this.inPlain.get());
+ }
+ this.inPlain.compact();
+ return n;
+ } else {
+ return 0;
+ }
+ }
+
+ public void close() {
+ if (this.closed) {
+ return;
+ }
+ this.closed = true;
+ synchronized(this) {
+ this.sslEngine.closeOutbound();
+ updateEventMask();
+ }
+ }
+
+ public boolean isClosed() {
+ return this.closed;
+ }
+
+ public synchronized boolean isInboundDone() {
+ return this.sslEngine.isInboundDone();
+ }
+
+ public synchronized boolean isOutboundDone() {
+ return this.sslEngine.isOutboundDone();
+ }
+
+ public void shutdown() {
+ this.closed = true;
+ this.session.close();
+ }
+
+ public ByteChannel channel() {
+ return this.channel;
+ }
+
+ public SocketAddress getLocalAddress() {
+ return this.session.getLocalAddress();
+ }
+
+ public SocketAddress getRemoteAddress() {
+ return this.session.getRemoteAddress();
+ }
+
+ public synchronized int getEventMask() {
+ return this.appEventMask;
+ }
+
+ public synchronized void setEventMask(int ops) {
+ this.appEventMask = ops;
+ updateEventMask();
+ }
+
+ public synchronized void setEvent(int op) {
+ this.appEventMask = this.appEventMask | op;
+ updateEventMask();
+ }
+
+ public synchronized void clearEvent(int op) {
+ this.appEventMask = this.appEventMask & ~op;
+ updateEventMask();
+ }
+
+ public int getSocketTimeout() {
+ return this.session.getSocketTimeout();
+ }
+
+ public void setSocketTimeout(int timeout) {
+ this.session.setSocketTimeout(timeout);
+ }
+
+ public synchronized boolean hasBufferedInput() {
+ return this.appBufferStatus.hasBufferedInput()
+ || this.inEncrypted.position() > 0
+ || this.inPlain.position() > 0;
+ }
+
+ public synchronized boolean hasBufferedOutput() {
+ return this.appBufferStatus.hasBufferedOutput()
+ || this.outEncrypted.position() > 0
+ || this.outPlain.position() > 0;
+ }
+
+ public synchronized void setBufferStatus(final SessionBufferStatus status) {
+ this.appBufferStatus = status;
+ }
+
+ public Object getAttribute(final String name) {
+ return this.session.getAttribute(name);
+ }
+
+ public Object removeAttribute(final String name) {
+ return this.session.removeAttribute(name);
+ }
+
+ public void setAttribute(final String name, final Object obj) {
+ this.session.setAttribute(name, obj);
+ }
+
+ // These methods can be used by super classes to query the state of the SSL session
+
+ protected HandshakeStatus getHandshakeStatus() {
+ return this.sslEngine.getHandshakeStatus();
+ }
+
+ protected int getSessionEventMask() {
+ return this.session.getEventMask();
+ }
+
+ protected int getInEncryptedLength() {
+ return this.inEncrypted.position();
+ }
+
+ protected int getOutEncryptedLength() {
+ return this.outEncrypted.position();
+ }
+
+ protected int getInPlainLength() {
+ return this.inPlain.position();
+ }
+
+ protected int getOutPlainLength() {
+ return this.outPlain.position();
+ }
+
+ private class InternalByteChannel implements ByteChannel {
+
+ public int write(final ByteBuffer src) throws IOException {
+ return wrap(src);
+ }
+
+ public int read(final ByteBuffer dst) throws IOException {
+ return unwrap(dst);
+ }
+
+ public void close() throws IOException {
+ close();
+ }
+
+ public boolean isOpen() {
+ return !isClosed();
+ }
+
+ }
+
+}
Propchange: jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/nio/reactor/SSLIOSession.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/nio/reactor/SSLIOSession.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/nio/reactor/SSLIOSession.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/nio/reactor/SSLServerIOEventDispatch.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/nio/reactor/SSLServerIOEventDispatch.java?view=auto&rev=505797
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/nio/reactor/SSLServerIOEventDispatch.java (added)
+++ jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/nio/reactor/SSLServerIOEventDispatch.java Sat Feb 10 15:46:14 2007
@@ -0,0 +1,154 @@
+/*
+ * $HeadURL$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ * 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.http.impl.nio.reactor;
+
+import java.io.IOException;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLException;
+
+import org.apache.http.impl.DefaultHttpRequestFactory;
+import org.apache.http.impl.nio.DefaultNHttpServerConnection;
+import org.apache.http.nio.NHttpServiceHandler;
+import org.apache.http.nio.reactor.IOEventDispatch;
+import org.apache.http.nio.reactor.IOSession;
+import org.apache.http.params.HttpParams;
+
+public class SSLServerIOEventDispatch implements IOEventDispatch {
+
+ private static final String NHTTP_CONN = "NHTTP_CONN";
+ private static final String SSL_SESSION = "SSL_SESSION";
+
+ private final NHttpServiceHandler handler;
+ private final SSLContext sslcontext;
+ private final HttpParams params;
+
+ public SSLServerIOEventDispatch(
+ final NHttpServiceHandler handler,
+ final SSLContext sslcontext,
+ final HttpParams params) {
+ super();
+ if (handler == null) {
+ throw new IllegalArgumentException("HTTP service handler may not be null");
+ }
+ if (sslcontext == null) {
+ throw new IllegalArgumentException("SSL context may not be null");
+ }
+ if (params == null) {
+ throw new IllegalArgumentException("HTTP parameters may not be null");
+ }
+ this.handler = handler;
+ this.params = params;
+ this.sslcontext = sslcontext;
+ }
+
+ public void connected(final IOSession session) {
+
+ SSLIOSession sslSession = new SSLIOSession(
+ session,
+ this.sslcontext);
+
+ DefaultNHttpServerConnection conn = new DefaultNHttpServerConnection(
+ sslSession,
+ new DefaultHttpRequestFactory(),
+ this.params);
+
+ session.setAttribute(NHTTP_CONN, conn);
+ session.setAttribute(SSL_SESSION, sslSession);
+
+ this.handler.connected(conn);
+
+ try {
+ sslSession.initialize(false);
+ } catch (SSLException ex) {
+ this.handler.exception(conn, ex);
+ sslSession.shutdown();
+ }
+ }
+
+ public void disconnected(final IOSession session) {
+ DefaultNHttpServerConnection conn = (DefaultNHttpServerConnection) session.getAttribute(
+ NHTTP_CONN);
+ this.handler.closed(conn);
+ }
+
+ public void inputReady(final IOSession session) {
+ DefaultNHttpServerConnection conn = (DefaultNHttpServerConnection) session.getAttribute(
+ NHTTP_CONN);
+ SSLIOSession sslSession = (SSLIOSession) session.getAttribute(
+ SSL_SESSION);
+ try {
+ synchronized (sslSession) {
+ if (sslSession.isAppInputReady()) {
+ conn.consumeInput(this.handler);
+ }
+ sslSession.inboundTransport();
+ }
+ } catch (IOException ex) {
+ this.handler.exception(conn, ex);
+ sslSession.shutdown();
+ }
+ }
+
+ public void outputReady(final IOSession session) {
+ DefaultNHttpServerConnection conn = (DefaultNHttpServerConnection) session.getAttribute(
+ NHTTP_CONN);
+ SSLIOSession sslSession = (SSLIOSession) session.getAttribute(
+ SSL_SESSION);
+ try {
+ synchronized (sslSession) {
+ if (sslSession.isAppOutputReady()) {
+ conn.produceOutput(this.handler);
+ }
+ sslSession.outboudTransport();
+ }
+ } catch (IOException ex) {
+ this.handler.exception(conn, ex);
+ sslSession.shutdown();
+ }
+ }
+
+ public void timeout(final IOSession session) {
+ DefaultNHttpServerConnection conn = (DefaultNHttpServerConnection) session.getAttribute(
+ NHTTP_CONN);
+ SSLIOSession sslSession = (SSLIOSession) session.getAttribute(
+ SSL_SESSION);
+ this.handler.timeout(conn);
+ synchronized (sslSession) {
+ if (sslSession.isOutboundDone() && !sslSession.isInboundDone()) {
+ // The session failed to cleanly terminate
+ sslSession.shutdown();
+ }
+ }
+ }
+
+}
Propchange: jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/nio/reactor/SSLServerIOEventDispatch.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/nio/reactor/SSLServerIOEventDispatch.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/nio/reactor/SSLServerIOEventDispatch.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: jakarta/httpcomponents/httpcore/trunk/module-niossl/src/test/resources/test.keystore
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-niossl/src/test/resources/test.keystore?view=auto&rev=505797
==============================================================================
Binary file - no diff available.
Propchange: jakarta/httpcomponents/httpcore/trunk/module-niossl/src/test/resources/test.keystore
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Modified: jakarta/httpcomponents/httpcore/trunk/pom.xml
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/pom.xml?view=diff&rev=505797&r1=505796&r2=505797
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/pom.xml (original)
+++ jakarta/httpcomponents/httpcore/trunk/pom.xml Sat Feb 10 15:46:14 2007
@@ -71,6 +71,7 @@
<modules>
<module>module-main</module>
<module>module-nio</module>
+ <module>module-niossl</module>
</modules>
<build>