Пример #1
0
        /// <summary>
        /// Invoked when an election timeout occurred. The state will change to <see cref="Candidate"/>.
        /// </summary>
        private void ElectionTimedOut()
        {
            // cancel the timer to prevent a double trigger
            watchDog.Cancel();

            // start an election
            Server.StartElection();
        }
        protected void StartNewHeartbeat()
        {
            if (string.IsNullOrEmpty(ConnectionInfo?.HeartbeatUrl))
            {
                return;
            }

            heartbeatTimer?.Cancel();

#if !NETSTANDARD1_1
            heartbeatTimer = PclExportClient.Instance.CreateTimer(Heartbeat,
                                                                  TimeSpan.FromMilliseconds(ConnectionInfo.HeartbeatIntervalMs), this);
#endif
        }
Пример #3
0
        protected void StartNewHeartbeat()
        {
            if (ConnectionInfo == null || string.IsNullOrEmpty(ConnectionInfo.HeartbeatUrl))
            {
                return;
            }

            if (heartbeatTimer != null)
            {
                heartbeatTimer.Cancel();
            }

            heartbeatTimer = PclExportClient.Instance.CreateTimer(Heartbeat,
                                                                  TimeSpan.FromMilliseconds(ConnectionInfo.HeartbeatIntervalMs), this);
        }
 private void CancelExistingTimer()
 {
     _timer?.Cancel();
 }
Пример #5
0
        private async Task <T> SendWebRequestAsync <T>(string httpMethod, string absoluteUrl, object request, CancellationToken token, bool recall = false)
        {
            if (httpMethod == null)
            {
                throw new ArgumentNullException(nameof(httpMethod));
            }

            this.PopulateRequestMetadata(request);

            var requestUri     = absoluteUrl;
            var hasQueryString = request != null && !HttpUtils.HasRequestBody(httpMethod);

            if (hasQueryString)
            {
                var queryString = QueryStringSerializer.SerializeToString(request);
                if (!string.IsNullOrEmpty(queryString))
                {
                    requestUri += "?" + queryString;
                }
            }

            var webReq = this.CreateHttpWebRequest(requestUri);

            if (webReq != null && Proxy != null)
            {
                webReq.Proxy = Proxy;
            }

            var    timedOut = false;
            ITimer timer    = null;

            timer = PclExportClient.Instance.CreateTimer(state =>
            {
                timedOut = true;
                webReq?.Abort();
                webReq = null;
                timer?.Cancel();
                timer = null;
            }, this.Timeout.GetValueOrDefault(DefaultTimeout), this);

            Exception ResolveException(Exception ex)
            {
                if (token.IsCancellationRequested)
                {
                    return(new OperationCanceledException(token));
                }
                if (timedOut)
                {
                    return(PclExportClient.Instance.CreateTimeoutException(ex, "The request timed out"));
                }
                return(ex);
            }

            bool            returningWebResponse = false;
            HttpWebResponse webRes = null;

            T Complete(T response)
            {
                timer.Cancel();
                PclExportClient.Instance.SynchronizeCookies(this);
                ResultsFilterResponse?.Invoke(webRes, response, httpMethod, absoluteUrl, request);
                return(response);
            }

            webReq.Accept = ContentType;

            if (this.EmulateHttpViaPost)
            {
                webReq.Method = "POST";
                webReq.Headers[HttpHeaders.XHttpMethodOverride] = httpMethod;
            }
            else
            {
                webReq.Method = httpMethod;
            }

            PclExportClient.Instance.AddHeader(webReq, Headers);
            PclExport.Instance.Config(webReq, userAgent: UserAgent);

            if (this.authInfo != null && !string.IsNullOrEmpty(this.UserName))
            {
                webReq.AddAuthInfo(this.UserName, this.Password, authInfo);
            }
            else if (this.BearerToken != null)
            {
                webReq.Headers[HttpHeaders.Authorization] = "Bearer " + this.BearerToken;
            }
            else if (this.Credentials != null)
            {
                webReq.Credentials = this.Credentials;
            }
            else if (this.AlwaysSendBasicAuthHeader)
            {
                webReq.AddBasicAuth(this.UserName, this.Password);
            }

            if (!DisableAutoCompression)
            {
                PclExport.Instance.AddCompression(webReq);
            }

            ApplyWebRequestFilters(webReq);

            try
            {
                if (HttpUtils.HasRequestBody(webReq.Method))
                {
                    webReq.ContentType = ContentType;

                    if (RequestCompressionType != null)
                    {
                        webReq.Headers[HttpHeaders.ContentEncoding] = RequestCompressionType;
                    }

                    using var requestStream = await webReq.GetRequestStreamAsync().ConfigAwait();

                    token.ThrowIfCancellationRequested();
                    if (request != null)
                    {
                        StreamSerializer(null, request, requestStream);
                    }
                }
            }
            catch (Exception ex)
            {
                if (Log.IsDebugEnabled)
                {
                    Log.Debug($"Error Sending Request: {ex.Message}", ex);
                }

                throw HandleResponseError <T>(ResolveException(ex), requestUri, request);
            }

            try
            {
                webRes = (HttpWebResponse)await webReq.GetResponseAsync().ConfigAwait();

                {
                    token.ThrowIfCancellationRequested();

                    ApplyWebResponseFilters(webRes);

                    returningWebResponse = typeof(T) == typeof(HttpWebResponse);
                    if (returningWebResponse)
                    {
                        return(Complete((T)(object)webRes));
                    }

                    var responseStream = webRes.ResponseStream();

                    var responseBodyLength = webRes.ContentLength;
                    var bufferRead         = new byte[BufferSize];

                    var totalRead = 0;
                    int read;
                    var ms = MemoryStreamFactory.GetStream();

                    while ((read = await responseStream.ReadAsync(bufferRead, 0, bufferRead.Length, token).ConfigAwait()) != 0)
                    {
                        await ms.WriteAsync(bufferRead, 0, read, token).ConfigAwait();

                        totalRead += read;
                        OnDownloadProgress?.Invoke(totalRead, responseBodyLength);
                    }

                    try
                    {
                        ms.Position = 0;
                        if (typeof(T) == typeof(Stream))
                        {
                            return(Complete((T)(object)ms));
                        }
                        else
                        {
                            var stream = ms;
                            try
                            {
                                if (typeof(T) == typeof(string))
                                {
                                    return(Complete((T)(object)await stream.ReadToEndAsync().ConfigAwait()));
                                }
                                else if (typeof(T) == typeof(byte[]))
                                {
                                    return(Complete((T)(object)stream.ToArray()));
                                }
                                else
                                {
                                    return(Complete((T)this.StreamDeserializer(typeof(T), stream)));
                                }
                            }
                            finally
                            {
                                if (stream.CanRead)
                                {
                                    stream.Dispose(); // Not yet disposed, but could've been.
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        if (Log.IsDebugEnabled)
                        {
                            Log.Debug($"Error Reading Response Error: {ex.Message}", ex);
                        }

                        throw;
                    }
                    finally
                    {
                        responseStream.Close();
                    }
                }
            }
            catch (Exception ex)
            {
                var webEx                 = ex as WebException;
                var firstCall             = !recall;
                var hasRefreshTokenCookie = this.CookieContainer.GetRefreshTokenCookie(BaseUri) != null;
                var hasRefreshToken       = RefreshToken != null || hasRefreshTokenCookie;

                if (firstCall && WebRequestUtils.ShouldAuthenticate(webEx,
                                                                    (!string.IsNullOrEmpty(UserName) && !string.IsNullOrEmpty(Password)) ||
                                                                    Credentials != null ||
                                                                    BearerToken != null ||
                                                                    hasRefreshToken ||
                                                                    OnAuthenticationRequired != null))
                {
                    try
                    {
                        if (hasRefreshToken)
                        {
                            var refreshRequest = new GetAccessToken {
                                RefreshToken   = RefreshToken,
                                UseTokenCookie = UseTokenCookie,
                            };
                            var uri = this.RefreshTokenUri ?? this.BaseUri.CombineWith(refreshRequest.ToPostUrl());

                            GetAccessTokenResponse tokenResponse;
                            try
                            {
                                tokenResponse = (await uri.PostJsonToUrlAsync(refreshRequest, requestFilter: req => {
                                    if (UseTokenCookie || hasRefreshTokenCookie)
                                    {
                                        req.CookieContainer = CookieContainer;
                                    }
                                }, token: token).ConfigAwait()).FromJson <GetAccessTokenResponse>();
                            }
                            catch (WebException refreshEx)
                            {
                                var webServiceEx = ServiceClientBase.ToWebServiceException(refreshEx,
                                                                                           stream => StreamDeserializer(typeof(T), stream),
                                                                                           ContentType);

                                if (webServiceEx != null)
                                {
                                    throw new RefreshTokenException(webServiceEx);
                                }

                                throw new RefreshTokenException(refreshEx.Message, refreshEx);
                            }

                            var accessToken   = tokenResponse?.AccessToken;
                            var refreshClient = webReq = (HttpWebRequest)WebRequest.Create(requestUri);
                            var tokenCookie   = this.CookieContainer.GetTokenCookie(BaseUri);

                            if (UseTokenCookie)
                            {
                                if (tokenCookie == null)
                                {
                                    throw new RefreshTokenException("Could not retrieve new AccessToken Cooke from: " + uri);
                                }

                                refreshClient.CookieContainer.SetTokenCookie(BaseUri, tokenCookie);
                            }
                            else
                            {
                                if (string.IsNullOrEmpty(accessToken))
                                {
                                    throw new RefreshTokenException("Could not retrieve new AccessToken from: " + uri);
                                }

                                if (tokenCookie != null)
                                {
                                    this.CookieContainer.SetTokenCookie(accessToken, BaseUri);
                                    refreshClient.CookieContainer.SetTokenCookie(BaseUri, accessToken);
                                }
                                else
                                {
                                    refreshClient.AddBearerToken(this.BearerToken = accessToken);
                                }
                            }

                            return(await SendWebRequestAsync <T>(httpMethod, absoluteUrl, request, token, recall : true).ConfigAwait());
                        }

                        OnAuthenticationRequired?.Invoke();

                        var newReq = (HttpWebRequest)WebRequest.Create(requestUri);

                        if (StoreCookies)
                        {
                            newReq.CookieContainer = CookieContainer;
                        }

                        HandleAuthException(ex, webReq);

                        return(await SendWebRequestAsync <T>(httpMethod, absoluteUrl, request, token, recall : true).ConfigAwait());
                    }
                    catch (WebServiceException)
                    {
                        throw;
                    }
                    catch (Exception /*subEx*/)
                    {
                        throw HandleResponseError <T>(ResolveException(ex), requestUri, request);
                    }
                }

                if (ExceptionFilter != null && webEx?.Response != null)
                {
                    var cachedResponse = ExceptionFilter(webEx, webEx.Response, requestUri, typeof(T));
                    if (cachedResponse is T variable)
                    {
                        return(variable);
                    }
                }

                throw HandleResponseError <T>(ResolveException(ex), requestUri, request);
            }
            finally
            {
                if (!returningWebResponse)
                {
                    webRes?.Dispose();
                }
            }
        }