private static void WebCallRejected(string Reason, NancyContext Context) { string ErrorReason = "[Launcher to Game Client] Web Call Rejected. "; switch (Reason) { case "RequestIsGzipCompatible": ErrorReason += "Request Is Not Gzip Compatible"; break; case "ResponseIsCompatibleMimeType": ErrorReason += "Response Is Not a Compatible Mime-Type"; break; case "ResponseIsCompressed": ErrorReason += "Response Is Already Compressed"; break; case "ContentLengthIsTooSmall": ErrorReason += "Content-Length Is Too Small"; break; case "GameTimer": ErrorReason += "Game Requires Termination"; break; default: ErrorReason += "Unknown Reason"; break; } CommunicationLog.RecordEntry(ServerProxy.Instance.GetServerName(), "LAUNCHER", CommunicationLogEntryType.Rejected, new CommunicationLogLauncherError(ErrorReason, Context.Request.Path, Context.Request.Method)); }
private TextResponse OnError(NancyContext context, Exception Error) { Log.Error("PROXY HANDLER: " + context.Request.Path); LogToFileAddons.OpenLog("PROXY HANDLER", null, Error, null, true); CommunicationLog.RecordEntry(ServerProxy.Instance.GetServerName(), "PROXY", CommunicationLogEntryType.Error, new CommunicationLogLauncherError(Error.Message, context.Request.Path, context.Request.Method)); context.Request.Dispose(); return(new TextResponse(HttpStatusCode.BadRequest, Error.Message)); }
private async Task <TextResponse> OnError(NancyContext context, Exception exception) { Log.Error($"PROXY ERROR [handling {context.Request.Path}]"); Log.Error($"\tMESSAGE: {exception.Message}"); Log.Error($"\t{exception.StackTrace}"); CommunicationLog.RecordEntry(ServerProxy.Instance.GetServerName(), "PROXY", CommunicationLogEntryType.Error, new CommunicationLogLauncherError(exception.Message, context.Request.Path, context.Request.Method)); await SubmitError(exception); return(new TextResponse(HttpStatusCode.BadRequest, exception.Message)); }
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) { // Don't send Content-Length for GET requests if (method == "GET" && header.Key.ToLowerInvariant() == "content-length") { continue; } request = request.WithHeader(header.Key, header.Key == "Host" ? resolvedUrl.ToUri().Host : header.Value.First()); } var requestBody = method != "GET" ? context.Request.Body.AsString(Encoding.UTF8) : ""; CommunicationLog.RecordEntry(ServerProxy.Instance.GetServerName(), "SERVER", CommunicationLogEntryType.Request, new CommunicationLogRequest(requestBody, resolvedUrl.ToString(), method)); IFlurlResponse 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()); switch (method) { case "GET": responseMessage = await request.GetAsync(cancellationToken); break; case "POST": responseMessage = await request.PostAsync(new CapturedStringContent(requestBody), cancellationToken); POSTContent = context.Request.Body.AsString(); break; case "PUT": responseMessage = await request.PutAsync(new CapturedStringContent(requestBody), cancellationToken); break; case "DELETE": responseMessage = await request.DeleteAsync(cancellationToken); break; default: throw new ProxyException("Cannot handle request method: " + method); } var responseBody = await responseMessage.GetStringAsync(); if (path == "/User/GetPermanentSession") { responseBody = CleanFromUnknownChars(responseBody); } int statusCode = responseMessage.StatusCode; try { DiscordGamePresence.HandleGameState(path, responseBody, GETContent); } catch (Exception e) { Log.Error($"DISCORD RPC ERROR [handling {context.Request.Path}]"); Log.Error($"\tMESSAGE: {e.Message}"); Log.Error($"\t{e.StackTrace}"); await SubmitError(e); } TextResponse textResponse = new TextResponse(responseBody, responseMessage.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); }
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); } }