/// <summary> /// Creates a new database with the given name in the server. /// The name must begin with a lowercase letter and can contains only lowercase characters, digits or _, $, (, ), +, - and /.s /// </summary> /// <typeparam name="TSource">The type of database documents.</typeparam> /// <param name="database">The database name.</param> /// <param name="shards">The number of range partitions. Default is 8, unless overridden in the cluster config.</param> /// <param name="replicas">The number of copies of the database in the cluster. The default is 3, unless overridden in the cluster config.</param> /// <returns>A task that represents the asynchronous operation. The task result contains the newly created CouchDB database.</returns> public async Task <CouchDatabase <TSource> > CreateDatabaseAsync <TSource>(string database, int?shards = null, int?replicas = null) where TSource : CouchDocument { database = EscapeDatabaseName(database); IFlurlRequest request = NewRequest() .AppendPathSegment(database); if (shards.HasValue) { request = request.SetQueryParam("q", shards.Value); } if (replicas.HasValue) { request = request.SetQueryParam("n", replicas.Value); } OperationResult result = await request .PutAsync(null) .ReceiveJson <OperationResult>() .SendRequestAsync() .ConfigureAwait(false); if (!result.Ok) { throw new CouchException("Something went wrong during the creation"); } return(new CouchDatabase <TSource>(_flurlClient, _settings, ConnectionString, database)); }
/// <summary> /// Creates a new database with the given name in the server. /// The name must begin with a lowercase letter and can contains only lowercase characters, digits or _, $, (, ), +, - and /.s /// </summary> /// <typeparam name="TSource">The type of database documents.</typeparam> /// <param name="database">The database name.</param> /// <param name="shards">The number of range partitions. Default is 8, unless overridden in the cluster config.</param> /// <param name="replicas">The number of copies of the database in the cluster. The default is 3, unless overridden in the cluster config.</param> /// <returns>A task that represents the asynchronous operation. The task result contains the newly created CouchDB database.</returns> public async Task <CouchDatabase <TSource> > CreateDatabaseAsync <TSource>(string database, int?shards = null, int?replicas = null) where TSource : CouchDocument { if (database == null) { throw new ArgumentNullException(nameof(database)); } if (!_systemDatabases.Contains(database) && !new Regex(@"^[a-z][a-z0-9_$()+/-]*$").IsMatch(database)) { throw new ArgumentException($"Name {database} contains invalid characters. Please visit: https://docs.couchdb.org/en/stable/api/database/common.html#put--db", nameof(database)); } IFlurlRequest request = NewRequest() .AppendPathSegment(database); if (shards.HasValue) { request = request.SetQueryParam("q", shards.Value); } if (replicas.HasValue) { request = request.SetQueryParam("n", replicas.Value); } OperationResult result = await request .PutAsync(null) .ReceiveJson <OperationResult>() .SendRequestAsync() .ConfigureAwait(false); if (!result.Ok) { throw new CouchException("Something went wrong during the creation"); } return(new CouchDatabase <TSource>(_flurlClient, _settings, ConnectionString, database)); }
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.PutAsync(null);
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); } }