Skip to content

Commit 4c88840

Browse files
committed
Refactor
1 parent 4564cbf commit 4c88840

6 files changed

Lines changed: 99 additions & 112 deletions

File tree

src/Docker.DotNet.BasicAuth/BasicAuthCredentials.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,20 +32,20 @@ private BasicAuthCredentials(MaybeSecureString username, MaybeSecureString passw
3232
_password = password;
3333
}
3434

35-
public override bool IsTlsCredentials()
35+
public override void Dispose()
3636
{
37-
return _isTls;
37+
_username.Dispose();
38+
_password.Dispose();
3839
}
3940

40-
public override bool IsSshCredentials()
41+
public override bool SupportsScheme(string scheme)
4142
{
42-
return false;
43+
return !(_isTls && scheme == "npipe");
4344
}
4445

45-
public override void Dispose()
46+
public override bool IsTlsCredentials()
4647
{
47-
_username.Dispose();
48-
_password.Dispose();
48+
return _isTls;
4949
}
5050
}
5151
}

src/Docker.DotNet.X509/CertificateCredentials.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,14 @@ public override HttpMessageHandler GetHandler(HttpMessageHandler innerHandler)
3535
return handler;
3636
}
3737

38-
public override bool IsTlsCredentials()
38+
public override bool SupportsScheme(string scheme)
3939
{
40-
return true;
40+
return scheme != "npipe";
4141
}
4242

43-
public override bool IsSshCredentials()
43+
public override bool IsTlsCredentials()
4444
{
45-
return false;
45+
return true;
4646
}
4747

4848
public override void Dispose()

src/Docker.DotNet/AnonymousCredentials.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ public override bool IsTlsCredentials()
99
return false;
1010
}
1111

12-
public override bool IsSshCredentials()
12+
public override bool SupportsScheme(string scheme)
1313
{
14-
return false;
14+
return true;
1515
}
1616

1717
public override void Dispose()

src/Docker.DotNet/Credentials.cs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,16 @@
11
using System;
22
using System.Net.Http;
3-
using Microsoft.Net.Http.Client;
43

54
namespace Docker.DotNet
65
{
76
public abstract class Credentials : IDisposable
87
{
9-
public abstract bool IsTlsCredentials();
8+
public abstract bool SupportsScheme(string scheme);
109

11-
public abstract bool IsSshCredentials();
10+
public abstract bool IsTlsCredentials();
1211

1312
public abstract HttpMessageHandler GetHandler(HttpMessageHandler innerHandler);
1413

15-
public virtual ManagedHandler.StreamOpener GetSshStreamOpener(string username)
16-
{
17-
return null;
18-
}
19-
2014
public virtual void Dispose()
2115
{
2216
}

src/Docker.DotNet/DockerClient.cs

Lines changed: 2 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
using System;
22
using System.Collections.Generic;
33
using System.IO;
4-
using System.IO.Pipes;
54
using System.Linq;
65
using System.Net;
76
using System.Net.Http;
8-
using System.Net.Sockets;
97
using System.Threading;
108
using System.Threading.Tasks;
119
using Microsoft.Net.Http.Client;
@@ -45,94 +43,8 @@ internal DockerClient(DockerClientConfiguration configuration, Version requested
4543
Plugin = new PluginOperations(this);
4644
Exec = new ExecOperations(this);
4745

48-
ManagedHandler handler;
49-
var uri = Configuration.EndpointBaseUri;
50-
switch (uri.Scheme.ToLowerInvariant())
51-
{
52-
case "npipe":
53-
if (Configuration.Credentials.IsTlsCredentials())
54-
{
55-
throw new Exception("TLS not supported over npipe");
56-
}
57-
58-
var segments = uri.Segments;
59-
if (segments.Length != 3 || !segments[1].Equals("pipe/", StringComparison.OrdinalIgnoreCase))
60-
{
61-
throw new ArgumentException($"{Configuration.EndpointBaseUri} is not a valid npipe URI");
62-
}
63-
64-
var serverName = uri.Host;
65-
if (string.Equals(serverName, "localhost", StringComparison.OrdinalIgnoreCase))
66-
{
67-
// npipe schemes dont work with npipe://localhost/... and need npipe://./... so fix that for a client here.
68-
serverName = ".";
69-
}
70-
71-
var pipeName = uri.Segments[2];
72-
73-
uri = new UriBuilder("http", pipeName).Uri;
74-
handler = new ManagedHandler(async (host, port, cancellationToken) =>
75-
{
76-
var timeout = (int)Configuration.NamedPipeConnectTimeout.TotalMilliseconds;
77-
var stream = new NamedPipeClientStream(serverName, pipeName, PipeDirection.InOut, PipeOptions.Asynchronous);
78-
var dockerStream = new DockerPipeStream(stream);
79-
80-
await stream.ConnectAsync(timeout, cancellationToken)
81-
.ConfigureAwait(false);
82-
83-
return dockerStream;
84-
});
85-
break;
86-
87-
case "tcp":
88-
case "http":
89-
var builder = new UriBuilder(uri)
90-
{
91-
Scheme = configuration.Credentials.IsTlsCredentials() ? "https" : "http"
92-
};
93-
uri = builder.Uri;
94-
handler = new ManagedHandler();
95-
break;
96-
97-
case "https":
98-
handler = new ManagedHandler();
99-
break;
100-
101-
case "unix":
102-
var pipeString = uri.LocalPath;
103-
handler = new ManagedHandler(async (host, port, cancellationToken) =>
104-
{
105-
var sock = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified);
106-
107-
await sock.ConnectAsync(new Microsoft.Net.Http.Client.UnixDomainSocketEndPoint(pipeString))
108-
.ConfigureAwait(false);
109-
110-
return sock;
111-
});
112-
uri = new UriBuilder("http", uri.Segments.Last()).Uri;
113-
break;
114-
115-
case "ssh":
116-
if(!Configuration.Credentials.IsSshCredentials())
117-
{
118-
throw new ArgumentException("ssh:// protocol can only be used with SSHCredentials");
119-
};
120-
121-
var username = uri.UserInfo;
122-
if(username.Contains(":"))
123-
{
124-
throw new ArgumentException("ssh:// protocol only supports authentication with private keys");
125-
};
126-
127-
handler = new ManagedHandler(Configuration.Credentials.GetSshStreamOpener(username));
128-
uri = new UriBuilder("http", uri.Host, uri.IsDefaultPort ? 22 : uri.Port).Uri;
129-
break;
130-
131-
default:
132-
throw new Exception($"Unknown URL scheme {configuration.EndpointBaseUri.Scheme}");
133-
}
134-
135-
_endpointBaseUri = uri;
46+
var (url, handler) = Configuration.GetHandler();
47+
_endpointBaseUri = url;
13648

13749
_client = new HttpClient(Configuration.Credentials.GetHandler(handler), true);
13850
_client.Timeout = SInfiniteTimeout;

src/Docker.DotNet/DockerClientConfiguration.cs

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.IO.Pipes;
4+
using System.Linq;
5+
using System.Net.Sockets;
36
using System.Runtime.InteropServices;
47
using System.Threading;
8+
using Microsoft.Net.Http.Client;
59

610
namespace Docker.DotNet
711
{
@@ -63,10 +67,87 @@ public void Dispose()
6367
Credentials.Dispose();
6468
}
6569

70+
public (Uri url, ManagedHandler handler) GetHandler()
71+
{
72+
if (!Credentials.SupportsScheme(EndpointBaseUri.Scheme))
73+
{
74+
throw new Exception($"The provided credentials don't support the {EndpointBaseUri.Scheme} scheme.");
75+
}
76+
77+
var uri = EndpointBaseUri;
78+
ManagedHandler handler;
79+
80+
switch (EndpointBaseUri.Scheme.ToLowerInvariant())
81+
{
82+
case "npipe":
83+
var segments = uri.Segments;
84+
if (segments.Length != 3 || !segments[1].Equals("pipe/", StringComparison.OrdinalIgnoreCase))
85+
{
86+
throw new ArgumentException($"{uri} is not a valid npipe URI");
87+
}
88+
89+
var serverName = uri.Host;
90+
if (string.Equals(serverName, "localhost", StringComparison.OrdinalIgnoreCase))
91+
{
92+
// npipe schemes dont work with npipe://localhost/... and need npipe://./... so fix that for a client here.
93+
serverName = ".";
94+
}
95+
96+
var pipeName = uri.Segments[2];
97+
98+
uri = new UriBuilder("http", pipeName).Uri;
99+
handler = new ManagedHandler(async (host, port, cancellationToken) =>
100+
{
101+
var timeout = (int)NamedPipeConnectTimeout.TotalMilliseconds;
102+
var stream = new NamedPipeClientStream(serverName, pipeName, PipeDirection.InOut, PipeOptions.Asynchronous);
103+
var dockerStream = new DockerPipeStream(stream);
104+
105+
await stream.ConnectAsync(timeout, cancellationToken)
106+
.ConfigureAwait(false);
107+
108+
return dockerStream;
109+
});
110+
break;
111+
112+
case "tcp":
113+
case "http":
114+
var builder = new UriBuilder(uri)
115+
{
116+
Scheme = Credentials.IsTlsCredentials() ? "https" : "http"
117+
};
118+
uri = builder.Uri;
119+
handler = new ManagedHandler();
120+
break;
121+
122+
case "https":
123+
handler = new ManagedHandler();
124+
break;
125+
126+
case "unix":
127+
var pipeString = uri.LocalPath;
128+
handler = new ManagedHandler(async (host, port, cancellationToken) =>
129+
{
130+
var sock = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified);
131+
132+
await sock.ConnectAsync(new Microsoft.Net.Http.Client.UnixDomainSocketEndPoint(pipeString))
133+
.ConfigureAwait(false);
134+
135+
return sock;
136+
});
137+
uri = new UriBuilder("http", uri.Segments.Last()).Uri;
138+
break;
139+
140+
default:
141+
throw new Exception($"URL scheme {EndpointBaseUri.Scheme} is unsupported by this implementation.");
142+
}
143+
144+
return (uri, handler);
145+
}
146+
66147
private static Uri GetLocalDockerEndpoint()
67148
{
68149
var isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
69150
return isWindows ? new Uri("npipe://./pipe/docker_engine") : new Uri("unix:/var/run/docker.sock");
70151
}
71152
}
72-
}
153+
}

0 commit comments

Comments
 (0)