net-ftp 0.1.2 → 0.2.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cb3a59b7b4a2153ab8e56bdf8dbad9402c9ae73aeb5dc765a990dc0fe491dd46
4
- data.tar.gz: 0c5552bcd67be7ae0087d83345716a8b6014d2d5347348ca72a48c5e1c306a2b
3
+ metadata.gz: cf9d2560e8bb495195915b83e2fa701ff039c328b06934515ac50f1309025769
4
+ data.tar.gz: 2231a3b5311f57b6fee02282e8cb41fd717b79cc1f2186d76483db8fd873ff47
5
5
  SHA512:
6
- metadata.gz: 4a67c6f9918df76bfb390cbaa44216e5180ab8f28c703da4fbf2cc83dccd062d420eb180a7db489a37fdc8dfbb676dee78695b71082a622172e208fa220a4a2c
7
- data.tar.gz: b501f9ee7c06712ed74eef5b5f414d9abb772d41f639a4bd71824e58cc62230715f5a23d139ccb0ff6c4cbf3033cb931c5921b9616e6f06c249fdcdcd8547af8
6
+ metadata.gz: 52f5676aecc77cc97286bbbe6c6649ff9a966e7e161674643593db4cdb1aacdd6080fa25d8f8e3e379b9649125a5dd1167b3292401268141f0924bf618e4e0ad
7
+ data.tar.gz: 19212687975c12da4fee59c30e620ead52ad0e5a8beccf178de4c74809e43fc662c6cf5a5e084d3b222c19d5bacc4c352bdebb7b2d18939f9762600f9c43b60d
@@ -0,0 +1,6 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: 'github-actions'
4
+ directory: '/'
5
+ schedule:
6
+ interval: 'weekly'
@@ -7,11 +7,11 @@ jobs:
7
7
  name: build (${{ matrix.ruby }} / ${{ matrix.os }})
8
8
  strategy:
9
9
  matrix:
10
- ruby: [ '3.0', 2.7, 2.6, 2.5, 2.4, head ]
10
+ ruby: [ head, '3.1', '3.0', '2.7', '2.6' ]
11
11
  os: [ ubuntu-latest, macos-latest ]
12
12
  runs-on: ${{ matrix.os }}
13
13
  steps:
14
- - uses: actions/checkout@v2
14
+ - uses: actions/checkout@v3
15
15
  - name: Set up Ruby
16
16
  uses: ruby/setup-ruby@v1
17
17
  with:
data/lib/net/ftp.rb CHANGED
@@ -85,7 +85,7 @@ module Net
85
85
  end
86
86
 
87
87
  # :stopdoc:
88
- VERSION = "0.1.2"
88
+ VERSION = "0.2.0"
89
89
  FTP_PORT = 21
90
90
  CRLF = "\r\n"
91
91
  DEFAULT_BLOCKSIZE = BufferedIO::BUFSIZE
@@ -98,10 +98,19 @@ module Net
98
98
  # When +true+, the connection is in passive mode. Default: +true+.
99
99
  attr_accessor :passive
100
100
 
101
+ # When +true+, use the IP address in PASV responses. Otherwise, it uses
102
+ # the same IP address for the control connection. Default: +false+.
103
+ attr_accessor :use_pasv_ip
104
+
101
105
  # When +true+, all traffic to and from the server is written
102
106
  # to +$stdout+. Default: +false+.
103
107
  attr_accessor :debug_mode
104
108
 
109
+ # Sets or retrieves the output stream for debugging.
110
+ # Output stream will be used only when +debug_mode+ is set to true.
111
+ # The default value is +$stdout+.
112
+ attr_accessor :debug_output
113
+
105
114
  # Sets or retrieves the +resume+ status, which decides whether incomplete
106
115
  # transfers are resumed or restarted. Default: +false+.
107
116
  attr_accessor :resume
@@ -191,6 +200,8 @@ module Net
191
200
  # as parameters.
192
201
  # private_data_connection:: If true, TLS is used for data connections.
193
202
  # Default: +true+ when +options+[:ssl] is true.
203
+ # implicit_ftps:: If true, TLS is established on initial connection.
204
+ # Default: +false+
194
205
  # username:: Username for login. If +options+[:username] is the string
195
206
  # "anonymous" and the +options+[:password] is +nil+,
196
207
  # "anonymous@" is used as a password.
@@ -206,6 +217,9 @@ module Net
206
217
  # handshake.
207
218
  # See Net::FTP#ssl_handshake_timeout for
208
219
  # details. Default: +nil+.
220
+ # use_pasv_ip:: When +true+, use the IP address in PASV responses.
221
+ # Otherwise, it uses the same IP address for the control
222
+ # connection. Default: +false+.
209
223
  # debug_mode:: When +true+, all traffic to and from the server is
210
224
  # written to +$stdout+. Default: +false+.
211
225
  #
@@ -241,6 +255,11 @@ module Net
241
255
  else
242
256
  @private_data_connection = options[:private_data_connection]
243
257
  end
258
+ if options[:implicit_ftps].nil?
259
+ @implicit_ftps = false
260
+ else
261
+ @implicit_ftps = options[:implicit_ftps]
262
+ end
244
263
  else
245
264
  @ssl_context = nil
246
265
  if options[:private_data_connection]
@@ -248,6 +267,11 @@ module Net
248
267
  "private_data_connection can be set to true only when ssl is enabled"
249
268
  end
250
269
  @private_data_connection = false
270
+ if options[:implicit_ftps]
271
+ raise ArgumentError,
272
+ "implicit_ftps can be set to true only when ssl is enabled"
273
+ end
274
+ @implicit_ftps = false
251
275
  end
252
276
  @binary = true
253
277
  if options[:passive].nil?
@@ -260,12 +284,14 @@ module Net
260
284
  else
261
285
  @debug_mode = options[:debug_mode]
262
286
  end
287
+ @debug_output = $stdout
263
288
  @resume = false
264
289
  @bare_sock = @sock = NullSocket.new
265
290
  @logged_in = false
266
291
  @open_timeout = options[:open_timeout]
267
292
  @ssl_handshake_timeout = options[:ssl_handshake_timeout]
268
293
  @read_timeout = options[:read_timeout] || 60
294
+ @use_pasv_ip = options[:use_pasv_ip] || false
269
295
  if host
270
296
  connect(host, options[:port] || FTP_PORT)
271
297
  if options[:username]
@@ -370,19 +396,17 @@ module Net
370
396
  # <tt>Errno::ECONNREFUSED</tt>) if the connection cannot be established.
371
397
  #
372
398
  def connect(host, port = FTP_PORT)
373
- if @debug_mode
374
- print "connect: ", host, ", ", port, "\n"
375
- end
399
+ debug_print "connect: #{host}:#{port}"
376
400
  synchronize do
377
401
  @host = host
378
402
  @bare_sock = open_socket(host, port)
379
- @sock = BufferedSocket.new(@bare_sock, read_timeout: @read_timeout)
380
- voidresp
381
403
  if @ssl_context
382
404
  begin
383
- voidcmd("AUTH TLS")
384
- ssl_sock = start_tls_session(@bare_sock)
385
- @sock = BufferedSSLSocket.new(ssl_sock, read_timeout: @read_timeout)
405
+ unless @implicit_ftps
406
+ set_socket(BufferedSocket.new(@bare_sock, read_timeout: @read_timeout))
407
+ voidcmd("AUTH TLS")
408
+ end
409
+ set_socket(BufferedSSLSocket.new(start_tls_session(@bare_sock), read_timeout: @read_timeout), @implicit_ftps)
386
410
  if @private_data_connection
387
411
  voidcmd("PBSZ 0")
388
412
  voidcmd("PROT P")
@@ -391,6 +415,8 @@ module Net
391
415
  @sock.close
392
416
  raise
393
417
  end
418
+ else
419
+ set_socket(BufferedSocket.new(@bare_sock, read_timeout: @read_timeout))
394
420
  end
395
421
  end
396
422
  end
@@ -422,9 +448,7 @@ module Net
422
448
  # Ensures that +line+ has a control return / line feed (CRLF) and writes
423
449
  # it to the socket.
424
450
  def putline(line) # :nodoc:
425
- if @debug_mode
426
- print "put: ", sanitize(line), "\n"
427
- end
451
+ debug_print "put: #{sanitize(line)}"
428
452
  if /[\r\n]/ =~ line
429
453
  raise ArgumentError, "A line must not contain CR or LF"
430
454
  end
@@ -437,9 +461,7 @@ module Net
437
461
  def getline # :nodoc:
438
462
  line = @sock.readline # if get EOF, raise EOFError
439
463
  line.sub!(/(\r\n|\n|\r)\z/n, "")
440
- if @debug_mode
441
- print "get: ", sanitize(line), "\n"
442
- end
464
+ debug_print "get: #{sanitize(line)}"
443
465
  return line
444
466
  end
445
467
  private :getline
@@ -537,7 +559,6 @@ module Net
537
559
  host, port = parse227(sendcmd("PASV"))
538
560
  else
539
561
  host, port = parse229(sendcmd("EPSV"))
540
- # host, port = parse228(sendcmd("LPSV"))
541
562
  end
542
563
  return host, port
543
564
  end
@@ -1240,7 +1261,7 @@ module Net
1240
1261
  #
1241
1262
  def abort
1242
1263
  line = "ABOR" + CRLF
1243
- print "put: ABOR\n" if @debug_mode
1264
+ debug_print "put: ABOR"
1244
1265
  @sock.send(line, Socket::MSG_OOB)
1245
1266
  resp = getmultiline
1246
1267
  unless ["426", "226", "225"].include?(resp[0, 3])
@@ -1260,7 +1281,7 @@ module Net
1260
1281
  if /[\r\n]/ =~ line
1261
1282
  raise ArgumentError, "A line must not contain CR or LF"
1262
1283
  end
1263
- print "put: #{line}\n" if @debug_mode
1284
+ debug_print "put: #{line}"
1264
1285
  @sock.send(line + CRLF, Socket::MSG_OOB)
1265
1286
  return getresp
1266
1287
  end
@@ -1381,31 +1402,18 @@ module Net
1381
1402
  raise FTPReplyError, resp
1382
1403
  end
1383
1404
  if m = /\((?<host>\d+(?:,\d+){3}),(?<port>\d+,\d+)\)/.match(resp)
1384
- return parse_pasv_ipv4_host(m["host"]), parse_pasv_port(m["port"])
1405
+ if @use_pasv_ip
1406
+ host = parse_pasv_ipv4_host(m["host"])
1407
+ else
1408
+ host = @bare_sock.remote_address.ip_address
1409
+ end
1410
+ return host, parse_pasv_port(m["port"])
1385
1411
  else
1386
1412
  raise FTPProtoError, resp
1387
1413
  end
1388
1414
  end
1389
1415
  private :parse227
1390
1416
 
1391
- # handler for response code 228
1392
- # (Entering Long Passive Mode)
1393
- #
1394
- # Returns host and port.
1395
- def parse228(resp) # :nodoc:
1396
- if !resp.start_with?("228")
1397
- raise FTPReplyError, resp
1398
- end
1399
- if m = /\(4,4,(?<host>\d+(?:,\d+){3}),2,(?<port>\d+,\d+)\)/.match(resp)
1400
- return parse_pasv_ipv4_host(m["host"]), parse_pasv_port(m["port"])
1401
- elsif m = /\(6,16,(?<host>\d+(?:,\d+){15}),2,(?<port>\d+,\d+)\)/.match(resp)
1402
- return parse_pasv_ipv6_host(m["host"]), parse_pasv_port(m["port"])
1403
- else
1404
- raise FTPProtoError, resp
1405
- end
1406
- end
1407
- private :parse228
1408
-
1409
1417
  def parse_pasv_ipv4_host(s)
1410
1418
  return s.tr(",", ".")
1411
1419
  end
@@ -1453,6 +1461,13 @@ module Net
1453
1461
  end
1454
1462
  private :parse257
1455
1463
 
1464
+ #
1465
+ # Writes debug message to the debug output stream
1466
+ #
1467
+ def debug_print(msg)
1468
+ @debug_output << msg + "\n" if @debug_mode && @debug_output
1469
+ end
1470
+
1456
1471
  # :stopdoc:
1457
1472
  class NullSocket
1458
1473
  def read_timeout=(sec)
data/net-ftp.gemspec CHANGED
@@ -16,7 +16,7 @@ Gem::Specification.new do |spec|
16
16
  spec.summary = %q{Support for the File Transfer Protocol.}
17
17
  spec.description = %q{Support for the File Transfer Protocol.}
18
18
  spec.homepage = "https://github.com/ruby/net-ftp"
19
- spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
19
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.6.0")
20
20
  spec.licenses = ["Ruby", "BSD-2-Clause"]
21
21
 
22
22
  spec.metadata["homepage_uri"] = spec.homepage
@@ -25,10 +25,8 @@ Gem::Specification.new do |spec|
25
25
  # Specify which files should be added to the gem when it is released.
26
26
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
27
27
  spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
28
- `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
28
+ `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(bin|test|spec|features)/}) }
29
29
  end
30
- spec.bindir = "exe"
31
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
32
30
  spec.require_paths = ["lib"]
33
31
 
34
32
  spec.add_dependency "net-protocol"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: net-ftp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shugo Maeda
8
8
  autorequire:
9
- bindir: exe
9
+ bindir: bin
10
10
  cert_chain: []
11
- date: 2021-05-11 00:00:00.000000000 Z
11
+ date: 2022-10-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: net-protocol
@@ -45,14 +45,13 @@ executables: []
45
45
  extensions: []
46
46
  extra_rdoc_files: []
47
47
  files:
48
+ - ".github/dependabot.yml"
48
49
  - ".github/workflows/test.yml"
49
50
  - ".gitignore"
50
51
  - Gemfile
51
52
  - LICENSE.txt
52
53
  - README.md
53
54
  - Rakefile
54
- - bin/console
55
- - bin/setup
56
55
  - lib/net/ftp.rb
57
56
  - net-ftp.gemspec
58
57
  homepage: https://github.com/ruby/net-ftp
@@ -70,14 +69,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
70
69
  requirements:
71
70
  - - ">="
72
71
  - !ruby/object:Gem::Version
73
- version: 2.3.0
72
+ version: 2.6.0
74
73
  required_rubygems_version: !ruby/object:Gem::Requirement
75
74
  requirements:
76
75
  - - ">="
77
76
  - !ruby/object:Gem::Version
78
77
  version: '0'
79
78
  requirements: []
80
- rubygems_version: 3.3.0.dev
79
+ rubygems_version: 3.4.0.dev
81
80
  signing_key:
82
81
  specification_version: 4
83
82
  summary: Support for the File Transfer Protocol.
data/bin/console DELETED
@@ -1,14 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "bundler/setup"
4
- require "net/ftp"
5
-
6
- # You can add fixtures and/or initialization code here to make experimenting
7
- # with your gem easier. You can also use a different console, if you like.
8
-
9
- # (If you use this, don't forget to add pry to your Gemfile!)
10
- # require "pry"
11
- # Pry.start
12
-
13
- require "irb"
14
- IRB.start(__FILE__)
data/bin/setup DELETED
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
5
-
6
- bundle install
7
-
8
- # Do any other automated setup that you need to do here