private async Task RequestHandler(HttpContext context) { var requestHandlerContext = new RequestHandlerContext { HttpContext = context }; Exception exception = null; Stopwatch sp = null; try { context.Response.StatusCode = (int)HttpStatusCode.OK; context.Response.Headers["Content-Type"] = "application/json; charset=utf-8"; context.Response.Headers[Constants.Headers.ServerVersion] = RavenVersionAttribute.Instance.AssemblyVersion; if (_server.ServerStore.Initialized == false) { await _server.ServerStore.InitializationCompleted.WaitAsync(); } sp = Stopwatch.StartNew(); await _router.HandlePath(requestHandlerContext); sp.Stop(); } catch (Exception e) { sp?.Stop(); exception = e; CheckVersionAndWrapException(context, ref e); MaybeSetExceptionStatusCode(context, _server.ServerStore, e); if (context.RequestAborted.IsCancellationRequested) { return; } using (_server.ServerStore.ContextPool.AllocateOperationContext(out JsonOperationContext ctx)) { var djv = new DynamicJsonValue { [nameof(ExceptionDispatcher.ExceptionSchema.Url)] = $"{context.Request.Path}{context.Request.QueryString}", [nameof(ExceptionDispatcher.ExceptionSchema.Type)] = e.GetType().FullName, [nameof(ExceptionDispatcher.ExceptionSchema.Message)] = e.Message, [nameof(ExceptionDispatcher.ExceptionSchema.Error)] = e.ToString() }; #if EXCEPTION_ERROR_HUNT var f = Guid.NewGuid() + ".error"; File.WriteAllText(f, $"{context.Request.Path}{context.Request.QueryString}" + Environment.NewLine + errorString); #endif MaybeAddAdditionalExceptionData(djv, e); await using (var writer = new AsyncBlittableJsonTextWriter(ctx, context.Response.Body)) { var json = ctx.ReadObject(djv, "exception"); writer.WriteObject(json); } #if EXCEPTION_ERROR_HUNT File.Delete(f); #endif } } finally { // check if TW has clients if (TrafficWatchManager.HasRegisteredClients) { var database = requestHandlerContext.Database?.Name; LogTrafficWatch(context, sp?.ElapsedMilliseconds ?? 0, database); } if (sp != null && requestHandlerContext.HttpContext.Response.StatusCode != (int)HttpStatusCode.SwitchingProtocols) // exclude web sockets { var requestDuration = sp.ElapsedMilliseconds; requestHandlerContext.RavenServer?.Metrics.Requests.UpdateDuration(requestDuration); requestHandlerContext.Database?.Metrics.Requests.UpdateDuration(requestDuration); } if (_logger.IsInfoEnabled && SkipHttpLogging == false) { _logger.Info($"{context.Request.Method} {context.Request.Path.Value}{context.Request.QueryString.Value} - {context.Response.StatusCode} - {(sp?.ElapsedMilliseconds ?? 0):#,#;;0} ms", exception); } } }
private async Task RequestHandler(HttpContext context) { string database = null; try { context.Response.StatusCode = (int)HttpStatusCode.OK; context.Response.Headers["Content-Type"] = "application/json; charset=utf-8"; var sp = Stopwatch.StartNew(); database = await _router.HandlePath(context, context.Request.Method, context.Request.Path.Value); sp.Stop(); if (_logger.IsInfoEnabled && SkipHttpLogging == false) { _logger.Info($"{context.Request.Method} {context.Request.Path.Value}?{context.Request.QueryString.Value} - {context.Response.StatusCode} - {sp.ElapsedMilliseconds:#,#;;0} ms"); } if (TrafficWatchManager.HasRegisteredClients) { LogTrafficWatch(context, sp.ElapsedMilliseconds, database); } } catch (Exception e) { if (TrafficWatchManager.HasRegisteredClients) { LogTrafficWatch(context, 0, database ?? "N/A"); } if (context.RequestAborted.IsCancellationRequested) { return; } //TODO: special handling for argument exception (400 bad request) //TODO: operation canceled (timeout) //TODO: Invalid data exception 422 //TODO: Proper json output, not like this MaybeSetExceptionStatusCode(context, e); using (_server.ServerStore.ContextPool.AllocateOperationContext(out JsonOperationContext ctx)) { var djv = new DynamicJsonValue { [nameof(ExceptionDispatcher.ExceptionSchema.Url)] = $"{context.Request.Path}{context.Request.QueryString}", [nameof(ExceptionDispatcher.ExceptionSchema.Type)] = e.GetType().FullName, [nameof(ExceptionDispatcher.ExceptionSchema.Message)] = e.Message }; #if EXCEPTION_ERROR_HUNT var f = Guid.NewGuid() + ".error"; File.WriteAllText(f, $"{context.Request.Path}{context.Request.QueryString}" + Environment.NewLine + errorString); #endif djv[nameof(ExceptionDispatcher.ExceptionSchema.Error)] = e.ToString(); MaybeAddAdditionalExceptionData(djv, e); var response = context.Response; using (var writer = new BlittableJsonTextWriter(ctx, response.Body)) { var json = ctx.ReadObject(djv, "exception"); writer.WriteObject(json); } #if EXCEPTION_ERROR_HUNT File.Delete(f); #endif } } }
private async Task RequestHandler(HttpContext context) { try { context.Response.StatusCode = 200; var sp = Stopwatch.StartNew(); var tenant = await _router.HandlePath(context, context.Request.Method, context.Request.Path.Value); sp.Stop(); if (_logger.IsInfoEnabled) { _logger.Info($"{context.Request.Method} {context.Request.Path.Value}?{context.Request.QueryString.Value} - {context.Response.StatusCode} - {sp.ElapsedMilliseconds:#,#;;0} ms"); } if (TrafficWatchManager.HasRegisteredClients) { var requestId = Interlocked.Increment(ref _requestId); var twn = new TrafficWatchNotification { TimeStamp = DateTime.UtcNow, RequestId = requestId, // counted only for traffic watch HttpMethod = context.Request.Method ?? "N/A", // N/A ? ElapsedMilliseconds = sp.ElapsedMilliseconds, ResponseStatusCode = context.Response.StatusCode, RequestUri = context.Request.GetEncodedUrl(), AbsoluteUri = $@"{context.Request.Scheme}://{context.Request.Host}", TenantName = tenant ?? "N/A", CustomInfo = "", // TODO: Implement InnerRequestsCount = 0, // TODO: Implement QueryTimings = null, // TODO: Implement }; TrafficWatchManager.DispatchMessage(twn); } } catch (Exception e) { if (context.RequestAborted.IsCancellationRequested) { return; } //TODO: special handling for argument exception (400 bad request) //TODO: database not found (503) //TODO: operaton cancelled (timeout) //TODO: Invalid data exception 422 //TODO: Proper json output, not like this var response = context.Response; var documentConflictException = e as DocumentConflictException; if (response.HasStarted == false) { if (documentConflictException != null) { response.StatusCode = 409; } else if (response.StatusCode < 400) { response.StatusCode = 500; } } JsonOperationContext ctx; using (_server.ServerStore.ContextPool.AllocateOperationContext(out ctx)) { var djv = new DynamicJsonValue { ["Url"] = $"{context.Request.Path}?{context.Request.QueryString}", ["Type"] = e.GetType().FullName, ["Message"] = e.Message }; string errorString; try { errorString = e.ToAsyncString(); } catch (Exception) { errorString = e.ToString(); } djv["Error"] = errorString; var indexCompilationException = e as IndexCompilationException; if (indexCompilationException != null) { djv[nameof(IndexCompilationException.IndexDefinitionProperty)] = indexCompilationException.IndexDefinitionProperty; djv[nameof(IndexCompilationException.ProblematicText)] = indexCompilationException.ProblematicText; } if (documentConflictException != null) { djv["ConflictInfo"] = ReplicationUtils.GetJsonForConflicts( documentConflictException.DocId, documentConflictException.Conflicts); } using (var writer = new BlittableJsonTextWriter(ctx, response.Body)) { var json = ctx.ReadObject(djv, "exception"); writer.WriteObject(json); } } } }
private async Task RequestHandler(HttpContext context) { string database = null; try { context.Response.StatusCode = (int)HttpStatusCode.OK; context.Response.Headers["Content-Type"] = "application/json; charset=utf-8"; var sp = Stopwatch.StartNew(); database = await _router.HandlePath(context, context.Request.Method, context.Request.Path.Value); sp.Stop(); if (_logger.IsInfoEnabled && SkipHttpLogging == false) { _logger.Info($"{context.Request.Method} {context.Request.Path.Value}?{context.Request.QueryString.Value} - {context.Response.StatusCode} - {sp.ElapsedMilliseconds:#,#;;0} ms"); } if (TrafficWatchManager.HasRegisteredClients) { LogTrafficWatch(context, sp.ElapsedMilliseconds, database); } } catch (Exception e) { if (TrafficWatchManager.HasRegisteredClients) { LogTrafficWatch(context, 0, database ?? "N/A"); } if (context.RequestAborted.IsCancellationRequested) { return; } if (context.Request.Headers.TryGetValue(Constants.Headers.ClientVersion, out var versions)) { var version = versions.ToString(); if (version.Length > 0 && version[0] != RavenVersionAttribute.Instance.MajorVersionAsChar) { e = new ClientVersionMismatchException($"RavenDB does not support interaction between Client API and Server when major version does not match. Client: {version}. Server: {RavenVersionAttribute.Instance.AssemblyVersion}", e); } } MaybeSetExceptionStatusCode(context, e); using (_server.ServerStore.ContextPool.AllocateOperationContext(out JsonOperationContext ctx)) { var djv = new DynamicJsonValue { [nameof(ExceptionDispatcher.ExceptionSchema.Url)] = $"{context.Request.Path}{context.Request.QueryString}", [nameof(ExceptionDispatcher.ExceptionSchema.Type)] = e.GetType().FullName, [nameof(ExceptionDispatcher.ExceptionSchema.Message)] = e.Message, [nameof(ExceptionDispatcher.ExceptionSchema.Error)] = e.ToString() }; #if EXCEPTION_ERROR_HUNT var f = Guid.NewGuid() + ".error"; File.WriteAllText(f, $"{context.Request.Path}{context.Request.QueryString}" + Environment.NewLine + errorString); #endif MaybeAddAdditionalExceptionData(djv, e); using (var writer = new BlittableJsonTextWriter(ctx, context.Response.Body)) { var json = ctx.ReadObject(djv, "exception"); writer.WriteObject(json); } #if EXCEPTION_ERROR_HUNT File.Delete(f); #endif } } }
private async Task RequestHandler(HttpContext context) { try { context.Response.StatusCode = (int)HttpStatusCode.OK; context.Response.Headers["Content-Type"] = "application/json; charset=utf-8"; var sp = Stopwatch.StartNew(); var database = await _router.HandlePath(context, context.Request.Method, context.Request.Path.Value); sp.Stop(); if (_logger.IsInfoEnabled && SkipHttpLogging == false) { _logger.Info($"{context.Request.Method} {context.Request.Path.Value}?{context.Request.QueryString.Value} - {context.Response.StatusCode} - {sp.ElapsedMilliseconds:#,#;;0} ms"); } if (TrafficWatchManager.HasRegisteredClients) { var requestId = Interlocked.Increment(ref _requestId); var twn = new TrafficWatchChange { TimeStamp = DateTime.UtcNow, RequestId = requestId, // counted only for traffic watch HttpMethod = context.Request.Method ?? "N/A", // N/A ? ElapsedMilliseconds = sp.ElapsedMilliseconds, ResponseStatusCode = context.Response.StatusCode, RequestUri = context.Request.GetEncodedUrl(), AbsoluteUri = $@"{context.Request.Scheme}://{context.Request.Host}", DatabaseName = database ?? "N/A", CustomInfo = "", // TODO: Implement InnerRequestsCount = 0, // TODO: Implement QueryTimings = null // TODO: Implement }; TrafficWatchManager.DispatchMessage(twn); } } catch (Exception e) { if (context.RequestAborted.IsCancellationRequested) { return; } //TODO: special handling for argument exception (400 bad request) //TODO: operation canceled (timeout) //TODO: Invalid data exception 422 //TODO: Proper json output, not like this var response = context.Response; MaybeSetExceptionStatusCode(response, e); using (_server.ServerStore.ContextPool.AllocateOperationContext(out JsonOperationContext ctx)) { var djv = new DynamicJsonValue { [nameof(ExceptionDispatcher.ExceptionSchema.Url)] = $"{context.Request.Path}{context.Request.QueryString}", [nameof(ExceptionDispatcher.ExceptionSchema.Type)] = e.GetType().FullName, [nameof(ExceptionDispatcher.ExceptionSchema.Message)] = e.Message }; #if EXCEPTION_ERROR_HUNT var f = Guid.NewGuid() + ".error"; File.WriteAllText(f, $"{context.Request.Path}{context.Request.QueryString}" + Environment.NewLine + errorString); #endif djv[nameof(ExceptionDispatcher.ExceptionSchema.Error)] = e.ToString(); MaybeAddAdditionalExceptionData(djv, e); using (var writer = new BlittableJsonTextWriter(ctx, response.Body)) { var json = ctx.ReadObject(djv, "exception"); writer.WriteObject(json); } #if EXCEPTION_ERROR_HUNT File.Delete(f); #endif } } }