Faraday: فشل التحقق من صحة URI عندما يحتوي على أحرف محجوزة

تم إنشاؤها على ٤ ديسمبر ٢٠٢٠  ·  3تعليقات  ·  مصدر: lostisland/faraday

معلومات أساسية

  • إصدار فاراداي: 1.1.0
  • إصدار روبي: 2.7.1

وصف المشكلة

أحد مزودي الخدمة الذين أستخدمهم لديه عناوين URL مثل هذا: https://service.com/service:search . هذه هي الطريقة التي نجهز بها فاراداي:

class Provider::Client
 ...
 delegate :post, :patch, :delete, :put, to: :client

 def client
  Faraday.new(url: 'https://service.com/') do |faraday|
    faraday.headers = headers.merge(content_type: content_type)
    faraday.response(:json, content_type: CONTENT_TYPE)
    faraday.basic_auth(USER, PASSWORD)
    faraday.adapter(Faraday.default_adapter)
  end
 end
end

وعندما أستدعيها

data = Provider::Client.post(
  "service:search?limit=#{LIMIT}&offset=#{offset}", search_params
)

ولكن عندما أفعل ذلك بعنوان URL المعني ، أحصل على هذا:

URI::InvalidURIError: query conflicts with opaque
from /Users/luiz/.rbenv/versions/2.7.1/lib/ruby/2.7.0/uri/generic.rb:832:in `query='

أفترض أنه كان شيئًا متعلقًا بمحول net / http نظرًا لأنه المحول الافتراضي لذلك أجريت نفس المكالمة يدويًا

require "uri"
require "net/http"

url = URI("https://service.com/service:search?limit=50&offset=400")

https = Net::HTTP.new(url.host, url.port);
https.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Accept"] = "custom_header"
request["Authorization"] = "Basic xxx="
request["Content-Type"] = "application/json"
request.body = "long_json"
response = https.request(request)

puts response.read_body

وهذا يعمل بالفعل ، لذا أظن أن شيئًا ما في Faraday يتحقق من صحة عنوان URL هذا بطريقة مختلفة عن net / http

bug good first issue

التعليق الأكثر فائدة

luizkowalski مثالي ، نعم هذا بالضبط ما قصدته

ومع ذلك ، لا يعمل هذا في جميع الحالات حيث قد تحتاج إلى إلحاق مسار نسبي بالقاعدة والذي لا يمكن أن يبدأ بـ /.

كما يفترض faraday أن عنوان URL المقدم مطلق إذا بدأ بـ / وأزال المسار المقدم إلى القاعدة.
يسعدني أنك عثرت بالفعل على الحل البديل ، ولكن لا يزال يتعين إصلاح ذلك بشكل صحيح حتى لا يكون الحل البديل ضروريًا بعد الآن

ال 3 كومينتر

مرحبًا luizkowalski ، الاستثناء يأتي من URI ويتم رفعه في الأسطر الأولى من طريقة query= :

def query=(v)
  return <strong i="9">@query</strong> = nil unless v
  raise InvalidURIError, "query conflicts with opaque" if <strong i="10">@opaque</strong>
  ...
end

يقوم Faraday ببعض السحر الداخلي على عنوان url للطلب عن طريق تقسيمه وإعادة تجميعه للمساعدة في بعض التحولات الشائعة ، وأفترض في وقت ما أنه قد يتسبب في تعيين @opaque بفضل وجود : في URL.
لقد تتبعت المشكلة وصولاً إلى هذا السطر: https://github.com/lostisland/faraday/blob/c26df87b8653db4f270e3bcdc7a15bcdd2dd5cae/lib/faraday/connection.rb#L525
باستخدام رمز المثال الخاص بك ، سيكون base #<URI::HTTPS https://service.com/> و url سيكون service:search?limit=50&offset=400 .
الآن ، من المثير للاهتمام ، أنه إذا كانت المعلمة الثانية لطريقة + لـ URI تحتوي على : ، يبدو أن النتيجة غير متوقعة تمامًا!

2.7.1 > url
 => "service:search?limit=50&offset=400" 
2.7.1 > base
 => #<URI::HTTPS https://service.com/> 
2.7.1 > base + url
 => #<URI::Generic service:search?limit=50&offset=400>

لسبب ما ، تمت إزالة base ولم يتبق سوى عنوان url.
الإصلاح سهل للغاية في هذه الحالة ، يكفي فقط إضافة / إلى عنوان url مسبقًا وتعمل الأشياء كما هو متوقع:

data = Provider::Client.post(
  "/service:search?limit=#{LIMIT}&offset=#{offset}", search_params
)

ومع ذلك ، لا يعمل هذا في جميع الحالات حيث قد تحتاج إلى إلحاق مسار نسبي بـ base والذي لا يمكن أن يبدأ بـ / .
يُرجى تجربة هذه المحاولة عن طريق إضافة / وإخباري إذا كان ذلك ناجحًا ، لكنني سأترك هذه المشكلة مفتوحة لإلقاء نظرة وإيجاد طريقة ممكنة لإصلاح هذا السطر من التعليمات البرمجية في Faraday بحيث يعمل في هذه الحالة.
إذا كنت تريد أن تجربها بنفسك ، فسيسعدني مراجعة العلاقات العامة 😃

iMacTia عملت الآن. عنوان URL الأساسي هو: https://service.com/api . عندما أضفت / إلى service:search حصلت على خطأ ولاحظت أن /api قد اختفى من عنوان URL الأساسي لذلك أضفت /api/service:search والآن أصبح الأمر جيدًا

luizkowalski مثالي ، نعم هذا بالضبط ما قصدته

ومع ذلك ، لا يعمل هذا في جميع الحالات حيث قد تحتاج إلى إلحاق مسار نسبي بالقاعدة والذي لا يمكن أن يبدأ بـ /.

كما يفترض faraday أن عنوان URL المقدم مطلق إذا بدأ بـ / وأزال المسار المقدم إلى القاعدة.
يسعدني أنك عثرت بالفعل على الحل البديل ، ولكن لا يزال يتعين إصلاح ذلك بشكل صحيح حتى لا يكون الحل البديل ضروريًا بعد الآن

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات