예제 #1
0
        private Task HandleRequest <TRequest, TResponse>(Func <TRequest, TResponse> handler, bool limitRatio = false) where TRequest : BaseRequest
        {
            // setup response
            Response.Headers.Add("Content-Type", "application/json; charset=utf-8");

            // load request body
            using var reader = new StreamReader(Request.Body);
            var body = reader.ReadToEnd();

            _logger.LogInformation($"REQUEST {typeof(TRequest)}:\n{body}");
            var request = JsonConvert.DeserializeObject <TRequest>(body, Utils.ConverterSettings);

            // check sign
            if (request == null || !_socialService.IsSignValid(request.UserId, request.Params, request.Sign))
            {
                _logger.LogWarning("Signature calculation failed");
                Response.StatusCode = 400;
                return(Response.WriteAsync(new ErrorResponse("Signature calculation failed").ToString()));
            }

            // check requests ratio
            if (limitRatio)
            {
                if (!_concurrencyService.CheckAddRequest(request.UserId))
                {
                    _logger.LogWarning("Too many requests");
                    Response.StatusCode = 400;
                    return(Response.WriteAsync(
                               new ErrorResponse("Вы вызываете запросы слишком часто, попробуйте через несколько секунд")
                               .ToString()
                               ));
                }
            }

            // handle request
            try
            {
                var response       = handler(request);
                var stringResponse = JsonConvert.SerializeObject(response, Utils.ConverterSettings);

                _logger.LogInformation($"RESPONSE:\n{stringResponse.SafeSubstring(300)}");
                return(Response.WriteAsync(stringResponse));
            }
            catch (KeyNotFoundException e)
            {
                _logger.LogWarning(e.Message);
                Response.StatusCode = 400;
                return(Response.WriteAsync(new ErrorResponse("Такой дуэли больше нет").ToString())); // TODO error codes
            }
            catch (Exception e)
            {
#if DEBUG
                throw;
#endif
                _logger.LogWarning(e.Message);
                Response.StatusCode = 400;
                return(Response.WriteAsync(new ErrorResponse(e.Message).ToString()));
            }
        }