Exemplo n.º 1
0
            public async Task <IssuedToken> GetTokenAsync(VssTraceActivity traceActivity)
            {
                IssuedToken token = null;

                try
                {
                    VssHttpEventSource.Log.IssuedTokenAcquiring(traceActivity, this.Provider);
                    if (this.Provider.InvokeRequired)
                    {
                        // Post to the UI thread using the scheduler. This may return a new task object which needs
                        // to be awaited, since once we get to the UI thread there may be nothing to do if someone else
                        // preempts us.

                        // The cancellation token source is used to handle race conditions between scheduling and
                        // waiting for the UI task to begin execution. The callback is responsible for disposing of
                        // the token source, since the thought here is that the callback will run eventually as the
                        // typical reason for not starting execution within the timeout is due to a deadlock with
                        // the scheduler being used.
                        var timerTask          = new TaskCompletionSource <Object>();
                        var timeoutTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(3));
                        timeoutTokenSource.Token.Register(() => timerTask.SetResult(null), false);

                        var uiTask = Task.Factory.StartNew((state) => PostCallback(state, timeoutTokenSource),
                                                           this,
                                                           this.CancellationToken,
                                                           TaskCreationOptions.None,
                                                           this.Provider.Credential.Scheduler).Unwrap();

                        var completedTask = await Task.WhenAny(timerTask.Task, uiTask).ConfigureAwait(false);

                        if (completedTask == uiTask)
                        {
                            token = uiTask.Result;
                        }
                    }
                    else
                    {
                        token = await this.Provider.OnGetTokenAsync(this.FailedToken, this.CancellationToken).ConfigureAwait(false);
                    }

                    CompletionSource.TrySetResult(token);
                    return(token);
                }
                catch (Exception exception)
                {
                    // Mark our completion source as failed so other waiters will get notified in all cases
                    CompletionSource.TrySetException(exception);
                    throw;
                }
                finally
                {
                    this.Provider.CurrentToken = token ?? this.FailedToken;
                    VssHttpEventSource.Log.IssuedTokenAcquired(traceActivity, this.Provider, token);
                }
            }
        /// <summary>
        /// Performs a token exchange using the specified authorization grant and client credentials.
        /// </summary>
        /// <param name="grant">The authorization grant for the token request</param>
        /// <param name="credential">The credentials to present to the secure token service as proof of identity</param>
        /// <param name="tokenParameters">An collection of additional parameters to provide for the token request</param>
        /// <param name="cancellationToken">A token for signalling cancellation</param>
        /// <returns>A <c>Task&lt;VssOAuthTokenResponse&gt;</c> which may be used to track progress of the token request</returns>
        public async Task <VssOAuthTokenResponse> GetTokenAsync(
            VssOAuthGrant grant,
            VssOAuthClientCredential credential,
            VssOAuthTokenParameters tokenParameters = null,
            CancellationToken cancellationToken     = default(CancellationToken))
        {
            VssTraceActivity traceActivity = VssTraceActivity.Current;

            using (HttpClient client = new HttpClient(CreateMessageHandler(this.AuthorizationUrl)))
            {
                var requestMessage = new HttpRequestMessage(HttpMethod.Post, this.AuthorizationUrl);
                requestMessage.Content = CreateRequestContent(grant, credential, tokenParameters);
                requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                if (VssClientHttpRequestSettings.Default.UseHttp11)
                {
                    requestMessage.Version = HttpVersion.Version11;
                }

                foreach (var headerVal in VssClientHttpRequestSettings.Default.UserAgent)
                {
                    if (!requestMessage.Headers.UserAgent.Contains(headerVal))
                    {
                        requestMessage.Headers.UserAgent.Add(headerVal);
                    }
                }

                using (var response = await client.SendAsync(requestMessage, cancellationToken: cancellationToken).ConfigureAwait(false))
                {
                    string correlationId = "Unknown";
                    if (response.Headers.TryGetValues("x-ms-request-id", out IEnumerable <string> requestIds))
                    {
                        correlationId = string.Join(",", requestIds);
                    }
                    VssHttpEventSource.Log.AADCorrelationID(correlationId);

                    if (IsValidTokenResponse(response))
                    {
                        return(await response.Content.ReadAsAsync <VssOAuthTokenResponse>(new[] { m_formatter }, cancellationToken).ConfigureAwait(false));
                    }
                    else
                    {
                        var responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

                        throw new VssServiceResponseException(response.StatusCode, responseContent, null);
                    }
                }
            }
        }
Exemplo n.º 3
0
        private void ApplyHeaders(HttpRequestMessage request)
        {
            if (this.Settings.ApplyTo(request))
            {
                VssTraceActivity activity = request.GetActivity();
                if (activity != null &&
                    activity != VssTraceActivity.Empty &&
                    !request.Headers.Contains(HttpHeaders.TfsSessionHeader))
                {
                    request.Headers.Add(HttpHeaders.TfsSessionHeader, activity.Id.ToString("D"));
                }

                request.Headers.ExpectContinue = this.ExpectContinue;
            }
        }
Exemplo n.º 4
0
 public GetTokenOperation(
     VssTraceActivity activity,
     IssuedTokenProvider provider,
     IssuedToken failedToken,
     CancellationToken cancellationToken,
     DisposableTaskCompletionSource <IssuedToken> completionSource,
     Boolean ownsCompletionSource = false)
 {
     this.Provider             = provider;
     this.ActivityId           = activity?.Id ?? Guid.Empty;
     this.FailedToken          = failedToken;
     this.CancellationToken    = cancellationToken;
     this.CompletionSource     = completionSource;
     this.OwnsCompletionSource = ownsCompletionSource;
 }
Exemplo n.º 5
0
 protected async Task <T> SendAsync <T>(
     HttpMethod method,
     IEnumerable <KeyValuePair <String, String> > additionalHeaders,
     Guid locationId,
     Object routeValues         = null,
     ApiResourceVersion version = null,
     HttpContent content        = null,
     IEnumerable <KeyValuePair <String, String> > queryParameters = null,
     Object userState = null,
     CancellationToken cancellationToken = default(CancellationToken),
     Func <HttpResponseMessage, CancellationToken, Task <T> > processResponse = null)
 {
     using (VssTraceActivity.GetOrCreate().EnterCorrelationScope())
         using (HttpRequestMessage requestMessage = await CreateRequestMessageAsync(method, additionalHeaders, locationId, routeValues, version, content, queryParameters, userState, cancellationToken).ConfigureAwait(false))
         {
             return(await SendAsync <T>(requestMessage, userState, cancellationToken, processResponse).ConfigureAwait(false));
         }
 }
Exemplo n.º 6
0
            public async Task <IssuedToken> WaitForTokenAsync(
                VssTraceActivity traceActivity,
                CancellationToken cancellationToken)
            {
                IssuedToken token = null;

                try
                {
                    VssHttpEventSource.Log.IssuedTokenWaitStart(traceActivity, this.Provider, this.ActivityId);
                    token = await Task.Factory.ContinueWhenAll <IssuedToken>(new Task[] { CompletionSource.Task }, (x) => CompletionSource.Task.Result, cancellationToken).ConfigureAwait(false);
                }
                finally
                {
                    VssHttpEventSource.Log.IssuedTokenWaitStop(traceActivity, this.Provider, token);
                }

                return(token);
            }
Exemplo n.º 7
0
        /// <summary>
        /// Creates a token provider for the configured issued token credentials.
        /// </summary>
        /// <param name="serverUrl">The targeted server</param>
        /// <param name="webResponse">The failed web response</param>
        /// <param name="failedToken">The failed token</param>
        /// <returns>A provider for retrieving tokens for the configured credential</returns>
        internal IssuedTokenProvider CreateTokenProvider(
            Uri serverUrl,
            IHttpResponse webResponse,
            IssuedToken failedToken)
        {
            ArgumentUtility.CheckForNull(serverUrl, "serverUrl");

            IssuedTokenProvider tokenProvider = null;
            VssTraceActivity    traceActivity = VssTraceActivity.Current;

            lock (m_thisLock)
            {
                tokenProvider = m_currentProvider;
                if (tokenProvider == null || !tokenProvider.IsAuthenticationChallenge(webResponse))
                {
                    // Prefer federated authentication over Windows authentication.
                    if (m_federatedCredential != null && m_federatedCredential.IsAuthenticationChallenge(webResponse))
                    {
                        if (tokenProvider != null)
                        {
                            VssHttpEventSource.Log.IssuedTokenProviderRemoved(traceActivity, tokenProvider);
                        }

                        // TODO: This needs to be refactored or renamed to be more generic ...
                        this.TryGetValidAdalToken(m_federatedCredential.Prompt);

                        tokenProvider = m_federatedCredential.CreateTokenProvider(serverUrl, webResponse, failedToken);

                        if (tokenProvider != null)
                        {
                            VssHttpEventSource.Log.IssuedTokenProviderCreated(traceActivity, tokenProvider);
                        }
                    }

                    m_currentProvider = tokenProvider;
                }

                return(tokenProvider);
            }
        }
Exemplo n.º 8
0
        /// <summary>
        /// Handles the authentication hand-shake for a Visual Studio service.
        /// </summary>
        /// <param name="request">The HTTP request message</param>
        /// <param name="cancellationToken">The cancellation token used for cooperative cancellation</param>
        /// <returns>A new <c>Task&lt;HttpResponseMessage&gt;</c> which wraps the response from the remote service</returns>
        protected override async Task <HttpResponseMessage> SendAsync(
            HttpRequestMessage request,
            CancellationToken cancellationToken)
        {
            VssTraceActivity traceActivity = VssTraceActivity.Current;

            var traceInfo = VssHttpMessageHandlerTraceInfo.GetTraceInfo(request);

            traceInfo?.TraceHandlerStartTime();

            if (!m_appliedClientCertificatesToTransportHandler &&
                request.RequestUri.Scheme == "https")
            {
                HttpClientHandler httpClientHandler = m_transportHandler as HttpClientHandler;
                if (httpClientHandler != null &&
                    this.Settings.ClientCertificateManager != null &&
                    this.Settings.ClientCertificateManager.ClientCertificates != null &&
                    this.Settings.ClientCertificateManager.ClientCertificates.Count > 0)
                {
                    httpClientHandler.ClientCertificates.AddRange(this.Settings.ClientCertificateManager.ClientCertificates);
                }
                m_appliedClientCertificatesToTransportHandler = true;
            }

            if (!m_appliedServerCertificateValidationCallbackToTransportHandler &&
                request.RequestUri.Scheme == "https")
            {
                HttpClientHandler httpClientHandler = m_transportHandler as HttpClientHandler;
                if (httpClientHandler != null &&
                    this.Settings.ServerCertificateValidationCallback != null)
                {
                    httpClientHandler.ServerCertificateCustomValidationCallback = this.Settings.ServerCertificateValidationCallback;
                }
                m_appliedServerCertificateValidationCallbackToTransportHandler = true;
            }

            // The .NET Core 2.1 runtime switched its HTTP default from HTTP 1.1 to HTTP 2.
            // This causes problems with some versions of the Curl handler on Linux.
            // See GitHub issue https://github.com/dotnet/corefx/issues/32376
            if (Settings.UseHttp11)
            {
                request.Version = HttpVersion.Version11;
            }

            IssuedToken         token = null;
            IssuedTokenProvider provider;

            if (this.Credentials.TryGetTokenProvider(request.RequestUri, out provider))
            {
                token = provider.CurrentToken;
            }

            // Add ourselves to the message so the underlying token issuers may use it if necessary
            request.Options.Set(new HttpRequestOptionsKey <VssHttpMessageHandler>(VssHttpMessageHandler.PropertyName), this);

            Boolean                    succeeded = false;
            Boolean                    lastResponseDemandedProxyAuth = false;
            Int32                      retries  = m_maxAuthRetries;
            HttpResponseMessage        response = null;
            HttpResponseMessageWrapper responseWrapper;
            CancellationTokenSource    tokenSource = null;

            try
            {
                tokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);

                if (this.Settings.SendTimeout > TimeSpan.Zero)
                {
                    tokenSource.CancelAfter(this.Settings.SendTimeout);
                }

                do
                {
                    if (response != null)
                    {
                        response.Dispose();
                    }

                    ApplyHeaders(request);

                    // In the case of a Windows token, only apply it to the web proxy if it
                    // returned a 407 Proxy Authentication Required. If we didn't get this
                    // status code back, then the proxy (if there is one) is clearly working fine,
                    // so we shouldn't mess with its credentials.
                    ApplyToken(request, token, applyICredentialsToWebProxy: lastResponseDemandedProxyAuth);
                    lastResponseDemandedProxyAuth = false;

                    // The WinHttpHandler will chunk any content that does not have a computed length which is
                    // not what we want. By loading into a buffer up-front we bypass this behavior and there is
                    // no difference in the normal HttpClientHandler behavior here since this is what they were
                    // already doing.
                    await BufferRequestContentAsync(request, tokenSource.Token).ConfigureAwait(false);

                    traceInfo?.TraceBufferedRequestTime();

                    // ConfigureAwait(false) enables the continuation to be run outside any captured
                    // SyncronizationContext (such as ASP.NET's) which keeps things from deadlocking...
                    response = await m_messageInvoker.SendAsync(request, tokenSource.Token).ConfigureAwait(false);

                    traceInfo?.TraceRequestSendTime();

                    // Now buffer the response content if configured to do so. In general we will be buffering
                    // the response content in this location, except in the few cases where the caller has
                    // specified HttpCompletionOption.ResponseHeadersRead.
                    // Trace content type in case of error
                    await BufferResponseContentAsync(request, response, () => $"[ContentType: {response.Content.GetType().Name}]", tokenSource.Token).ConfigureAwait(false);

                    traceInfo?.TraceResponseContentTime();

                    responseWrapper = new HttpResponseMessageWrapper(response);

                    if (!this.Credentials.IsAuthenticationChallenge(responseWrapper))
                    {
                        // Validate the token after it has been successfully authenticated with the server.
                        if (provider != null)
                        {
                            provider.ValidateToken(token, responseWrapper);
                        }

                        // Make sure that once we can authenticate with the service that we turn off the
                        // Expect100Continue behavior to increase performance.
                        this.ExpectContinue = false;
                        succeeded           = true;
                        break;
                    }
                    else
                    {
                        // In the case of a Windows token, only apply it to the web proxy if it
                        // returned a 407 Proxy Authentication Required. If we didn't get this
                        // status code back, then the proxy (if there is one) is clearly working fine,
                        // so we shouldn't mess with its credentials.
                        lastResponseDemandedProxyAuth = responseWrapper.StatusCode == HttpStatusCode.ProxyAuthenticationRequired;

                        // Invalidate the token and ensure that we have the correct token provider for the challenge
                        // which we just received
                        VssHttpEventSource.Log.AuthenticationFailed(traceActivity, response);

                        if (provider != null)
                        {
                            provider.InvalidateToken(token);
                        }

                        // Ensure we have an appropriate token provider for the current challenge
                        provider = this.Credentials.CreateTokenProvider(request.RequestUri, responseWrapper, token);

                        // Make sure we don't invoke the provider in an invalid state
                        if (provider == null)
                        {
                            VssHttpEventSource.Log.IssuedTokenProviderNotFound(traceActivity);
                            break;
                        }
                        else if (provider.GetTokenIsInteractive && this.Credentials.PromptType == CredentialPromptType.DoNotPrompt)
                        {
                            VssHttpEventSource.Log.IssuedTokenProviderPromptRequired(traceActivity, provider);
                            break;
                        }

                        // If the user has already tried once but still unauthorized, stop retrying. The main scenario for this condition
                        // is a user typed in a valid credentials for a hosted account but the associated identity does not have
                        // access. We do not want to continually prompt 3 times without telling them the failure reason. In the
                        // next release we should rethink about presenting user the failure and options between retries.
                        IEnumerable <String> headerValues;
                        Boolean hasAuthenticateError =
                            response.Headers.TryGetValues(HttpHeaders.VssAuthenticateError, out headerValues) &&
                            !String.IsNullOrEmpty(headerValues.FirstOrDefault());

                        if (retries == 0 || (retries < m_maxAuthRetries && hasAuthenticateError))
                        {
                            break;
                        }

                        // Now invoke the provider and await the result
                        token = await provider.GetTokenAsync(token, tokenSource.Token).ConfigureAwait(false);

                        // I always see 0 here, but the method above could take more time so keep for now
                        traceInfo?.TraceGetTokenTime();

                        // If we just received a token, lets ask the server for the VSID
                        request.Headers.Add(HttpHeaders.VssUserData, String.Empty);

                        retries--;
                    }
                }while (retries >= 0);

                if (traceInfo != null)
                {
                    traceInfo.TokenRetries = m_maxAuthRetries - retries;
                }

                // We're out of retries and the response was an auth challenge -- then the request was unauthorized
                // and we will throw a strongly-typed exception with a friendly error message.
                if (!succeeded && response != null && this.Credentials.IsAuthenticationChallenge(responseWrapper))
                {
                    String message = null;
                    IEnumerable <String> serviceError;

                    if (response.Headers.TryGetValues(HttpHeaders.TfsServiceError, out serviceError))
                    {
                        message = UriUtility.UrlDecode(serviceError.FirstOrDefault());
                    }
                    else
                    {
                        message = CommonResources.VssUnauthorized(request.RequestUri.GetLeftPart(UriPartial.Authority));
                    }

                    // Make sure we do not leak the response object when raising an exception
                    if (response != null)
                    {
                        response.Dispose();
                    }

                    VssHttpEventSource.Log.HttpRequestUnauthorized(traceActivity, request, message);
                    VssUnauthorizedException unauthorizedException = new VssUnauthorizedException(message);

                    if (provider != null)
                    {
                        unauthorizedException.Data.Add(CredentialsType, provider.CredentialType);
                    }

                    throw unauthorizedException;
                }

                return(response);
            }
            catch (OperationCanceledException ex)
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    VssHttpEventSource.Log.HttpRequestCancelled(traceActivity, request);
                    throw;
                }
                else
                {
                    VssHttpEventSource.Log.HttpRequestTimedOut(traceActivity, request, this.Settings.SendTimeout);
                    throw new TimeoutException(CommonResources.HttpRequestTimeout(this.Settings.SendTimeout), ex);
                }
            }
            finally
            {
                // We always dispose of the token source since otherwise we leak resources if there is a timer pending
                if (tokenSource != null)
                {
                    tokenSource.Dispose();
                }

                traceInfo?.TraceTrailingTime();
            }
        }
Exemplo n.º 9
0
        protected override async Task <HttpResponseMessage> SendAsync(
            HttpRequestMessage request,
            CancellationToken cancellationToken)
        {
            Int32 attempt = 1;
            HttpResponseMessage  response      = null;
            HttpRequestException exception     = null;
            VssTraceActivity     traceActivity = VssTraceActivity.Current;

            // Allow overriding default retry options per request
            VssHttpRetryOptions retryOptions = m_retryOptions;
            object retryOptionsObject;

            if (request.Options.TryGetValue(HttpRetryOptionsKey, out retryOptionsObject)) // NETSTANDARD compliant, TryGetValue<T> is not
            {
                // Fallback to default options if object of unexpected type was passed
                retryOptions = retryOptionsObject as VssHttpRetryOptions ?? m_retryOptions;
            }

            TimeSpan minBackoff  = retryOptions.MinBackoff;
            Int32    maxAttempts = retryOptions.MaxRetries + 1;

            IVssHttpRetryInfo retryInfo = null;
            object            retryInfoObject;

            if (request.Options.TryGetValue(HttpRetryInfoKey, out retryInfoObject)) // NETSTANDARD compliant, TryGetValue<T> is not
            {
                retryInfo = retryInfoObject as IVssHttpRetryInfo;
            }

            if (IsLowPriority(request))
            {
                // Increase the backoff and retry count, low priority requests can be retried many times if the server is busy.
                minBackoff  = TimeSpan.FromSeconds(minBackoff.TotalSeconds * 2);
                maxAttempts = maxAttempts * 10;
            }

            TimeSpan backoff = minBackoff;

            while (attempt <= maxAttempts)
            {
                // Reset the exception so we don't have a lingering variable
                exception = null;

                Boolean            canRetry           = false;
                SocketError?       socketError        = null;
                HttpStatusCode?    statusCode         = null;
                WebExceptionStatus?webExceptionStatus = null;
                WinHttpErrorCode?  winHttpErrorCode   = null;
                CurlErrorCode?     curlErrorCode      = null;
                string             afdRefInfo         = null;
                try
                {
                    if (attempt == 1)
                    {
                        retryInfo?.InitialAttempt(request);
                    }

                    response = await base.SendAsync(request, cancellationToken).ConfigureAwait(false);

                    if (attempt > 1)
                    {
                        TraceHttpRequestSucceededWithRetry(traceActivity, response, attempt);
                    }

                    // Verify the response is successful or the status code is one that may be retried.
                    if (response.IsSuccessStatusCode)
                    {
                        break;
                    }
                    else
                    {
                        statusCode = response.StatusCode;
                        afdRefInfo = response.Headers.TryGetValues(HttpHeaders.AfdResponseRef, out var headers) ? headers.First() : null;
                        canRetry   = m_retryOptions.IsRetryableResponse(response);
                    }
                }
                catch (HttpRequestException ex)
                {
                    exception = ex;
                    canRetry  = VssNetworkHelper.IsTransientNetworkException(exception, m_retryOptions, out statusCode, out webExceptionStatus, out socketError, out winHttpErrorCode, out curlErrorCode);
                }
                catch (TimeoutException)
                {
                    throw;
                }

                if (attempt < maxAttempts && canRetry)
                {
                    backoff = BackoffTimerHelper.GetExponentialBackoff(attempt, minBackoff, m_retryOptions.MaxBackoff, m_retryOptions.BackoffCoefficient);
                    retryInfo?.Retry(backoff);
                    TraceHttpRequestRetrying(traceActivity, request, attempt, backoff, statusCode, webExceptionStatus, socketError, winHttpErrorCode, curlErrorCode, afdRefInfo);
                }
                else
                {
                    if (attempt < maxAttempts)
                    {
                        if (exception == null)
                        {
                            TraceHttpRequestFailed(traceActivity, request, statusCode != null ? statusCode.Value : (HttpStatusCode)0, afdRefInfo);
                        }
                        else
                        {
                            TraceHttpRequestFailed(traceActivity, request, exception);
                        }
                    }
                    else
                    {
                        TraceHttpRequestFailedMaxAttempts(traceActivity, request, attempt, statusCode, webExceptionStatus, socketError, winHttpErrorCode, curlErrorCode, afdRefInfo);
                    }
                    break;
                }

                // Make sure to dispose of this so we don't keep the connection open
                if (response != null)
                {
                    response.Dispose();
                }

                attempt++;
                TraceRaw(request, 100011, TraceLevel.Error,
                         "{{ \"Client\":\"{0}\", \"Endpoint\":\"{1}\", \"Attempt\":{2}, \"MaxAttempts\":{3}, \"Backoff\":{4} }}",
                         m_clientName,
                         request.RequestUri.Host,
                         attempt,
                         maxAttempts,
                         backoff.TotalMilliseconds);
                await Task.Delay(backoff, cancellationToken).ConfigureAwait(false);
            }

            if (exception != null)
            {
                throw exception;
            }

            return(response);
        }
Exemplo n.º 10
0
 protected virtual void TraceHttpRequestRetrying(VssTraceActivity activity, HttpRequestMessage request, Int32 attempt, TimeSpan backoffDuration, HttpStatusCode?httpStatusCode, WebExceptionStatus?webExceptionStatus, SocketError?socketErrorCode, WinHttpErrorCode?winHttpErrorCode, CurlErrorCode?curlErrorCode, string afdRefInfo)
 {
     VssHttpEventSource.Log.HttpRequestRetrying(activity, request, attempt, backoffDuration, httpStatusCode, webExceptionStatus, socketErrorCode, winHttpErrorCode, curlErrorCode, afdRefInfo);
 }
Exemplo n.º 11
0
 protected virtual void TraceHttpRequestSucceededWithRetry(VssTraceActivity activity, HttpResponseMessage response, Int32 attempt)
 {
     VssHttpEventSource.Log.HttpRequestSucceededWithRetry(activity, response, attempt);
 }
Exemplo n.º 12
0
 protected virtual void TraceHttpRequestFailedMaxAttempts(VssTraceActivity activity, HttpRequestMessage request, Int32 attempt, HttpStatusCode?httpStatusCode, WebExceptionStatus?webExceptionStatus, SocketError?socketErrorCode, WinHttpErrorCode?winHttpErrorCode, CurlErrorCode?curlErrorCode, string afdRefInfo)
 {
     VssHttpEventSource.Log.HttpRequestFailedMaxAttempts(activity, request, attempt, httpStatusCode, webExceptionStatus, socketErrorCode, winHttpErrorCode, curlErrorCode, afdRefInfo);
 }
Exemplo n.º 13
0
 protected virtual void TraceHttpRequestFailed(VssTraceActivity activity, HttpRequestMessage request, Exception exception)
 {
     VssHttpEventSource.Log.HttpRequestFailed(activity, request, exception);
 }
Exemplo n.º 14
0
 protected virtual void TraceHttpRequestFailed(VssTraceActivity activity, HttpRequestMessage request, HttpStatusCode statusCode, string afdRefInfo)
 {
     VssHttpEventSource.Log.HttpRequestFailed(activity, request, statusCode, afdRefInfo);
 }
Exemplo n.º 15
0
        /// <summary>
        /// Retrieves a token for the credentials.
        /// </summary>
        /// <param name="failedToken">The token which previously failed authentication, if available</param>
        /// <param name="cancellationToken">The <c>CancellationToken</c>that will be assigned to the new task</param>
        /// <returns>A security token for the current credentials</returns>
        public async Task <IssuedToken> GetTokenAsync(
            IssuedToken failedToken,
            CancellationToken cancellationToken)
        {
            IssuedToken      currentToken      = this.CurrentToken;
            VssTraceActivity traceActivity     = VssTraceActivity.Current;
            Stopwatch        aadAuthTokenTimer = Stopwatch.StartNew();

            try
            {
                VssHttpEventSource.Log.AuthenticationStart(traceActivity);

                if (currentToken != null)
                {
                    VssHttpEventSource.Log.IssuedTokenRetrievedFromCache(traceActivity, this, currentToken);
                    return(currentToken);
                }
                else
                {
                    GetTokenOperation operation = null;
                    try
                    {
                        GetTokenOperation operationInProgress;
                        operation = CreateOperation(traceActivity, failedToken, cancellationToken, out operationInProgress);
                        if (operationInProgress == null)
                        {
                            return(await operation.GetTokenAsync(traceActivity).ConfigureAwait(false));
                        }
                        else
                        {
                            return(await operationInProgress.WaitForTokenAsync(traceActivity, cancellationToken).ConfigureAwait(false));
                        }
                    }
                    finally
                    {
                        lock (m_thisLock)
                        {
                            m_operations.Remove(operation);
                        }

                        operation?.Dispose();
                    }
                }
            }
            finally
            {
                VssHttpEventSource.Log.AuthenticationStop(traceActivity);

                aadAuthTokenTimer.Stop();
                TimeSpan getTokenTime = aadAuthTokenTimer.Elapsed;

                if (getTokenTime.TotalSeconds >= c_slowTokenAcquisitionTimeInSeconds)
                {
                    // It may seem strange to pass the string value of TotalSeconds into this method, but testing
                    // showed that ETW is persnickety when you register a method in an EventSource that doesn't
                    // use strings or integers as its parameters. It is easier to simply give the method a string
                    // than figure out to get ETW to reliably accept a double or TimeSpan.
                    VssHttpEventSource.Log.AuthorizationDelayed(getTokenTime.TotalSeconds.ToString());
                }
            }
        }