Beispiel #1
0
        public async Task <Uri> ListenToSingleRequestAndRespondAsync(
            int port,
            Func <Uri, MessageAndHttpCode> responseProducer,
            CancellationToken cancellationToken)
        {
            TestBeforeTopLevelCall?.Invoke();
            cancellationToken.ThrowIfCancellationRequested();

            HttpListener httpListener = null;

            try
            {
                string urlToListenTo = "http://localhost:" + port + "/";

                httpListener = new HttpListener();
                httpListener.Prefixes.Add(urlToListenTo);

                TestBeforeStart?.Invoke();

                httpListener.Start();
                _logger.Info("Listening for authorization code on " + urlToListenTo);

                using (cancellationToken.Register(() =>
                {
                    _logger.Warning("HttpListener stopped because cancellation was requested.");
                    TryStopListening(httpListener);
                }))
                {
                    TestBeforeGetContext?.Invoke();
                    HttpListenerContext context = await httpListener.GetContextAsync()
                                                  .ConfigureAwait(false);

                    cancellationToken.ThrowIfCancellationRequested();

                    Respond(responseProducer, context);
                    _logger.Verbose("HttpListner received a message on " + urlToListenTo);

                    // the request URL should now contain the auth code and pkce
                    return(context.Request.Url);
                }
            }
            // If cancellation is requested before GetContextAsync is called, then either
            // an ObjectDisposedException or an HttpListenerException is thrown.
            // But this is just cancellation...
            catch (Exception ex) when(ex is HttpListenerException || ex is ObjectDisposedException)
            {
                _logger.Info("HttpListenerException - cancellation requested? " + cancellationToken.IsCancellationRequested);
                cancellationToken.ThrowIfCancellationRequested();

                // if cancellation was not requested, propagate original ex
                throw;
            }
            finally
            {
                TryStopListening(httpListener);
            }
        }
Beispiel #2
0
        public async Task <Uri> ListenToSingleRequestAndRespondAsync(
            int port,
            string path,
            Func <Uri, MessageAndHttpCode> responseProducer,
            CancellationToken cancellationToken)
        {
            TestBeforeTopLevelCall?.Invoke();
            cancellationToken.ThrowIfCancellationRequested();

            HttpListener httpListener  = null;
            string       urlToListenTo = string.Empty;

            try
            {
                if (string.IsNullOrEmpty(path))
                {
                    path = "/";
                }
                else
                {
                    path = (path.StartsWith("/") ? path : "/" + path);
                }

                urlToListenTo = "http://localhost:" + port + path;

                if (!urlToListenTo.EndsWith("/"))
                {
                    urlToListenTo += "/";
                }

                httpListener = new HttpListener();
                httpListener.Prefixes.Add(urlToListenTo);

                TestBeforeStart?.Invoke(urlToListenTo);

                httpListener.Start();
                _logger.Info("Listening for authorization code on " + urlToListenTo);

                using (cancellationToken.Register(() =>
                {
                    _logger.Warning("HttpListener stopped because cancellation was requested.");
                    TryStopListening(httpListener);
                }))
                {
                    TestBeforeGetContext?.Invoke();
                    HttpListenerContext context = await httpListener.GetContextAsync()
                                                  .ConfigureAwait(false);

                    cancellationToken.ThrowIfCancellationRequested();

                    Respond(responseProducer, context);
                    _logger.Verbose("HttpListner received a message on " + urlToListenTo);

                    // the request URL should now contain the auth code and pkce
                    return(context.Request.Url);
                }
            }
            // If cancellation is requested before GetContextAsync is called, then either
            // an ObjectDisposedException or an HttpListenerException is thrown.
            // But this is just cancellation...
            catch (Exception ex) when(ex is HttpListenerException || ex is ObjectDisposedException)
            {
                _logger.Info("HttpListenerException - cancellation requested? " + cancellationToken.IsCancellationRequested);
                cancellationToken.ThrowIfCancellationRequested();

                if (ex is HttpListenerException)
                {
                    throw new MsalClientException(MsalError.HttpListenerError,
                                                  $"An HttpListenerException occurred while listening on {urlToListenTo} for the system browser to complete the login. " +
                                                  "Possible cause and mitigation: the app is unable to listen on the specified URL; " +
                                                  "run 'netsh http add iplisten 127.0.0.1' from the Admin command prompt.",
                                                  ex);
                }

                // if cancellation was not requested, propagate original ex
                throw;
            }
            finally
            {
                TryStopListening(httpListener);
            }
        }