Commit ea69e703 authored by Alex Wenckus's avatar Alex Wenckus Committed by alex

Merged http-bind changes.

git-svn-id: http://svn.igniterealtime.org/svn/repos/wildfire/trunk@5912 b35dd754-fafc-0310-a699-88a17e54d16e
parent a0996044
......@@ -132,6 +132,11 @@
<attribute name="URI" value="/WEB-INF/lib/jaxen.jar" />
<url>jar://$MODULE_DIR$/build/lib/merge/jaxen.jar!/</url>
</containerElement>
<containerElement type="library" level="module">
<attribute name="method" value="0" />
<attribute name="URI" value="/WEB-INF/lib/jetty-util.jar" />
<url>jar://$MODULE_DIR$/build/lib/merge/jetty-util.jar!/</url>
</containerElement>
<containerElement type="library" level="module">
<attribute name="method" value="0" />
<attribute name="URI" value="/WEB-INF/lib/jetty.jar" />
......@@ -142,6 +147,11 @@
<attribute name="URI" value="/WEB-INF/lib/jmdns.jar" />
<url>jar://$MODULE_DIR$/build/lib/merge/jmdns.jar!/</url>
</containerElement>
<containerElement type="library" level="module">
<attribute name="method" value="0" />
<attribute name="URI" value="&lt;N/A&gt;" />
<url>jar://$MODULE_DIR$/build/lib/merge/jsp-api.jar!/</url>
</containerElement>
<containerElement type="library" level="module">
<attribute name="method" value="0" />
<attribute name="URI" value="/WEB-INF/lib/jstl.jar" />
......
......@@ -57,7 +57,6 @@
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="file://J:/whack/source/java" />
<root url="jar://$MODULE_DIR$/build/lib/merge/whack.jar!/" />
</SOURCES>
</library>
......@@ -149,9 +148,7 @@
<root url="jar://$MODULE_DIR$/build/lib/merge/dom4j.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="file://$MODULE_DIR$/../../java/dom4j-1.6.1/src/java" />
</SOURCES>
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library" exported="">
......@@ -337,7 +334,16 @@
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/../../Documents and Settings/gato/.IntelliJIdea60/config/plugins/Clover_for_IDEA_2848.jar!/" />
<root url="jar://$MODULE_DIR$/build/lib/merge/jetty-util.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/build/lib/merge/jsp-api.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
......
......@@ -302,7 +302,6 @@
</component>
<component name="ProjectRootManager" version="2" assert-keyword="true" jdk-15="true" project-jdk-name="JDK 1.5.0" project-jdk-type="JavaSDK" />
<component name="ProjectRunConfigurationManager" />
<component name="ProjectRunConfigurationManager" />
<component name="RmicSettings">
<option name="IS_EANABLED" value="false" />
<option name="DEBUGGING_INFO" value="true" />
......
No preview for this file type
Name | Version
---------------------------------------------
ant.jar | Jetty 5.1.10
ant.jar | Jetty 6.1.0 (1.6.5)
ant-contrib.jar | 1.0b1
ant-subdirtask.jar | Revision 1.4 (CVS)
bouncycastle.jar | JDK 1.5, 134 (bcprov-jdk15-134.jar)
commons-logging.jar | Jetty 5.1.10
commons-el.jar | Jetty 5.1.10
commons-el.jar | Jetty 6.1.0 (1.0)
commons-httpclient.jar | 3.0
commons-codec.jar | 1.3
dom4j.jar | 1.6.1
hsqldb.jar | 1.8.0.5
jetty.jar | Jetty 5.1.10
jasper-compiler.jar | Jetty 5.1.10
jasper-runtime.jar | Jetty 5.1.10
jetty.jar | Jetty 6.1.0
jetty-util.jar | Jetty 6.1.0
jasper-compiler.jar | Jetty 6.1.0 (5.5.15)
jasper-runtime.jar | Jetty 6.1.0 (5.5.15)
jaxen.jar | 1.1 beta 4 (from DOM4J 1.6.1)
junit.jar | 3.8.1
jdic.jar | 0.9.1 (for windows only)
jstl.jar | Jakarta standard taglib 1.1.2
jmdns.jar | 1.0 RC1
jsp-api.jar | Jetty 6.1.0 (2.0)
jtds.jar | 1.2
jzlib.jar | 1.0.7
mail.jar | 1.4.0 (JavaMail)
mysql.jar | 3.1.13
pack200task.jar | August 5, 2004
postgres.jar | 8.1-404 JDBC 3
servlet.jar | Jetty 5.1.10
servlet.jar | Jetty 6.1.0 (2.5)
shaj.jar | 0.5
sitemesh.jar | 2.2.1
standard.jar | Jakarta standard taglib 1.1.2
......
......@@ -45,6 +45,8 @@ tab.server.descr=Klikn\u011bte pro spr\u00e1vu nastaven\u00ed serveru
sidebar.external-components-settings.descr=Klikn\u011bte pro zm\u011bnu nastaven\u00ed extern\u00edch komponent
sidebar.connection-managers-settings=Spr\u00e1vci p\u0159ipojen\u00ed
sidebar.connection-managers-settings.descr=Klikn\u011bte pro konfiguraci nastaven\u00ed spr\u00e1vce p\u0159ipojen\u00ed
sidebar.http-bind=HTTP Binding
sidebar.http-bind.descr=Click to configure HTTP binding settings
sidebar.server-reg-and-login=Registrace &amp; p\u0159ihl\u00e1\u0161en\u00ed
sidebar.server-reg-and-login.descr=Klikn\u011bte pro \u00fapravu registrace &amp; p\u0159ihla\u0161ovac\u00edch politik
sidebar.server-session-conflict=Politika zdroj\u016f
......@@ -1969,6 +1971,22 @@ plugin.enterprise.dont.show= Nezobrazovat znovu tuto str\u00e1nku
plugin.enterprise.installing = Instaluje se dopln\u011bk Enterprise ...
plugin.enterprise.installed = Dopln\u011bk Enterprise \u00fasp\u011b\u0161n\u011b nainstalov\u00e1n. Moment\u00e1ln\u011b prob\u00edh\u00e1 obnoven\u00ed...
# http bind settings page
httpbind.settings.enabled.legend=Service Enabled
httpbind.settings.title=HTTP Bind Settings
httpbind.settings.info=HTTP binding allows clients using the HTTP protocol to connect to Wildfire.
httpbind.settings.label_disable=Disabled
httpbind.settings.label_disable_info=Clients will not be able to connect with this server using HTTP binding.
httpbind.settings.label_enable=Enabled
httpbind.settings.label_enable_info=Clients can connect to this server using HTTP binding.
httpbind.settings.vanilla_port=Port:
httpbind.settings.label_seperate=Use Admin Console Ports
httpbind.settings.label_seperate_info=The HTTP bind service will be run on the same ports as the admin console
httpbind.settings.label_same=Use Distinct Ports
httpbind.settings.label_same_info=The HTTP bind service will use distinct ports from those of the admin console
httpbind.settings.secure_port=Secure Port
# Profile Settings
profile-settings.title=Nastaven\u00ed profilu
......
......@@ -44,6 +44,8 @@ tab.server.descr=Hier klicken um die Servereinstellungen zu verwalten
sidebar.external-components-settings.descr=
sidebar.connection-managers-settings=Connection Managers
sidebar.connection-managers-settings.descr=Click to configure connection manager settings
sidebar.http-bind=HTTP Binding
sidebar.http-bind.descr=Click to configure HTTP binding settings
sidebar.server-reg-and-login=Registrierung &amp; Anmeldung
sidebar.server-reg-and-login.descr=Hier klicken um die Registrierungs- und Anmeldungsrichtlinien zu bearbeiten
sidebar.server-session-conflict=Ressourcerichtlinien
......@@ -1726,3 +1728,19 @@ calendar.close = Close
calendar.today = Today
calendar.time_part = (Shift-)Click or drag to change value
calendar.time = Time:
# http bind settings page
httpbind.settings.enabled.legend=Service Enabled
httpbind.settings.title=HTTP Bind Settings
httpbind.settings.info=HTTP binding allows clients using the HTTP protocol to connect to Wildfire.
httpbind.settings.label_disable=Disabled
httpbind.settings.label_disable_info=Clients will not be able to connect with this server using HTTP binding.
httpbind.settings.label_enable=Enabled
httpbind.settings.label_enable_info=Clients can connect to this server using HTTP binding.
httpbind.settings.vanilla_port=Port:
httpbind.settings.label_seperate=Use Admin Console Ports
httpbind.settings.label_seperate_info=The HTTP bind service will be run on the same ports as the admin console
httpbind.settings.label_same=Use Distinct Ports
httpbind.settings.label_same_info=The HTTP bind service will use distinct ports from those of the admin console
httpbind.settings.secure_port=Secure Port
\ No newline at end of file
......@@ -125,6 +125,23 @@
## Added key: 'plugin.enterprise.installing'
## Added key: 'plugin.enterprise.installed'
##
## 3.2.0
## Added key: 'sidebar.http-bind'
## Added key: 'sidebar.http-bind.descr'
## Added key: 'httpbind.settings.enabled.legend'
## Added key: 'httpbind.settings.title'
## Added key: 'httpbind.settings.info'
## Added key: 'httpbind.settings.label_disable'
## Added key: 'httpbind.settings.label_disable_info'
## Added key: 'httpbind.settings.label_enable'
## Added key: 'httpbind.settings.label_enable_info'
## Added key: 'httpbind.settings.vanilla_port'
## Added key: 'httpbind.settings.label_seperate'
## Added key: 'httpbind.settings.label_seperate_info'
## Added key: 'httpbind.settings.label_same'
## Added key: 'httpbind.settings.label_same_info'
## Added key: 'httpbind.settings.secure_port'
##
## 3.1.1
## Added key: 'global.second'
## Added key: 'global.minute'
......@@ -193,6 +210,8 @@ tab.server.descr=Click to manage server settings
sidebar.external-components-settings.descr=Click to configure external component settings
sidebar.connection-managers-settings=Connection Managers
sidebar.connection-managers-settings.descr=Click to configure connection manager settings
sidebar.http-bind=HTTP Binding
sidebar.http-bind.descr=Click to configure HTTP binding settings
sidebar.server-reg-and-login=Registration &amp; Login
sidebar.server-reg-and-login.descr=Click to edit registration &amp; login policies
sidebar.server-session-conflict=Resource Policy
......@@ -2121,6 +2140,22 @@ plugin.enterprise.dont.show= Don't show this page again
plugin.enterprise.installing = Installing Enterprise Plugin...
plugin.enterprise.installed = Enterprise plugin installed successfully. Refreshing momentarily...
# http bind settings page
httpbind.settings.enabled.legend=Service Enabled
httpbind.settings.title=HTTP Bind Settings
httpbind.settings.info=HTTP binding allows clients using the HTTP protocol to connect to Wildfire.
httpbind.settings.label_disable=Disabled
httpbind.settings.label_disable_info=Clients will not be able to connect with this server using HTTP binding.
httpbind.settings.label_enable=Enabled
httpbind.settings.label_enable_info=Clients can connect to this server using HTTP binding.
httpbind.settings.vanilla_port=Port:
httpbind.settings.label_seperate=Use Admin Console Ports
httpbind.settings.label_seperate_info=The HTTP bind service will be run on the same ports as the admin console
httpbind.settings.label_same=Use Distinct Ports
httpbind.settings.label_same_info=The HTTP bind service will use distinct ports from those of the admin console
httpbind.settings.secure_port=SSL Port:
# Profile Settings
profile-settings.title=Profile Settings
......
......@@ -41,6 +41,8 @@ tab.server.descr=Presione para administrar la configuraci\u00f3n del servidor
sidebar.external-components-settings.descr=Presione para configurar los componentes externos
sidebar.connection-managers-settings=Administradores de Conexiones
sidebar.connection-managers-settings.descr=Presione para configurar los administradores de conexiones
sidebar.http-bind=HTTP Binding
sidebar.http-bind.descr=Click to configure HTTP binding settings
sidebar.server-reg-and-login=Registro y Conexiones
sidebar.server-reg-and-login.descr=Presione para editar la pol\u00edtica de registro y conexiones
sidebar.server-session-conflict=Pol\u00edtica de Recursos
......@@ -1837,6 +1839,22 @@ plugin.enterprise.dont.show= No mostrar esta p\u00e1gina nuevamente
plugin.enterprise.installing = Instalando Plugin Corporativo...
plugin.enterprise.installed = Plugin Corporativo instalado exitosamente. Refrescando en un instante...
# http bind settings page
httpbind.settings.enabled.legend=Service Enabled
httpbind.settings.title=HTTP Bind Settings
httpbind.settings.info=HTTP binding allows clients using the HTTP protocol to connect to Wildfire.
httpbind.settings.label_disable=Disabled
httpbind.settings.label_disable_info=Clients will not be able to connect with this server using HTTP binding.
httpbind.settings.label_enable=Enabled
httpbind.settings.label_enable_info=Clients can connect to this server using HTTP binding.
httpbind.settings.vanilla_port=Port:
httpbind.settings.label_seperate=Use Admin Console Ports
httpbind.settings.label_seperate_info=The HTTP bind service will be run on the same ports as the admin console
httpbind.settings.label_same=Use Distinct Ports
httpbind.settings.label_same_info=The HTTP bind service will use distinct ports from those of the admin console
httpbind.settings.secure_port=Secure Port
# Profile Settings
profile-settings.title=Seteos de Perfil
......
......@@ -42,6 +42,8 @@ tab.server.descr=Klik hier om de serverinstellingen te beheren
sidebar.external-components-settings.descr=
sidebar.connection-managers-settings=Connection Managers
sidebar.connection-managers-settings.descr=Click to configure connection manager settings
sidebar.http-bind=HTTP Binding
sidebar.http-bind.descr=Click to configure HTTP binding settings
sidebar.server-reg-and-login=Registratie &amp; aanmelding
sidebar.server-reg-and-login.descr=Klik hier om het registratie- &amp; aanmeldingsbeleid te wijzigen
sidebar.server-session-conflict=Extensiebeleid
......@@ -1732,3 +1734,19 @@ calendar.close = Close
calendar.today = Today
calendar.time_part = (Shift-)Click or drag to change value
calendar.time = Time:
# http bind settings page
httpbind.settings.enabled.legend=Service Enabled
httpbind.settings.title=HTTP Bind Settings
httpbind.settings.info=HTTP binding allows clients using the HTTP protocol to connect to Wildfire.
httpbind.settings.label_disable=Disabled
httpbind.settings.label_disable_info=Clients will not be able to connect with this server using HTTP binding.
httpbind.settings.label_enable=Enabled
httpbind.settings.label_enable_info=Clients can connect to this server using HTTP binding.
httpbind.settings.vanilla_port=Port:
httpbind.settings.label_seperate=Use Admin Console Ports
httpbind.settings.label_seperate_info=The HTTP bind service will be run on the same ports as the admin console
httpbind.settings.label_same=Use Distinct Ports
httpbind.settings.label_same_info=The HTTP bind service will use distinct ports from those of the admin console
httpbind.settings.secure_port=Secure Port
\ No newline at end of file
......@@ -46,6 +46,8 @@ tab.server.descr=Zarz\u0105dzanie ustawieniami serwera
sidebar.external-components-settings.descr=Kliknij aby skonfigurowa\u0107 ustawienia zewn\u0119trznych komponent\u00f3w
sidebar.connection-managers-settings=Menad\u017cer po\u0142\u0105cze\u0144
sidebar.connection-managers-settings.descr=Kliknij aby skonfigurowa\u0107 menad\u017cera po\u0142\u0105cze\u0144
sidebar.http-bind=HTTP Binding
sidebar.http-bind.descr=Click to configure HTTP binding settings
sidebar.server-reg-and-login=Rejestracja i logowanie
sidebar.server-reg-and-login.descr=Kliknij aby edytowa\u0107 ustawienia rejestracji i logowania u\u017cytkownik\u00f3w
sidebar.server-session-conflict=Polityka zasob\u00f3w
......@@ -1702,3 +1704,19 @@ calendar.close = Zamknij
calendar.today = Dzisiaj
calendar.time_part = (Shift-)klik lub chwy\u0107 aby zmieni\u0107 warto\u015b\u0107
calendar.time = Czas:
# http bind settings page
httpbind.settings.enabled.legend=Service Enabled
httpbind.settings.title=HTTP Bind Settings
httpbind.settings.info=HTTP binding allows clients using the HTTP protocol to connect to Wildfire.
httpbind.settings.label_disable=Disabled
httpbind.settings.label_disable_info=Clients will not be able to connect with this server using HTTP binding.
httpbind.settings.label_enable=Enabled
httpbind.settings.label_enable_info=Clients can connect to this server using HTTP binding.
httpbind.settings.vanilla_port=Port:
httpbind.settings.label_seperate=Use Admin Console Ports
httpbind.settings.label_seperate_info=The HTTP bind service will be run on the same ports as the admin console
httpbind.settings.label_same=Use Distinct Ports
httpbind.settings.label_same_info=The HTTP bind service will use distinct ports from those of the admin console
httpbind.settings.secure_port=Secure Port
\ No newline at end of file
......@@ -42,6 +42,8 @@ tab.server.descr=Clique para gerenciar as configura\u00e7\u00f5es do servidor
sidebar.external-components-settings.descr=Clique para editar as configura\u00e7\u00f5es de componentes externos
sidebar.connection-managers-settings=Gerenciadores de Conex\u00e3o
sidebar.connection-managers-settings.descr=Clique para configurar o gerenciador de conex\u00e3o
sidebar.http-bind=HTTP Binding
sidebar.http-bind.descr=Click to configure HTTP binding settings
sidebar.server-reg-and-login=Registro &amp; Login
sidebar.server-reg-and-login.descr=Clique para editar as pol\u00edticas de registro &amp;
sidebar.server-session-conflict=Pol\u00edtica de Recursos
......@@ -1733,3 +1735,19 @@ calendar.close = Fechar
calendar.today = Hoje
calendar.time_part = (Shift-)Clique ou arraste para mudar valor
calendar.time = Hora:
# http bind settings page
httpbind.settings.enabled.legend=Service Enabled
httpbind.settings.title=HTTP Bind Settings
httpbind.settings.info=HTTP binding allows clients using the HTTP protocol to connect to Wildfire.
httpbind.settings.label_disable=Disabled
httpbind.settings.label_disable_info=Clients will not be able to connect with this server using HTTP binding.
httpbind.settings.label_enable=Enabled
httpbind.settings.label_enable_info=Clients can connect to this server using HTTP binding.
httpbind.settings.vanilla_port=Port:
httpbind.settings.label_seperate=Use Admin Console Ports
httpbind.settings.label_seperate_info=The HTTP bind service will be run on the same ports as the admin console
httpbind.settings.label_same=Use Distinct Ports
httpbind.settings.label_same_info=The HTTP bind service will use distinct ports from those of the admin console
httpbind.settings.secure_port=Secure Port
\ No newline at end of file
......@@ -45,6 +45,8 @@ tab.server.descr=\u5355\u51fb\u53ef\u7ba1\u7406\u670d\u52a1\u5668\u8bbe\u7f6e
sidebar.external-components-settings.descr=\u70b9\u51fb\u914d\u7f6e\u5916\u90e8\u7ec4\u4ef6\u8bbe\u7f6e
sidebar.connection-managers-settings=\u8fde\u63a5\u7ba1\u7406
sidebar.connection-managers-settings.descr=\u5355\u51fb\u914d\u7f6e\u8fde\u63a5\u7ba1\u7406\u8bbe\u7f6e
sidebar.http-bind=HTTP Binding
sidebar.http-bind.descr=Click to configure HTTP binding settings
sidebar.server-reg-and-login=\u6ce8\u518c\u548c\u767b\u5f55
sidebar.server-reg-and-login.descr=\u5355\u51fb\u53ef\u7f16\u8f91\u6ce8\u518c\u548c\u767b\u5f55\u7b56\u7565
sidebar.server-session-conflict=\u8d44\u6e90\u7b56\u7565
......@@ -1769,6 +1771,22 @@ calendar.today = \u4eca\u5929
calendar.time_part = (Shift-)\u5355\u51fb\u6216\u62d6\u52a8\u6539\u53d8\u503c
calendar.time = \u65f6\u95f4:
# http bind settings page
httpbind.settings.enabled.legend=Service Enabled
httpbind.settings.title=HTTP Bind Settings
httpbind.settings.info=HTTP binding allows clients using the HTTP protocol to connect to Wildfire.
httpbind.settings.label_disable=Disabled
httpbind.settings.label_disable_info=Clients will not be able to connect with this server using HTTP binding.
httpbind.settings.label_enable=Enabled
httpbind.settings.label_enable_info=Clients can connect to this server using HTTP binding.
httpbind.settings.vanilla_port=Port:
httpbind.settings.label_seperate=Use Admin Console Ports
httpbind.settings.label_seperate_info=The HTTP bind service will be run on the same ports as the admin console
httpbind.settings.label_same=Use Distinct Ports
httpbind.settings.label_same_info=The HTTP bind service will use distinct ports from those of the admin console
httpbind.settings.secure_port=Secure Port
# Enterprise Download Page
plugin.enterprise.download.error = \u4e0d\u80fd\u4e0b\u8f7d\u4f01\u4e1a\u63d2\u4ef6\uff0c\u8bf7\u5c1d\u8bd5\u518d\u6b21\u4e0b\u8f7d
plugin.enterprise.dont.show= \u4e0d\u8981\u518d\u6b21\u663e\u793a\u6b64\u9875
......
......@@ -41,6 +41,8 @@ public interface ConnectionManager {
* @param serverPort holds information about the port on which the server is listening for
* connections.
* @param useBlockingMode true means that the server will use a thread per connection.
* @return the created socket reader.
* @throws java.io.IOException when there is an error creating the socket reader.
*/
public SocketReader createSocketReader(Socket socket, boolean isSecure, ServerPort serverPort,
boolean useBlockingMode) throws IOException;
......
This diff is collapsed.
......@@ -30,6 +30,7 @@ import org.jivesoftware.wildfire.server.OutgoingSessionPromise;
import org.jivesoftware.wildfire.spi.BasicStreamIDFactory;
import org.jivesoftware.wildfire.user.UserManager;
import org.jivesoftware.wildfire.user.UserNotFoundException;
import org.jivesoftware.wildfire.http.HttpSession;
import org.xmpp.packet.JID;
import org.xmpp.packet.Message;
import org.xmpp.packet.Packet;
......@@ -541,6 +542,21 @@ public class SessionManager extends BasicModule {
return session;
}
public HttpSession createClientHttpSession(InetAddress address, StreamID id)
throws UnauthorizedException
{
if (serverName == null) {
throw new UnauthorizedException("Server not initialized");
}
HttpSession session = new HttpSession(serverName, address, id);
Connection conn = session.getConnection();
conn.init(session);
conn.registerCloseListener(clientSessionListener, session);
preAuthenticatedSessions.put(session.getAddress().getResource(), session);
usersSessionsCounter.incrementAndGet();
return session;
}
public Session createComponentSession(Connection conn) throws UnauthorizedException {
if (serverName == null) {
throw new UnauthorizedException("Server not initialized");
......
......@@ -22,9 +22,10 @@ import org.jivesoftware.wildfire.audit.AuditManager;
import org.jivesoftware.wildfire.audit.spi.AuditManagerImpl;
import org.jivesoftware.wildfire.commands.AdHocCommandHandler;
import org.jivesoftware.wildfire.component.InternalComponentManager;
import org.jivesoftware.wildfire.container.AdminConsolePlugin;
import org.jivesoftware.wildfire.container.Module;
import org.jivesoftware.wildfire.container.PluginManager;
import org.jivesoftware.wildfire.container.PluginListener;
import org.jivesoftware.wildfire.container.Plugin;
import org.jivesoftware.wildfire.disco.IQDiscoInfoHandler;
import org.jivesoftware.wildfire.disco.IQDiscoItemsHandler;
import org.jivesoftware.wildfire.disco.ServerFeaturesProvider;
......@@ -125,6 +126,7 @@ public class XMPPServer {
"org.jivesoftware.wildfire.starter.ServerStarter";
private static final String WRAPPER_CLASSNAME =
"org.tanukisoftware.wrapper.WrapperManager";
private HttpServerManager httpServerManager;
/**
* Returns a singleton instance of XMPPServer.
......@@ -295,6 +297,7 @@ public class XMPPServer {
loader = Thread.currentThread().getContextClassLoader();
componentManager = InternalComponentManager.getInstance();
httpServerManager = HttpServerManager.getInstance();
initialized = true;
}
......@@ -327,8 +330,8 @@ public class XMPPServer {
// Otherwise, the page that requested the setup finish won't
// render properly!
Thread.sleep(1000);
((AdminConsolePlugin) pluginManager.getPlugin("admin"))
.restartListeners();
httpServerManager.shutdown();
httpServerManager.startup();
}
}
......@@ -383,6 +386,19 @@ public class XMPPServer {
ServerTrafficCounter.initStatistics();
// Load plugins (when in setup mode only the admin console will be loaded)
pluginManager.addPluginListener(new PluginListener() {
public void pluginCreated(String pluginName, Plugin plugin) {
if("admin".equals(pluginName)) {
httpServerManager.startup();
}
}
public void pluginDestroyed(String pluginName, Plugin plugin) {
if ("admin".equals(pluginName)) {
httpServerManager.shutdown();
}
}
});
pluginManager.start();
// Log that the server has been started
......
/**
* $RCSfile$
* $Revision: $
* $Date: $
*
* Copyright (C) 2006 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.wildfire.container;
/**
* Allows for notifications that a plugin has been either created or destroyed.
*
* @author Alexander Wenckus
*/
public interface PluginListener {
/**
* Called when a plugin has been created.
*
* @param pluginName the name of the created plugin.
* @param plugin the plugin that was created.
*/
void pluginCreated(String pluginName, Plugin plugin);
/**
* Called when a plugin has been destroyed.
*
* @param pluginName the name of the destroyed plugin.
* @param plugin the plugin that was destroyed.
*/
void pluginDestroyed(String pluginName, Plugin plugin);
}
......@@ -58,6 +58,7 @@ public class PluginManager {
private Map<Plugin, String> childPluginMap;
private Set<String> devPlugins;
private PluginMonitor pluginMonitor;
private Set<PluginListener> pluginListeners = new HashSet<PluginListener>();
/**
* Constructs a new plugin manager.
......@@ -458,6 +459,7 @@ public class PluginManager {
AdminConsole.addModel(pluginName, adminElement);
}
firePluginCreatedEvent(pluginDir.getName(), plugin);
}
else {
Log.warn("Plugin " + pluginDir + " could not be loaded: no plugin.xml file found");
......@@ -468,6 +470,14 @@ public class PluginManager {
}
}
private void firePluginCreatedEvent(String name, Plugin plugin) {
Collection<PluginListener> pluginListeners
= new ArrayList<PluginListener>(this.pluginListeners);
for(PluginListener listener : pluginListeners) {
listener.pluginCreated(name, plugin);
}
}
/**
* Unloads a plugin. The {@link Plugin#destroyPlugin()} method will be called and then
* any resources will be released. The name should be the name of the plugin directory
......@@ -538,6 +548,15 @@ public class PluginManager {
unloadPlugin(childPluginMap.get(plugin));
}
childPluginMap.remove(plugin);
firePluginDestroyedEvent(pluginName, plugin);
}
private void firePluginDestroyedEvent(String name, Plugin plugin) {
Collection<PluginListener> pluginListeners
= new ArrayList<PluginListener>(this.pluginListeners);
for (PluginListener listener : pluginListeners) {
listener.pluginDestroyed(name, plugin);
}
}
/**
......@@ -1054,4 +1073,12 @@ public class PluginManager {
return dir.delete();
}
}
public void addPluginListener(PluginListener listener) {
pluginListeners.add(listener);
}
public void removePluginListener(PluginListener listener) {
pluginListeners.remove(listener);
}
}
\ No newline at end of file
/**
* $RCSfile: $
* $Revision: $
* $Date: $
*
* Copyright (C) 2006 Jive Software. All rights reserved.
* This software is the proprietary information of Jive Software. Use is subject to license terms.
*/
package org.jivesoftware.wildfire.http;
/**
*
*/
public class HttpBindException extends Exception {
private boolean shouldCloseSession;
private int httpError;
public HttpBindException(String message, boolean shouldCloseSession, int httpError) {
super(message);
this.shouldCloseSession = shouldCloseSession;
this.httpError = httpError;
}
public int getHttpError() {
return httpError;
}
public boolean shouldCloseSession() {
return shouldCloseSession;
}
}
/**
* $RCSfile$
* $Revision: $
* $Date: $
*
* Copyright (C) 2006 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.wildfire.http;
import org.xmlpull.v1.XmlPullParserFactory;
import org.xmlpull.v1.XmlPullParserException;
import org.jivesoftware.util.Log;
import org.jivesoftware.wildfire.net.MXParser;
import org.jivesoftware.wildfire.auth.UnauthorizedException;
import org.dom4j.io.XMPPPacketReader;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.DocumentHelper;
import org.mortbay.util.ajax.ContinuationSupport;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
import java.io.IOException;
import java.net.InetAddress;
/**
* Handles requests to the HTTP Bind service.
*
* @author Alexander Wenckus
*/
public class HttpBindServlet extends HttpServlet {
private HttpSessionManager sessionManager;
private static XmlPullParserFactory factory;
static {
try {
factory = XmlPullParserFactory.newInstance(MXParser.class.getName(), null);
}
catch (XmlPullParserException e) {
Log.error("Error creating a parser factory", e);
}
}
public HttpBindServlet(HttpSessionManager sessionManager) {
this.sessionManager = sessionManager;
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
if (isContinuation(request, response)) {
return;
}
Document document;
try {
document = createDocument(request);
}
catch (Exception e) {
Log.warn("Error parsing user request. [" + request.getRemoteAddr() + "]");
response.sendError(HttpServletResponse.SC_BAD_REQUEST,
"Unable to parse request content: " + e.getMessage());
return;
}
Element node = document.getRootElement();
if (node == null || !"body".equals(node.getName())) {
Log.warn("Body missing from request content. [" + request.getRemoteAddr() + "]");
response.sendError(HttpServletResponse.SC_BAD_REQUEST,
"Body missing from request content.");
return;
}
String sid = node.attributeValue("sid");
// We have a new session
if (sid == null) {
createNewSession(request, response, node);
}
else {
handleSessionRequest(sid, request, response, node);
}
}
private boolean isContinuation(HttpServletRequest request, HttpServletResponse response)
throws IOException
{
HttpConnection connection = (HttpConnection) request.getAttribute("request-connection");
if (connection == null) {
return false;
}
respond(response, connection);
return true;
}
private void handleSessionRequest(String sid, HttpServletRequest request,
HttpServletResponse response, Element rootNode)
throws IOException
{
long rid = getLongAttribue(rootNode.attributeValue("rid"), -1);
if (rid <= 0) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Body missing RID (Request ID)");
return;
}
HttpSession session = sessionManager.getSession(sid);
if (session == null) {
Log.warn("Client provided invalid session: " + sid + ". [" +
request.getRemoteAddr() + "]");
response.sendError(HttpServletResponse.SC_NOT_FOUND, "Invalid SID.");
return;
}
synchronized (session) {
HttpConnection connection;
try {
connection = sessionManager.forwardRequest(rid, session,
request.isSecure(), rootNode);
}
catch (HttpBindException e) {
response.sendError(e.getHttpError(), e.getMessage());
if(e.shouldCloseSession()) {
session.close();
}
return;
}
catch (HttpConnectionClosedException nc) {
Log.error("Error sending packet to client.", nc);
return;
}
String type = rootNode.attributeValue("type");
if ("terminate".equals(type)) {
session.close();
respond(response, createEmptyBody().getBytes("utf-8"));
}
else {
connection
.setContinuation(ContinuationSupport.getContinuation(request, connection));
request.setAttribute("request-connection", connection);
respond(response, connection);
}
}
}
private void createNewSession(HttpServletRequest request, HttpServletResponse response,
Element rootNode)
throws IOException
{
long rid = getLongAttribue(rootNode.attributeValue("rid"), -1);
if (rid <= 0) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Body missing RID (Request ID)");
return;
}
try {
HttpConnection connection = new HttpConnection(rid, request.isSecure());
InetAddress address = InetAddress.getByName(request.getRemoteAddr());
connection.setSession(sessionManager.createSession(address, rootNode, connection));
respond(response, connection);
}
catch (UnauthorizedException e) {
// Server wasn't initialized yet.
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
"Server Not initialized");
}
catch (HttpBindException e) {
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
}
private void respond(HttpServletResponse response, HttpConnection connection)
throws IOException
{
byte[] content;
try {
content = connection.getDeliverable().getBytes("utf-8");
}
catch (HttpBindTimeoutException e) {
content = createEmptyBody().getBytes("utf-8");
}
respond(response, content);
}
private void respond(HttpServletResponse response, byte [] content) throws IOException {
response.setStatus(HttpServletResponse.SC_OK);
response.setContentType("text/xml");
response.setCharacterEncoding("utf-8");
response.setContentLength(content.length);
response.getOutputStream().write(content);
}
private String createEmptyBody() {
Element body = DocumentHelper.createElement("body");
body.addNamespace("", "http://jabber.org/protocol/httpbind");
return body.asXML();
}
private long getLongAttribue(String value, long defaultValue) {
if (value == null || "".equals(value)) {
return defaultValue;
}
try {
return Long.valueOf(value);
}
catch (Exception ex) {
return defaultValue;
}
}
private Document createDocument(HttpServletRequest request) throws
DocumentException, IOException, XmlPullParserException {
// Reader is associated with a new XMPPPacketReader
XMPPPacketReader reader = new XMPPPacketReader();
reader.setXPPFactory(factory);
return reader.read(request.getInputStream());
}
}
/**
* $RCSfile$
* $Revision: $
* $Date: $
*
* Copyright (C) 2006 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.wildfire.http;
/**
* An exception which indicates that the maximum waiting time for a client response has been
* surpassed and an empty response should be returned to the requesting client.
*
* @author Alexander Wenckus
*/
class HttpBindTimeoutException extends Exception {
public HttpBindTimeoutException(String message) {
super(message);
}
public HttpBindTimeoutException() {
super();
}
}
/**
* $RCSfile: $
* $Revision: $
* $Date: $
*
* Copyright (C) 2006 Jive Software. All rights reserved.
* This software is the proprietary information of Jive Software. Use is subject to license terms.
*/
package org.jivesoftware.wildfire.http;
import org.jivesoftware.wildfire.Connection;
import org.mortbay.util.ajax.Continuation;
/**
* A connection to a client. The client will wait on getDeliverable() until the server forwards a
* message to it or the wait time on the session timesout.
*
* @author Alexander Wenckus
*/
public class HttpConnection {
private Connection.CompressionPolicy compressionPolicy;
private long requestId;
private String body;
private HttpSession session;
private Continuation continuation;
private boolean isClosed;
private boolean isSecure = false;
public HttpConnection(long requestId, boolean isSecure) {
this.requestId = requestId;
this.isSecure = isSecure;
}
public boolean validate() {
return false;
}
/**
* The connection should be closed without delivering a stanza to the requestor.
*/
public void close() {
if (isClosed) {
return;
}
try {
deliverBody(null);
}
catch (HttpConnectionClosedException e) {
/* Shouldn't happen */
}
}
public boolean isClosed() {
return isClosed;
}
public boolean isSecure() {
return isSecure;
}
/**
* Delivers content to the client. The content should be valid XMPP wrapped inside of a body.
* A <i>null</i> value for body indicates that the connection should be closed and the client
* sent an empty body.
*
* @param body the XMPP content to be forwarded to the client inside of a body tag.
*
* @throws HttpConnectionClosedException when this connection to the client has already recieved
* a deliverable to forward to the client
*/
public void deliverBody(String body) throws HttpConnectionClosedException {
// We only want to use this function once so we will close it when the body is delivered.
if (isClosed) {
throw new HttpConnectionClosedException("The http connection is no longer " +
"available to deliver content");
}
else {
isClosed = true;
}
if (continuation != null) {
continuation.setObject(body);
continuation.resume();
}
else {
this.body = body;
}
}
/**
* A call that will cause a wait, or in the case of Jetty the thread to be freed, if there is no
* deliverable currently available. Once the deliverable becomes available it is returned.
*
* @return the deliverable to send to the client
*
* @throws HttpBindTimeoutException to indicate that the maximum wait time requested by the
* client has been surpassed and an empty response should be returned.
*/
public String getDeliverable() throws HttpBindTimeoutException {
if (body == null && continuation != null) {
body = waitForDeliverable();
}
else if (body == null && continuation == null) {
throw new IllegalStateException("Continuation not set, cannot wait for deliverable.");
}
return body;
}
private String waitForDeliverable() throws HttpBindTimeoutException {
if (continuation.suspend(session.getWait() * 1000)) {
String deliverable = (String) continuation.getObject();
// This will occur when the hold attribute of a session has been exceded.
if (deliverable == null) {
throw new HttpBindTimeoutException();
}
return deliverable;
}
throw new HttpBindTimeoutException("Request " + requestId + " exceded response time from " +
"server of " + session.getWait() + " seconds.");
}
public boolean isCompressed() {
return false;
}
public Connection.CompressionPolicy getCompressionPolicy() {
return compressionPolicy;
}
public void setCompressionPolicy(Connection.CompressionPolicy compressionPolicy) {
this.compressionPolicy = compressionPolicy;
}
public long getRequestId() {
return requestId;
}
/**
* Set the session that this connection belongs to.
*
* @param session the session that this connection belongs to.
*/
void setSession(HttpSession session) {
this.session = session;
}
/**
* Returns the session that this connection belongs to.
*
* @return the session that this connection belongs to.
*/
public HttpSession getSession() {
return session;
}
void setContinuation(Continuation continuation) {
this.continuation = continuation;
}
}
/**
* $RCSfile$
* $Revision: $
* $Date: $
*
* Copyright (C) 2006 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.wildfire.http;
/**
* This exception is thrown when an action attempted on the connection to the client but the
* connection has been closed.
*
* @author Alexander Wenckus
*/
public class HttpConnectionClosedException extends Exception {
public HttpConnectionClosedException(String message) {
super(message);
}
}
This diff is collapsed.
/**
* $RCSfile$
* $Revision: $
* $Date: $
*
* Copyright (C) 2006 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.wildfire.http;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.Log;
import org.jivesoftware.wildfire.SessionManager;
import org.jivesoftware.wildfire.StreamID;
import org.jivesoftware.wildfire.multiplex.MultiplexerPacketRouter;
import org.jivesoftware.wildfire.multiplex.UnknownStanzaException;
import org.jivesoftware.wildfire.auth.UnauthorizedException;
import org.dom4j.*;
import java.util.*;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
/**
*
*/
public class HttpSessionManager {
/**
* Milliseconds a connection has to be idle to be closed. Default is 30 minutes. Sending
* stanzas to the client is not considered as activity. We are only considering the connection
* active when the client sends some data or hearbeats (i.e. whitespaces) to the server.
* The reason for this is that sending data will fail if the connection is closed. And if
* the thread is blocked while sending data (because the socket is closed) then the clean up
* thread will close the socket anyway.
*/
private static int inactivityTimeout;
/**
* The connection manager MAY limit the number of simultaneous requests the client makes with
* the 'requests' attribute. The RECOMMENDED value is "2". Servers that only support polling
* behavior MUST prevent clients from making simultaneous requests by setting the 'requests'
* attribute to a value of "1" (however, polling is NOT RECOMMENDED). In any case, clients MUST
* NOT make more simultaneous requests than specified by the connection manager.
*/
private static int maxRequests;
/**
* The connection manager SHOULD include two additional attributes in the session creation
* response element, specifying the shortest allowable polling interval and the longest
* allowable inactivity period (both in seconds). Communication of these parameters enables
* the client to engage in appropriate behavior (e.g., not sending empty request elements more
* often than desired, and ensuring that the periods with no requests pending are
* never too long).
*/
private static int pollingInterval;
private InactivityTimer timer = new InactivityTimer();
private SessionManager sessionManager;
private Map<String, HttpSession> sessionMap = new HashMap<String, HttpSession>();
static {
// Set the default read idle timeout. If none was set then assume 30 minutes
inactivityTimeout = JiveGlobals.getIntProperty("xmpp.httpbind.client.idle", 30);
maxRequests = JiveGlobals.getIntProperty("xmpp.httpbind.client.requests.max", 2);
pollingInterval = JiveGlobals.getIntProperty("xmpp.httpbind.client.requests.polling", 5);
}
public HttpSessionManager() {
this.sessionManager = SessionManager.getInstance();
}
public HttpSession getSession(String streamID) {
return sessionMap.get(streamID);
}
public HttpSession createSession(InetAddress address, Element rootNode,
HttpConnection connection)
throws UnauthorizedException, HttpBindException
{
// TODO Check if IP address is allowed to connect to the server
// Default language is English ("en").
String language = rootNode.attributeValue("xml:lang");
if(language == null || "".equals(language)) {
language = "en";
}
int wait = getIntAttribute(rootNode.attributeValue("wait"), 60);
int hold = getIntAttribute(rootNode.attributeValue("hold"), 1);
HttpSession session = createSession(address);
session.setWait(wait);
session.setHold(hold);
session.setSecure(connection.isSecure());
session.setMaxPollingInterval(pollingInterval);
session.setInactivityTimeout(inactivityTimeout);
// Store language and version information in the connection.
session.setLanaguage(language);
try {
connection.deliverBody(createSessionCreationResponse(session));
}
catch (HttpConnectionClosedException e) {
/* This won't happen here. */
}
catch (DocumentException e) {
Log.error("Error creating document", e);
throw new HttpBindException("Internal server error", true, 500);
}
timer.reset(session);
return session;
}
private HttpSession createSession(InetAddress address) throws UnauthorizedException {
// Create a ClientSession for this user.
StreamID streamID = SessionManager.getInstance().nextStreamID();
// Send to the server that a new client session has been created
HttpSession session = sessionManager.createClientHttpSession(address, streamID);
// Register that the new session is associated with the specified stream ID
sessionMap.put(streamID.getID(), session);
session.addSessionCloseListener(new SessionListener() {
public void connectionOpened(HttpSession session, HttpConnection connection) {
timer.stop(session);
}
public void connectionClosed(HttpSession session, HttpConnection connection) {
if (session.getConnectionCount() <= 0) {
timer.reset(session);
}
}
public void sessionClosed(HttpSession session) {
sessionMap.remove(session.getStreamID().getID());
sessionManager.removeSession(session);
timer.stop(session);
}
});
return session;
}
private static int getIntAttribute(String value, int defaultValue) {
if(value == null || "".equals(value)) {
return defaultValue;
}
try {
return Integer.valueOf(value);
}
catch (Exception ex) {
return defaultValue;
}
}
private String createSessionCreationResponse(HttpSession session) throws DocumentException {
Element response = DocumentHelper.createElement("body");
response.addNamespace("", "http://jabber.org/protocol/httpbind");
response.addNamespace("stream", "http://etherx.jabber.org/streams");
response.addAttribute("authid", session.getStreamID().getID());
response.addAttribute("sid", session.getStreamID().getID());
response.addAttribute("secure", Boolean.TRUE.toString());
response.addAttribute("requests", String.valueOf(maxRequests));
response.addAttribute("inactivity", String.valueOf(session.getInactivityTimeout()));
response.addAttribute("polling", String.valueOf(pollingInterval));
response.addAttribute("wait", String.valueOf(session.getWait()));
Element features = response.addElement("stream:features");
for(Element feature : session.getAvailableStreamFeaturesElements()) {
features.add(feature);
}
return response.asXML();
}
public HttpConnection forwardRequest(long rid, HttpSession session, boolean isSecure,
Element rootNode) throws HttpBindException,
HttpConnectionClosedException
{
//noinspection unchecked
List<Element> elements = rootNode.elements();
boolean isPoll = elements.size() <= 0;
HttpConnection connection = new HttpConnection(rid, isSecure);
session.addConnection(connection, isPoll);
MultiplexerPacketRouter router = new MultiplexerPacketRouter(session);
for (Element packet : elements) {
try {
router.route(packet);
session.incrementClientPacketCount();
}
catch (UnsupportedEncodingException e) {
throw new HttpBindException("Bad auth request, unknown encoding", true, 400);
}
catch (UnknownStanzaException e) {
throw new HttpBindException("Unknown packet type.", false, 400);
}
}
return connection;
}
private class InactivityTimer extends Timer {
private Map<String, InactivityTimeoutTask> sessionMap
= new HashMap<String, InactivityTimeoutTask>();
public void stop(HttpSession session) {
InactivityTimeoutTask task = sessionMap.remove(session.getStreamID().getID());
if(task != null) {
task.cancel();
}
}
public void reset(HttpSession session) {
stop(session);
if(session.isClosed()) {
return;
}
InactivityTimeoutTask task = new InactivityTimeoutTask(session);
schedule(task, session.getInactivityTimeout() * 1000);
sessionMap.put(session.getStreamID().getID(), task);
}
}
private class InactivityTimeoutTask extends TimerTask {
private HttpSession session;
public InactivityTimeoutTask(HttpSession session) {
this.session = session;
}
public void run() {
session.close();
timer.sessionMap.remove(session.getStreamID().getID());
}
}
}
/**
* $RCSfile: $
* $Revision: $
* $Date: $
*
* Copyright (C) 2006 Jive Software. All rights reserved.
* This software is the proprietary information of Jive Software. Use is subject to license terms.
*/
package org.jivesoftware.wildfire.http;
/**
*
*/
public interface SessionListener {
public void connectionOpened(HttpSession session, HttpConnection connection);
public void connectionClosed(HttpSession session, HttpConnection connection);
public void sessionClosed(HttpSession session);
}
......@@ -16,11 +16,7 @@ import org.dom4j.Element;
import org.dom4j.QName;
import org.jivesoftware.util.Log;
import org.jivesoftware.wildfire.ClientSession;
import org.jivesoftware.wildfire.PacketRouter;
import org.jivesoftware.wildfire.XMPPServer;
import org.jivesoftware.wildfire.interceptor.InterceptorManager;
import org.jivesoftware.wildfire.interceptor.PacketRejectedException;
import org.jivesoftware.wildfire.net.SASLAuthentication;
import org.xmpp.packet.*;
import java.io.UnsupportedEncodingException;
......@@ -40,12 +36,10 @@ import java.util.List;
public class MultiplexerPacketHandler {
private String connectionManagerDomain;
private PacketRouter router;
private final ConnectionMultiplexerManager multiplexerManager;
public MultiplexerPacketHandler(String connectionManagerDomain) {
this.connectionManagerDomain = connectionManagerDomain;
router = XMPPServer.getInstance().getPacketRouter();
multiplexerManager = ConnectionMultiplexerManager.getInstance();
}
......@@ -160,144 +154,30 @@ public class MultiplexerPacketHandler {
sendErrorPacket(route, PacketError.Condition.item_not_found, null);
return;
}
// Connection Manager wrapped a packet from a Client Session.
Element wrappedElement = route.getChildElement();
String tag = wrappedElement.getName();
MultiplexerPacketRouter router = new MultiplexerPacketRouter(session);
try {
if ("auth".equals(tag) || "response".equals(tag)) {
SASLAuthentication.handle(session, wrappedElement);
}
else if ("iq".equals(tag)) {
processIQ(session, getIQ(wrappedElement));
}
else if ("message".equals(tag)) {
processMessage(session, new Message(wrappedElement));
router.route(route.getChildElement());
}
else if ("presence".equals(tag)) {
processPresence(session, new Presence(wrappedElement));
}
else {
catch (UnknownStanzaException use) {
Element extraError = DocumentHelper.createElement(QName.get(
"unknown-stanza",
"http://jabber.org/protocol/connectionmanager#errors"));
sendErrorPacket(route, PacketError.Condition.bad_request, extraError);
}
}
catch (UnsupportedEncodingException e) {
Log.error("Error processing wrapped packet: " + wrappedElement.asXML(), e);
Log.error("Error processing wrapped packet: " + route.getChildElement().asXML(), e);
sendErrorPacket(route, PacketError.Condition.internal_server_error, null);
}
}
private void processIQ(ClientSession session, IQ packet) {
packet.setFrom(session.getAddress());
try {
// Invoke the interceptors before we process the read packet
InterceptorManager.getInstance().invokeInterceptors(packet, session, true,
false);
router.route(packet);
// Invoke the interceptors after we have processed the read packet
InterceptorManager.getInstance().invokeInterceptors(packet, session, true,
true);
session.incrementClientPacketCount();
}
catch (PacketRejectedException e) {
// An interceptor rejected this packet so answer a not_allowed error
IQ reply = new IQ();
reply.setChildElement(packet.getChildElement().createCopy());
reply.setID(packet.getID());
reply.setTo(session.getAddress());
reply.setFrom(packet.getTo());
reply.setError(PacketError.Condition.not_allowed);
session.process(reply);
// Check if a message notifying the rejection should be sent
if (e.getRejectionMessage() != null && e.getRejectionMessage().trim().length() > 0) {
// A message for the rejection will be sent to the sender of the rejected packet
Message notification = new Message();
notification.setTo(session.getAddress());
notification.setFrom(packet.getTo());
notification.setBody(e.getRejectionMessage());
session.process(notification);
}
}
}
private void processPresence(ClientSession session, Presence packet) {
packet.setFrom(session.getAddress());
try {
// Invoke the interceptors before we process the read packet
InterceptorManager.getInstance().invokeInterceptors(packet, session, true,
false);
router.route(packet);
// Invoke the interceptors after we have processed the read packet
InterceptorManager.getInstance().invokeInterceptors(packet, session, true,
true);
session.incrementClientPacketCount();
}
catch (PacketRejectedException e) {
// An interceptor rejected this packet so answer a not_allowed error
Presence reply = new Presence();
reply.setID(packet.getID());
reply.setTo(session.getAddress());
reply.setFrom(packet.getTo());
reply.setError(PacketError.Condition.not_allowed);
session.process(reply);
// Check if a message notifying the rejection should be sent
if (e.getRejectionMessage() != null && e.getRejectionMessage().trim().length() > 0) {
// A message for the rejection will be sent to the sender of the rejected packet
Message notification = new Message();
notification.setTo(session.getAddress());
notification.setFrom(packet.getTo());
notification.setBody(e.getRejectionMessage());
session.process(notification);
}
}
}
private void processMessage(ClientSession session, Message packet) {
packet.setFrom(session.getAddress());
try {
// Invoke the interceptors before we process the read packet
InterceptorManager.getInstance().invokeInterceptors(packet, session, true,
false);
router.route(packet);
// Invoke the interceptors after we have processed the read packet
InterceptorManager.getInstance().invokeInterceptors(packet, session, true,
true);
session.incrementClientPacketCount();
}
catch (PacketRejectedException e) {
// An interceptor rejected this packet
if (e.getRejectionMessage() != null && e.getRejectionMessage().trim().length() > 0) {
// A message for the rejection will be sent to the sender of the rejected packet
Message reply = new Message();
reply.setID(packet.getID());
reply.setTo(session.getAddress());
reply.setFrom(packet.getTo());
reply.setType(packet.getType());
reply.setThread(packet.getThread());
reply.setBody(e.getRejectionMessage());
session.process(reply);
}
}
}
private IQ getIQ(Element doc) {
Element query = doc.element("query");
if (query != null && "jabber:iq:roster".equals(query.getNamespaceURI())) {
return new Roster(doc);
}
else {
return new IQ(doc);
}
}
/**
* Sends an IQ error with the specified condition to the sender of the original
* IQ packet.
*
* @param packet the packet to be bounced.
* @param extraError application specific error or null if none.
* @param error the error.
*/
private void sendErrorPacket(IQ packet, PacketError.Condition error, Element extraError) {
IQ reply = IQ.createResultIQ(packet);
......@@ -316,6 +196,7 @@ public class MultiplexerPacketHandler {
*
* @param packet the packet to be bounced.
* @param extraError application specific error or null if none.
* @param error the error.
*/
private void sendErrorPacket(Route packet, PacketError.Condition error, Element extraError) {
Route reply = new Route(packet.getStreamID());
......
/**
* $RCSfile: $
* $Revision: $
* $Date: $
*
* Copyright (C) 2006 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.wildfire.multiplex;
import org.jivesoftware.wildfire.PacketRouter;
import org.jivesoftware.wildfire.ClientSession;
import org.jivesoftware.wildfire.XMPPServer;
import org.jivesoftware.wildfire.interceptor.InterceptorManager;
import org.jivesoftware.wildfire.interceptor.PacketRejectedException;
import org.jivesoftware.wildfire.net.SASLAuthentication;
import org.xmpp.packet.*;
import org.dom4j.Element;
import java.io.UnsupportedEncodingException;
/**
* Handles the routing of packets to a particular session.
*
* @author Alexander Wenckus
*/
public class MultiplexerPacketRouter {
private ClientSession session;
private PacketRouter router;
public MultiplexerPacketRouter(ClientSession session) {
this.session = session;
router = XMPPServer.getInstance().getPacketRouter();
}
public void route(Element wrappedElement)
throws UnsupportedEncodingException, UnknownStanzaException
{
String tag = wrappedElement.getName();
if ("auth".equals(tag) || "response".equals(tag)) {
SASLAuthentication.handle(session, wrappedElement);
}
else if ("iq".equals(tag)) {
route(getIQ(wrappedElement));
}
else if ("message".equals(tag)) {
route(new Message(wrappedElement));
}
else if ("presence".equals(tag)) {
route(new Presence(wrappedElement));
}
else {
throw new UnknownStanzaException();
}
}
private IQ getIQ(Element doc) {
Element query = doc.element("query");
if (query != null && "jabber:iq:roster".equals(query.getNamespaceURI())) {
return new Roster(doc);
}
else {
return new IQ(doc);
}
}
public void route(IQ packet) {
packet.setFrom(session.getAddress());
try {
// Invoke the interceptors before we process the read packet
InterceptorManager.getInstance().invokeInterceptors(packet, session, true,
false);
router.route(packet);
// Invoke the interceptors after we have processed the read packet
InterceptorManager.getInstance().invokeInterceptors(packet, session, true,
true);
session.incrementClientPacketCount();
}
catch (PacketRejectedException e) {
// An interceptor rejected this packet so answer a not_allowed error
IQ reply = new IQ();
reply.setChildElement(packet.getChildElement().createCopy());
reply.setID(packet.getID());
reply.setTo(session.getAddress());
reply.setFrom(packet.getTo());
reply.setError(PacketError.Condition.not_allowed);
session.process(reply);
// Check if a message notifying the rejection should be sent
if (e.getRejectionMessage() != null && e.getRejectionMessage().trim().length() > 0) {
// A message for the rejection will be sent to the sender of the rejected packet
Message notification = new Message();
notification.setTo(session.getAddress());
notification.setFrom(packet.getTo());
notification.setBody(e.getRejectionMessage());
session.process(notification);
}
}
}
public void route(Message packet) {
packet.setFrom(session.getAddress());
try {
// Invoke the interceptors before we process the read packet
InterceptorManager.getInstance().invokeInterceptors(packet, session, true,
false);
router.route(packet);
// Invoke the interceptors after we have processed the read packet
InterceptorManager.getInstance().invokeInterceptors(packet, session, true,
true);
session.incrementClientPacketCount();
}
catch (PacketRejectedException e) {
// An interceptor rejected this packet
if (e.getRejectionMessage() != null && e.getRejectionMessage().trim().length() > 0) {
// A message for the rejection will be sent to the sender of the rejected packet
Message reply = new Message();
reply.setID(packet.getID());
reply.setTo(session.getAddress());
reply.setFrom(packet.getTo());
reply.setType(packet.getType());
reply.setThread(packet.getThread());
reply.setBody(e.getRejectionMessage());
session.process(reply);
}
}
}
public void route(Presence packet) {
packet.setFrom(session.getAddress());
try {
// Invoke the interceptors before we process the read packet
InterceptorManager.getInstance().invokeInterceptors(packet, session, true,
false);
router.route(packet);
// Invoke the interceptors after we have processed the read packet
InterceptorManager.getInstance().invokeInterceptors(packet, session, true,
true);
session.incrementClientPacketCount();
}
catch (PacketRejectedException e) {
// An interceptor rejected this packet so answer a not_allowed error
Presence reply = new Presence();
reply.setID(packet.getID());
reply.setTo(session.getAddress());
reply.setFrom(packet.getTo());
reply.setError(PacketError.Condition.not_allowed);
session.process(reply);
// Check if a message notifying the rejection should be sent
if (e.getRejectionMessage() != null && e.getRejectionMessage().trim().length() > 0) {
// A message for the rejection will be sent to the sender of the rejected packet
Message notification = new Message();
notification.setTo(session.getAddress());
notification.setFrom(packet.getTo());
notification.setBody(e.getRejectionMessage());
session.process(notification);
}
}
}
}
/**
* $RCSfile: $
* $Revision: $
* $Date: $
*
* Copyright (C) 2006 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.wildfire.multiplex;
/**
*
*/
public class UnknownStanzaException extends Exception {
}
......@@ -12,6 +12,9 @@
package org.jivesoftware.wildfire.net;
import org.dom4j.Element;
import org.dom4j.DocumentHelper;
import org.dom4j.QName;
import org.dom4j.Namespace;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.Log;
import org.jivesoftware.util.StringUtils;
......@@ -147,6 +150,43 @@ public class SASLAuthentication {
return sb.toString();
}
public static Element getSASLMechanismsElement(Session session) {
if (!(session instanceof ClientSession) && !(session instanceof IncomingServerSession)) {
return null;
}
Element mechs = DocumentHelper.createElement(new QName("mechanisms",
new Namespace("", "urn:ietf:params:xml:ns:xmpp-sasl")));
if (session instanceof IncomingServerSession) {
// Server connections dont follow the same rules as clients
if (session.getConnection().isSecure()) {
// Offer SASL EXTERNAL only if TLS has already been negotiated
Element mechanism = mechs.addElement("mechanism");
mechanism.setText("EXTERNAL");
}
}
else {
for (String mech : mechanisms) {
if (mech.equals("CRAM-MD5") || mech.equals("DIGEST-MD5")) {
// Check if the user provider in use supports passwords retrieval. Accessing
// to the users passwords will be required by the CallbackHandler
if (!AuthFactory.getAuthProvider().supportsPasswordRetrieval()) {
continue;
}
}
else if (mech.equals("ANONYMOUS")) {
// Check anonymous is supported
if (!XMPPServer.getInstance().getIQAuthHandler().isAnonymousAllowed()) {
continue;
}
}
Element mechanism = mechs.addElement("mechanism");
mechanism.setText(mech);
}
}
return mechs;
}
/**
* Handles the SASL authentication packet. The entity may be sending an initial
* authentication request or a response to a challenge made by the server. The returned
......
......@@ -3,7 +3,7 @@
* $Revision: 1217 $
* $Date: 2005-04-11 18:11:06 -0300 (Mon, 11 Apr 2005) $
*
* Copyright (C) 2004 Jive Software. All rights reserved.
* Copyright (C) 2006 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
......@@ -36,13 +36,14 @@ public class SSLConfig {
private static String trustpass;
private static String keyStoreLocation;
private static String trustStoreLocation;
private static String storeType;
private SSLConfig() {
}
static {
String algorithm = JiveGlobals.getProperty("xmpp.socket.ssl.algorithm", "TLS");
String storeType = JiveGlobals.getProperty("xmpp.socket.ssl.storeType", "jks");
storeType = JiveGlobals.getProperty("xmpp.socket.ssl.storeType", "jks");
// Get the keystore location. The default location is security/keystore
keyStoreLocation = JiveGlobals.getProperty("xmpp.socket.ssl.keystore",
......@@ -151,4 +152,20 @@ public class SSLConfig {
return sslFactory.createServerSocket(port, -1, ifAddress);
}
}
public static String getKeystoreLocation() {
return keyStoreLocation;
}
public static String getTruststoreLocation() {
return trustStoreLocation;
}
public static String getStoreType() {
return storeType;
}
public static SSLJiveServerSocketFactory getServerSocketFactory() {
return sslFactory;
}
}
\ No newline at end of file
......@@ -15,10 +15,14 @@ import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Log;
import org.jivesoftware.wildfire.*;
import org.jivesoftware.wildfire.http.HttpSessionManager;
import org.jivesoftware.wildfire.http.HttpBindServlet;
import org.jivesoftware.wildfire.container.BasicModule;
import org.jivesoftware.wildfire.multiplex.MultiplexerPacketDeliverer;
import org.jivesoftware.wildfire.net.*;
import org.mortbay.jetty.Handler;
import org.mortbay.jetty.servlet.ServletHolder;
import org.mortbay.jetty.servlet.ServletHandler;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
......@@ -48,10 +52,12 @@ public class ConnectionManagerImpl extends BasicModule implements ConnectionMana
private boolean isStarted = false;
// Used to know if the sockets have been started
private boolean isSocketStarted = false;
private HttpServerManager serverManager;
public ConnectionManagerImpl() {
super("Connection Manager");
ports = new ArrayList<ServerPort>(4);
serverManager = HttpServerManager.getInstance();
}
private void createSocket() {
......@@ -82,6 +88,8 @@ public class ConnectionManagerImpl extends BasicModule implements ConnectionMana
startClientListeners(localIPAddress);
// Start the port listener for secured clients
startClientSSLListeners(localIPAddress);
// Start the HTTP client listener
startHTTPBindListeners();
}
private void startServerListener(String localIPAddress) {
......@@ -282,6 +290,14 @@ public class ConnectionManagerImpl extends BasicModule implements ConnectionMana
}
}
private void startHTTPBindListeners() {
serverManager.setHttpBindContext(createServletHandler(), "/http-bind/");
}
private ServletHolder createServletHandler() {
return new ServletHolder(new HttpBindServlet(new HttpSessionManager()));
}
public void initialize(XMPPServer server) {
super.initialize(server);
this.server = server;
......
......@@ -72,6 +72,11 @@
url="connection-managers-settings.jsp"
description="${sidebar.connection-managers-settings.descr}" />
<!-- HTTP binding -->
<item id="http-bind" name="${sidebar.http-bind}"
url="http-bind.jsp"
description="${sidebar.http-bind.descr}" />
<!-- Manage updates -->
<item id="manage-updates" name="${sidebar.manage-updates}"
url="manage-updates.jsp"
......
<%@ page import="org.jivesoftware.wildfire.HttpServerManager" %>
<%@ page import="org.jivesoftware.util.ParamUtils" %>
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %>
<%--
- $Revision: $
- $Date: $
-
- Copyright (C) 2006 Jive Software. All rights reserved.
-
- This software is published under the terms of the GNU Public License (GPL),
- a copy of which is included in this distribution.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %>
<%!
Map<String, String> errorMap = new HashMap<String, String>();
HttpServerManager serverManager = HttpServerManager.getInstance();
void handleUpdate(HttpServletRequest request) {
boolean isEnabled = ParamUtils.getBooleanParameter(request, "httpBindEnabled");
if (isEnabled) {
boolean httpPortsDistinct = ParamUtils.getBooleanParameter(request, "httpPortsDistinct",
false);
int requestedPort;
int requestedSecurePort;
if (httpPortsDistinct) {
requestedPort = ParamUtils.getIntParameter(request, "port", -1);
requestedSecurePort = ParamUtils.getIntParameter(request, "securePort", -1);
}
else {
requestedPort = serverManager.getAdminUnsecurePort();
requestedSecurePort = serverManager.getAdminSecurePort();
}
try {
serverManager.setHttpBindPorts(requestedPort, requestedSecurePort);
}
catch (Exception e) {
errorMap.put("port", e.getMessage());
}
}
serverManager.setHttpBindEnabled(isEnabled);
}
%>
<%
if (request.getParameter("update") != null) {
handleUpdate(request);
}
boolean isHttpBindEnabled = serverManager.isHttpBindEnabled();
boolean isHttpBindServerSperate = serverManager.isSeperateHttpBindServerConfigured();
int port = serverManager.getHttpBindUnsecurePort();
int securePort = serverManager.getHttpBindSecurePort();
%>
<html>
<head>
<title>
<fmt:message key="httpbind.settings.title"/>
</title>
<meta name="pageID" content="http-bind"/>
</head>
<body>
<p>
<fmt:message key="httpbind.settings.info"/>
</p>
<form action="http-bind.jsp" method="post">
<div class="jive-contentBoxHeader">
<fmt:message key="httpbind.settings.enabled.legend"/>
</div>
<div class="jive-contentBox">
<table cellpadding="3" cellspacing="0" border="0">
<tbody>
<tr valign="middle">
<td width="1%" nowrap>
<input type="radio" name="httpBindEnabled" value="false" id="rb01"
<%= (!isHttpBindEnabled ? "checked" : "") %>>
</td>
<td width="99%" colspan="2">
<label for="rb01">
<b>
<fmt:message key="httpbind.settings.label_disable"/>
</b> -
<fmt:message key="httpbind.settings.label_disable_info"/>
</label>
</td>
</tr>
<tr valign="middle">
<td width="1%" nowrap>
<input type="radio" name="httpBindEnabled" value="true" id="rb02"
<%= (isHttpBindEnabled ? "checked" : "") %>>
</td>
<td width="99%" colspan="2">
<label for="rb02">
<b>
<fmt:message key="httpbind.settings.label_enable"/>
</b> -
<fmt:message key="httpbind.settings.label_enable_info"/>
</label>
</td>
</tr>
<tr valign="middle">
<td width="1%">
&nbsp;
</td>
<td width="1%" nowrap>
<input type="radio" name="httpPortsDistinct" value="false" id="rb03"
<%= (!isHttpBindServerSperate ? "checked" : "") %>>
</td>
<td width="98%">
<label for="rb03">
<b>
<fmt:message key="httpbind.settings.label_seperate"/>
</b> -
<fmt:message key="httpbind.settings.label_seperate_info"/>
</label>
</td>
</tr>
<tr valign="middle">
<td width="1%">
&nbsp;
</td>
<td width="1%" nowrap>
<input type="radio" name="httpPortsDistinct" value="true" id="rb04"
<%= (isHttpBindServerSperate ? "checked" : "") %>>
</td>
<td width="98%">
<label for="rb04">
<b>
<fmt:message key="httpbind.settings.label_same"/>
</b> -
<fmt:message key="httpbind.settings.label_same_info"/>
</label>
</td>
</tr>
<tr>
<td width="1%">
&nbsp;
</td>
<td colspan="2">
<label for="port">
<fmt:message key="httpbind.settings.vanilla_port"/>
</label>
<input id="port" type="text" size="5" maxlength="10" name="port"
value="<%=port%>" />
</td>
</tr>
<tr>
<td width="1%">
&nbsp;
</td>
<td colspan="2">
<label for="securePort">
<fmt:message key="httpbind.settings.secure_port"/>
</label>
<input id="securePort" type="text" size="5" maxlength="10" name="securePort"
value="<%=securePort%>" />
</td>
</tr>
</tbody>
</table>
<input type="submit" id="settingsUpdate" name="update"
value="<fmt:message key="global.save_settings" />">
</div>
</form>
</body>
</html>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment