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();
                    }
                }
            }
            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.");
            }
 private static extern int WebSocketCreateServerHandle_Raw(
     [In] Property[] properties,
     [In] uint propertyCount,
     [Out] out SafeWebSocketHandle webSocketHandle);
            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.");
            }