summaryrefslogtreecommitdiff
path: root/cpp/src/IceWS
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/IceWS')
-rw-r--r--cpp/src/IceWS/.depend11
-rw-r--r--cpp/src/IceWS/.depend.mak11
-rw-r--r--cpp/src/IceWS/.gitignore7
-rw-r--r--cpp/src/IceWS/AcceptorI.cpp87
-rw-r--r--cpp/src/IceWS/AcceptorI.h55
-rw-r--r--cpp/src/IceWS/ConnectorI.cpp114
-rw-r--r--cpp/src/IceWS/ConnectorI.h51
-rw-r--r--cpp/src/IceWS/EndpointI.cpp449
-rw-r--r--cpp/src/IceWS/EndpointI.h95
-rw-r--r--cpp/src/IceWS/IceWS.rc38
-rw-r--r--cpp/src/IceWS/Instance.cpp28
-rw-r--r--cpp/src/IceWS/Instance.h30
-rw-r--r--cpp/src/IceWS/InstanceF.h25
-rw-r--r--cpp/src/IceWS/Makefile64
-rw-r--r--cpp/src/IceWS/Makefile.mak71
-rw-r--r--cpp/src/IceWS/PluginI.cpp62
-rw-r--r--cpp/src/IceWS/PluginI.h35
-rw-r--r--cpp/src/IceWS/TransceiverI.cpp1593
-rw-r--r--cpp/src/IceWS/TransceiverI.h147
-rw-r--r--cpp/src/IceWS/Util.cpp690
-rw-r--r--cpp/src/IceWS/Util.h124
21 files changed, 3787 insertions, 0 deletions
diff --git a/cpp/src/IceWS/.depend b/cpp/src/IceWS/.depend
new file mode 100644
index 00000000000..b7e5abb2909
--- /dev/null
+++ b/cpp/src/IceWS/.depend
@@ -0,0 +1,11 @@
+AcceptorI$(OBJEXT): AcceptorI.cpp ../IceWS/AcceptorI.h $(includedir)/Ice/LoggerF.h $(includedir)/Ice/ProxyF.h $(includedir)/IceUtil/Shared.h $(includedir)/IceUtil/Config.h $(includedir)/Ice/Config.h $(includedir)/Ice/ProxyHandle.h $(includedir)/IceUtil/Handle.h $(includedir)/IceUtil/Exception.h $(includedir)/Ice/ObjectF.h $(includedir)/Ice/Handle.h $(includedir)/Ice/Exception.h $(includedir)/Ice/Format.h $(includedir)/Ice/StreamF.h $(includedir)/Ice/LocalObject.h $(includedir)/Ice/LocalObjectF.h $(includedir)/Ice/StreamHelpers.h $(includedir)/IceUtil/ScopedArray.h $(includedir)/IceUtil/Iterator.h $(includedir)/IceUtil/Optional.h $(includedir)/Ice/UndefSysMacros.h ../Ice/TransceiverF.h ../Ice/Acceptor.h ../Ice/AcceptorF.h ../Ice/Network.h ../Ice/NetworkF.h $(includedir)/Ice/PropertiesF.h $(includedir)/Ice/Proxy.h $(includedir)/IceUtil/Mutex.h $(includedir)/IceUtil/Lock.h $(includedir)/IceUtil/ThreadException.h $(includedir)/IceUtil/Time.h $(includedir)/IceUtil/MutexProtocol.h $(includedir)/Ice/ProxyFactoryF.h $(includedir)/Ice/ConnectionIF.h $(includedir)/Ice/RequestHandlerF.h $(includedir)/Ice/EndpointF.h $(includedir)/Ice/EndpointTypes.h $(includedir)/Ice/ObjectAdapterF.h $(includedir)/Ice/ReferenceF.h $(includedir)/Ice/OutgoingAsync.h $(includedir)/IceUtil/Monitor.h $(includedir)/IceUtil/Cond.h $(includedir)/IceUtil/Timer.h $(includedir)/IceUtil/Thread.h $(includedir)/IceUtil/UniquePtr.h $(includedir)/Ice/OutgoingAsyncF.h $(includedir)/Ice/InstanceF.h $(includedir)/Ice/CommunicatorF.h $(includedir)/Ice/Current.h $(includedir)/Ice/ConnectionF.h $(includedir)/Ice/Identity.h $(includedir)/Ice/Version.h $(includedir)/Ice/BasicStream.h $(includedir)/Ice/Object.h $(includedir)/Ice/GCShared.h $(includedir)/Ice/GCCountMap.h $(includedir)/Ice/IncomingAsyncF.h $(includedir)/Ice/ObjectFactoryF.h $(includedir)/Ice/ObjectFactoryManagerF.h $(includedir)/Ice/Buffer.h $(includedir)/Ice/Protocol.h $(includedir)/Ice/SlicedDataF.h $(includedir)/Ice/UserExceptionFactory.h $(includedir)/Ice/FactoryTable.h $(includedir)/Ice/ObserverHelper.h $(includedir)/Ice/Instrumentation.h ../IceWS/InstanceF.h ../IceWS/Instance.h ../Ice/ProtocolInstance.h ../Ice/ProtocolInstanceF.h $(includedir)/Ice/StatsF.h ../Ice/EndpointIF.h ../Ice/ConnectorF.h ../Ice/IPEndpointIF.h ../IceWS/TransceiverI.h $(includedir)/IceWS/Plugin.h $(includedir)/Ice/Plugin.h $(includedir)/Ice/BuiltinSequences.h ../IceWS/Util.h ../Ice/Transceiver.h
+ConnectorI$(OBJEXT): ConnectorI.cpp ../IceWS/ConnectorI.h $(includedir)/Ice/LoggerF.h $(includedir)/Ice/ProxyF.h $(includedir)/IceUtil/Shared.h $(includedir)/IceUtil/Config.h $(includedir)/Ice/Config.h $(includedir)/Ice/ProxyHandle.h $(includedir)/IceUtil/Handle.h $(includedir)/IceUtil/Exception.h $(includedir)/Ice/ObjectF.h $(includedir)/Ice/Handle.h $(includedir)/Ice/Exception.h $(includedir)/Ice/Format.h $(includedir)/Ice/StreamF.h $(includedir)/Ice/LocalObject.h $(includedir)/Ice/LocalObjectF.h $(includedir)/Ice/StreamHelpers.h $(includedir)/IceUtil/ScopedArray.h $(includedir)/IceUtil/Iterator.h $(includedir)/IceUtil/Optional.h $(includedir)/Ice/UndefSysMacros.h ../Ice/TransceiverF.h ../Ice/Connector.h ../Ice/ConnectorF.h ../IceWS/InstanceF.h ../IceWS/Instance.h ../Ice/ProtocolInstance.h ../Ice/ProtocolInstanceF.h $(includedir)/Ice/CommunicatorF.h $(includedir)/Ice/PropertiesF.h $(includedir)/Ice/Proxy.h $(includedir)/IceUtil/Mutex.h $(includedir)/IceUtil/Lock.h $(includedir)/IceUtil/ThreadException.h $(includedir)/IceUtil/Time.h $(includedir)/IceUtil/MutexProtocol.h $(includedir)/Ice/ProxyFactoryF.h $(includedir)/Ice/ConnectionIF.h $(includedir)/Ice/RequestHandlerF.h $(includedir)/Ice/EndpointF.h $(includedir)/Ice/EndpointTypes.h $(includedir)/Ice/ObjectAdapterF.h $(includedir)/Ice/ReferenceF.h $(includedir)/Ice/OutgoingAsync.h $(includedir)/IceUtil/Monitor.h $(includedir)/IceUtil/Cond.h $(includedir)/IceUtil/Timer.h $(includedir)/IceUtil/Thread.h $(includedir)/IceUtil/UniquePtr.h $(includedir)/Ice/OutgoingAsyncF.h $(includedir)/Ice/InstanceF.h $(includedir)/Ice/Current.h $(includedir)/Ice/ConnectionF.h $(includedir)/Ice/Identity.h $(includedir)/Ice/Version.h $(includedir)/Ice/BasicStream.h $(includedir)/Ice/Object.h $(includedir)/Ice/GCShared.h $(includedir)/Ice/GCCountMap.h $(includedir)/Ice/IncomingAsyncF.h $(includedir)/Ice/ObjectFactoryF.h $(includedir)/Ice/ObjectFactoryManagerF.h $(includedir)/Ice/Buffer.h $(includedir)/Ice/Protocol.h $(includedir)/Ice/SlicedDataF.h $(includedir)/Ice/UserExceptionFactory.h $(includedir)/Ice/FactoryTable.h $(includedir)/Ice/ObserverHelper.h $(includedir)/Ice/Instrumentation.h $(includedir)/Ice/StatsF.h ../Ice/EndpointIF.h ../Ice/IPEndpointIF.h ../Ice/NetworkF.h ../IceWS/TransceiverI.h $(includedir)/IceWS/Plugin.h $(includedir)/Ice/Plugin.h $(includedir)/Ice/BuiltinSequences.h ../IceWS/Util.h ../Ice/Transceiver.h ../Ice/Network.h ../IceWS/EndpointI.h ../Ice/EndpointI.h $(includedir)/Ice/Endpoint.h ../Ice/AcceptorF.h ../Ice/EndpointFactory.h ../Ice/EndpointFactoryF.h $(includedir)/IceWS/EndpointInfo.h
+EndpointInfo$(OBJEXT): EndpointInfo.cpp $(includedir)/IceWS/EndpointInfo.h $(includedir)/Ice/ProxyF.h $(includedir)/IceUtil/Shared.h $(includedir)/IceUtil/Config.h $(includedir)/Ice/Config.h $(includedir)/Ice/ProxyHandle.h $(includedir)/IceUtil/Handle.h $(includedir)/IceUtil/Exception.h $(includedir)/Ice/ObjectF.h $(includedir)/Ice/Handle.h $(includedir)/Ice/Exception.h $(includedir)/Ice/Format.h $(includedir)/Ice/StreamF.h $(includedir)/Ice/LocalObject.h $(includedir)/Ice/LocalObjectF.h $(includedir)/Ice/StreamHelpers.h $(includedir)/IceUtil/ScopedArray.h $(includedir)/IceUtil/Iterator.h $(includedir)/IceUtil/Optional.h $(includedir)/Ice/Endpoint.h $(includedir)/Ice/Version.h $(includedir)/Ice/UndefSysMacros.h $(includedir)/Ice/BuiltinSequences.h $(includedir)/Ice/EndpointF.h $(includedir)/Ice/BasicStream.h $(includedir)/Ice/InstanceF.h $(includedir)/Ice/Object.h $(includedir)/IceUtil/Mutex.h $(includedir)/IceUtil/Lock.h $(includedir)/IceUtil/ThreadException.h $(includedir)/IceUtil/Time.h $(includedir)/IceUtil/MutexProtocol.h $(includedir)/Ice/GCShared.h $(includedir)/Ice/GCCountMap.h $(includedir)/Ice/IncomingAsyncF.h $(includedir)/Ice/Current.h $(includedir)/Ice/ObjectAdapterF.h $(includedir)/Ice/ConnectionF.h $(includedir)/Ice/Identity.h $(includedir)/Ice/ObjectFactoryF.h $(includedir)/Ice/ObjectFactoryManagerF.h $(includedir)/Ice/Buffer.h $(includedir)/Ice/Protocol.h $(includedir)/Ice/SlicedDataF.h $(includedir)/Ice/UserExceptionFactory.h $(includedir)/Ice/FactoryTable.h $(includedir)/IceUtil/DisableWarnings.h
+ConnectionInfo$(OBJEXT): ConnectionInfo.cpp $(includedir)/IceWS/ConnectionInfo.h $(includedir)/Ice/ProxyF.h $(includedir)/IceUtil/Shared.h $(includedir)/IceUtil/Config.h $(includedir)/Ice/Config.h $(includedir)/Ice/ProxyHandle.h $(includedir)/IceUtil/Handle.h $(includedir)/IceUtil/Exception.h $(includedir)/Ice/ObjectF.h $(includedir)/Ice/Handle.h $(includedir)/Ice/Exception.h $(includedir)/Ice/Format.h $(includedir)/Ice/StreamF.h $(includedir)/Ice/LocalObject.h $(includedir)/Ice/LocalObjectF.h $(includedir)/Ice/StreamHelpers.h $(includedir)/IceUtil/ScopedArray.h $(includedir)/IceUtil/Iterator.h $(includedir)/Ice/Proxy.h $(includedir)/IceUtil/Mutex.h $(includedir)/IceUtil/Lock.h $(includedir)/IceUtil/ThreadException.h $(includedir)/IceUtil/Time.h $(includedir)/IceUtil/MutexProtocol.h $(includedir)/Ice/ProxyFactoryF.h $(includedir)/Ice/ConnectionIF.h $(includedir)/Ice/RequestHandlerF.h $(includedir)/Ice/EndpointF.h $(includedir)/IceUtil/Optional.h $(includedir)/Ice/UndefSysMacros.h $(includedir)/Ice/EndpointTypes.h $(includedir)/Ice/ObjectAdapterF.h $(includedir)/Ice/ReferenceF.h $(includedir)/Ice/OutgoingAsync.h $(includedir)/IceUtil/Monitor.h $(includedir)/IceUtil/Cond.h $(includedir)/IceUtil/Timer.h $(includedir)/IceUtil/Thread.h $(includedir)/IceUtil/UniquePtr.h $(includedir)/Ice/OutgoingAsyncF.h $(includedir)/Ice/InstanceF.h $(includedir)/Ice/CommunicatorF.h $(includedir)/Ice/Current.h $(includedir)/Ice/ConnectionF.h $(includedir)/Ice/Identity.h $(includedir)/Ice/Version.h $(includedir)/Ice/BasicStream.h $(includedir)/Ice/Object.h $(includedir)/Ice/GCShared.h $(includedir)/Ice/GCCountMap.h $(includedir)/Ice/IncomingAsyncF.h $(includedir)/Ice/ObjectFactoryF.h $(includedir)/Ice/ObjectFactoryManagerF.h $(includedir)/Ice/Buffer.h $(includedir)/Ice/Protocol.h $(includedir)/Ice/SlicedDataF.h $(includedir)/Ice/UserExceptionFactory.h $(includedir)/Ice/FactoryTable.h $(includedir)/Ice/ObserverHelper.h $(includedir)/Ice/Instrumentation.h $(includedir)/Ice/Connection.h $(includedir)/Ice/Endpoint.h $(includedir)/Ice/BuiltinSequences.h $(includedir)/IceUtil/DisableWarnings.h
+EndpointI$(OBJEXT): EndpointI.cpp ../IceWS/EndpointI.h ../Ice/EndpointI.h ../Ice/EndpointIF.h $(includedir)/IceUtil/Shared.h $(includedir)/IceUtil/Config.h $(includedir)/Ice/Handle.h $(includedir)/IceUtil/Handle.h $(includedir)/IceUtil/Exception.h $(includedir)/Ice/Config.h $(includedir)/Ice/Endpoint.h $(includedir)/Ice/ProxyF.h $(includedir)/Ice/ProxyHandle.h $(includedir)/Ice/ObjectF.h $(includedir)/Ice/Exception.h $(includedir)/Ice/Format.h $(includedir)/Ice/StreamF.h $(includedir)/Ice/LocalObject.h $(includedir)/Ice/LocalObjectF.h $(includedir)/Ice/StreamHelpers.h $(includedir)/IceUtil/ScopedArray.h $(includedir)/IceUtil/Iterator.h $(includedir)/IceUtil/Optional.h $(includedir)/Ice/Version.h $(includedir)/Ice/UndefSysMacros.h $(includedir)/Ice/BuiltinSequences.h $(includedir)/Ice/EndpointF.h $(includedir)/Ice/EndpointTypes.h ../Ice/TransceiverF.h ../Ice/ConnectorF.h ../Ice/AcceptorF.h ../Ice/IPEndpointIF.h ../Ice/EndpointFactory.h ../Ice/EndpointFactoryF.h ../Ice/ProtocolInstanceF.h ../IceWS/InstanceF.h $(includedir)/IceWS/EndpointInfo.h ../IceWS/AcceptorI.h $(includedir)/Ice/LoggerF.h ../Ice/Acceptor.h ../Ice/Network.h ../Ice/NetworkF.h $(includedir)/Ice/PropertiesF.h $(includedir)/Ice/Proxy.h $(includedir)/IceUtil/Mutex.h $(includedir)/IceUtil/Lock.h $(includedir)/IceUtil/ThreadException.h $(includedir)/IceUtil/Time.h $(includedir)/IceUtil/MutexProtocol.h $(includedir)/Ice/ProxyFactoryF.h $(includedir)/Ice/ConnectionIF.h $(includedir)/Ice/RequestHandlerF.h $(includedir)/Ice/ObjectAdapterF.h $(includedir)/Ice/ReferenceF.h $(includedir)/Ice/OutgoingAsync.h $(includedir)/IceUtil/Monitor.h $(includedir)/IceUtil/Cond.h $(includedir)/IceUtil/Timer.h $(includedir)/IceUtil/Thread.h $(includedir)/IceUtil/UniquePtr.h $(includedir)/Ice/OutgoingAsyncF.h $(includedir)/Ice/InstanceF.h $(includedir)/Ice/CommunicatorF.h $(includedir)/Ice/Current.h $(includedir)/Ice/ConnectionF.h $(includedir)/Ice/Identity.h $(includedir)/Ice/BasicStream.h $(includedir)/Ice/Object.h $(includedir)/Ice/GCShared.h $(includedir)/Ice/GCCountMap.h $(includedir)/Ice/IncomingAsyncF.h $(includedir)/Ice/ObjectFactoryF.h $(includedir)/Ice/ObjectFactoryManagerF.h $(includedir)/Ice/Buffer.h $(includedir)/Ice/Protocol.h $(includedir)/Ice/SlicedDataF.h $(includedir)/Ice/UserExceptionFactory.h $(includedir)/Ice/FactoryTable.h $(includedir)/Ice/ObserverHelper.h $(includedir)/Ice/Instrumentation.h ../IceWS/ConnectorI.h ../Ice/Connector.h ../IceWS/TransceiverI.h $(includedir)/IceWS/Plugin.h $(includedir)/Ice/Plugin.h ../IceWS/Util.h $(includedir)/Ice/StatsF.h ../Ice/Transceiver.h ../IceWS/Instance.h ../Ice/ProtocolInstance.h $(includedir)/Ice/LocalException.h ../Ice/IPEndpointI.h ../Ice/HashUtil.h
+Instance$(OBJEXT): Instance.cpp ../IceWS/Instance.h ../IceWS/InstanceF.h $(includedir)/IceUtil/Shared.h $(includedir)/IceUtil/Config.h $(includedir)/Ice/Handle.h $(includedir)/IceUtil/Handle.h $(includedir)/IceUtil/Exception.h $(includedir)/Ice/Config.h ../Ice/ProtocolInstance.h ../Ice/ProtocolInstanceF.h $(includedir)/Ice/CommunicatorF.h $(includedir)/Ice/ProxyF.h $(includedir)/Ice/ProxyHandle.h $(includedir)/Ice/ObjectF.h $(includedir)/Ice/Exception.h $(includedir)/Ice/Format.h $(includedir)/Ice/StreamF.h $(includedir)/Ice/LocalObject.h $(includedir)/Ice/LocalObjectF.h $(includedir)/Ice/StreamHelpers.h $(includedir)/IceUtil/ScopedArray.h $(includedir)/IceUtil/Iterator.h $(includedir)/IceUtil/Optional.h $(includedir)/Ice/UndefSysMacros.h $(includedir)/Ice/PropertiesF.h $(includedir)/Ice/Proxy.h $(includedir)/IceUtil/Mutex.h $(includedir)/IceUtil/Lock.h $(includedir)/IceUtil/ThreadException.h $(includedir)/IceUtil/Time.h $(includedir)/IceUtil/MutexProtocol.h $(includedir)/Ice/ProxyFactoryF.h $(includedir)/Ice/ConnectionIF.h $(includedir)/Ice/RequestHandlerF.h $(includedir)/Ice/EndpointF.h $(includedir)/Ice/EndpointTypes.h $(includedir)/Ice/ObjectAdapterF.h $(includedir)/Ice/ReferenceF.h $(includedir)/Ice/OutgoingAsync.h $(includedir)/IceUtil/Monitor.h $(includedir)/IceUtil/Cond.h $(includedir)/IceUtil/Timer.h $(includedir)/IceUtil/Thread.h $(includedir)/IceUtil/UniquePtr.h $(includedir)/Ice/OutgoingAsyncF.h $(includedir)/Ice/InstanceF.h $(includedir)/Ice/Current.h $(includedir)/Ice/ConnectionF.h $(includedir)/Ice/Identity.h $(includedir)/Ice/Version.h $(includedir)/Ice/BasicStream.h $(includedir)/Ice/Object.h $(includedir)/Ice/GCShared.h $(includedir)/Ice/GCCountMap.h $(includedir)/Ice/IncomingAsyncF.h $(includedir)/Ice/ObjectFactoryF.h $(includedir)/Ice/ObjectFactoryManagerF.h $(includedir)/Ice/Buffer.h $(includedir)/Ice/Protocol.h $(includedir)/Ice/SlicedDataF.h $(includedir)/Ice/UserExceptionFactory.h $(includedir)/Ice/FactoryTable.h $(includedir)/Ice/ObserverHelper.h $(includedir)/Ice/Instrumentation.h $(includedir)/Ice/LoggerF.h $(includedir)/Ice/StatsF.h ../Ice/EndpointIF.h ../Ice/ConnectorF.h ../Ice/IPEndpointIF.h ../Ice/NetworkF.h ../IceWS/EndpointI.h ../Ice/EndpointI.h $(includedir)/Ice/Endpoint.h $(includedir)/Ice/BuiltinSequences.h ../Ice/TransceiverF.h ../Ice/AcceptorF.h ../Ice/EndpointFactory.h ../Ice/EndpointFactoryF.h $(includedir)/IceWS/EndpointInfo.h ../Ice/ProtocolPluginFacade.h ../Ice/ProtocolPluginFacadeF.h
+PluginI$(OBJEXT): PluginI.cpp ../IceWS/PluginI.h $(includedir)/IceWS/Plugin.h $(includedir)/Ice/Plugin.h $(includedir)/Ice/ProxyF.h $(includedir)/IceUtil/Shared.h $(includedir)/IceUtil/Config.h $(includedir)/Ice/Config.h $(includedir)/Ice/ProxyHandle.h $(includedir)/IceUtil/Handle.h $(includedir)/IceUtil/Exception.h $(includedir)/Ice/ObjectF.h $(includedir)/Ice/Handle.h $(includedir)/Ice/Exception.h $(includedir)/Ice/Format.h $(includedir)/Ice/StreamF.h $(includedir)/Ice/LocalObject.h $(includedir)/Ice/LocalObjectF.h $(includedir)/Ice/StreamHelpers.h $(includedir)/IceUtil/ScopedArray.h $(includedir)/IceUtil/Iterator.h $(includedir)/IceUtil/Optional.h $(includedir)/Ice/LoggerF.h $(includedir)/Ice/UndefSysMacros.h $(includedir)/Ice/BuiltinSequences.h ../IceWS/InstanceF.h $(includedir)/Ice/CommunicatorF.h ../IceWS/Instance.h ../Ice/ProtocolInstance.h ../Ice/ProtocolInstanceF.h $(includedir)/Ice/PropertiesF.h $(includedir)/Ice/Proxy.h $(includedir)/IceUtil/Mutex.h $(includedir)/IceUtil/Lock.h $(includedir)/IceUtil/ThreadException.h $(includedir)/IceUtil/Time.h $(includedir)/IceUtil/MutexProtocol.h $(includedir)/Ice/ProxyFactoryF.h $(includedir)/Ice/ConnectionIF.h $(includedir)/Ice/RequestHandlerF.h $(includedir)/Ice/EndpointF.h $(includedir)/Ice/EndpointTypes.h $(includedir)/Ice/ObjectAdapterF.h $(includedir)/Ice/ReferenceF.h $(includedir)/Ice/OutgoingAsync.h $(includedir)/IceUtil/Monitor.h $(includedir)/IceUtil/Cond.h $(includedir)/IceUtil/Timer.h $(includedir)/IceUtil/Thread.h $(includedir)/IceUtil/UniquePtr.h $(includedir)/Ice/OutgoingAsyncF.h $(includedir)/Ice/InstanceF.h $(includedir)/Ice/Current.h $(includedir)/Ice/ConnectionF.h $(includedir)/Ice/Identity.h $(includedir)/Ice/Version.h $(includedir)/Ice/BasicStream.h $(includedir)/Ice/Object.h $(includedir)/Ice/GCShared.h $(includedir)/Ice/GCCountMap.h $(includedir)/Ice/IncomingAsyncF.h $(includedir)/Ice/ObjectFactoryF.h $(includedir)/Ice/ObjectFactoryManagerF.h $(includedir)/Ice/Buffer.h $(includedir)/Ice/Protocol.h $(includedir)/Ice/SlicedDataF.h $(includedir)/Ice/UserExceptionFactory.h $(includedir)/Ice/FactoryTable.h $(includedir)/Ice/ObserverHelper.h $(includedir)/Ice/Instrumentation.h $(includedir)/Ice/StatsF.h ../Ice/EndpointIF.h ../Ice/ConnectorF.h ../Ice/IPEndpointIF.h ../Ice/NetworkF.h ../IceWS/EndpointI.h ../Ice/EndpointI.h $(includedir)/Ice/Endpoint.h ../Ice/TransceiverF.h ../Ice/AcceptorF.h ../Ice/EndpointFactory.h ../Ice/EndpointFactoryF.h $(includedir)/IceWS/EndpointInfo.h ../Ice/ProtocolPluginFacade.h ../Ice/ProtocolPluginFacadeF.h
+TransceiverI$(OBJEXT): TransceiverI.cpp ../IceWS/TransceiverI.h ../IceWS/InstanceF.h $(includedir)/IceUtil/Shared.h $(includedir)/IceUtil/Config.h $(includedir)/Ice/Handle.h $(includedir)/IceUtil/Handle.h $(includedir)/IceUtil/Exception.h $(includedir)/Ice/Config.h $(includedir)/IceWS/Plugin.h $(includedir)/Ice/Plugin.h $(includedir)/Ice/ProxyF.h $(includedir)/Ice/ProxyHandle.h $(includedir)/Ice/ObjectF.h $(includedir)/Ice/Exception.h $(includedir)/Ice/Format.h $(includedir)/Ice/StreamF.h $(includedir)/Ice/LocalObject.h $(includedir)/Ice/LocalObjectF.h $(includedir)/Ice/StreamHelpers.h $(includedir)/IceUtil/ScopedArray.h $(includedir)/IceUtil/Iterator.h $(includedir)/IceUtil/Optional.h $(includedir)/Ice/LoggerF.h $(includedir)/Ice/UndefSysMacros.h $(includedir)/Ice/BuiltinSequences.h ../IceWS/Util.h $(includedir)/Ice/StatsF.h ../Ice/Transceiver.h ../Ice/TransceiverF.h $(includedir)/Ice/ConnectionF.h ../Ice/Network.h ../Ice/NetworkF.h $(includedir)/Ice/PropertiesF.h $(includedir)/Ice/Proxy.h $(includedir)/IceUtil/Mutex.h $(includedir)/IceUtil/Lock.h $(includedir)/IceUtil/ThreadException.h $(includedir)/IceUtil/Time.h $(includedir)/IceUtil/MutexProtocol.h $(includedir)/Ice/ProxyFactoryF.h $(includedir)/Ice/ConnectionIF.h $(includedir)/Ice/RequestHandlerF.h $(includedir)/Ice/EndpointF.h $(includedir)/Ice/EndpointTypes.h $(includedir)/Ice/ObjectAdapterF.h $(includedir)/Ice/ReferenceF.h $(includedir)/Ice/OutgoingAsync.h $(includedir)/IceUtil/Monitor.h $(includedir)/IceUtil/Cond.h $(includedir)/IceUtil/Timer.h $(includedir)/IceUtil/Thread.h $(includedir)/IceUtil/UniquePtr.h $(includedir)/Ice/OutgoingAsyncF.h $(includedir)/Ice/InstanceF.h $(includedir)/Ice/CommunicatorF.h $(includedir)/Ice/Current.h $(includedir)/Ice/Identity.h $(includedir)/Ice/Version.h $(includedir)/Ice/BasicStream.h $(includedir)/Ice/Object.h $(includedir)/Ice/GCShared.h $(includedir)/Ice/GCCountMap.h $(includedir)/Ice/IncomingAsyncF.h $(includedir)/Ice/ObjectFactoryF.h $(includedir)/Ice/ObjectFactoryManagerF.h $(includedir)/Ice/Buffer.h $(includedir)/Ice/Protocol.h $(includedir)/Ice/SlicedDataF.h $(includedir)/Ice/UserExceptionFactory.h $(includedir)/Ice/FactoryTable.h $(includedir)/Ice/ObserverHelper.h $(includedir)/Ice/Instrumentation.h $(includedir)/IceWS/EndpointInfo.h $(includedir)/Ice/Endpoint.h $(includedir)/IceWS/ConnectionInfo.h $(includedir)/Ice/Connection.h ../IceWS/Instance.h ../Ice/ProtocolInstance.h ../Ice/ProtocolInstanceF.h ../Ice/EndpointIF.h ../Ice/ConnectorF.h ../Ice/IPEndpointIF.h $(includedir)/Ice/Communicator.h $(includedir)/Ice/Outgoing.h $(includedir)/Ice/Incoming.h $(includedir)/Ice/ServantLocatorF.h $(includedir)/Ice/ServantManagerF.h $(includedir)/Ice/IncomingAsync.h $(includedir)/Ice/Direct.h $(includedir)/Ice/InstrumentationF.h $(includedir)/Ice/RouterF.h $(includedir)/Ice/LocatorF.h $(includedir)/Ice/PluginF.h $(includedir)/Ice/ImplicitContextF.h $(includedir)/Ice/Properties.h $(includedir)/Ice/PropertiesAdmin.h $(includedir)/Ice/LoggerUtil.h $(includedir)/Ice/Logger.h $(includedir)/Ice/LocalException.h $(includedir)/Ice/Stats.h ../Ice/Base64.h $(includedir)/IceUtil/Random.h $(includedir)/IceUtil/StringUtil.h $(includedir)/IceUtil/DisableWarnings.h
+Util$(OBJEXT): Util.cpp $(includedir)/IceUtil/Config.h ../IceWS/Util.h $(includedir)/IceUtil/Shared.h $(includedir)/IceUtil/Handle.h $(includedir)/IceUtil/Exception.h $(includedir)/Ice/Config.h $(includedir)/Ice/LocalException.h $(includedir)/Ice/ProxyF.h $(includedir)/Ice/ProxyHandle.h $(includedir)/Ice/ObjectF.h $(includedir)/Ice/Handle.h $(includedir)/Ice/Exception.h $(includedir)/Ice/Format.h $(includedir)/Ice/StreamF.h $(includedir)/Ice/LocalObject.h $(includedir)/Ice/LocalObjectF.h $(includedir)/Ice/StreamHelpers.h $(includedir)/IceUtil/ScopedArray.h $(includedir)/IceUtil/Iterator.h $(includedir)/IceUtil/Optional.h $(includedir)/Ice/Identity.h $(includedir)/Ice/UndefSysMacros.h $(includedir)/Ice/Version.h $(includedir)/Ice/BuiltinSequences.h $(includedir)/IceUtil/StringUtil.h $(includedir)/IceUtil/DisableWarnings.h
+$(HDIR)/EndpointInfo.h EndpointInfo.cpp: $(slicedir)/IceWS/EndpointInfo.ice $(slicedir)/Ice/Endpoint.ice $(slicedir)/Ice/Version.ice $(slicedir)/Ice/BuiltinSequences.ice $(slicedir)/Ice/EndpointF.ice $(SLICE2CPP) $(SLICEPARSERLIB)
+$(HDIR)/ConnectionInfo.h ConnectionInfo.cpp: $(slicedir)/IceWS/ConnectionInfo.ice $(slicedir)/Ice/Connection.ice $(slicedir)/Ice/ObjectAdapterF.ice $(slicedir)/Ice/Identity.ice $(slicedir)/Ice/Endpoint.ice $(slicedir)/Ice/Version.ice $(slicedir)/Ice/BuiltinSequences.ice $(slicedir)/Ice/EndpointF.ice $(SLICE2CPP) $(SLICEPARSERLIB)
diff --git a/cpp/src/IceWS/.depend.mak b/cpp/src/IceWS/.depend.mak
new file mode 100644
index 00000000000..353e3f4b5cd
--- /dev/null
+++ b/cpp/src/IceWS/.depend.mak
@@ -0,0 +1,11 @@
+AcceptorI$(OBJEXT): AcceptorI.cpp ../IceWS/AcceptorI.h "$(includedir)/Ice/LoggerF.h" "$(includedir)/Ice/ProxyF.h" "$(includedir)/IceUtil/Shared.h" "$(includedir)/IceUtil/Config.h" "$(includedir)/Ice/Config.h" "$(includedir)/Ice/ProxyHandle.h" "$(includedir)/IceUtil/Handle.h" "$(includedir)/IceUtil/Exception.h" "$(includedir)/Ice/ObjectF.h" "$(includedir)/Ice/Handle.h" "$(includedir)/Ice/Exception.h" "$(includedir)/Ice/Format.h" "$(includedir)/Ice/StreamF.h" "$(includedir)/Ice/LocalObject.h" "$(includedir)/Ice/LocalObjectF.h" "$(includedir)/Ice/StreamHelpers.h" "$(includedir)/IceUtil/ScopedArray.h" "$(includedir)/IceUtil/Iterator.h" "$(includedir)/IceUtil/Optional.h" "$(includedir)/Ice/UndefSysMacros.h" ../Ice/TransceiverF.h ../Ice/Acceptor.h ../Ice/AcceptorF.h ../Ice/Network.h ../Ice/NetworkF.h "$(includedir)/Ice/PropertiesF.h" "$(includedir)/Ice/Proxy.h" "$(includedir)/IceUtil/Mutex.h" "$(includedir)/IceUtil/Lock.h" "$(includedir)/IceUtil/ThreadException.h" "$(includedir)/IceUtil/Time.h" "$(includedir)/IceUtil/MutexProtocol.h" "$(includedir)/Ice/ProxyFactoryF.h" "$(includedir)/Ice/ConnectionIF.h" "$(includedir)/Ice/RequestHandlerF.h" "$(includedir)/Ice/EndpointF.h" "$(includedir)/Ice/EndpointTypes.h" "$(includedir)/Ice/ObjectAdapterF.h" "$(includedir)/Ice/ReferenceF.h" "$(includedir)/Ice/OutgoingAsync.h" "$(includedir)/IceUtil/Monitor.h" "$(includedir)/IceUtil/Cond.h" "$(includedir)/IceUtil/Timer.h" "$(includedir)/IceUtil/Thread.h" "$(includedir)/IceUtil/UniquePtr.h" "$(includedir)/Ice/OutgoingAsyncF.h" "$(includedir)/Ice/InstanceF.h" "$(includedir)/Ice/CommunicatorF.h" "$(includedir)/Ice/Current.h" "$(includedir)/Ice/ConnectionF.h" "$(includedir)/Ice/Identity.h" "$(includedir)/Ice/Version.h" "$(includedir)/Ice/BasicStream.h" "$(includedir)/Ice/Object.h" "$(includedir)/Ice/GCShared.h" "$(includedir)/Ice/GCCountMap.h" "$(includedir)/Ice/IncomingAsyncF.h" "$(includedir)/Ice/ObjectFactoryF.h" "$(includedir)/Ice/ObjectFactoryManagerF.h" "$(includedir)/Ice/Buffer.h" "$(includedir)/Ice/Protocol.h" "$(includedir)/Ice/SlicedDataF.h" "$(includedir)/Ice/UserExceptionFactory.h" "$(includedir)/Ice/FactoryTable.h" "$(includedir)/Ice/ObserverHelper.h" "$(includedir)/Ice/Instrumentation.h" ../IceWS/InstanceF.h ../IceWS/Instance.h ../Ice/ProtocolInstance.h ../Ice/ProtocolInstanceF.h "$(includedir)/Ice/StatsF.h" ../Ice/EndpointIF.h ../Ice/ConnectorF.h ../Ice/IPEndpointIF.h ../IceWS/TransceiverI.h "$(includedir)/IceWS/Plugin.h" "$(includedir)/Ice/Plugin.h" "$(includedir)/Ice/BuiltinSequences.h" ../IceWS/Util.h ../Ice/Transceiver.h
+ConnectorI$(OBJEXT): ConnectorI.cpp ../IceWS/ConnectorI.h "$(includedir)/Ice/LoggerF.h" "$(includedir)/Ice/ProxyF.h" "$(includedir)/IceUtil/Shared.h" "$(includedir)/IceUtil/Config.h" "$(includedir)/Ice/Config.h" "$(includedir)/Ice/ProxyHandle.h" "$(includedir)/IceUtil/Handle.h" "$(includedir)/IceUtil/Exception.h" "$(includedir)/Ice/ObjectF.h" "$(includedir)/Ice/Handle.h" "$(includedir)/Ice/Exception.h" "$(includedir)/Ice/Format.h" "$(includedir)/Ice/StreamF.h" "$(includedir)/Ice/LocalObject.h" "$(includedir)/Ice/LocalObjectF.h" "$(includedir)/Ice/StreamHelpers.h" "$(includedir)/IceUtil/ScopedArray.h" "$(includedir)/IceUtil/Iterator.h" "$(includedir)/IceUtil/Optional.h" "$(includedir)/Ice/UndefSysMacros.h" ../Ice/TransceiverF.h ../Ice/Connector.h ../Ice/ConnectorF.h ../IceWS/InstanceF.h ../IceWS/Instance.h ../Ice/ProtocolInstance.h ../Ice/ProtocolInstanceF.h "$(includedir)/Ice/CommunicatorF.h" "$(includedir)/Ice/PropertiesF.h" "$(includedir)/Ice/Proxy.h" "$(includedir)/IceUtil/Mutex.h" "$(includedir)/IceUtil/Lock.h" "$(includedir)/IceUtil/ThreadException.h" "$(includedir)/IceUtil/Time.h" "$(includedir)/IceUtil/MutexProtocol.h" "$(includedir)/Ice/ProxyFactoryF.h" "$(includedir)/Ice/ConnectionIF.h" "$(includedir)/Ice/RequestHandlerF.h" "$(includedir)/Ice/EndpointF.h" "$(includedir)/Ice/EndpointTypes.h" "$(includedir)/Ice/ObjectAdapterF.h" "$(includedir)/Ice/ReferenceF.h" "$(includedir)/Ice/OutgoingAsync.h" "$(includedir)/IceUtil/Monitor.h" "$(includedir)/IceUtil/Cond.h" "$(includedir)/IceUtil/Timer.h" "$(includedir)/IceUtil/Thread.h" "$(includedir)/IceUtil/UniquePtr.h" "$(includedir)/Ice/OutgoingAsyncF.h" "$(includedir)/Ice/InstanceF.h" "$(includedir)/Ice/Current.h" "$(includedir)/Ice/ConnectionF.h" "$(includedir)/Ice/Identity.h" "$(includedir)/Ice/Version.h" "$(includedir)/Ice/BasicStream.h" "$(includedir)/Ice/Object.h" "$(includedir)/Ice/GCShared.h" "$(includedir)/Ice/GCCountMap.h" "$(includedir)/Ice/IncomingAsyncF.h" "$(includedir)/Ice/ObjectFactoryF.h" "$(includedir)/Ice/ObjectFactoryManagerF.h" "$(includedir)/Ice/Buffer.h" "$(includedir)/Ice/Protocol.h" "$(includedir)/Ice/SlicedDataF.h" "$(includedir)/Ice/UserExceptionFactory.h" "$(includedir)/Ice/FactoryTable.h" "$(includedir)/Ice/ObserverHelper.h" "$(includedir)/Ice/Instrumentation.h" "$(includedir)/Ice/StatsF.h" ../Ice/EndpointIF.h ../Ice/IPEndpointIF.h ../Ice/NetworkF.h ../IceWS/TransceiverI.h "$(includedir)/IceWS/Plugin.h" "$(includedir)/Ice/Plugin.h" "$(includedir)/Ice/BuiltinSequences.h" ../IceWS/Util.h ../Ice/Transceiver.h ../Ice/Network.h ../IceWS/EndpointI.h ../Ice/EndpointI.h "$(includedir)/Ice/Endpoint.h" ../Ice/AcceptorF.h ../Ice/EndpointFactory.h ../Ice/EndpointFactoryF.h "$(includedir)/IceWS/EndpointInfo.h"
+EndpointInfo$(OBJEXT): EndpointInfo.cpp "$(includedir)/IceWS/EndpointInfo.h" "$(includedir)/Ice/ProxyF.h" "$(includedir)/IceUtil/Shared.h" "$(includedir)/IceUtil/Config.h" "$(includedir)/Ice/Config.h" "$(includedir)/Ice/ProxyHandle.h" "$(includedir)/IceUtil/Handle.h" "$(includedir)/IceUtil/Exception.h" "$(includedir)/Ice/ObjectF.h" "$(includedir)/Ice/Handle.h" "$(includedir)/Ice/Exception.h" "$(includedir)/Ice/Format.h" "$(includedir)/Ice/StreamF.h" "$(includedir)/Ice/LocalObject.h" "$(includedir)/Ice/LocalObjectF.h" "$(includedir)/Ice/StreamHelpers.h" "$(includedir)/IceUtil/ScopedArray.h" "$(includedir)/IceUtil/Iterator.h" "$(includedir)/IceUtil/Optional.h" "$(includedir)/Ice/Endpoint.h" "$(includedir)/Ice/Version.h" "$(includedir)/Ice/UndefSysMacros.h" "$(includedir)/Ice/BuiltinSequences.h" "$(includedir)/Ice/EndpointF.h" "$(includedir)/Ice/BasicStream.h" "$(includedir)/Ice/InstanceF.h" "$(includedir)/Ice/Object.h" "$(includedir)/IceUtil/Mutex.h" "$(includedir)/IceUtil/Lock.h" "$(includedir)/IceUtil/ThreadException.h" "$(includedir)/IceUtil/Time.h" "$(includedir)/IceUtil/MutexProtocol.h" "$(includedir)/Ice/GCShared.h" "$(includedir)/Ice/GCCountMap.h" "$(includedir)/Ice/IncomingAsyncF.h" "$(includedir)/Ice/Current.h" "$(includedir)/Ice/ObjectAdapterF.h" "$(includedir)/Ice/ConnectionF.h" "$(includedir)/Ice/Identity.h" "$(includedir)/Ice/ObjectFactoryF.h" "$(includedir)/Ice/ObjectFactoryManagerF.h" "$(includedir)/Ice/Buffer.h" "$(includedir)/Ice/Protocol.h" "$(includedir)/Ice/SlicedDataF.h" "$(includedir)/Ice/UserExceptionFactory.h" "$(includedir)/Ice/FactoryTable.h" "$(includedir)/IceUtil/DisableWarnings.h"
+ConnectionInfo$(OBJEXT): ConnectionInfo.cpp "$(includedir)/IceWS/ConnectionInfo.h" "$(includedir)/Ice/ProxyF.h" "$(includedir)/IceUtil/Shared.h" "$(includedir)/IceUtil/Config.h" "$(includedir)/Ice/Config.h" "$(includedir)/Ice/ProxyHandle.h" "$(includedir)/IceUtil/Handle.h" "$(includedir)/IceUtil/Exception.h" "$(includedir)/Ice/ObjectF.h" "$(includedir)/Ice/Handle.h" "$(includedir)/Ice/Exception.h" "$(includedir)/Ice/Format.h" "$(includedir)/Ice/StreamF.h" "$(includedir)/Ice/LocalObject.h" "$(includedir)/Ice/LocalObjectF.h" "$(includedir)/Ice/StreamHelpers.h" "$(includedir)/IceUtil/ScopedArray.h" "$(includedir)/IceUtil/Iterator.h" "$(includedir)/Ice/Proxy.h" "$(includedir)/IceUtil/Mutex.h" "$(includedir)/IceUtil/Lock.h" "$(includedir)/IceUtil/ThreadException.h" "$(includedir)/IceUtil/Time.h" "$(includedir)/IceUtil/MutexProtocol.h" "$(includedir)/Ice/ProxyFactoryF.h" "$(includedir)/Ice/ConnectionIF.h" "$(includedir)/Ice/RequestHandlerF.h" "$(includedir)/Ice/EndpointF.h" "$(includedir)/IceUtil/Optional.h" "$(includedir)/Ice/UndefSysMacros.h" "$(includedir)/Ice/EndpointTypes.h" "$(includedir)/Ice/ObjectAdapterF.h" "$(includedir)/Ice/ReferenceF.h" "$(includedir)/Ice/OutgoingAsync.h" "$(includedir)/IceUtil/Monitor.h" "$(includedir)/IceUtil/Cond.h" "$(includedir)/IceUtil/Timer.h" "$(includedir)/IceUtil/Thread.h" "$(includedir)/IceUtil/UniquePtr.h" "$(includedir)/Ice/OutgoingAsyncF.h" "$(includedir)/Ice/InstanceF.h" "$(includedir)/Ice/CommunicatorF.h" "$(includedir)/Ice/Current.h" "$(includedir)/Ice/ConnectionF.h" "$(includedir)/Ice/Identity.h" "$(includedir)/Ice/Version.h" "$(includedir)/Ice/BasicStream.h" "$(includedir)/Ice/Object.h" "$(includedir)/Ice/GCShared.h" "$(includedir)/Ice/GCCountMap.h" "$(includedir)/Ice/IncomingAsyncF.h" "$(includedir)/Ice/ObjectFactoryF.h" "$(includedir)/Ice/ObjectFactoryManagerF.h" "$(includedir)/Ice/Buffer.h" "$(includedir)/Ice/Protocol.h" "$(includedir)/Ice/SlicedDataF.h" "$(includedir)/Ice/UserExceptionFactory.h" "$(includedir)/Ice/FactoryTable.h" "$(includedir)/Ice/ObserverHelper.h" "$(includedir)/Ice/Instrumentation.h" "$(includedir)/Ice/Connection.h" "$(includedir)/Ice/Endpoint.h" "$(includedir)/Ice/BuiltinSequences.h" "$(includedir)/IceUtil/DisableWarnings.h"
+EndpointI$(OBJEXT): EndpointI.cpp ../IceWS/EndpointI.h ../Ice/EndpointI.h ../Ice/EndpointIF.h "$(includedir)/IceUtil/Shared.h" "$(includedir)/IceUtil/Config.h" "$(includedir)/Ice/Handle.h" "$(includedir)/IceUtil/Handle.h" "$(includedir)/IceUtil/Exception.h" "$(includedir)/Ice/Config.h" "$(includedir)/Ice/Endpoint.h" "$(includedir)/Ice/ProxyF.h" "$(includedir)/Ice/ProxyHandle.h" "$(includedir)/Ice/ObjectF.h" "$(includedir)/Ice/Exception.h" "$(includedir)/Ice/Format.h" "$(includedir)/Ice/StreamF.h" "$(includedir)/Ice/LocalObject.h" "$(includedir)/Ice/LocalObjectF.h" "$(includedir)/Ice/StreamHelpers.h" "$(includedir)/IceUtil/ScopedArray.h" "$(includedir)/IceUtil/Iterator.h" "$(includedir)/IceUtil/Optional.h" "$(includedir)/Ice/Version.h" "$(includedir)/Ice/UndefSysMacros.h" "$(includedir)/Ice/BuiltinSequences.h" "$(includedir)/Ice/EndpointF.h" "$(includedir)/Ice/EndpointTypes.h" ../Ice/TransceiverF.h ../Ice/ConnectorF.h ../Ice/AcceptorF.h ../Ice/IPEndpointIF.h ../Ice/EndpointFactory.h ../Ice/EndpointFactoryF.h ../Ice/ProtocolInstanceF.h ../IceWS/InstanceF.h "$(includedir)/IceWS/EndpointInfo.h" ../IceWS/AcceptorI.h "$(includedir)/Ice/LoggerF.h" ../Ice/Acceptor.h ../Ice/Network.h ../Ice/NetworkF.h "$(includedir)/Ice/PropertiesF.h" "$(includedir)/Ice/Proxy.h" "$(includedir)/IceUtil/Mutex.h" "$(includedir)/IceUtil/Lock.h" "$(includedir)/IceUtil/ThreadException.h" "$(includedir)/IceUtil/Time.h" "$(includedir)/IceUtil/MutexProtocol.h" "$(includedir)/Ice/ProxyFactoryF.h" "$(includedir)/Ice/ConnectionIF.h" "$(includedir)/Ice/RequestHandlerF.h" "$(includedir)/Ice/ObjectAdapterF.h" "$(includedir)/Ice/ReferenceF.h" "$(includedir)/Ice/OutgoingAsync.h" "$(includedir)/IceUtil/Monitor.h" "$(includedir)/IceUtil/Cond.h" "$(includedir)/IceUtil/Timer.h" "$(includedir)/IceUtil/Thread.h" "$(includedir)/IceUtil/UniquePtr.h" "$(includedir)/Ice/OutgoingAsyncF.h" "$(includedir)/Ice/InstanceF.h" "$(includedir)/Ice/CommunicatorF.h" "$(includedir)/Ice/Current.h" "$(includedir)/Ice/ConnectionF.h" "$(includedir)/Ice/Identity.h" "$(includedir)/Ice/BasicStream.h" "$(includedir)/Ice/Object.h" "$(includedir)/Ice/GCShared.h" "$(includedir)/Ice/GCCountMap.h" "$(includedir)/Ice/IncomingAsyncF.h" "$(includedir)/Ice/ObjectFactoryF.h" "$(includedir)/Ice/ObjectFactoryManagerF.h" "$(includedir)/Ice/Buffer.h" "$(includedir)/Ice/Protocol.h" "$(includedir)/Ice/SlicedDataF.h" "$(includedir)/Ice/UserExceptionFactory.h" "$(includedir)/Ice/FactoryTable.h" "$(includedir)/Ice/ObserverHelper.h" "$(includedir)/Ice/Instrumentation.h" ../IceWS/ConnectorI.h ../Ice/Connector.h ../IceWS/TransceiverI.h "$(includedir)/IceWS/Plugin.h" "$(includedir)/Ice/Plugin.h" ../IceWS/Util.h "$(includedir)/Ice/StatsF.h" ../Ice/Transceiver.h ../IceWS/Instance.h ../Ice/ProtocolInstance.h "$(includedir)/Ice/LocalException.h" ../Ice/IPEndpointI.h ../Ice/HashUtil.h
+Instance$(OBJEXT): Instance.cpp ../IceWS/Instance.h ../IceWS/InstanceF.h "$(includedir)/IceUtil/Shared.h" "$(includedir)/IceUtil/Config.h" "$(includedir)/Ice/Handle.h" "$(includedir)/IceUtil/Handle.h" "$(includedir)/IceUtil/Exception.h" "$(includedir)/Ice/Config.h" ../Ice/ProtocolInstance.h ../Ice/ProtocolInstanceF.h "$(includedir)/Ice/CommunicatorF.h" "$(includedir)/Ice/ProxyF.h" "$(includedir)/Ice/ProxyHandle.h" "$(includedir)/Ice/ObjectF.h" "$(includedir)/Ice/Exception.h" "$(includedir)/Ice/Format.h" "$(includedir)/Ice/StreamF.h" "$(includedir)/Ice/LocalObject.h" "$(includedir)/Ice/LocalObjectF.h" "$(includedir)/Ice/StreamHelpers.h" "$(includedir)/IceUtil/ScopedArray.h" "$(includedir)/IceUtil/Iterator.h" "$(includedir)/IceUtil/Optional.h" "$(includedir)/Ice/UndefSysMacros.h" "$(includedir)/Ice/PropertiesF.h" "$(includedir)/Ice/Proxy.h" "$(includedir)/IceUtil/Mutex.h" "$(includedir)/IceUtil/Lock.h" "$(includedir)/IceUtil/ThreadException.h" "$(includedir)/IceUtil/Time.h" "$(includedir)/IceUtil/MutexProtocol.h" "$(includedir)/Ice/ProxyFactoryF.h" "$(includedir)/Ice/ConnectionIF.h" "$(includedir)/Ice/RequestHandlerF.h" "$(includedir)/Ice/EndpointF.h" "$(includedir)/Ice/EndpointTypes.h" "$(includedir)/Ice/ObjectAdapterF.h" "$(includedir)/Ice/ReferenceF.h" "$(includedir)/Ice/OutgoingAsync.h" "$(includedir)/IceUtil/Monitor.h" "$(includedir)/IceUtil/Cond.h" "$(includedir)/IceUtil/Timer.h" "$(includedir)/IceUtil/Thread.h" "$(includedir)/IceUtil/UniquePtr.h" "$(includedir)/Ice/OutgoingAsyncF.h" "$(includedir)/Ice/InstanceF.h" "$(includedir)/Ice/Current.h" "$(includedir)/Ice/ConnectionF.h" "$(includedir)/Ice/Identity.h" "$(includedir)/Ice/Version.h" "$(includedir)/Ice/BasicStream.h" "$(includedir)/Ice/Object.h" "$(includedir)/Ice/GCShared.h" "$(includedir)/Ice/GCCountMap.h" "$(includedir)/Ice/IncomingAsyncF.h" "$(includedir)/Ice/ObjectFactoryF.h" "$(includedir)/Ice/ObjectFactoryManagerF.h" "$(includedir)/Ice/Buffer.h" "$(includedir)/Ice/Protocol.h" "$(includedir)/Ice/SlicedDataF.h" "$(includedir)/Ice/UserExceptionFactory.h" "$(includedir)/Ice/FactoryTable.h" "$(includedir)/Ice/ObserverHelper.h" "$(includedir)/Ice/Instrumentation.h" "$(includedir)/Ice/LoggerF.h" "$(includedir)/Ice/StatsF.h" ../Ice/EndpointIF.h ../Ice/ConnectorF.h ../Ice/IPEndpointIF.h ../Ice/NetworkF.h ../IceWS/EndpointI.h ../Ice/EndpointI.h "$(includedir)/Ice/Endpoint.h" "$(includedir)/Ice/BuiltinSequences.h" ../Ice/TransceiverF.h ../Ice/AcceptorF.h ../Ice/EndpointFactory.h ../Ice/EndpointFactoryF.h "$(includedir)/IceWS/EndpointInfo.h" ../Ice/ProtocolPluginFacade.h ../Ice/ProtocolPluginFacadeF.h
+PluginI$(OBJEXT): PluginI.cpp ../IceWS/PluginI.h "$(includedir)/IceWS/Plugin.h" "$(includedir)/Ice/Plugin.h" "$(includedir)/Ice/ProxyF.h" "$(includedir)/IceUtil/Shared.h" "$(includedir)/IceUtil/Config.h" "$(includedir)/Ice/Config.h" "$(includedir)/Ice/ProxyHandle.h" "$(includedir)/IceUtil/Handle.h" "$(includedir)/IceUtil/Exception.h" "$(includedir)/Ice/ObjectF.h" "$(includedir)/Ice/Handle.h" "$(includedir)/Ice/Exception.h" "$(includedir)/Ice/Format.h" "$(includedir)/Ice/StreamF.h" "$(includedir)/Ice/LocalObject.h" "$(includedir)/Ice/LocalObjectF.h" "$(includedir)/Ice/StreamHelpers.h" "$(includedir)/IceUtil/ScopedArray.h" "$(includedir)/IceUtil/Iterator.h" "$(includedir)/IceUtil/Optional.h" "$(includedir)/Ice/LoggerF.h" "$(includedir)/Ice/UndefSysMacros.h" "$(includedir)/Ice/BuiltinSequences.h" ../IceWS/InstanceF.h "$(includedir)/Ice/CommunicatorF.h" ../IceWS/Instance.h ../Ice/ProtocolInstance.h ../Ice/ProtocolInstanceF.h "$(includedir)/Ice/PropertiesF.h" "$(includedir)/Ice/Proxy.h" "$(includedir)/IceUtil/Mutex.h" "$(includedir)/IceUtil/Lock.h" "$(includedir)/IceUtil/ThreadException.h" "$(includedir)/IceUtil/Time.h" "$(includedir)/IceUtil/MutexProtocol.h" "$(includedir)/Ice/ProxyFactoryF.h" "$(includedir)/Ice/ConnectionIF.h" "$(includedir)/Ice/RequestHandlerF.h" "$(includedir)/Ice/EndpointF.h" "$(includedir)/Ice/EndpointTypes.h" "$(includedir)/Ice/ObjectAdapterF.h" "$(includedir)/Ice/ReferenceF.h" "$(includedir)/Ice/OutgoingAsync.h" "$(includedir)/IceUtil/Monitor.h" "$(includedir)/IceUtil/Cond.h" "$(includedir)/IceUtil/Timer.h" "$(includedir)/IceUtil/Thread.h" "$(includedir)/IceUtil/UniquePtr.h" "$(includedir)/Ice/OutgoingAsyncF.h" "$(includedir)/Ice/InstanceF.h" "$(includedir)/Ice/Current.h" "$(includedir)/Ice/ConnectionF.h" "$(includedir)/Ice/Identity.h" "$(includedir)/Ice/Version.h" "$(includedir)/Ice/BasicStream.h" "$(includedir)/Ice/Object.h" "$(includedir)/Ice/GCShared.h" "$(includedir)/Ice/GCCountMap.h" "$(includedir)/Ice/IncomingAsyncF.h" "$(includedir)/Ice/ObjectFactoryF.h" "$(includedir)/Ice/ObjectFactoryManagerF.h" "$(includedir)/Ice/Buffer.h" "$(includedir)/Ice/Protocol.h" "$(includedir)/Ice/SlicedDataF.h" "$(includedir)/Ice/UserExceptionFactory.h" "$(includedir)/Ice/FactoryTable.h" "$(includedir)/Ice/ObserverHelper.h" "$(includedir)/Ice/Instrumentation.h" "$(includedir)/Ice/StatsF.h" ../Ice/EndpointIF.h ../Ice/ConnectorF.h ../Ice/IPEndpointIF.h ../Ice/NetworkF.h ../IceWS/EndpointI.h ../Ice/EndpointI.h "$(includedir)/Ice/Endpoint.h" ../Ice/TransceiverF.h ../Ice/AcceptorF.h ../Ice/EndpointFactory.h ../Ice/EndpointFactoryF.h "$(includedir)/IceWS/EndpointInfo.h" ../Ice/ProtocolPluginFacade.h ../Ice/ProtocolPluginFacadeF.h
+TransceiverI$(OBJEXT): TransceiverI.cpp ../IceWS/TransceiverI.h ../IceWS/InstanceF.h "$(includedir)/IceUtil/Shared.h" "$(includedir)/IceUtil/Config.h" "$(includedir)/Ice/Handle.h" "$(includedir)/IceUtil/Handle.h" "$(includedir)/IceUtil/Exception.h" "$(includedir)/Ice/Config.h" "$(includedir)/IceWS/Plugin.h" "$(includedir)/Ice/Plugin.h" "$(includedir)/Ice/ProxyF.h" "$(includedir)/Ice/ProxyHandle.h" "$(includedir)/Ice/ObjectF.h" "$(includedir)/Ice/Exception.h" "$(includedir)/Ice/Format.h" "$(includedir)/Ice/StreamF.h" "$(includedir)/Ice/LocalObject.h" "$(includedir)/Ice/LocalObjectF.h" "$(includedir)/Ice/StreamHelpers.h" "$(includedir)/IceUtil/ScopedArray.h" "$(includedir)/IceUtil/Iterator.h" "$(includedir)/IceUtil/Optional.h" "$(includedir)/Ice/LoggerF.h" "$(includedir)/Ice/UndefSysMacros.h" "$(includedir)/Ice/BuiltinSequences.h" ../IceWS/Util.h "$(includedir)/Ice/StatsF.h" ../Ice/Transceiver.h ../Ice/TransceiverF.h "$(includedir)/Ice/ConnectionF.h" ../Ice/Network.h ../Ice/NetworkF.h "$(includedir)/Ice/PropertiesF.h" "$(includedir)/Ice/Proxy.h" "$(includedir)/IceUtil/Mutex.h" "$(includedir)/IceUtil/Lock.h" "$(includedir)/IceUtil/ThreadException.h" "$(includedir)/IceUtil/Time.h" "$(includedir)/IceUtil/MutexProtocol.h" "$(includedir)/Ice/ProxyFactoryF.h" "$(includedir)/Ice/ConnectionIF.h" "$(includedir)/Ice/RequestHandlerF.h" "$(includedir)/Ice/EndpointF.h" "$(includedir)/Ice/EndpointTypes.h" "$(includedir)/Ice/ObjectAdapterF.h" "$(includedir)/Ice/ReferenceF.h" "$(includedir)/Ice/OutgoingAsync.h" "$(includedir)/IceUtil/Monitor.h" "$(includedir)/IceUtil/Cond.h" "$(includedir)/IceUtil/Timer.h" "$(includedir)/IceUtil/Thread.h" "$(includedir)/IceUtil/UniquePtr.h" "$(includedir)/Ice/OutgoingAsyncF.h" "$(includedir)/Ice/InstanceF.h" "$(includedir)/Ice/CommunicatorF.h" "$(includedir)/Ice/Current.h" "$(includedir)/Ice/Identity.h" "$(includedir)/Ice/Version.h" "$(includedir)/Ice/BasicStream.h" "$(includedir)/Ice/Object.h" "$(includedir)/Ice/GCShared.h" "$(includedir)/Ice/GCCountMap.h" "$(includedir)/Ice/IncomingAsyncF.h" "$(includedir)/Ice/ObjectFactoryF.h" "$(includedir)/Ice/ObjectFactoryManagerF.h" "$(includedir)/Ice/Buffer.h" "$(includedir)/Ice/Protocol.h" "$(includedir)/Ice/SlicedDataF.h" "$(includedir)/Ice/UserExceptionFactory.h" "$(includedir)/Ice/FactoryTable.h" "$(includedir)/Ice/ObserverHelper.h" "$(includedir)/Ice/Instrumentation.h" "$(includedir)/IceWS/EndpointInfo.h" "$(includedir)/Ice/Endpoint.h" "$(includedir)/IceWS/ConnectionInfo.h" "$(includedir)/Ice/Connection.h" ../IceWS/Instance.h ../Ice/ProtocolInstance.h ../Ice/ProtocolInstanceF.h ../Ice/EndpointIF.h ../Ice/ConnectorF.h ../Ice/IPEndpointIF.h "$(includedir)/Ice/Communicator.h" "$(includedir)/Ice/Outgoing.h" "$(includedir)/Ice/Incoming.h" "$(includedir)/Ice/ServantLocatorF.h" "$(includedir)/Ice/ServantManagerF.h" "$(includedir)/Ice/IncomingAsync.h" "$(includedir)/Ice/Direct.h" "$(includedir)/Ice/InstrumentationF.h" "$(includedir)/Ice/RouterF.h" "$(includedir)/Ice/LocatorF.h" "$(includedir)/Ice/PluginF.h" "$(includedir)/Ice/ImplicitContextF.h" "$(includedir)/Ice/Properties.h" "$(includedir)/Ice/PropertiesAdmin.h" "$(includedir)/Ice/LoggerUtil.h" "$(includedir)/Ice/Logger.h" "$(includedir)/Ice/LocalException.h" "$(includedir)/Ice/Stats.h" ../Ice/Base64.h "$(includedir)/IceUtil/Random.h" "$(includedir)/IceUtil/StringUtil.h" "$(includedir)/IceUtil/DisableWarnings.h"
+Util$(OBJEXT): Util.cpp "$(includedir)/IceUtil/Config.h" ../IceWS/Util.h "$(includedir)/IceUtil/Shared.h" "$(includedir)/IceUtil/Handle.h" "$(includedir)/IceUtil/Exception.h" "$(includedir)/Ice/Config.h" "$(includedir)/Ice/LocalException.h" "$(includedir)/Ice/ProxyF.h" "$(includedir)/Ice/ProxyHandle.h" "$(includedir)/Ice/ObjectF.h" "$(includedir)/Ice/Handle.h" "$(includedir)/Ice/Exception.h" "$(includedir)/Ice/Format.h" "$(includedir)/Ice/StreamF.h" "$(includedir)/Ice/LocalObject.h" "$(includedir)/Ice/LocalObjectF.h" "$(includedir)/Ice/StreamHelpers.h" "$(includedir)/IceUtil/ScopedArray.h" "$(includedir)/IceUtil/Iterator.h" "$(includedir)/IceUtil/Optional.h" "$(includedir)/Ice/Identity.h" "$(includedir)/Ice/UndefSysMacros.h" "$(includedir)/Ice/Version.h" "$(includedir)/Ice/BuiltinSequences.h" "$(includedir)/IceUtil/StringUtil.h" "$(includedir)/IceUtil/DisableWarnings.h"
+$(HDIR)\EndpointInfo.h EndpointInfo.cpp: "$(slicedir)/IceWS/EndpointInfo.ice" "$(slicedir)/Ice/Endpoint.ice" "$(slicedir)/Ice/Version.ice" "$(slicedir)/Ice/BuiltinSequences.ice" "$(slicedir)/Ice/EndpointF.ice" "$(SLICE2CPP)" "$(SLICEPARSERLIB)"
+$(HDIR)\ConnectionInfo.h ConnectionInfo.cpp: "$(slicedir)/IceWS/ConnectionInfo.ice" "$(slicedir)/Ice/Connection.ice" "$(slicedir)/Ice/ObjectAdapterF.ice" "$(slicedir)/Ice/Identity.ice" "$(slicedir)/Ice/Endpoint.ice" "$(slicedir)/Ice/Version.ice" "$(slicedir)/Ice/BuiltinSequences.ice" "$(slicedir)/Ice/EndpointF.ice" "$(SLICE2CPP)" "$(SLICEPARSERLIB)"
diff --git a/cpp/src/IceWS/.gitignore b/cpp/src/IceWS/.gitignore
new file mode 100644
index 00000000000..88e034bad9d
--- /dev/null
+++ b/cpp/src/IceWS/.gitignore
@@ -0,0 +1,7 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+EndpointInfo.cpp
+ConnectionInfo.cpp
+EndpointInfo.h
+ConnectionInfo.h
diff --git a/cpp/src/IceWS/AcceptorI.cpp b/cpp/src/IceWS/AcceptorI.cpp
new file mode 100644
index 00000000000..c3f536c733b
--- /dev/null
+++ b/cpp/src/IceWS/AcceptorI.cpp
@@ -0,0 +1,87 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <IceWS/AcceptorI.h>
+#include <IceWS/Instance.h>
+#include <IceWS/TransceiverI.h>
+
+using namespace std;
+using namespace Ice;
+using namespace IceWS;
+
+IceInternal::NativeInfoPtr
+IceWS::AcceptorI::getNativeInfo()
+{
+ return _delegate->getNativeInfo();
+}
+
+#ifdef ICE_USE_IOCP
+IceInternal::AsyncInfo*
+IceWS::AcceptorI::getAsyncInfo(IceInternal::SocketOperation status)
+{
+ return _delegate->getNativeInfo()->getAsyncInfo(status);
+}
+#endif
+
+void
+IceWS::AcceptorI::close()
+{
+ _delegate->close();
+}
+
+void
+IceWS::AcceptorI::listen()
+{
+ _delegate->listen();
+}
+
+#ifdef ICE_USE_IOCP
+void
+IceWS::AcceptorI::startAccept()
+{
+ _delegate->startAccept();
+}
+
+void
+IceWS::AcceptorI::finishAccept()
+{
+ _delegate->finishAccept();
+}
+#endif
+
+IceInternal::TransceiverPtr
+IceWS::AcceptorI::accept()
+{
+ //
+ // WebSocket handshaking is performed in TransceiverI::initialize, since
+ // accept must not block.
+ //
+ return new TransceiverI(_instance, _delegate->accept());
+}
+
+string
+IceWS::AcceptorI::protocol() const
+{
+ return _delegate->protocol();
+}
+
+string
+IceWS::AcceptorI::toString() const
+{
+ return _delegate->toString();
+}
+
+IceWS::AcceptorI::AcceptorI(const InstancePtr& instance, const IceInternal::AcceptorPtr& del) :
+ _instance(instance), _delegate(del)
+{
+}
+
+IceWS::AcceptorI::~AcceptorI()
+{
+}
diff --git a/cpp/src/IceWS/AcceptorI.h b/cpp/src/IceWS/AcceptorI.h
new file mode 100644
index 00000000000..90a156c33ce
--- /dev/null
+++ b/cpp/src/IceWS/AcceptorI.h
@@ -0,0 +1,55 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#ifndef ICE_WS_ACCEPTOR_I_H
+#define ICE_WS_ACCEPTOR_I_H
+
+#include <Ice/LoggerF.h>
+#include <Ice/TransceiverF.h>
+#include <Ice/Acceptor.h>
+#include <Ice/Network.h>
+#include <IceWS/InstanceF.h>
+
+namespace IceWS
+{
+
+class EndpointI;
+
+class AcceptorI : public IceInternal::Acceptor, public IceInternal::NativeInfo
+{
+public:
+
+ virtual IceInternal::NativeInfoPtr getNativeInfo();
+#ifdef ICE_USE_IOCP
+ virtual IceInternal::AsyncInfo* getAsyncInfo(IceInternal::SocketOperation);
+#endif
+
+ virtual void close();
+ virtual void listen();
+#ifdef ICE_USE_IOCP
+ virtual void startAccept();
+ virtual void finishAccept();
+#endif
+ virtual IceInternal::TransceiverPtr accept();
+ virtual std::string protocol() const;
+ virtual std::string toString() const;
+
+private:
+
+ AcceptorI(const InstancePtr&, const IceInternal::AcceptorPtr&);
+ virtual ~AcceptorI();
+ friend class EndpointI;
+
+ const InstancePtr _instance;
+ const IceInternal::AcceptorPtr _delegate;
+};
+
+}
+
+#endif
diff --git a/cpp/src/IceWS/ConnectorI.cpp b/cpp/src/IceWS/ConnectorI.cpp
new file mode 100644
index 00000000000..1772fcd27c8
--- /dev/null
+++ b/cpp/src/IceWS/ConnectorI.cpp
@@ -0,0 +1,114 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <IceWS/ConnectorI.h>
+#include <IceWS/Instance.h>
+#include <IceWS/TransceiverI.h>
+#include <IceWS/EndpointI.h>
+#include <IceWS/Util.h>
+
+using namespace std;
+using namespace Ice;
+using namespace IceWS;
+
+IceInternal::TransceiverPtr
+IceWS::ConnectorI::connect()
+{
+ return new TransceiverI(_instance, _delegate->connect(), _host, _port, _resource);
+}
+
+Short
+IceWS::ConnectorI::type() const
+{
+ return _delegate->type();
+}
+
+string
+IceWS::ConnectorI::toString() const
+{
+ return _delegate->toString();
+}
+
+bool
+IceWS::ConnectorI::operator==(const Connector& r) const
+{
+ const ConnectorI* p = dynamic_cast<const ConnectorI*>(&r);
+ if(!p)
+ {
+ return false;
+ }
+
+ if(this == p)
+ {
+ return true;
+ }
+
+ if(_delegate != p->_delegate)
+ {
+ return false;
+ }
+
+ if(_resource != p->_resource)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool
+IceWS::ConnectorI::operator!=(const Connector& r) const
+{
+ return !operator==(r);
+}
+
+bool
+IceWS::ConnectorI::operator<(const Connector& r) const
+{
+ const ConnectorI* p = dynamic_cast<const ConnectorI*>(&r);
+ if(!p)
+ {
+ return type() < r.type();
+ }
+
+ if(this == p)
+ {
+ return false;
+ }
+
+ if(_delegate < p->_delegate)
+ {
+ return true;
+ }
+ else if(p->_delegate < _delegate)
+ {
+ return false;
+ }
+
+ if(_resource < p->_resource)
+ {
+ return true;
+ }
+ else if(p->_resource < _resource)
+ {
+ return false;
+ }
+
+ return false;
+}
+
+IceWS::ConnectorI::ConnectorI(const InstancePtr& instance, const IceInternal::ConnectorPtr& del,
+ const string& host, int port, const string& resource) :
+ _instance(instance), _delegate(del), _host(host), _port(port), _resource(resource)
+{
+}
+
+IceWS::ConnectorI::~ConnectorI()
+{
+}
diff --git a/cpp/src/IceWS/ConnectorI.h b/cpp/src/IceWS/ConnectorI.h
new file mode 100644
index 00000000000..7314685db41
--- /dev/null
+++ b/cpp/src/IceWS/ConnectorI.h
@@ -0,0 +1,51 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#ifndef ICE_WS_CONNECTOR_I_H
+#define ICE_WS_CONNECTOR_I_H
+
+#include <Ice/LoggerF.h>
+#include <Ice/TransceiverF.h>
+#include <Ice/Connector.h>
+#include <IceWS/InstanceF.h>
+
+namespace IceWS
+{
+
+class EndpointI;
+
+class ConnectorI : public IceInternal::Connector
+{
+public:
+
+ virtual IceInternal::TransceiverPtr connect();
+
+ virtual Ice::Short type() const;
+ virtual std::string toString() const;
+
+ virtual bool operator==(const IceInternal::Connector&) const;
+ virtual bool operator!=(const IceInternal::Connector&) const;
+ virtual bool operator<(const IceInternal::Connector&) const;
+
+private:
+
+ ConnectorI(const InstancePtr&, const IceInternal::ConnectorPtr&, const std::string&, int, const std::string&);
+ virtual ~ConnectorI();
+ friend class EndpointI;
+
+ const InstancePtr _instance;
+ const IceInternal::ConnectorPtr _delegate;
+ const std::string _host;
+ const int _port;
+ const std::string _resource;
+};
+
+}
+
+#endif
diff --git a/cpp/src/IceWS/EndpointI.cpp b/cpp/src/IceWS/EndpointI.cpp
new file mode 100644
index 00000000000..0e87cdf9f7b
--- /dev/null
+++ b/cpp/src/IceWS/EndpointI.cpp
@@ -0,0 +1,449 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <IceWS/EndpointI.h>
+#include <IceWS/AcceptorI.h>
+#include <IceWS/ConnectorI.h>
+#include <IceWS/TransceiverI.h>
+#include <IceWS/Instance.h>
+#include <Ice/BasicStream.h>
+#include <Ice/LocalException.h>
+#include <Ice/IPEndpointI.h>
+#include <Ice/HashUtil.h>
+
+using namespace std;
+using namespace Ice;
+using namespace IceWS;
+
+IceWS::EndpointI::EndpointI(const InstancePtr& instance, const IceInternal::EndpointIPtr& del, const string& res) :
+ _instance(instance), _delegate(IceInternal::IPEndpointIPtr::dynamicCast(del)), _resource(res)
+{
+}
+
+IceWS::EndpointI::EndpointI(const InstancePtr& instance, const IceInternal::EndpointIPtr& del, vector<string>& args) :
+ _instance(instance), _delegate(IceInternal::IPEndpointIPtr::dynamicCast(del))
+{
+ initWithOptions(args);
+
+ if(_resource.empty())
+ {
+ const_cast<string&>(_resource) = "/";
+ }
+}
+
+IceWS::EndpointI::EndpointI(const InstancePtr& instance, const IceInternal::EndpointIPtr& del,
+ IceInternal::BasicStream* s) :
+ _instance(instance), _delegate(IceInternal::IPEndpointIPtr::dynamicCast(del))
+{
+ s->read(const_cast<string&>(_resource), false);
+}
+
+Ice::EndpointInfoPtr
+IceWS::EndpointI::getInfo() const
+{
+ class InfoI : public IceWS::EndpointInfo
+ {
+ public:
+
+ InfoI(const IceInternal::EndpointIPtr& e) : _endpoint(e)
+ {
+ }
+
+ virtual Short
+ type() const
+ {
+ return _endpoint->type();
+ }
+
+ virtual bool
+ datagram() const
+ {
+ return _endpoint->datagram();
+ }
+
+ virtual bool
+ secure() const
+ {
+ return _endpoint->secure();
+ }
+
+ private:
+
+ const IceInternal::EndpointIPtr _endpoint;
+ };
+
+ EndpointInfoPtr info = new InfoI(const_cast<EndpointI*>(this));
+ info->timeout = _delegate->timeout();
+ info->compress = _delegate->compress();
+ _delegate->fillEndpointInfo(info.get());
+ info->resource = _resource;
+ return info;
+}
+
+Ice::Short
+IceWS::EndpointI::type() const
+{
+ return _delegate->type();
+}
+
+const string&
+IceWS::EndpointI::protocol() const
+{
+ return _delegate->protocol();
+}
+
+void
+IceWS::EndpointI::streamWrite(IceInternal::BasicStream* s) const
+{
+ s->startWriteEncaps();
+ _delegate->streamWriteImpl(s);
+ s->write(_resource, false);
+ s->endWriteEncaps();
+}
+
+Int
+IceWS::EndpointI::timeout() const
+{
+ return _delegate->timeout();
+}
+
+IceInternal::EndpointIPtr
+IceWS::EndpointI::timeout(Int timeout) const
+{
+ if(timeout == _delegate->timeout())
+ {
+ return const_cast<EndpointI*>(this);
+ }
+ else
+ {
+ return new EndpointI(_instance, _delegate->timeout(timeout), _resource);
+ }
+}
+
+const string&
+IceWS::EndpointI::connectionId() const
+{
+ return _delegate->connectionId();
+}
+
+IceInternal::EndpointIPtr
+IceWS::EndpointI::connectionId(const string& connectionId) const
+{
+ if(connectionId == _delegate->connectionId())
+ {
+ return const_cast<EndpointI*>(this);
+ }
+ else
+ {
+ return new EndpointI(_instance, _delegate->connectionId(connectionId), _resource);
+ }
+}
+
+bool
+IceWS::EndpointI::compress() const
+{
+ return _delegate->compress();
+}
+
+IceInternal::EndpointIPtr
+IceWS::EndpointI::compress(bool compress) const
+{
+ if(compress == _delegate->compress())
+ {
+ return const_cast<EndpointI*>(this);
+ }
+ else
+ {
+ return new EndpointI(_instance, _delegate->compress(compress), _resource);
+ }
+}
+
+bool
+IceWS::EndpointI::datagram() const
+{
+ return _delegate->datagram();
+}
+
+bool
+IceWS::EndpointI::secure() const
+{
+ return _delegate->secure();
+}
+
+IceInternal::TransceiverPtr
+IceWS::EndpointI::transceiver(IceInternal::EndpointIPtr& endp) const
+{
+ endp = const_cast<EndpointI*>(this);
+ return 0;
+}
+
+vector<IceInternal::ConnectorPtr>
+IceWS::EndpointI::connectors(Ice::EndpointSelectionType selType) const
+{
+ vector<IceInternal::ConnectorPtr> connectors = _delegate->connectors(selType);
+ for(vector<IceInternal::ConnectorPtr>::iterator p = connectors.begin(); p != connectors.end(); ++p)
+ {
+ *p = new ConnectorI(_instance, *p, _delegate->host(), _delegate->port(), _resource);
+ }
+ return connectors;
+}
+
+void
+IceWS::EndpointI::connectors_async(Ice::EndpointSelectionType selType,
+ const IceInternal::EndpointI_connectorsPtr& callback) const
+{
+ class CallbackI : public IceInternal::EndpointI_connectors
+ {
+ public:
+
+ CallbackI(const IceInternal::EndpointI_connectorsPtr& callback, const InstancePtr& instance,
+ const string& host, int port, const string& resource) :
+ _callback(callback), _instance(instance), _host(host), _port(port), _resource(resource)
+ {
+ }
+
+ virtual void connectors(const vector<IceInternal::ConnectorPtr>& c)
+ {
+ vector<IceInternal::ConnectorPtr> connectors = c;
+ for(vector<IceInternal::ConnectorPtr>::iterator p = connectors.begin(); p != connectors.end(); ++p)
+ {
+ *p = new ConnectorI(_instance, *p, _host, _port, _resource);
+ }
+ _callback->connectors(connectors);
+ }
+
+ virtual void exception(const Ice::LocalException& ex)
+ {
+ _callback->exception(ex);
+ }
+
+ private:
+
+ const IceInternal::EndpointI_connectorsPtr _callback;
+ const InstancePtr _instance;
+ const string _host;
+ const int _port;
+ const string _resource;
+ };
+ _delegate->connectors_async(selType, new CallbackI(callback, _instance, _delegate->host(), _delegate->port(),
+ _resource));
+}
+
+IceInternal::AcceptorPtr
+IceWS::EndpointI::acceptor(IceInternal::EndpointIPtr& endp, const string& adapterName) const
+{
+ IceInternal::EndpointIPtr delEndp;
+ IceInternal::AcceptorPtr delAcc = _delegate->acceptor(delEndp, adapterName);
+ if(delEndp)
+ {
+ endp = new EndpointI(_instance, delEndp, _resource);
+ }
+ return new AcceptorI(_instance, delAcc);
+}
+
+vector<IceInternal::EndpointIPtr>
+IceWS::EndpointI::expand() const
+{
+ vector<IceInternal::EndpointIPtr> endps = _delegate->expand();
+ for(vector<IceInternal::EndpointIPtr>::iterator p = endps.begin(); p != endps.end(); ++p)
+ {
+ *p = p->get() == _delegate.get() ? const_cast<EndpointI*>(this) : new EndpointI(_instance, *p, _resource);
+ }
+ return endps;
+}
+
+bool
+IceWS::EndpointI::equivalent(const IceInternal::EndpointIPtr& endpoint) const
+{
+ const EndpointI* wsEndpointI = dynamic_cast<const EndpointI*>(endpoint.get());
+ if(!wsEndpointI)
+ {
+ return false;
+ }
+ return _delegate->equivalent(wsEndpointI->_delegate);
+}
+
+Ice::Int
+IceWS::EndpointI::hash() const
+{
+ int h = _delegate->hash();
+ IceInternal::hashAdd(h, _resource);
+ return h;
+}
+
+string
+IceWS::EndpointI::options() const
+{
+ //
+ // WARNING: Certain features, such as proxy validation in Glacier2,
+ // depend on the format of proxy strings. Changes to toString() and
+ // methods called to generate parts of the reference string could break
+ // these features. Please review for all features that depend on the
+ // format of proxyToString() before changing this and related code.
+ //
+ ostringstream s;
+ s << _delegate->options();
+
+ if(!_resource.empty())
+ {
+ s << " -r ";
+ bool addQuote = _resource.find(':') != string::npos;
+ if(addQuote)
+ {
+ s << "\"";
+ }
+ s << _resource;
+ if(addQuote)
+ {
+ s << "\"";
+ }
+ }
+
+ return s.str();
+}
+
+bool
+IceWS::EndpointI::operator==(const Ice::LocalObject& r) const
+{
+ const EndpointI* p = dynamic_cast<const EndpointI*>(&r);
+ if(!p)
+ {
+ return false;
+ }
+
+ if(this == p)
+ {
+ return true;
+ }
+
+ if(_delegate != p->_delegate)
+ {
+ return false;
+ }
+
+ if(_resource != p->_resource)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool
+IceWS::EndpointI::operator<(const Ice::LocalObject& r) const
+{
+ const EndpointI* p = dynamic_cast<const EndpointI*>(&r);
+ if(!p)
+ {
+ const IceInternal::EndpointI* e = dynamic_cast<const IceInternal::EndpointI*>(&r);
+ if(!e)
+ {
+ return false;
+ }
+ return type() < e->type();
+ }
+
+ if(this == p)
+ {
+ return false;
+ }
+
+ if(_delegate < p->_delegate)
+ {
+ return true;
+ }
+ else if (p->_delegate < _delegate)
+ {
+ return false;
+ }
+
+ if(_resource < p->_resource)
+ {
+ return true;
+ }
+ else if (p->_resource < _resource)
+ {
+ return false;
+ }
+
+ return false;
+
+}
+
+bool
+IceWS::EndpointI::checkOption(const string& option, const string& argument, const string& endpoint)
+{
+ switch(option[1])
+ {
+ case 'r':
+ {
+ if(argument.empty())
+ {
+ EndpointParseException ex(__FILE__, __LINE__);
+ ex.str = "no argument provided for -r option in endpoint " + endpoint + _delegate->options();
+ throw ex;
+ }
+ const_cast<string&>(_resource) = argument;
+ return true;
+ }
+
+ default:
+ {
+ return false;
+ }
+ }
+}
+
+IceWS::EndpointFactoryI::EndpointFactoryI(const InstancePtr& instance, const IceInternal::EndpointFactoryPtr& del) :
+ _instance(instance),
+ _delegate(del)
+{
+}
+
+IceWS::EndpointFactoryI::~EndpointFactoryI()
+{
+}
+
+Short
+IceWS::EndpointFactoryI::type() const
+{
+ return _instance->type();
+}
+
+string
+IceWS::EndpointFactoryI::protocol() const
+{
+ return _instance->protocol();
+}
+
+IceInternal::EndpointIPtr
+IceWS::EndpointFactoryI::create(vector<string>& args, bool oaEndpoint) const
+{
+ return new EndpointI(_instance, _delegate->create(args, oaEndpoint), args);
+}
+
+IceInternal::EndpointIPtr
+IceWS::EndpointFactoryI::read(IceInternal::BasicStream* s) const
+{
+ return new EndpointI(_instance, _delegate->read(s), s);
+}
+
+void
+IceWS::EndpointFactoryI::destroy()
+{
+ _delegate->destroy();
+ _instance = 0;
+}
+
+IceInternal::EndpointFactoryPtr
+IceWS::EndpointFactoryI::clone(const IceInternal::ProtocolInstancePtr&) const
+{
+ assert(false); // We don't support cloning this transport.
+ return 0;
+}
diff --git a/cpp/src/IceWS/EndpointI.h b/cpp/src/IceWS/EndpointI.h
new file mode 100644
index 00000000000..119a937b051
--- /dev/null
+++ b/cpp/src/IceWS/EndpointI.h
@@ -0,0 +1,95 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#ifndef ICE_WS_ENDPOINT_I_H
+#define ICE_WS_ENDPOINT_I_H
+
+#include <Ice/EndpointI.h>
+#include <Ice/IPEndpointIF.h>
+#include <Ice/EndpointFactory.h>
+#include <IceWS/InstanceF.h>
+#include <IceWS/EndpointInfo.h>
+
+namespace IceWS
+{
+
+class EndpointI : public IceInternal::EndpointI
+{
+public:
+
+ EndpointI(const InstancePtr&, const IceInternal::EndpointIPtr&, const std::string&);
+ EndpointI(const InstancePtr&, const IceInternal::EndpointIPtr&, std::vector<std::string>&);
+ EndpointI(const InstancePtr&, const IceInternal::EndpointIPtr&, IceInternal::BasicStream*);
+
+ virtual Ice::EndpointInfoPtr getInfo() const;
+ virtual Ice::Short type() const;
+ virtual const std::string& protocol() const;
+ virtual void streamWrite(IceInternal::BasicStream*) const;
+
+ virtual Ice::Int timeout() const;
+ virtual IceInternal::EndpointIPtr timeout(Ice::Int) const;
+ virtual const std::string& connectionId() const;
+ virtual IceInternal::EndpointIPtr connectionId(const ::std::string&) const;
+ virtual bool compress() const;
+ virtual IceInternal::EndpointIPtr compress(bool) const;
+ virtual bool datagram() const;
+ virtual bool secure() const;
+
+ virtual IceInternal::TransceiverPtr transceiver(IceInternal::EndpointIPtr&) const;
+ virtual std::vector<IceInternal::ConnectorPtr> connectors(Ice::EndpointSelectionType) const;
+ virtual void connectors_async(Ice::EndpointSelectionType, const IceInternal::EndpointI_connectorsPtr&) const;
+ virtual IceInternal::AcceptorPtr acceptor(IceInternal::EndpointIPtr&, const std::string&) const;
+ virtual std::vector<IceInternal::EndpointIPtr> expand() const;
+ virtual bool equivalent(const IceInternal::EndpointIPtr&) const;
+ virtual ::Ice::Int hash() const;
+ virtual std::string options() const;
+
+ virtual bool operator==(const Ice::LocalObject&) const;
+ virtual bool operator<(const Ice::LocalObject&) const;
+
+protected:
+
+ virtual bool checkOption(const std::string&, const std::string&, const std::string&);
+
+private:
+
+ //
+ // All members are const, because endpoints are immutable.
+ //
+ const InstancePtr _instance;
+ const IceInternal::IPEndpointIPtr _delegate;
+ const std::string _resource;
+};
+
+class EndpointFactoryI : public IceInternal::EndpointFactory
+{
+public:
+
+ virtual ~EndpointFactoryI();
+
+ virtual Ice::Short type() const;
+ virtual std::string protocol() const;
+ virtual IceInternal::EndpointIPtr create(std::vector<std::string>&, bool) const;
+ virtual IceInternal::EndpointIPtr read(IceInternal::BasicStream*) const;
+ virtual void destroy();
+
+ virtual IceInternal::EndpointFactoryPtr clone(const IceInternal::ProtocolInstancePtr&) const;
+
+private:
+
+ EndpointFactoryI(const InstancePtr&, const IceInternal::EndpointFactoryPtr&);
+ friend class PluginI;
+
+ InstancePtr _instance;
+ const IceInternal::EndpointFactoryPtr _delegate;
+};
+
+}
+
+#endif
diff --git a/cpp/src/IceWS/IceWS.rc b/cpp/src/IceWS/IceWS.rc
new file mode 100644
index 00000000000..c8bda4075f1
--- /dev/null
+++ b/cpp/src/IceWS/IceWS.rc
@@ -0,0 +1,38 @@
+#include "winver.h"
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 3,5,0,0
+ PRODUCTVERSION 3,5,0,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+#ifdef _DEBUG
+ FILEFLAGS VS_FF_DEBUG
+ #define INTERNALNAME "icews35d\0"
+ #define ORIGINALFILENAME "icews35d.dll\0"
+#else
+ FILEFLAGS 0x0L
+ #define INTERNALNAME "icews35\0"
+ #define ORIGINALFILENAME "icews35.dll\0"
+#endif
+ FILEOS 0x4L
+ FILETYPE VFT_DLL
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904e4"
+ BEGIN
+ VALUE "CompanyName", "ZeroC, Inc.\0"
+ VALUE "FileDescription", "IceWS DLL\0"
+ VALUE "FileVersion", "3.5.0\0"
+ VALUE "InternalName", INTERNALNAME
+ VALUE "LegalCopyright", "Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.\0"
+ VALUE "OriginalFilename", ORIGINALFILENAME
+ VALUE "ProductName", "Ice\0"
+ VALUE "ProductVersion", "3.5.0\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1252
+ END
+END
diff --git a/cpp/src/IceWS/Instance.cpp b/cpp/src/IceWS/Instance.cpp
new file mode 100644
index 00000000000..11eadbda3d0
--- /dev/null
+++ b/cpp/src/IceWS/Instance.cpp
@@ -0,0 +1,28 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <IceWS/Instance.h>
+#include <IceWS/EndpointI.h>
+#include <Ice/ProtocolPluginFacade.h>
+
+using namespace std;
+using namespace Ice;
+using namespace IceInternal;
+using namespace IceWS;
+
+IceUtil::Shared* IceWS::upCast(IceWS::Instance* p) { return p; }
+
+IceWS::Instance::Instance(const CommunicatorPtr& communicator, Short type, const string& protocol) :
+ ProtocolInstance(communicator, type, protocol)
+{
+}
+
+IceWS::Instance::~Instance()
+{
+}
diff --git a/cpp/src/IceWS/Instance.h b/cpp/src/IceWS/Instance.h
new file mode 100644
index 00000000000..d148a133c85
--- /dev/null
+++ b/cpp/src/IceWS/Instance.h
@@ -0,0 +1,30 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#ifndef ICE_WS_INSTANCE_H
+#define ICE_WS_INSTANCE_H
+
+#include <IceWS/InstanceF.h>
+#include <Ice/ProtocolInstance.h>
+#include <Ice/CommunicatorF.h>
+
+namespace IceWS
+{
+
+class Instance : public IceInternal::ProtocolInstance
+{
+public:
+
+ Instance(const Ice::CommunicatorPtr&, Ice::Short, const std::string&);
+ virtual ~Instance();
+};
+
+}
+
+#endif
diff --git a/cpp/src/IceWS/InstanceF.h b/cpp/src/IceWS/InstanceF.h
new file mode 100644
index 00000000000..d069ca9d3ec
--- /dev/null
+++ b/cpp/src/IceWS/InstanceF.h
@@ -0,0 +1,25 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#ifndef ICE_WS_INSTANCE_F_H
+#define ICE_WS_INSTANCE_F_H
+
+#include <IceUtil/Shared.h>
+#include <Ice/Handle.h>
+
+namespace IceWS
+{
+
+class Instance;
+IceUtil::Shared* upCast(IceWS::Instance*);
+typedef IceInternal::Handle<Instance> InstancePtr;
+
+}
+
+#endif
diff --git a/cpp/src/IceWS/Makefile b/cpp/src/IceWS/Makefile
new file mode 100644
index 00000000000..3e961791839
--- /dev/null
+++ b/cpp/src/IceWS/Makefile
@@ -0,0 +1,64 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../..
+
+LIBFILENAME = $(call mklibfilename,IceWS,$(VERSION))
+SONAME = $(call mksoname,IceWS,$(SOVERSION))
+LIBNAME = $(call mklibname,IceWS)
+
+TARGETS = $(call mklibtargets,$(libdir)/$(LIBFILENAME),$(libdir)/$(SONAME),$(libdir)/$(LIBNAME))
+
+OBJS = AcceptorI.o \
+ ConnectorI.o \
+ EndpointInfo.o \
+ ConnectionInfo.o \
+ EndpointI.o \
+ Instance.o \
+ PluginI.o \
+ TransceiverI.o \
+ Util.o
+
+SRCS = $(OBJS:.o=.cpp)
+
+SLICE_SRCS = $(SDIR)/EndpointInfo.ice \
+ $(SDIR)/ConnectionInfo.ice
+
+HDIR = $(headerdir)/IceWS
+SDIR = $(slicedir)/IceWS
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I.. $(CPPFLAGS) -DICE_WS_API_EXPORTS $(OPENSSL_FLAGS)
+SLICE2CPPFLAGS := --ice --include-dir IceWS --dll-export ICE_WS_API $(SLICE2CPPFLAGS)
+
+LINKWITH := $(BZIP2_RPATH_LINK) -lIce -lIceUtil $(OPENSSL_LIBS) $(CXXLIBS)
+
+ifeq ($(STATICLIBS),yes)
+$(libdir)/$(LIBNAME): $(OBJS)
+ rm -f $@
+ $(call mklib,$@,$(OBJS))
+else
+$(libdir)/$(LIBFILENAME): $(OBJS)
+ rm -f $@
+ $(call mkshlib,$@,$(SONAME),$(OBJS),$(LINKWITH))
+
+$(libdir)/$(SONAME): $(libdir)/$(LIBFILENAME)
+ rm -f $@
+ ln -s $(LIBFILENAME) $@
+
+$(libdir)/$(LIBNAME): $(libdir)/$(SONAME)
+ rm -f $@
+ ln -s $(SONAME) $@
+endif
+
+install:: all
+ $(call installlib,$(install_libdir),$(libdir),$(LIBFILENAME),$(SONAME),$(LIBNAME))
+
+include .depend
diff --git a/cpp/src/IceWS/Makefile.mak b/cpp/src/IceWS/Makefile.mak
new file mode 100644
index 00000000000..0b1b9339c72
--- /dev/null
+++ b/cpp/src/IceWS/Makefile.mak
@@ -0,0 +1,71 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ..\..
+
+LIBNAME = $(top_srcdir)\lib\icews$(LIBSUFFIX).lib
+DLLNAME = $(top_srcdir)\bin\icews$(SOVERSION)$(LIBSUFFIX)$(COMPSUFFIX).dll
+
+TARGETS = $(LIBNAME) $(DLLNAME)
+
+OBJS = AcceptorI.obj \
+ ConnectorI.obj \
+ ConnectionInfo.obj \
+ EndpointInfo.obj \
+ EndpointI.obj \
+ Instance.obj \
+ PluginI.obj \
+ TransceiverI.obj \
+ Util.obj
+
+SRCS = $(OBJS:.obj=.cpp)
+
+HDIR = $(headerdir)\IceWS
+SDIR = $(slicedir)\IceWS
+
+!include $(top_srcdir)/config/Make.rules.mak
+
+CPPFLAGS = -I.. $(CPPFLAGS) -DICE_WS_API_EXPORTS -DWIN32_LEAN_AND_MEAN
+SLICE2CPPFLAGS = --ice --include-dir IceWS --dll-export ICE_WS_API $(SLICE2CPPFLAGS)
+
+LINKWITH = $(OPENSSL_LIBS) $(LIBS) ws2_32.lib
+
+!if "$(GENERATE_PDB)" == "yes"
+PDBFLAGS = /pdb:$(DLLNAME:.dll=.pdb)
+!endif
+
+RES_FILE = IceWS.res
+
+$(LIBNAME): $(DLLNAME)
+
+$(DLLNAME): $(OBJS) IceWS.res
+ $(LINK) $(BASE):0x24000000 $(LD_DLLFLAGS) $(PDBFLAGS) $(OBJS) $(PREOUT)$@ $(PRELIBS)$(LINKWITH) $(RES_FILE)
+ move $(DLLNAME:.dll=.lib) $(LIBNAME)
+ @if exist $@.manifest echo ^ ^ ^ Embedding manifest using $(MT) && \
+ $(MT) -nologo -manifest $@.manifest -outputresource:$@;#2 && del /q $@.manifest
+ @if exist $(DLLNAME:.dll=.exp) del /q $(DLLNAME:.dll=.exp)
+
+clean::
+ -del /q ConnectionInfo.cpp $(HDIR)\ConnectionInfo.h
+ -del /q EndpointInfo.cpp $(HDIR)\EndpointInfo.h
+ -del /q IceWS.res
+
+install:: all
+ copy $(LIBNAME) "$(install_libdir)"
+ copy $(DLLNAME) "$(install_bindir)"
+
+
+!if "$(GENERATE_PDB)" == "yes"
+
+install:: all
+ copy $(DLLNAME:.dll=.pdb) "$(install_bindir)"
+
+!endif
+
+!include .depend.mak
diff --git a/cpp/src/IceWS/PluginI.cpp b/cpp/src/IceWS/PluginI.cpp
new file mode 100644
index 00000000000..e4cacc3aea2
--- /dev/null
+++ b/cpp/src/IceWS/PluginI.cpp
@@ -0,0 +1,62 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <IceWS/PluginI.h>
+#include <IceWS/Instance.h>
+#include <IceWS/EndpointI.h>
+#include <IceWS/EndpointInfo.h>
+#include <Ice/ProtocolPluginFacade.h>
+
+using namespace std;
+using namespace Ice;
+using namespace IceWS;
+
+//
+// Plug-in factory function.
+//
+extern "C"
+{
+
+ICE_DECLSPEC_EXPORT Ice::Plugin*
+createIceWS(const CommunicatorPtr& communicator, const string& /*name*/, const StringSeq& /*args*/)
+{
+ return new PluginI(communicator);
+}
+
+}
+
+//
+// Plugin implementation.
+//
+IceWS::PluginI::PluginI(const Ice::CommunicatorPtr& communicator)
+{
+ IceInternal::ProtocolPluginFacadePtr facade = getProtocolPluginFacade(communicator);
+ IceInternal::EndpointFactoryPtr tcpFactory = facade->getEndpointFactory(TCPEndpointType);
+ if(tcpFactory)
+ {
+ InstancePtr tcpInstance = new Instance(communicator, WSEndpointType, "ws");
+ facade->addEndpointFactory(new EndpointFactoryI(tcpInstance, tcpFactory->clone(tcpInstance)));
+ }
+ IceInternal::EndpointFactoryPtr sslFactory = facade->getEndpointFactory(2); // 2 = SSLEndpointType
+ if(sslFactory)
+ {
+ InstancePtr sslInstance = new Instance(communicator, WSSEndpointType, "wss");
+ facade->addEndpointFactory(new EndpointFactoryI(sslInstance, sslFactory->clone(sslInstance)));
+ }
+}
+
+void
+IceWS::PluginI::initialize()
+{
+}
+
+void
+IceWS::PluginI::destroy()
+{
+}
diff --git a/cpp/src/IceWS/PluginI.h b/cpp/src/IceWS/PluginI.h
new file mode 100644
index 00000000000..436e8084295
--- /dev/null
+++ b/cpp/src/IceWS/PluginI.h
@@ -0,0 +1,35 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#ifndef ICE_WS_PLUGIN_I_H
+#define ICE_WS_PLUGIN_I_H
+
+#include <IceWS/Plugin.h>
+#include <IceWS/InstanceF.h>
+#include <Ice/CommunicatorF.h>
+
+namespace IceWS
+{
+
+class PluginI : public IceWS::Plugin
+{
+public:
+
+ PluginI(const Ice::CommunicatorPtr&);
+
+ //
+ // From Ice::Plugin.
+ //
+ virtual void initialize();
+ virtual void destroy();
+};
+
+}
+
+#endif
diff --git a/cpp/src/IceWS/TransceiverI.cpp b/cpp/src/IceWS/TransceiverI.cpp
new file mode 100644
index 00000000000..ae1c1fb7442
--- /dev/null
+++ b/cpp/src/IceWS/TransceiverI.cpp
@@ -0,0 +1,1593 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <IceWS/TransceiverI.h>
+#include <IceWS/EndpointInfo.h>
+#include <IceWS/ConnectionInfo.h>
+#include <IceWS/Instance.h>
+#include <IceWS/Util.h>
+#include <Ice/Communicator.h>
+#include <Ice/LoggerUtil.h>
+#include <Ice/Buffer.h>
+#include <Ice/LocalException.h>
+#include <Ice/Stats.h>
+#include <Ice/Base64.h>
+#include <IceUtil/Random.h>
+#include <IceUtil/StringUtil.h>
+
+#include <IceUtil/DisableWarnings.h>
+
+#include <stdint.h>
+#include <climits>
+
+using namespace std;
+using namespace Ice;
+using namespace IceWS;
+using namespace IceInternal;
+
+//
+// WebSocket opcodes
+//
+#define OP_CONT 0x0 // Continuation frame
+#define OP_TEXT 0x1 // Text frame
+#define OP_DATA 0x2 // Data frame
+#define OP_RES_0x3 0x3 // Reserved
+#define OP_RES_0x4 0x4 // Reserved
+#define OP_RES_0x5 0x5 // Reserved
+#define OP_RES_0x6 0x6 // Reserved
+#define OP_RES_0x7 0x7 // Reserved
+#define OP_CLOSE 0x8 // Connection close
+#define OP_PING 0x9 // Ping
+#define OP_PONG 0xA // Pong
+#define OP_RES_0xB 0xB // Reserved
+#define OP_RES_0xC 0xC // Reserved
+#define OP_RES_0xD 0xD // Reserved
+#define OP_RES_0xE 0xE // Reserved
+#define OP_RES_0xF 0xF // Reserved
+#define FLAG_FINAL 0x80 // Last frame
+#define FLAG_MASKED 0x80 // Payload is masked
+
+#define CLOSURE_NORMAL 1000
+#define CLOSURE_SHUTDOWN 1001
+#define CLOSURE_PROTOCOL_ERROR 1002
+#define CLOSURE_TOO_BIG 1009
+
+namespace
+{
+
+const string _iceProtocol = "ice.zeroc.com";
+const string _wsUUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
+
+void htonll(Long v, Byte* dest)
+{
+ //
+ // Transfer a 64-bit integer in network (big-endian) order.
+ //
+#ifdef ICE_BIG_ENDIAN
+ const Byte* src = reinterpret_cast<const Byte*>(&v);
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest = *src;
+#else
+ const Byte* src = reinterpret_cast<const Byte*>(&v) + sizeof(Long) - 1;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest++ = *src--;
+ *dest = *src;
+#endif
+}
+
+Long nlltoh(const Byte* src)
+{
+ Long v;
+
+ //
+ // Extract a 64-bit integer in network (big-endian) order.
+ //
+#ifdef ICE_BIG_ENDIAN
+ Byte* dest = reinterpret_cast<Byte*>(&v);
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest++ = *src++;
+ *dest = *src;
+#else
+ Byte* dest = reinterpret_cast<Byte*>(&v) + sizeof(Long) - 1;
+ *dest-- = *src++;
+ *dest-- = *src++;
+ *dest-- = *src++;
+ *dest-- = *src++;
+ *dest-- = *src++;
+ *dest-- = *src++;
+ *dest-- = *src++;
+ *dest = *src;
+#endif
+
+ return v;
+}
+
+}
+
+NativeInfoPtr
+IceWS::TransceiverI::getNativeInfo()
+{
+ return _delegate->getNativeInfo();
+}
+
+#ifdef ICE_USE_IOCP
+AsyncInfo*
+IceWS::TransceiverI::getAsyncInfo(SocketOperation status)
+{
+ return _delegate->getNativeInfo()->getAsyncInfo(status);
+}
+#endif
+
+SocketOperation
+IceWS::TransceiverI::initialize(Buffer& readBuffer, Buffer& writeBuffer, bool& hasMoreData)
+{
+ //
+ // Delegate logs exceptions that occur during initialize(), so there's no need to trap them here.
+ //
+ if(_state == StateInitializeDelegate)
+ {
+ SocketOperation op = _delegate->initialize(readBuffer, writeBuffer, hasMoreData);
+ if(op != SocketOperationNone)
+ {
+ return op;
+ }
+ _state = StateConnected;
+ }
+
+ try
+ {
+ if(_state == StateConnected)
+ {
+ //
+ // We don't know how much we'll need to read.
+ //
+ _readBuffer.b.resize(1024);
+ _readI = _readBuffer.i = _readBuffer.b.begin();
+
+ //
+ // The server waits for the client's upgrade request, the
+ // client sends the upgrade request.
+ //
+ _state = StateUpgradeRequestPending;
+ if(!_incoming)
+ {
+ //
+ // Compose the upgrade request.
+ //
+ ostringstream out;
+ out << "GET " << _resource << " HTTP/1.1\r\n"
+ << "Host: " << _host << ":" << _port << "\r\n"
+ << "Upgrade: websocket\r\n"
+ << "Connection: Upgrade\r\n"
+ << "Sec-WebSocket-Protocol: " << _iceProtocol << "\r\n"
+ << "Sec-WebSocket-Version: 13\r\n"
+ << "Sec-WebSocket-Key: ";
+
+ //
+ // The value for Sec-WebSocket-Key is a 16-byte random number,
+ // encoded with Base64.
+ //
+ vector<unsigned char> key(16);
+ IceUtilInternal::generateRandom(reinterpret_cast<char*>(&key[0]), static_cast<int>(key.size()));
+ _key = IceInternal::Base64::encode(key);
+ out << _key << "\r\n\r\n"; // EOM
+
+ string str = out.str();
+ _writeBuffer.b.resize(str.size());
+ memcpy(&_writeBuffer.b[0], str.c_str(), str.size());
+ _writeBuffer.i = _writeBuffer.b.begin();
+ }
+ }
+
+ //
+ // Try to write the client's upgrade request.
+ //
+ if(_state == StateUpgradeRequestPending && !_incoming)
+ {
+ if(_writeBuffer.i < _writeBuffer.b.end())
+ {
+ SocketOperation s = _delegate->write(_writeBuffer);
+ if(s)
+ {
+ return s;
+ }
+ }
+ assert(_writeBuffer.i == _writeBuffer.b.end());
+ _state = StateUpgradeResponsePending;
+ }
+
+ while(true)
+ {
+ if(_readBuffer.i < _readBuffer.b.end())
+ {
+ SocketOperation s = _delegate->read(_readBuffer, hasMoreData);
+ if(s == SocketOperationWrite || _readBuffer.i == _readBuffer.b.begin())
+ {
+ return s;
+ }
+ }
+
+ //
+ // Try to read the client's upgrade request or the server's response.
+ //
+ if((_state == StateUpgradeRequestPending && _incoming) ||
+ (_state == StateUpgradeResponsePending && !_incoming))
+ {
+ //
+ // Check if we have enough data for a complete message.
+ //
+ const Ice::Byte* p = _parser->isCompleteMessage(&_readBuffer.b[0], _readBuffer.i);
+ if(!p)
+ {
+ if(_readBuffer.i < _readBuffer.b.end())
+ {
+ return SocketOperationRead;
+ }
+
+ //
+ // Enlarge the buffer and try to read more.
+ //
+ const size_t oldSize = static_cast<size_t>(_readBuffer.i - _readBuffer.b.begin());
+ if(oldSize + 1024 > _instance->messageSizeMax())
+ {
+ throw MemoryLimitException(__FILE__, __LINE__);
+ }
+ _readBuffer.b.resize(oldSize + 1024);
+ _readBuffer.i = _readBuffer.b.begin() + oldSize;
+ continue; // Try again to read the response/request
+ }
+
+ //
+ // Set _readI at the end of the response/request message.
+ //
+ _readI = _readBuffer.b.begin() + (p - &_readBuffer.b[0]);
+ }
+
+ //
+ // We're done, the client's upgrade request or server's response is read.
+ //
+ break;
+ }
+
+ try
+ {
+ //
+ // Parse the client's upgrade request.
+ //
+ if(_state == StateUpgradeRequestPending && _incoming)
+ {
+ if(_parser->parse(&_readBuffer.b[0], _readI))
+ {
+ handleRequest(_writeBuffer);
+ _state = StateUpgradeResponsePending;
+ }
+ else
+ {
+ throw ProtocolException(__FILE__, __LINE__, "incomplete request message");
+ }
+ }
+
+ if(_state == StateUpgradeResponsePending)
+ {
+ if(_incoming)
+ {
+ if(_writeBuffer.i < _writeBuffer.b.end())
+ {
+ SocketOperation s = _delegate->write(_writeBuffer);
+ if(s)
+ {
+ return s;
+ }
+ }
+ }
+ else
+ {
+ //
+ // Parse the server's response
+ //
+ if(_parser->parse(&_readBuffer.b[0], _readI))
+ {
+ handleResponse();
+ }
+ else
+ {
+ throw ProtocolException(__FILE__, __LINE__, "incomplete response message");
+ }
+ }
+ }
+ }
+ catch(const WebSocketException& ex)
+ {
+ throw ProtocolException(__FILE__, __LINE__, ex.reason);
+ }
+
+ _state = StateOpened;
+ _nextState = StateOpened;
+
+ hasMoreData |= _readI < _readBuffer.i;
+ }
+ catch(const Ice::LocalException& ex)
+ {
+ if(_instance->traceLevel() >= 2)
+ {
+ Trace out(_instance->logger(), _instance->traceCategory());
+ out << protocol() << " connection HTTP upgrade request failed\n" << toString() << "\n" << ex;
+ }
+ throw;
+ }
+
+ if(_instance->traceLevel() >= 1)
+ {
+ Trace out(_instance->logger(), _instance->traceCategory());
+ if(_incoming)
+ {
+ out << "accepted " << protocol() << " connection HTTP upgrade request\n" << toString();
+ }
+ else
+ {
+ out << protocol() << " connection HTTP upgrade request accepted\n" << toString();
+ }
+ }
+
+ return SocketOperationNone;
+}
+
+SocketOperation
+IceWS::TransceiverI::closing(bool initiator, const Ice::LocalException& reason)
+{
+ if(_instance->traceLevel() >= 1)
+ {
+ Trace out(_instance->logger(), _instance->traceCategory());
+ out << "gracefully closing " << protocol() << " connection\n" << toString();
+ }
+
+ State s = _nextState == StateOpened ? _state : _nextState;
+
+ if(s == StateClosingRequestPending && _closingInitiator)
+ {
+ //
+ // If we initiated a close connection but also received a
+ // close connection, we assume we didn't initiated the
+ // connection and we send the close frame now. This is to
+ // ensure that if both peers close the connection at the same
+ // time we don't hang having both peer waiting for the close
+ // frame of the other.
+ //
+ assert(!initiator);
+ _closingInitiator = false;
+ return SocketOperationWrite;
+ }
+ else if(s >= StateClosingRequestPending)
+ {
+ return SocketOperationNone;
+ }
+
+ _closingInitiator = initiator;
+ if(dynamic_cast<const Ice::CloseConnectionException*>(&reason))
+ {
+ _closingReason = CLOSURE_NORMAL;
+ }
+ else if(dynamic_cast<const Ice::ObjectAdapterDeactivatedException*>(&reason) ||
+ dynamic_cast<const Ice::CommunicatorDestroyedException*>(&reason))
+ {
+ _closingReason = CLOSURE_SHUTDOWN;
+ }
+ else if(dynamic_cast<const Ice::ProtocolException*>(&reason))
+ {
+ _closingReason = CLOSURE_PROTOCOL_ERROR;
+ }
+ else if(dynamic_cast<const Ice::MemoryLimitException*>(&reason))
+ {
+ _closingReason = CLOSURE_TOO_BIG;
+ }
+
+ if(_state == StateOpened)
+ {
+ _state = StateClosingRequestPending;
+ return initiator ? SocketOperationRead : SocketOperationWrite;
+ }
+ else
+ {
+ _nextState = StateClosingRequestPending;
+ return SocketOperationNone;
+ }
+}
+
+void
+IceWS::TransceiverI::close()
+{
+ _delegate->close();
+ _state = StateClosed;
+}
+
+SocketOperation
+IceWS::TransceiverI::write(Buffer& buf)
+{
+ if(_writePending)
+ {
+ return SocketOperationWrite;
+ }
+
+ if(_state < StateOpened)
+ {
+ if(_state < StateConnected)
+ {
+ return _delegate->write(buf);
+ }
+ else
+ {
+ return _delegate->write(_writeBuffer);
+ }
+ }
+
+ do
+ {
+ if(preWrite(buf))
+ {
+ if(_writeBuffer.i < _writeBuffer.b.end())
+ {
+ SocketOperation s = _delegate->write(_writeBuffer);
+ if(s)
+ {
+ return s;
+ }
+ }
+
+ if(_incoming && !buf.b.empty() && _writeState == WriteStatePayload)
+ {
+ SocketOperation s = _delegate->write(buf);
+ if(s)
+ {
+ return s;
+ }
+ }
+ }
+ }
+ while(postWrite(buf));
+
+ if(_state == StateClosingResponsePending && !_closingInitiator)
+ {
+ return SocketOperationRead;
+ }
+ return SocketOperationNone;
+}
+
+SocketOperation
+IceWS::TransceiverI::read(Buffer& buf, bool& hasMoreData)
+{
+ if(_readPending)
+ {
+ return SocketOperationRead;
+ }
+
+ if(_state < StateOpened)
+ {
+ if(_state < StateConnected)
+ {
+ return _delegate->read(buf, hasMoreData);
+ }
+ else
+ {
+ if(_delegate->read(_readBuffer, hasMoreData) == SocketOperationWrite)
+ {
+ return SocketOperationWrite;
+ }
+ else
+ {
+ return SocketOperationNone;
+ }
+ }
+ }
+
+ SocketOperation s = SocketOperationNone;
+ do
+ {
+ if(preRead(buf))
+ {
+ if(_readState == ReadStatePayload)
+ {
+ s = _delegate->read(buf, hasMoreData);
+ }
+ else
+ {
+ s = _delegate->read(_readBuffer, hasMoreData);
+ }
+
+ if(s == SocketOperationWrite)
+ {
+ postRead(buf);
+ return s;
+ }
+ }
+ }
+ while(postRead(buf));
+
+ hasMoreData = _readI < _readBuffer.i;
+
+ s = buf.i == buf.b.end() ? SocketOperationNone : SocketOperationRead;
+
+ if(((_state == StateClosingRequestPending && !_closingInitiator) ||
+ (_state == StateClosingResponsePending && _closingInitiator) ||
+ _state == StatePingPending ||
+ _state == StatePongPending) &&
+ _writeState == WriteStateHeader)
+ {
+ // We have things to write, ask to be notified when writes are ready.
+ s = static_cast<SocketOperation>(s | SocketOperationWrite);
+ }
+ return s;
+}
+
+#ifdef ICE_USE_IOCP
+bool
+IceWS::TransceiverI::startWrite(Buffer& buf)
+{
+ _writePending = true;
+ if(_state < StateOpened)
+ {
+ if(_state < StateConnected)
+ {
+ return _delegate->startWrite(buf);
+ }
+ else
+ {
+ return _delegate->startWrite(buf);
+ }
+ }
+
+ if(preWrite(buf))
+ {
+ if(_writeBuffer.i < _writeBuffer.b.end())
+ {
+ _delegate->startWrite(_writeBuffer);
+ return false;
+ }
+ else
+ {
+ assert(_incoming);
+ return _delegate->startWrite(buf);
+ }
+ }
+ else
+ {
+ _delegate->getNativeInfo()->completed(IceInternal::SocketOperationWrite);
+ return false;
+ }
+}
+
+void
+IceWS::TransceiverI::finishWrite(Buffer& buf)
+{
+ _writePending = false;
+ if(_state < StateOpened)
+ {
+ if(_state < StateConnected)
+ {
+ _delegate->finishWrite(buf);
+ }
+ else
+ {
+ _delegate->finishWrite(_writeBuffer);
+ }
+ return;
+ }
+
+ if(_writeBuffer.i < _writeBuffer.b.end())
+ {
+ _delegate->finishWrite(_writeBuffer);
+ }
+ else if(!buf.b.empty() && buf.i != buf.b.end())
+ {
+ assert(_incoming);
+ _delegate->finishWrite(buf);
+ }
+
+ postWrite(buf);
+}
+
+void
+IceWS::TransceiverI::startRead(Buffer& buf)
+{
+ _readPending = true;
+ if(_state < StateOpened)
+ {
+ if(_state < StateConnected)
+ {
+ _delegate->startRead(buf);
+ }
+ else
+ {
+ _delegate->startRead(_readBuffer);
+ }
+ return;
+ }
+
+ if(preRead(buf))
+ {
+ if(_readState == ReadStatePayload)
+ {
+ _delegate->startRead(buf);
+ }
+ else
+ {
+ _delegate->startRead(_readBuffer);
+ }
+ }
+ else
+ {
+ _delegate->getNativeInfo()->completed(IceInternal::SocketOperationRead);
+ }
+}
+
+void
+IceWS::TransceiverI::finishRead(Buffer& buf)
+{
+ _readPending = false;
+ if(_state < StateOpened)
+ {
+ if(_state < StateConnected)
+ {
+ _delegate->finishRead(buf);
+ }
+ else
+ {
+ _delegate->finishRead(_readBuffer);
+ }
+ return;
+ }
+
+ if(buf.b.empty() || buf.i == buf.b.end())
+ {
+ // Nothing to do.
+ }
+ else if(_readState == ReadStatePayload)
+ {
+ _delegate->finishRead(buf);
+ }
+ else
+ {
+ _delegate->finishRead(_readBuffer);
+ }
+ postRead(buf);
+}
+#endif
+
+string
+IceWS::TransceiverI::protocol() const
+{
+ return _instance->protocol();
+}
+
+string
+IceWS::TransceiverI::toString() const
+{
+ return _delegate->toString();
+}
+
+Ice::ConnectionInfoPtr
+IceWS::TransceiverI::getInfo() const
+{
+ IPConnectionInfoPtr di = IPConnectionInfoPtr::dynamicCast(_delegate->getInfo());
+ assert(di);
+ IceWS::ConnectionInfoPtr info = new IceWS::ConnectionInfo();
+ info->localAddress = di->localAddress;
+ info->localPort = di->localPort;
+ info->remoteAddress = di->remoteAddress;
+ info->remotePort = di->remotePort;
+ return info;
+}
+
+void
+IceWS::TransceiverI::checkSendSize(const Buffer& buf, size_t messageSizeMax)
+{
+ _delegate->checkSendSize(buf, messageSizeMax);
+}
+
+IceWS::TransceiverI::TransceiverI(const InstancePtr& instance, const TransceiverPtr& del,
+ const string& host, int port, const string& resource) :
+ _instance(instance),
+ _delegate(del),
+ _host(host),
+ _port(port),
+ _resource(resource),
+ _incoming(false),
+ _state(StateInitializeDelegate),
+ _parser(new HttpParser),
+ _readState(ReadStateOpcode),
+ _readBuffer(0),
+ _readBufferSize(1024),
+ _readLastFrame(false),
+ _readOpCode(0),
+ _readHeaderLength(0),
+ _readPayloadLength(0),
+ _writeState(WriteStateHeader),
+ _writeBuffer(0),
+ _writeBufferSize(1024),
+ _readPending(false),
+ _writePending(false)
+{
+ //
+ // For client connections, the sent frame payload must be
+ // masked. So we copy and send the message buffer data in chuncks
+ // of data whose size is up to the write buffer size.
+ //
+ const_cast<size_t&>(_writeBufferSize) = max(IceInternal::getSendBufferSize(del->getNativeInfo()->fd()), 1024);
+
+ //
+ // Write and read buffer size must be large enough to hold the frame header!
+ //
+ assert(_writeBufferSize > 256);
+ assert(_readBufferSize > 256);
+}
+
+IceWS::TransceiverI::TransceiverI(const InstancePtr& instance, const TransceiverPtr& del) :
+ _instance(instance),
+ _delegate(del),
+ _port(-1),
+ _incoming(true),
+ _state(StateInitializeDelegate),
+ _parser(new HttpParser),
+ _readState(ReadStateOpcode),
+ _readBuffer(0),
+ _readBufferSize(1024),
+ _readLastFrame(false),
+ _readOpCode(0),
+ _readHeaderLength(0),
+ _readPayloadLength(0),
+ _writeState(WriteStateHeader),
+ _writeBuffer(0),
+ _writeBufferSize(1024),
+ _readPending(false),
+ _writePending(false)
+{
+ //
+ // Write and read buffer size must be large enough to hold the frame header!
+ //
+ assert(_writeBufferSize > 256);
+ assert(_readBufferSize > 256);
+}
+
+IceWS::TransceiverI::~TransceiverI()
+{
+}
+
+void
+IceWS::TransceiverI::handleRequest(Buffer& responseBuffer)
+{
+ string val;
+
+ //
+ // HTTP/1.1
+ //
+ if(_parser->versionMajor() != 1 || _parser->versionMinor() != 1)
+ {
+ throw WebSocketException("unsupported HTTP version");
+ }
+
+ //
+ // "An |Upgrade| header field containing the value 'websocket',
+ // treated as an ASCII case-insensitive value."
+ //
+ if(!_parser->getHeader("Upgrade", val, true))
+ {
+ throw WebSocketException("missing value for Upgrade field");
+ }
+ else if(val != "websocket")
+ {
+ throw WebSocketException("invalid value `" + val + "' for Upgrade field");
+ }
+
+ //
+ // "A |Connection| header field that includes the token 'Upgrade',
+ // treated as an ASCII case-insensitive value.
+ //
+ if(!_parser->getHeader("Connection", val, true))
+ {
+ throw WebSocketException("missing value for Connection field");
+ }
+ else if(val.find("upgrade") == string::npos)
+ {
+ throw WebSocketException("invalid value `" + val + "' for Connection field");
+ }
+
+ //
+ // "A |Sec-WebSocket-Version| header field, with a value of 13."
+ //
+ if(!_parser->getHeader("Sec-WebSocket-Version", val, false))
+ {
+ throw WebSocketException("missing value for WebSocket version");
+ }
+ else if(val != "13")
+ {
+ throw WebSocketException("unsupported WebSocket version `" + val + "'");
+ }
+
+ //
+ // "Optionally, a |Sec-WebSocket-Protocol| header field, with a list
+ // of values indicating which protocols the client would like to
+ // speak, ordered by preference."
+ //
+ bool addProtocol = false;
+ if(_parser->getHeader("Sec-WebSocket-Protocol", val, true))
+ {
+ vector<string> protocols;
+ if(!IceUtilInternal::splitString(val, ",", protocols))
+ {
+ throw WebSocketException("invalid value `" + val + "' for WebSocket protocol");
+ }
+ for(vector<string>::iterator p = protocols.begin(); p != protocols.end(); ++p)
+ {
+ if(IceUtilInternal::trim(*p) != _iceProtocol)
+ {
+ throw WebSocketException("unknown value `" + *p + "' for WebSocket protocol");
+ }
+ addProtocol = true;
+ }
+ }
+
+ //
+ // "A |Sec-WebSocket-Key| header field with a base64-encoded
+ // value that, when decoded, is 16 bytes in length."
+ //
+ string key;
+ if(!_parser->getHeader("Sec-WebSocket-Key", key, false))
+ {
+ throw WebSocketException("missing value for WebSocket key");
+ }
+
+ vector<unsigned char> decodedKey = Base64::decode(key);
+ if(decodedKey.size() != 16)
+ {
+ throw WebSocketException("invalid value `" + key + "' for WebSocket key");
+ }
+
+ //
+ // Retain the target resource.
+ //
+ const_cast<string&>(_resource) = _parser->uri();
+
+ //
+ // Compose the response.
+ //
+ ostringstream out;
+ out << "HTTP/1.1 101 Switching Protocols\r\n"
+ << "Upgrade: websocket\r\n"
+ << "Connection: Upgrade\r\n";
+ if(addProtocol)
+ {
+ out << "Sec-WebSocket-Protocol: " << _iceProtocol << "\r\n";
+ }
+
+ //
+ // The response includes:
+ //
+ // "A |Sec-WebSocket-Accept| header field. The value of this
+ // header field is constructed by concatenating /key/, defined
+ // above in step 4 in Section 4.2.2, with the string "258EAFA5-
+ // E914-47DA-95CA-C5AB0DC85B11", taking the SHA-1 hash of this
+ // concatenated value to obtain a 20-byte value and base64-
+ // encoding (see Section 4 of [RFC4648]) this 20-byte hash.
+ //
+ out << "Sec-WebSocket-Accept: ";
+ string input = key + _wsUUID;
+ vector<unsigned char> v(&input[0], &input[0] + input.size());
+ vector<unsigned char> hash = calcSHA1(v);
+ out << IceInternal::Base64::encode(hash) << "\r\n" << "\r\n"; // EOM
+
+ string str = out.str();
+ responseBuffer.b.resize(str.size());
+ memcpy(&responseBuffer.b[0], str.c_str(), str.size());
+ responseBuffer.i = responseBuffer.b.begin();
+}
+
+void
+IceWS::TransceiverI::handleResponse()
+{
+ string val;
+
+ //
+ // HTTP/1.1
+ //
+ if(_parser->versionMajor() != 1 || _parser->versionMinor() != 1)
+ {
+ throw WebSocketException("unsupported HTTP version");
+ }
+
+ //
+ // "If the status code received from the server is not 101, the
+ // client handles the response per HTTP [RFC2616] procedures. In
+ // particular, the client might perform authentication if it
+ // receives a 401 status code; the server might redirect the client
+ // using a 3xx status code (but clients are not required to follow
+ // them), etc."
+ //
+ if(_parser->status() != 101)
+ {
+ ostringstream out;
+ out << "unexpected status value " << _parser->status();
+ if(!_parser->reason().empty())
+ {
+ out << ":" << endl << _parser->reason();
+ }
+ throw WebSocketException(out.str());
+ }
+
+ //
+ // "If the response lacks an |Upgrade| header field or the |Upgrade|
+ // header field contains a value that is not an ASCII case-
+ // insensitive match for the value "websocket", the client MUST
+ // _Fail the WebSocket Connection_."
+ //
+ if(!_parser->getHeader("Upgrade", val, true))
+ {
+ throw WebSocketException("missing value for Upgrade field");
+ }
+ else if(val != "websocket")
+ {
+ throw WebSocketException("invalid value `" + val + "' for Upgrade field");
+ }
+
+ //
+ // "If the response lacks a |Connection| header field or the
+ // |Connection| header field doesn't contain a token that is an
+ // ASCII case-insensitive match for the value "Upgrade", the client
+ // MUST _Fail the WebSocket Connection_."
+ //
+ if(!_parser->getHeader("Connection", val, true))
+ {
+ throw WebSocketException("missing value for Connection field");
+ }
+ else if(val.find("upgrade") == string::npos)
+ {
+ throw WebSocketException("invalid value `" + val + "' for Connection field");
+ }
+
+ //
+ // "If the response includes a |Sec-WebSocket-Protocol| header field
+ // and this header field indicates the use of a subprotocol that was
+ // not present in the client's handshake (the server has indicated a
+ // subprotocol not requested by the client), the client MUST _Fail
+ // the WebSocket Connection_."
+ //
+ if(_parser->getHeader("Sec-WebSocket-Protocol", val, true) && val != _iceProtocol)
+ {
+ throw WebSocketException("invalid value `" + val + "' for WebSocket protocol");
+ }
+
+ //
+ // "If the response lacks a |Sec-WebSocket-Accept| header field or
+ // the |Sec-WebSocket-Accept| contains a value other than the
+ // base64-encoded SHA-1 of the concatenation of the |Sec-WebSocket-
+ // Key| (as a string, not base64-decoded) with the string "258EAFA5-
+ // E914-47DA-95CA-C5AB0DC85B11" but ignoring any leading and
+ // trailing whitespace, the client MUST _Fail the WebSocket
+ // Connection_."
+ //
+ if(!_parser->getHeader("Sec-WebSocket-Accept", val, false))
+ {
+ throw WebSocketException("missing value for Sec-WebSocket-Accept");
+ }
+ string input = _key + _wsUUID;
+ vector<unsigned char> v(&input[0], &input[0] + input.size());
+ vector<unsigned char> hash = calcSHA1(v);
+ if(val != IceInternal::Base64::encode(hash))
+ {
+ throw WebSocketException("invalid value `" + val + "' for Sec-WebSocket-Accept");
+ }
+}
+
+bool
+IceWS::TransceiverI::preRead(Buffer& buf)
+{
+ while(true)
+ {
+ if(_readState == ReadStateOpcode)
+ {
+ //
+ // Is there enough data available to read the opcode?
+ //
+ if(!readBuffered(2))
+ {
+ return true;
+ }
+
+ //
+ // Most-significant bit indicates whether this is the
+ // last frame. Least-significant four bits hold the
+ // opcode.
+ //
+ unsigned char ch = static_cast<unsigned char>(*_readI++);
+ _readLastFrame = (ch & FLAG_FINAL) == FLAG_FINAL;
+ _readOpCode = ch & 0xf;
+
+ ch = static_cast<unsigned char>(*_readI++);
+
+ //
+ // Check the MASK bit. Messages sent by a client must be masked;
+ // messages sent by a server must not be masked.
+ //
+ const bool masked = (ch & FLAG_MASKED) == FLAG_MASKED;
+ if(masked != _incoming)
+ {
+ throw ProtocolException(__FILE__, __LINE__, "invalid masking");
+ }
+
+ //
+ // Extract the payload length, which can have the following values:
+ //
+ // 0-125: The payload length
+ // 126: The subsequent two bytes contain the payload length
+ // 127: The subsequent eight bytes contain the payload length
+ //
+ _readPayloadLength = (ch & 0x7f);
+ if(_readPayloadLength < 126)
+ {
+ _readHeaderLength = 0;
+ }
+ else if(_readPayloadLength == 126)
+ {
+ _readHeaderLength = 2; // Need to read a 16-bit payload length.
+ }
+ else
+ {
+ _readHeaderLength = 8; // Need to read a 64-bit payload length.
+ }
+ if(masked)
+ {
+ _readHeaderLength += 4; // Need to read a 32-bit mask.
+ }
+
+ _readState = ReadStateHeader;
+ }
+
+ if(_readState == ReadStateHeader)
+ {
+ //
+ // Is there enough data available to read the header?
+ //
+ if(_readHeaderLength > 0 && !readBuffered(_readHeaderLength))
+ {
+ return true;
+ }
+
+ if(_readPayloadLength == 126)
+ {
+ _readPayloadLength = static_cast<size_t>(ntohs(*reinterpret_cast<uint16_t*>(_readI)));
+ _readI += 2;
+ }
+ else if(_readPayloadLength == 127)
+ {
+ assert(_readPayloadLength == 127);
+ Long l = nlltoh(_readI);
+ _readI += 8;
+ if(l < 0 || l > INT_MAX)
+ {
+ ostringstream ostr;
+ ostr << "invalid WebSocket payload length: " << l;
+ throw ProtocolException(__FILE__, __LINE__, ostr.str());
+ }
+ _readPayloadLength = static_cast<size_t>(l);
+ }
+
+ //
+ // Read the mask if this is an incoming connection.
+ //
+ if(_incoming)
+ {
+ assert(_readBuffer.i - _readI >= 4); // We must have needed to read the mask.
+ memcpy(_readMask, _readI, 4); // Copy the mask.
+ _readI += 4;
+ }
+
+ switch(_readOpCode)
+ {
+ case OP_CONT: // Continuation frame
+ {
+ // TODO: Add support for continuation frames?
+ throw ProtocolException(__FILE__, __LINE__, "continuation frames not supported");
+ }
+ case OP_TEXT: // Text frame
+ {
+ throw ProtocolException(__FILE__, __LINE__, "text frames not supported");
+ }
+ case OP_DATA: // Data frame
+ {
+ if(!_readLastFrame)
+ {
+ throw ProtocolException(__FILE__, __LINE__, "continuation frames not supported");
+ }
+ if(_readPayloadLength <= 0)
+ {
+ throw ProtocolException(__FILE__, __LINE__, "payload length is 0");
+ }
+ _readState = ReadStatePayload;
+ break;
+ }
+ case OP_CLOSE: // Connection close
+ {
+ if(_instance->traceLevel() >= 2)
+ {
+ Trace out(_instance->logger(), _instance->traceCategory());
+ out << "received " << protocol() << " connection close frame\n" << toString();
+ }
+
+ State s = _nextState == StateOpened ? _state : _nextState;
+ if(s == StateClosingRequestPending)
+ {
+ //
+ // If we receive a close frame while we were actually
+ // waiting to send one, change the role and send a
+ // close frame response.
+ //
+ if(!_closingInitiator)
+ {
+ _closingInitiator = true;
+ }
+ if(_state == StateClosingRequestPending)
+ {
+ _state = StateClosingResponsePending;
+ }
+ else
+ {
+ _nextState = StateClosingResponsePending;
+ }
+ return false; // No longer interested in reading
+ }
+ else
+ {
+ ConnectionLostException ex(__FILE__, __LINE__);
+ ex.error = 0;
+ throw ex;
+ }
+ }
+ case OP_PING:
+ {
+ if(_instance->traceLevel() >= 2)
+ {
+ Trace out(_instance->logger(), _instance->traceCategory());
+ out << "received " << protocol() << " connection ping frame\n" << toString();
+ }
+ _readState = ReadStateControlFrame;
+ break;
+ }
+ case OP_PONG: // Pong
+ {
+ if(_instance->traceLevel() >= 2)
+ {
+ Trace out(_instance->logger(), _instance->traceCategory());
+ out << "received " << protocol() << " connection pong frame\n" << toString();
+ }
+ _readState = ReadStateControlFrame;
+ break;
+ }
+ default:
+ {
+ ostringstream ostr;
+ ostr << "unsupported opcode: " << _readOpCode;
+ throw ProtocolException(__FILE__, __LINE__, ostr.str());
+ }
+ }
+ }
+
+ if(_readState == ReadStateControlFrame)
+ {
+ if(_readPayloadLength > 0 && !readBuffered(_readPayloadLength))
+ {
+ return true;
+ }
+
+ if(_readPayloadLength > 0 && _readOpCode == OP_PING)
+ {
+ _pingPayload.clear();
+ _pingPayload.resize(_readPayloadLength);
+ memcpy(&_pingPayload[0], _readI, _pingPayload.size());
+ }
+
+ _readI += _readPayloadLength;
+ _readPayloadLength = 0;
+
+ if(_readOpCode == OP_PING)
+ {
+ if(_state == StateOpened)
+ {
+ _state = StatePongPending; // Send pong frame now
+ }
+ else if(_nextState < StatePongPending)
+ {
+ _nextState = StatePongPending; // Send pong frame next
+ }
+ }
+
+ //
+ // We've read the payload of the PING/PONG frame, we're ready
+ // to read a new frame.
+ //
+ _readState = ReadStateOpcode;
+ }
+
+ if(_readState == ReadStatePayload)
+ {
+ //
+ // This must be assigned before the check for the buffer. If the buffer is empty
+ // or already read, postRead will return false.
+ //
+ _readStart = buf.i;
+
+ if(buf.b.empty() || buf.i == buf.b.end())
+ {
+ return false;
+ }
+
+ if(_readI < _readBuffer.i)
+ {
+ size_t n = min(_readBuffer.i - _readI, buf.b.end() - buf.i);
+ memcpy(buf.i, _readI, n);
+ buf.i += n;
+ _readI += n;
+ }
+
+ //
+ // Continue reading if we didn't read the full message, otherwise give back
+ // the control to the connection
+ //
+ return buf.i < buf.b.end();
+ }
+ }
+}
+
+bool
+IceWS::TransceiverI::postRead(Buffer& buf)
+{
+ if(_readState != ReadStatePayload)
+ {
+ return _readStart < _readBuffer.i; // Returns true if data was read.
+ }
+
+ if(_readStart == buf.i)
+ {
+ return false; // Nothing was read or nothing to read.
+ }
+ assert(_readStart < buf.i);
+
+ if(_incoming)
+ {
+ //
+ // Unmask the data we just read.
+ //
+ IceInternal::Buffer::Container::iterator p = _readStart;
+ for(size_t n = _readStart - buf.b.begin(); p < buf.i; ++p, ++n)
+ {
+ *p ^= _readMask[n % 4];
+ }
+ }
+
+ _readPayloadLength -= buf.i - _readStart;
+ _readStart = buf.i;
+ if(_readPayloadLength == 0)
+ {
+ //
+ // We've read the complete payload, we're ready to read a new frame.
+ //
+ _readState = ReadStateOpcode;
+ }
+ return buf.i != buf.b.end();
+}
+
+bool
+IceWS::TransceiverI::preWrite(Buffer& buf)
+{
+ if(_writeState == WriteStateHeader)
+ {
+ if(_state == StateOpened)
+ {
+ if(buf.b.empty() || buf.i == buf.b.end())
+ {
+ return false;
+ }
+
+ assert(buf.i = buf.b.begin());
+ prepareWriteHeader(OP_DATA, buf.b.size());
+
+ //
+ // For server connections, we use the _writeBuffer only to
+ // write the header, the message is sent directly from the
+ // message buffer. For client connections, we use the write
+ // buffer for both the header and message buffer since we need
+ // to mask the message data.
+ //
+ if(_incoming)
+ {
+ _writeBuffer.b.resize(_writeBuffer.i - _writeBuffer.b.begin());
+ _writeBuffer.i = _writeBuffer.b.begin();
+ }
+ _writeState = WriteStatePayload;
+ }
+ else if(_state == StatePingPending)
+ {
+ prepareWriteHeader(OP_PING, 0); // Don't send any payload
+
+ _writeBuffer.b.resize(_writeBuffer.i - _writeBuffer.b.begin());
+ _writeState = WriteStateControlFrame;
+ _writeBuffer.i = _writeBuffer.b.begin();
+ }
+ else if(_state == StatePongPending)
+ {
+ prepareWriteHeader(OP_PONG, _pingPayload.size());
+ if(_pingPayload.size() > static_cast<size_t>(_writeBuffer.b.end() - _writeBuffer.i))
+ {
+ size_t pos = _writeBuffer.i - _writeBuffer.b.begin();
+ _writeBuffer.b.resize(pos + _pingPayload.size());
+ _writeBuffer.i = _writeBuffer.b.begin() + pos;
+ }
+ memcpy(_writeBuffer.i, &_pingPayload[0], _pingPayload.size());
+ _writeBuffer.i += _pingPayload.size();
+ _pingPayload.clear();
+
+ _writeBuffer.b.resize(_writeBuffer.i - _writeBuffer.b.begin());
+ _writeState = WriteStateControlFrame;
+ _writeBuffer.i = _writeBuffer.b.begin();
+ }
+ else if((_state == StateClosingRequestPending && !_closingInitiator) ||
+ (_state == StateClosingResponsePending && _closingInitiator))
+ {
+ prepareWriteHeader(OP_CLOSE, 2);
+
+ // Write closing reason
+ *reinterpret_cast<uint16_t*>(_writeBuffer.i) = htons(static_cast<uint16_t>(_closingReason));
+ if(!_incoming)
+ {
+ *_writeBuffer.i++ ^= _writeMask[0];
+ *_writeBuffer.i++ ^= _writeMask[1];
+ }
+ else
+ {
+ _writeBuffer.i += 2;
+ }
+
+ _writeState = WriteStateControlFrame;
+ _writeBuffer.b.resize(_writeBuffer.i - _writeBuffer.b.begin());
+ _writeBuffer.i = _writeBuffer.b.begin();
+ }
+ else
+ {
+ assert(_state != StateClosed);
+ return false; // Nothing to write in this state
+ }
+
+ _writePayloadLength = 0;
+ }
+
+ if(_writeState == WriteStatePayload)
+ {
+ //
+ // For an outgoing connection, each message must be masked with a random
+ // 32-bit value, so we copy the entire message into the internal buffer
+ // for writing.
+ //
+ // For an incoming connection, we use the internal buffer to hold the
+ // frame header, and then write the caller's buffer to avoid copying.
+ //
+ if(!_incoming)
+ {
+ if((_writePayloadLength == 0 || _writeBuffer.i == _writeBuffer.b.end()))
+ {
+ if(_writeBuffer.i == _writeBuffer.b.end())
+ {
+ _writeBuffer.i = _writeBuffer.b.begin();
+ }
+
+ size_t n = buf.i - buf.b.begin();
+ for(; n < buf.b.size() && _writeBuffer.i < _writeBuffer.b.end(); ++_writeBuffer.i, ++n)
+ {
+ *_writeBuffer.i = buf.b[n] ^ _writeMask[n % 4];
+ }
+ _writePayloadLength = n;
+
+ if(_writeBuffer.i < _writeBuffer.b.end())
+ {
+ _writeBuffer.b.resize(_writeBuffer.i - _writeBuffer.b.begin());
+ }
+ _writeBuffer.i = _writeBuffer.b.begin();
+ }
+ }
+ return true;
+ }
+ else
+ {
+ return _writeBuffer.i < _writeBuffer.b.end();
+ }
+}
+
+bool
+IceWS::TransceiverI::postWrite(Buffer& buf)
+{
+ if(_state > StateOpened && _writeState == WriteStateControlFrame)
+ {
+ if(_writeBuffer.i == _writeBuffer.b.end())
+ {
+ if(_state == StatePingPending)
+ {
+ if(_instance->traceLevel() >= 2)
+ {
+ Trace out(_instance->logger(), _instance->traceCategory());
+ out << "sent " << protocol() << " connection ping frame\n" << toString();
+ }
+ }
+ else if(_state == StatePongPending)
+ {
+ if(_instance->traceLevel() >= 2)
+ {
+ Trace out(_instance->logger(), _instance->traceCategory());
+ out << "sent " << protocol() << " connection pong frame\n" << toString();
+ }
+ }
+ else if((_state == StateClosingRequestPending && !_closingInitiator) ||
+ (_state == StateClosingResponsePending && _closingInitiator))
+ {
+ if(_instance->traceLevel() >= 2)
+ {
+ Trace out(_instance->logger(), _instance->traceCategory());
+ out << "sent " << protocol() << " connection close frame\n" << toString();
+ }
+
+ if(_state == StateClosingRequestPending && !_closingInitiator)
+ {
+ _writeState = WriteStateHeader;
+ _state = StateClosingResponsePending;
+ return false;
+ }
+ else
+ {
+ ConnectionLostException ex(__FILE__, __LINE__);
+ ex.error = 0;
+ throw ex;
+ }
+ }
+ else if(_state == StateClosed)
+ {
+ return false;
+ }
+
+ _state = _nextState;
+ _nextState = StateOpened;
+ _writeState = WriteStateHeader;
+ }
+ else
+ {
+ return true;
+ }
+ }
+
+ if(!_incoming && _writePayloadLength > 0)
+ {
+ if(_writeBuffer.i == _writeBuffer.b.end())
+ {
+ buf.i = buf.b.begin() + _writePayloadLength;
+ }
+ }
+
+ if(buf.b.empty() || buf.i == buf.b.end())
+ {
+ _writeState = WriteStateHeader;
+ if(_state == StatePingPending ||
+ _state == StatePongPending ||
+ (_state == StateClosingRequestPending && !_closingInitiator) ||
+ (_state == StateClosingResponsePending && _closingInitiator))
+ {
+ return true;
+ }
+ }
+ else if(_state == StateOpened)
+ {
+ return true;
+ }
+ return false;
+}
+
+bool
+IceWS::TransceiverI::readBuffered(IceInternal::Buffer::Container::size_type sz)
+{
+ if(_readI == _readBuffer.i)
+ {
+ _readBuffer.b.resize(_readBufferSize);
+ _readI = _readBuffer.i = _readBuffer.b.begin();
+ }
+ else
+ {
+ IceInternal::Buffer::Container::size_type available = _readBuffer.i - _readI;
+ if(available < sz)
+ {
+ if(_readI != &_readBuffer.b[0])
+ {
+ memmove(&_readBuffer.b[0], _readI, available);
+ }
+ _readBuffer.b.resize(max(_readBufferSize, sz));
+ _readI = _readBuffer.b.begin();
+ _readBuffer.i = _readI + available;
+ }
+ }
+
+ _readStart = _readBuffer.i;
+ if(_readI + sz > _readBuffer.i)
+ {
+ return false; // Not enough read.
+ }
+ assert(_readBuffer.i > _readI);
+ return true;
+}
+
+void
+IceWS::TransceiverI::prepareWriteHeader(Byte opCode, IceInternal::Buffer::Container::size_type payloadLength)
+{
+ //
+ // We need to prepare the frame header.
+ //
+ _writeBuffer.b.resize(_writeBufferSize);
+ _writeBuffer.i = _writeBuffer.b.begin();
+
+ //
+ // Set the opcode - this is the one and only data frame.
+ //
+ *_writeBuffer.i++ = static_cast<Byte>(opCode | FLAG_FINAL);
+
+ //
+ // Set the payload length.
+ //
+ if(payloadLength <= 125)
+ {
+ *_writeBuffer.i++ = static_cast<Byte>(payloadLength);
+ }
+ else if(payloadLength > 125 && payloadLength <= USHRT_MAX)
+ {
+ //
+ // Use an extra 16 bits to encode the payload length.
+ //
+ *_writeBuffer.i++ = static_cast<Byte>(126);
+ *reinterpret_cast<uint16_t*>(_writeBuffer.i) = htons(static_cast<uint16_t>(payloadLength));
+ _writeBuffer.i += 2;
+ }
+ else if(payloadLength > USHRT_MAX)
+ {
+ //
+ // Use an extra 64 bits to encode the payload length.
+ //
+ *_writeBuffer.i++ = static_cast<Byte>(127);
+ htonll(payloadLength, _writeBuffer.i);
+ _writeBuffer.i += 8;
+ }
+
+ if(!_incoming)
+ {
+ //
+ // Add a random 32-bit mask to every outgoing frame, copy the payload data,
+ // and apply the mask.
+ //
+ _writeBuffer.b[1] |= FLAG_MASKED;
+ IceUtilInternal::generateRandom(reinterpret_cast<char*>(_writeMask), sizeof(_writeMask));
+ memcpy(_writeBuffer.i, _writeMask, sizeof(_writeMask));
+ _writeBuffer.i += sizeof(_writeMask);
+ }
+}
+
diff --git a/cpp/src/IceWS/TransceiverI.h b/cpp/src/IceWS/TransceiverI.h
new file mode 100644
index 00000000000..87e809e6653
--- /dev/null
+++ b/cpp/src/IceWS/TransceiverI.h
@@ -0,0 +1,147 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#ifndef ICE_WS_TRANSCEIVER_I_H
+#define ICE_WS_TRANSCEIVER_I_H
+
+#include <IceWS/InstanceF.h>
+#include <IceWS/Plugin.h>
+#include <IceWS/Util.h>
+
+#include <Ice/LoggerF.h>
+#include <Ice/StatsF.h>
+#include <Ice/Transceiver.h>
+#include <Ice/Network.h>
+#include <Ice/Buffer.h>
+
+namespace IceWS
+{
+
+class ConnectorI;
+class AcceptorI;
+
+class TransceiverI : public IceInternal::Transceiver
+{
+public:
+
+ virtual IceInternal::NativeInfoPtr getNativeInfo();
+#ifdef ICE_USE_IOCP
+ virtual IceInternal::AsyncInfo* getAsyncInfo(IceInternal::SocketOperation);
+#endif
+
+ virtual IceInternal::SocketOperation initialize(IceInternal::Buffer&, IceInternal::Buffer&, bool&);
+ virtual IceInternal::SocketOperation closing(bool, const Ice::LocalException&);
+ virtual void close();
+ virtual IceInternal::SocketOperation write(IceInternal::Buffer&);
+ virtual IceInternal::SocketOperation read(IceInternal::Buffer&, bool&);
+#ifdef ICE_USE_IOCP
+ virtual bool startWrite(IceInternal::Buffer&);
+ virtual void finishWrite(IceInternal::Buffer&);
+ virtual void startRead(IceInternal::Buffer&);
+ virtual void finishRead(IceInternal::Buffer&);
+#endif
+ virtual std::string protocol() const;
+ virtual std::string toString() const;
+ virtual Ice::ConnectionInfoPtr getInfo() const;
+ virtual void checkSendSize(const IceInternal::Buffer&, size_t);
+
+private:
+
+ TransceiverI(const InstancePtr&, const IceInternal::TransceiverPtr&, const std::string&, int, const std::string&);
+ TransceiverI(const InstancePtr&, const IceInternal::TransceiverPtr&);
+ virtual ~TransceiverI();
+
+ void handleRequest(IceInternal::Buffer&);
+ void handleResponse();
+
+ bool preRead(IceInternal::Buffer&);
+ bool postRead(IceInternal::Buffer&);
+
+ bool preWrite(IceInternal::Buffer&);
+ bool postWrite(IceInternal::Buffer&);
+
+ bool readBuffered(IceInternal::Buffer::Container::size_type);
+ void prepareWriteHeader(Ice::Byte, IceInternal::Buffer::Container::size_type);
+
+ friend class ConnectorI;
+ friend class AcceptorI;
+
+ const InstancePtr _instance;
+ const IceInternal::TransceiverPtr _delegate;
+ const std::string _host;
+ const int _port;
+ const std::string _resource;
+ const bool _incoming;
+
+ enum State
+ {
+ StateInitializeDelegate,
+ StateConnected,
+ StateUpgradeRequestPending,
+ StateUpgradeResponsePending,
+ StateOpened,
+ StatePingPending,
+ StatePongPending,
+ StateClosingRequestPending,
+ StateClosingResponsePending,
+ StateClosed
+ };
+
+ State _state;
+ State _nextState;
+
+ HttpParserPtr _parser;
+ std::string _key;
+
+ enum ReadState
+ {
+ ReadStateOpcode,
+ ReadStateHeader,
+ ReadStateControlFrame,
+ ReadStatePayload,
+ };
+
+ ReadState _readState;
+ IceInternal::Buffer _readBuffer;
+ IceInternal::Buffer::Container::iterator _readI;
+ const IceInternal::Buffer::Container::size_type _readBufferSize;
+
+ bool _readLastFrame;
+ int _readOpCode;
+ size_t _readHeaderLength;
+ size_t _readPayloadLength;
+ IceInternal::Buffer::Container::iterator _readStart;
+ unsigned char _readMask[4];
+
+ enum WriteState
+ {
+ WriteStateHeader,
+ WriteStatePayload,
+ WriteStateControlFrame,
+ };
+
+ WriteState _writeState;
+ IceInternal::Buffer _writeBuffer;
+ const IceInternal::Buffer::Container::size_type _writeBufferSize;
+ unsigned char _writeMask[4];
+ size_t _writePayloadLength;
+
+ bool _closingInitiator;
+ int _closingReason;
+
+ bool _readPending;
+ bool _writePending;
+
+ std::vector<Ice::Byte> _pingPayload;
+};
+typedef IceUtil::Handle<TransceiverI> TransceiverIPtr;
+
+}
+
+#endif
diff --git a/cpp/src/IceWS/Util.cpp b/cpp/src/IceWS/Util.cpp
new file mode 100644
index 00000000000..417acc68cb2
--- /dev/null
+++ b/cpp/src/IceWS/Util.cpp
@@ -0,0 +1,690 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <IceUtil/Config.h>
+#include <IceWS/Util.h>
+#include <Ice/LocalException.h>
+#include <IceUtil/StringUtil.h>
+
+#include <openssl/err.h>
+#include <openssl/sha.h>
+
+#include <IceUtil/DisableWarnings.h>
+
+using namespace std;
+using namespace Ice;
+using namespace IceWS;
+
+vector<unsigned char>
+IceWS::calcSHA1(const vector<unsigned char>& data)
+{
+ vector<unsigned char> hash(SHA_DIGEST_LENGTH);
+ ::SHA1(&data[0], static_cast<unsigned long>(data.size()), &hash[0]);
+ return hash;
+}
+
+WebSocketException::WebSocketException(const string& r) :
+ reason(r)
+{
+}
+
+IceWS::HttpParser::HttpParser() :
+ _type(TypeUnknown),
+ _versionMajor(0),
+ _versionMinor(0),
+ _status(0),
+ _state(StateInit)
+{
+}
+
+const Ice::Byte*
+IceWS::HttpParser::isCompleteMessage(const Ice::Byte* begin, const Ice::Byte* end) const
+{
+ const Ice::Byte* p = begin;
+
+ //
+ // Skip any leading CR-LF characters.
+ //
+ while(p < end)
+ {
+ char ch = static_cast<char>(*p);
+ if(ch != '\r' && ch != '\n')
+ {
+ break;
+ }
+ ++p;
+ }
+
+ //
+ // Look for adjacent CR-LF/CR-LF or LF/LF.
+ //
+ bool seenFirst = false;
+ while(p < end)
+ {
+ char ch = static_cast<char>(*p++);
+ if(ch == '\n')
+ {
+ if(seenFirst)
+ {
+ return p;
+ }
+ else
+ {
+ seenFirst = true;
+ }
+ }
+ else if(ch != '\r')
+ {
+ seenFirst = false;
+ }
+ }
+
+ return 0;
+}
+
+bool
+IceWS::HttpParser::parse(const Ice::Byte* begin, const Ice::Byte* end)
+{
+ const Ice::Byte* p = begin;
+ const Ice::Byte* start = 0;
+ const string::value_type CR = '\r';
+ const string::value_type LF = '\n';
+
+ if(_state == StateComplete)
+ {
+ _state = StateInit;
+ }
+
+ while(p != end && _state != StateComplete)
+ {
+ char c = static_cast<char>(*p);
+
+ switch(_state)
+ {
+ case StateInit:
+ {
+ _method.clear();
+ _uri.clear();
+ _versionMajor = -1;
+ _versionMinor = -1;
+ _status = -1;
+ _reason.clear();
+ _headers.clear();
+ _state = StateType;
+ continue;
+ }
+ case StateType:
+ {
+ if(c == CR || c == LF)
+ {
+ break;
+ }
+ else if(c == 'H')
+ {
+ //
+ // Could be the start of "HTTP/1.1" or "HEAD".
+ //
+ _state = StateTypeCheck;
+ break;
+ }
+ else
+ {
+ _state = StateRequest;
+ continue;
+ }
+ }
+ case StateTypeCheck:
+ {
+ if(c == 'T') // Continuing "H_T_TP/1.1"
+ {
+ _state = StateResponse;
+ }
+ else if(c == 'E') // Expecting "HEAD"
+ {
+ _state = StateRequest;
+ _method.push_back('H');
+ _method.push_back('E');
+ }
+ else
+ {
+ throw WebSocketException("malformed request or response");
+ }
+ break;
+ }
+ case StateRequest:
+ {
+ _type = TypeRequest;
+ _state = StateRequestMethod;
+ continue;
+ }
+ case StateRequestMethod:
+ {
+ if(c == ' ' || c == CR || c == LF)
+ {
+ _state = StateRequestMethodSP;
+ continue;
+ }
+ _method.push_back(c);
+ break;
+ }
+ case StateRequestMethodSP:
+ {
+ if(c == ' ')
+ {
+ break;
+ }
+ else if(c == CR || c == LF)
+ {
+ throw WebSocketException("malformed request");
+ }
+ _state = StateRequestURI;
+ continue;
+ }
+ case StateRequestURI:
+ {
+ if(c == ' ' || c == CR || c == LF)
+ {
+ _state = StateRequestURISP;
+ continue;
+ }
+ _uri.push_back(c);
+ break;
+ }
+ case StateRequestURISP:
+ {
+ if(c == ' ')
+ {
+ break;
+ }
+ else if(c == CR || c == LF)
+ {
+ throw WebSocketException("malformed request");
+ }
+ _state = StateVersion;
+ continue;
+ }
+ case StateRequestLF:
+ {
+ if(c != LF)
+ {
+ throw WebSocketException("malformed request");
+ }
+ _state = StateHeaderFieldStart;
+ break;
+ }
+ case StateHeaderFieldStart:
+ {
+ //
+ // We've already seen a LF to reach this state.
+ //
+ // Another CR or LF indicates the end of the header fields.
+ //
+ if(c == CR)
+ {
+ _state = StateHeaderFieldEndLF;
+ break;
+ }
+ else if(c == LF)
+ {
+ _state = StateComplete;
+ break;
+ }
+ else if(c == ' ')
+ {
+ //
+ // Could be a continuation line.
+ //
+ _state = StateHeaderFieldContStart;
+ break;
+ }
+
+ _state = StateHeaderFieldNameStart;
+ continue;
+ }
+ case StateHeaderFieldContStart:
+ {
+ if(c == ' ')
+ {
+ break;
+ }
+
+ _state = StateHeaderFieldCont;
+ start = p;
+ continue;
+ }
+ case StateHeaderFieldCont:
+ {
+ if(c == CR || c == LF)
+ {
+ if(p > start)
+ {
+ if(_headerName.empty())
+ {
+ throw WebSocketException("malformed header");
+ }
+ HeaderMap::iterator q = _headers.find(_headerName);
+ assert(q != _headers.end());
+ string newValue = q->second + " " + string(start, p);
+ _headers[_headerName] = newValue;
+ _state = c == CR ? StateHeaderFieldLF : StateHeaderFieldStart;
+ }
+ else
+ {
+ //
+ // Could mark the end of the header fields.
+ //
+ _state = c == CR ? StateHeaderFieldEndLF : StateComplete;
+ }
+ }
+
+ break;
+ }
+ case StateHeaderFieldNameStart:
+ {
+ assert(c != ' ');
+ start = p;
+ _headerName.clear();
+ _state = StateHeaderFieldName;
+ continue;
+ }
+ case StateHeaderFieldName:
+ {
+ if(c == ' ' || c == ':')
+ {
+ _state = StateHeaderFieldNameEnd;
+ continue;
+ }
+ else if(c == CR || c == LF)
+ {
+ throw WebSocketException("malformed header");
+ }
+ break;
+ }
+ case StateHeaderFieldNameEnd:
+ {
+ if(_headerName.empty())
+ {
+ _headerName = IceUtilInternal::toLower(string(start, p));
+ HeaderMap::iterator q = _headers.find(_headerName);
+ //
+ // Add a placeholder entry if necessary.
+ //
+ if(q == _headers.end())
+ {
+ _headers[_headerName] = "";
+ }
+ }
+
+ if(c == ' ')
+ {
+ break;
+ }
+ else if(c != ':' || p == start)
+ {
+ throw WebSocketException("malformed header");
+ }
+
+ _state = StateHeaderFieldValueStart;
+ break;
+ }
+ case StateHeaderFieldValueStart:
+ {
+ if(c == ' ')
+ {
+ break;
+ }
+
+ //
+ // Check for "Name:\r\n"
+ //
+ if(c == CR)
+ {
+ _state = StateHeaderFieldLF;
+ break;
+ }
+ else if(c == LF)
+ {
+ _state = StateHeaderFieldStart;
+ break;
+ }
+
+ start = p;
+ _state = StateHeaderFieldValue;
+ continue;
+ }
+ case StateHeaderFieldValue:
+ {
+ if(c == CR || c == LF)
+ {
+ _state = StateHeaderFieldValueEnd;
+ continue;
+ }
+ break;
+ }
+ case StateHeaderFieldValueEnd:
+ {
+ assert(c == CR || c == LF);
+ if(p > start)
+ {
+ HeaderMap::iterator q = _headers.find(_headerName);
+ if(q == _headers.end() || q->second.empty())
+ {
+ _headers[_headerName] = string(start, p);
+ }
+ else
+ {
+ _headers[_headerName] = q->second + ", " + string(start, p);
+ }
+ }
+
+ if(c == CR)
+ {
+ _state = StateHeaderFieldLF;
+ }
+ else
+ {
+ _state = StateHeaderFieldStart;
+ }
+ break;
+ }
+ case StateHeaderFieldLF:
+ {
+ if(c != LF)
+ {
+ throw WebSocketException("malformed header");
+ }
+ _state = StateHeaderFieldStart;
+ break;
+ }
+ case StateHeaderFieldEndLF:
+ {
+ if(c != LF)
+ {
+ throw WebSocketException("malformed header");
+ }
+ _state = StateComplete;
+ break;
+ }
+ case StateVersion:
+ {
+ if(c != 'H')
+ {
+ throw WebSocketException("malformed version");
+ }
+ _state = StateVersionH;
+ break;
+ }
+ case StateVersionH:
+ {
+ if(c != 'T')
+ {
+ throw WebSocketException("malformed version");
+ }
+ _state = StateVersionHT;
+ break;
+ }
+ case StateVersionHT:
+ {
+ if(c != 'T')
+ {
+ throw WebSocketException("malformed version");
+ }
+ _state = StateVersionHTT;
+ break;
+ }
+ case StateVersionHTT:
+ {
+ if(c != 'P')
+ {
+ throw WebSocketException("malformed version");
+ }
+ _state = StateVersionHTTP;
+ break;
+ }
+ case StateVersionHTTP:
+ {
+ if(c != '/')
+ {
+ throw WebSocketException("malformed version");
+ }
+ _state = StateVersionMajor;
+ break;
+ }
+ case StateVersionMajor:
+ {
+ if(c == '.')
+ {
+ if(_versionMajor == -1)
+ {
+ throw WebSocketException("malformed version");
+ }
+ _state = StateVersionMinor;
+ break;
+ }
+ else if(c < '0' || c > '9')
+ {
+ throw WebSocketException("malformed version");
+ }
+ if(_versionMajor == -1)
+ {
+ _versionMajor = 0;
+ }
+ _versionMajor *= 10;
+ _versionMajor += (c - '0');
+ break;
+ }
+ case StateVersionMinor:
+ {
+ if(c == CR)
+ {
+ if(_versionMinor == -1 || _type != TypeRequest)
+ {
+ throw WebSocketException("malformed version");
+ }
+ _state = StateRequestLF;
+ break;
+ }
+ else if(c == LF)
+ {
+ if(_versionMinor == -1 || _type != TypeRequest)
+ {
+ throw WebSocketException("malformed version");
+ }
+ _state = StateHeaderFieldStart;
+ break;
+ }
+ else if(c == ' ')
+ {
+ if(_versionMinor == -1 || _type != TypeResponse)
+ {
+ throw WebSocketException("malformed version");
+ }
+ _state = StateResponseVersionSP;
+ break;
+ }
+ else if(c < '0' || c > '9')
+ {
+ throw WebSocketException("malformed version");
+ }
+ if(_versionMinor == -1)
+ {
+ _versionMinor = 0;
+ }
+ _versionMinor *= 10;
+ _versionMinor += (c - '0');
+ break;
+ }
+ case StateResponse:
+ {
+ _type = TypeResponse;
+ _state = StateVersionHT;
+ continue;
+ }
+ case StateResponseVersionSP:
+ {
+ if(c == ' ')
+ {
+ break;
+ }
+
+ _state = StateResponseStatus;
+ continue;
+ }
+ case StateResponseStatus:
+ {
+ // TODO: Is reason string optional?
+ if(c == CR)
+ {
+ if(_status == -1)
+ {
+ throw WebSocketException("malformed response status");
+ }
+ _state = StateResponseLF;
+ break;
+ }
+ else if(c == LF)
+ {
+ if(_status == -1)
+ {
+ throw WebSocketException("malformed response status");
+ }
+ _state = StateHeaderFieldStart;
+ break;
+ }
+ else if(c == ' ')
+ {
+ if(_status == -1)
+ {
+ throw WebSocketException("malformed response status");
+ }
+ _state = StateResponseReasonStart;
+ break;
+ }
+ else if(c < '0' || c > '9')
+ {
+ throw WebSocketException("malformed response status");
+ }
+ if(_status == -1)
+ {
+ _status = 0;
+ }
+ _status *= 10;
+ _status += (c - '0');
+ break;
+ }
+ case StateResponseReasonStart:
+ {
+ //
+ // Skip leading spaces.
+ //
+ if(c == ' ')
+ {
+ break;
+ }
+
+ _state = StateResponseReason;
+ start = p;
+ continue;
+ }
+ case StateResponseReason:
+ {
+ if(c == CR || c == LF)
+ {
+ if(p > start)
+ {
+ _reason = string(start, p);
+ }
+ _state = c == CR ? StateResponseLF : StateHeaderFieldStart;
+ }
+
+ break;
+ }
+ case StateResponseLF:
+ {
+ if(c != LF)
+ {
+ throw WebSocketException("malformed status line");
+ }
+ _state = StateHeaderFieldStart;
+ break;
+ }
+ case StateComplete:
+ {
+ assert(false); // Shouldn't reach
+ }
+ }
+
+ ++p;
+ }
+
+ return _state == StateComplete;
+}
+
+IceWS::HttpParser::Type
+IceWS::HttpParser::type() const
+{
+ return _type;
+}
+
+string
+IceWS::HttpParser::method() const
+{
+ assert(_type == TypeRequest);
+ return _method;
+}
+
+string
+IceWS::HttpParser::uri() const
+{
+ assert(_type == TypeRequest);
+ return _uri;
+}
+
+int
+IceWS::HttpParser::versionMajor() const
+{
+ return _versionMajor;
+}
+
+int
+IceWS::HttpParser::versionMinor() const
+{
+ return _versionMinor;
+}
+
+int
+IceWS::HttpParser::status() const
+{
+ return _status;
+}
+
+string
+IceWS::HttpParser::reason() const
+{
+ return _reason;
+}
+
+bool
+IceWS::HttpParser::getHeader(const string& name, string& value, bool toLower) const
+{
+ HeaderMap::const_iterator q = _headers.find(IceUtilInternal::toLower(name));
+ if(q != _headers.end())
+ {
+ value = toLower ? IceUtilInternal::toLower(IceUtilInternal::trim(q->second)) : IceUtilInternal::trim(q->second);
+ return true;
+ }
+
+ return false;
+}
+
+const IceWS::HttpParser::HeaderMap&
+IceWS::HttpParser::headers() const
+{
+ return _headers;
+}
diff --git a/cpp/src/IceWS/Util.h b/cpp/src/IceWS/Util.h
new file mode 100644
index 00000000000..23faf2bf776
--- /dev/null
+++ b/cpp/src/IceWS/Util.h
@@ -0,0 +1,124 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#ifndef ICE_WS_UTIL_H
+#define ICE_WS_UTIL_H
+
+#include <IceUtil/Shared.h>
+#include <IceUtil/Handle.h>
+#include <Ice/Config.h>
+
+namespace IceWS
+{
+
+std::vector<unsigned char> calcSHA1(const std::vector<unsigned char>&);
+
+typedef std::map<std::string, std::string> HeaderFields;
+
+class WebSocketException
+{
+public:
+ WebSocketException(const std::string&);
+
+ std::string reason;
+};
+
+class HttpParser : public IceUtil::Shared
+{
+public:
+
+ HttpParser();
+
+ enum Type
+ {
+ TypeUnknown,
+ TypeRequest,
+ TypeResponse
+ };
+
+ const Ice::Byte* isCompleteMessage(const Ice::Byte*, const Ice::Byte*) const;
+
+ bool parse(const Ice::Byte*, const Ice::Byte*);
+
+ Type type() const;
+
+ std::string method() const;
+ std::string uri() const;
+ int versionMajor() const;
+ int versionMinor() const;
+
+ int status() const;
+ std::string reason() const;
+
+ bool getHeader(const std::string&, std::string&, bool) const;
+
+ typedef std::map<std::string, std::string> HeaderMap;
+
+ const HeaderMap& headers() const;
+
+private:
+
+ Type _type;
+
+ std::string _method;
+ std::string _uri;
+
+ HeaderMap _headers;
+ std::string _headerName;
+
+ int _versionMajor;
+ int _versionMinor;
+
+ int _status;
+ std::string _reason;
+
+ enum State
+ {
+ StateInit,
+ StateType,
+ StateTypeCheck,
+ StateRequest,
+ StateRequestMethod,
+ StateRequestMethodSP,
+ StateRequestURI,
+ StateRequestURISP,
+ StateRequestLF,
+ StateHeaderFieldStart,
+ StateHeaderFieldContStart,
+ StateHeaderFieldCont,
+ StateHeaderFieldNameStart,
+ StateHeaderFieldName,
+ StateHeaderFieldNameEnd,
+ StateHeaderFieldValueStart,
+ StateHeaderFieldValue,
+ StateHeaderFieldValueEnd,
+ StateHeaderFieldLF,
+ StateHeaderFieldEndLF,
+ StateVersion,
+ StateVersionH,
+ StateVersionHT,
+ StateVersionHTT,
+ StateVersionHTTP,
+ StateVersionMajor,
+ StateVersionMinor,
+ StateResponse,
+ StateResponseVersionSP,
+ StateResponseStatus,
+ StateResponseReasonStart,
+ StateResponseReason,
+ StateResponseLF,
+ StateComplete
+ };
+ State _state;
+};
+typedef IceUtil::Handle<HttpParser> HttpParserPtr;
+
+}
+
+#endif