private static void ForwardData(object args) { StreamsPair pair = args as StreamsPair; HeyLogger logger = pair.Logger; byte[] buffer = new byte[1024 * 1024]; try { while (pair.StreamA.CanRead) { int bytesRead = pair.StreamA.Read(buffer, 0, buffer.Length); if (bytesRead == 0) { logger.WriteLine(String.Format("No more bytes to read from {0}.", pair.Label)); break; } pair.StreamB.Write(buffer, 0, bytesRead); logger.WriteLine(String.Format("{0} bytes from {1}.", bytesRead, pair.Label)); } } catch (IOException ex) { WriteLine(ConsoleColor.Red, pair.Label); logger.WriteLine(ex.ToString()); } // TODO: Check this is right. // Tell the other side connections is being shutdown. pair.StreamB.Close(); }
private static void DoHttp(HeyLogger logger, Stream sslStream, Socket clientSocket) { HeyHttpServerThread connection = new HeyHttpServerThread( logger, clientSocket, null); connection.Accept(sslStream); }
private void IsAuthorizationValid(string path, string authorizationHeader, bool isValid) { HeyLogger logger = new HeyLogger(); HeyHttpRequest request = new HeyHttpRequest(logger); request.ParsePath(path); request.Authorization = authorizationHeader; Assert.AreEqual(isValid, HeyHttpAuthentication.IsAuthorizationValid(request)); }
public void AddAuthenticateHeaderIfNeeded_Basic_NoAuthorization() { HeyLogger logger = new HeyLogger(); HeyHttpRequest request = new HeyHttpRequest(logger); HeyHttpResponse response = new HeyHttpResponse(logger); request.ParsePath("/?basic=1"); HeyHttpAuthentication.AddAuthenticateHeaderIfNeeded(request, response); Assert.AreEqual("401 Unauthorized", response.Status); Assert.IsTrue(response.Headers.Contains("WWW-Authenticate: Basic realm=\"Secure Area\"")); }
private static void Reply407AndClose(HeyLogger logger, NetworkStream clientStream) { HeyHttpResponse response = new HeyHttpResponse(logger); response.Version = "HTTP/1.0"; response.Status = "407 Proxy Authentication Required"; response.Headers.Add("Proxy-agent: Netscape-Proxy/1.1"); response.Headers.Add("Proxy-Authenticate: Basic realm=\"WallyWorld\""); response.Headers.Add("Content-Length: 0"); response.Headers.Add("Connection: close"); response.CopyHeadersTo(clientStream); clientStream.Close(); }
public void AddAuthenticateHeaderIfNeeded_Basic_InvalidAuthorization() { HeyLogger logger = new HeyLogger(); HeyHttpRequest request = new HeyHttpRequest(logger); HeyHttpResponse response = new HeyHttpResponse(logger); request.ParsePath("/?basic=1&user=foo&password=bar"); request.Authorization = "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="; HeyHttpAuthentication.AddAuthenticateHeaderIfNeeded(request, response); Assert.AreEqual("401 Unauthorized", response.Status); Assert.IsTrue(response.Headers.Contains("WWW-Authenticate: Basic realm=\"Secure Area\"")); }
public void AddAuthenticateHeaderIfNeeded_Basic_ValidAuthorization() { HeyLogger logger = new HeyLogger(); HeyHttpRequest request = new HeyHttpRequest(logger); HeyHttpResponse response = new HeyHttpResponse(logger); request.ParsePath("/?basic=1&user=foo&password=bar"); request.Authorization = "Basic Zm9vOmJhcg=="; HeyHttpAuthentication.AddAuthenticateHeaderIfNeeded(request, response); Assert.IsTrue(String.IsNullOrEmpty(response.Status)); Assert.AreEqual(0, response.Headers.Count); }
public static void Start(HeyWebSocketServerSettings settings) { HeyWebSocketServer.OnMessage += (sender, data) => { Console.WriteLine(data.Length); //// Send a ping. //WebSocketServerPro.Ping(); //WebSocketServerPro.Send(new String('x', 0x10000)); // Non-fragmented message. HeyWebSocketServer.Send(FinType.Set, OpcodeType.Text, "Hey!"); // Send fragmented message. HeyWebSocketServer.Send(FinType.Clear, OpcodeType.Text, "Go"); Thread.Sleep(1000); HeyWebSocketServer.Send(FinType.Set, OpcodeType.Continuation, "Hawks!"); }; TcpListener tcpListener = new TcpListener(IPAddress.IPv6Any, settings.Port); tcpListener.Start(); Console.WriteLine("Listening on port {0} ...", settings.Port); while (true) { try { using (TcpClient tcpClient = tcpListener.AcceptTcpClient()) { Console.WriteLine("Connected: {0}", tcpClient.Client.RemoteEndPoint); Console.WriteLine(); using (networkStream = tcpClient.GetStream()) { logger = new HeyLogger(); AcceptCore(); } } } catch (Exception ex) { Console.WriteLine(ex.Message); } Console.WriteLine(); Console.WriteLine("Disconnected."); } }
public HeyHttpRequest(HeyLogger logger) { this.logger = logger; // Use the default port, unless any header specifies a different one. Port = 80; // Invariant culture is a fake culture based on English, great to write out, for example, // stuff into config files so it can be read an written regardless of the culture the user // has defined. headers = new Dictionary <string, string>(StringComparer.InvariantCultureIgnoreCase); // Initialize with an empty NameValueCollection, so we never have to check if QueryString is null. ParseQueryString(""); }
private static void ProcessDigestAuthorization(HeyHttpRequest request, HeyLogger logger) { string headerValue = request.Authorization.Substring("Digest ".Length); string[] pairs = headerValue.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); foreach (string pair in pairs) { string[] keyAndValue = pair.Split(new char[] { '=' }, 2); if (keyAndValue.Length == 2) { string key = keyAndValue[0].Trim(); string value = keyAndValue[1].Trim('"'); logger.WriteHeadersLine( String.Format("{0}: {1}", key, value)); } } logger.WriteHeadersLine("\r\n"); // TODO: If the password is not the expected one, clear Authorization header, // so a 401 Unauthorized response is sent. }
public HeyHttpResponse(HeyLogger logger) { this.logger = logger; Headers = new List <string>(); Version = "HTTP/1.1"; }
public static void Accept(HeyLogger logger, Stream stream) { HeyWebSocketServer.logger = logger; HeyWebSocketServer.networkStream = stream; AcceptCore(); }
private static void OnAccept(IAsyncResult asyncResult) { HeyLogger logger = new HeyLogger(); Socket socketListener = asyncResult.AsyncState as Socket; SslStream sslStream = null; string clientName = null; try { using (Socket clientSocket = socketListener.EndAccept(asyncResult)) { socketListener.BeginAccept(OnAccept, socketListener); clientName = clientSocket.RemoteEndPoint.ToString(); logger.WriteTransportLine(String.Format("Client connected from {0}\r\n", clientName)); NetworkStream networkStream = new NetworkStream(clientSocket); // Plain connection before upgrading to SSL? //message = ReadMessage(networkStream); //Console.WriteLine(message); RemoteCertificateValidationCallback callback = null; if (settings.ClientCertificateRequired) { callback = new RemoteCertificateValidationCallback(ValidateClientCertificate); } sslStream = new SslStream( networkStream, false, callback, null); sslStream.AuthenticateAsServer( serverCertificate, settings.ClientCertificateRequired, SslProtocols.Default, false); switch (settings.Protocol) { case ApplicationLayerProtocol.Http: DoHttp(logger, sslStream, clientSocket); break; case ApplicationLayerProtocol.Ws: DoWs(logger, sslStream, clientSocket); break; default: DoUndefined(sslStream); break; } } } catch (Exception ex) { logger.WriteErrorLine(ex.Message); } finally { logger.WriteTransportLine(String.Format("Disconnected from {0}\r\n", clientName)); if (sslStream != null) { SslClientCertificateInfo.Remove(sslStream.GetHashCode()); } } }
private static void DoWs(HeyLogger logger, Stream sslStream, Socket clientSocket) { HeyWebSocketServer.Accept(logger, sslStream); }
private static void OnAccept(IAsyncResult asyncResult) { HeyLogger logger = new HeyLogger(); Socket socketListener = asyncResult.AsyncState as Socket; Socket client = socketListener.EndAccept(asyncResult); socketListener.BeginAccept(OnAccept, asyncResult.AsyncState); try { HeyHttpRequest request = new HeyHttpRequest(logger); // Client got connected. logger.WriteLine(String.Format("Connected: {0}", client.RemoteEndPoint)); // Read HTTP headers. NetworkStream clientStream = new NetworkStream(client); MemoryStream tempStream = new MemoryStream(); request.ReadHeaders(clientStream, tempStream); // Authentication. if (settings.AuthenticationRequired && !IsAuthenticated(request)) { Reply407AndClose(logger, clientStream); return; } // Find server host name. logger.WriteLine(String.Format("Trying to connect to {0}", request.Host)); // Get IP address for the given server hostname. IPHostEntry hostEntry = Dns.GetHostEntry(request.Host); if (hostEntry.AddressList.Length == 0) { throw new Exception("Unknow server hostname."); } IPAddress address = hostEntry.AddressList[0]; // Connect to server. Socket server = new Socket(address.AddressFamily, SocketType.Stream, ProtocolType.Tcp); server.Connect(new IPEndPoint(address, request.Port)); logger.WriteLine(String.Format("Connected to {0}", request.Host)); // Send cached data to server. NetworkStream serverStream = new NetworkStream(server); // When using the CONNECT method, proxy must send a HTTP response to client. // See "Tunneling TCP based protocols through Web proxy servers" internet-draft. if (request.Method == "CONNECT") { HeyHttpResponse response = new HeyHttpResponse(logger); response.Status = "200 Connection established"; response.Headers.Add("Proxy-agent: Happy-Sockets-Proxy/1.0"); response.CopyHeadersTo(clientStream); } else { // Only forward headers when it is not a CONNECT request. tempStream.Seek(0, SeekOrigin.Begin); tempStream.CopyTo(serverStream); } // Forward data. ParameterizedThreadStart serverToClientStart = new ParameterizedThreadStart(ForwardData); Thread serverToClientThread = new Thread(serverToClientStart); serverToClientThread.Start( new StreamsPair { StreamA = serverStream, StreamB = clientStream, Label = "server to client", Logger = logger }); ParameterizedThreadStart clientToServerStart = new ParameterizedThreadStart(ForwardData); Thread clientToServerThread = new Thread(clientToServerStart); clientToServerThread.Start( new StreamsPair { StreamA = clientStream, StreamB = serverStream, Label = "client to server", Logger = logger }); //serverToClientThread.Join(); //clientToServerThread.Join(); // TODO: make sure streams do not go out of scope. // TODO: wait until threads end and ensure connections are close. } catch (SocketException ex) { WriteLine(ConsoleColor.Red, ex.Message); logger.WriteLine(ex.ToString()); // We couldn't connect to the server, terminate connection with the client. client.Close(); } catch (IOException ex) { WriteLine(ConsoleColor.Red, ex.Message); logger.WriteLine(ex.ToString()); // The client closed the connection, terminate the connection with the server. client.Close(); } catch (Exception ex) { WriteLine(ConsoleColor.Red, ex.Message); logger.WriteLine(ex.ToString()); } }
public HeyHttpServerThread(HeyLogger logger, Socket tcpClient, RemoveConnectionDelegate removeConnection) { this.clientSocket = tcpClient; this.removeConnection = removeConnection; this.logger = logger; }