private static IEnumerator SendRequest(UnityWebRequest www, Action <string> callback,
                                               Action <ApiResponseException> errback)
        {
            yield return(www.SendWebRequest());

            if (www.isNetworkError)
            {
                errback(new ApiResponseException(www.error));
            }
            else if (www.isHttpError)
            {
                var decoded = www.downloadHandler.text.FromJson <Dictionary <string, object> >();

                ApiResponseException e = new ApiResponseException(www.downloadHandler.text);

                if (decoded != null)
                {
                    e = new ApiResponseException(www.responseCode, decoded["message"].ToString(), (int)decoded["code"]);

                    if (decoded.ContainsKey("error"))
                    {
                        _instance.CopyResponseError(decoded["error"], e);
                    }
                }

                errback(e);
            }
            else
            {
                callback?.Invoke(www.downloadHandler?.text);
            }
        }
        public void And_Using_Message_And_InnerException_Ctor_Then_Sets_Message_From_Param(
            Exception innerException)
        {
            var exception = new ApiResponseException(System.Net.HttpStatusCode.MethodNotAllowed, "something went wrong", innerException);

            exception.Message.Should().Be($"HTTP status code did not indicate success: 405 MethodNotAllowed");
            exception.InnerException.Should().Be(innerException);
        }
        /// <inheritdoc cref="IHttpAdapter"/>
        public async Task <string> SendAsync(string method, Uri uri, IDictionary <string, string> headers, byte[] body,
                                             int timeout)
        {
            var request = new HttpRequestMessage
            {
                RequestUri = uri,
                Method     = new HttpMethod(method),
                Headers    =
                {
                    Accept = { new MediaTypeWithQualityHeaderValue("application/json") }
                }
            };

            foreach (var kv in headers)
            {
                request.Headers.Add(kv.Key, kv.Value);
            }

            if (body != null)
            {
                request.Content = new ByteArrayContent(body);
            }

            var timeoutToken = new CancellationTokenSource();

            timeoutToken.CancelAfter(TimeSpan.FromSeconds(timeout));

            Logger?.InfoFormat("Send: method='{0}', uri='{1}', body='{2}'", method, uri, body);

            var response = await _httpClient.SendAsync(request, timeoutToken.Token);

            var contents = await response.Content.ReadAsStringAsync();

            response.Content?.Dispose();

            Logger?.InfoFormat("Received: status={0}, contents='{1}'", response.StatusCode, contents);

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

            var    decoded  = contents.FromJson <Dictionary <string, object> >();
            string message  = decoded.ContainsKey("message") ? decoded["message"].ToString() : string.Empty;
            int    grpcCode = decoded.ContainsKey("code") ? (int)decoded["code"] : -1;

            var exception = new ApiResponseException((int)response.StatusCode, message, grpcCode);

            if (decoded.ContainsKey("error"))
            {
                this.CopyResponseError(decoded["error"], exception);
            }

            throw exception;
        }
Exemple #4
0
        public static ApiResponse <T> EnsureSuccessStatusCode <T>(this ApiResponse <T> response)
        {
            if (response == null)
            {
                throw new ArgumentNullException(nameof(response));
            }

            if (!IsSuccessStatusCode(response.StatusCode))
            {
                throw ApiResponseException.Create(response);
            }

            return(response);
        }
Exemple #5
0
        /// <summary>
        ///     Executes are request and parses into the requested type T
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public virtual async Task <T> Execute <T>() where T : BaseResponse
        {
            // Create our requested, based on the various parameters we have for this call
            HttpRequestMessage request = BuildRequest();

            // Debug - notify listeners that we are making this request
            _messageHub.APIRequestSent(_requestDetails);

            // Send to the API
            HttpResponseMessage response = await _client.SendAsync(request);

            // Debug - get the raw JSON out so we can debug
            var responseDetails = new ResponseDetails();

            responseDetails.StatusCode = ((int)response.StatusCode) + " " + response.StatusCode;

            responseDetails.JSON = await response.Content.ReadAsStringAsync();

            // If it's an error, we parse out exception and throw
            if (!response.IsSuccessStatusCode)
            {
                ApiResponseException exception;
                try
                {
                    var errorResponse = responseDetails.JSON.FromJSON <ErrorResponse>();
                    exception = new ApiResponseException(response.StatusCode, response.ReasonPhrase, errorResponse);
                }
                catch
                {
                    // If it's not JSON formatted, we just render a general message
                    exception = new ApiResponseException(HttpStatusCode.BadRequest, "A big exception occurred", new ErrorResponse {
                        Message = responseDetails.JSON
                    });
                }

                _messageHub.APIError(exception);

                // Friendlier message for our UI
                throw new UserException(exception.Message);
            }

            // Parse and return
            _messageHub.APIResponseReceived(responseDetails);

            var result = responseDetails.JSON.FromJSON <T>();

            return(result);
        }
        public async void RetryConfiguration_NonTransientError_Throws()
        {
            var adapterSchedule = new TransientAdapterResponseType[1]
            {
                TransientAdapterResponseType.NonTransientError,
            };

            var adapter = new TransientExceptionHttpAdapter(adapterSchedule);
            var client  = TestsUtil.FromSettingsFile(TestsUtil.DefaultSettingsPath, adapter);

            client.GlobalRetryConfiguration = new RetryConfiguration(baseDelayMs: 1, maxRetries: 3);

            ApiResponseException e =
                await Assert.ThrowsAsync <ApiResponseException>(async() =>
                                                                await client.AuthenticateCustomAsync("test_id"));
        }
        /// <summary>
        /// Performs an in-place copy of data from Nakama's error response into
        /// the data dictionary of an <see cref="Nakama.ApiResponseException"/>.
        /// </summary>
        /// <param name="adapter">The adapter receiving the error response.</param>
        /// <param name="err"> The decoded error field from the server response.</param>
        /// <param name="e"> The exception whose data dictionary is being written to.</param>
        public static void CopyResponseError(this IHttpAdapter adapter, object err, ApiResponseException e)
        {
            var errString = err as string;
            var errDict   = err as Dictionary <string, object>;

            if (errString != null)
            {
                e.Data["error"] = err;
            }
            else if (errDict != null)
            {
                foreach (KeyValuePair <string, object> keyVal in errDict)
                {
                    e.Data[keyVal.Key] = keyVal.Value;
                }
            }
        }
 /// <summary>
 ///     Notifies listeners that the API threw the given error
 /// </summary>
 /// <param name="errorMessage"></param>
 public void APIError(ApiResponseException errorMessage)
 {
     Connection.Clients.Group(GetCurrentAPIRequestGroupName()).APIError(errorMessage, TransactionId, Description);
 }
Exemple #9
0
        /// <summary>
        ///     Executes are request and parses into the requested type T
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public virtual async Task <T> Execute <T>() where T : BaseResponse
        {
            bool readyForProcessing = false;

            // Create our requested, based on the various parameters we have for this call
            HttpRequestMessage  request         = BuildRequest();
            HttpResponseMessage response        = null;
            ResponseDetails     responseDetails = null;

            do
            {
                if (PushPayRateLimiter.Instance.ShouldStop)
                {
                    // chase up the stack to make sure not swallowed
                    throw new Exception("Max retry window exceeded.");
                }
                // Wait any currently scheduled delay
                await Task.Delay(PushPayRateLimiter.Instance.CurrentDelay);

                // Send to the API
                response = await _client.SendAsync(request);

                // Debug - get the raw JSON out so we can debug
                responseDetails = new ResponseDetails
                {
                    StatusCode = ((int)response.StatusCode) + " " + response.StatusCode,
                    JSON       = await response.Content.ReadAsStringAsync()
                };

                readyForProcessing = response.StatusCode != (HttpStatusCode)429;

                if (!readyForProcessing && response.Headers.Contains("retry-after"))
                {
                    var retryHeader = response.Headers.GetValues("retry-after");
                    var retryWindow = int.Parse(retryHeader?.FirstOrDefault());

                    PushPayRateLimiter.Instance.AddDelay(retryWindow);
                }
            } while (!readyForProcessing);

            PushPayRateLimiter.Instance.ResetDelay();

            // If it's an error, we parse out exception and throw
            if (!response.IsSuccessStatusCode)
            {
                ApiResponseException exception;
                try
                {
                    var errorResponse = responseDetails.JSON.FromJSON <ErrorResponse>();
                    exception = new ApiResponseException(response.StatusCode, response.ReasonPhrase, errorResponse);
                }
                catch
                {
                    // If it's not JSON formatted, we just render a general message
                    exception = new ApiResponseException(HttpStatusCode.BadRequest, "An exception occurred", new ErrorResponse {
                        Message = responseDetails.JSON
                    });
                }

                // Friendlier message for our UI
                throw new UserException(exception.Message);
            }

            var result = responseDetails.JSON.FromJSON <T>();

            return(result);
        }
        public void And_Using_Message_Ctor_Then_Sets_Message_From_Param()
        {
            var exception = new ApiResponseException(System.Net.HttpStatusCode.BadRequest, "something went wrong");

            exception.Message.Should().Be($"HTTP status code did not indicate success: 400 BadRequest");
        }
Exemple #11
0
        private void ConfigJwtAuthentication(IServiceCollection services)
        {
            var symmetricKey = Convert.FromBase64String(EncryptionUtil.ToBase64Encode("123456abcdefqwer"));

            services.AddAuthentication(x =>
            {
                x.DefaultScheme             = JwtBearerDefaults.AuthenticationScheme;
                x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                x.DefaultChallengeScheme    = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(x =>
            {
                x.RequireHttpsMetadata      = false;
                x.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey         = new SymmetricSecurityKey(symmetricKey),
                    ValidateIssuer           = false,
                    ValidateAudience         = false,
                    ValidateLifetime         = true,
                    ClockSkew = TimeSpan.Zero
                };

                x.Events = new JwtBearerEvents()
                {
                    OnAuthenticationFailed = async context =>
                    {
                        Console.WriteLine("ABCDDDDDDDDDDDDDDDDDDD");
                        var apiErrorMessage = new ApiErrorMessage();
                        var statusCode      = HttpStatusCode.Unauthorized;

                        if (context.Exception is SecurityTokenExpiredException)
                        {
                            apiErrorMessage.ErrorCode    = (int)ErrorCodeEnum.ACCESS_TOKEN_IS_EXPIRED;
                            apiErrorMessage.ErrorMessage = ErrorMessageConstant.ACCESS_TOKEN_IS_EXPIRED;
                        }
                        else
                        {
                            apiErrorMessage.ErrorCode    = (int)ErrorCodeEnum.ACCESS_TOKEN_IS_INVALID;
                            apiErrorMessage.ErrorMessage = ErrorMessageConstant.ACCESS_TOKEN_IS_INVALID;
                            statusCode = (HttpStatusCode.Forbidden);
                        }

                        var apiResponseException = new ApiResponseException()
                        {
                            ErrorMessages = new List <ApiErrorMessage>
                            {
                                apiErrorMessage
                            },
                            StatusCode = statusCode
                        };

                        var apiResponse = new ApiSingleResponse <string>()
                        {
                            Data   = null,
                            Errors = apiResponseException.ErrorMessages
                        };

                        context.Response.StatusCode  = (int)statusCode;
                        context.Response.ContentType = "application/json";
                        await context.Response.WriteAsync(JsonSerializer.Serialize(apiResponse, new JsonSerializerOptions {
                            PropertyNamingPolicy = JsonNamingPolicy.CamelCase
                        }));
                    }
                };
            });
        }