aspera-cli 4.26.2 → 4.27.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +310 -21
- data/CONTRIBUTING.md +99 -14
- data/TODO.md +50 -0
- data/bin/ascli +3 -3
- data/docs/README.md +10977 -0
- data/docs/test-mcp-with-ai.md +202 -0
- data/lib/aspera/agent/base.rb +29 -7
- data/lib/aspera/agent/connect.rb +58 -21
- data/lib/aspera/agent/desktop.rb +53 -18
- data/lib/aspera/agent/direct.rb +71 -40
- data/lib/aspera/agent/factory.rb +3 -3
- data/lib/aspera/agent/httpgw.rb +55 -14
- data/lib/aspera/agent/node.rb +34 -2
- data/lib/aspera/agent/transferd.rb +48 -12
- data/lib/aspera/api/alee.rb +1 -1
- data/lib/aspera/api/aoc.rb +42 -44
- data/lib/aspera/api/cos_node.rb +10 -9
- data/lib/aspera/api/faspex.rb +16 -15
- data/lib/aspera/api/httpgw.rb +23 -23
- data/lib/aspera/api/node.rb +51 -70
- data/lib/aspera/api/queries/bss_subscription_account.graphql +18 -0
- data/lib/aspera/api/queries/bss_subscription_usage.graphql +18 -0
- data/lib/aspera/ascmd.rb +32 -30
- data/lib/aspera/ascp/installation.rb +75 -69
- data/lib/aspera/ascp/management.rb +7 -8
- data/lib/aspera/assert.rb +12 -13
- data/lib/aspera/cli/ascp_actions.rb +155 -0
- data/lib/aspera/cli/async_transfer_store.rb +125 -0
- data/lib/aspera/cli/bootstrapper.rb +197 -0
- data/lib/aspera/cli/command_registry.rb +145 -0
- data/lib/aspera/cli/command_spec.rb +141 -0
- data/lib/aspera/cli/context.rb +19 -6
- data/lib/aspera/cli/error.rb +16 -0
- data/lib/aspera/cli/extended_value.rb +27 -26
- data/lib/aspera/cli/formatter.rb +95 -59
- data/lib/aspera/cli/gem_checker.rb +65 -0
- data/lib/aspera/cli/hints.rb +3 -3
- data/lib/aspera/cli/http.rb +74 -30
- data/lib/aspera/cli/info.rb +2 -0
- data/lib/aspera/cli/mailer.rb +97 -0
- data/lib/aspera/cli/mcp_tool.rb +225 -0
- data/lib/aspera/cli/option_declarator.rb +77 -0
- data/lib/aspera/cli/options.schema.yaml +634 -7
- data/lib/aspera/cli/parser.rb +1217 -0
- data/lib/aspera/cli/plugins/alee.rb +20 -22
- data/lib/aspera/cli/plugins/aoc.rb +1178 -881
- data/lib/aspera/cli/plugins/ats.rb +205 -162
- data/lib/aspera/cli/plugins/base.rb +703 -175
- data/lib/aspera/cli/plugins/basic_auth.rb +7 -9
- data/lib/aspera/cli/plugins/config.rb +434 -757
- data/lib/aspera/cli/plugins/console.rb +107 -65
- data/lib/aspera/cli/plugins/cos.rb +46 -33
- data/lib/aspera/cli/plugins/factory.rb +6 -6
- data/lib/aspera/cli/plugins/faspex5.rb +627 -388
- data/lib/aspera/cli/plugins/faspio.rb +54 -51
- data/lib/aspera/cli/plugins/httpgw.rb +18 -25
- data/lib/aspera/cli/plugins/mcp.rb +279 -0
- data/lib/aspera/cli/plugins/node.rb +988 -840
- data/lib/aspera/cli/plugins/oauth.rb +7 -10
- data/lib/aspera/cli/plugins/orchestrator.rb +112 -135
- data/lib/aspera/cli/plugins/preview.rb +195 -157
- data/lib/aspera/cli/plugins/server.rb +141 -91
- data/lib/aspera/cli/plugins/shares.rb +343 -110
- data/lib/aspera/cli/preset_actions.rb +159 -0
- data/lib/aspera/cli/preset_manager.rb +82 -39
- data/lib/aspera/cli/result.rb +78 -26
- data/lib/aspera/cli/runner.rb +323 -153
- data/lib/aspera/cli/secret_finder.rb +40 -0
- data/lib/aspera/cli/special_values.rb +1 -0
- data/lib/aspera/cli/sync_actions.rb +89 -64
- data/lib/aspera/cli/terminal_formatter.rb +3 -3
- data/lib/aspera/cli/transfer_actions.rb +90 -0
- data/lib/aspera/cli/transfer_agent.rb +129 -64
- data/lib/aspera/cli/transfer_progress.rb +9 -9
- data/lib/aspera/cli/vault_manager.rb +79 -0
- data/lib/aspera/cli/version.rb +1 -1
- data/lib/aspera/cli/wizard.rb +28 -30
- data/lib/aspera/colors.rb +3 -3
- data/lib/aspera/command_line_builder.rb +34 -34
- data/lib/aspera/command_line_converter.rb +1 -1
- data/lib/aspera/coverage.rb +1 -2
- data/lib/aspera/data_repository.rb +2 -1
- data/lib/aspera/dot_container.rb +12 -12
- data/lib/aspera/environment.rb +30 -23
- data/lib/aspera/exec_spec.rb +13 -0
- data/lib/aspera/faspex_gw.rb +5 -5
- data/lib/aspera/faspex_postproc.rb +16 -10
- data/lib/aspera/graphql.rb +37 -0
- data/lib/aspera/hash_ext.rb +8 -2
- data/lib/aspera/json_rpc/client.rb +62 -0
- data/lib/aspera/json_rpc/version.rb +7 -0
- data/lib/aspera/keychain/base.rb +10 -3
- data/lib/aspera/keychain/encrypted_hash.rb +92 -17
- data/lib/aspera/keychain/factory.rb +20 -8
- data/lib/aspera/keychain/hashicorp_vault.rb +1 -1
- data/lib/aspera/keychain/macos_security.rb +23 -25
- data/lib/aspera/keychain/one_password_api.rb +86 -0
- data/lib/aspera/keychain/one_password_base.rb +34 -0
- data/lib/aspera/keychain/one_password_cli.rb +98 -0
- data/lib/aspera/link_header.rb +82 -0
- data/lib/aspera/log.rb +29 -15
- data/lib/aspera/markdown.rb +90 -7
- data/lib/aspera/nagios.rb +8 -8
- data/lib/aspera/node_simulator.rb +35 -27
- data/lib/aspera/oauth/base.rb +9 -10
- data/lib/aspera/oauth/boot.rb +5 -5
- data/lib/aspera/oauth/factory.rb +12 -10
- data/lib/aspera/oauth/jwt.rb +9 -11
- data/lib/aspera/oauth/web.rb +6 -6
- data/lib/aspera/persistency_action_once.rb +12 -12
- data/lib/aspera/persistency_folder.rb +18 -11
- data/lib/aspera/preview/file_types.rb +5 -5
- data/lib/aspera/preview/generator.rb +52 -49
- data/lib/aspera/preview/options.rb +3 -2
- data/lib/aspera/preview/terminal.rb +5 -5
- data/lib/aspera/preview/utils.rb +66 -19
- data/lib/aspera/products/connect.rb +2 -2
- data/lib/aspera/products/desktop.rb +1 -1
- data/lib/aspera/products/other.rb +3 -3
- data/lib/aspera/products/transferd.rb +4 -4
- data/lib/aspera/proxy_auto_config.rb +15 -14
- data/lib/aspera/rest.rb +159 -151
- data/lib/aspera/rest_error_analyzer.rb +6 -6
- data/lib/aspera/rest_errors_aspera.rb +0 -10
- data/lib/aspera/rest_list.rb +11 -10
- data/lib/aspera/schema/IBM Aspera Node API-4.4.6.yaml +6232 -0
- data/lib/aspera/schema/IBM Aspera faspio Gateway API-1.0.0.yaml +249 -0
- data/lib/aspera/schema/IBM Aspera on Cloud API-0.2.6-enhanced.yaml +1853 -510
- data/lib/aspera/schema/IBM_Aspera_Shares.yaml +4653 -0
- data/lib/aspera/schema/documentation.rb +65 -28
- data/lib/aspera/schema/reader.rb +136 -13
- data/lib/aspera/schema/registry.rb +60 -8
- data/lib/aspera/secret_hider.rb +12 -7
- data/lib/aspera/ssh.rb +64 -31
- data/lib/aspera/ssl.rb +5 -5
- data/lib/aspera/sync/conf.schema.yaml +2 -2
- data/lib/aspera/sync/database.rb +2 -2
- data/lib/aspera/sync/operations.rb +22 -25
- data/lib/aspera/temp_file_manager.rb +25 -5
- data/lib/aspera/timer_limiter.rb +1 -1
- data/lib/aspera/transfer/faux_file.rb +24 -11
- data/lib/aspera/transfer/parameters.rb +36 -34
- data/lib/aspera/transfer/result.rb +74 -0
- data/lib/aspera/transfer/resumer.rb +10 -10
- data/lib/aspera/transfer/spec.rb +18 -1
- data/lib/aspera/transfer/spec.schema.yaml +12 -3
- data/lib/aspera/uri_reader.rb +52 -15
- data/lib/aspera/web_auth.rb +8 -7
- data/lib/aspera/web_server_simple.rb +15 -12
- data/lib/aspera/yaml.rb +5 -4
- data.tar.gz.sig +0 -0
- metadata +34 -6
- metadata.gz.sig +0 -0
- data/lib/aspera/cli/manager.rb +0 -766
- data/lib/aspera/cli/plugins/faspex.rb +0 -539
- data/lib/aspera/json_rpc.rb +0 -52
- data/lib/aspera/transfer/uri.rb +0 -56
|
@@ -58,7 +58,7 @@ module Aspera
|
|
|
58
58
|
pixel_colors = []
|
|
59
59
|
@image.scale(*terminal_scaling(@image.rows, @image.columns)).each_pixel do |pixel, col, row|
|
|
60
60
|
pixel_rgb = [pixel.red, pixel.green, pixel.blue]
|
|
61
|
-
pixel_rgb = pixel_rgb.map{ |color| color >> shift_for_8_bit} unless shift_for_8_bit.eql?(0)
|
|
61
|
+
pixel_rgb = pixel_rgb.map { |color| color >> shift_for_8_bit } unless shift_for_8_bit.eql?(0)
|
|
62
62
|
# Initialize the destination 2D pixel matrix row by row.
|
|
63
63
|
pixel_colors[row] ||= []
|
|
64
64
|
pixel_colors[row][col] = pixel_rgb
|
|
@@ -87,7 +87,7 @@ module Aspera
|
|
|
87
87
|
dst_w, dst_h = terminal_scaling(src_h, src_w)
|
|
88
88
|
dst_w = [dst_w, 1].max
|
|
89
89
|
dst_h = [dst_h, 1].max
|
|
90
|
-
pixel_colors = Array.new(dst_h){Array.new(dst_w)}
|
|
90
|
+
pixel_colors = Array.new(dst_h) { Array.new(dst_w) }
|
|
91
91
|
x_ratio = src_w.to_f / dst_w
|
|
92
92
|
y_ratio = src_h.to_f / dst_h
|
|
93
93
|
dst_h.times do |dy|
|
|
@@ -98,7 +98,7 @@ module Aspera
|
|
|
98
98
|
sx = src_w - 1 if sx >= src_w
|
|
99
99
|
rgba = @png.get_pixel(sx, sy)
|
|
100
100
|
# ChunkyPNG stores pixels as 0xRRGGBBAA; extract 8-bit RGB channels.
|
|
101
|
-
pixel_colors[dy][dx] = %i[r g b].map{ |i| ::ChunkyPNG::Color.send(i, rgba)}
|
|
101
|
+
pixel_colors[dy][dx] = %i[r g b].map { |i| ::ChunkyPNG::Color.send(i, rgba) }
|
|
102
102
|
end
|
|
103
103
|
end
|
|
104
104
|
pixel_colors
|
|
@@ -178,7 +178,7 @@ module Aspera
|
|
|
178
178
|
size: blob.length
|
|
179
179
|
# width: image.columns,
|
|
180
180
|
# height: image.rows
|
|
181
|
-
}.map{ |k, v| "#{k}=#{v}"}.join(';')
|
|
181
|
+
}.map { |k, v| "#{k}=#{v}" }.join(';')
|
|
182
182
|
# `\a` is BEL and `\e` is ESC.
|
|
183
183
|
# See: https://github.com/ruby/ruby/blob/master/doc/syntax/literals.rdoc#label-Strings
|
|
184
184
|
# Return the full escape sequence expected by iTerm2-compatible terminals.
|
|
@@ -190,7 +190,7 @@ module Aspera
|
|
|
190
190
|
# @return [Boolean] `true` when the current terminal advertises iTerm2 image support
|
|
191
191
|
def iterm_supported?
|
|
192
192
|
TERM_ENV_VARS.each do |env_var|
|
|
193
|
-
return true if ITERM_NAMES.any?{ |term| ENV[env_var]&.include?(term)}
|
|
193
|
+
return true if ITERM_NAMES.any? { |term| ENV[env_var]&.include?(term) }
|
|
194
194
|
end
|
|
195
195
|
false
|
|
196
196
|
end
|
data/lib/aspera/preview/utils.rb
CHANGED
|
@@ -20,11 +20,25 @@ module Aspera
|
|
|
20
20
|
'-y', # overwrite output without asking
|
|
21
21
|
'-loglevel', 'error' # show only errors and up
|
|
22
22
|
].freeze
|
|
23
|
-
|
|
23
|
+
# Preferred H.264 encoders in order: best quality/compatibility first.
|
|
24
|
+
H264_ENCODER_PREFERENCE = %w[libx264 libopenh264 h264_nvenc h264_amf h264_qsv h264_vaapi h264_v4l2m2m].freeze
|
|
25
|
+
private_constant :EXTERNAL_TOOLS, :TEMP_FORMAT, :FFMPEG_DEFAULT_PARAMS, :H264_ENCODER_PREFERENCE
|
|
24
26
|
|
|
25
27
|
class << self
|
|
26
|
-
#
|
|
28
|
+
# Return the first H.264 encoder available in the local ffmpeg installation.
|
|
29
|
+
# Result is memoized after the first call.
|
|
30
|
+
# @return [String] encoder name (e.g. 'libx264', 'libopenh264')
|
|
31
|
+
# @raise [RuntimeError] if no supported H.264 encoder is found
|
|
32
|
+
def available_h264_encoder
|
|
33
|
+
return @available_h264_encoder if defined?(@available_h264_encoder)
|
|
34
|
+
stdout, = execute(:ffmpeg, '-encoders', mode: :capture, exception: false)
|
|
35
|
+
@available_h264_encoder = H264_ENCODER_PREFERENCE.find { |enc| stdout.include?(enc) } ||
|
|
36
|
+
raise("No supported H.264 encoder found in ffmpeg. Available: #{stdout.lines.grep(/h264/i).map(&:strip).join(', ')}")
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Check that external tools can be executed.
|
|
27
40
|
# @param skip_types [Array<Symbol>] list of tools to skip
|
|
41
|
+
# @raise [RuntimeError] if a required tool binary is missing
|
|
28
42
|
# @return [nil]
|
|
29
43
|
def check_tools(skip_types = [])
|
|
30
44
|
tools_to_check = EXTERNAL_TOOLS.dup
|
|
@@ -42,29 +56,47 @@ module Aspera
|
|
|
42
56
|
end
|
|
43
57
|
end
|
|
44
58
|
|
|
45
|
-
# Execute external command, verify it is in the supported list
|
|
59
|
+
# Execute external command, verify it is in the supported list.
|
|
60
|
+
# @param args [Array] command name followed by CLI arguments
|
|
61
|
+
# @param kwargs [Hash] execution options passed to {Environment.secure_execute}
|
|
62
|
+
# @raise [Aspera::AssertError] if the command is not in {EXTERNAL_TOOLS}
|
|
63
|
+
# @return [Array<String>] captured stdout and stderr lines depending on mode
|
|
46
64
|
def execute(*args, **kwargs)
|
|
47
|
-
Aspera.assert_values(args.first, EXTERNAL_TOOLS){'command'}
|
|
65
|
+
Aspera.assert_values(args.first, EXTERNAL_TOOLS) { 'command' }
|
|
48
66
|
Environment.secure_execute(*args, **kwargs)
|
|
49
67
|
end
|
|
50
68
|
|
|
51
|
-
# Execute external command
|
|
69
|
+
# Execute external command, capturing and discarding output unless it fails.
|
|
70
|
+
# On failure, the captured stderr is included in the raised exception message.
|
|
71
|
+
# @param args [Array] command name followed by CLI arguments
|
|
52
72
|
# @return [nil]
|
|
53
73
|
def silent_execute(*args)
|
|
54
|
-
execute(*args,
|
|
74
|
+
execute(*args, mode: :capture)
|
|
55
75
|
nil
|
|
56
76
|
end
|
|
57
77
|
|
|
58
|
-
# Execute `ffmpeg
|
|
78
|
+
# Execute `ffmpeg`, capturing output.
|
|
79
|
+
# On failure, the ffmpeg stderr is logged at debug level and re-raised.
|
|
80
|
+
# @param in [Array] input file path followed by input options
|
|
81
|
+
# @param out [Array] output file path followed by output options
|
|
82
|
+
# @param global [Array<String>] global options for ffmpeg
|
|
59
83
|
# @return [nil]
|
|
60
|
-
def ffmpeg(
|
|
61
|
-
Aspera.assert_type(
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
84
|
+
def ffmpeg(in:, out:, global: FFMPEG_DEFAULT_PARAMS)
|
|
85
|
+
Aspera.assert_type(global, Array)
|
|
86
|
+
# NOTE: cannot use just "in", as it is a reserved word in ruby
|
|
87
|
+
in_args = binding.local_variable_get(:in).dup
|
|
88
|
+
out_args = out.dup
|
|
89
|
+
Aspera.assert_type(in_args, Array)
|
|
90
|
+
Aspera.assert_type(out_args, Array)
|
|
91
|
+
in_file = in_args.shift
|
|
92
|
+
out_file = out_args.shift
|
|
93
|
+
execute(:ffmpeg, *global, *in_args, '-i', in_file, *out_args, out_file, mode: :capture)
|
|
94
|
+
nil
|
|
65
95
|
end
|
|
66
96
|
|
|
67
|
-
#
|
|
97
|
+
# Get duration of a video file using `ffprobe`.
|
|
98
|
+
# @param input_file [String] path to video file
|
|
99
|
+
# @return [Float] duration in seconds
|
|
68
100
|
def video_get_duration(input_file)
|
|
69
101
|
return execute(
|
|
70
102
|
:ffprobe,
|
|
@@ -76,23 +108,39 @@ module Aspera
|
|
|
76
108
|
).first.to_f
|
|
77
109
|
end
|
|
78
110
|
|
|
79
|
-
# File output
|
|
111
|
+
# File output pattern for ffmpeg, including temp folder.
|
|
112
|
+
# @param temp_folder [String] path to temp folder
|
|
113
|
+
# @return [String] file path pattern
|
|
80
114
|
def ffmpeg_fmt(temp_folder)
|
|
81
115
|
return File.join(temp_folder, TEMP_FORMAT)
|
|
82
116
|
end
|
|
83
117
|
|
|
118
|
+
# Get numbered temporary file path.
|
|
119
|
+
# @param temp_folder [String] path to temp folder
|
|
120
|
+
# @param file_number [Integer] frame index
|
|
121
|
+
# @return [String] file path
|
|
84
122
|
def get_tmp_num_filepath(temp_folder, file_number)
|
|
85
|
-
# Format using {Kernel.format}
|
|
86
123
|
return File.join(temp_folder, format(TEMP_FORMAT, file_number))
|
|
87
124
|
end
|
|
88
125
|
|
|
126
|
+
# Duplicate a video frame by creating symlinks.
|
|
127
|
+
# @param temp_folder [String] path to temp folder
|
|
128
|
+
# @param index [Integer] frame index to duplicate
|
|
129
|
+
# @param count [Integer] number of duplicate frames to create
|
|
130
|
+
# @return [nil]
|
|
89
131
|
def video_dupe_frame(temp_folder, index, count)
|
|
90
132
|
input_file = get_tmp_num_filepath(temp_folder, index)
|
|
91
133
|
1.upto(count) do |i|
|
|
92
134
|
FileUtils.ln_s(input_file, get_tmp_num_filepath(temp_folder, index + i))
|
|
93
135
|
end
|
|
136
|
+
nil
|
|
94
137
|
end
|
|
95
138
|
|
|
139
|
+
# Blend transition frames between two keyframes using ImageMagick.
|
|
140
|
+
# @param temp_folder [String] path to temp folder
|
|
141
|
+
# @param index_begin [Integer] starting frame index
|
|
142
|
+
# @param index_end [Integer] ending frame index
|
|
143
|
+
# @return [nil]
|
|
96
144
|
def video_blend_frames(temp_folder, index_begin, index_end)
|
|
97
145
|
img1 = get_tmp_num_filepath(temp_folder, index_begin)
|
|
98
146
|
img2 = get_tmp_num_filepath(temp_folder, index_end)
|
|
@@ -102,6 +150,7 @@ module Aspera
|
|
|
102
150
|
filename = get_tmp_num_filepath(temp_folder, index_begin + i)
|
|
103
151
|
silent_execute(:magick, 'composite', '-blend', percent, img2, img1, filename)
|
|
104
152
|
end
|
|
153
|
+
nil
|
|
105
154
|
end
|
|
106
155
|
|
|
107
156
|
# Dump a frame from a video file
|
|
@@ -112,10 +161,8 @@ module Aspera
|
|
|
112
161
|
# @return [nil]
|
|
113
162
|
def video_dump_frame(input_file, offset_seconds, scale, output_file)
|
|
114
163
|
ffmpeg(
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
out_f: output_file,
|
|
118
|
-
out_p: ['-frames:v', 1, '-filter:v', "scale=#{scale}"]
|
|
164
|
+
in: [input_file, '-ss', offset_seconds],
|
|
165
|
+
out: [output_file, '-frames:v', 1, '-filter:v', "scale='#{scale}'"]
|
|
119
166
|
)
|
|
120
167
|
end
|
|
121
168
|
|
|
@@ -47,7 +47,7 @@ module Aspera
|
|
|
47
47
|
app_root: File.join(Dir.home, '.aspera', 'connect'),
|
|
48
48
|
run_root: File.join(Dir.home, '.aspera', 'connect')
|
|
49
49
|
}]
|
|
50
|
-
end.map{ |i| i.merge({expected: APP_NAME})}
|
|
50
|
+
end.map { |i| i.merge({expected: APP_NAME}) }
|
|
51
51
|
end
|
|
52
52
|
end
|
|
53
53
|
|
|
@@ -65,7 +65,7 @@ module Aspera
|
|
|
65
65
|
Log.dump(:javascript, connect_versions_javascript)
|
|
66
66
|
# get javascript object only
|
|
67
67
|
found = connect_versions_javascript.match(/^.*? = (.*);/)
|
|
68
|
-
|
|
68
|
+
Aspera.assert(!found.nil?, type: Cli::Error) { 'Problem when getting connect versions from internet' }
|
|
69
69
|
all_data = JSON.parse(found[1])
|
|
70
70
|
@connect_versions = all_data['entries']
|
|
71
71
|
end
|
|
@@ -57,15 +57,15 @@ module Aspera
|
|
|
57
57
|
# Find installed products and provide paths for it.
|
|
58
58
|
# @param scan_locations [Array] Array of Hash with keys: expected, app_root, sub_bin, ascp_path, name, version
|
|
59
59
|
# @return [Array] of products found, with filled missing fields
|
|
60
|
-
# @raise
|
|
60
|
+
# @raise [RuntimeError] if no installed product found
|
|
61
61
|
def find(scan_locations)
|
|
62
62
|
product_names = []
|
|
63
63
|
found = scan_locations.select do |item|
|
|
64
64
|
product_names.push(item[:expected]) unless product_names.include?(item[:expected])
|
|
65
65
|
# skip if not main folder
|
|
66
|
-
Log.log.trace1{"Checking #{item[:app_root]}"}
|
|
66
|
+
Log.log.trace1 { "Checking #{item[:app_root]}" }
|
|
67
67
|
next false unless Dir.exist?(item[:app_root])
|
|
68
|
-
Log.log.debug{"Found #{item[:expected]}"}
|
|
68
|
+
Log.log.debug { "Found #{item[:expected]}" }
|
|
69
69
|
sub_bin = item[:sub_bin] || 'bin'
|
|
70
70
|
item[:ascp_path] = File.join(item[:app_root], sub_bin, Environment.instance.exe_file('ascp'))
|
|
71
71
|
# skip if no ascp
|
|
@@ -17,17 +17,17 @@ module Aspera
|
|
|
17
17
|
[{
|
|
18
18
|
app_root: sdk_directory,
|
|
19
19
|
sub_bin: ''
|
|
20
|
-
}].map{ |i| i.merge({expected: APP_NAME})}
|
|
20
|
+
}].map { |i| i.merge({expected: APP_NAME}) }
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
# location of SDK files
|
|
24
24
|
def sdk_directory=(folder)
|
|
25
|
-
Log.log.debug{"sdk_directory=#{folder}"}
|
|
25
|
+
Log.log.debug { "sdk_directory=#{folder}" }
|
|
26
26
|
@sdk_dir = folder
|
|
27
27
|
sdk_directory
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
-
# @return the path to folder where SDK is or should be installed
|
|
30
|
+
# @return [String] the path to folder where SDK is or should be installed
|
|
31
31
|
def sdk_directory
|
|
32
32
|
Aspera.assert(!@sdk_dir.nil?, 'SDK path was not initialized')
|
|
33
33
|
@sdk_dir
|
|
@@ -53,7 +53,7 @@ module Aspera
|
|
|
53
53
|
end
|
|
54
54
|
end
|
|
55
55
|
Aspera.assert(!result.nil?, 'Port not found in daemon logs')
|
|
56
|
-
Log.log.debug{"Got port #{result} from log"}
|
|
56
|
+
Log.log.debug { "Got port #{result} from log" }
|
|
57
57
|
return result
|
|
58
58
|
end
|
|
59
59
|
end
|
|
@@ -16,7 +16,7 @@ module URI
|
|
|
16
16
|
def register_proxy_finder
|
|
17
17
|
Aspera.assert(block_given?, 'block required for register_proxy_finder')
|
|
18
18
|
# overload the method in URI : call user's provided block and fallback to original method
|
|
19
|
-
define_method(:find_proxy){ |env_vars = ENV| yield(to_s) || find_proxy_orig(env_vars)}
|
|
19
|
+
define_method(:find_proxy) { |env_vars = ENV| yield(to_s) || find_proxy_orig(env_vars) }
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
22
|
end
|
|
@@ -44,7 +44,7 @@ module Aspera
|
|
|
44
44
|
context_ip = r_addr.to_s if r_addr.is_a?(Resolv::IPv4)
|
|
45
45
|
end
|
|
46
46
|
end
|
|
47
|
-
|
|
47
|
+
Aspera.assert(!context_ip.nil?) { "DNS name not found: #{context_host}" }
|
|
48
48
|
# NOTE: Javascript code here with string inclusions
|
|
49
49
|
javascript = <<END_OF_JAVASCRIPT
|
|
50
50
|
function dnsResolve(host) {
|
|
@@ -63,7 +63,7 @@ END_OF_JAVASCRIPT
|
|
|
63
63
|
|
|
64
64
|
attr_writer :proxy_user, :proxy_pass
|
|
65
65
|
|
|
66
|
-
# @param proxy_auto_config the proxy auto config script to be evaluated
|
|
66
|
+
# @param proxy_auto_config [String] the proxy auto config script to be evaluated
|
|
67
67
|
def initialize(proxy_auto_config)
|
|
68
68
|
# user provided javascript with FindProxyForURL function
|
|
69
69
|
@proxy_auto_config = proxy_auto_config
|
|
@@ -73,18 +73,18 @@ END_OF_JAVASCRIPT
|
|
|
73
73
|
end
|
|
74
74
|
|
|
75
75
|
def register_uri_generic
|
|
76
|
-
URI::Generic.register_proxy_finder{ |url_str| get_proxies(url_str).first}
|
|
76
|
+
URI::Generic.register_proxy_finder { |url_str| get_proxies(url_str).first }
|
|
77
77
|
# allow chaining
|
|
78
78
|
return self
|
|
79
79
|
end
|
|
80
80
|
|
|
81
81
|
# execute proxy auto config script for the given URL : https://en.wikipedia.org/wiki/Proxy_auto-config
|
|
82
|
-
# @return either nil, or a String formatted following PAC standard
|
|
82
|
+
# @return [String, nil] either nil, or a String formatted following PAC standard
|
|
83
83
|
def find_proxy_for_url(service_url)
|
|
84
84
|
uri = URI.parse(service_url)
|
|
85
85
|
simple_url = "#{uri.scheme}://#{uri.host}"
|
|
86
86
|
if !@cache.key?(simple_url)
|
|
87
|
-
Log.log.debug{"PAC: starting javascript for #{service_url}"}
|
|
87
|
+
Log.log.debug { "PAC: starting javascript for #{service_url}" }
|
|
88
88
|
# require at runtime, in case there is no js engine
|
|
89
89
|
require 'execjs'
|
|
90
90
|
# read template lib
|
|
@@ -93,20 +93,20 @@ END_OF_JAVASCRIPT
|
|
|
93
93
|
js_to_execute = "#{pac_dns_functions(uri.host)}#{@pac_functions}#{@proxy_auto_config}"
|
|
94
94
|
executable_js = ExecJS.compile(js_to_execute)
|
|
95
95
|
@cache[simple_url] = executable_js.call(PAC_MAIN_FUNCTION, simple_url, uri.host)
|
|
96
|
-
Log.log.debug{"PAC: result: #{@cache[simple_url]}"}
|
|
96
|
+
Log.log.debug { "PAC: result: #{@cache[simple_url]}" }
|
|
97
97
|
end
|
|
98
98
|
return @cache[simple_url]
|
|
99
99
|
end
|
|
100
100
|
|
|
101
101
|
# used to replace URI::Generic.find_proxy
|
|
102
|
-
# @return Array of
|
|
102
|
+
# @return [Array<URI>] list of URIs, possibly empty
|
|
103
103
|
def get_proxies(service_url)
|
|
104
104
|
# prepare result
|
|
105
105
|
uri_list = []
|
|
106
106
|
# execute PAC script
|
|
107
107
|
proxy_list_str = find_proxy_for_url(service_url)
|
|
108
108
|
if !proxy_list_str.is_a?(String)
|
|
109
|
-
Log.log.warn{"PAC: did not return a String, returned #{proxy_list_str.class}"}
|
|
109
|
+
Log.log.warn { "PAC: did not return a String, returned #{proxy_list_str.class}" }
|
|
110
110
|
return uri_list
|
|
111
111
|
end
|
|
112
112
|
proxy_list_str.strip!
|
|
@@ -114,7 +114,8 @@ END_OF_JAVASCRIPT
|
|
|
114
114
|
proxy_list_str.split(';').each do |item|
|
|
115
115
|
# strip and split by space
|
|
116
116
|
parts = item.strip.split
|
|
117
|
-
|
|
117
|
+
proxy_type = parts.shift
|
|
118
|
+
case proxy_type
|
|
118
119
|
when 'DIRECT'
|
|
119
120
|
Aspera.assert(parts.empty?, 'DIRECT has no param')
|
|
120
121
|
Log.log.debug('ignoring proxy DIRECT')
|
|
@@ -131,15 +132,15 @@ END_OF_JAVASCRIPT
|
|
|
131
132
|
uri.password = @proxy_pass
|
|
132
133
|
uri_list.push(uri)
|
|
133
134
|
else
|
|
134
|
-
Log.log.warn{"PAC: PROXY must be <address>:<port>, ignoring #{addr_port}"}
|
|
135
|
+
Log.log.warn { "PAC: PROXY must be <address>:<port>, ignoring #{addr_port}" }
|
|
135
136
|
end
|
|
136
137
|
rescue StandardError => e
|
|
137
|
-
Log.log.warn{"PAC: cannot parse #{addr_port} #{e}"}
|
|
138
|
+
Log.log.warn { "PAC: cannot parse #{addr_port} #{e}" }
|
|
138
139
|
end
|
|
139
|
-
else Log.log.warn{"PAC: ignoring proxy type #{
|
|
140
|
+
else Log.log.warn { "PAC: ignoring proxy type #{proxy_type}: not supported" }
|
|
140
141
|
end
|
|
141
142
|
end
|
|
142
|
-
Log.log.debug{"Proxies: #{uri_list}"}
|
|
143
|
+
Log.log.debug { "Proxies: #{uri_list}" }
|
|
143
144
|
return uri_list
|
|
144
145
|
end
|
|
145
146
|
end
|