/// <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()); }
/// <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()); } }
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); }
protected override Task <IFlurlResponse> CallOnFlurlRequest(IFlurlRequest req) => req.DeleteAsync();
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)); } }
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 }); }
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); } }