Faraday: Validasi URI gagal saat berisi karakter yang dicadangkan

Dibuat pada 4 Des 2020  ·  3Komentar  ·  Sumber: lostisland/faraday

Info dasar

  • Versi Faraday: 1.1.0
  • Versi Ruby: 2.7.1

Deskripsi masalah

Salah satu penyedia layanan yang saya gunakan memiliki URL seperti ini: https://service.com/service:search . Inilah cara kami mengatur Faraday:

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

dan ketika saya memanggilnya

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

tetapi ketika saya melakukan ini dengan URL yang dimaksud, saya mendapatkan ini:

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='

Saya berasumsi itu adalah sesuatu yang terkait dengan adaptor net/http karena ini adalah adaptor default jadi saya melakukan panggilan yang sama secara manual

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

dan ini benar-benar berfungsi jadi saya curiga ada sesuatu di Faraday yang memvalidasi URL ini dengan cara yang berbeda dari net/http

bug good first issue

Komentar yang paling membantu

@luizkowalski sempurna, ya itulah yang saya maksud dengan

Namun ini tidak berfungsi dalam semua kasus karena Anda mungkin perlu menambahkan jalur relatif ke basis yang tidak dapat dimulai dengan /.

Seperti yang diasumsikan faraday, URL yang disediakan adalah absolut jika dimulai dengan / dan menghapus jalur yang disediakan ke pangkalan.
Senang Anda sudah menemukan solusinya, tetapi ini masih harus diperbaiki dengan benar sehingga solusi tidak diperlukan lagi

Semua 3 komentar

Hai @luizkowalski , pengecualian berasal dari URI dan dimunculkan di baris pertama metode 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 melakukan beberapa keajaiban internal pada url permintaan dengan memisahkan dan menggabungkannya kembali untuk membantu beberapa transformasi umum, dan saya kira pada titik tertentu itu dapat menyebabkan @opaque disetel berkat kehadiran : di URL.
Saya telah melacak masalah ini ke baris ini: https://github.com/lostisland/faraday/blob/c26df87b8653db4f270e3bcdc7a15bcdd2dd5cae/lib/faraday/connection.rb#L525
Menggunakan kode contoh Anda, base akan menjadi #<URI::HTTPS https://service.com/> dan url akan menjadi service:search?limit=50&offset=400 .
Sekarang, cukup menarik, jika parameter kedua dari metode + untuk URI berisi : , sepertinya hasilnya sangat tidak terduga!

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>

Untuk beberapa alasan, base dihapus dan hanya url yang tersisa.
Perbaikannya cukup mudah dalam hal ini, cukup dengan menambahkan / ke url dan semuanya berfungsi seperti yang diharapkan:

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

Namun ini tidak berfungsi dalam semua kasus karena Anda mungkin perlu menambahkan jalur relatif ke base yang tidak dapat dimulai dengan / .
Silakan coba ini dengan menambahkan / dan beri tahu saya jika itu berhasil, tetapi saya akan membiarkan masalah ini terbuka untuk melihat dan menemukan cara yang mungkin untuk memperbaiki baris kode itu di Faraday sehingga bekerja dalam kasus ini.
Jika Anda ingin mencobanya sendiri, saya akan dengan senang hati meninjau PR

@iMacTia berhasil sekarang. URL dasarnya adalah: https://service.com/api . Ketika saya menambahkan / ke service:search saya mendapatkan kesalahan dan memperhatikan bahwa /api hilang dari URL dasar jadi saya menambahkan /api/service:search dan sekarang tidak masalah

@luizkowalski sempurna, ya itulah yang saya maksud dengan

Namun ini tidak berfungsi dalam semua kasus karena Anda mungkin perlu menambahkan jalur relatif ke basis yang tidak dapat dimulai dengan /.

Seperti yang diasumsikan faraday, URL yang disediakan adalah absolut jika dimulai dengan / dan menghapus jalur yang disediakan ke pangkalan.
Senang Anda sudah menemukan solusinya, tetapi ini masih harus diperbaiki dengan benar sehingga solusi tidak diperlukan lagi

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

jordansissel picture jordansissel  ·  5Komentar

ioquatix picture ioquatix  ·  4Komentar

jeffb-stell picture jeffb-stell  ·  5Komentar

amrrbakry picture amrrbakry  ·  4Komentar

Lewiscowles1986 picture Lewiscowles1986  ·  4Komentar