net-ftp 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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