Rails RoutingError из-за сбоя ограничения (IP-список файлов) - PullRequest
0 голосов
/ 26 февраля 2020

Я пытаюсь получить IP-доступ к белому списку к определенному файлу, установив ограничение на маршрут файла.

## config/routes.rb
get 'SOME FILE',
      to: 'main#(function that renders the file as plain)',
      constraints: <IP CONSTRAINT CLASS>.new


## (ip constraint class).rb
require 'ipaddr'
WHITELIST = %w(8.8.8.8/27).freeze

    def matches?(request)
      request && APPLE_IP_WHITELIST.reduce(false) do |match, range|
        match || IPAddr.new(range).include?(request.remote_addr)
      end
    end

Для IP-адресов вне белого списка выдается ошибка RoutingError. Я пытаюсь обработать ошибку, используя перехват всех маршрутов.

## config/routes.rb
get '*unmatched_route', :to => 'application#show_not_found', via: :all


## app/controllers/application_controller.rb
def show_not_found
  render_error_status(404)
end

def render_error_status(status)
    @status = status
    template = case @status
               when 400, 401, 403, 405
                 'application/errors/standard'
               when 404, 422
                 'application/errors/with_block'
               when 500
                 'application/errors/custom_500'
               end
    render template: template, layout: 'error', status: @status
end

Интересно, что когда я пытаюсь получить доступ к какому-то бессмысленному маршруту, например, localhost: 3000 / asdf, соответствующая страница 404 (приложение / ошибки /with_block.html.haml). Однако, когда обрабатывается белый список RoutingError, я получаю

ActionView :: MissingTemplate (Отсутствует шаблон приложения / errors / with_block с {: locale => [: en],: format => [: text], : варианты => [],: обработчики => [: raw,: erb,: html,: builder,: ruby,: haml,: coffee]}. Поиск в: * "... / app / views "*" ... /.rbenv/versions/2.5.7/lib/ruby/gems/2.5.0/gems/kaminari-0.17.0/app/views "):

tldr: как обработать RoutingError в результате сбоя ограничения?

Редактировать: кажется, что форматы: [: html] необходимо добавлять при вызове render - но почему это необходимо сейчас, а не в других случаях, когда вызывается render_error_status?

1 Ответ

1 голос
/ 26 февраля 2020

Основная проблема связана с типом запроса: при сбое ограничения маршрутизации Rails пытается найти файл в текстовом формате, см. Ошибку:

ActionView::MissingTemplate (Missing template application/errors/with_block with {:locale=>[:en], :formats=>[:text]

Это потому, что вы запрашиваете текстовый файл из маршрут, который не может быть возвращен, потому что ваше ограничение маршрутизации не выполнено. Поэтому, когда тип запроса text, страница ошибки также должна быть в этом формате. Например, если у меня есть API, куда я отправляю запрос JSON, и если есть проблема с разрешением, и я предоставляю ответ HTML, тогда он будет бесполезен для API. Таким образом, формат запроса и ответа должен быть одинаковым в Rails при использовании соглашений по умолчанию.

Ваш метод должен иметь разные типы ответов, такие как:

def render_error_status(status)
  status = status
  template = case status
             when 400, 401, 403, 405
               'application/errors/standard'
             when 404, 422
               'application/errors/with_block'
             when 500
               'application/errors/custom_500'
             end
  respond_to do |format|
    format.html { render template, status: status }
    format.text { render text: 'Not found', status: :not_found }
  end
end

Есть и другие опции, доступные для выполнения это похоже на ответ HTML в случае текстового запроса, но стандартный способ Rails такой:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...