示例#1
0
		public async Task ConnectAsync (Uri uri, CancellationToken cancellationToken)
		{
			state = WebSocketState.Connecting;
			var httpUri = new UriBuilder (uri);
			if (uri.Scheme == "wss")
				httpUri.Scheme = "https";
			else
				httpUri.Scheme = "http";
			req = (HttpWebRequest)WebRequest.Create (httpUri.Uri);
			req.ReuseConnection = true;
			if (options.Cookies != null)
				req.CookieContainer = options.Cookies;

			if (options.CustomRequestHeaders.Count > 0) {
				foreach (var header in options.CustomRequestHeaders)
					req.Headers[header.Key] = header.Value;
			}

			var secKey = Convert.ToBase64String (Encoding.ASCII.GetBytes (Guid.NewGuid ().ToString ().Substring (0, 16)));
			string expectedAccept = StreamWebSocket.CreateAcceptKey (secKey);

			req.Headers["Upgrade"] = "WebSocket";
			req.Headers["Sec-WebSocket-Version"] = VersionTag;
			req.Headers["Sec-WebSocket-Key"] = secKey;
			req.Headers["Sec-WebSocket-Origin"] = uri.Host;
			if (options.SubProtocols.Count > 0)
				req.Headers["Sec-WebSocket-Protocol"] = string.Join (",", options.SubProtocols);

			if (options.Credentials != null)
				req.Credentials = options.Credentials;
			if (options.ClientCertificates != null)
				req.ClientCertificates = options.ClientCertificates;
			if (options.Proxy != null)
				req.Proxy = options.Proxy;
			req.UseDefaultCredentials = options.UseDefaultCredentials;
			req.Connection = "Upgrade";

			HttpWebResponse resp = null;
			try {
				resp = (HttpWebResponse)(await req.GetResponseAsync ().ConfigureAwait (false));
			} catch (Exception e) {
				throw new WebSocketException (WebSocketError.Success, e);
			}

			if (resp.StatusCode != HttpStatusCode.SwitchingProtocols)
				throw new WebSocketException ("The server returned status code '" + (int)resp.StatusCode + "' when status code '101' was expected");
			if (!string.Equals (resp.Headers["Upgrade"], "WebSocket", StringComparison.OrdinalIgnoreCase)
				|| !string.Equals (resp.Headers["Connection"], "Upgrade", StringComparison.OrdinalIgnoreCase)
				|| !string.Equals (resp.Headers["Sec-WebSocket-Accept"], expectedAccept))
				throw new WebSocketException ("HTTP header error during handshake");
			if (resp.Headers["Sec-WebSocket-Protocol"] != null) {
				if (!options.SubProtocols.Contains (resp.Headers["Sec-WebSocket-Protocol"]))
					throw new WebSocketException (WebSocketError.UnsupportedProtocol);
				subProtocol = resp.Headers["Sec-WebSocket-Protocol"];
			}
			state = WebSocketState.Open;
			connection = req.StoredConnection;
			internalWebSocket = new StreamWebSocket(connection.nstream, connection.nstream, connection.socket, subProtocol, true, new ArraySegment<byte>(new byte[0]));
		}
示例#2
0
		public async Task<HttpListenerWebSocketContext> AcceptWebSocketAsync (string subProtocol, int receiveBufferSize, TimeSpan keepAliveInterval)
		{
			if (subProtocol != null && subProtocol == "") {
				throw new ArgumentException ("subProtocol must not empty string");
			}
			if (receiveBufferSize < 16 || receiveBufferSize > 64 * 1024) {
				throw new ArgumentOutOfRangeException ("receiveBufferSize should be >=16 and <=64K bytes");
			}
			if (!request.IsWebSocketRequest) {
				throw new WebSocketException ("Request is not WebSocket Handshake");
			}
			string secKey = request.Headers ["Sec-WebSocket-Key"];
			if (secKey == null) {
				throw new WebSocketException ("Request doesn't contain Sec-WebSocket-Key header");
			}
			string acceptKey = StreamWebSocket.CreateAcceptKey (secKey);
			ArraySegment<byte> preloaded;
			var stream = new NetworkStream (cnc.Hijack (out preloaded));
			string header = "HTTP/1.1 101 Switching Protocols\r\n" +
				"Upgrade: websocket\r\n" +
				"Connection: Upgrade\r\n" +
				"Sec-WebSocket-Accept: " + acceptKey + "\r\n\r\n";
			var headerBytes = Encoding.ASCII.GetBytes (header);
			await stream.WriteAsync (headerBytes, 0, headerBytes.Length);
			var ws = new StreamWebSocket (stream, stream, null, subProtocol, false, preloaded);
			return new HttpListenerWebSocketContext (ws, request, user);
		}
		internal HttpListenerWebSocketContext(StreamWebSocket websocket, HttpListenerRequest request, IPrincipal user)
		{
			this.websocket = websocket;
			this.request = request;
			this.user = user;
		}