예제 #1
0
            internal static string GetSupportedVersion()
            {
                if (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,
                                                                  InitialClientRequestHeaders,
                                                                  (uint)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();
                    }
                }
            }
예제 #2
0
            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 (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,
                                                              ServerFakeRequestHeaders,
                                                              (uint)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.");
            }
예제 #3
0
        public ServerWebSocket(Stream innerStream,
                               string subProtocol,
                               int receiveBufferSize,
                               TimeSpan keepAliveInterval,
                               ArraySegment <byte> internalBuffer)
            : base(innerStream, subProtocol, keepAliveInterval,
                   WebSocketBuffer.CreateServerBuffer(internalBuffer, receiveBufferSize))
        {
            _properties    = this.InternalBuffer.CreateProperties(false);
            _sessionHandle = this.CreateWebSocketHandle();

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

            StartKeepAliveTimer();
        }
예제 #4
0
        // This method is not thread safe. It must only be called after enforcing at most 1 outstanding send operation
        internal void PinSendBuffer(ArraySegment <byte> payload, out bool bufferHasBeenPinned)
        {
            bufferHasBeenPinned = false;
            WebSocketHelpers.ValidateBuffer(payload.Array, payload.Offset, payload.Count);
            int previousState = Interlocked.Exchange(ref _SendBufferState, SendBufferState.SendPayloadSpecified);

            if (previousState != SendBufferState.None)
            {
                Contract.Assert(false, "'m_SendBufferState' MUST BE 'None' at this point.");
                // Indicates a violation in the API contract that could indicate
                // memory corruption because the pinned sendbuffer is shared between managed and native code
                throw new AccessViolationException();
            }
            _PinnedSendBuffer             = payload;
            _PinnedSendBufferHandle       = GCHandle.Alloc(_PinnedSendBuffer.Array, GCHandleType.Pinned);
            bufferHasBeenPinned           = true;
            _PinnedSendBufferStartAddress =
                Marshal.UnsafeAddrOfPinnedArrayElement(_PinnedSendBuffer.Array, _PinnedSendBuffer.Offset).ToInt64();
            _PinnedSendBufferEndAddress = _PinnedSendBufferStartAddress + _PinnedSendBuffer.Count;
        }
예제 #5
0
            internal static void WebSocketCreateClientHandle(Property[] properties,
                                                             out SafeWebSocketHandle webSocketHandle)
            {
                uint propertyCount = properties == null ? 0 : (uint)properties.Length;

                if (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,
                                                              InitialClientRequestHeaders,
                                                              (uint)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.");
            }