diff --git a/README.md b/README.md index c880fea0..87c35fac 100644 --- a/README.md +++ b/README.md @@ -191,3 +191,11 @@ Your version of OpenSSL may be be outdated, make sure you are using the last one * __On Windows:__ A fix to the issue stated above has been found on [StackOverflow](http://stackoverflow.com/questions/5720484/how-to-solve-certificate-verify-failed-on-windows). If you follow the steps described in this topic, you will most likely get rid of this issue. + +### Solve Connection failures + +If your network is flaky you might try to change the way u3d uses ruby's Net::HTTP trsnsport mechanism + +* set U3D_HTTP_READ_TIMEOUT (defaults 300 seconds) to change the http read timeout + +* U3D_HTTP_MAX_RETRIES (ruby 2.5 only, defaults 1). Ruby automatically retries once upon failures on idempotents methods. From ruby 2.5. you can change the number of time ruby might retry. diff --git a/lib/u3d/utils.rb b/lib/u3d/utils.rb index 0d578c94..ccec6d2c 100644 --- a/lib/u3d/utils.rb +++ b/lib/u3d/utils.rb @@ -58,7 +58,7 @@ def follow_redirects(url, redirect_limit: 10, http_method: :get, request_headers uri = URI(url) begin use_ssl = /^https/.match(url) - Net::HTTP.start(uri.host, uri.port, use_ssl: use_ssl) do |http| + Net::HTTP.start(uri.host, uri.port, http_opts(use_ssl: use_ssl)) do |http| request = http_request_class http_method, uri request_headers.each do |k, v| request[k] = v @@ -93,7 +93,7 @@ def download_file(path, url, size: nil) current = 0 last_print_update = 0 print_progress = UI.interactive? || U3dCore::Globals.verbose? - Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http| + Net::HTTP.start(uri.host, uri.port, http_opts(use_ssl: uri.scheme == 'https')) do |http| request = Net::HTTP::Get.new uri http.request request do |response| begin @@ -129,7 +129,7 @@ def get_url_content_length(url) UI.verbose "get_url_content_length #{url}" uri = URI(url) size = nil - Net::HTTP.start(uri.host, uri.port) do |http| + Net::HTTP.start(uri.host, uri.port, http_opts) do |http| response = http.request_head url size = Integer(response['Content-Length']) end @@ -204,6 +204,26 @@ def pretty_filesize(filesize) def windows_path(path) path.gsub(%r{\/(\d)}, '/\\\\\1').tr('/', '\\') end + + private + + def http_max_retries + ENV['U3D_HTTP_MAX_RETRIES'].to_i if ENV['U3D_HTTP_MAX_RETRIES'] + end + + def http_read_timeout + return ENV['U3D_HTTP_READ_TIMEOUT'].to_i if ENV['U3D_HTTP_READ_TIMEOUT'] + 300 + end + + def http_opts(opt = {}) + # the keys are #ca_file, #ca_path, cert, #cert_store, ciphers, #close_on_empty_response, key, #open_timeout, + # #read_timeout, #ssl_timeout, #ssl_version, use_ssl, #verify_callback, #verify_depth and verify_mode + opt[:max_retries] = http_max_retries if http_max_retries + opt[:read_timeout] = http_read_timeout if http_read_timeout + UI.verbose "Using http opts: #{opt}" + opt + end end end # rubocop:enable ModuleLength