public void Trace(IOnPremiseConnectorRequest request, IOnPremiseConnectorResponse response, IEnumerable <Guid> traceConfigurationIds) { foreach (var traceConfigurationId in traceConfigurationIds) { Trace(request, response, traceConfigurationId); } }
public HttpResponseMessage BuildFromConnectorResponse(IOnPremiseConnectorResponse response, Link link, string requestId) { var message = new HttpResponseMessage(); if (response == null) { _logger?.Verbose("Received no response. request-id={RequestId}", requestId); message.StatusCode = HttpStatusCode.GatewayTimeout; message.Content = new ByteArrayContent(Array.Empty <byte>()); message.Content.Headers.Add("X-TTRELAY-TIMEOUT", "On-Premise"); } else { message.StatusCode = response.StatusCode; message.Content = GetResponseContentForOnPremiseTargetResponse(response, link); if (response.HttpHeaders.TryGetValue("WWW-Authenticate", out var wwwAuthenticate)) { message.Headers.Add("WWW-Authenticate", wwwAuthenticate); } if (IsRedirectStatusCode(response.StatusCode) && response.HttpHeaders.TryGetValue("Location", out var location)) { message.Headers.Location = new Uri(location, UriKind.RelativeOrAbsolute); } } return(message); }
public void LogRequest(IOnPremiseConnectorRequest request, IOnPremiseConnectorResponse response, Guid linkId, Guid originId, string relayPath, HttpStatusCode?statusCode) { if (request == null) { throw new ArgumentNullException(nameof(request)); } var pathInformation = _pathSplitter.Split(relayPath); _logRepository.LogRequest(new RequestLogEntry { LocalUrl = pathInformation.LocalUrl, HttpStatusCode = statusCode ?? HttpStatusCode.InternalServerError, ContentBytesIn = request.ContentLength, ContentBytesOut = response?.ContentLength ?? 0, OnPremiseConnectorInDate = request.RequestStarted, OnPremiseConnectorOutDate = request.RequestFinished, OnPremiseTargetInDate = response?.RequestStarted, OnPremiseTargetOutDate = response?.RequestFinished, OriginId = originId, OnPremiseTargetKey = pathInformation.OnPremiseTargetKey, LinkId = linkId, RequestId = request.RequestId, }); }
public void SendOnPremiseTargetResponse(Guid originId, IOnPremiseConnectorResponse response) { CheckDisposed(); _logger?.Debug("Dispatching response. origin-id={OriginId}", originId); _messageDispatcher.DispatchResponse(originId, response); }
public void DispatchResponse(Guid originId, IOnPremiseConnectorResponse response) { var content = Serialize(response, out var props); lock (_model) { _model.BasicPublish(_EXCHANGE_NAME, $"{_RESPONSE_QUEUE_PREFIX}{originId}", false, props, content); } }
private void ForwardOnPremiseTargetResponse(IOnPremiseConnectorResponse response) { if (_requestCompletedCallbacks.TryRemove(response.RequestId, out var onPremiseConnectorCallback)) { _logger?.Debug("Forwarding on-premise target response. request-id={RequestId}", response.RequestId); onPremiseConnectorCallback.Response.SetResult(response); } else { _logger?.Information("Response received but no request callback found for request {RequestId}", response.RequestId); } }
public InterceptedResponse(IOnPremiseConnectorResponse other) { RequestId = other.RequestId; OriginId = other.OriginId; RequestStarted = other.RequestStarted; RequestFinished = other.RequestFinished; StatusCode = other.StatusCode; HttpHeaders = other.HttpHeaders; Body = other.Body; // this is because of legacy on-premise connectors (v1) Stream = other.Stream; ContentLength = other.ContentLength; }
public void DispatchResponse(Guid originId, IOnPremiseConnectorResponse response) { if (response == null) { throw new ArgumentNullException(nameof(response)); } CheckDisposed(); _logger?.Debug("Dispatching response. origin-id={OriginId}, request-id={RequestId}, status-code={ResponseStatusCode}", originId, response.RequestId, response.StatusCode); GetResponseSubject(originId).OnNext(response); }
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 void FinishRequest(IOnPremiseConnectorRequest request, IOnPremiseConnectorResponse response, Guid linkId, string path, HttpStatusCode statusCode) { 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 HttpContent GetResponseContentForOnPremiseTargetResponse(IOnPremiseConnectorResponse response, Link link) { if (response == null) { throw new ArgumentNullException(nameof(response)); } if (response.StatusCode >= HttpStatusCode.InternalServerError && !link.ForwardOnPremiseTargetErrorResponse) { return(null); } HttpContent content; if (response.ContentLength == 0) { _logger?.Verbose("Received empty body. request-id={RequestId}", response.RequestId); content = new ByteArrayContent(Array.Empty <byte>()); } else if (response.Body != null) { // only legacy on-premise connectors (v1) use this property _logger?.Verbose("Received small legacy body with data. request-id={RequestId}, body-length={ResponseContentLength}", response.RequestId, response.Body.Length); content = new ByteArrayContent(response.Body); } else { _logger?.Verbose("Received body. request-id={RequestId}, content-length={ResponseContentLength}", response.RequestId, response.ContentLength); var stream = _postDataTemporaryStore.GetResponseStream(response.RequestId); if (stream == null) { throw new InvalidOperationException(); // TODO what now? } content = new StreamContent(stream, 0x10000); } AddContentHttpHeaders(content, response.HttpHeaders); return(content); }
public HttpContent GetResponseContentForOnPremiseTargetResponse(IOnPremiseConnectorResponse response, bool forwardOnPremiseTargetErrorResponse) { if (response == null) { throw new ArgumentNullException(nameof(response)); } if (response.StatusCode >= HttpStatusCode.InternalServerError && !forwardOnPremiseTargetErrorResponse) { return(null); } HttpContent content; if (response.ContentLength == 0) { // No content content = new ByteArrayContent(Array.Empty <byte>()); } else if (response.Body != null) { // Unmodified legacy response content = new ByteArrayContent(response.Body); } else { // Normal content stream var stream = response.Stream; if (stream == null) { throw new InvalidOperationException(); // TODO what now? } else if (stream.Position != 0 && stream.CanSeek) { stream.Position = 0; } content = new StreamContent(stream, 0x10000); } AddContentHttpHeaders(content, response.HttpHeaders); return(content); }
public void Trace(IOnPremiseConnectorRequest request, IOnPremiseConnectorResponse response, Guid traceConfigurationId) { try { if (!Directory.Exists(_configuration.TraceFileDirectory)) { Directory.CreateDirectory(_configuration.TraceFileDirectory); } var filenamePrefix = $"{Path.Combine(_configuration.TraceFileDirectory, traceConfigurationId.ToString())}-{DateTime.Now.Ticks}"; _traceFileWriter.WriteHeaderFileAsync(filenamePrefix + _ON_PREMISE_CONNECTOR_HEADER_EXTENSION, request.HttpHeaders); _traceFileWriter.WriteContentFileAsync(filenamePrefix + _ON_PREMISE_CONNECTOR_CONTENT_EXTENSION, request.Body); _traceFileWriter.WriteHeaderFileAsync(filenamePrefix + _ON_PREMISE_TARGET_HEADER_EXTENSION, response.HttpHeaders); _traceFileWriter.WriteContentFileAsync(filenamePrefix + _ON_PREMISE_TARGET_CONTENT_EXTENSION, response.Body); } catch (Exception ex) { _logger?.Warning(ex, "Could not create trace"); } }
public HttpResponseMessage HandleResponse(IOnPremiseConnectorRequest request, HttpRequestMessage message, IPrincipal clientUser, IOnPremiseConnectorResponse response) { if (_responseInterceptor == null) { return(null); } _logger?.Verbose("Handling response. request-id={RequestId}", request.RequestId); try { var interceptedRequest = CreateInterceptedRequest(request, message, clientUser); var immediateResponse = response == null?_responseInterceptor.OnResponseFailed(interceptedRequest) : _responseInterceptor.OnResponseReceived(interceptedRequest, new InterceptedResponse(response)); if (immediateResponse != null) { immediateResponse.RequestMessage = message; } return(immediateResponse); } catch (Exception ex) { _logger?.Error(ex, "Error while executing the response interceptor. type-name={InterceptorType}, request-id={RequestId}", _requestInceptor?.GetType().Name, request.RequestId); return(null); } }
public void DispatchResponse(Guid originId, IOnPremiseConnectorResponse response) { EnsureResponseChannel(originId.ToString()).Dispatch(response); }
public async Task <HttpResponseMessage> Relay(string fullPathToOnPremiseEndpoint) { _logger?.Debug("Relaying request. method={RequestMethod}, path={RequestPath}", ControllerContext.Request.Method, fullPathToOnPremiseEndpoint); if (fullPathToOnPremiseEndpoint == null) { _logger?.Information("Path to on premise endpoint is not set"); return(NotFound()); } var pathInformation = _pathSplitter.Split(fullPathToOnPremiseEndpoint); var link = _linkRepository.GetLink(pathInformation.UserName); if (!CanRequestBeHandled(fullPathToOnPremiseEndpoint, pathInformation, link)) { _logger?.Information("Request cannot be handled"); return(NotFound()); } var request = await _onPremiseRequestBuilder.BuildFromHttpRequest(Request, _backendCommunication.OriginId, pathInformation.PathWithoutUserName).ConfigureAwait(false); var statusCode = HttpStatusCode.GatewayTimeout; IOnPremiseConnectorResponse response = null; try { request = _interceptorManager.HandleRequest(request, Request, User, out var message); if (message != null) { _logger?.Verbose("Interceptor caused direct answering of request. request-id={RequestId}, status-code={ResponseStatusCode}", request.RequestId, message.StatusCode); statusCode = message.StatusCode; if (request.AlwaysSendToOnPremiseConnector) { _logger?.Verbose("Interceptor caused always sending of request. request-id={RequestId}", request.RequestId); SendOnPremiseConnectorRequest(link.Id, request); } return(message); } var task = _backendCommunication.GetResponseAsync(request.RequestId); SendOnPremiseConnectorRequest(link.Id, request); _logger?.Verbose("Waiting for response. request-id={RequestId}, link-id={LinkId}", request.RequestId, link.Id); response = await task.ConfigureAwait(false); if (response != null) { _logger?.Verbose("Response received. request-id={RequestId}, link-id={LinkId}", request.RequestId, link.Id); FetchResponseBodyForIntercepting((OnPremiseConnectorResponse)response); statusCode = response.StatusCode; } else { _logger?.Verbose("No response received because of on-premise timeout. request-id={RequestId}, link-id={LinkId}", request.RequestId, link.Id); } return(_interceptorManager.HandleResponse(request, Request, User, response, link.ForwardOnPremiseTargetErrorResponse)); } finally { FinishRequest(request as OnPremiseConnectorRequest, response, link.Id, fullPathToOnPremiseEndpoint, statusCode); } }
public void LogRequest(IOnPremiseConnectorRequest request, IOnPremiseConnectorResponse response, Guid linkId, Guid originId, String relayPath, HttpStatusCode?statusCode) { // Noop }
public HttpResponseMessage HandleResponse(IOnPremiseConnectorRequest request, HttpRequestMessage message, IPrincipal clientUser, IOnPremiseConnectorResponse response, bool forwardOnPremiseTargetErrorResponse) { if (_responseInterceptor == null) { return(_httpResponseMessageBuilder.BuildFromConnectorResponse(response, forwardOnPremiseTargetErrorResponse, request.RequestId)); } _logger.Verbose("Handling response. request-id={RequestId}", request.RequestId); try { var interceptedRequest = CreateInterceptedRequest(request, message, clientUser); HttpResponseMessage immediateResponse = null; if (response == null) { immediateResponse = _responseInterceptor.OnResponseFailed(interceptedRequest); } else { var interceptedResponse = new InterceptedResponse(_logger.ForContext <IInterceptedResponse>(), response); immediateResponse = _responseInterceptor.OnResponseReceived(interceptedRequest, interceptedResponse); if (immediateResponse == null) { return(_httpResponseMessageBuilder.BuildFromConnectorResponse(interceptedResponse, forwardOnPremiseTargetErrorResponse, request.RequestId)); } } if (immediateResponse != null) { immediateResponse.RequestMessage = message; } return(immediateResponse ?? _httpResponseMessageBuilder.BuildFromConnectorResponse(null, forwardOnPremiseTargetErrorResponse, request.RequestId)); } catch (Exception ex) { _logger.Error(ex, "Error while executing the response interceptor. type-name={InterceptorType}, request-id={RequestId}", _requestInterceptor?.GetType().Name, request.RequestId); return(null); } }