コード例 #1
0
        internal async Task AddAuthHeader(AblyRequest request)
        {
            EnsureSecureConnection();

            if (request.Headers.ContainsKey("Authorization"))
            {
                request.Headers.Remove("Authorization");
            }

            if (AuthMethod == AuthMethod.Basic)
            {
                var authInfo = Convert.ToBase64String(Options.Key.GetBytes());
                request.Headers["Authorization"] = "Basic " + authInfo;
            }
            else
            {
                var currentValidToken = await GetCurrentValidTokenAndRenewIfNecessaryAsync();

                if (currentValidToken == null)
                {
                    throw new AblyException("Invalid token credentials: " + CurrentToken, 40100, HttpStatusCode.Unauthorized);
                }

                request.Headers["Authorization"] = "Bearer " + CurrentToken.Token.ToBase64();
            }
        }
コード例 #2
0
ファイル: AblyAuth.cs プロジェクト: selim1763/Lost-Library
        internal async Task AddAuthHeader(AblyRequest request)
        {
            EnsureSecureConnection();

            if (request.Headers.ContainsKey("Authorization"))
            {
                request.Headers.Remove("Authorization");
            }

            if (AuthMethod == AuthMethod.Basic)
            {
                var authInfo = Convert.ToBase64String(Options.Key.GetBytes());
                request.Headers["Authorization"] = "Basic " + authInfo;

                // (RSA7e) If clientId is provided in ClientOptions and RSA4 indicates that basic auth is to be used, then:
                if (Options.ClientId.IsNotEmpty())
                {
                    // (RSA7e2) For REST clients, all requests should include an X-Ably-ClientId header with value set to the clientId, Base64 encoded
                    request.Headers["X-Ably-ClientId"] = Options.ClientId.ToBase64();
                }
            }
            else
            {
                var currentValidToken = await GetCurrentValidTokenAndRenewIfNecessaryAsync();

                if (currentValidToken == null)
                {
                    throw new AblyException("Invalid token credentials: " + CurrentToken, 40100, HttpStatusCode.Unauthorized);
                }

                request.Headers["Authorization"] = "Bearer " + CurrentToken.Token.ToBase64();
            }
        }
コード例 #3
0
        private async Task <AblyResponse> CallAuthUrl(AuthOptions mergedOptions, TokenParams @params)
        {
            var url         = mergedOptions.AuthUrl;
            var protocol    = Options.UseBinaryProtocol == false ? Protocol.Json : Protocol.MsgPack;
            var authRequest = new AblyRequest(url.ToString(), mergedOptions.AuthMethod, protocol);

            if (mergedOptions.AuthMethod == HttpMethod.Get)
            {
                authRequest.AddQueryParameters(@params.ToRequestParams(mergedOptions.AuthParams));
            }
            else
            {
                authRequest.PostParameters = @params.ToRequestParams(mergedOptions.AuthParams);
            }

            authRequest.Headers            = authRequest.Headers.Merge(mergedOptions.AuthHeaders);
            authRequest.SkipAuthentication = true;
            AblyResponse response = await _rest.ExecuteRequest(authRequest);

            if (response.Type == ResponseType.Binary)
            {
                throw new AblyException(
                          new ErrorInfo(
                              string.Format("Content Type {0} is not supported by this client library",
                                            response.ContentType), 500));
            }

            return(response);
        }
コード例 #4
0
ファイル: AblyHttpClient.cs プロジェクト: ddrinka/ably-dotnet
        private HttpRequestMessage GetRequestMessage(AblyRequest request, string host)
        {
            var message = new HttpRequestMessage(request.Method, GetRequestUrl(request, host));

            foreach (var header in request.Headers)
            {
                message.Headers.TryAddWithoutValidation(header.Key, header.Value);
            }

            if (request.Protocol == Protocol.MsgPack)
            {
                message.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(GetHeaderValue(request.Protocol)));
            }

            //Always accept JSON
            message.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(GetHeaderValue(Protocol.Json)));
            if (message.Method == HttpMethod.Post)
            {
                if (request.PostParameters.Any() && request.RequestBody.Length == 0)
                {
                    message.Content = new FormUrlEncodedContent(request.PostParameters);
                }
                else
                {
                    var content = new ByteArrayContent(request.RequestBody);
                    content.Headers.ContentType = new MediaTypeHeaderValue(GetHeaderValue(request.Protocol));
                    message.Content             = content;
                }
            }

            return(message);
        }
コード例 #5
0
ファイル: AblyRest.cs プロジェクト: jeddawson/ably-dotnet
        /// <summary>/// Retrieves the ably service time/// </summary>
        /// <returns></returns>
        public async Task <DateTimeOffset> TimeAsync()
        {
            AblyRequest request = CreateGetRequest("/time");

            request.SkipAuthentication = true;
            List <long> response = await ExecuteRequest <List <long> >(request);

            return(response.First().FromUnixTimeInMilliseconds());
        }
コード例 #6
0
ファイル: AblyHttpClient.cs プロジェクト: ddrinka/ably-dotnet
        private string GetQuery(AblyRequest request)
        {
            var query = request.QueryParameters.ToQueryString();

            if (query.IsNotEmpty())
            {
                return("?" + query);
            }
            return(string.Empty);
        }
コード例 #7
0
ファイル: AblyRest.cs プロジェクト: jeddawson/ably-dotnet
        internal async Task <AblyResponse> ExecuteRequest(AblyRequest request)
        {
            Logger.Debug("Sending {0} request to {1}", request.Method, request.Url);

            if (request.SkipAuthentication == false)
            {
                await AblyAuth.AddAuthHeader(request);
            }

            try
            {
                MessageHandler.SetRequestBody(request);
                return(await ExecuteHttpRequest(request));
            }
            catch (AblyException ex)
            {
                if (Logger.IsDebug)
                {
                    Logger.Debug("Error Executing request. Message: " + ex.Message);
                }

                if (ex.ErrorInfo.IsUnAuthorizedError &&
                    ex.ErrorInfo.IsTokenError && AblyAuth.TokenRenewable)
                {
                    if (Logger.IsDebug)
                    {
                        Logger.Debug("Handling UnAuthorized Error and repeating request.");
                    }

                    await AblyAuth.AuthoriseAsync(null, new AuthOptions()
                    {
                        Force = true
                    });

                    await AblyAuth.AddAuthHeader(request);

                    return(await ExecuteHttpRequest(request));
                }
                throw;
            }
            catch (Exception ex)
            {
                if (Logger.IsDebug)
                {
                    Logger.Debug("Error Executing request. Message: " + ex.Message);
                }

                throw new AblyException(ex);
            }
        }
コード例 #8
0
        public Uri GetRequestUrl(AblyRequest request, string host = null)
        {
            if (host == null)
            {
                host = Options.Host;
            }

            string protocol = Options.IsSecure ? "https://" : "http://";

            if (request.Url.StartsWith("http"))
            {
                return(new Uri($"{request.Url}{GetQuery(request)}"));
            }

            return(new Uri($"{protocol}{host}{(Options.Port.HasValue ? ":" + Options.Port.Value : string.Empty)}{request.Url}{GetQuery(request)}"));
        }
コード例 #9
0
ファイル: AblyRest.cs プロジェクト: jeddawson/ably-dotnet
        internal async Task <PaginatedResult <T> > ExecutePaginatedRequest <T>(AblyRequest request, Func <HistoryRequestParams, Task <PaginatedResult <T> > > executeDataQueryRequest) where T : class
        {
            var response = await ExecuteRequest(request);

            if (Logger.IsDebug)
            {
                Logger.Debug("Response received. Status: " + response.StatusCode);
                Logger.Debug("Content type: " + response.ContentType);
                Logger.Debug("Encoding: " + response.Encoding);
                if (response.Body != null)
                {
                    Logger.Debug("Raw response (base64):" + response.Body.ToBase64());
                }
            }

            return(MessageHandler.ParsePaginatedResponse <T>(request, response, executeDataQueryRequest));
        }
コード例 #10
0
ファイル: AblyRest.cs プロジェクト: jeddawson/ably-dotnet
        internal async Task <T> ExecuteRequest <T>(AblyRequest request) where T : class
        {
            var response = await ExecuteRequest(request);

            if (Logger.IsDebug)
            {
                Logger.Debug("Response received. Status: " + response.StatusCode);
                Logger.Debug("Content type: " + response.ContentType);
                Logger.Debug("Encoding: " + response.Encoding);
                if (response.Body != null)
                {
                    Logger.Debug("Raw response (base64):" + response.Body.ToBase64());
                }
            }

            return(MessageHandler.ParseResponse <T>(request, response));
        }
コード例 #11
0
ファイル: AblyRest.cs プロジェクト: jeddawson/ably-dotnet
        public async Task <bool> CanConnectToAbly()
        {
            if (Options.SkipInternetCheck)
            {
                return(true);
            }

            try
            {
                var request  = new AblyRequest(Defaults.InternetCheckUrl, HttpMethod.Get);
                var response = await ExecuteHttpRequest(request);

                return(response.TextResponse == Defaults.InternetCheckOkMessage);
            }
            catch (Exception ex)
            {
                Logger.Error("Error accessing ably internet check url. Internet is down!", ex);
                return(false);
            }
        }
コード例 #12
0
ファイル: AblyHttpClient.cs プロジェクト: ddrinka/ably-dotnet
        public Uri GetRequestUrl(AblyRequest request, string host = null)
        {
            if (host == null)
            {
                host = Options.Host;
            }

            string protocol = Options.IsSecure ? "https://" : "http://";

            if (request.Url.StartsWith("http"))
            {
                return(new Uri(request.Url));
            }
            return(new Uri(string.Format("{0}{1}{2}{3}{4}",
                                         protocol,
                                         host,
                                         Options.Port.HasValue ? ":" + Options.Port.Value : "",
                                         request.Url,
                                         GetQuery(request))));
        }
コード例 #13
0
ファイル: AblyHttpClient.cs プロジェクト: ddrinka/ably-dotnet
        public async Task <AblyResponse> Execute(AblyRequest request)
        {
            var fallbackHosts = Defaults.FallbackHosts.ToList();

            if (CustomHost.IsNotEmpty())
            {
                //The custom host is a fallback host currently in use by the Realtime client.
                //We need to remove it from the fallback hosts
                fallbackHosts.Remove(CustomHost);
            }

            var random = new Random();

            int currentTry      = 0;
            var startTime       = Config.Now();
            var numberOfRetries = Options.HttpMaxRetryCount;
            var host            = CustomHost.IsNotEmpty() ? CustomHost : Options.Host;

            while (currentTry < numberOfRetries)
            {
                var requestTime = Config.Now();
                if ((requestTime - startTime).TotalSeconds >= Options.HttpMaxRetryDuration.TotalSeconds)
                {
                    Logger.Error("Cumulative retry timeout of {0}s was exceeded", Config.CommulativeFailedRequestTimeOutInSeconds);
                    throw new AblyException(
                              new ErrorInfo(string.Format("Commulative retry timeout of {0}s was exceeded.",
                                                          Config.CommulativeFailedRequestTimeOutInSeconds), 500, null));
                }

                Logger.Debug("Executing request: " + request.Url + (currentTry > 0 ? $"try {currentTry}" : ""));
                try
                {
                    var message = GetRequestMessage(request, host);

                    await LogMessage(message);

                    var response = await Client.SendAsync(message, HttpCompletionOption.ResponseContentRead);

                    var ablyResponse = await GetAblyResponse(response);

                    LogResponse(ablyResponse, request.Url);

                    if (response.IsSuccessStatusCode)
                    {
                        return(ablyResponse);
                    }

                    if (IsRetryableResponse(response) && Options.IsDefaultHost)
                    {
                        Logger.Warning("Failed response. Retrying. Returned response with status code: " +
                                       response.StatusCode);

                        if (TryGetNextRandomHost(fallbackHosts, random, out host))
                        {
                            Logger.Debug("Retrying using host {0}", host);
                            currentTry++;
                            continue;
                        }
                    }
                    throw AblyException.FromResponse(ablyResponse);
                }
                catch (HttpRequestException ex) when(IsRetryableError(ex) && Options.IsDefaultHost)
                {
                    Logger.Warning("Error making a connection to Ably servers. Retrying", ex);

                    if (TryGetNextRandomHost(fallbackHosts, random, out host))
                    {
                        Logger.Debug("Retrying using host {0}", host);
                        currentTry++;
                        continue;
                    }
                    throw;
                    //_host = hosts[currentTry - 1];
                }
                catch (TaskCanceledException ex) when(IsRetryableError(ex) && Options.IsDefaultHost)
                {
                    Logger.Warning("Error making a connection to Ably servers. Retrying", ex);
                    if (TryGetNextRandomHost(fallbackHosts, random, out host))
                    {
                        Logger.Debug("Retrying using host {0}", host);
                        currentTry++;
                        continue;
                    }
                    throw;
                }
                catch (HttpRequestException ex) { throw new AblyException(new ErrorInfo("Error executing request", 500), ex); }
                catch (TaskCanceledException ex) { throw new AblyException(new ErrorInfo("Error executing request", 500), ex); }
            }

            throw new AblyException(new ErrorInfo("Error exectuting request", 500));
        }
コード例 #14
0
        public async Task <AblyResponse> Execute(AblyRequest request)
        {
            var fallbackHosts = Options.FallbackHosts.ToList();

            if (CustomHost.IsNotEmpty())
            {
                // The custom host is a fallback host currently in use by the Realtime client.
                // We need to remove it from the fallback hosts
                fallbackHosts.Remove(CustomHost);
            }

            var random = new Random();

            int currentTry      = 0;
            var startTime       = Now();
            var numberOfRetries = Options.HttpMaxRetryCount;
            var host            = CustomHost.IsNotEmpty() ? CustomHost : Options.Host;

            while (currentTry < numberOfRetries)
            {
                DateTimeOffset requestTime = Now();
                if ((requestTime - startTime).TotalSeconds >= Options.HttpMaxRetryDuration.TotalSeconds)
                {
                    Logger.Error("Cumulative retry timeout of {0}s was exceeded", Config.CommulativeFailedRequestTimeOutInSeconds);
                    throw new AblyException(
                              new ErrorInfo($"Commulative retry timeout of {Config.CommulativeFailedRequestTimeOutInSeconds}s was exceeded.", 50000, null));
                }

                Logger.Debug("Executing request: " + request.Url + (currentTry > 0 ? $"try {currentTry}" : string.Empty));
                try
                {
                    var message = GetRequestMessage(request, host);
                    await LogMessage(message);

                    var response = await SendAsync(message).ConfigureAwait(false);

                    var ablyResponse = await GetAblyResponse(response);

                    LogResponse(ablyResponse, request.Url);

                    if (response.IsSuccessStatusCode)
                    {
                        return(ablyResponse);
                    }

                    if (IsRetryableResponse(response) && (Options.IsDefaultHost || Options.FallbackHostsUseDefault))
                    {
                        Logger.Warning("Failed response. Retrying. Returned response with status code: " +
                                       response.StatusCode);

                        if (TryGetNextRandomHost(fallbackHosts, random, out host))
                        {
                            Logger.Debug("Retrying using host {0}", host);
                            currentTry++;
                            continue;
                        }
                    }

                    if (request.NoExceptionOnHttpError)
                    {
                        return(ablyResponse);
                    }

                    try
                    {
                        response.EnsureSuccessStatusCode();
                    }
                    catch (HttpRequestException ex)
                    {
                        throw new AblyException(ErrorInfo.Parse(ablyResponse), ex);
                    }

                    throw AblyException.FromResponse(ablyResponse);
                }
                catch (HttpRequestException ex) when(IsRetryableError(ex) && (Options.IsDefaultHost || Options.FallbackHostsUseDefault))
                {
                    Logger.Warning("Error making a connection to Ably servers. Retrying", ex);
                    if (TryGetNextRandomHost(fallbackHosts, random, out host))
                    {
                        Logger.Debug("Retrying using host {0}", host);
                        currentTry++;
                        continue;
                    }

                    throw;
                }
                catch (TaskCanceledException ex) when(IsRetryableError(ex) && (Options.IsDefaultHost || Options.FallbackHostsUseDefault))
                {
                    Logger.Warning("Error making a connection to Ably servers. Retrying", ex);
                    if (TryGetNextRandomHost(fallbackHosts, random, out host))
                    {
                        Logger.Debug("Retrying using host {0}", host);
                        currentTry++;
                        continue;
                    }

                    throw;
                }
                catch (HttpRequestException ex)
                {
                    StringBuilder reason  = new StringBuilder(ex.Message);
                    var           innerEx = ex.InnerException;
                    while (innerEx != null)
                    {
                        reason.Append(" " + innerEx.Message);
                        innerEx = innerEx.InnerException;
                    }

                    throw new AblyException(new ErrorInfo(reason.ToString(), 50000), ex);
                }
                catch (TaskCanceledException ex)
                {
                    // if the cancellation was not requested then this is timeout.
                    if (ex.CancellationToken.IsCancellationRequested == false)
                    {
                        throw new AblyException(new ErrorInfo("Error executing request. Request timed out.", 50000), ex);
                    }
                    else
                    {
                        throw new AblyException(new ErrorInfo("Error executing request", 50000), ex);
                    }
                }
            }

            throw new AblyException(new ErrorInfo("Error exectuting request", 50000));
        }