public void Trace_logs_exception()
        {
            var traceFileWriterMock  = new Mock <ITraceFileWriter>();
            var loggerMock           = new Mock <ILogger>();
            var traceConfigurationId = Guid.NewGuid();
            var clientRequest        = new OnPremiseConnectorRequest
            {
                HttpHeaders = new Dictionary <string, string>
                {
                    ["Content-Type"]   = "text/plain",
                    ["Content-Length"] = "700"
                },
                Body = new byte[] { 65, 66, 67 }
            };
            var onPremiseConnectorResponse = new OnPremiseConnectorResponse()
            {
                HttpHeaders = new Dictionary <string, string>
                {
                    ["Content-Type"]   = "image/png",
                    ["Content-Length"] = "7500"
                },
                Body = new byte[] { 66, 67, 68 }
            };
            ITraceManager sut = new TraceManager(null, traceFileWriterMock.Object, null, CreateDummyConfiguration(), loggerMock.Object);

            var exception = new Exception();

            traceFileWriterMock.Setup(t => t.WriteContentFileAsync(It.IsAny <string>(), clientRequest.Body)).Throws(exception);
            loggerMock.Setup(l => l.Warning(exception, It.IsAny <string>()));

            sut.Trace(clientRequest, onPremiseConnectorResponse, traceConfigurationId);

            traceFileWriterMock.VerifyAll();
        }
        public async Task <IHttpActionResult> Forward()
        {
            var requestStream = await Request.Content.ReadAsStreamAsync().ConfigureAwait(false);

            OnPremiseConnectorResponse response = null;

            if (Request.Headers.TryGetValues("X-TTRELAY-METADATA", out var headerValues))
            {
                response = JToken.Parse(headerValues.First()).ToObject <OnPremiseConnectorResponse>();

                using (var stream = _postDataTemporaryStore.CreateResponseStream(response.RequestId))
                {
                    await requestStream.CopyToAsync(stream).ConfigureAwait(false);

                    response.ContentLength = stream.Length;
                }
            }
            else
            {
                // this is a legacy on-premise connector (v1)
                response = await ForwardLegacyResponse(Encoding.UTF8, requestStream).ConfigureAwait(false);
            }

            _logger?.Verbose("Received on-premise response. request-id={RequestId}, content-length={ResponseContentLength}", response.RequestId, response.ContentLength);

            _backendCommunication.SendOnPremiseTargetResponse(response.OriginId, response);

            return(Ok());
        }
        public async Task <IHttpActionResult> Forward()
        {
            var claimsPrincipal = (ClaimsPrincipal)RequestContext.Principal;
            var onPremiseId     = claimsPrincipal.FindFirst(AuthorizationServerProvider.OnPremiseIdClaimName)?.Value;

            Request.GetCallCancelled().Register(() => _logger?.Warning("Disconnect during receiving on-premise response detected. link-id={LinkId}", onPremiseId));

            var requestStream = await Request.Content.ReadAsStreamAsync().ConfigureAwait(false);

            OnPremiseConnectorResponse response = null;

            if (Request.Headers.TryGetValues("X-TTRELAY-METADATA", out var headerValues))
            {
                response = JToken.Parse(headerValues.First()).ToObject <OnPremiseConnectorResponse>();

                using (var stream = _postDataTemporaryStore.CreateResponseStream(response.RequestId))
                {
                    await requestStream.CopyToAsync(stream).ConfigureAwait(false);

                    response.ContentLength = stream.Length;
                }
            }
            else
            {
                // this is a legacy on-premise connector (v1)
                response = await ForwardLegacyResponse(Encoding.UTF8, requestStream).ConfigureAwait(false);
            }

            _logger?.Verbose("Received on-premise response. request-id={RequestId}, content-length={ResponseContentLength}", response.RequestId, response.ContentLength);

            _backendCommunication.SendOnPremiseTargetResponse(response.OriginId, response);

            return(Ok());
        }
Exemple #4
0
        public async Task Relay_delegates_information_and_returns_valid_httpResponseMessage_when_entered_a_valid_path()
        {
            var startTime = DateTime.UtcNow;
            var sut       = CreateClientController();

            sut.ControllerContext = new HttpControllerContext {
                Request = new HttpRequestMessage {
                    Method = HttpMethod.Post
                }
            };
            sut.Request = new HttpRequestMessage();
            sut.User    = new FakePrincipal();

            HttpResponseMessage result;

            var requestId = "239b6e03-9795-450d-bdd1-ab72900f1a98";
            var linkId    = new Guid("fb35e2fb-5fb6-4475-baa0-e0b06f5fdeda");
            var linkFake  = new Link {
                Id = linkId
            };
            var clientRequestFake = new OnPremiseConnectorRequest {
                RequestId = requestId
            };
            var onPremiseTargetResponseFake = new OnPremiseConnectorResponse();
            var httpResponseMessageFake     = new HttpResponseMessage {
                StatusCode = HttpStatusCode.Found
            };
            var localConfigurationGuid = Guid.NewGuid();
            var originId = new Guid("c9208bdb-c195-460d-b84e-6c146bb252e5");

            _loggerMock.Setup(l => l.Verbose(It.IsAny <string>()));
            _backendCommunicationMock.SetupGet(b => b.OriginId).Returns(originId);
            _relayRepositoryMock.Setup(l => l.GetLink(It.IsAny <string>())).Returns(linkFake);
            _pathSplitterMock.Setup(p => p.Split(It.IsAny <string>())).Returns(new PathInformation {
                PathWithoutUserName = "******"
            });
            _clientRequestBuilderMock.Setup(c => c.BuildFromHttpRequest(sut.Request, originId, "Bar/Baz")).ReturnsAsync(clientRequestFake);
            _backendCommunicationMock.Setup(b => b.SendOnPremiseConnectorRequest(linkId, clientRequestFake));
            _backendCommunicationMock.Setup(b => b.GetResponseAsync(requestId, null)).ReturnsAsync(onPremiseTargetResponseFake);
            _traceManagerMock.Setup(t => t.GetCurrentTraceConfigurationId(linkFake.Id)).Returns(localConfigurationGuid);
            _traceManagerMock.Setup(t => t.Trace(clientRequestFake, onPremiseTargetResponseFake, localConfigurationGuid));
            _requestLoggerMock.Setup(r => r.LogRequest(clientRequestFake, onPremiseTargetResponseFake, linkId, originId, "Foo/Bar/Baz", 0));
            HttpResponseMessage messageDummy;

            _interceptorManagerMock.Setup(i => i.HandleRequest(clientRequestFake, sut.Request, sut.User, out messageDummy)).Returns(clientRequestFake);
            _interceptorManagerMock.Setup(i => i.HandleResponse(clientRequestFake, sut.Request, sut.User, onPremiseTargetResponseFake, false)).Returns(httpResponseMessageFake);

            result = await sut.Relay("Foo/Bar/Baz");

            _relayRepositoryMock.VerifyAll();
            _pathSplitterMock.VerifyAll();
            _backendCommunicationMock.VerifyAll();
            _clientRequestBuilderMock.VerifyAll();
            _requestLoggerMock.VerifyAll();
            _traceManagerMock.VerifyAll();
            _interceptorManagerMock.VerifyAll();
            clientRequestFake.RequestFinished.Should().BeAfter(startTime).And.BeOnOrBefore(DateTime.UtcNow);
            result.Should().BeSameAs(httpResponseMessageFake);
        }
        public void GetResponseContentForOnPremiseTargetResponse_does_not_disclose_content_when_other_error_occurred_and_ForwardOnPremiseTargetErrorResponse_is_turned_off()
        {
            var sut = new HttpResponseMessageBuilder(null);
            var onPremiseTargetResponse = new OnPremiseConnectorResponse {
                StatusCode = HttpStatusCode.NotImplemented
            };

            using (var result = sut.GetResponseContentForOnPremiseTargetResponse(onPremiseTargetResponse, false))
            {
                result.Should().BeNull();
            }
        }
Exemple #6
0
        public void GetResponseContentForOnPremiseTargetResponse_does_not_disclose_content_when_InternalServerError_occurred_and_ForwardOnPremiseTargetErrorResponse_is_turned_off()
        {
            var sut = new HttpResponseMessageBuilder(null, GetInMemoryStore());
            var onPremiseTargetResponse = new OnPremiseConnectorResponse {
                StatusCode = HttpStatusCode.InternalServerError
            };
            var link = new Link();

            using (var result = sut.GetResponseContentForOnPremiseTargetResponse(onPremiseTargetResponse, link))
            {
                result.Should().BeNull();
            }
        }
        public void Trace_uses_correct_file_names_build_from_Trace_ID_and_DateTime_ticks()
        {
            var traceFileWriterMock  = new Mock <ITraceFileWriter>();
            var loggerMock           = new Mock <ILogger>();
            var traceConfigurationId = Guid.NewGuid();
            var clientRequest        = new OnPremiseConnectorRequest
            {
                HttpHeaders = new Dictionary <string, string>
                {
                    ["Content-Type"]   = "text/plain",
                    ["Content-Length"] = "700"
                },
                Body = new byte[] { 65, 66, 67 }
            };
            var onPremiseConnectorResponse = new OnPremiseConnectorResponse()
            {
                HttpHeaders = new Dictionary <string, string>
                {
                    ["Content-Type"]   = "image/png",
                    ["Content-Length"] = "7500"
                },
                Body = new byte[] { 66, 67, 68 }
            };
            string        clientRequestBodyFileName              = null;
            string        clientRequestHeadersFileName           = null;
            string        onPremiseTargetResponseBodyFileName    = null;
            string        onPremiseTargetResponseHeadersFileName = null;
            DateTime      startTime;
            ITraceManager sut = new TraceManager(null, traceFileWriterMock.Object, null, CreateDummyConfiguration(), loggerMock.Object);

            startTime = DateTime.Now;

            traceFileWriterMock.Setup(t => t.WriteContentFileAsync(It.IsAny <string>(), clientRequest.Body)).Callback((string f, byte[] c) => clientRequestBodyFileName = f);
            traceFileWriterMock.Setup(t => t.WriteContentFileAsync(It.IsAny <string>(), onPremiseConnectorResponse.Body)).Callback((string f, byte[] c) => onPremiseTargetResponseBodyFileName = f);
            traceFileWriterMock.Setup(t => t.WriteHeaderFileAsync(It.IsAny <string>(), clientRequest.HttpHeaders)).Callback((string f, IReadOnlyDictionary <string, string> c) => clientRequestHeadersFileName = f);
            traceFileWriterMock.Setup(t => t.WriteHeaderFileAsync(It.IsAny <string>(), onPremiseConnectorResponse.HttpHeaders)).Callback((string f, IReadOnlyDictionary <string, string> c) => onPremiseTargetResponseHeadersFileName = f);

            sut.Trace(clientRequest, onPremiseConnectorResponse, traceConfigurationId);

            var ticks = new DateTime(Int64.Parse(clientRequestBodyFileName.Split('-').Skip(5).First().Split('.').First()));
            var expectedFileNamePrefix = Path.Combine("tracefiles", traceConfigurationId + "-" + ticks.Ticks);

            traceFileWriterMock.VerifyAll();
            ticks.Should().BeOnOrAfter(startTime).And.BeOnOrBefore(DateTime.Now);
            clientRequestBodyFileName.Should().Be(expectedFileNamePrefix + ".ct.content");
            onPremiseTargetResponseBodyFileName.Should().Be(expectedFileNamePrefix + ".optt.content");
            clientRequestHeadersFileName.Should().Be(expectedFileNamePrefix + ".ct.headers");
            onPremiseTargetResponseHeadersFileName.Should().Be(expectedFileNamePrefix + ".optt.headers");
        }
        public async Task GetResponseContentForOnPremiseTargetResponse_sets_StatusCode_accordingly_and_discloses_content()
        {
            var sut = new HttpResponseMessageBuilder(null);
            var onPremiseTargetResponse = new OnPremiseConnectorResponse {
                StatusCode = HttpStatusCode.OK, Body = new byte[] { 0, 0, 0, 0 }, ContentLength = 4,
            };

            using (var result = sut.GetResponseContentForOnPremiseTargetResponse(onPremiseTargetResponse, false))
            {
                var body = await result.ReadAsByteArrayAsync();

                result.Should().NotBeNull();
                body.LongLength.Should().Be(4L);
            }
        }
        public async Task GetResponseContentForOnPremiseTargetResponse_discloses_content_when_other_error_occurred_and_ForwardOnPremiseTargetErrorResponse_is_turned_on()
        {
            var sut = new HttpResponseMessageBuilder(null);
            var onPremiseTargetResponse = new OnPremiseConnectorResponse {
                StatusCode = HttpStatusCode.NotImplemented, Body = new byte[] { 0, 0, 0 }, ContentLength = 3,
            };

            using (var result = sut.GetResponseContentForOnPremiseTargetResponse(onPremiseTargetResponse, true))
            {
                var body = await result.ReadAsByteArrayAsync();

                result.Should().NotBeNull();
                body.LongLength.Should().Be(3L);
            }
        }
 private void FetchResponseBodyForIntercepting(OnPremiseConnectorResponse response)
 {
     if (response.ContentLength == 0)
     {
         _logger?.Verbose("Received empty body. request-id={RequestId}", response.RequestId);
     }
     else if (response.Body != null)
     {
         _logger?.Verbose("Received small legacy body with data. request-id={RequestId}, body-length={ResponseContentLength}", response.RequestId, response.Body.Length);
     }
     else
     {
         _logger?.Verbose("Received body. request-id={RequestId}, content-length={ResponseContentLength}", response.RequestId, response.ContentLength);
         response.Stream = _postDataTemporaryStore.GetResponseStream(response.RequestId);
     }
 }
Exemple #11
0
        public async Task GetResponseContentForOnPremiseTargetResponse_discloses_content_when_InternalServerError_occurred_and_ForwardOnPremiseTargetErrorResponse_is_turned_on()
        {
            var sut = new HttpResponseMessageBuilder(null, GetInMemoryStore());
            var onPremiseTargetResponse = new OnPremiseConnectorResponse {
                StatusCode = HttpStatusCode.InternalServerError, Body = new byte[] { 0, 0, 0 }, ContentLength = 3,
            };
            var link = new Link {
                ForwardOnPremiseTargetErrorResponse = true
            };

            using (var result = sut.GetResponseContentForOnPremiseTargetResponse(onPremiseTargetResponse, link))
            {
                var body = await result.ReadAsByteArrayAsync();

                result.Should().NotBeNull();
                body.LongLength.Should().Be(3L);
            }
        }
        public void LogRequest_writes_correctly_composed_log_entry_to_the_RelayRepository_with_OnPremiseTargetResult_set()
        {
            var            logRepositoryMock = new Mock <ILogRepository>();
            var            pathSplitterMock  = new Mock <IPathSplitter>();
            IRequestLogger sut           = new RequestLogger(logRepositoryMock.Object, pathSplitterMock.Object);
            var            clientRequest = new OnPremiseConnectorRequest
            {
                Body            = new byte[] { 0, 0, 0 },
                RequestStarted  = new DateTime(2014, 1, 1),
                RequestFinished = new DateTime(2014, 1, 2),
                ContentLength   = 3,
            };
            var onPremiseConnectorResponse = new OnPremiseConnectorResponse
            {
                RequestStarted  = new DateTime(2014, 1, 3),
                RequestFinished = new DateTime(2014, 1, 4),
                ContentLength   = 2,
            };
            RequestLogEntry result = null;

            logRepositoryMock.Setup(r => r.LogRequest(It.IsAny <RequestLogEntry>())).Callback <RequestLogEntry>(r => result = r);
            pathSplitterMock.Setup(p => p.Split(It.IsAny <string>())).Returns(new PathInformation {
                OnPremiseTargetKey = "that", LocalUrl = "/file.html"
            });

            sut.LogRequest(clientRequest, onPremiseConnectorResponse, Guid.Parse("4bb4ff98-ba03-49ee-bd83-5a229f63fade"), new Guid("35eff886-2d7c-4265-a6a4-f3f471ab93e8"), "gimme/that/file.html", HttpStatusCode.PaymentRequired);

            logRepositoryMock.Verify(r => r.LogRequest(It.IsAny <RequestLogEntry>()));
            result.HttpStatusCode.Should().Be(HttpStatusCode.PaymentRequired);
            result.OriginId.Should().Be(Guid.Parse("35eff886-2d7c-4265-a6a4-f3f471ab93e8"));
            result.LocalUrl.Should().Be("/file.html");
            result.OnPremiseTargetKey.Should().Be("that");
            result.OnPremiseConnectorInDate.Should().Be(new DateTime(2014, 1, 1));
            result.OnPremiseConnectorOutDate.Should().Be(new DateTime(2014, 1, 2));
            result.OnPremiseTargetInDate.Should().Be(new DateTime(2014, 1, 3));
            result.OnPremiseTargetOutDate.Should().Be(new DateTime(2014, 1, 4));
            result.ContentBytesIn.Should().Be(3L);
            result.ContentBytesOut.Should().Be(2L);
            result.LinkId.Should().Be(Guid.Parse("4bb4ff98-ba03-49ee-bd83-5a229f63fade"));
        }
        public void Trace_creates_tracefiles_directory()
        {
            var traceFileWriterMock  = new Mock <ITraceFileWriter>();
            var loggerMock           = new Mock <ILogger>();
            var traceConfigurationId = Guid.NewGuid();
            var clientRequest        = new OnPremiseConnectorRequest
            {
                HttpHeaders = new Dictionary <string, string>
                {
                    ["Content-Type"]   = "text/plain",
                    ["Content-Length"] = "700"
                },
                Body = new byte[] { 65, 66, 67 }
            };
            var onPremiseConnectorResponse = new OnPremiseConnectorResponse()
            {
                HttpHeaders = new Dictionary <string, string>
                {
                    ["Content-Type"]   = "image/png",
                    ["Content-Length"] = "7500"
                },
                Body = new byte[] { 66, 67, 68 }
            };
            ITraceManager sut = new TraceManager(null, traceFileWriterMock.Object, null, CreateDummyConfiguration(), loggerMock.Object);

            Directory.CreateDirectory("tracefiles");
            Directory.Delete("tracefiles");

            traceFileWriterMock.Setup(t => t.WriteContentFileAsync(It.IsAny <string>(), clientRequest.Body));
            traceFileWriterMock.Setup(t => t.WriteContentFileAsync(It.IsAny <string>(), onPremiseConnectorResponse.Body));
            traceFileWriterMock.Setup(t => t.WriteHeaderFileAsync(It.IsAny <string>(), clientRequest.HttpHeaders));
            traceFileWriterMock.Setup(t => t.WriteHeaderFileAsync(It.IsAny <string>(), onPremiseConnectorResponse.HttpHeaders));

            sut.Trace(clientRequest, onPremiseConnectorResponse, traceConfigurationId);

            traceFileWriterMock.VerifyAll();
            Directory.Exists("tracefiles").Should().BeTrue();

            Directory.Delete("tracefiles");
        }