net-ftp 0.1.3 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +6 -0
- data/.github/workflows/test.yml +2 -2
- data/lib/net/ftp.rb +44 -47
- data/net-ftp.gemspec +2 -4
- metadata +6 -7
- data/bin/console +0 -14
- data/bin/setup +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6da1dd16a259cb0b9da3833be6087725451c66020a77484962ce512ebe76bd86
|
4
|
+
data.tar.gz: 5baf86565938970ff01dca9f6c85d8ae5afa57493ca96c35e8ccb30184f8fd96
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b634e82e54a09c1ad7174bafa5049f77f4878c5bf8b5d9fe4f43626c75d83831b91968a211075f5e36c7514c29d7dd2f8834134dc08f4f63def4b6e5a266b991
|
7
|
+
data.tar.gz: 4b124cb421ad550f889fd5dce46efb22cb726516a1e245131a4d0c5c125c0eb229b8041e952df0c85abed0a8e82697ea3116ef7c1eae1db7ebd09f45ea854355
|
data/.github/workflows/test.yml
CHANGED
@@ -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
|
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@
|
14
|
+
- uses: actions/checkout@v4
|
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.
|
88
|
+
VERSION = "0.3.0"
|
89
89
|
FTP_PORT = 21
|
90
90
|
CRLF = "\r\n"
|
91
91
|
DEFAULT_BLOCKSIZE = BufferedIO::BUFSIZE
|
@@ -106,6 +106,11 @@ module Net
|
|
106
106
|
# to +$stdout+. Default: +false+.
|
107
107
|
attr_accessor :debug_mode
|
108
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
|
+
|
109
114
|
# Sets or retrieves the +resume+ status, which decides whether incomplete
|
110
115
|
# transfers are resumed or restarted. Default: +false+.
|
111
116
|
attr_accessor :resume
|
@@ -195,6 +200,8 @@ module Net
|
|
195
200
|
# as parameters.
|
196
201
|
# private_data_connection:: If true, TLS is used for data connections.
|
197
202
|
# Default: +true+ when +options+[:ssl] is true.
|
203
|
+
# implicit_ftps:: If true, TLS is established on initial connection.
|
204
|
+
# Default: +false+
|
198
205
|
# username:: Username for login. If +options+[:username] is the string
|
199
206
|
# "anonymous" and the +options+[:password] is +nil+,
|
200
207
|
# "anonymous@" is used as a password.
|
@@ -248,6 +255,11 @@ module Net
|
|
248
255
|
else
|
249
256
|
@private_data_connection = options[:private_data_connection]
|
250
257
|
end
|
258
|
+
if options[:implicit_ftps].nil?
|
259
|
+
@implicit_ftps = false
|
260
|
+
else
|
261
|
+
@implicit_ftps = options[:implicit_ftps]
|
262
|
+
end
|
251
263
|
else
|
252
264
|
@ssl_context = nil
|
253
265
|
if options[:private_data_connection]
|
@@ -255,6 +267,11 @@ module Net
|
|
255
267
|
"private_data_connection can be set to true only when ssl is enabled"
|
256
268
|
end
|
257
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
|
258
275
|
end
|
259
276
|
@binary = true
|
260
277
|
if options[:passive].nil?
|
@@ -267,6 +284,7 @@ module Net
|
|
267
284
|
else
|
268
285
|
@debug_mode = options[:debug_mode]
|
269
286
|
end
|
287
|
+
@debug_output = $stdout
|
270
288
|
@resume = false
|
271
289
|
@bare_sock = @sock = NullSocket.new
|
272
290
|
@logged_in = false
|
@@ -338,19 +356,14 @@ module Net
|
|
338
356
|
# SOCKS_SERVER, then a SOCKSSocket is returned, else a Socket is
|
339
357
|
# returned.
|
340
358
|
def open_socket(host, port) # :nodoc:
|
341
|
-
|
342
|
-
|
343
|
-
|
359
|
+
return Timeout.timeout(@open_timeout, OpenTimeout) {
|
360
|
+
if defined? SOCKSSocket and ENV["SOCKS_SERVER"]
|
361
|
+
@passive = true
|
344
362
|
SOCKSSocket.open(host, port)
|
363
|
+
else
|
364
|
+
Socket.tcp(host, port)
|
345
365
|
end
|
346
|
-
|
347
|
-
begin
|
348
|
-
Socket.tcp host, port, nil, nil, connect_timeout: @open_timeout
|
349
|
-
rescue Errno::ETIMEDOUT #raise Net:OpenTimeout instead for compatibility with previous versions
|
350
|
-
raise Net::OpenTimeout, "Timeout to open TCP connection to "\
|
351
|
-
"#{host}:#{port} (exceeds #{@open_timeout} seconds)"
|
352
|
-
end
|
353
|
-
end
|
366
|
+
}
|
354
367
|
end
|
355
368
|
private :open_socket
|
356
369
|
|
@@ -378,19 +391,17 @@ module Net
|
|
378
391
|
# <tt>Errno::ECONNREFUSED</tt>) if the connection cannot be established.
|
379
392
|
#
|
380
393
|
def connect(host, port = FTP_PORT)
|
381
|
-
|
382
|
-
print "connect: ", host, ", ", port, "\n"
|
383
|
-
end
|
394
|
+
debug_print "connect: #{host}:#{port}"
|
384
395
|
synchronize do
|
385
396
|
@host = host
|
386
397
|
@bare_sock = open_socket(host, port)
|
387
|
-
@sock = BufferedSocket.new(@bare_sock, read_timeout: @read_timeout)
|
388
|
-
voidresp
|
389
398
|
if @ssl_context
|
390
399
|
begin
|
391
|
-
|
392
|
-
|
393
|
-
|
400
|
+
unless @implicit_ftps
|
401
|
+
set_socket(BufferedSocket.new(@bare_sock, read_timeout: @read_timeout))
|
402
|
+
voidcmd("AUTH TLS")
|
403
|
+
end
|
404
|
+
set_socket(BufferedSSLSocket.new(start_tls_session(@bare_sock), read_timeout: @read_timeout), @implicit_ftps)
|
394
405
|
if @private_data_connection
|
395
406
|
voidcmd("PBSZ 0")
|
396
407
|
voidcmd("PROT P")
|
@@ -399,6 +410,8 @@ module Net
|
|
399
410
|
@sock.close
|
400
411
|
raise
|
401
412
|
end
|
413
|
+
else
|
414
|
+
set_socket(BufferedSocket.new(@bare_sock, read_timeout: @read_timeout))
|
402
415
|
end
|
403
416
|
end
|
404
417
|
end
|
@@ -430,9 +443,7 @@ module Net
|
|
430
443
|
# Ensures that +line+ has a control return / line feed (CRLF) and writes
|
431
444
|
# it to the socket.
|
432
445
|
def putline(line) # :nodoc:
|
433
|
-
|
434
|
-
print "put: ", sanitize(line), "\n"
|
435
|
-
end
|
446
|
+
debug_print "put: #{sanitize(line)}"
|
436
447
|
if /[\r\n]/ =~ line
|
437
448
|
raise ArgumentError, "A line must not contain CR or LF"
|
438
449
|
end
|
@@ -445,9 +456,7 @@ module Net
|
|
445
456
|
def getline # :nodoc:
|
446
457
|
line = @sock.readline # if get EOF, raise EOFError
|
447
458
|
line.sub!(/(\r\n|\n|\r)\z/n, "")
|
448
|
-
|
449
|
-
print "get: ", sanitize(line), "\n"
|
450
|
-
end
|
459
|
+
debug_print "get: #{sanitize(line)}"
|
451
460
|
return line
|
452
461
|
end
|
453
462
|
private :getline
|
@@ -545,7 +554,6 @@ module Net
|
|
545
554
|
host, port = parse227(sendcmd("PASV"))
|
546
555
|
else
|
547
556
|
host, port = parse229(sendcmd("EPSV"))
|
548
|
-
# host, port = parse228(sendcmd("LPSV"))
|
549
557
|
end
|
550
558
|
return host, port
|
551
559
|
end
|
@@ -1248,7 +1256,7 @@ module Net
|
|
1248
1256
|
#
|
1249
1257
|
def abort
|
1250
1258
|
line = "ABOR" + CRLF
|
1251
|
-
|
1259
|
+
debug_print "put: ABOR"
|
1252
1260
|
@sock.send(line, Socket::MSG_OOB)
|
1253
1261
|
resp = getmultiline
|
1254
1262
|
unless ["426", "226", "225"].include?(resp[0, 3])
|
@@ -1268,7 +1276,7 @@ module Net
|
|
1268
1276
|
if /[\r\n]/ =~ line
|
1269
1277
|
raise ArgumentError, "A line must not contain CR or LF"
|
1270
1278
|
end
|
1271
|
-
|
1279
|
+
debug_print "put: #{line}"
|
1272
1280
|
@sock.send(line + CRLF, Socket::MSG_OOB)
|
1273
1281
|
return getresp
|
1274
1282
|
end
|
@@ -1401,24 +1409,6 @@ module Net
|
|
1401
1409
|
end
|
1402
1410
|
private :parse227
|
1403
1411
|
|
1404
|
-
# handler for response code 228
|
1405
|
-
# (Entering Long Passive Mode)
|
1406
|
-
#
|
1407
|
-
# Returns host and port.
|
1408
|
-
def parse228(resp) # :nodoc:
|
1409
|
-
if !resp.start_with?("228")
|
1410
|
-
raise FTPReplyError, resp
|
1411
|
-
end
|
1412
|
-
if m = /\(4,4,(?<host>\d+(?:,\d+){3}),2,(?<port>\d+,\d+)\)/.match(resp)
|
1413
|
-
return parse_pasv_ipv4_host(m["host"]), parse_pasv_port(m["port"])
|
1414
|
-
elsif m = /\(6,16,(?<host>\d+(?:,\d+){15}),2,(?<port>\d+,\d+)\)/.match(resp)
|
1415
|
-
return parse_pasv_ipv6_host(m["host"]), parse_pasv_port(m["port"])
|
1416
|
-
else
|
1417
|
-
raise FTPProtoError, resp
|
1418
|
-
end
|
1419
|
-
end
|
1420
|
-
private :parse228
|
1421
|
-
|
1422
1412
|
def parse_pasv_ipv4_host(s)
|
1423
1413
|
return s.tr(",", ".")
|
1424
1414
|
end
|
@@ -1466,6 +1456,13 @@ module Net
|
|
1466
1456
|
end
|
1467
1457
|
private :parse257
|
1468
1458
|
|
1459
|
+
#
|
1460
|
+
# Writes debug message to the debug output stream
|
1461
|
+
#
|
1462
|
+
def debug_print(msg)
|
1463
|
+
@debug_output << msg + "\n" if @debug_mode && @debug_output
|
1464
|
+
end
|
1465
|
+
|
1469
1466
|
# :stopdoc:
|
1470
1467
|
class NullSocket
|
1471
1468
|
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.
|
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.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shugo Maeda
|
8
8
|
autorequire:
|
9
|
-
bindir:
|
9
|
+
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-12-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.
|
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.
|
79
|
+
rubygems_version: 3.5.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__)
|