├── .gitignore
├── conf
├── aliases.conf
├── keystore.jks
├── log4j.properties
└── server.xml
├── lib
├── simpleXML.jar
├── log4j-1.2.16.jar
├── servlet-api-3.0.jar
├── slf4j-api-1.6.1.jar
├── slf4j-log4j12-1.6.1.jar
├── jetty-io-8.0.1.v20110908.jar
├── jetty-http-8.0.1.v20110908.jar
├── jetty-server-8.0.1.v20110908.jar
├── jetty-util-8.0.1.v20110908.jar
├── jetty-websocket-8.0.1.v20110908.jar
└── jetty-continuation-8.0.1.v20110908.jar
├── NOTICE
├── java
└── de
│ └── rwth_aachen
│ └── dbis
│ └── wsxmppgateway
│ ├── WebSocketConstants.java
│ ├── connection
│ ├── WsConnectionState.java
│ └── WsXMPPConnectionHandler.java
│ ├── exception
│ └── StreamErrorException.java
│ ├── error
│ └── StreamError.java
│ ├── WebSocketXmppGateway.java
│ └── XMPPConstants.java
├── www
└── testbed.html
├── README
└── LICENSE
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .classpath
3 | .project
4 | bin
5 |
--------------------------------------------------------------------------------
/conf/aliases.conf:
--------------------------------------------------------------------------------
1 | # aliases.conf
2 | googlemail.com=talk.google.com
--------------------------------------------------------------------------------
/conf/keystore.jks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hocken/wxg/HEAD/conf/keystore.jks
--------------------------------------------------------------------------------
/lib/simpleXML.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hocken/wxg/HEAD/lib/simpleXML.jar
--------------------------------------------------------------------------------
/lib/log4j-1.2.16.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hocken/wxg/HEAD/lib/log4j-1.2.16.jar
--------------------------------------------------------------------------------
/lib/servlet-api-3.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hocken/wxg/HEAD/lib/servlet-api-3.0.jar
--------------------------------------------------------------------------------
/lib/slf4j-api-1.6.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hocken/wxg/HEAD/lib/slf4j-api-1.6.1.jar
--------------------------------------------------------------------------------
/lib/slf4j-log4j12-1.6.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hocken/wxg/HEAD/lib/slf4j-log4j12-1.6.1.jar
--------------------------------------------------------------------------------
/lib/jetty-io-8.0.1.v20110908.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hocken/wxg/HEAD/lib/jetty-io-8.0.1.v20110908.jar
--------------------------------------------------------------------------------
/lib/jetty-http-8.0.1.v20110908.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hocken/wxg/HEAD/lib/jetty-http-8.0.1.v20110908.jar
--------------------------------------------------------------------------------
/lib/jetty-server-8.0.1.v20110908.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hocken/wxg/HEAD/lib/jetty-server-8.0.1.v20110908.jar
--------------------------------------------------------------------------------
/lib/jetty-util-8.0.1.v20110908.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hocken/wxg/HEAD/lib/jetty-util-8.0.1.v20110908.jar
--------------------------------------------------------------------------------
/lib/jetty-websocket-8.0.1.v20110908.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hocken/wxg/HEAD/lib/jetty-websocket-8.0.1.v20110908.jar
--------------------------------------------------------------------------------
/lib/jetty-continuation-8.0.1.v20110908.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hocken/wxg/HEAD/lib/jetty-continuation-8.0.1.v20110908.jar
--------------------------------------------------------------------------------
/NOTICE:
--------------------------------------------------------------------------------
1 | WebSocket XMPP Gateway
2 | Copyright 2011 Christian Hocken, Dominik Renzel,
3 | Chair of Computer Science 5 (Information Systems) at RWTH Aachen University, Germany
4 |
5 | This product includes software developed at
6 | The Apache Software Foundation (http://www.apache.org/).
7 |
8 | This product makes use of SLF4J developed at
9 | Quality Open Software (qos.ch), distributed under the MIT license.
10 |
11 | This software was developed at the
12 | Chair of Computer Science 5 (Information Systems) at RWTH Aachen University, Germany.
13 |
--------------------------------------------------------------------------------
/conf/log4j.properties:
--------------------------------------------------------------------------------
1 | log4j.rootLogger=DEBUG, file
2 | log4j.logger.org.eclipse.jetty=INFO, file
3 |
4 | log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
5 | log4j.appender.file.File=log/wxg.log
6 | log4j.appender.file.layout=org.apache.log4j.PatternLayout
7 | log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %-5p %x - %m\n
8 |
9 | #log4j.rootLogger=DEBUG, stdout, file
10 | #log4j.logger.org.eclipse.jetty=INFO, stdout
11 |
12 | #log4j.appender.stdout=org.apache.log4j.ConsoleAppender
13 | #log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
14 | #log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %-5p %x - %m\n
--------------------------------------------------------------------------------
/conf/server.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | 8080
8 |
9 | 8090
10 |
11 | 300000
12 |
13 | conf/keystore.jks/
14 |
15 | 123456
16 |
17 | www
18 |
19 | true
20 |
--------------------------------------------------------------------------------
/java/de/rwth_aachen/dbis/wsxmppgateway/WebSocketConstants.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 Christian Hocken, Dominik Renzel,
3 | * Chair of Computer Science 5 (Information Systems) at RWTH Aachen University, Germany.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package de.rwth_aachen.dbis.wsxmppgateway;
18 |
19 | /**
20 | * Constants defined in the WebSockets protocol
21 | * @author Christian Hocken (hocken@dbis.rwth-aachen.de)
22 | */
23 | public class WebSocketConstants {
24 |
25 | public static final int CLOSE_NORMAL = 1000;
26 | public static final int CLOSE_GOING_DOWN = 1001;
27 | public static final int CLOSE_PROTOCOL_ERROR = 1002;
28 | public static final int CLOSE_WRONG_ENCODING = 1003;
29 | public static final int CLOSE_MESSAGESIZE_EXCEEDED = 1004;
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/java/de/rwth_aachen/dbis/wsxmppgateway/connection/WsConnectionState.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 Christian Hocken, Dominik Renzel,
3 | * Chair of Computer Science 5 (Information Systems) at RWTH Aachen University, Germany.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package de.rwth_aachen.dbis.wsxmppgateway.connection;
18 |
19 | /**
20 | * Constants that represent the life cycle of an XMPP connection
21 | * @author Christian Hocken (hocken@dbis.rwth-aachen.de)
22 | */
23 | public class WsConnectionState {
24 |
25 | public static final int CONNECTED = 0;
26 | public static final int HANDSHAKE_COMPLETE = 100;
27 | public static final int HEADER_READ = 200;
28 | public static final int STREAM_OPENED = 300;
29 | public static final int STREAM_CLOSED = 400;
30 | public static final int DISCONNECTED = 500;
31 | }
32 |
--------------------------------------------------------------------------------
/java/de/rwth_aachen/dbis/wsxmppgateway/exception/StreamErrorException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 Christian Hocken, Dominik Renzel,
3 | * Chair of Computer Science 5 (Information Systems) at RWTH Aachen University, Germany.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package de.rwth_aachen.dbis.wsxmppgateway.exception;
18 |
19 | import de.rwth_aachen.dbis.wsxmppgateway.XMPPConstants;
20 | import de.rwth_aachen.dbis.wsxmppgateway.error.StreamError;
21 |
22 | /**
23 | * A throwable wrapper for class {@link StreamError}
24 | * @see XMPPConstants
25 | * @author Patrick Schlebusch (schlebu@dbis.rwth-aachen.de) & Christian Hocken (hocken@dbis.rwth-aachen.de)
26 | */
27 | public class StreamErrorException extends Exception {
28 |
29 | /**
30 | * generated serial version UID
31 | */
32 | private static final long serialVersionUID = -8885817580289448845L;
33 | private StreamError streamError;
34 |
35 | /**
36 | * Creates a new stream error exception
37 | * @param code the error code according to {@link XMPPConstants}
38 | */
39 | public StreamErrorException(int code) {
40 | streamError = new StreamError(code);
41 | }
42 |
43 | /**
44 | * Creates a new stream error exception
45 | * @param code the error code according to {@link XMPPConstants}
46 | * @param message A message that can be passed to the recipient
47 | * @param language The language of the message. Valid values are "de", "en", "fr", etc.
48 | */
49 | public StreamErrorException(int code, String message,
50 | String language) {
51 | super(message);
52 | streamError = new StreamError(code, message, language);
53 | }
54 |
55 | /**
56 | * Get the wrapped stream error
57 | * @return The wrapped stream error
58 | */
59 | public StreamError getStreamError() {
60 | return streamError;
61 | }
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/java/de/rwth_aachen/dbis/wsxmppgateway/error/StreamError.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 Christian Hocken, Dominik Renzel,
3 | * Chair of Computer Science 5 (Information Systems) at RWTH Aachen University, Germany.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package de.rwth_aachen.dbis.wsxmppgateway.error;
18 |
19 | import de.rwth_aachen.dbis.wsxmppgateway.XMPPConstants;
20 |
21 | /**
22 | * StreamError is a wrapper class for an XMPP stream error
23 | * @see XMPPConstants
24 | * @author Patrick Schlebusch (schlebu@dbis.rwth-aachen.de) & Christian Hocken (hocken@dbis.rwth-aachen.de)
25 | */
26 | public class StreamError {
27 | private int code;
28 | private String message;
29 | private String language;
30 | private String appContent;
31 |
32 | /**
33 | * Creates a new stream error
34 | * @param code the error code according to {@link XMPPConstants}
35 | */
36 | public StreamError(int code) {
37 | this.code = code;
38 | }
39 |
40 | /**
41 | * Creates a new stream error
42 | * @param code the error code according to {@link XMPPConstants}
43 | * @param message A message that can be passed to the recipient
44 | * @param language The language of the message. Valid values are "de", "en", "fr", etc.
45 | */
46 | public StreamError(int code, String message, String language) {
47 | this.code = code;
48 | this.message = message;
49 | this.language = language;
50 | }
51 |
52 | /**
53 | * Creates a new stream error
54 | * @param code the error code according to {@link XMPPConstants}
55 | * @param message A message that can be passed to the recipient
56 | * @param language The language of the message. Valid values are "de", "en", "fr", etc.
57 | * @param appContent an additional message filled by XEP handlers
58 | */
59 | public StreamError(int code, String message, String language, String appContent) {
60 | this(code, message, language);
61 | this.appContent = appContent;
62 | }
63 |
64 | /**
65 | * Get the error code
66 | * @return The error code according to {@link XMPPConstants}
67 | */
68 | public int getCode() {
69 | return code;
70 | }
71 |
72 | /**
73 | * Get the message
74 | * @return The message if set, otherwise null
75 | */
76 | public String getMessage() {
77 | return message;
78 | }
79 |
80 | /**
81 | * Get the language of the message
82 | * @return The language of the message if set, otherwise null
83 | */
84 | public String getLanguage() {
85 | return language;
86 | }
87 |
88 | /**
89 | * Get the application content
90 | * @return The application content if set, otherwise null
91 | */
92 | public String getAppContent() {
93 | return appContent;
94 | }
95 |
96 | /**
97 | *
98 | * @return true if the message has been set
99 | */
100 | public boolean hasMessage() {
101 | return (message != null);
102 | }
103 |
104 | /**
105 | *
106 | * @return true if the language of the message has been set
107 | */
108 | public boolean hasLanguage() {
109 | return (language != null);
110 | }
111 |
112 | /**
113 | *
114 | * @return true if the application content has been set
115 | */
116 | public boolean hasAppContent() {
117 | return (appContent != null);
118 | }
119 |
120 | }
121 |
--------------------------------------------------------------------------------
/www/testbed.html:
--------------------------------------------------------------------------------
1 |
2 |
79 |
87 |
88 |
89 |
90 |
91 |
--------------------------------------------------------------------------------
/README:
--------------------------------------------------------------------------------
1 | WebSocket XMPP Gateway (WXG) - README
2 | =====================================
3 | WXG (pronounce as "Wixig") is a Java-implementation of a gateway enabling communication
4 | with native XMPP[1] servers over the WebSocket protocol[2] and API[3], as specified in [4].
5 |
6 | Until now, one of the common techniques in using XMPP in JS-powered Web applications was
7 | to make use of BOSH[5] and XMPP over BOSH[6]. However, with the advent of the WebSocket
8 | protocol and API already widely available in modern Web browsers, the unstable and slow
9 | BOSH technique should be replaced. Currently, most XMPP servers are not equipped with
10 | connectors for receiving and delivering stanzas over the WebSocket protocol as specified in [4].
11 |
12 | The following scheme shows the basic functionality of WXG:
13 |
14 | Client <----> ws(xmpp) <----> WXG <----> xmpp <----> XMPP Server
15 |
16 | As such, WXG realizes two basic use cases:
17 |
18 | 1) When a client sends an XMPP stanza encapsulated in a WebSocket message, WXG "unpacks" the
19 | stanza and forwards it to the XMPP server natively.
20 |
21 | 2) When an XMPP server directs a stanza to one of its clients, WXG receives the native stanza,
22 | wraps it into a WebSocket message and forwards it to the client.
23 |
24 | In the following we describe how to build, configure, and run WXG.
25 |
26 | Prerequisites
27 | =============
28 | - for running WXG, an installed Java Runtime Environment is required.
29 | - for building WXG, an installed Java SDK is required.
30 | - for performing automated builds of WXG, an installation of Apache Ant (http://ant.apache.org/)
31 | is required to run the bundled build script.
32 |
33 | Check-out and build WXG
34 | =======================
35 |
36 | Perform the following steps to build WXG:
37 |
38 | 1) check out a copy of the git repository from github
39 |
40 | git clone git@github.com:hocken/wxg
41 |
42 | 2) change to the root directory of the WXG working copy
43 |
44 | cd wxg
45 |
46 | 3) perform an automated build using Apache Ant
47 |
48 | ant
49 |
50 | The result of the building process is a JAR file wxg.jar
51 |
52 | Configure WXG
53 | =============
54 |
55 | Perform the following steps to configure WXG:
56 |
57 | 1) change to the conf directory relative to the WXG root directory
58 |
59 | cd ${WXG_HOME}/conf
60 |
61 | 2) edit the configuration file "server.xml" to your needs
62 |
63 | All configurable parameters are documented in the configuration file.
64 |
65 | Run WXG
66 | =======
67 |
68 | Perform the following steps to run WXG:
69 |
70 | 1) change to the WXG root directory
71 |
72 | 2) run WXG
73 |
74 | java -jar wxg.jar
75 |
76 | Access WXG from client-side
77 | ==========================
78 |
79 | Open a new WebSocket and point it to ws://${WXG_HOSTNAME}:${WXG_PORT} where ${WXG_HOSTNAME} is the IP address
80 | or the hostname of the interface WXG is bound to and ${WXG_PORT} is the port specified in conf/server.xml.
81 | Keep in mind that according to [4] "xmpp" must be registered as subprotocol in the WebSocket object.
82 | WXG waits until the opening stream tag arrives and then reads the "to" attribute. Three options are available
83 | to define the hostname of the XMPP server to which the stream should be forwared:
84 |
85 | 1) Pass the desired hostname and port in the WebSocket URL
86 | Example: ws://localhost:8080/?xmpphost=jabber.com&xmppport=5222
87 |
88 | 2) Use the aliases db in conf/aliases.conf to rewrite the hostname set in the "to"
89 | attribute of the opening stream tag
90 |
91 | 3) Use the hostname set in the "to" attribute of the opening stream tag
92 |
93 | The options are applied in the given order.
94 |
95 | A simple testbed is available in ${WXG_HOME}/www/testbed.html. It can be accessed by pointing the browser
96 | to http://${WXG_HOSTNAME}:${WXG_PORT}/testbed.html (standard config: http://localhost:8080/testbed.html)
97 |
98 | References
99 | ==========
100 | [1] P. Saint-Andre. Extensible Messaging and Presence Protocol (XMPP): Core. RFC3920. Oct 2004. http://www.ietf.org/rfc/rfc3920.txt
101 | [2] I. Fette. The WebSocket protocol. HyBi Working Group Internet Draft. Jun 2011. http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-09
102 | [3] I. Hickson. The WebSocket API. W3C Editor's draft. Jun 2011. http://dev.w3.org/html5/websockets/
103 | [4] J. Moffit, E. Cestari. An XMPP Sub-protocol for WebSocket. HyBi Working Group Internet Draft. Dec 2010. http://tools.ietf.org/html/draft-moffitt-xmpp-over-websocket-00
104 | [5] I. Paterson, D. Smith, P. Saint-Andre, J. Moffitt. XEP-0124: Bidirectional-streams Over Synchronous HTTP (BOSH). XSF Draft Standard. Jul 2010. http://xmpp.org/extensions/xep-0124.html
105 | [6] I. Paterson, P. Saint-Andre. XEP-0206: XMPP Over BOSH. XSF Draft Standard. Jul 2010. http://xmpp.org/extensions/xep-0206.html
106 |
--------------------------------------------------------------------------------
/java/de/rwth_aachen/dbis/wsxmppgateway/WebSocketXmppGateway.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 Christian Hocken, Dominik Renzel,
3 | * Chair of Computer Science 5 (Information Systems) at RWTH Aachen University, Germany.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package de.rwth_aachen.dbis.wsxmppgateway;
18 |
19 | import java.io.FileInputStream;
20 | import java.io.FileNotFoundException;
21 | import java.io.IOException;
22 | import java.util.ArrayList;
23 | import java.util.Collections;
24 | import java.util.Enumeration;
25 | import java.util.HashMap;
26 | import java.util.List;
27 | import java.util.Map;
28 | import java.util.Properties;
29 |
30 | import javax.servlet.http.HttpServletRequest;
31 |
32 | import org.eclipse.jetty.http.ssl.SslContextFactory;
33 | import org.eclipse.jetty.server.Server;
34 | import org.eclipse.jetty.server.handler.ResourceHandler;
35 | import org.eclipse.jetty.server.nio.SelectChannelConnector;
36 | import org.eclipse.jetty.server.ssl.SslSelectChannelConnector;
37 | import org.eclipse.jetty.websocket.WebSocket;
38 | import org.eclipse.jetty.websocket.WebSocketHandler;
39 | import org.slf4j.Logger;
40 | import org.slf4j.LoggerFactory;
41 |
42 | import de.rwth_aachen.dbis.wsxmppgateway.connection.WsXMPPConnectionHandler;
43 |
44 | /**
45 | * This class is the main class of the WebSocket XMPP gateway. It starts a Jetty HTTP servlet server with connectors and handlers.
46 | * @author Christian Hocken
47 | */
48 | public class WebSocketXmppGateway extends Server {
49 |
50 | //******************** defaults ********************//
51 | private static final String DEFAULT_CONFIG_FILE = "conf/server.xml";
52 | private static final String DEFAULT_ALIASES_FILE ="conf/aliases.conf";
53 | private static final int DEFAULT_TIMEOUT = 5*60*1000; //5 min
54 | private static final String DEFAULT_DOC_ROOT = "www";
55 | private static final boolean DEFAULT_LIST_DIRECTORIES = false;
56 |
57 | //******************** private static configuration switches ********************//
58 | private static String configFile = DEFAULT_CONFIG_FILE;
59 | private static String aliasesFile = DEFAULT_ALIASES_FILE;
60 |
61 | private static String hostname = null;
62 | private static int webSocketPort = -1;
63 | private static int sslWebSocketPort = -1;
64 | private static int timeout = DEFAULT_TIMEOUT; //connection timeout in ms
65 |
66 | private static String keyStorePath = null;
67 | private static String keyStorePassword = null;
68 |
69 | private static String docRoot = DEFAULT_DOC_ROOT;
70 | private static boolean listDirectories = DEFAULT_LIST_DIRECTORIES;
71 |
72 | //******************** private static variables ********************//
73 | //initialize slf4j logging framework
74 | private static final Logger logger = LoggerFactory.getLogger(WebSocketXmppGateway.class);
75 |
76 | //initialize the aliases cache
77 | private static Map aliases = Collections.synchronizedMap(new HashMap());
78 |
79 | //******************** private instance variables ********************//
80 | //Jetty connectors
81 | private SelectChannelConnector connector;
82 | private SslSelectChannelConnector sslConnector;
83 |
84 | //Jetty handlers
85 | private WebSocketHandler wsHandler;
86 | private ResourceHandler rHandler;
87 |
88 | //List of connected WebSocket clients
89 | private static final List connectedSockets = Collections.synchronizedList(new ArrayList());
90 |
91 | //instance of the gateway
92 | private static WebSocketXmppGateway gateway = null;
93 |
94 | /**
95 | * Creates WebSocketXmppGateway and adds connectors and handlers as defined in static configuration switches
96 | */
97 | public WebSocketXmppGateway() {
98 | //add Jetty connectors
99 | if (webSocketPort > -1) {
100 | //create plain channel connector
101 | connector = new SelectChannelConnector();
102 | connector.setHost(hostname);
103 | connector.setPort(webSocketPort);
104 | addConnector(connector);
105 | }
106 | if(sslWebSocketPort > -1) {
107 | //create ssl channel connector
108 | SslContextFactory sslContextFactory = new SslContextFactory();
109 | sslContextFactory.setKeyStore(keyStorePath);
110 | sslContextFactory.setKeyStorePassword(keyStorePassword);
111 | sslConnector = new SslSelectChannelConnector(sslContextFactory);
112 | sslConnector.setHost(hostname);
113 | sslConnector.setPort(sslWebSocketPort);
114 | addConnector(sslConnector);
115 | }
116 |
117 | //add Jetty handlers
118 | wsHandler = new WebSocketHandler() {
119 | @Override
120 | public WebSocket doWebSocketConnect(HttpServletRequest request, String subProtocol) {
121 | if ("xmpp".equals(subProtocol.toLowerCase()))
122 | return new WsXMPPConnectionHandler(request);
123 | else {
124 | //TODO
125 | //Exception handling for missing or wrong sub protocol
126 | return null;
127 | }
128 | }
129 | };
130 | setHandler(wsHandler);
131 | rHandler = new ResourceHandler();
132 | rHandler.setResourceBase(docRoot);
133 | rHandler.setDirectoriesListed(listDirectories);
134 | wsHandler.setHandler(rHandler);
135 | }
136 |
137 | //******************** static methods ********************//
138 | public static void main(String...args) {
139 | logger.info("Starting WebSocket XMPP gateway");
140 | //load properties from location specified in configFile
141 | loadProperties();
142 | //load aliases in cache
143 | loadAliases();
144 | //init and start gateway
145 | gateway = new WebSocketXmppGateway();
146 | try {
147 | gateway.start();
148 | gateway.join();
149 | } catch (Exception e) {
150 | logger.error("Cannot start WebSocket XMPP gateway", e);
151 | System.exit(1);
152 | }
153 | }
154 |
155 | /**
156 | * load properties from config file
157 | */
158 | private static void loadProperties() {
159 | Properties prop = new Properties();
160 | FileInputStream fis;
161 | try {
162 | fis = new FileInputStream(configFile);
163 | prop.loadFromXML(fis);
164 | hostname = prop.getProperty("Host");
165 | webSocketPort = Integer.parseInt(prop.getProperty("Port", "-1"));
166 | sslWebSocketPort = Integer.parseInt(prop.getProperty("SSLport", "-1"));
167 | timeout = Integer.parseInt(prop.getProperty("Timeout", DEFAULT_TIMEOUT + ""));
168 | keyStorePath = prop.getProperty("Keystore");
169 | keyStorePassword = prop.getProperty("KeystorePassword");
170 | docRoot = prop.getProperty("DocRoot", DEFAULT_DOC_ROOT);
171 | listDirectories = "true".equals(prop.getProperty("DirectoryListing", DEFAULT_LIST_DIRECTORIES + "").toLowerCase());
172 | } catch (Exception e) {
173 | logger.error("Cannot load properties from config file " + configFile,e);
174 | System.exit(1);
175 | }
176 | }
177 |
178 | /**
179 | * load aliases from config file
180 | */
181 | private static void loadAliases() {
182 | Properties prop = new Properties();
183 | FileInputStream fis;
184 | try {
185 | fis = new FileInputStream(aliasesFile);
186 | prop.load(fis);
187 | Enumeration