Skip to content

Commit 4706a7c

Browse files
committed
Change the customizing way of TCP connecting to a functional style
1 parent 6a61c70 commit 4706a7c

File tree

6 files changed

+65
-69
lines changed

6 files changed

+65
-69
lines changed

WhoisClient.NET/DefaultTcpConnector.cs

Lines changed: 0 additions & 37 deletions
This file was deleted.

WhoisClient.NET/IQueryOptions.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
using System.Text;
1+
using System;
2+
using System.Net.Sockets;
3+
using System.Text;
4+
using System.Threading.Tasks;
25

36
namespace Whois.NET
47
{
@@ -25,8 +28,9 @@ internal interface IQueryOptions
2528
bool RethrowExceptions { get; }
2629

2730
/// <summary>
28-
/// Gets or sets connection manager instance. Replace it if you need to create a connection in specific way, for example, over SOCKS proxy.
31+
/// Gets the function to create a TCP connection to a whois server asynchronously.<br/>
32+
/// This property allows us to override a way of creating a connection.
2933
/// </summary>
30-
ITcpConnector TcpConnector { get; }
34+
Func<TcpConnectionArgs, Task<TcpClient>> ConnectAsync { get; }
3135
}
3236
}

WhoisClient.NET/ITcpConnector.cs

Lines changed: 0 additions & 21 deletions
This file was deleted.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System.Threading;
2+
3+
namespace Whois.NET
4+
{
5+
/// <summary>
6+
/// Represents the arguments required for establishing a TCP connection.
7+
/// </summary>
8+
public class TcpConnectionArgs
9+
{
10+
/// <summary>
11+
/// Gets the host name or IP address of the server.
12+
/// </summary>
13+
public string Host { get; internal set; }
14+
15+
/// <summary>
16+
/// Gets the TCP port number to connect to on the server.
17+
/// </summary>
18+
public int Port { get; internal set; }
19+
20+
/// <summary>
21+
/// Gets the cancellation token to monitor for cancellation requests.
22+
/// </summary>
23+
public CancellationToken CancellationToken { get; internal set; }
24+
}
25+
}

WhoisClient.NET/WhoisClient.cs

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ private static string RawQuery(string query, EndPoint server, IQueryOptions opti
274274
try
275275
{
276276
// Async connect
277-
var tcpClientTask = options.TcpConnector.ConnectAsync(server.Host, server.Port);
277+
var tcpClientTask = ConnectAsync(server, options);
278278
tcpClientTask.ConfigureAwait(false);
279279

280280
// Wait at most timeout
@@ -318,7 +318,7 @@ private static string RawQuery(string query, EndPoint server, IQueryOptions opti
318318
{
319319
cbRead = s.Read(readBuff, 0, readBuff.Length);
320320
res.Append(options.Encoding.GetString(readBuff, 0, cbRead));
321-
if (cbRead > 0)
321+
if (cbRead > 0)
322322
Thread.Sleep(100);
323323
} while (cbRead > 0);
324324

@@ -393,8 +393,7 @@ private static async Task<string> RawQueryAsync(string query, EndPoint server, I
393393
// Async connect
394394
try
395395
{
396-
tcpClient = await options.TcpConnector.ConnectAsync(server.Host, server.Port, token)
397-
.ConfigureAwait(false);
396+
tcpClient = await ConnectAsync(server, options, token).ConfigureAwait(false);
398397
}
399398
catch (SocketException)
400399
{
@@ -426,7 +425,7 @@ private static async Task<string> RawQueryAsync(string query, EndPoint server, I
426425
{
427426
cbRead = await s.ReadAsync(readBuff, 0, buffSize, token).ConfigureAwait(false);
428427
res.Append(options.Encoding.GetString(readBuff, 0, cbRead));
429-
if (cbRead > 0)
428+
if (cbRead > 0)
430429
await Task.Delay(100, token).ConfigureAwait(false);
431430
} while (cbRead > 0);
432431

@@ -448,5 +447,27 @@ private static async Task<string> RawQueryAsync(string query, EndPoint server, I
448447
tcpClient.Close();
449448
}
450449
}
450+
451+
private static readonly Func<TcpConnectionArgs, Task<TcpClient>> DefaultConnectAsync = async args =>
452+
{
453+
if (string.IsNullOrWhiteSpace(args.Host)) throw new ArgumentException("Value cannot be null or whitespace.", nameof(args.Host));
454+
if (args.Port <= 0 || args.Port > ushort.MaxValue) throw new ArgumentOutOfRangeException(nameof(args.Port));
455+
456+
var tcpClient = new TcpClient();
457+
await tcpClient.ConnectAsync(args.Host, args.Port).ConfigureAwait(false);
458+
return tcpClient;
459+
};
460+
461+
private static async Task<TcpClient> ConnectAsync(EndPoint server, IQueryOptions options, CancellationToken cancellationToken = default)
462+
{
463+
var tcpConnectionArgs = new TcpConnectionArgs
464+
{
465+
Host = server.Host,
466+
Port = server.Port,
467+
CancellationToken = CancellationToken.None
468+
};
469+
var connectAsync = options.ConnectAsync != null ? options.ConnectAsync : DefaultConnectAsync;
470+
return await connectAsync.Invoke(tcpConnectionArgs).ConfigureAwait(false);
471+
}
451472
}
452473
}

WhoisClient.NET/WhoisQueryOptions.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
using System.Text;
1+
using System;
2+
using System.Net.Sockets;
3+
using System.Text;
4+
using System.Threading.Tasks;
25

36
namespace Whois.NET
47
{
@@ -38,8 +41,9 @@ public class WhoisQueryOptions : IQueryOptions
3841
public bool RethrowExceptions { get; set; } = false;
3942

4043
/// <summary>
41-
/// Gets or sets connection manager instance. Replace it if you need to create a connection in specific way, for example, over SOCKS proxy.
44+
/// Gets or sets the function to create a TCP connection to a whois server asynchronously.<br/>
45+
/// Replace it if you need to create a connection in a specific way, for example, over a SOCKS proxy.
4246
/// </summary>
43-
public ITcpConnector TcpConnector { get; set; } = DefaultTcpConnector.Instance;
47+
public Func<TcpConnectionArgs, Task<TcpClient>> ConnectAsync { get; set; }
4448
}
4549
}

0 commit comments

Comments
 (0)