public async Task InvokeAsync(HttpContext context, RequestDelegate next)
        {
            try
            {
                await next.Invoke(context);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, ex.Message);
                _sentry.CaptureException(ex);

                var bae = ex as BaeException;
                if (!(ex is BaeException))
                {
                    // TODO(0xdeafcafe): How should this be done?
                    bae = new BaeException(BaeCodes.Unknown);
                }

                var json = JsonConvert.SerializeObject(bae, _jsonSerializerSettings);

                context.Response.StatusCode  = bae.StatusCode();
                context.Response.ContentType = "application/json; charset=utf-8";
                await context.Response.WriteAsync(json);
            }
        }
Beispiel #2
0
        public async Task SetCacheMeta(string identifier, string cacheState, BaeException cacheFailure = null)
        {
            using (var command = Connection.CreateCommand())
            {
                command.CommandText = @"
					INSERT INTO cache_meta
						(id, identifier, cache_state, cache_failure)
					VALUES
						(@id, @identifier, @cache_state, @cache_failure)
					ON CONFLICT (identifier)
					DO UPDATE SET
						cache_state = @cache_state, cache_failure = @cache_failure, updated_at = NOW();
				"                ;

                command.Parameters.AddWithValue("@id", Ksuid.Ksuid.Generate("h2cachemeta").ToString());
                command.Parameters.AddWithValue("@identifier", identifier);
                command.Parameters.AddWithValueAsEnum("@cache_state", cacheState, "cache_status");
                command.Parameters.AddWithJsonOrNull("@cache_failure", cacheFailure);

                if (await command.ExecuteNonQueryAsync() != 1)
                {
                    throw new InvalidOperationException("Zero rows affected. Expected 1");
                }
            }
        }
Beispiel #3
0
        public async Task InvokeAsync(HttpContext context, RequestDelegate next)
        {
            if (context.Request.Method != "POST")
            {
                throw new BaeException(BaeCodes.MethodNotAllowed);
            }

            ensureAcceptIsAllowed(context);

            var match = _urlRegex.Match(context.Request.Path.ToUriComponent());

            if (match.Groups.Count != 3)
            {
                throw new BaeException(BaeCodes.RouteNotFound);
            }

            var urlDate   = match.Groups[1].Value;
            var urlMethod = match.Groups[2].Value;

            if (!_registrationOptions.Registrations.ContainsKey(urlMethod))
            {
                throw new BaeException(BaeCodes.RouteNotFound);
            }

            var registration = _registrationOptions.Registrations[urlMethod];
            KeyValuePair <string, CrpcVersionRegistration> version;

            switch (urlDate)
            {
            case "preview":
                version = registration.FirstOrDefault(r => r.Value.IsPreview);
                break;

            case "latest":
                var versions = registration.Where(r => !r.Value.IsPreview).Select(r => r.Key);

                // If the method is only in preview, it should only be exposed if
                // preview is explicitly stated
                if (versions.Count() == 0)
                {
                    throw new BaeException(BaeCodes.RouteNotFound);
                }

                var latestVersion = versions.OrderByDescending(v => DateTime.Parse(v)).First();

                version = registration.First(r => r.Key == latestVersion);
                break;

            default:
                if (!registration.ContainsKey(urlDate))
                {
                    throw new BaeException(BaeCodes.RouteNotFound);
                }

                version = registration.First(r => r.Key == urlDate);
                break;
            }

            var request  = readRequest(context, version.Value);
            var response = await(dynamic) version.Value.Method.Invoke(_server, new object[] { request });

            if (response == null && version.Value.ResponseType != null)
            {
                var ex = new BaeException("missing_response");

                _logger.LogError(ex, "A response was expected but isn't present");

                throw ex;
            }

            if (response == null)
            {
                context.Response.StatusCode = (int)HttpStatusCode.NoContent;
                return;
            }

            string json = JsonConvert.SerializeObject(response, _jsonSerializerSettings);

            context.Response.StatusCode  = (int)HttpStatusCode.OK;
            context.Response.ContentType = "application/json; charset=utf-8";
            await context.Response.WriteAsync(json);
        }