ruby-on-rails ruby ruby-on-rails-3 utf-8 ruby-1.9.3

Ruby on Rails "secuencia de bytes no válida en UTF-8" debido a bot



ruby-on-rails ruby-on-rails-3 (3)

Tengo algunos errores desencadenados por un bot chino: http://www.easou.com/search/spider.html cuando se desplaza por mis sitios web.

Las versiones de mis aplicaciones son todas con Ruby 1.9.3 y Rails 3.2.X

Aquí una stacktrace:

An ArgumentError occurred in listings#show: invalid byte sequence in UTF-8 rack (1.4.5) lib/rack/utils.rb:104:in `normalize_params'' ------------------------------- Request: ------------------------------- * URL : http://www.my-website.com * IP address: X.X.X.X * Parameters: {"action"=>"show", "controller"=>"listings", "id"=>"location-t7-villeurbanne--58"} * Rails root: /.../releases/20140708150222 * Timestamp : 2014-07-09 02:57:43 +0200 ------------------------------- Backtrace: ------------------------------- rack (1.4.5) lib/rack/utils.rb:104:in `normalize_params'' rack (1.4.5) lib/rack/utils.rb:96:in `block in parse_nested_query'' rack (1.4.5) lib/rack/utils.rb:93:in `each'' rack (1.4.5) lib/rack/utils.rb:93:in `parse_nested_query'' rack (1.4.5) lib/rack/request.rb:332:in `parse_query'' actionpack (3.2.18) lib/action_dispatch/http/request.rb:275:in `parse_query'' rack (1.4.5) lib/rack/request.rb:209:in `POST'' actionpack (3.2.18) lib/action_dispatch/http/request.rb:237:in `POST'' actionpack (3.2.18) lib/action_dispatch/http/parameters.rb:10:in `parameters'' ------------------------------- Session: ------------------------------- * session id: nil * data: {} ------------------------------- Environment: ------------------------------- * CONTENT_LENGTH : 514 * CONTENT_TYPE : application/x-www-form-urlencoded * HTTP_ACCEPT : text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1 * HTTP_ACCEPT_ENCODING : gzip, deflate * HTTP_ACCEPT_LANGUAGE : zh;q=0.9,en;q=0.8 * HTTP_CONNECTION : close * HTTP_HOST : www.my-website.com * HTTP_REFER : http://www.my-website.com/ * HTTP_USER_AGENT : Mozilla/5.0 (compatible; EasouSpider; +http://www.easou.com/search/spider.html) * ORIGINAL_FULLPATH : / * PASSENGER_APP_SPAWNER_IDLE_TIME : -1 * PASSENGER_APP_TYPE : rack * PASSENGER_CONNECT_PASSWORD : [FILTERED] * PASSENGER_DEBUGGER : false * PASSENGER_ENVIRONMENT : production * PASSENGER_FRAMEWORK_SPAWNER_IDLE_TIME : -1 * PASSENGER_FRIENDLY_ERROR_PAGES : true * PASSENGER_GROUP : * PASSENGER_MAX_REQUESTS : 0 * PASSENGER_MIN_INSTANCES : 1 * PASSENGER_SHOW_VERSION_IN_HEADER : true * PASSENGER_SPAWN_METHOD : smart-lv2 * PASSENGER_USER : * PASSENGER_USE_GLOBAL_QUEUE : true * PATH_INFO : / * QUERY_STRING : * REMOTE_ADDR : 183.60.212.153 * REMOTE_PORT : 52997 * REQUEST_METHOD : GET * REQUEST_URI : / * SCGI : 1 * SCRIPT_NAME : * SERVER_PORT : 80 * SERVER_PROTOCOL : HTTP/1.1 * SERVER_SOFTWARE : nginx/1.2.6 * UNION_STATION_SUPPORT : false * _ : _ * action_controller.instance : listings#show * action_dispatch.backtrace_cleaner : #<Rails::BacktraceCleaner:0x000000056e8660> * action_dispatch.cookies : #<ActionDispatch::Cookies::CookieJar:0x00000006564e28> * action_dispatch.logger : #<ActiveSupport::TaggedLogging:0x0000000318aff8> * action_dispatch.parameter_filter : [:password, /RAW_POST_DATA/, /RAW_POST_DATA/, /RAW_POST_DATA/] * action_dispatch.remote_ip : 183.60.212.153 * action_dispatch.request.content_type : application/x-www-form-urlencoded * action_dispatch.request.parameters : {"action"=>"show", "controller"=>"listings", "id"=>"location-t7-villeurbanne--58"} * action_dispatch.request.path_parameters : {:action=>"show", :controller=>"listings", :id=>"location-t7-villeurbanne--58"} * action_dispatch.request.query_parameters : {} * action_dispatch.request.request_parameters : {} * action_dispatch.request.unsigned_session_cookie: {} * action_dispatch.request_id : 9f8afbc8ff142f91ddbd9cabee3629f3 * action_dispatch.routes : #<ActionDispatch::Routing::RouteSet:0x0000000339f370> * action_dispatch.show_detailed_exceptions : false * action_dispatch.show_exceptions : true * rack-cache.allow_reload : false * rack-cache.allow_revalidate : false * rack-cache.cache_key : Rack::Cache::Key * rack-cache.default_ttl : 0 * rack-cache.entitystore : rails:/ * rack-cache.ignore_headers : ["Set-Cookie"] * rack-cache.metastore : rails:/ * rack-cache.private_headers : ["Authorization", "Cookie"] * rack-cache.storage : #<Rack::Cache::Storage:0x000000039c5768> * rack-cache.use_native_ttl : false * rack-cache.verbose : false * rack.errors : #<IO:0x000000006592a8> * rack.input : #<PhusionPassenger::Utils::RewindableInput:0x0000000655b3a0> * rack.multiprocess : true * rack.multithread : false * rack.request.cookie_hash : {} * rack.request.form_hash : * rack.request.form_input : #<PhusionPassenger::Utils::RewindableInput:0x0000000655b3a0> * rack.request.form_vars : ���W�"��陷q�B��)��� �F��P Z� 8�� & G/y�P��u�T ed �.�%�mxEAẳ/�d*�Hg� �C賳�lj��� � U 1��]pgt�P� Ɗ ��c"� ��LX��D���HR�y��p`6�l���lN�P �l�S����`V4y��c����X2� &JO!��*p �l��-�гU��w }g�ԍk�� (� F J�� q�:�5G�Jh�pί����ࡃ] �z�h���� d }�} * rack.request.query_hash : {} * rack.request.query_string : * rack.run_once : false * rack.session : {} * rack.session.options : {:path=>"/", :domain=>nil, :expire_after=>nil, :secure=>false, :httponly=>true, :defer=>false, :renew=>false, :coder=>#<Rack::Session::Cookie::Base64::Marshal:0x000000034d4ad8>, :id=>nil} * rack.url_scheme : http * rack.version : [1, 0]

Como puede ver, no existe un utf-8 no válido en la url pero solo en el rack.request.form_vars . Tengo alrededor de cien errores por día, y todos similares a este.

Entonces, intenté forzar utf-8 en rack.request.form_vars con algo como esto:

class RackFormVarsSanitizer def initialize(app) @app = app end def call(env) if env["rack.request.form_vars"] env["rack.request.form_vars"] = env["rack.request.form_vars"].force_encoding(''UTF-8'') end @app.call(env) end end

Y lo llamo en mi application.rb :

config.middleware.use "RackFormVarsSanitizer"

No parece funcionar porque ya tengo errores. El problema es que no puedo probar en modo de desarrollo porque no sé cómo configurar rack.request.form_vars .

utf8-cleaner gema utf8-cleaner pero no soluciona nada.

Alguien tiene una idea para arreglar esto? o para activarlo en el desarrollo?


Agregue esta línea a su Gemfile , luego ejecute bundle en su terminal:

gem "handle_invalid_percent_encoding_requests"

Esta solución se basa en la respuesta de Henrik , convertida en una gema de Rails Engine .


Entonces no tienes que armar los comentarios en mi otra respuesta, esto es lo que estoy haciendo ahora. No he visto ningún error durante 24 horas, así que parece muy prometedor:

Agrega rack-utf8_sanitizer a tu Gemfile:

gem ''rack-utf8_sanitizer''

y correr

bundle

Coloque este middleware en la app/middleware/handle_invalid_percent_encoding.rb y cambie el nombre de la clase HandleInvalidPercentEncoding (porque ExceptionApp es un poco demasiado general).

En el bloque de config/application.rb de config/application.rb do:

require "#{Rails.root}/app/middleware/handle_invalid_percent_encoding.rb" # NOTE: These must be in this order relative to each other. # HandleInvalidPercentEncoding just raises for encoding errors it doesn''t cover, # so it must run after (= be inserted before) Rack::UTF8Sanitizer. config.middleware.insert 0, HandleInvalidPercentEncoding config.middleware.insert 0, Rack::UTF8Sanitizer # from a gem

Desplegar. Hecho.

(La app es la ubicación de middleware en el proyecto en el que estoy trabajando, pero probablemente preferiría lib . Lo que sea, cualquiera debería funcionar).


Hay un problema en el repositorio de gemas con un enlace a la posible solución de alguien : dicen que funciona para ellos, pero no están seguros de si es una buena solución.

Todavía tengo que intentarlo, pero creo que lo haré.