internal void RemoveIgnoredHeaders(OnPremiseConnectorRequest onPremiseConnectorRequest) { foreach (var key in _ignoredHeaders) { onPremiseConnectorRequest.HttpHeaders.Remove(key); } }
private async Task ProvideLinkConfigurationAsync(IOnPremiseConnectionContext onPremiseConnectionContext) { try { var config = _linkRepository.GetLinkConfiguration(onPremiseConnectionContext.LinkId); config.ApplyDefaults(_configuration); var requestId = Guid.NewGuid().ToString(); _logger?.Debug("Sending configuration to OPC. connection-id={ConnectionId}, link-id={LinkId}, connector-version={ConnectorVersion}, link-configuration={@LinkConfiguration}, request-id={RequestId}", onPremiseConnectionContext.ConnectionId, onPremiseConnectionContext.LinkId, onPremiseConnectionContext.ConnectorVersion, config, requestId); var request = new OnPremiseConnectorRequest() { HttpMethod = "CONFIG", Url = String.Empty, RequestStarted = DateTime.UtcNow, OriginId = OriginId, RequestId = requestId, AcknowledgmentMode = AcknowledgmentMode.Auto, Body = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(config)), }; // configs, like heartbeats, do not go through the message dispatcher but directly to the connection await onPremiseConnectionContext.RequestAction(request, CancellationToken.None).ConfigureAwait(false); } catch (Exception ex) { _logger?.Error(ex, "An error happened while sending the link config to the connected OPC."); } }
public async Task Relay_delegates_information_and_returns_valid_httpResponseMessage_when_entered_a_valid_path() { var startTime = DateTime.UtcNow; var loggerMock = new Mock <ILogger>(); var backendCommunicationMock = new Mock <IBackendCommunication>(); var relayRepositoryMock = new Mock <ILinkRepository>(); var pathSplitterMock = new Mock <IPathSplitter>(); var clientRequestBuilderMock = new Mock <IOnPremiseRequestBuilder>(); var httpResponseMessageBuilderMock = new Mock <IHttpResponseMessageBuilder>(); var requestLoggerMock = new Mock <IRequestLogger>(); var traceManagerMock = new Mock <ITraceManager>(); var sut = new ClientController(backendCommunicationMock.Object, loggerMock.Object, relayRepositoryMock.Object, requestLoggerMock.Object, httpResponseMessageBuilderMock.Object, clientRequestBuilderMock.Object, pathSplitterMock.Object, traceManagerMock.Object) { ControllerContext = new HttpControllerContext { Request = new HttpRequestMessage { Method = HttpMethod.Post } }, Request = new HttpRequestMessage() }; HttpResponseMessage result; var linkFake = new Link { Id = Guid.Parse("fb35e2fb-5fb6-4475-baa0-e0b06f5fdeda") }; var clientRequestFake = new OnPremiseConnectorRequest { RequestId = "239b6e03-9795-450d-bdd1-ab72900f1a98" }; var onPremiseTargetReponseFake = new OnPremiseTargetReponse(); var httpResponseMessageFake = new HttpResponseMessage { StatusCode = HttpStatusCode.Found }; var localConfigurationGuid = Guid.NewGuid(); loggerMock.Setup(l => l.Trace(It.IsAny <string>)); backendCommunicationMock.SetupGet(b => b.OriginId).Returns("c9208bdb-c195-460d-b84e-6c146bb252e5"); 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.BuildFrom(sut.Request, "c9208bdb-c195-460d-b84e-6c146bb252e5", "Bar/Baz")).ReturnsAsync(clientRequestFake); backendCommunicationMock.Setup(b => b.SendOnPremiseConnectorRequest("fb35e2fb-5fb6-4475-baa0-e0b06f5fdeda", clientRequestFake)).Returns(Task.FromResult(0)); backendCommunicationMock.Setup(b => b.GetResponseAsync("239b6e03-9795-450d-bdd1-ab72900f1a98")).ReturnsAsync(onPremiseTargetReponseFake); httpResponseMessageBuilderMock.Setup(h => h.BuildFrom(onPremiseTargetReponseFake, linkFake)).Returns(httpResponseMessageFake); traceManagerMock.Setup(t => t.GetCurrentTraceConfigurationId(linkFake.Id)).Returns(localConfigurationGuid); traceManagerMock.Setup(t => t.Trace(clientRequestFake, onPremiseTargetReponseFake, localConfigurationGuid)); requestLoggerMock.Setup(r => r.LogRequest(clientRequestFake, onPremiseTargetReponseFake, HttpStatusCode.Found, Guid.Parse("fb35e2fb-5fb6-4475-baa0-e0b06f5fdeda"), "c9208bdb-c195-460d-b84e-6c146bb252e5", "Foo/Bar/Baz")); result = await sut.Relay("Foo/Bar/Baz"); relayRepositoryMock.VerifyAll(); pathSplitterMock.VerifyAll(); backendCommunicationMock.VerifyAll(); clientRequestBuilderMock.VerifyAll(); httpResponseMessageBuilderMock.VerifyAll(); requestLoggerMock.VerifyAll(); traceManagerMock.VerifyAll(); clientRequestFake.RequestFinished.Should().BeAfter(startTime).And.BeOnOrBefore(DateTime.UtcNow); result.Should().BeSameAs(httpResponseMessageFake); }
public void LogRequest_writes_correctly_composed_log_entry_to_the_RelayRepository_when_OnPremiseTargetResult_is_null() { 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) }; 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, null, HttpStatusCode.PaymentRequired, Guid.Parse("4bb4ff98-ba03-49ee-bd83-5a229f63fade"), "35eff886-2d7c-4265-a6a4-f3f471ab93e8", "gimme/that/file.html"); 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(null); result.OnPremiseTargetOutDate.Should().Be(null); result.ContentBytesIn.Should().Be(3L); result.ContentBytesOut.Should().Be(0L); result.LinkId.Should().Be(Guid.Parse("4bb4ff98-ba03-49ee-bd83-5a229f63fade")); }
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 onPremiseTargetResponse = new OnPremiseTargetReponse { 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, new Configuration(), loggerMock.Object); var exception = new Exception(); traceFileWriterMock.Setup(t => t.WriteContentFile(It.IsAny <string>(), clientRequest.Body)).Throws(exception); loggerMock.Setup(l => l.Warn(It.IsAny <string>(), exception)); sut.Trace(clientRequest, onPremiseTargetResponse, traceConfigurationId); traceFileWriterMock.VerifyAll(); }
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); }
private void FinishRequest(OnPremiseConnectorRequest request, IOnPremiseConnectorResponse response, LinkInformation link, string path, HttpStatusCode statusCode) { if (request == null) { return; } request.RequestFinished = DateTime.UtcNow; _logger?.Verbose("Finishing request. request-id={RequestId}, link-id={LinkId}, link-name={LinkName}, on-premise-duration={RemoteDuration}, global-duration={GlobalDuration}", request.RequestId, link.Id, link.SymbolicName, response?.RequestFinished - response?.RequestStarted, request.RequestFinished - request.RequestStarted); _traceManager.Trace(request, response, link.TraceConfigurationIds); _requestLogger.LogRequest(request, response, link.Id, _backendCommunication.OriginId, path, statusCode); }
private async Task SendHeartbeatAsync(IOnPremiseConnectionContext connectionContext, CancellationToken token) { if (connectionContext == null) { throw new ArgumentNullException(nameof(connectionContext)); } if (connectionContext.NextHeartbeat > DateTime.UtcNow) { return; } connectionContext.NextHeartbeat = DateTime.UtcNow.Add(_heartbeatInterval); try { _logger?.Verbose("Sending {PingMethod}. connection-id={ConnectionId}", connectionContext.SupportsHeartbeat ? "Heartbeat" : "Ping (as heartbeat)", connectionContext.ConnectionId); var requestId = Guid.NewGuid().ToString(); var request = new OnPremiseConnectorRequest() { HttpMethod = connectionContext.SupportsHeartbeat ? "HEARTBEAT" : "PING", Url = String.Empty, RequestStarted = DateTime.UtcNow, OriginId = _backendCommunication.OriginId, RequestId = requestId, AcknowledgmentMode = AcknowledgmentMode.Auto, HttpHeaders = connectionContext.SupportsConfiguration ? null : new Dictionary <string, string> { ["X-TTRELAY-HEARTBEATINTERVAL"] = _heartbeatInterval.TotalSeconds.ToString(CultureInfo.InvariantCulture) }, }; // wait for the response of the Heartbeat / Ping var task = _backendCommunication.GetResponseAsync(requestId, _configuration.ActiveConnectionTimeout); // heartbeats do NOT go through the message dispatcher as we want to heartbeat the connections directly await connectionContext.RequestAction(request, token).ConfigureAwait(false); var response = await task.ConfigureAwait(false); if (response != null) { await _backendCommunication.RenewLastActivityAsync(connectionContext.ConnectionId).ConfigureAwait(false); } } catch (Exception ex) { _logger?.Error(ex, "Error during sending heartbeat to a client. link-id={LinkId}, connection-id={ConnectionId}, connector-version={ConnectorVersion}", connectionContext.LinkId, connectionContext.ConnectionId, connectionContext.ConnectorVersion); } }
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 onPremiseTargetResponse = new OnPremiseTargetReponse { 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, new Configuration(), loggerMock.Object); startTime = DateTime.Now; traceFileWriterMock.Setup(t => t.WriteContentFile(It.IsAny <string>(), clientRequest.Body)).Callback((string f, byte[] c) => clientRequestBodyFileName = f); traceFileWriterMock.Setup(t => t.WriteContentFile(It.IsAny <string>(), onPremiseTargetResponse.Body)).Callback((string f, byte[] c) => onPremiseTargetResponseBodyFileName = f);; traceFileWriterMock.Setup(t => t.WriteHeaderFile(It.IsAny <string>(), clientRequest.HttpHeaders)).Callback((string f, IDictionary <string, string> c) => clientRequestHeadersFileName = f);; traceFileWriterMock.Setup(t => t.WriteHeaderFile(It.IsAny <string>(), onPremiseTargetResponse.HttpHeaders)).Callback((string f, IDictionary <string, string> c) => onPremiseTargetResponseHeadersFileName = f);; sut.Trace(clientRequest, onPremiseTargetResponse, traceConfigurationId); var ticks = new DateTime(long.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"); }
private void PrepareRequestBodyForRelaying(OnPremiseConnectorRequest request) { if (request.Stream == null) { request.Body = null; return; } if (request.ContentLength == 0 || request.ContentLength >= 0x10000) { // We might have no Content-Length header, but still content, so we'll assume a large body first using (var storeStream = _postDataTemporaryStore.CreateRequestStream(request.RequestId)) { request.Stream.CopyTo(storeStream); if (storeStream.Length < 0x10000) { if (storeStream.Length == 0) { // no body available (e.g. GET request) } else { // the body is small enough to be used directly request.Body = new byte[storeStream.Length]; storeStream.Position = 0; storeStream.Read(request.Body, 0, (int)storeStream.Length); } } else { // a length of 0 indicates that there is a larger body available on the server request.Body = Array.Empty <byte>(); } request.Stream = null; request.ContentLength = storeStream.Length; } } else { // we have a body, and it is small enough to be transmitted directly request.Body = new byte[request.ContentLength]; request.Stream.Read(request.Body, 0, (int)request.ContentLength); request.Stream = null; } }
public void RemoveIgnoredHeaders_removes_ignored_headers_from_ClientRequest() { var clientRequest = new OnPremiseConnectorRequest { HttpHeaders = new Dictionary <string, string> { { "Host", "tt.invalid" }, { "Connection", "close" }, { "Content-Length", "3" } } }; var sut = new OnPremiseRequestBuilder(); sut.RemoveIgnoredHeaders(clientRequest); clientRequest.HttpHeaders.Should().HaveCount(1); clientRequest.HttpHeaders.Single().Key.Should().Be("Content-Length"); }
private void FinishRequest(OnPremiseConnectorRequest request, IOnPremiseConnectorResponse response, Guid linkId, string path, HttpStatusCode statusCode) { if (request == null) { return; } request.RequestFinished = DateTime.UtcNow; _logger?.Verbose("Finishing request. request-id={RequestId}, link-id={LinkId}, on-premise-duration={RemoteDuration}, global-duration={GlobalDuration}", request.RequestId, linkId, response?.RequestFinished - response?.RequestStarted, request.RequestFinished - request.RequestStarted); // TODO this may be debounced for e.g. 5 minutes to skip querying on each request in future release var currentTraceConfigurationId = _traceManager.GetCurrentTraceConfigurationId(linkId); if (currentTraceConfigurationId != null) { _traceManager.Trace(request, response, currentTraceConfigurationId.Value); } _requestLogger.LogRequest(request, response, linkId, _backendCommunication.OriginId, path, statusCode); }
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 onPremiseTargetResponse = new OnPremiseTargetReponse { 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, new Configuration(), loggerMock.Object); Directory.CreateDirectory("tracefiles"); Directory.Delete("tracefiles"); traceFileWriterMock.Setup(t => t.WriteContentFile(It.IsAny <string>(), clientRequest.Body)); traceFileWriterMock.Setup(t => t.WriteContentFile(It.IsAny <string>(), onPremiseTargetResponse.Body)); traceFileWriterMock.Setup(t => t.WriteHeaderFile(It.IsAny <string>(), clientRequest.HttpHeaders)); traceFileWriterMock.Setup(t => t.WriteHeaderFile(It.IsAny <string>(), onPremiseTargetResponse.HttpHeaders)); sut.Trace(clientRequest, onPremiseTargetResponse, traceConfigurationId); traceFileWriterMock.VerifyAll(); Directory.Exists("tracefiles").Should().BeTrue(); Directory.Delete("tracefiles"); }
public async Task <IHttpActionResult> PingAsync(Guid id) { var requestId = Guid.NewGuid().ToString(); var onPremiseConnectorRequest = new OnPremiseConnectorRequest { HttpMethod = "PING", Url = "", RequestStarted = DateTime.UtcNow, OriginId = _backendCommunication.OriginId, RequestId = requestId }; await _backendCommunication.SendOnPremiseConnectorRequest(id.ToString(), onPremiseConnectorRequest); var onPremiseTargetReponse = await _backendCommunication.GetResponseAsync(requestId); onPremiseConnectorRequest.RequestFinished = DateTime.UtcNow; _requestLogger.LogRequest(onPremiseConnectorRequest, onPremiseTargetReponse, HttpStatusCode.OK, id, _backendCommunication.OriginId, "invalid/Ping.local/"); return(Ok()); }
public void AddContentHeaders_adds_content_headers_to_ClientRequest_headers() { var clientRequest = new OnPremiseConnectorRequest { HttpHeaders = new Dictionary <string, string> { { "Content-Length", "3" } } }; var request = new HttpRequestMessage { Content = new ByteArrayContent(new byte[] { }) }; var sut = new OnPremiseRequestBuilder(); request.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment"); sut.AddContentHeaders(clientRequest, request); clientRequest.HttpHeaders.Should().HaveCount(2); clientRequest.HttpHeaders.Last().Key.Should().Be("Content-Disposition"); }
public async Task <IHttpActionResult> SendPing(Guid id) { var requestId = Guid.NewGuid().ToString(); var request = new OnPremiseConnectorRequest() { HttpMethod = "PING", Url = String.Empty, RequestStarted = DateTime.UtcNow, OriginId = _backendCommunication.OriginId, RequestId = requestId }; var task = _backendCommunication.GetResponseAsync(requestId); _backendCommunication.SendOnPremiseConnectorRequest(id, request); var response = await task.ConfigureAwait(false); request.RequestFinished = DateTime.UtcNow; _requestLogger.LogRequest(request, response, id, _backendCommunication.OriginId, "DEBUG/PING/", response?.StatusCode); return((response != null) ? (IHttpActionResult)Ok() : new StatusCodeResult(HttpStatusCode.GatewayTimeout, Request)); }
public async Task <IOnPremiseConnectorRequest> BuildFromHttpRequest(HttpRequestMessage message, Guid originId, string pathWithoutUserName) { var request = new OnPremiseConnectorRequest() { RequestId = Guid.NewGuid().ToString(), HttpMethod = message.Method.Method, Url = pathWithoutUserName + message.RequestUri.Query, HttpHeaders = message.Headers.ToDictionary(kvp => kvp.Key, kvp => CombineMultipleHttpHeaderValuesIntoOneCommaSeparatedValue(kvp.Value), StringComparer.OrdinalIgnoreCase), OriginId = originId, RequestStarted = DateTime.UtcNow, Expiration = _configuration.RequestExpiration, ContentLength = message.Content.Headers.ContentLength.GetValueOrDefault(0), Stream = await message.Content.ReadAsStreamAsync().ConfigureAwait(false), }; request.HttpHeaders = message.Headers .Union(message.Content.Headers) .Where(kvp => _ignoredHeaders.All(name => name != kvp.Key)) .Select(kvp => new { Name = kvp.Key, Value = CombineMultipleHttpHeaderValuesIntoOneCommaSeparatedValue(kvp.Value) }) .ToDictionary(header => header.Name, header => header.Value); return(request); }
public async Task <IOnPremiseConnectorRequest> BuildFrom(HttpRequestMessage request, string originId, string pathWithoutUserName) { var onPremiseConnectorRequest = new OnPremiseConnectorRequest { RequestId = Guid.NewGuid().ToString(), Body = await GetClientRequestBodyAsync(request.Content), HttpMethod = request.Method.Method, Url = pathWithoutUserName + request.RequestUri.Query, HttpHeaders = request.Headers.ToDictionary(kvp => kvp.Key, kvp => CombineMultipleHttpHeaderValuesIntoOneCommaSeperatedValue(kvp.Value), StringComparer.OrdinalIgnoreCase), OriginId = originId, RequestStarted = DateTime.UtcNow }; AddContentHeaders(onPremiseConnectorRequest, request); RemoveIgnoredHeaders(onPremiseConnectorRequest); return(onPremiseConnectorRequest); }
public async Task <IOnPremiseConnectorRequest> BuildFromHttpRequest(HttpRequestMessage message, Guid originId, string pathWithoutUserName) { var request = new OnPremiseConnectorRequest { RequestId = Guid.NewGuid().ToString(), HttpMethod = message.Method.Method, Url = pathWithoutUserName + message.RequestUri.Query, HttpHeaders = message.Headers.ToDictionary(kvp => kvp.Key, kvp => CombineMultipleHttpHeaderValuesIntoOneCommaSeperatedValue(kvp.Value), StringComparer.OrdinalIgnoreCase), OriginId = originId, RequestStarted = DateTime.UtcNow, Expiration = _configuration.RequestExpiration, }; if (message.Content.Headers.ContentLength.GetValueOrDefault(0x10000) >= 0x10000) { var contentStream = await message.Content.ReadAsStreamAsync().ConfigureAwait(false); using (var storeStream = _postDataTemporaryStore.CreateRequestStream(request.RequestId)) { await contentStream.CopyToAsync(storeStream).ConfigureAwait(false); if (storeStream.Length < 0x10000) { if (storeStream.Length == 0) { // no body available (e.g. GET request) } else { // the body is small enough to be used directly request.Body = new byte[storeStream.Length]; storeStream.Position = 0; await storeStream.ReadAsync(request.Body, 0, (int)storeStream.Length).ConfigureAwait(false); } // TODO delete obsolete file now } else { // a length of 0 indicates that there is a larger body available on the server request.Body = Array.Empty <byte>(); } request.ContentLength = storeStream.Length; } } else { var contentLength = message.Content.Headers.ContentLength.GetValueOrDefault(0); if (contentLength > 0) { // we have a body, and it is small enough to be transmitted directly var contentStream = await message.Content.ReadAsStreamAsync().ConfigureAwait(false); request.Body = new byte[contentLength]; await contentStream.ReadAsync(request.Body, 0, (int)contentLength).ConfigureAwait(false); request.ContentLength = contentLength; } } request.HttpHeaders = message.Headers .Union(message.Content.Headers) .Where(kvp => _ignoredHeaders.All(name => name != kvp.Key)) .Select(kvp => new { Name = kvp.Key, Value = CombineMultipleHttpHeaderValuesIntoOneCommaSeperatedValue(kvp.Value) }) .ToDictionary(header => header.Name, header => header.Value); return(request); }