/// <summary>
        /// DELETE request to the API
        /// </summary>
        /// <typeparam name="T">Type of return data</typeparam>
        /// <param name="id">Unique identifier of entity that will be partially updated</param>
        /// <param name="pathToAppend">Additional path to append on base url (e.g. "lock" custom operation as "/users/1/lock")</param>
        public async Task <APIServiceResult <T> > Delete <T>(int id, string pathToAppend = "")
        {
            try
            {
                request.Url.AppendPathSegment(id);
                if (!string.IsNullOrWhiteSpace(pathToAppend))
                {
                    request.Url.AppendPathSegment(pathToAppend);
                }

                var response = await request.DeleteAsync();

                RevertToBaseRequest();
                if (response.StatusCode != HttpStatusCode.OK)
                {
                    if (response.StatusCode == HttpStatusCode.Forbidden)
                    {
                    }

                    if (response.StatusCode == HttpStatusCode.BadRequest)
                    {
                        if (response.Content != null)
                        {
                            var errorMessage = await response.Content?.ReadAsStringAsync() ?? string.Empty;

                            return(APIServiceResult <T> .BadRequest(errorMessage));
                        }
                    }

                    return(APIServiceResult <T> .WithStatusCode(response.StatusCode));
                }

                if (response.Content != null)
                {
                    var result = await response.Content?.ReadAsAsync <T>();

                    return(result != null ? APIServiceResult <T> .OK(result) : APIServiceResult <T> .NoContent());
                }

                APIServiceResult <T> .NoContent();
            }
            catch (Exception ex)
            {
                return(APIServiceResult <T> .Exception());
            }

            return(APIServiceResult <T> .BadRequest());
        }
示例#2
0
        /// <summary>
        /// DELETE request to the API
        /// </summary>
        /// <typeparam name="T">Type of return data</typeparam>
        /// <param name="id">Unique identifier of entity that will be partially updated</param>
        /// <param name="pathToAppend">Additional path to append on base url (e.g. "lock" custom operation as "/users/1/lock")</param>
        public async Task <APIServiceResult <T> > Delete <T>(object id, string pathToAppend = "")
        {
            try
            {
                request.Url.AppendPathSegment(id);
                if (!string.IsNullOrWhiteSpace(pathToAppend))
                {
                    request.Url.AppendPathSegment(pathToAppend);
                }

                var response = await request.DeleteAsync();

                RevertToBaseRequest();
                if (response.StatusCode != HttpStatusCode.OK)
                {
                    if (response.StatusCode == HttpStatusCode.Forbidden)
                    {
                        dlgError.ShowDialog(Resources.AccessDenied);
                    }

                    if (response.StatusCode == HttpStatusCode.BadRequest)
                    {
                        dlgError.ShowDialog(await response.Content?.ReadAsStringAsync() ?? string.Empty);
                    }

                    return(APIServiceResult <T> .WithStatusCode(response.StatusCode));
                }

                var result = await response.Content?.ReadAsAsync <T>();

                return(result != null ? APIServiceResult <T> .OK(result) : APIServiceResult <T> .NoContent());
            }
            catch (Exception ex)
            {
                logger.Error(ex);
                dlgError.ShowDialog(Resources.TemporarilyUnvailable);
                return(APIServiceResult <T> .Exception());
            }
        }
示例#3
0
        private async Task <Response> ProxyRequest(NancyContext context, CancellationToken cancellationToken)
        {
            string path   = context.Request.Path;
            string method = context.Request.Method.ToUpperInvariant();

            if (!path.StartsWith("/nfsw/Engine.svc"))
            {
                throw new ProxyException("Invalid request path: " + path);
            }

            path = path.Substring("/nfsw/Engine.svc".Length);

            Url resolvedUrl = new Url(ServerProxy.Instance.GetServerUrl()).AppendPathSegment(path);

            foreach (var queryParamName in context.Request.Query)
            {
                resolvedUrl = resolvedUrl.SetQueryParam(queryParamName, context.Request.Query[queryParamName],
                                                        NullValueHandling.Ignore);
            }

            IFlurlRequest request = resolvedUrl.AllowAnyHttpStatus();

            foreach (var header in context.Request.Headers)
            {
                request = request.WithHeader(header.Key,
                                             header.Key == "Host" ? resolvedUrl.ToUri().Host : header.Value.First());
            }

            var requestBody = context.Request.Method != "GET" ? context.Request.Body.AsString(Encoding.UTF8) : "";

            CommunicationLog.RecordEntry(ServerProxy.Instance.GetServerName(), "SERVER",
                                         CommunicationLogEntryType.Request,
                                         new CommunicationLogRequest(requestBody, resolvedUrl.ToString(), method));

            HttpResponseMessage responseMessage;

            var POSTContent = String.Empty;

            var queryParams = new Dictionary <string, object>();

            foreach (var param in context.Request.Query)
            {
                var value = context.Request.Query[param];
                queryParams[param] = value;
            }

            var GETContent = string.Join(";", queryParams.Select(x => x.Key + "=" + x.Value).ToArray());

            // ReSharper disable once LocalizableElement
            //Console.WriteLine($"[LOG] [{method}] ProxyHandler: {path}");

            switch (method)
            {
            case "GET":
                responseMessage = await request.GetAsync(cancellationToken);

                break;

            case "POST":
                responseMessage = await request.PostAsync(new CapturedStringContent(requestBody, Encoding.UTF8),
                                                          cancellationToken);

                POSTContent = context.Request.Body.AsString();
                break;

            case "PUT":
                responseMessage = await request.PutAsync(new CapturedStringContent(requestBody, Encoding.UTF8),
                                                         cancellationToken);

                break;

            case "DELETE":
                responseMessage = await request.DeleteAsync(cancellationToken);

                break;

            default:
                throw new ProxyException("Cannot handle request method: " + method);
            }

            var responseBody = await responseMessage.Content.ReadAsStringAsync();

            if (path == "/User/GetPermanentSession")
            {
                responseBody = Self.CleanFromUnknownChars(responseBody);
            }

            int statusCode = (int)responseMessage.StatusCode;

            try
            {
                DiscordGamePresence.HandleGameState(path, responseBody, POSTContent, GETContent);
            }
            catch (Exception e)
            {
                Log.Error($"DISCORD RPC ERROR [handling {context.Request.Path}]");
                Log.Error($"\tMESSAGE: {e.Message}");
                Log.Error($"\t{e.StackTrace}");
                await Self.SubmitError(e);
            }

            TextResponse textResponse = new TextResponse(responseBody,
                                                         responseMessage.Content.Headers.ContentType?.MediaType ?? "application/xml;charset=UTF-8")
            {
                StatusCode = (HttpStatusCode)statusCode
            };

            queryParams.Clear();

            CommunicationLog.RecordEntry(ServerProxy.Instance.GetServerName(), "SERVER",
                                         CommunicationLogEntryType.Response, new CommunicationLogResponse(
                                             responseBody, resolvedUrl.ToString(), method));

            return(textResponse);
        }
示例#4
0
 protected override Task <IFlurlResponse> CallOnFlurlRequest(IFlurlRequest req) => req.DeleteAsync();
示例#5
0
        private async Task <ServiceResult <TResult> > ResolveHttpResponseAsync <TResult>(DoType type, int retryCount, IFlurlRequest webApiObject, object bodyObject = null, int secondsTimeout = 30, string callerMemberName = null)
        {
            var                 _retMessage = "";
            ReturnMessage       _message;
            HttpResponseMessage _exec           = null;
            HttpStatusCode      _HttpStatusCode = HttpStatusCode.BadRequest;

            var _policyResult = await Policy
                                .Handle <FlurlHttpTimeoutException>().Or <FlurlHttpException>().Or <Exception>()
                                .RetryAsync(retryCount, (exception, retryNumber) =>
            {
                System.Diagnostics.Debug.WriteLine($"==================================================================");
                System.Diagnostics.Debug.WriteLine($"Method: {callerMemberName} -> Retry: number#{retryNumber} -> exception:{exception.Message}");
                System.Diagnostics.Debug.WriteLine($"==================================================================");
            })
                                .ExecuteAndCaptureAsync(new Func <Task <ServiceResult <TResult> > >(async() =>
            {
                var _token   = this.GetCancelationToken(secondsTimeout).Token;
                var _content = "";

#if DEBUG
                var _json = JsonConvert.SerializeObject(bodyObject);
#endif
                switch (type)
                {
                case DoType.Get:
                    _exec = await webApiObject.GetAsync(_token);
                    break;

                case DoType.Post:
                    _exec = await webApiObject.PostJsonAsync(bodyObject, _token);
                    break;

                case DoType.Put:
                    _exec = await webApiObject.PutJsonAsync(bodyObject, _token);
                    break;

                case DoType.Delete:
                    _exec = bodyObject == null ? await webApiObject.DeleteAsync(_token) : await webApiObject.SendJsonAsync(HttpMethod.Delete, bodyObject, _token);
                    break;
                }

                switch (_exec.StatusCode)
                {
                case HttpStatusCode.OK:
                    switch (type)
                    {
                    case DoType.Get:
                    case DoType.Post:
                    case DoType.Put:
                        // lê o retorno do serviço
                        var _stringContent = await _exec.Content.ReadAsStringAsync();

                        // checa se está nulo, se estiver manda uma string vazia
                        _stringContent = string.IsNullOrEmpty(_stringContent) ? "" : _stringContent;

                        // vê se o conteúdo é um json, se não for, formatamos para que seja
                        TResult _result = default(TResult);

                        if (this.IsValidJson(_stringContent))
                        {
                            _result = JsonConvert.DeserializeObject <TResult>(_stringContent);
                        }
                        else
                        {
                            _result = (TResult)Convert.ChangeType(_stringContent, typeof(TResult), CultureInfo.CurrentCulture);
                        }

                        // retornamos o resultado deserializando no formato informado
                        return(new ServiceResult <TResult>(_result, true, _exec.StatusCode));

                    case DoType.Delete:
                        object _RetBool = true;
                        return(new ServiceResult <TResult>((TResult)_RetBool, true, _exec.StatusCode));
                    }
                    break;

                case HttpStatusCode.Unauthorized:
                    _retMessage = $"Você não está autorizado a executar essa rotina: {callerMemberName}!\r\nPor favor contacte o suporte.";
                    break;

                case HttpStatusCode.InternalServerError:
                case HttpStatusCode.BadRequest:
                    _content = await _exec.Content.ReadAsStringAsync();
                    try
                    {
                        _message    = JsonConvert.DeserializeObject <ReturnMessage>(_content);
                        _retMessage = _message.Message;
                    }
                    catch (Exception)
                    {
                        _retMessage = _content;
                    }

                    break;

                case HttpStatusCode.NoContent:
                    return(new ServiceResult <TResult>(default(TResult), false, _exec.StatusCode));

                case HttpStatusCode.NotFound:
                    return(new ServiceResult <TResult>(default(TResult), false, _exec.StatusCode));

                default:
                    _content    = await _exec.Content.ReadAsStringAsync();
                    _message    = JsonConvert.DeserializeObject <ReturnMessage>(_content);
                    _retMessage = $"Ocorreu um erro ao executar operação na rotina {callerMemberName}!\r\nPor favor contacte o suporte:\r\n\r\n{_message.Message}";
                    break;
                }
                _HttpStatusCode = _exec.StatusCode;
                return(new ServiceResult <TResult>(default(TResult), false, _HttpStatusCode, _retMessage));
            }));

            if (_policyResult.Outcome == OutcomeType.Successful)
            {
                return(_policyResult.Result);
            }
            else
            {
                switch (_policyResult.FinalException)
                {
                case FlurlHttpTimeoutException fhtex:
                    _HttpStatusCode = HttpStatusCode.GatewayTimeout;
                    _retMessage     = $"O tempo para execução desta tarefa expirou!Rotina{callerMemberName}\r\nTente novamente em alguns segundos.";
                    break;

                case FlurlHttpException fhex:
                    string _retString = fhex.Message;
                    if (fhex.Call.HttpStatus.HasValue)
                    {
                        _HttpStatusCode = fhex.Call.HttpStatus.Value;
                        switch (fhex.Call.HttpStatus.Value)
                        {
                        case HttpStatusCode.InternalServerError:
                        case HttpStatusCode.BadRequest:
                            _retMessage = fhex.Call.Response.Content.ReadAsStringAsync().Result;
                            break;
                        }
                    }
                    else
                    {
                        //_retMessage = $"Ocorreu um erro ao executar a operação na rotina {callerMemberName}!\r\nPor favor contacte o suporte:\r\n\r\n{_retString}";
                        _retMessage = $"Não foi possível executar a sua solicitação. Verifique a sua conexão com a Internet e tente novamente.";
                    }
                    break;

                case Exception ex:
                    _retMessage = this.GetInnerExceptionMessages(ex);
                    break;

                default:
                    _retMessage = this.GetInnerExceptionMessages(_policyResult.FinalException);
                    break;
                }
                return(new ServiceResult <TResult>(default(TResult), false, _HttpStatusCode, _retMessage));
            }
        }
示例#6
0
        private async Task <Response> ProxyRequest(NancyContext ctx, CancellationToken ct)
        {
            Debug.WriteLine("{0} - {1}", ctx.Request.Method, ctx.Request.Path);

            foreach (var requestHeader in ctx.Request.Headers)
            {
                Debug.WriteLine("\t{0}: {1}", requestHeader.Key, string.Join(" ; ", requestHeader.Value));
            }

            // Build new request
            var url = new Flurl.Url(ServerProxy.Instance.GetCurrentServer().ServerAddress)
                      .AppendPathSegment(ctx.Request.Path.Replace("/nfsw/Engine.svc", ""));

            foreach (var key in ctx.Request.Query)
            {
                url = url.SetQueryParam(key, ctx.Request.Query[key], NullValueHandling.Ignore);
            }

            IFlurlRequest request = url.WithTimeout(TimeSpan.FromSeconds(30));

            foreach (var requestHeader in ctx.Request.Headers)
            {
                request = request.WithHeader(requestHeader.Key, requestHeader.Value.First());
            }

            HttpResponseMessage responseMessage;

            switch (ctx.Request.Method)
            {
            case "GET":
                responseMessage = await request.GetAsync(ct);

                break;

            case "POST":
                responseMessage =
                    await request.PostAsync(new CapturedStringContent(ctx.Request.Body.AsString(Encoding.UTF8)), ct);

                break;

            case "PUT":
                responseMessage =
                    await request.PutAsync(new CapturedStringContent(ctx.Request.Body.AsString(Encoding.UTF8)), ct);

                break;

            case "DELETE":
                responseMessage =
                    await request.DeleteAsync(ct);

                break;

            default:
                throw new ServerProxyException("Cannot handle request method: " + ctx.Request.Method);
            }

            return(new TextResponse(await responseMessage.Content.ReadAsStringAsync(),
                                    responseMessage.Content.Headers.ContentType?.MediaType ?? "application/xml;charset=UTF-8")
            {
                StatusCode = (HttpStatusCode)(int)responseMessage.StatusCode
            });
        }
示例#7
0
        private async Task <Response> ProxyRequest(NancyContext context, CancellationToken cancellationToken)
        {
            string path   = Strings.Encode(context.Request.Path);
            string method = Strings.Encode(context.Request.Method.ToUpperInvariant());

            if (!path.StartsWith("/nfsw/Engine.svc"))
            {
                Log.Error("PROXY HANDLER: Invalid Request: " + path);
                return("SBRW Launcher Version: " + Theming.PrivacyRPCBuild + "\nBuild Date: " + InsiderInfo.BuildNumberOnly());
            }
            else
            {
                path = path.Substring("/nfsw/Engine.svc".Length);

                UrlFlurl resolvedUrl = new UrlFlurl(ServerProxy.Instance.GetServerUrl()).AppendPathSegment(path, false);

                foreach (var queryParamName in context.Request.Query)
                {
                    resolvedUrl = resolvedUrl.SetQueryParam(queryParamName, context.Request.Query[queryParamName],
                                                            NullValueHandling.Ignore);
                }

                IFlurlRequest request = resolvedUrl.AllowAnyHttpStatus();

                foreach (var header in context.Request.Headers)
                {
                    /* Don't send Content-Length for GET requests - HeyItsLeo */
                    if (method == "GET" && header.Key.ToLowerInvariant() == "content-length")
                    {
                        continue;
                    }

                    request = request.WithHeader
                                  (header.Key, (header.Key == "Host") ? resolvedUrl.ToUri().Host : ((header.Value != null) ? header.Value.First() : string.Empty));
                }

                string requestBody = (method != "GET") ? context.Request.Body.AsString(UTF8) : string.Empty;

                CommunicationLog.RecordEntry(ServerProxy.Instance.GetServerName(), "SERVER", CommunicationLogEntryType.Request,
                                             new CommunicationLogRequest(requestBody, resolvedUrl.ToString(), method));

                IFlurlResponse responseMessage;

                if (path == "/event/arbitration" && !string.IsNullOrWhiteSpace(requestBody))
                {
                    requestBody = Strings.Encode(
                        requestBody.Replace("</TopSpeed>", "</TopSpeed><Konami>" + AntiCheat.Get_Cheat_Status() + "</Konami>"));
                    foreach (var header in context.Request.Headers)
                    {
                        if (header.Key.ToLowerInvariant() == "content-length")
                        {
                            int KonamiCode = Convert.ToInt32(header.Value.First()) +
                                             ("<Konami>" + AntiCheat.Get_Cheat_Status() + "</Konami>").Length;
                            request = request.WithHeader(header.Key, KonamiCode);
                        }
                    }
                }

                switch (method)
                {
                case "GET":
                    responseMessage = await request.GetAsync(cancellationToken);

                    break;

                case "POST":
                    responseMessage = await request.PostAsync(new CapturedStringContent(requestBody),
                                                              cancellationToken);

                    break;

                case "PUT":
                    responseMessage = await request.PutAsync(new CapturedStringContent(requestBody),
                                                             cancellationToken);

                    break;

                case "DELETE":
                    responseMessage = await request.DeleteAsync(cancellationToken);

                    break;

                default:
                    Log.Error("PROXY HANDLER: Cannot handle Request Method " + method);
                    responseMessage = null;
                    break;
                }

                string responseBody = Strings.Encode(await responseMessage.GetStringAsync());

                int statusCode = responseMessage.StatusCode;

                DiscordGamePresence.HandleGameState(path, responseBody, context.Request.Query);

                TextResponse Response = new TextResponse(responseBody,
                                                         responseMessage.ResponseMessage.Content.Headers.ContentType?.MediaType ?? "application/xml;charset=UTF-8")
                {
                    StatusCode = (HttpStatusCode)statusCode
                };

                CommunicationLog.RecordEntry(ServerProxy.Instance.GetServerName(), "SERVER", CommunicationLogEntryType.Response,
                                             new CommunicationLogResponse(responseBody, resolvedUrl.ToString(), method));

                return(Response);
            }
        }