So I have an application running Ruby 2.7.6 and Rails 6.1. Also using rom and rom-http for API calls. We have suddenly started to see our URLs in the browser, as well as server-side API request parameters, get overwritten with one of the symbols we use to represent an ID in the code. I have started learning the Ruby on Rails Course, but I can't able solve this question.
For example, a request that should be https://sampleapi.json?currency=USD&locale=EN will be turned into https://sampleapi.json?currency=%3Asearch_id&locale=EN.
:search_id is a symbol we do use as a request parameter in many other places where we send a unique id related to a user search. But somehow, it has been injecting itself into almost all API calls as the actual value (encoded as %3Asearch_id). Sometimes we see API calls filled with almost every request parameter set this way.
The suspect is that something in active resource or one of the rom gems has changed at some point and we never accounted for it.
There are some requests that would have &search_id as a request parameter... but with this bug the symbol:search_id itself is getting into the right side of param values.
Does this sound familiar to anyone?
Request handler code that processes data to form the final request:
def call(dataset)
uri = URI(dataset.uri)
uri.path += [dataset.name, dataset.path.presence].compact.join('/') + '.json'
# recaptcha api endpoint urls
Rails.logger.info "api endpoint is #{dataset.name}"
if (dataset.name == '/hotels/rooms' && Settings.enable_recaptcha)
api_path = dataset.name.split('/')
uri = URI(Settings.recaptcha_api_gateway_url)
uri.path += ['/', api_path.last, dataset.path.presence].compact.join('/')
end
if Rails.env == 'test' && dataset.name == '/hotels/rateshopping'
dataset.params[:client_ip] = "74.125.228.110"
end
if dataset.request_method == :get
uri.query = URI.encode_www_form(dataset.params.symbolize_keys.to_a.sort)
else
uri.query = "ip_address=#{$user_ip}"
end
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = uri.scheme.to_s == 'https'
request_klass = Net::HTTP.const_get(ROM::Inflector.classify(dataset.request_method))
Rails.logger.info "dataset.params: #{dataset.params}"
request = request_klass.new(uri.request_uri)
dataset.headers.each_with_object(request) do |(header, value), request|
request[header.to_s] = value
end
if dataset.request_method == :post
request['Content-Type'] = 'application/json; charset=utf-8'
request.body = dataset.params.to_json
end
with_cache(dataset, uri) do
with_logging(dataset, uri) { http.request(request) }
end
end
Replies