public override async Task ProcessAsync(ArraySegment <byte> data) { Stopwatch stopwatch = Stopwatch.StartNew(); IncrementBytesReceivedMetric(data.Count); using TextReader request = new StreamReader(new MemoryStream(data.Array !, data.Offset, data.Count), Encoding.UTF8); int allResponsesSize = 0; await foreach (JsonRpcResult result in _jsonRpcProcessor.ProcessAsync(request, _jsonRpcContext)) { using (result) { int singleResponseSize = await SendJsonRpcResult(result); allResponsesSize += singleResponseSize; if (result.IsCollection) { _jsonRpcLocalStats.ReportCalls(result.Reports); long handlingTimeMicroseconds = stopwatch.ElapsedMicroseconds(); _jsonRpcLocalStats.ReportCall(new RpcReport("# collection serialization #", handlingTimeMicroseconds, true), handlingTimeMicroseconds, singleResponseSize); stopwatch.Restart(); } else { long handlingTimeMicroseconds = stopwatch.ElapsedMicroseconds(); _jsonRpcLocalStats.ReportCall(result.Report, handlingTimeMicroseconds, singleResponseSize); stopwatch.Restart(); } } } IncrementBytesSentMetric(allResponsesSize); }
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IJsonRpcProcessor jsonRpcProcessor, IJsonRpcService jsonRpcService) { _jsonSerializer = new EthereumJsonSerializer(); foreach (JsonConverter converter in jsonRpcService.Converters) { _jsonSerializer.RegisterConverter(converter); } if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseCors("Cors"); var initConfig = app.ApplicationServices.GetService <IConfigProvider>().GetConfig <IInitConfig>(); if (initConfig.WebSocketsEnabled) { app.UseWebSockets(); app.UseWhen(ctx => ctx.WebSockets.IsWebSocketRequest && ctx.Request.Path.HasValue && ctx.Request.Path.Value.StartsWith("/ws"), builder => builder.UseWebSocketsModules()); } app.Use(async(ctx, next) => { if (ctx.Request.Method == "GET") { await ctx.Response.WriteAsync("Nethermind JSON RPC"); return; } if (ctx.Request.Method != "POST") { return; } using var reader = new StreamReader(ctx.Request.Body, Encoding.UTF8); var request = await reader.ReadToEndAsync(); var result = await jsonRpcProcessor.ProcessAsync(request); if (result.IsCollection) { _jsonSerializer.Serialize(ctx.Response.Body, result.Responses); } else { _jsonSerializer.Serialize(ctx.Response.Body, result.Response); } await ctx.Response.CompleteAsync(); }); }
public async Task <JsonResult> Post() { using (var reader = new StreamReader(Request.Body, Encoding.UTF8)) { var result = await _jsonRpcProcessor.ProcessAsync(await reader.ReadToEndAsync()); return(result.IsCollection ? new JsonResult(result.Responses, _jsonSettings) : new JsonResult(result.Responses.SingleOrDefault(), _jsonSettings)); } }
public async Task Post() { using (var reader = new StreamReader(Request.Body, Encoding.UTF8)) { var result = await _jsonRpcProcessor.ProcessAsync(await reader.ReadToEndAsync()); var json = result.IsCollection ? JsonConvert.SerializeObject(result.Responses, _jsonSettings) : JsonConvert.SerializeObject(result.Responses.SingleOrDefault(), _jsonSettings); await Response.WriteAsync($"{json}\n"); } }
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IJsonRpcProcessor jsonRpcProcessor, IJsonRpcService jsonRpcService) { _jsonSerializer = CreateJsonSerializer(); foreach (JsonConverter converter in jsonRpcService.Converters) { _jsonSerializer.RegisterConverter(converter); } if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseCors("Cors"); IConfigProvider configProvider = app.ApplicationServices.GetService <IConfigProvider>(); IInitConfig initConfig = configProvider.GetConfig <IInitConfig>(); IJsonRpcConfig jsonRpcConfig = configProvider.GetConfig <IJsonRpcConfig>(); if (initConfig.WebSocketsEnabled) { app.UseWebSockets(); app.UseWhen(ctx => ctx.WebSockets.IsWebSocketRequest && ctx.Connection.LocalPort == jsonRpcConfig.WebSocketsPort, builder => builder.UseWebSocketsModules()); } app.Use(async(ctx, next) => { if (ctx.Request.Method == "GET") { await ctx.Response.WriteAsync("Nethermind JSON RPC"); } else if (ctx.Connection.LocalPort == jsonRpcConfig.Port && ctx.Request.Method == "POST") { using StreamReader reader = new StreamReader(ctx.Request.Body, Encoding.UTF8); string request = await reader.ReadToEndAsync(); JsonRpcResult result = await jsonRpcProcessor.ProcessAsync(request); if (result.IsCollection) { _jsonSerializer.Serialize(ctx.Response.Body, result.Responses); } else { _jsonSerializer.Serialize(ctx.Response.Body, result.Response); } await ctx.Response.CompleteAsync(); } }); }
public async Task Post() { using (var reader = new StreamReader(Request.Body, Encoding.UTF8)) { string request = await reader.ReadToEndAsync(); var result = await _jsonRpcProcessor.ProcessAsync(request); using (var streamWriter = new StreamWriter(Response.Body)) using (var jsonTextWriter = new JsonTextWriter(streamWriter)) { if (result.IsCollection) { _serializer.Serialize(jsonTextWriter, result.Responses); } else { _serializer.Serialize(jsonTextWriter, result.Responses[0]); } } } }
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IJsonRpcProcessor jsonRpcProcessor, IJsonRpcService jsonRpcService, IJsonRpcLocalStats jsonRpcLocalStats) { void SerializeTimeoutException(IJsonRpcService service, Stream resultStream) { JsonRpcErrorResponse?error = service.GetErrorResponse(ErrorCodes.Timeout, "Request was canceled due to enabled timeout."); _jsonSerializer.Serialize(resultStream, error); } _jsonSerializer = CreateJsonSerializer(); foreach (JsonConverter converter in jsonRpcService.Converters) { _jsonSerializer.RegisterConverter(converter); } if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseCors("Cors"); IConfigProvider configProvider = app.ApplicationServices.GetService <IConfigProvider>(); IInitConfig initConfig = configProvider.GetConfig <IInitConfig>(); IJsonRpcConfig jsonRpcConfig = configProvider.GetConfig <IJsonRpcConfig>(); if (initConfig.WebSocketsEnabled) { app.UseWebSockets(); app.UseWhen(ctx => ctx.WebSockets.IsWebSocketRequest && ctx.Connection.LocalPort == jsonRpcConfig.WebSocketsPort, builder => builder.UseWebSocketsModules()); } app.Use(async(ctx, next) => { if (ctx.Request.Method == "GET") { await ctx.Response.WriteAsync("Nethermind JSON RPC"); } else if (ctx.Connection.LocalPort == jsonRpcConfig.Port && ctx.Request.Method == "POST") { Stopwatch stopwatch = Stopwatch.StartNew(); using StreamReader reader = new StreamReader(ctx.Request.Body, Encoding.UTF8); string request = await reader.ReadToEndAsync(); using JsonRpcResult result = await jsonRpcProcessor.ProcessAsync(request); ctx.Response.ContentType = "application/json"; Stream resultStream = jsonRpcConfig.BufferResponses ? new MemoryStream() : ctx.Response.Body; try { if (result.IsCollection) { _jsonSerializer.Serialize(resultStream, result.Responses); } else { _jsonSerializer.Serialize(resultStream, result.Response); } if (jsonRpcConfig.BufferResponses) { ctx.Response.ContentLength = resultStream.Length; resultStream.Seek(0, SeekOrigin.Begin); await resultStream.CopyToAsync(ctx.Response.Body); } } catch (Exception e) when(e.InnerException is OperationCanceledException) { SerializeTimeoutException(jsonRpcService, resultStream); } catch (OperationCanceledException) { SerializeTimeoutException(jsonRpcService, resultStream); } finally { await ctx.Response.CompleteAsync(); if (jsonRpcConfig.BufferResponses) { await resultStream.DisposeAsync(); } } if (result.IsCollection) { jsonRpcLocalStats.ReportCalls(result.Reports); jsonRpcLocalStats.ReportCall(new RpcReport("# collection serialization #", stopwatch.ElapsedMicroseconds(), true)); } else { jsonRpcLocalStats.ReportCall(result.Report, stopwatch.ElapsedMicroseconds()); } } }); }
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IJsonRpcProcessor jsonRpcProcessor, IJsonRpcService jsonRpcService, IJsonRpcLocalStats jsonRpcLocalStats, IJsonSerializer jsonSerializer) { long SerializeTimeoutException(IJsonRpcService service, Stream resultStream) { JsonRpcErrorResponse?error = service.GetErrorResponse(ErrorCodes.Timeout, "Request was canceled due to enabled timeout."); return(jsonSerializer.Serialize(resultStream, error)); } if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseCors("Cors"); app.UseRouting(); app.UseResponseCompression(); IConfigProvider? configProvider = app.ApplicationServices.GetService <IConfigProvider>(); IRpcAuthentication?rpcAuthentication = app.ApplicationServices.GetService <IRpcAuthentication>(); if (configProvider == null) { throw new ApplicationException($"{nameof(IConfigProvider)} has not been loaded properly"); } ILogManager? logManager = app.ApplicationServices.GetService <ILogManager>() ?? NullLogManager.Instance; ILogger logger = logManager.GetClassLogger(); IInitConfig initConfig = configProvider.GetConfig <IInitConfig>(); IJsonRpcConfig jsonRpcConfig = configProvider.GetConfig <IJsonRpcConfig>(); IJsonRpcUrlCollection jsonRpcUrlCollection = app.ApplicationServices.GetRequiredService <IJsonRpcUrlCollection>(); IHealthChecksConfig healthChecksConfig = configProvider.GetConfig <IHealthChecksConfig>(); if (initConfig.WebSocketsEnabled) { app.UseWebSockets(new WebSocketOptions()); app.UseWhen(ctx => ctx.WebSockets.IsWebSocketRequest && jsonRpcUrlCollection.TryGetValue(ctx.Connection.LocalPort, out JsonRpcUrl jsonRpcUrl) && jsonRpcUrl.RpcEndpoint.HasFlag(RpcEndpoint.Ws), builder => builder.UseWebSocketsModules()); } app.UseEndpoints(endpoints => { if (healthChecksConfig.Enabled) { try { endpoints.MapHealthChecks(healthChecksConfig.Slug, new HealthCheckOptions() { Predicate = _ => true, ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse }); if (healthChecksConfig.UIEnabled) { endpoints.MapHealthChecksUI(setup => setup.AddCustomStylesheet(Path.Combine(AppDomain.CurrentDomain.BaseDirectory !, "nethermind.css"))); } } catch (Exception e) { if (logger.IsError) { logger.Error("Unable to initialize health checks. Check if you have Nethermind.HealthChecks.dll in your plugins folder.", e); } } } }); app.Run(async(ctx) => { if (ctx.Request.Method == "GET") { await ctx.Response.WriteAsync("Nethermind JSON RPC"); } if (ctx.Request.Method == "POST" && jsonRpcUrlCollection.TryGetValue(ctx.Connection.LocalPort, out JsonRpcUrl jsonRpcUrl) && jsonRpcUrl.RpcEndpoint.HasFlag(RpcEndpoint.Http)) { if (jsonRpcUrl.IsAuthenticated && !rpcAuthentication !.Authenticate(ctx.Request.Headers["Authorization"])) { var response = jsonRpcService.GetErrorResponse(ErrorCodes.ParseError, "Authentication error"); ctx.Response.ContentType = "application/json"; ctx.Response.StatusCode = StatusCodes.Status200OK; jsonSerializer.Serialize(ctx.Response.Body, response); await ctx.Response.CompleteAsync(); return; } Stopwatch stopwatch = Stopwatch.StartNew(); using CountingTextReader request = new(new StreamReader(ctx.Request.Body, Encoding.UTF8)); try { await foreach (JsonRpcResult result in jsonRpcProcessor.ProcessAsync(request, JsonRpcContext.Http(jsonRpcUrl))) { using (result) { Stream resultStream = jsonRpcConfig.BufferResponses ? new MemoryStream() : ctx.Response.Body; long responseSize; try { ctx.Response.ContentType = "application/json"; ctx.Response.StatusCode = GetStatusCode(result); responseSize = result.IsCollection ? jsonSerializer.Serialize(resultStream, result.Responses) : jsonSerializer.Serialize(resultStream, result.Response); if (jsonRpcConfig.BufferResponses) { ctx.Response.ContentLength = responseSize = resultStream.Length; resultStream.Seek(0, SeekOrigin.Begin); await resultStream.CopyToAsync(ctx.Response.Body); } } catch (Exception e) when(e.InnerException is OperationCanceledException) { responseSize = SerializeTimeoutException(jsonRpcService, resultStream); } catch (OperationCanceledException) { responseSize = SerializeTimeoutException(jsonRpcService, resultStream); } finally { await ctx.Response.CompleteAsync(); if (jsonRpcConfig.BufferResponses) { await resultStream.DisposeAsync(); } } long handlingTimeMicroseconds = stopwatch.ElapsedMicroseconds(); if (result.IsCollection) { jsonRpcLocalStats.ReportCalls(result.Reports); jsonRpcLocalStats.ReportCall(new RpcReport("# collection serialization #", handlingTimeMicroseconds, true), handlingTimeMicroseconds, responseSize); } else { jsonRpcLocalStats.ReportCall(result.Report, handlingTimeMicroseconds, responseSize); } Interlocked.Add(ref Metrics.JsonRpcBytesSentHttp, responseSize); } // There should be only one response because we don't expect multiple JSON tokens in the request break; } } catch (Microsoft.AspNetCore.Http.BadHttpRequestException e) { if (logger.IsDebug) { logger.Debug($"Couldn't read request.{Environment.NewLine}{e}"); } } finally { Interlocked.Add(ref Metrics.JsonRpcBytesReceivedHttp, ctx.Request.ContentLength ?? request.Length); } } }); }
public static IAsyncEnumerable <JsonRpcResult> ProcessAsync(this IJsonRpcProcessor processor, string request, JsonRpcContext context) => processor.ProcessAsync(new StringReader(request), context);