Description
Hi and thank you very much for this project at first.
Basic Info
- Faraday Version: 2.9.1
- Ruby Version: 3.3.3
Issue description
By the #1237 improvements, colons in path are now encoded as %3A. However, it is up to the server implementation to accept encoded colons, and in fact Firebase's fcm v1 api responds 404 status for encoded messages%3Asend
.
https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages/send
Currently, encoding occurs only in limited cases like a below reproduction code.
And no error occurs in the following situations.
- Give the full url to
Faraday.initialize()
orpost()
method - Give the full path to
post()
(like:client.post("/v1/projects/#{project_id}/messages:send")
)
Steps to reproduce
(using ENV for secret values)
require "faraday"
project_id = ENV["PROJECT_ID"]
iid_token = ENV["IID_TOKEN"]
def get_access_token
ENV["ACCESS_TOKEN"]
end
base_url = "https://fcm.googleapis.com/v1/projects/#{project_id}"
path = "messages:send"
client = Faraday.new(url: base_url) do |builder|
builder.request :authorization, 'Bearer', get_access_token
builder.request :json
builder.response :json,
content_type: /application\/json/,
parser_options: { symbolize_names: true }
builder.response :logger,
Logger.new(STDOUT),
{ headers: true, bodies: true, errors: true }
end
res = client.post(path) do |req|
req.body = {
validate_only: true,
message: {
token: iid_token,
notification: {
title: "test",
body: "test",
}
}
}
end
Execution log
I, [2024-06-13T08:31:07.928238 #1] INFO -- request: POST https://fcm.googleapis.com/v1/projects/***/messages%3Asend
I, [2024-06-13T08:31:07.928371 #1] INFO -- request: User-Agent: "Faraday v2.9.1"
Authorization: "Bearer ***"
Content-Type: "application/json"
I, [2024-06-13T08:31:07.928417 #1] INFO -- request: {"validate_only":true,"message":{"token":"***","notification":{"title":"test","body":"test"}}}
I, [2024-06-13T08:31:08.084930 #1] INFO -- response: Status 404
I, [2024-06-13T08:31:08.085055 #1] INFO -- response: content-type: "text/html"
date: "Thu, 13 Jun 2024 08:31:08 GMT"
server: "scaffolding on HTTPServer2"
content-length: "0"
x-xss-protection: "0"
x-frame-options: "SAMEORIGIN"
x-content-type-options: "nosniff"
alt-svc: "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000"
I, [2024-06-13T08:31:08.085115 #1] INFO -- response:
My thoughts
faraday/lib/faraday/connection.rb
Lines 470 to 483 in 4abafa5
How about replace URL + string merge to string + string merge
- url = url.to_s.gsub(':', '%3A') if URI.parse(url.to_s).opaque
- uri = url ? base + url : base
+ uri = url ? URI.parse(base.to_s + url) : base
This has the following advantages and disadvantages.
Advantages.
- No error if colons are included in the path url.
- User can decide whether to encode colons or not.
- The path contained in base url is not ignored if the path url starts with slash.
Disadvantages.
- Inefficient because base is already parsed to URL.
- Error might occur if query or hash is contained in the base url.
- Needs to remove first slash because base url is assumed to end with slash.