public void Handles_ServerGetPeerAddress(string username, IPAddress ip, int port) { GetPeerAddressResponse result = null; var waiter = new Mock <IWaiter>(); waiter.Setup(m => m.Complete(It.IsAny <WaitKey>(), It.IsAny <GetPeerAddressResponse>())) .Callback <WaitKey, GetPeerAddressResponse>((key, response) => result = response); var ipBytes = ip.GetAddressBytes(); Array.Reverse(ipBytes); var message = new MessageBuilder() .Code(MessageCode.ServerGetPeerAddress) .WriteString(username) .WriteBytes(ipBytes) .WriteInteger(port) .Build(); using (var s = new SoulseekClient("127.0.0.1", 1, waiter: waiter.Object)) { s.InvokeMethod("ServerConnection_MessageRead", null, message); Assert.Equal(username, result.Username); Assert.Equal(ip, result.IPAddress); Assert.Equal(port, result.Port); } }
public void Handles_ServerGetPeerAddress(string username, IPAddress ip, int port) { GetPeerAddressResponse result = null; var(handler, mocks) = GetFixture(); mocks.Waiter.Setup(m => m.Complete(It.IsAny <WaitKey>(), It.IsAny <GetPeerAddressResponse>())) .Callback <WaitKey, GetPeerAddressResponse>((key, response) => result = response); var ipBytes = ip.GetAddressBytes(); Array.Reverse(ipBytes); var message = new MessageBuilder() .WriteCode(MessageCode.Server.GetPeerAddress) .WriteString(username) .WriteBytes(ipBytes) .WriteInteger(port) .Build(); handler.HandleMessage(null, message); Assert.Equal(username, result.Username); Assert.Equal(ip, result.IPAddress); Assert.Equal(port, result.Port); }
public void Parse_Throws_MessageException_On_Code_Mismatch() { var msg = new MessageBuilder() .Code(MessageCode.PeerBrowseRequest) .Build(); var ex = Record.Exception(() => GetPeerAddressResponse.Parse(msg)); Assert.NotNull(ex); Assert.IsType <MessageException>(ex); }
public void Parse_Throws_MessageReadException_On_Missing_Data() { var msg = new MessageBuilder() .Code(MessageCode.ServerGetPeerAddress) .WriteString("foo") .Build(); var ex = Record.Exception(() => GetPeerAddressResponse.Parse(msg)); Assert.NotNull(ex); Assert.IsType <MessageReadException>(ex); }
public void Instantiates_With_The_Given_Data() { var un = RandomGuid; var ip = new IPAddress(Random.Next(1024)); var port = Random.Next(); GetPeerAddressResponse response = null; var ex = Record.Exception(() => response = new GetPeerAddressResponse(un, ip, port)); Assert.Null(ex); Assert.Equal(un, response.Username); Assert.Equal(ip, response.IPAddress); Assert.Equal(port, response.Port); }
public void Parse_Returns_Expected_Data() { var un = RandomGuid; var ip = new IPAddress(Random.Next(1024)); var ipBytes = ip.GetAddressBytes(); Array.Reverse(ipBytes); var port = Random.Next(); var msg = new MessageBuilder() .Code(MessageCode.ServerGetPeerAddress) .WriteString(un) .WriteBytes(ipBytes) .WriteInteger(port) .Build(); var response = GetPeerAddressResponse.Parse(msg); Assert.Equal(un, response.Username); Assert.Equal(ip, response.IPAddress); Assert.Equal(port, response.Port); }
/// <summary> /// Handles incoming messages. /// </summary> /// <param name="sender">The <see cref="IMessageConnection"/> instance from which the message originated.</param> /// <param name="message">The message.</param> public async void HandleMessage(object sender, byte[] message) { var code = new MessageReader <MessageCode.Server>(message).ReadCode(); Diagnostic.Debug($"Server message received: {code}"); try { switch (code) { case MessageCode.Server.ParentMinSpeed: case MessageCode.Server.ParentSpeedRatio: case MessageCode.Server.WishlistInterval: SoulseekClient.Waiter.Complete(new WaitKey(code), IntegerResponse.FromByteArray <MessageCode.Server>(message)); break; case MessageCode.Server.Login: SoulseekClient.Waiter.Complete(new WaitKey(code), LoginResponse.FromByteArray(message)); break; case MessageCode.Server.RoomList: SoulseekClient.Waiter.Complete(new WaitKey(code), RoomList.FromByteArray(message)); break; case MessageCode.Server.PrivilegedUsers: SoulseekClient.Waiter.Complete(new WaitKey(code), PrivilegedUserList.FromByteArray(message)); break; case MessageCode.Server.NetInfo: var netInfo = NetInfo.FromByteArray(message); try { await SoulseekClient.DistributedConnectionManager.AddParentConnectionAsync(netInfo.Parents).ConfigureAwait(false); } catch (Exception ex) { Diagnostic.Debug($"Error handling NetInfo message: {ex.Message}"); } break; case MessageCode.Server.ConnectToPeer: ConnectToPeerResponse connectToPeerResponse = default; try { connectToPeerResponse = ConnectToPeerResponse.FromByteArray(message); if (connectToPeerResponse.Type == Constants.ConnectionType.Transfer) { // ensure that we are expecting at least one file from this user before we connect. the response // doesn't contain any other identifying information about the file. if (!SoulseekClient.Downloads.IsEmpty && SoulseekClient.Downloads.Values.Any(d => d.Username == connectToPeerResponse.Username)) { var(connection, remoteToken) = await SoulseekClient.PeerConnectionManager.GetTransferConnectionAsync(connectToPeerResponse).ConfigureAwait(false); var download = SoulseekClient.Downloads.Values.FirstOrDefault(v => v.RemoteToken == remoteToken && v.Username == connectToPeerResponse.Username); if (download != default(Transfer)) { SoulseekClient.Waiter.Complete(new WaitKey(Constants.WaitKey.IndirectTransfer, download.Username, download.Filename, download.RemoteToken), connection); } } else { throw new SoulseekClientException($"Unexpected transfer request from {connectToPeerResponse.Username} ({connectToPeerResponse.IPAddress}:{connectToPeerResponse.Port}); Ignored"); } } else if (connectToPeerResponse.Type == Constants.ConnectionType.Peer) { await SoulseekClient.PeerConnectionManager.GetOrAddMessageConnectionAsync(connectToPeerResponse).ConfigureAwait(false); } else if (connectToPeerResponse.Type == Constants.ConnectionType.Distributed) { await SoulseekClient.DistributedConnectionManager.AddChildConnectionAsync(connectToPeerResponse).ConfigureAwait(false); } else { throw new MessageException($"Unknown Connect To Peer connection type '{connectToPeerResponse.Type}'"); } } catch (Exception ex) { Diagnostic.Debug($"Error handling ConnectToPeer response from {connectToPeerResponse?.Username} ({connectToPeerResponse?.IPAddress}:{connectToPeerResponse.Port}): {ex.Message}"); } break; case MessageCode.Server.AddUser: var addUserResponse = AddUserResponse.FromByteArray(message); SoulseekClient.Waiter.Complete(new WaitKey(code, addUserResponse.Username), addUserResponse); break; case MessageCode.Server.GetStatus: var statsResponse = GetStatusResponse.FromByteArray(message); SoulseekClient.Waiter.Complete(new WaitKey(code, statsResponse.Username), statsResponse); UserStatusChanged?.Invoke(this, new UserStatusChangedEventArgs(statsResponse)); break; case MessageCode.Server.PrivateMessage: var pm = PrivateMessage.FromByteArray(message); PrivateMessageReceived?.Invoke(this, pm); if (SoulseekClient.Options.AutoAcknowledgePrivateMessages) { await SoulseekClient.AcknowledgePrivateMessageAsync(pm.Id, CancellationToken.None).ConfigureAwait(false); } break; case MessageCode.Server.GetPeerAddress: var peerAddressResponse = GetPeerAddressResponse.FromByteArray(message); SoulseekClient.Waiter.Complete(new WaitKey(code, peerAddressResponse.Username), peerAddressResponse); break; default: Diagnostic.Debug($"Unhandled server message: {code}; {message.Length} bytes"); break; } } catch (Exception ex) { Diagnostic.Warning($"Error handling server message: {code}; {ex.Message}", ex); } }