public async Task AddsDFSHeaderWhenSendingARequest() { //Arrange var requestUrl = $"https://someurl.com"; var httpContextAccessor = A.Fake <IHttpContextAccessor>(); httpContextAccessor.HttpContext = new DefaultHttpContext(); var headerName = "X-Dfc-Composite-Request"; var headerValue1 = requestUrl; httpContextAccessor.HttpContext.Request.Headers.Add(headerName, headerValue1); var httpRequestChildMessage = new HttpRequestMessage(HttpMethod.Get, requestUrl); using (var handler = new CompositeRequestDelegatingHandler()) { handler.InnerHandler = new StatusOkDelegatingHandler(); //Act var invoker = new HttpMessageInvoker(handler); await invoker.SendAsync(httpRequestChildMessage, CancellationToken.None); //Assert Assert.Single(httpRequestChildMessage.Headers); Assert.True(httpRequestChildMessage.Headers.Contains(headerName)); httpRequestChildMessage.Dispose(); invoker.Dispose(); } }
public void Dispose() { if (_shouldDicpose && !HttpClientProvider.IsCached(_client)) { _client.Dispose(); } }
protected virtual void Dispose(bool disposing) { if (!_disposed) { _disposed = true; _messageInvoker.Dispose(); } }
private void OnAppDisposing() { if (!_disposed) { _messageInvoker.Dispose(); _disposed = true; } }
public void Cleanup() { _invoker.Dispose(); _handler.Dispose(); _listener.Dispose(); _serverTask.GetAwaiter().GetResult(); _serverCert.Dispose(); }
protected override void Dispose(bool disposing) { if (disposing) { _client.Dispose(); } base.Dispose(disposing); }
protected override void Dispose(bool disposing) { if (disposing) { _httpMessageInvoker.Dispose(); _tokenClient.Dispose(); } base.Dispose(disposing); }
public void Dispose_DontDisposeHandler_HandlerNotDisposed() { var handler = new MockHandler(); var invoker = new HttpMessageInvoker(handler, false); invoker.Dispose(); Assert.Equal(0, handler.DisposeCount); Assert.Throws <ObjectDisposedException>(() => { Task t = invoker.SendAsync(new HttpRequestMessage(), CancellationToken.None); }); Assert.Equal(0, handler.SendAsyncCount); }
public void Dispose_DontDisposeHandler_HandlerNotDisposed() { var handler = new MockHandler(); var invoker = new HttpMessageInvoker(handler, false); invoker.Dispose(); Assert.Equal(0, handler.DisposeCount); Assert.Throws<ObjectDisposedException>(() => { Task t = invoker.SendAsync(new HttpRequestMessage(), CancellationToken.None); }); Assert.Equal(0, handler.SendAsyncCount); }
public async Task WhenShellAuthenticatedPassOnToken() { //Arrange var path1 = "path1"; var path2 = "path2"; var requestUrl = $"https://someurl.com/{path1}"; //Create fakes pathLocator = A.Fake <IPathLocator>(); httpContextAccessor = A.Fake <IHttpContextAccessor>(); compositeDataProtectionDataProvider = A.Fake <ICompositeDataProtectionDataProvider>(); //Fake calls A.CallTo(() => pathLocator.GetPath()).Returns(path1); A.CallTo(() => compositeDataProtectionDataProvider.Unprotect(A <string> .Ignored)).ReturnsLazily(x => x.Arguments.First().ToString()); A.CallTo(() => compositeDataProtectionDataProvider.Protect(A <string> .Ignored)).ReturnsLazily(x => x.Arguments.First().ToString()); //Set some headers on the incoming request httpContextAccessor.HttpContext = new DefaultHttpContext { User = new ClaimsPrincipal(new ClaimsIdentity(new List <Claim> { new Claim("bearer", "test") }, "mock")) }; httpContextAccessor.HttpContext.Request.Headers.Add(HeaderNames.Cookie, $"{Constants.DfcSession}=sessionId1;{path1}v1=value1;{path1}v2=value2;{path2}v3=value3;{path2}v4=value4"); httpContextAccessor.HttpContext.Session = new MockHttpSession(); //Create a get request that is used to send data to the child app var httpRequestChildMessage = new HttpRequestMessage(HttpMethod.Get, requestUrl); //Create handlers and set the inner handler handler = new CookieDelegatingHandler(httpContextAccessor, pathLocator, compositeDataProtectionDataProvider) { InnerHandler = new StatusOkDelegatingHandler(), }; //Act var invoker = new HttpMessageInvoker(handler); await invoker.SendAsync(httpRequestChildMessage, CancellationToken.None).ConfigureAwait(false); //Check that the values that are sent back are correct var headerValue = httpRequestChildMessage.Headers.Authorization; Assert.Equal("test", headerValue.Parameter); httpRequestChildMessage.Dispose(); invoker.Dispose(); }
public async Task CanCopyHeadersFromShellToChildApp() { //Arrange var path1 = "path1"; var path2 = "path2"; var requestUrl = $"https://someurl.com/{path1}"; //Create fakes pathLocator = A.Fake <IPathLocator>(); httpContextAccessor = A.Fake <IHttpContextAccessor>(); compositeDataProtectionDataProvider = A.Fake <ICompositeDataProtectionDataProvider>(); //Fake calls A.CallTo(() => pathLocator.GetPath()).Returns(path1); A.CallTo(() => compositeDataProtectionDataProvider.Unprotect(A <string> .Ignored)).ReturnsLazily(x => x.Arguments.First().ToString()); A.CallTo(() => compositeDataProtectionDataProvider.Protect(A <string> .Ignored)).ReturnsLazily(x => x.Arguments.First().ToString()); //Set some headers on the incoming request httpContextAccessor.HttpContext = new DefaultHttpContext(); httpContextAccessor.HttpContext.Request.Headers.Add(HeaderNames.Cookie, $"{path1}v1=value1;{path1}v2=value2;{path2}v3=value3;{path2}v4=value4"); //Create a get request that is used to send data to the child app var httpRequestChildMessage = new HttpRequestMessage(HttpMethod.Get, requestUrl); //Create handlers and set the inner handler handler = new CookieDelegatingHandler(httpContextAccessor, pathLocator, compositeDataProtectionDataProvider) { InnerHandler = new StatusOkDelegatingHandler(), }; //Act var invoker = new HttpMessageInvoker(handler); await invoker.SendAsync(httpRequestChildMessage, CancellationToken.None).ConfigureAwait(false); //Check that the child app has the correct number of headers based on the incoming request Assert.Single(httpRequestChildMessage.Headers); //Check that the values that are sent back are correct var headerValue = httpRequestChildMessage.Headers.First().Value.ToList(); Assert.Equal("v1=value1", headerValue.First()); Assert.Equal("v2=value2", headerValue.Last()); httpRequestChildMessage.Dispose(); invoker.Dispose(); }
public async Task ConnectAsync(Uri uri, HttpMessageInvoker?invoker, CancellationToken cancellationToken, ClientWebSocketOptions options) { bool disposeHandler = false; invoker ??= new HttpMessageInvoker(SetupHandler(options, out disposeHandler)); HttpResponseMessage?response = null; bool disposeResponse = false; bool tryDowngrade = false; try { while (true) { try { HttpRequestMessage request; if (!tryDowngrade && options.HttpVersion >= HttpVersion.Version20 || (options.HttpVersion == HttpVersion.Version11 && options.HttpVersionPolicy == HttpVersionPolicy.RequestVersionOrHigher)) { if (options.HttpVersion > HttpVersion.Version20 && options.HttpVersionPolicy != HttpVersionPolicy.RequestVersionOrLower) { throw new WebSocketException(WebSocketError.UnsupportedProtocol); } request = new HttpRequestMessage(HttpMethod.Connect, uri) { Version = HttpVersion.Version20 }; tryDowngrade = true; } else if (tryDowngrade || options.HttpVersion == HttpVersion.Version11) { request = new HttpRequestMessage(HttpMethod.Get, uri) { Version = HttpVersion.Version11 }; tryDowngrade = false; } else { throw new WebSocketException(WebSocketError.UnsupportedProtocol); } if (options._requestHeaders?.Count > 0) // use field to avoid lazily initializing the collection { foreach (string key in options.RequestHeaders) { request.Headers.TryAddWithoutValidation(key, options.RequestHeaders[key]); } } string?secValue = AddWebSocketHeaders(request, options); // Issue the request. CancellationTokenSource?linkedCancellation; CancellationTokenSource externalAndAbortCancellation; if (cancellationToken.CanBeCanceled) // avoid allocating linked source if external token is not cancelable { linkedCancellation = externalAndAbortCancellation = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, _abortSource.Token); } else { linkedCancellation = null; externalAndAbortCancellation = _abortSource; } using (linkedCancellation) { response = await invoker.SendAsync(request, externalAndAbortCancellation.Token).ConfigureAwait(false); externalAndAbortCancellation.Token.ThrowIfCancellationRequested(); // poll in case sends/receives in request/response didn't observe cancellation } ValidateResponse(response, secValue, options); break; } catch (HttpRequestException ex) when ((ex.Data.Contains("SETTINGS_ENABLE_CONNECT_PROTOCOL") || ex.Data.Contains("HTTP2_ENABLED")) && tryDowngrade && (options.HttpVersion == HttpVersion.Version11 || options.HttpVersionPolicy == HttpVersionPolicy.RequestVersionOrLower)) { } } // The SecWebSocketProtocol header is optional. We should only get it with a non-empty value if we requested subprotocols, // and then it must only be one of the ones we requested. If we got a subprotocol other than one we requested (or if we // already got one in a previous header), fail. Otherwise, track which one we got. string?subprotocol = null; if (response.Headers.TryGetValues(HttpKnownHeaderNames.SecWebSocketProtocol, out IEnumerable <string>?subprotocolEnumerableValues)) { Debug.Assert(subprotocolEnumerableValues is string[]); string[] subprotocolArray = (string[])subprotocolEnumerableValues; if (subprotocolArray.Length > 0 && !string.IsNullOrEmpty(subprotocolArray[0])) { if (options._requestedSubProtocols is not null) { foreach (string requestedProtocol in options._requestedSubProtocols) { if (requestedProtocol.Equals(subprotocolArray[0], StringComparison.OrdinalIgnoreCase)) { subprotocol = requestedProtocol; break; } } } if (subprotocol == null) { throw new WebSocketException( WebSocketError.UnsupportedProtocol, SR.Format(SR.net_WebSockets_AcceptUnsupportedProtocol, string.Join(", ", options.RequestedSubProtocols), string.Join(", ", subprotocolArray))); } } } // Because deflate options are negotiated we need a new object WebSocketDeflateOptions?negotiatedDeflateOptions = null; if (options.DangerousDeflateOptions is not null && response.Headers.TryGetValues(HttpKnownHeaderNames.SecWebSocketExtensions, out IEnumerable <string>?extensions)) { foreach (ReadOnlySpan <char> extension in extensions) { if (extension.TrimStart().StartsWith(ClientWebSocketDeflateConstants.Extension)) { negotiatedDeflateOptions = ParseDeflateOptions(extension, options.DangerousDeflateOptions); break; } } } // Get the response stream and wrap it in a web socket. Stream connectedStream = response.Content.ReadAsStream(); Debug.Assert(connectedStream.CanWrite); Debug.Assert(connectedStream.CanRead); WebSocket = WebSocket.CreateFromStream(connectedStream, new WebSocketCreationOptions { IsServer = false, SubProtocol = subprotocol, KeepAliveInterval = options.KeepAliveInterval, DangerousDeflateOptions = negotiatedDeflateOptions }); _negotiatedDeflateOptions = negotiatedDeflateOptions; } catch (Exception exc) { if (_state < WebSocketState.Closed) { _state = WebSocketState.Closed; } Abort(); disposeResponse = true; if (exc is WebSocketException || (exc is OperationCanceledException && cancellationToken.IsCancellationRequested)) { throw; } throw new WebSocketException(WebSocketError.Faulted, SR.net_webstatus_ConnectFailure, exc); } finally { if (response is not null) { if (options.CollectHttpResponseDetails) { HttpStatusCode = response.StatusCode; HttpResponseHeaders = new HttpResponseHeadersReadOnlyCollection(response.Headers); } if (disposeResponse) { response.Dispose(); } } // Disposing the handler will not affect any active stream wrapped in the WebSocket. if (disposeHandler) { invoker?.Dispose(); } } }
public void Tearown() { _httpMessageInvoker.Dispose(); _httpServer.Dispose(); }
protected override void Dispose(bool disposing) { (_tokenManager as IDisposable)?.Dispose(); _httpMessageInvoker.Dispose(); base.Dispose(disposing); }
public void Dispose() { invoker.Dispose(); }
public void TearDown() { invoker.Dispose(); }
/// <inheritdoc /> protected override void Dispose(bool disposing) { _httpMessageInvoker.Dispose(); base.Dispose(disposing); }
public void Dispose() { invoker.Dispose(); authenticationHandler.Dispose(); testHttpMessageHandler.Dispose(); }
public void Dispose() => _sender.Dispose();