Skip to content

Commit

Permalink
Merge pull request #13986 from opf/task/50684-migrate-to-httpx-http-r…
Browse files Browse the repository at this point in the history
…uby-client

[#50684] Migrate to httpx http ruby client
  • Loading branch information
dominic-braeunlein authored Jan 10, 2024
2 parents 3affdf0 + e91b13c commit e10f5e1
Show file tree
Hide file tree
Showing 33 changed files with 346 additions and 311 deletions.
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,8 @@ gem 'factory_bot_rails', '~> 6.4.0', require: false

gem 'turbo-rails', "~> 1.1"

gem 'httpx'

group :test do
gem 'launchy', '~> 2.5.0'
gem 'rack-test', '~> 2.1.0'
Expand Down
4 changes: 4 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -586,8 +586,11 @@ GEM
htmlbeautifier (1.4.2)
htmldiff (0.0.1)
htmlentities (4.3.4)
http-2-next (1.0.1)
http_parser.rb (0.6.0)
httpclient (2.8.3)
httpx (1.0.2)
http-2-next (>= 1.0.1)
i18n (1.14.1)
concurrent-ruby (~> 1.0)
i18n-js (4.2.3)
Expand Down Expand Up @@ -1145,6 +1148,7 @@ DEPENDENCIES
grids!
html-pipeline (~> 2.14.0)
htmldiff
httpx
i18n-js (~> 4.2.3)
i18n-tasks (~> 1.0.13)
json_schemer (~> 2.1.0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ def basic_rack_oauth_client = raise ::Storages::Errors::SubclassResponsibility

def authorization_check_wrapper
case yield
when Net::HTTPSuccess
when 200..299
:success
when Net::HTTPForbidden, Net::HTTPUnauthorized
when 401, 403
:refresh_needed
else
:error
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,14 @@ def authorization_state_check(token)
util = ::Storages::Peripherals::StorageInteraction::Nextcloud::Util

authorization_check_wrapper do
Net::HTTP.start(@uri.host, @uri.port, use_ssl: true) do |http|
http.get(
util.join_uri_path(@uri.path, '/ocs/v1.php/cloud/user'),
{
'Authorization' => "Bearer #{token}",
'OCS-APIRequest' => 'true',
'Accept' => 'application/json'
}
)
end
HTTPX.get(
util.join_uri_path(@uri, '/ocs/v1.php/cloud/user'),
headers: {
'Authorization' => "Bearer #{token}",
'OCS-APIRequest' => 'true',
'Accept' => 'application/json'
}
).status
end
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,13 @@ def initialize(storage)
end

def authorization_state_check(access_token)
util = ::Storages::Peripherals::StorageInteraction::OneDrive::Util

authorization_check_wrapper do
Net::HTTP.start(@uri.host, @uri.port, use_ssl: true) do |http|
http.get('/v1.0/me', { 'Authorization' => "Bearer #{access_token}", 'Accept' => 'application/json' })
end
HTTPX.get(
util.join_uri_path(@uri, '/v1.0/me'),
headers: { 'Authorization' => "Bearer #{access_token}", 'Accept' => 'application/json' }
).status
end
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,21 +43,25 @@ def self.call(storage:, user:, group: storage.group)
end

def call(user:, group: @group)
response = Util.http(@uri).post(
Util.join_uri_path(@uri.path, 'ocs/v1.php/cloud/users', CGI.escapeURIComponent(user), 'groups'),
"groupid=#{CGI.escapeURIComponent(group)}",
Util
.basic_auth_header(@username, @password)
.merge(
'OCS-APIRequest' => 'true'
)
)
response = Util
.httpx
.basic_auth(@username, @password)
.with(headers: { 'OCS-APIRequest' => 'true' })
.post(
Util.join_uri_path(
@uri,
'ocs/v1.php/cloud/users',
CGI.escapeURIComponent(user),
'groups'
),
form: { "groupid" => CGI.escapeURIComponent(group) },
)

error_data = Storages::StorageErrorData.new(source: self.class, payload: response)

case response
when Net::HTTPSuccess
statuscode = Nokogiri::XML(response.body).xpath('/ocs/meta/statuscode').text
case response.status
when 200..299
statuscode = Nokogiri::XML(response.body.to_s).xpath('/ocs/meta/statuscode').text

case statuscode
when "100"
Expand All @@ -73,13 +77,13 @@ def call(user:, group: @group)
when "105"
Util.error(:error, "Failed to add user to group", error_data)
end
when Net::HTTPMethodNotAllowed
when 405
Util.error(:not_allowed, 'Outbound request method not allowed', error_data)
when Net::HTTPNotFound
when 401
Util.error(:not_found, 'Outbound request destination not found', error_data)
when Net::HTTPUnauthorized
when 404
Util.error(:unauthorized, 'Outbound request not authorized', error_data)
when Net::HTTPConflict
when 409
Util.error(:conflict, Util.error_text_from_response(response), error_data)
else
Util.error(:error, 'Outbound request failed', error_data)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,14 @@ def build_origin_paths
escaped_username = CGI.escapeURIComponent(@username)

source = Util.join_uri_path(
@uri.path,
@uri,
"remote.php/dav/files",
escaped_username,
Util.escape_path(input[:source_path])
)

destination = Util.join_uri_path(
@uri.path,
@uri,
"remote.php/dav/files",
escaped_username,
Util.escape_path(input[:destination_path])
Expand All @@ -79,49 +79,49 @@ def build_origin_paths

def validate_destination
->(urls) do
request = Net::HTTP::Head.new(urls[:destination_url])
request.initialize_http_header Util.basic_auth_header(@username, @password)
response = Util
.httpx
.basic_auth(@username, @password)
.head(urls[:destination_url])

response = Util.http(@uri).request(request)

case response
when Net::HTTPSuccess
case response.status
when 200..299
Util.error(:conflict, 'Destination folder already exists.')
when Net::HTTPUnauthorized
when 401
Util.error(:unauthorized, "unauthorized (validate_destination)")
when Net::HTTPNotFound
when 404
ServiceResult.success(result: urls)
else
Util.error(:unknown, "Unexpected response (validate_destination): #{response.code}", response)
end
end
end

# rubocop:disable Metrics/AbcSize
def copy_folder
->(urls) do
headers = Util.basic_auth_header(@username, @password)
headers['Destination'] = urls[:destination_url]
headers['Depth'] = 'infinity'

request = Net::HTTP::Copy.new(urls[:source_url], headers)
response = Util.http(@uri).request(request)

case response
when Net::HTTPCreated
response = Util
.httpx
.basic_auth(@username, @password)
.request("COPY",
urls[:source_url],
headers: {
'Destination' => urls[:destination_url],
'Depth' => 'infinity'
})

case response.status
when 200..299
ServiceResult.success(message: 'Folder was successfully copied')
when Net::HTTPUnauthorized
when 401
Util.error(:unauthorized, "Unauthorized (copy_folder)")
when Net::HTTPNotFound
when 404
Util.error(:not_found, "Project folder not found (copy_folder)")
when Net::HTTPConflict
when 409
Util.error(:conflict, Util.error_text_from_response(response))
else
Util.error(:unknown, "Unexpected response (copy_folder): #{response.code}", response)
Util.error(:unknown, "Unexpected response (copy_folder): #{response.status}", response)
end
end
end

# rubocop:enable Metrics/AbcSize
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -44,28 +44,34 @@ def self.call(storage:, folder_path:)

# rubocop:disable Metrics/AbcSize
def call(folder_path:)
response = Util.http(@uri).mkcol(
Util.join_uri_path(@uri.path, "remote.php/dav/files", CGI.escapeURIComponent(@username), Util.escape_path(folder_path)),
nil,
Util.basic_auth_header(@username, @password)
)
response = Util
.httpx
.basic_auth(@username, @password)
.mkcol(
Util.join_uri_path(
@uri,
"remote.php/dav/files",
CGI.escapeURIComponent(@username),
Util.escape_path(folder_path)
)
)

error_data = Storages::StorageErrorData.new(source: self.class, payload: response)

case response
when Net::HTTPSuccess
case response.status
when 200..299
ServiceResult.success(message: 'Folder was successfully created.')
when Net::HTTPMethodNotAllowed
when 405
if Util.error_text_from_response(response) == 'The resource you tried to create already exists'
ServiceResult.success(message: 'Folder already exists.')
else
Util.error(:not_allowed, 'Outbound request method not allowed', error_data)
end
when Net::HTTPNotFound
Util.error(:not_found, 'Outbound request destination not found', error_data)
when Net::HTTPUnauthorized
when 401
Util.error(:unauthorized, 'Outbound request not authorized', error_data)
when Net::HTTPConflict
when 404
Util.error(:not_found, 'Outbound request destination not found', error_data)
when 409
Util.error(:conflict, Util.error_text_from_response(response), error_data)
else
Util.error(:error, 'Outbound request failed', error_data)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,22 +45,24 @@ def self.call(storage:, user:, file_link:)
def call(user:, file_link:)
result = Util.token(user:, configuration: @configuration) do |token|
service_result = begin
response = Util.http(@uri).post(
Util.join_uri_path(@uri.path, '/ocs/v2.php/apps/dav/api/v1/direct'),
{ fileId: file_link.origin_id }.to_json,
{
'Authorization' => "Bearer #{token.access_token}",
'OCS-APIRequest' => 'true',
'Accept' => 'application/json',
'Content-Type' => 'application/json'
}
)
case response
when Net::HTTPSuccess
response = Util
.httpx
.post(
Util.join_uri_path(@uri, '/ocs/v2.php/apps/dav/api/v1/direct'),
json: { fileId: file_link.origin_id },
headers: {
'Authorization' => "Bearer #{token.access_token}",
'OCS-APIRequest' => 'true',
'Accept' => 'application/json',
'Content-Type' => 'application/json'
}
)
case response.status
when 200..299
ServiceResult.success(result: response)
when Net::HTTPNotFound
when 404
Util.error(:not_found, 'Outbound request destination not found!', response)
when Net::HTTPUnauthorized
when 401
Util.error(:unauthorized, 'Outbound request not authorized!', response)
else
Util.error(:error, 'Outbound request failed!')
Expand All @@ -72,7 +74,7 @@ def call(user:, file_link:)
if resp.body.blank?
Util.error(:unauthorized, 'Outbound request not authorized!')
else
ServiceResult.success(result: resp.body)
ServiceResult.success(result: resp.body.to_s)
end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,21 +52,19 @@ def call(user:, file_id:)
private

def file_info(file_id, token)
response = Util.http(@uri).get(
Util.join_uri_path(@uri.path, FILE_INFO_PATH, file_id),
{
'Authorization' => "Bearer #{token.access_token}",
'Accept' => 'application/json',
'OCS-APIRequest' => 'true'
}
)

case response
when Net::HTTPSuccess
response = Util
.httpx
.with(headers: { 'Authorization' => "Bearer #{token.access_token}",
'Accept' => 'application/json',
'OCS-APIRequest' => 'true' })
.get(Util.join_uri_path(@uri, FILE_INFO_PATH, file_id))

case response.status
when 200..299
ServiceResult.success(result: response.body)
when Net::HTTPNotFound
when 404
Util.error(:not_found, 'Outbound request destination not found!', response)
when Net::HTTPUnauthorized
when 401
Util.error(:unauthorized, 'Outbound request not authorized!', response)
else
Util.error(:error, 'Outbound request failed!')
Expand All @@ -84,7 +82,7 @@ def parse_json
def handle_failure
->(response_object) do
case response_object.ocs.data.statuscode
when 200
when 200..299
ServiceResult.success(result: response_object)
when 403
Util.error(:forbidden, 'Access to storage file forbidden!', response_object)
Expand Down
Loading

0 comments on commit e10f5e1

Please sign in to comment.