public async Task <ReverseProxyResponse> Send(ICommunicationContext context, string target) { var proxyTargetUri = GetProxyTargetUri(context.PipelineData.SelectedResource.Results.Single(), target); var requestMessage = new HttpRequestMessage(new HttpMethod(context.Request.HttpMethod), proxyTargetUri) { Version = new Version(2, 0) }; PrepareRequestBody(context, requestMessage); PrepareRequestHeaders(context, requestMessage, _convertForwardedHeaders); var viaIdentifier = AppendViaHeaderToRequest(context, requestMessage); var cts = new CancellationTokenSource(); cts.CancelAfter(_timeout); var timeoutToken = cts.Token; ReverseProxyResponse reverseProxyResponse; try { _onSend?.Invoke(context, requestMessage); var httpClient = _httpClient(requestMessage.RequestUri.Host); var responseMessage = await httpClient.SendAsync( requestMessage, HttpCompletionOption.ResponseHeadersRead, timeoutToken ); reverseProxyResponse = new ReverseProxyResponse(requestMessage, responseMessage, viaIdentifier); cts.Dispose(); } catch (TaskCanceledException e) when(timeoutToken.IsCancellationRequested || e.CancellationToken == timeoutToken) { // Note we check both cancellation token because mono/fullfx/core don't have the same behaviour reverseProxyResponse = new ReverseProxyResponse(requestMessage, via: null, error: e, statusCode: 504); } catch (HttpRequestException e) { context.ServerErrors.Add(new Error { Exception = e, Title = $"Reverse Proxy failed to connect." }); reverseProxyResponse = new ReverseProxyResponse(requestMessage, via: null, error: e, statusCode: 502); } _onProxyResponse?.Invoke(reverseProxyResponse); return(reverseProxyResponse); }
public ReverseProxyOperationResult(ReverseProxyResponse response) : base(response.StatusCode) { ResponseResource = response; }