2013-04-02 4 views
10

रेल साइट पर हमारे रूबी में एक यूआरआई है कि हमारे भागीदारों में से एक XML डेटा को पोस्ट करता है।रेल/रैक: POST डेटा के लिए "ArgumentError: अवैध% -encoding"

चूंकि हम एक्सएमएल से निपटना नहीं चाहते हैं, इसलिए हम सचमुच कच्चे डेटा को डेटाबेस कॉलम में डालते हैं और इसे संसाधित करने के साथ आगे नहीं जाते हैं।

ArgumentError: invalid %-encoding ("http://ns.hr-xml.org/2004-08-02" 
userId="" password=""><BackgroundReportPackage type="report"> 
<ProviderReferenceId>.... 
पश्व-अनुरेखन साथ

:

हालांकि, पदों हमें प्राप्त हुआ है में से एक हमें airbrake में इस त्रुटि दे दी

vendor/ruby-1.9.3/lib/ruby/1.9.1/uri/common.rb:898:in `decode_www_form_component' 
vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/utils.rb:41:in `unescape' 
vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/utils.rb:94:in `block (2 levels) in parse_nested_query' 
vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/utils.rb:94:in `map' 
vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/utils.rb:94:in `block in parse_nested_query' 
vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/utils.rb:93:in `each' 
vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/utils.rb:93:in `parse_nested_query' 
vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/request.rb:332:in `parse_query' 
vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/request.rb:209:in `POST' 
vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/methodoverride.rb:26:in `method_override' 
vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/methodoverride.rb:14:in `call' 
vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/runtime.rb:17:in `call' 
vendor/bundle/ruby/1.9.1/gems/activesupport-3.2.13/lib/active_support/cache/strategy/local_cache.rb:72:in `call' 
vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/lock.rb:15:in `call' 
vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.13/lib/action_dispatch/middleware/static.rb:63:in `call' 
vendor/bundle/ruby/1.9.1/gems/rack-cache-1.2/lib/rack/cache/context.rb:136:in `forward' 
vendor/bundle/ruby/1.9.1/gems/rack-cache-1.2/lib/rack/cache/context.rb:143:in `pass' 
vendor/bundle/ruby/1.9.1/gems/rack-cache-1.2/lib/rack/cache/context.rb:155:in `invalidate' 
vendor/bundle/ruby/1.9.1/gems/rack-cache-1.2/lib/rack/cache/context.rb:71:in `call!' 
vendor/bundle/ruby/1.9.1/gems/rack-cache-1.2/lib/rack/cache/context.rb:51:in `call' 
vendor/bundle/ruby/1.9.1/gems/railties-3.2.13/lib/rails/engine.rb:479:in `call' 
vendor/bundle/ruby/1.9.1/gems/railties-3.2.13/lib/rails/application.rb:223:in `call' 
vendor/bundle/ruby/1.9.1/gems/railties-3.2.13/lib/rails/railtie/configurable.rb:30:in `method_missing' 
vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/deflater.rb:13:in `call' 
vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/content_length.rb:14:in `call' 
vendor/bundle/ruby/1.9.1/gems/railties-3.2.13/lib/rails/rack/log_tailer.rb:17:in `call' 
vendor/bundle/ruby/1.9.1/gems/thin-1.4.1/lib/thin/connection.rb:80:in `block in pre_process' 
vendor/bundle/ruby/1.9.1/gems/thin-1.4.1/lib/thin/connection.rb:78:in `catch' 
vendor/bundle/ruby/1.9.1/gems/thin-1.4.1/lib/thin/connection.rb:78:in `pre_process' 
vendor/bundle/ruby/1.9.1/gems/thin-1.4.1/lib/thin/connection.rb:53:in `process' 
vendor/bundle/ruby/1.9.1/gems/thin-1.4.1/lib/thin/connection.rb:38:in `receive_data' 
vendor/bundle/ruby/1.9.1/gems/eventmachine-0.12.10/lib/eventmachine.rb:256:in `run_machine' 
vendor/bundle/ruby/1.9.1/gems/eventmachine-0.12.10/lib/eventmachine.rb:256:in `run' 
vendor/bundle/ruby/1.9.1/gems/thin-1.4.1/lib/thin/backends/base.rb:63:in `start' 
vendor/bundle/ruby/1.9.1/gems/thin-1.4.1/lib/thin/server.rb:159:in `start' 
vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/handler/thin.rb:13:in `run' 
vendor/bundle/ruby/1.9.1/gems/rack-1.4.5/lib/rack/server.rb:268:in `start' 
vendor/bundle/ruby/1.9.1/gems/railties-3.2.13/lib/rails/commands/server.rb:70:in `start' 
vendor/bundle/ruby/1.9.1/gems/railties-3.2.13/lib/rails/commands.rb:55:in `block in <top (required)>' 
vendor/bundle/ruby/1.9.1/gems/railties-3.2.13/lib/rails/commands.rb:50:in `tap' 
vendor/bundle/ruby/1.9.1/gems/railties-3.2.13/lib/rails/commands.rb:50:in `<top (required)>' 
script/rails:6:in `require' 
script/rails:6:in `<main>' 

मुद्दा यह है कि पोस्ट डेटा होता है:

<ChargeOrComplaint>DRIVE WHILE BLOOD ALCOHOL LEVEL IS 0.08% OR MORE</ChargeOrComplaint> 

संभवतः यह वैध एक्सएमएल है, लेकिन नग्न %के अंत मेंत्रुटि उत्पन्न कर रहा है, क्योंकि यह HTTP के माध्यम से आ रहा है और मुझे लगता है कि रैक यह यूआरएल एन्कोडेड होने की उम्मीद कर रहा है।

बैकट्रैस इंगित करता है कि यह हमारे कोड तक पहुंचने से पहले भी हो रहा है, इसलिए मुझे नहीं लगता कि हम इसे कैसे संसाधित कर रहे हैं इसके साथ कुछ भी करना है।

मेरे सवालों का है, तो:

1) कहाँ मुद्दा झूठ करता है? रूबी 1.9.3 के decode_www_form_component के कार्यान्वयन (स्टैक ट्रेस के शीर्ष पर)? रैक? हमारे साथी का पोस्ट डेटा या हेडर? पोस्ट का हमारा प्रबंधन?

2) HTTP के माध्यम से पोस्ट किए गए XML डेटा को यूआरएल एन्कोड किए जाने की आवश्यकता है?

3) क्या कोई हेडर है कि इस पोस्ट को रैक के लिए सही तरीके से व्याख्या करने की आवश्यकता है? (यानी .: यह एक्सएमएल बाइनरी डेटा है, और यूआरएल एन्कोड नहीं किया गया है)।

4) अगर हम अपने साथी को जो कुछ पोस्ट कर रहे हैं उसे बदलने के लिए नहीं मिल पा रहे हैं, तो हम इसके आसपास कैसे काम कर सकते हैं? कुछ रैक मिडलवेयर?

+2

मैं इस सटीक समस्या में भाग रहा हूं। क्या आप समाधान ढूंढ रहे हैं? –

उत्तर

7

मुझे लगता है कि आपका साथी शायद आपको "x-www-form-urlencoded" के रूप में डेटा पोस्ट कर रहा है, जिससे रैक इसे इस तरह से पार्स करने का प्रयास करता है। अगर वे जो भी भेज रहे हैं उसे बदल सकते हैं, तो मुझे संदेह है कि उनकी सामग्री-प्रकार "टेक्स्ट/एक्सएमएल" इसे ठीक कर देगा।

यदि आप उन्हें जो भी भेजते हैं उसे बदलने के लिए नहीं मिल पा रहे हैं, तो हाँ, मुझे लगता है कि आपको रैक मिडलवेयर (या बंदरगाह) का उपयोग करना होगा। यद्यपि आप रैक स्रोत के चारों ओर पोक कर सकते हैं, हो सकता है कि कोई पार्सिंग करने से बचने के लिए एक सेटिंग हो।

+4

मुझे लगता है कि रैक यह भी मानता है कि अनुरोध 'x-www-form-urlencoded' है यदि यह एक पोस्ट है और कोई सामग्री-प्रकार शीर्षलेख नहीं है, तो यह वह व्यवहार है जिसे आप देख सकते हैं यदि भागीदार कोई सामग्री निर्दिष्ट नहीं करता है टाइप करें: https://github.com/rack/rack/blob/1.4.5/lib/rack/request.rb#L171 – matt

0

मेरे मामले में हेडर के बाद और अनुरोध निकाय के बाद अतिरिक्त अतिरिक्त पंक्तियां थीं। मुझे लगता है कि वहां सामग्री-लंबाई असंगतता है जो पार्सर को फेंकता है। यदि आप हेडर्स प्रोग्रामेटिक रूप से सेट कर रहे हैं तो सुनिश्चित करें कि उनके पास पिछली न्यूलाइन नहीं है।

1

विभिन्न मंचों में कुछ बहस है जहां जिम्मेदारी शरीर की सामग्री में अमान्य एन्कोडिंग त्रुटियों को पकड़ने के लिए जिम्मेदारी है, लेकिन न तो रैक और न ही रेल इसे संभालती है, दोनों इसे ऐप को संभालने के लिए छोड़ देते हैं।

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

    def call(env) 
    request_content = Rack::Request.new(env).POST rescue :bad_form_data 

    headers = {'Content-Type' => 'text/plain'} 

    if request_content == :bad_form_data 
     [400, headers, ['Bad Request']] 
    else 
     @app.call(env) 
    end 
    end 
end 

फिर कहा: अमान्य पोस्ट डेटा अवरोधन करने Rails ArgumentError: invalid %-encoding

मैं app/middleware/invalid_post_data_interceptor.rb में इस मिडलवेयर कहा: मेरे एप्लिकेशन में पोस्ट डेटा में चारों ओर अवैध% -encoding करने के लिए, मैं इस संबंधित सवाल करने के लिए एक समान समाधान के लिए इस्तेमाल किया इसे application.rb पर जोड़कर मिडलवेयर स्टैक में:

config.middleware.insert_before Rack::Runtime, "InvalidPostDataInterceptor" 
संबंधित मुद्दे