public static WebSocket CreateClientWebSocket(Stream innerStream,
                                                      string subProtocol,
                                                      int receiveBufferSize,
                                                      int sendBufferSize,
                                                      TimeSpan keepAliveInterval,
                                                      bool useZeroMaskingKey,
                                                      ArraySegment <byte> internalBuffer)
        {
            if (!WebSocketProtocolComponent.IsSupported)
            {
                WebSocketHelpers.ThrowPlatformNotSupportedException_WSPC();
            }

            WebSocketHelpers.ValidateInnerStream(innerStream);
            WebSocketHelpers.ValidateOptions(subProtocol, receiveBufferSize, sendBufferSize, keepAliveInterval);
            WebSocketHelpers.ValidateArraySegment <byte>(internalBuffer, "internalBuffer");
            WebSocketBuffer.Validate(internalBuffer.Count, receiveBufferSize, sendBufferSize, false);

            return(new InternalClientWebSocket(innerStream,
                                               subProtocol,
                                               receiveBufferSize,
                                               sendBufferSize,
                                               keepAliveInterval,
                                               useZeroMaskingKey,
                                               internalBuffer));
        }
        internal static string GetSupportedVersion()
        {
            if (s_WebSocketDllHandle.IsInvalid)
            {
                WebSocketHelpers.ThrowPlatformNotSupportedException_WSPC();
            }

            SafeWebSocketHandle webSocketHandle = null;

            try
            {
                int errorCode = WebSocketCreateClientHandle_Raw(null, 0, out webSocketHandle);
                ThrowOnError(errorCode);

                if (webSocketHandle == null ||
                    webSocketHandle.IsInvalid)
                {
                    WebSocketHelpers.ThrowPlatformNotSupportedException_WSPC();
                }

                IntPtr additionalHeadersPtr;
                uint   additionalHeaderCount;

                errorCode = WebSocketBeginClientHandshake_Raw(webSocketHandle,
                                                              IntPtr.Zero,
                                                              0,
                                                              IntPtr.Zero,
                                                              0,
                                                              s_InitialClientRequestHeaders,
                                                              (uint)s_InitialClientRequestHeaders.Length,
                                                              out additionalHeadersPtr,
                                                              out additionalHeaderCount);
                ThrowOnError(errorCode);

                HttpHeader[] additionalHeaders = MarshalHttpHeaders(additionalHeadersPtr, (int)additionalHeaderCount);

                string version = null;
                foreach (HttpHeader header in additionalHeaders)
                {
                    if (string.Compare(header.Name,
                                       HttpKnownHeaderNames.SecWebSocketVersion,
                                       StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        version = header.Value;
                        break;
                    }
                }
                Contract.Assert(version != null, "'version' MUST NOT be NULL.");

                return(version);
            }
            finally
            {
                if (webSocketHandle != null)
                {
                    webSocketHandle.Dispose();
                }
            }
        }
        internal static void WebSocketCreateServerHandle(Property[] properties,
                                                         int propertyCount,
                                                         out SafeWebSocketHandle webSocketHandle)
        {
            Contract.Assert(propertyCount >= 0, "'propertyCount' MUST NOT be negative.");
            Contract.Assert((properties == null && propertyCount == 0) ||
                            (properties != null && propertyCount == properties.Length),
                            "'propertyCount' MUST MATCH 'properties.Length'.");

            if (s_WebSocketDllHandle.IsInvalid)
            {
                WebSocketHelpers.ThrowPlatformNotSupportedException_WSPC();
            }

            int errorCode = WebSocketCreateServerHandle_Raw(properties, (uint)propertyCount, out webSocketHandle);

            ThrowOnError(errorCode);

            if (webSocketHandle == null ||
                webSocketHandle.IsInvalid)
            {
                WebSocketHelpers.ThrowPlatformNotSupportedException_WSPC();
            }

            IntPtr responseHeadersPtr;
            uint   responseHeaderCount;

            // Currently the WSPC doesn't allow to initiate a data session
            // without also being involved in the http handshake
            // There is no information whatsoever, which is needed by the
            // WSPC for parsing WebSocket frames from the HTTP handshake
            // In the managed implementation the HTTP header handling
            // will be done using the managed HTTP stack and we will
            // just fake an HTTP handshake for the WSPC calling
            // WebSocketBeginServerHandshake and WebSocketEndServerHandshake
            // with statically defined dummy headers.
            errorCode = WebSocketBeginServerHandshake_Raw(webSocketHandle,
                                                          IntPtr.Zero,
                                                          IntPtr.Zero,
                                                          0,
                                                          s_ServerFakeRequestHeaders,
                                                          (uint)s_ServerFakeRequestHeaders.Length,
                                                          out responseHeadersPtr,
                                                          out responseHeaderCount);

            ThrowOnError(errorCode);

            HttpHeader[] responseHeaders = MarshalHttpHeaders(responseHeadersPtr, (int)responseHeaderCount);
            errorCode = WebSocketEndServerHandshake_Raw(webSocketHandle);

            ThrowOnError(errorCode);

            Contract.Assert(webSocketHandle != null, "'webSocketHandle' MUST NOT be NULL at this point.");
        }
예제 #4
0
        public InternalClientWebSocket(Stream innerStream, string subProtocol, int receiveBufferSize, int sendBufferSize,
                                       TimeSpan keepAliveInterval, bool useZeroMaskingKey, ArraySegment <byte> internalBuffer)
            : base(innerStream, subProtocol, keepAliveInterval,
                   WebSocketBuffer.CreateClientBuffer(internalBuffer, receiveBufferSize, sendBufferSize))
        {
            m_Properties    = this.InternalBuffer.CreateProperties(useZeroMaskingKey);
            m_SessionHandle = this.CreateWebSocketHandle();

            if (m_SessionHandle == null || m_SessionHandle.IsInvalid)
            {
                WebSocketHelpers.ThrowPlatformNotSupportedException_WSPC();
            }

            StartKeepAliveTimer();
        }
예제 #5
0
        public ClientWebSocket()
        {
            if (Logging.On)
            {
                Logging.Enter(Logging.WebSockets, this, ".ctor", null);
            }

            if (!WebSocketProtocolComponent.IsSupported)
            {
                WebSocketHelpers.ThrowPlatformNotSupportedException_WSPC();
            }

            state   = created;
            options = new ClientWebSocketOptions();
            cts     = new CancellationTokenSource();

            if (Logging.On)
            {
                Logging.Exit(Logging.WebSockets, this, ".ctor", null);
            }
        }
        internal static WebSocket CreateServerWebSocket(Stream innerStream,
                                                        string subProtocol,
                                                        int receiveBufferSize,
                                                        TimeSpan keepAliveInterval,
                                                        ArraySegment <byte> internalBuffer)
        {
            if (!WebSocketProtocolComponent.IsSupported)
            {
                WebSocketHelpers.ThrowPlatformNotSupportedException_WSPC();
            }

            WebSocketHelpers.ValidateInnerStream(innerStream);
            WebSocketHelpers.ValidateOptions(subProtocol, receiveBufferSize, WebSocketBuffer.MinSendBufferSize, keepAliveInterval);
            WebSocketHelpers.ValidateArraySegment <byte>(internalBuffer, "internalBuffer");
            WebSocketBuffer.Validate(internalBuffer.Count, receiveBufferSize, WebSocketBuffer.MinSendBufferSize, true);

            return(new ServerWebSocket(innerStream,
                                       subProtocol,
                                       receiveBufferSize,
                                       keepAliveInterval,
                                       internalBuffer));
        }
        internal static void WebSocketCreateClientHandle(Property[] properties,
                                                         out SafeWebSocketHandle webSocketHandle)
        {
            uint propertyCount = properties == null ? 0 : (uint)properties.Length;

            if (s_WebSocketDllHandle.IsInvalid)
            {
                WebSocketHelpers.ThrowPlatformNotSupportedException_WSPC();
            }

            int errorCode = WebSocketCreateClientHandle_Raw(properties, propertyCount, out webSocketHandle);

            ThrowOnError(errorCode);

            if (webSocketHandle == null ||
                webSocketHandle.IsInvalid)
            {
                WebSocketHelpers.ThrowPlatformNotSupportedException_WSPC();
            }

            IntPtr additionalHeadersPtr;
            uint   additionalHeaderCount;

            // Currently the WSPC doesn't allow to initiate a data session
            // without also being involved in the http handshake
            // There is no information whatsoever, which is needed by the
            // WSPC for parsing WebSocket frames from the HTTP handshake
            // In the managed implementation the HTTP header handling
            // will be done using the managed HTTP stack and we will
            // just fake an HTTP handshake for the WSPC  calling
            // WebSocketBeginClientHandshake and WebSocketEndClientHandshake
            // with statically defined dummy headers.
            errorCode = WebSocketBeginClientHandshake_Raw(webSocketHandle,
                                                          IntPtr.Zero,
                                                          0,
                                                          IntPtr.Zero,
                                                          0,
                                                          s_InitialClientRequestHeaders,
                                                          (uint)s_InitialClientRequestHeaders.Length,
                                                          out additionalHeadersPtr,
                                                          out additionalHeaderCount);

            ThrowOnError(errorCode);

            HttpHeader[] additionalHeaders = MarshalHttpHeaders(additionalHeadersPtr, (int)additionalHeaderCount);

            string key = null;

            foreach (HttpHeader header in additionalHeaders)
            {
                if (string.Compare(header.Name,
                                   HttpKnownHeaderNames.SecWebSocketKey,
                                   StringComparison.OrdinalIgnoreCase) == 0)
                {
                    key = header.Value;
                    break;
                }
            }
            Contract.Assert(key != null, "'key' MUST NOT be NULL.");

            string acceptValue = WebSocketHelpers.GetSecWebSocketAcceptString(key);

            HttpHeader[] responseHeaders = new HttpHeader[]
            {
                new HttpHeader()
                {
                    Name        = HttpKnownHeaderNames.Connection,
                    NameLength  = (uint)HttpKnownHeaderNames.Connection.Length,
                    Value       = HttpKnownHeaderNames.Upgrade,
                    ValueLength = (uint)HttpKnownHeaderNames.Upgrade.Length
                },
                new HttpHeader()
                {
                    Name        = HttpKnownHeaderNames.Upgrade,
                    NameLength  = (uint)HttpKnownHeaderNames.Upgrade.Length,
                    Value       = WebSocketHelpers.WebSocketUpgradeToken,
                    ValueLength = (uint)WebSocketHelpers.WebSocketUpgradeToken.Length
                },
                new HttpHeader()
                {
                    Name        = HttpKnownHeaderNames.SecWebSocketAccept,
                    NameLength  = (uint)HttpKnownHeaderNames.SecWebSocketAccept.Length,
                    Value       = acceptValue,
                    ValueLength = (uint)acceptValue.Length
                }
            };

            errorCode = WebSocketEndClientHandshake_Raw(webSocketHandle,
                                                        responseHeaders,
                                                        (uint)responseHeaders.Length,
                                                        IntPtr.Zero,
                                                        IntPtr.Zero,
                                                        IntPtr.Zero);

            ThrowOnError(errorCode);

            Contract.Assert(webSocketHandle != null, "'webSocketHandle' MUST NOT be NULL at this point.");
        }