Skip to content

Commit

Permalink
Lets play with potentially proxing search requests through Quepid to …
Browse files Browse the repository at this point in the history
…avoid CORS. (o19s#820)

* first cut of proxy

* let's play with some proxies...

* now supporting headers and better handling of the body
  • Loading branch information
epugh committed Oct 22, 2023
1 parent 753ba2c commit 20a9ed4
Show file tree
Hide file tree
Showing 4 changed files with 249 additions and 0 deletions.
98 changes: 98 additions & 0 deletions app/controllers/proxy_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# frozen_string_literal: true

require 'faraday'
# require 'faraday_middleware'
# rubocop:disable Layout/LineLength
# rubocop:disable Metrics/AbcSize
# rubocop:disable Metrics/MethodLength
# rubocop:disable Metrics/PerceivedComplexity
# rubocop:disable Metrics/CyclomaticComplexity
class ProxyController < ApplicationController
skip_before_action :require_login
skip_before_action :verify_authenticity_token, only: [ :fetch ]
# curl -X GET "http://localhost:3000/proxy/fetch?url=https://quepid-solr.dev.o19s.com/solr/tmdb/select&q=*:*"
# curl -X POST "http://localhost:3000/proxy/fetch?url=https://quepid-solr.dev.o19s.com/solr/tmdb/query" -d '{"query":"star"}'
#
def fetch
uri = URI.parse(proxy_url_params)
url_without_path = "#{uri.scheme}://#{uri.host}"
url_without_path += ":#{uri.port}" unless uri.port.nil?

connection = Faraday.new(url: url_without_path) do |faraday|
# Configure the connection options, such as headers or middleware
# faraday.response :logger, nil, { headers: true, bodies: true }
faraday.response :logger, nil, { headers: true, bodies: true, errors: true }
faraday.ssl.verify = false
faraday.request :url_encoded

matching_headers = request.headers.select { |name, _| name.start_with?('HTTP') && !rack_header?(name) }

matching_headers.each do |name, value|
converted_name = name.sub('HTTP_', '')
converted_name = converted_name.tr('_', '-')
faraday.headers[converted_name] = value
end

faraday.headers['Content-Type'] = 'application/json'
faraday.adapter Faraday.default_adapter
end

if request.get?
response = connection.get do |req|
req.path = uri.path
excluded_keys = [ :url, :action, :controller ]
query_params = request.query_parameters.except(*excluded_keys)
body_params = request.request_parameters.except(*query_params.keys)

query_params.each do |param|
req.params[param.first] = param.second
end
unless body_params.empty?

json_query = body_params.first.first
req.body = json_query
end
end
elsif request.post?
response = connection.post do |req|
req.path = uri.path
excluded_keys = [ :url, :action, :controller ]
query_params = request.query_parameters.except(*excluded_keys)
body_params = request.request_parameters.except(*query_params.keys) # not sure about this and the request.raw_post
query_params.each do |param|
req.params[param.first] = param.second
end
unless body_params.empty?
json_query = request.raw_post

req.body = json_query
end
end
end

data = JSON.parse(response.body)
# Process the data as needed
render json: data, status: response.status
end

def proxy_url_params
params.require(:url)
end

private

def rack_header? header_name
predefined_rack_headers = %w[
HTTP_VERSION HTTP_ACCEPT HTTP_ACCEPT_CHARSET HTTP_ACCEPT_ENCODING
HTTP_ACCEPT_LANGUAGE HTTP_CACHE_CONTROL HTTP_CONNECTION HTTP_HOST
HTTP_REFERER HTTP_USER_AGENT HTTP_X_REQUEST_ID
]

predefined_rack_headers.include?(header_name)
end
end
# rubocop:enable Layout/LineLength
# rubocop:enable Metrics/AbcSize
# rubocop:enable Metrics/MethodLength
# rubocop:enable Metrics/PerceivedComplexity
# rubocop:enable Metrics/CyclomaticComplexity
7 changes: 7 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,15 @@

# rubocop:disable Metrics/BlockLength
Rails.application.routes.draw do



# get 'home/show'
apipie
root 'home#show'

get 'proxy/fetch'
post 'proxy/fetch'

# Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html

Expand Down
30 changes: 30 additions & 0 deletions test/controllers/proxy_controller_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# frozen_string_literal: true

require 'test_helper'

# rubocop:disable Layout/LineLength
class ProxyControllerTest < ActionDispatch::IntegrationTest
test 'should require a url query parameter' do
assert_raises(ActionController::ParameterMissing) do
get proxy_fetch_path
end
assert_raises(ActionController::ParameterMissing) do
post proxy_fetch_path
end
end

test 'should be able to handle a get' do
get proxy_fetch_url params: {
url: 'http://solr.quepid.com:8983/solr/statedecoded/select', fl: 'id,text', q: '*:*', rows: 10, start: 0
}
assert_response :success
end
test 'should be able to handle a post' do
json_data = { query: 'star', key2: 'value2' }.to_json

post '/proxy/fetch?url=http://solr.quepid.com:8983/solr/statedecoded/select', params: json_data,
headers: { 'Content-Type' => 'application/json' }
assert_response :success
end
end
# rubocop:enable Layout/LineLength
Loading

0 comments on commit 20a9ed4

Please sign in to comment.