Ejemplo n.º 1
0
        private static (HttpMessageHandler handler, Uri uri) ResolveHandlerAndUri(string baseUrl)
        {
            ManagedHandler handler;
            var            uri = new Uri(baseUrl.Equals(".") ? DockerApiUri() : baseUrl);

            switch (uri.Scheme.ToLowerInvariant())
            {
            case "npipe":
                var segments = uri.Segments;

                if (segments.Length != 3 || !segments[1].Equals("pipe/", StringComparison.OrdinalIgnoreCase))
                {
                    throw new ArgumentException($"{baseUrl} is not a valid npipe URI");
                }

                var serverName = uri.Host;

                // npipe schemes dont work with npipe://localhost/... and need npipe://./... so fix that for a client here.
                serverName = string.Equals(serverName, "localhost", StringComparison.OrdinalIgnoreCase) ? "." : serverName;

                var pipeName = uri.Segments[2];

                uri     = new UriBuilder("http", pipeName).Uri;
                handler = new ManagedHandler(async(host, port, cancellationToken) =>
                {
                    var stream       = new NamedPipeClientStream(serverName, pipeName, PipeDirection.InOut, PipeOptions.Asynchronous);
                    var dockerStream = new DockerPipeStream(stream);

                    await stream.ConnectAsync(100, cancellationToken);

                    return(dockerStream);
                });

                break;

            case "unix":
                handler = new ManagedHandler(async(string host, int port, CancellationToken cancellationToken) =>
                {
                    var sock = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified);
                    await sock.ConnectAsync(new UnixDomainSocketEndPoint(uri.LocalPath), cancellationToken: cancellationToken);

                    return(sock);
                });

                uri = new UriBuilder("http", uri.Segments.Last()).Uri;

                break;

            default:
                throw new UnsupportedProtocolException(uri.Scheme);
            }

            return(handler, uri);
        }
Ejemplo n.º 2
0
        internal DockerAPIClient(APIConfig config, Version apiVersion = null)
        {
            Config = config;
            requestedApiVersion = apiVersion;
            JsonSerializer      = new JsonSerializer();

            Images = new ImagesEndpoint(this);

            ManagedHandler handler;
            var            uri = Config.Endpoint;

            switch (uri.Scheme.ToLowerInvariant())
            {
            case "npipe":
                if (Config.Credentials.IsTlsEnabled())
                {
                    throw new Exception("TLS not supported over npipe");
                }

                var segments = uri.Segments;
                if (segments.Length != 3 || !segments[1].Equals("pipe/", StringComparison.OrdinalIgnoreCase))
                {
                    throw new ArgumentException($"{Config.Endpoint} is not a valid npipe URI");
                }

                var serverName = uri.Host;
                var pipeName   = uri.Segments[2];

                uri     = new UriBuilder("http", pipeName).Uri;
                handler = new ManagedHandler(async(host, port, cancellationToken) =>
                {
                    // NamedPipeClientStream handles file not found by polling until the server arrives. Use a short
                    // timeout so that the user doesn't get stuck waiting for a dockerd instance that is not running.
                    var timeout      = 100; // 100ms
                    var stream       = new NamedPipeClientStream(serverName, pipeName);
                    var dockerStream = new DockerPipeStream(stream);

                    await stream.ConnectAsync(timeout, cancellationToken);
                    return(dockerStream);
                });

                break;

            case "tcp":
            case "http":
                var builder = new UriBuilder(uri)
                {
                    Scheme = config.Credentials.IsTlsEnabled() ? "https" : "http"
                };
                uri     = builder.Uri;
                handler = new ManagedHandler();
                break;

            case "https":
                handler = new ManagedHandler();
                break;

            case "unix":
                var pipeString = uri.LocalPath;
                handler = new ManagedHandler(async(string host, int port, CancellationToken cancellationToken) =>
                {
                    var sock = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified);
                    await sock.ConnectAsync(new UnixDomainSocketEndPoint(pipeString));
                    return(sock);
                });
                uri = new UriBuilder("http", uri.Segments.Last()).Uri;
                break;

            default:
                throw new Exception($"Unknown URL scheme {config.Endpoint.Scheme}");
            }

            endpointBaseUri = uri;

            client         = new HttpClient(Config.Credentials.GetHandler(handler), true);
            defaultTimeout = client.Timeout;
            client.Timeout = s_InfiniteTimeout;
        }