2013-04-29 20 views
34

Geçtiğimiz ay, sitemizde düzenli olarak yayınladığımız bir bot var. Bu nedenle, URL'ler hatalı biçimlendirilmiş olduğundan, ArgumentError: invalid %-encoding hatalarıyla karşılaşıyor. here ve here raflarında ve here raylarında bir dizi soruna baktım ve this SO thread'a baktım ama kesin bir çözüm yok gibi görünüyor. GET hataları için doğru bir çözüm var mı? Maymun rafına mı ihtiyacım var?Rails ArgumentError: invalid% -encoding

düzenleme:

/usr/local/lib/ruby/1.9.1/uri/common.rb:898:in `decode_www_form_component' 
[GEM_ROOT]/gems/rack-1.4.5/lib/rack/utils.rb:41:in `unescape' 
[GEM_ROOT]/gems/rack-1.4.5/lib/rack/utils.rb:94:in `block (2 levels) in parse_nested_query' 
[GEM_ROOT]/gems/rack-1.4.5/lib/rack/utils.rb:94:in `map' 
[GEM_ROOT]/gems/rack-1.4.5/lib/rack/utils.rb:94:in `block in parse_nested_query' 
[GEM_ROOT]/gems/rack-1.4.5/lib/rack/utils.rb:93:in `each' 
[GEM_ROOT]/gems/rack-1.4.5/lib/rack/utils.rb:93:in `parse_nested_query' 
[GEM_ROOT]/gems/rack-1.4.5/lib/rack/request.rb:332:in `parse_query' 
[GEM_ROOT]/gems/actionpack-3.2.12/lib/action_dispatch/http/request.rb:269:in `parse_query' 
[GEM_ROOT]/gems/rack-1.4.5/lib/rack/request.rb:186:in `GET' 
[GEM_ROOT]/gems/actionpack-3.2.12/lib/action_dispatch/http/request.rb:225:in `GET' 
[GEM_ROOT]/gems/actionpack-3.2.12/lib/action_dispatch/http/parameters.rb:10:in `parameters' 
[GEM_ROOT]/gems/actionpack-3.2.12/lib/action_dispatch/http/filter_parameters.rb:33:in `filtered_parameters' 
[GEM_ROOT]/gems/actionpack-3.2.12/lib/action_controller/metal/instrumentation.rb:21:in `process_action' 
[GEM_ROOT]/gems/actionpack-3.2.12/lib/action_controller/metal/params_wrapper.rb:207:in `process_action' 
[GEM_ROOT]/gems/activerecord-3.2.12/lib/active_record/railties/controller_runtime.rb:18:in `process_action' 
[GEM_ROOT]/gems/actionpack-3.2.12/lib/abstract_controller/base.rb:121:in `process' 
[GEM_ROOT]/gems/actionpack-3.2.12/lib/abstract_controller/rendering.rb:45:in `process' 
[GEM_ROOT]/gems/actionpack-3.2.12/lib/action_controller/metal.rb:203:in `dispatch' 
[GEM_ROOT]/gems/actionpack-3.2.12/lib/action_controller/metal/rack_delegation.rb:14:in `dispatch' 
[GEM_ROOT]/gems/actionpack-3.2.12/lib/action_controller/metal.rb:246:in `block in action' 
[GEM_ROOT]/gems/actionpack-3.2.12/lib/action_dispatch/routing/route_set.rb:73:in `call' 
[GEM_ROOT]/gems/actionpack-3.2.12/lib/action_dispatch/routing/route_set.rb:73:in `dispatch' 
[GEM_ROOT]/gems/actionpack-3.2.12/lib/action_dispatch/routing/route_set.rb:36:in `call' 
[GEM_ROOT]/gems/journey-1.0.4/lib/journey/router.rb:68:in `block in call' 
[GEM_ROOT]/gems/journey-1.0.4/lib/journey/router.rb:56:in `each' 
[GEM_ROOT]/gems/journey-1.0.4/lib/journey/router.rb:56:in `call' 
[GEM_ROOT]/gems/actionpack-3.2.12/lib/action_dispatch/routing/route_set.rb:601:in `call' 
[GEM_ROOT]/gems/omniauth-1.1.1/lib/omniauth/strategy.rb:177:in `call!' 
[GEM_ROOT]/gems/omniauth-1.1.1/lib/omniauth/strategy.rb:157:in `call' 
[GEM_ROOT]/gems/sass-3.2.7/lib/sass/plugin/rack.rb:54:in `call' 
[GEM_ROOT]/gems/warden-1.2.1/lib/warden/manager.rb:35:in `block in call' 
[GEM_ROOT]/gems/warden-1.2.1/lib/warden/manager.rb:34:in `catch' 
[GEM_ROOT]/gems/warden-1.2.1/lib/warden/manager.rb:34:in `call' 
[GEM_ROOT]/gems/actionpack-3.2.12/lib/action_dispatch/middleware/best_standards_support.rb:17:in `call' 
[GEM_ROOT]/gems/rack-1.4.5/lib/rack/etag.rb:23:in `call' 
[GEM_ROOT]/gems/rack-1.4.5/lib/rack/conditionalget.rb:25:in `call' 
[GEM_ROOT]/gems/actionpack-3.2.12/lib/action_dispatch/middleware/head.rb:14:in `call' 
[GEM_ROOT]/gems/actionpack-3.2.12/lib/action_dispatch/middleware/params_parser.rb:21:in `call' 
[GEM_ROOT]/gems/actionpack-3.2.12/lib/action_dispatch/middleware/flash.rb:242:in `call' 
[GEM_ROOT]/gems/rack-1.4.5/lib/rack/session/abstract/id.rb:210:in `context' 
[GEM_ROOT]/gems/rack-1.4.5/lib/rack/session/abstract/id.rb:205:in `call' 
[GEM_ROOT]/gems/actionpack-3.2.12/lib/action_dispatch/middleware/cookies.rb:341:in `call' 
[GEM_ROOT]/gems/activerecord-3.2.12/lib/active_record/query_cache.rb:64:in `call' 
[GEM_ROOT]/gems/activerecord-3.2.12/lib/active_record/connection_adapters/abstract/connection_pool.rb:479:in `call' 
[GEM_ROOT]/gems/actionpack-3.2.12/lib/action_dispatch/middleware/callbacks.rb:28:in `block in call' 
[GEM_ROOT]/gems/activesupport-3.2.12/lib/active_support/callbacks.rb:405:in `_run__497203393471184793__call__4495106819278994598__callbacks' 
[GEM_ROOT]/gems/activesupport-3.2.12/lib/active_support/callbacks.rb:405:in `__run_callback' 
[GEM_ROOT]/gems/activesupport-3.2.12/lib/active_support/callbacks.rb:385:in `_run_call_callbacks' 
[GEM_ROOT]/gems/activesupport-3.2.12/lib/active_support/callbacks.rb:81:in `run_callbacks' 
[GEM_ROOT]/gems/actionpack-3.2.12/lib/action_dispatch/middleware/callbacks.rb:27:in `call' 
[GEM_ROOT]/gems/actionpack-3.2.12/lib/action_dispatch/middleware/remote_ip.rb:31:in `call' 
[GEM_ROOT]/gems/actionpack-3.2.12/lib/action_dispatch/middleware/debug_exceptions.rb:16:in `call' 
[GEM_ROOT]/gems/actionpack-3.2.12/lib/action_dispatch/middleware/show_exceptions.rb:56:in `call' 
[GEM_ROOT]/gems/railties-3.2.12/lib/rails/rack/logger.rb:32:in `call_app' 
[GEM_ROOT]/gems/railties-3.2.12/lib/rails/rack/logger.rb:16:in `block in call' 
[GEM_ROOT]/gems/activesupport-3.2.12/lib/active_support/tagged_logging.rb:22:in `tagged' 
[GEM_ROOT]/gems/railties-3.2.12/lib/rails/rack/logger.rb:16:in `call' 
[GEM_ROOT]/gems/actionpack-3.2.12/lib/action_dispatch/middleware/request_id.rb:22:in `call' 
[GEM_ROOT]/gems/rack-1.4.5/lib/rack/methodoverride.rb:21:in `call' 
[GEM_ROOT]/gems/rack-1.4.5/lib/rack/runtime.rb:17:in `call' 
[GEM_ROOT]/gems/activesupport-3.2.12/lib/active_support/cache/strategy/local_cache.rb:72:in `call' 
[GEM_ROOT]/gems/rack-1.4.5/lib/rack/lock.rb:15:in `call' 
[GEM_ROOT]/gems/rack-cache-1.2/lib/rack/cache/context.rb:136:in `forward' 
[GEM_ROOT]/gems/rack-cache-1.2/lib/rack/cache/context.rb:143:in `pass' 
[GEM_ROOT]/gems/rack-cache-1.2/lib/rack/cache/context.rb:172:in `rescue in lookup' 
[GEM_ROOT]/gems/rack-cache-1.2/lib/rack/cache/context.rb:168:in `lookup' 
[GEM_ROOT]/gems/rack-cache-1.2/lib/rack/cache/context.rb:66:in `call!' 
[GEM_ROOT]/gems/rack-cache-1.2/lib/rack/cache/context.rb:51:in `call' 
[GEM_ROOT]/gems/railties-3.2.12/lib/rails/engine.rb:479:in `call' 
[GEM_ROOT]/gems/railties-3.2.12/lib/rails/application.rb:223:in `call' 
[GEM_ROOT]/gems/railties-3.2.12/lib/rails/railtie/configurable.rb:30:in `method_missing' 
/usr/local/lib/ruby/gems/1.9.1/gems/passenger-3.0.13/lib/phusion_passenger/rack/request_handler.rb:96:in `process_request' 
/usr/local/lib/ruby/gems/1.9.1/gems/passenger-3.0.13/lib/phusion_passenger/abstract_request_handler.rb:516:in `accept_and_process_next_request' 
/usr/local/lib/ruby/gems/1.9.1/gems/passenger-3.0.13/lib/phusion_passenger/abstract_request_handler.rb:274:in `main_loop' 
/usr/local/lib/ruby/gems/1.9.1/gems/passenger-3.0.13/lib/phusion_passenger/rack/application_spawner.rb:206:in `start_request_handler' 
/usr/local/lib/ruby/gems/1.9.1/gems/passenger-3.0.13/lib/phusion_passenger/rack/application_spawner.rb:171:in `block in handle_spawn_application' 
/usr/local/lib/ruby/gems/1.9.1/gems/passenger-3.0.13/lib/phusion_passenger/utils.rb:479:in `safe_fork' 
/usr/local/lib/ruby/gems/1.9.1/gems/passenger-3.0.13/lib/phusion_passenger/rack/application_spawner.rb:166:in `handle_spawn_application' 
/usr/local/lib/ruby/gems/1.9.1/gems/passenger-3.0.13/lib/phusion_passenger/abstract_server.rb:357:in `server_main_loop' 
/usr/local/lib/ruby/gems/1.9.1/gems/passenger-3.0.13/lib/phusion_passenger/abstract_server.rb:206:in `start_synchronously' 
/usr/local/lib/ruby/gems/1.9.1/gems/passenger-3.0.13/lib/phusion_passenger/abstract_server.rb:180:in `start' 
/usr/local/lib/ruby/gems/1.9.1/gems/passenger-3.0.13/lib/phusion_passenger/rack/application_spawner.rb:129:in `start' 
/usr/local/lib/ruby/gems/1.9.1/gems/passenger-3.0.13/lib/phusion_passenger/spawn_manager.rb:253:in `block (2 levels) in spawn_rack_application' 
/usr/local/lib/ruby/gems/1.9.1/gems/passenger-3.0.13/lib/phusion_passenger/abstract_server_collection.rb:132:in `lookup_or_add' 
/usr/local/lib/ruby/gems/1.9.1/gems/passenger-3.0.13/lib/phusion_passenger/spawn_manager.rb:246:in `block in spawn_rack_application' 
/usr/local/lib/ruby/gems/1.9.1/gems/passenger-3.0.13/lib/phusion_passenger/abstract_server_collection.rb:82:in `block in synchronize' 
/usr/local/lib/ruby/gems/1.9.1/gems/passenger-3.0.13/lib/phusion_passenger/abstract_server_collection.rb:79:in `synchronize' 
/usr/local/lib/ruby/gems/1.9.1/gems/passenger-3.0.13/lib/phusion_passenger/spawn_manager.rb:244:in `spawn_rack_application' 
/usr/local/lib/ruby/gems/1.9.1/gems/passenger-3.0.13/lib/phusion_passenger/spawn_manager.rb:137:in `spawn_application' 
/usr/local/lib/ruby/gems/1.9.1/gems/passenger-3.0.13/lib/phusion_passenger/spawn_manager.rb:275:in `handle_spawn_application' 
/usr/local/lib/ruby/gems/1.9.1/gems/passenger-3.0.13/lib/phusion_passenger/abstract_server.rb:357:in `server_main_loop' 
/usr/local/lib/ruby/gems/1.9.1/gems/passenger-3.0.13/lib/phusion_passenger/abstract_server.rb:206:in `start_synchronously' 
/usr/local/lib/ruby/gems/1.9.1/gems/passenger-3.0.13/helper-scripts/passenger-spawn-server:99:in `<main>' 
+0

En son raf sürümüne sabitlenebilir. 2 yıl önce bu konuya sahip olduğumda, hatalardan birkaçı [yorumda bulunduğum kişi dahil] (https://github.com/rack/rack/isss/225#issuecomment-2594611) kapalıydı. Botu bir seçenek engelliyor mu? –

+0

Ne yazık ki en son rafa geçmeyi denedim ve hala problemi gördüm (daha sonra bazı diğer taşları kapatmam gerektiğinden tekrar düştü). Birden fazla IP adresinden geliyor, bu yüzden bir maçın içine giriyor, artı daha iyi bir yol olması gerektiğini umuyorum. :) –

+0

Bir backtrace paylaşabilir misiniz? –

cevap

5

Bu algılamak ve incelikle başarısız tasarlanmış bir ara katman enjekte edebilir: burada Ve bir backtrace bu. Temel fikir, yalnızca sorgu dizesini ayrıştırmaya çalışmaktır ve başarısız olursa, bir HTTP 400 ile kurtarın. Aksi takdirde, yalnızca isteğine izin verin.

class RefuseInvalidRequest 
    def initialize(app) 
    @app = app 
    end 

    def call(env) 
    query = Rack::Utils.parse_nested_query(env['QUERY_STRING'].to_s) rescue :bad_query 
    if query == :bad_query 
     [400, {'Content-Type' => 'text/plain'}, "Bad Request"] 
    else 
     @app.call(env) 
    end 
    end 
end 

Bunu test etmedim ama konsept çalışması gerekir.

module Rack 
    module Utils 
    if defined?(::Encoding) 
     def unescape(s, encoding = Encoding::UTF_8) 
     begin 
      URI.decode_www_form_component(s, encoding) 
     rescue ArgumentError 
      URI.decode_www_form_component(URI.encode(s), encoding) 
     end 
     end 
    else 
     def unescape(s, encoding = nil) 
     begin 
      URI.decode_www_form_component(s, encoding) 
     rescue ArgumentError 
      URI.decode_www_form_component(URI.encode(s), encoding) 
     end 
     end 
    end 
    module_function :unescape 
    end 
end 

Dip not: Eğer monkeypatching Rack karşı sakıncası yoksa

+1

Bu benim dev ortamımda çalışmıyor. Nedenini bilmiyorum ama sadece göster! Günlükte geçersiz istek var. Ve '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ''den çağrılan' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' sadece '' !! Geçersiz istek '. Evet benim application.rb için config.middleware.use ("RefuseInvalidRequest") 'i ekledim. Bunun neden olduğu hakkında bir fikrin var mı? – Yana

+0

Belki de ara yazılım yığınınızda yeterince yüksek orta tabaka enjekte etmediniz. –

+0

'config.middleware.insert_before Rack :: Runtime," RefuseInvalidRequest "'. Ekleyebileceğim en yüksek. Aslında 'Rack :: MiniProfiler' ve' Honeybadger'. Ama ondan önce ekleyemem. Hala aynı çıktı. Eski sorularımın günlükleri http://stackoverflow.com/questions/21229499/custom-message-or-redirection-for-400-bad-request-because-of-unexcaped-on-par – Yana

5

sonra bu içerik ile (örneğin rack.rb için) config/initializers dosyada oluşturmak Yolcu ile çalışır, ancak Webrick ve Thin ile olmaz. Hem webrick hem de ince bir isteği de ayrıştırıyor gibi görünüyor, bu nedenle başlatma başlatıcısı yüklenmeden önce başarısız oluyor. Örneğin İnce hata ile thin-1.6.2/lib/thin/request.rb:84 içinde olur.