J'ai des erreurs déclenchées par un bot chinois: http://www.easou.com/search/spider.html lorsqu'il fait défiler mes sites Web.
Les versions de mes applications sont toutes avec Ruby 1.9.3 et Rails 3.2.X
Voici un 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]
Comme vous pouvez le voir, il n'y a pas d'utf-8 invalide dans l'url mais seulement dans le rack.request.form_vars
. J'ai environ une centaine d'erreurs par jour, et toutes similaires à celle-ci.
J'ai donc essayé de forcer utf-8 dans rack.request.form_vars
avec quelque chose comme ceci:
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
Et je l'appelle dans mon application.rb
:
config.middleware.use "RackFormVarsSanitizer"
Cela ne semble pas fonctionner car j'ai déjà des erreurs. Le problème est que je ne peux pas tester en mode développement car je ne sais pas comment définir rack.request.form_vars
.
J'ai installé utf8-cleaner
gem mais ça ne règle rien.
Quelqu'un a une idée pour résoudre ce problème? ou pour le déclencher en développement?
Vous n'avez donc pas besoin de rassembler les commentaires dans mon autre réponse, c'est ce que je fais maintenant - je n'ai vu aucune erreur pendant 24 heures, donc cela semble très prometteur:
Ajoutez rack-utf8_sanitizer à votre Gemfile:
gem 'rack-utf8_sanitizer'
et courir
bundle
Mettez ce middleware dans app/middleware/handle_invalid_percent_encoding.rb
et renommez la classe HandleInvalidPercentEncoding
(car ExceptionApp
est un peu trop général).
Dans le bloc config
de config/application.rb
faire:
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
Déployer. Terminé.
(app
se trouve être l'emplacement du middleware dans le projet sur lequel je travaille, mais je préférerais probablement lib
. Peu importe. L'un ou l'autre devrait fonctionner.)
Ajoutez cette ligne dans votre Gemfile
, puis exécutez bundle
dans votre terminal:
gem "handle_invalid_percent_encoding_requests"
Cette solution est basée sur réponse d'Henrik , transformée en a Rails Gemme du moteur .
Il y a n problème dans le dépôt de gemmes avec un lien vers la solution possible de quelqu'un - ils disent que cela fonctionne pour eux mais ils ne sont pas sûrs que ce soit une bonne solution.
Je n'ai pas encore essayé, mais je pense que je le ferai.