私が使用しているサービスプロバイダーの1つには、 https://service.com/service:search
ようなURLがあります。 これがファラデーの設定方法です。
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
これは実際に機能するので、ファラデーの何かがnet / httpとは異なる方法でこのURLを検証しているのではないかと思います。
こんにちは@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 :
サンプルコードを使用すると、 base
は#<URI::HTTPS https://service.com/>
なり、 url
はservice:search?limit=50&offset=400
ます。
興味深いことに、URIの+
メソッドの2番目のパラメーターに:
が含まれている場合、結果はまったく予想外のようです。
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
相対パスを追加する必要がある場合があるため、これはすべての場合に機能するとは限りません。
/
を前に付けて試してみて、それが機能するかどうかを知らせてください。ただし、この問題を開いたままにして、ファラデーでそのコード行を修正して修正できる方法を見つけます。この場合は機能します。
自分で試してみたい場合は、PRを喜んでレビューします😃
@iMacTiaそれは今働いた。 ベースURLはhttps://service.com/api
です。 私は追加すると/
するservice:search
私はエラーを持っていることに気づい/api
、私は追加して、ベースURLから消えていた/api/service:search
と今の罰金
@luizkowalski完璧です、はい、それはまさに私が意味したことです
ただし、/で開始できないベースに相対パスを追加する必要がある場合があるため、これはすべての場合に機能するとは限りません。
faradayは、提供されたURLが/
で始まり、ベースに提供されたパスを削除した場合、絶対的なものと見なします。
すでに回避策を見つけてよかったですが、回避策が不要になるように、これは適切に修正する必要があります。
最も参考になるコメント
@luizkowalski完璧です、はい、それはまさに私が意味したことです
faradayは、提供されたURLが
/
で始まり、ベースに提供されたパスを削除した場合、絶対的なものと見なします。すでに回避策を見つけてよかったですが、回避策が不要になるように、これは適切に修正する必要があります。