public void TestIsBrokenPipe_notBrokenPipe()
 {
     Assert.IsFalse(RegistryEndpointCaller.IsBrokenPipe(new IOException()));
     Assert.IsFalse(RegistryEndpointCaller.IsBrokenPipe(new SocketException()));
     Assert.IsFalse(RegistryEndpointCaller.IsBrokenPipe(new AuthenticationException("mock")));
     Assert.IsFalse(RegistryEndpointCaller.IsBrokenPipe(new HttpRequestException("mock")));
 }
 public void TestIsBrokenPipe_brokenPipe()
 {
     Assert.IsTrue(RegistryEndpointCaller.IsBrokenPipe(new Win32Exception(RegistryEndpointCaller.ERROR_BROKEN_PIPE)));
     Assert.IsTrue(RegistryEndpointCaller.IsBrokenPipe(new SocketException(RegistryEndpointCaller.ERROR_BROKEN_PIPE)));
     Assert.IsTrue(RegistryEndpointCaller.IsBrokenPipe(
                       new HttpRequestException("mock", new SocketException(RegistryEndpointCaller.ERROR_BROKEN_PIPE))));
 }
        public async Task TestCall_insecureCallerOnHttpServerAsync()
        {
            Mock.Get(mockConnection)
            .Setup(c =>
                   c.SendAsync(It.Is <HttpRequestMessage>(m => m.RequestUri.Equals(new Uri("https://apiroutebase/api")))))
            .Throws(new HttpRequestException("", new AuthenticationException()));     // server is not HTTPS
            Mock.Get(mockConnection)
            .Setup(c =>
                   c.SendAsync(It.Is <HttpRequestMessage>(m => m.RequestUri.Equals(new Uri("http://apiroutebase:80/api")))))
            .Returns(Task.FromResult(mockResponse));
            Mock.Get(mockInsecureConnection).Setup(c => c.SendAsync(It.IsAny <HttpRequestMessage>()))
            .Throws(new HttpRequestException("", new AuthenticationException()));     // server is not HTTPS

            RegistryEndpointCaller <string> insecureEndpointCaller = CreateRegistryEndpointCaller(true, -1);

            Assert.AreEqual("body", await insecureEndpointCaller.CallAsync().ConfigureAwait(false));

            Mock.Get(mockEventHandlers).Verify(m => m.Dispatch(
                                                   LogEvent.Info(
                                                       "Cannot verify server at https://apiroutebase/api. Attempting again with no TLS verification.")));

            Mock.Get(mockEventHandlers).Verify(m => m.Dispatch(
                                                   LogEvent.Info(
                                                       "Failed to connect to https://apiroutebase/api over HTTPS. Attempting again with HTTP: http://apiroutebase/api")));
        }
        public async Task TestCall_credentialsForcedOverHttpAsync()
        {
            using (HttpResponseMessage redirectResponse = MockRedirectHttpResponse("http://newlocation"))
            {
                Mock.Get(mockConnection)
                .Setup(c =>
                       c.SendAsync(It.Is <HttpRequestMessage>(m => m.RequestUri.Equals(new Uri("https://apiroutebase/api")))))
                .Throws(new HttpRequestException("", new AuthenticationException()));     // server is not HTTPS

                Mock.Get(mockConnection)
                .Setup(c =>
                       c.SendAsync(It.Is <HttpRequestMessage>(m => m.RequestUri.Equals(new Uri("http://apiroutebase/api")))))
                .Throws(new HttpResponseException(redirectResponse));     // redirect to HTTP

                Mock.Get(mockConnection)
                .Setup(c => c.SendAsync(It.Is <HttpRequestMessage>(m => m.RequestUri.Equals(new Uri("http://newlocation")))))
                .Returns(Task.FromResult(mockResponse));                              // final response
                Mock.Get(mockInsecureConnection).Setup(c => c.SendAsync(It.IsAny <HttpRequestMessage>()))
                .Throws(new HttpRequestException("", new AuthenticationException())); // server is not HTTPS

                Environment.SetEnvironmentVariable(FibSystemProperties.SendCredentialsOverHttp, "true");
                RegistryEndpointCaller <string> insecureEndpointCaller = CreateRegistryEndpointCaller(true, -1);
                Assert.AreEqual("body", await insecureEndpointCaller.CallAsync().ConfigureAwait(false));

                Mock.Get(mockEventHandlers).Verify(m => m.Dispatch(
                                                       LogEvent.Info(
                                                           "Cannot verify server at https://apiroutebase/api. Attempting again with no TLS verification.")));

                Mock.Get(mockEventHandlers).Verify(m => m.Dispatch(
                                                       LogEvent.Info(
                                                           "Failed to connect to https://apiroutebase/api over HTTPS. Attempting again with HTTP: http://apiroutebase/api")));
            }
        }
        public void TestIsBrokenPipe_nestedBrokenPipe()
        {
            IOException exception = new IOException(
                "",
                new AuthenticationException("", new SocketException(RegistryEndpointCaller.ERROR_BROKEN_PIPE)));

            Assert.IsTrue(RegistryEndpointCaller.IsBrokenPipe(exception));
        }
        public async Task TestCall_insecureCallerOnHttpServerAndNoPortSpecifiedAsync()
        {
            Mock.Get(mockConnection)
            .Setup(c => c.SendAsync(It.Is <HttpRequestMessage>(m => m.RequestUri.Equals(new Uri("https://apiroutebase/api")))))
            .Throws(new ConnectException());     // server is not listening on 443

            Mock.Get(mockConnection)
            .Setup(c => c.SendAsync(It.Is <HttpRequestMessage>(m => m.RequestUri.Equals(new Uri("http://apiroutebase/api")))))
            .Returns(Task.FromResult(mockResponse));     // respond when connected through 80

            RegistryEndpointCaller <string> insecureEndpointCaller = CreateRegistryEndpointCaller(true, -1);

            Assert.AreEqual("body", await insecureEndpointCaller.CallAsync().ConfigureAwait(false));

            Mock.Get(mockEventHandlers).Verify(m => m.Dispatch(
                                                   LogEvent.Info(
                                                       "Failed to connect to https://apiroutebase/api over HTTPS. Attempting again with HTTP: http://apiroutebase/api")));
        }
        public void SetUp()
        {
            mockEventHandlers             = Mock.Of <IEventHandlers>();
            mockConnection                = Mock.Of <IConnection>();
            mockInsecureConnection        = Mock.Of <IConnection>();
            mockConnectionFactory         = Mock.Of <Func <Uri, IConnection> >();
            mockInsecureConnectionFactory = Mock.Of <Func <Uri, IConnection> >();
            secureEndpointCaller          = CreateRegistryEndpointCaller(false, -1);

            Mock.Get(mockConnectionFactory).Setup(m => m(It.IsAny <Uri>())).Returns(mockConnection);

            Mock.Get(mockInsecureConnectionFactory).Setup(m => m(It.IsAny <Uri>())).Returns(mockInsecureConnection);

            mockResponse = new HttpResponseMessage
            {
                Content = new StringContent("body")
            };
        }
        public async Task TestCall_insecureCallerOnUnverifiableServerAsync()
        {
            Mock.Get(mockConnection).Setup(m => m.SendAsync(It.IsAny <HttpRequestMessage>()))
            .Throws(new HttpRequestException("", new AuthenticationException()));     // unverifiable HTTPS server

            Mock.Get(mockInsecureConnection)
            .Setup(m => m.SendAsync(It.IsAny <HttpRequestMessage>()))
            .Returns(Task.FromResult(mockResponse));     // OK with non-verifying connection

            RegistryEndpointCaller <string> insecureCaller = CreateRegistryEndpointCaller(true, -1);

            Assert.AreEqual("body", await insecureCaller.CallAsync().ConfigureAwait(false));

            Mock.Get(mockConnectionFactory).Verify(m => m(new Uri("https://apiroutebase/api")));
            Mock.Get(mockInsecureConnectionFactory).Verify(m => m(new Uri("https://apiroutebase/api")));

            Mock.Get(mockEventHandlers).Verify(m => m.Dispatch(
                                                   LogEvent.Info(
                                                       "Cannot verify server at https://apiroutebase/api. Attempting again with no TLS verification.")));
        }
        public async Task TestCall_insecureCallerOnNonListeningServerAndPortSpecifiedAsync()
        {
            ConnectException expectedException = new ConnectException();

            Mock.Get(mockConnection).Setup(m => m.SendAsync(It.IsAny <HttpRequestMessage>()))
            .Throws(expectedException);     // server is not listening on 5000

            RegistryEndpointCaller <string> insecureEndpointCaller =
                CreateRegistryEndpointCaller(true, 5000);

            try
            {
                await insecureEndpointCaller.CallAsync().ConfigureAwait(false);

                Assert.Fail("Should not fall back to HTTP if port was explicitly given and cannot connect");
            }
            catch (ConnectException ex)
            {
                Assert.AreEqual(expectedException, ex);
            }
        }
        public async Task TestCall_credentialsNotSentOverHttpAsync()
        {
            HttpResponseMessage redirectResponse     = MockRedirectHttpResponse("http://newlocation");
            HttpResponseMessage unauthroizedResponse =
                MockHttpResponse(HttpStatusCode.Unauthorized, null);

            Mock.Get(mockConnection)
            .Setup(c =>
                   c.SendAsync(It.Is <HttpRequestMessage>(m => m.RequestUri.Equals(new Uri("https://apiroutebase/api")))))
            .Throws(new HttpRequestException("", new AuthenticationException()));     // server is not HTTPS

            Mock.Get(mockConnection)
            .Setup(c =>
                   c.SendAsync(It.Is <HttpRequestMessage>(m => m.RequestUri.Equals(new Uri("http://apiroutebase:80/api")))))
            .Returns(Task.FromResult(redirectResponse));     // redirect to HTTP

            Mock.Get(mockConnection)
            .Setup(c => c.SendAsync(It.Is <HttpRequestMessage>(m => m.RequestUri.Equals(new Uri("http://newlocation")))))
            .Returns(Task.FromResult(unauthroizedResponse));                      // final response
            Mock.Get(mockInsecureConnection).Setup(c => c.SendAsync(It.IsAny <HttpRequestMessage>()))
            .Throws(new HttpRequestException("", new AuthenticationException())); // server is not HTTPS

            RegistryEndpointCaller <string> insecureEndpointCaller = CreateRegistryEndpointCaller(true, -1);

            try
            {
                await insecureEndpointCaller.CallAsync().ConfigureAwait(false);

                Assert.Fail("Call should have failed");
            }
            catch (RegistryCredentialsNotSentException ex)
            {
                Assert.AreEqual(
                    "Required credentials for serverUrl/imageName were not sent because the connection was over HTTP",
                    ex.Message);
            }
        }