fastdfs-client 1.3.0 → 1.4.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 +4 -4
- data/README.md +12 -9
- data/lib/fastdfs-client.rb +2 -1
- data/lib/fastdfs-client/client_proxy.rb +6 -4
- data/lib/fastdfs-client/cmd.rb +10 -0
- data/lib/fastdfs-client/extend_core.rb +5 -2
- data/lib/fastdfs-client/proto_common.rb +1 -1
- data/lib/fastdfs-client/socket.rb +4 -5
- data/lib/fastdfs-client/storage.rb +30 -20
- data/lib/fastdfs-client/tracker.rb +3 -3
- data/lib/fastdfs-client/utils.rb +0 -4
- data/lib/fastdfs-client/version.rb +1 -1
- data/spec/mock_tcp_socket.rb +25 -4
- data/spec/spec_helper.rb +1 -0
- data/spec/storage_spec.rb +18 -6
- data/spec/test_config.rb +1 -1
- data/spec/tracker_spec.rb +1 -1
- data/spec/upload.rb +59 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a8009a29d5b18921a4b3d9f628a9f7eaea019635
|
4
|
+
data.tar.gz: ac88fd2d1e51070637b34496619e750ccda97d57
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 445d9a50ccb21df204e0210cb968610831e137352d94a2c2fc62504c48864af9ef28190f1552b0e38476d91a6621925d7361706616361c9e2da638874c21ea01
|
7
|
+
data.tar.gz: 928522790ed79785a931dd0ac000c5ee977f6f5329a5ff74102522a5da3a26ab3daf9271835fe41867deba809380867445e8b136e554d6cc267885b10305046e
|
data/README.md
CHANGED
@@ -21,18 +21,21 @@ fastdfs client for ruby
|
|
21
21
|
|
22
22
|
@storage = tracker.get_storage
|
23
23
|
|
24
|
-
@storage.
|
25
|
-
#result: {group_name: "group1", path: "m1/xfsd/fds.jpg"}
|
24
|
+
if @storage.is_a?(Fastdfs::Client::Storage)
|
26
25
|
|
27
|
-
|
26
|
+
@storage.upload(@file)
|
27
|
+
#result: {group_name: "group1", path: "m1/xfsd/fds.jpg"}
|
28
28
|
|
29
|
-
|
30
|
-
@storage.set_metadata(path, group_name, {author: "kaka", width: "300"}, flag)
|
29
|
+
@storage.delete(path, group_name)
|
31
30
|
|
32
|
-
|
33
|
-
|
31
|
+
# flag params [cover, merge]
|
32
|
+
@storage.set_metadata(path, group_name, {author: "kaka", width: "300"}, flag)
|
34
33
|
|
35
|
-
|
36
|
-
|
34
|
+
@storage.get_metadata(path, group_name)
|
35
|
+
#result: {author: "kaka", width: "300"}
|
36
|
+
|
37
|
+
@storage.download(path, group_name)
|
38
|
+
#result: #<Tempfile:/var/folders/m7/bt2j0rk54x555t44dpn4b7bm0000gn/T/test.jpg20160416-43738-1560vq3>
|
39
|
+
end
|
37
40
|
|
38
41
|
```
|
data/lib/fastdfs-client.rb
CHANGED
@@ -17,12 +17,14 @@ module Fastdfs
|
|
17
17
|
@socket = Socket.new(host, port, options[:socket])
|
18
18
|
end
|
19
19
|
|
20
|
-
def dispose(cmd,
|
20
|
+
def dispose(cmd, header = [], content = [], &block)
|
21
21
|
synchronize do
|
22
|
-
@socket.connection do
|
23
|
-
|
22
|
+
@socket.connection do
|
23
|
+
contents = Array(content)
|
24
|
+
body_len = contents.map{|c| c.bytes.size }.inject(header.length){|sum, x| sum + x }
|
25
|
+
full_header = ProtoCommon.header_bytes(cmd, body_len).concat(header)
|
24
26
|
@socket.write(cmd, full_header)
|
25
|
-
|
27
|
+
contents.each do |c|
|
26
28
|
@socket.write(cmd, c)
|
27
29
|
end
|
28
30
|
@socket.receive &block
|
data/lib/fastdfs-client/cmd.rb
CHANGED
@@ -9,6 +9,16 @@ module Fastdfs
|
|
9
9
|
GET_METADATA = 15
|
10
10
|
SET_METADATA = 13
|
11
11
|
DOWNLOAD_FILE = 14
|
12
|
+
|
13
|
+
MAPPING_NAME = {
|
14
|
+
101 => "GET STORAGE",
|
15
|
+
11 => "UPLOAD FILE",
|
16
|
+
101 => "RESP CODE",
|
17
|
+
12 => "DELETE FILE",
|
18
|
+
15 => "GET METADATA",
|
19
|
+
13 => "SET METADATA",
|
20
|
+
14 => "DOWNLOAD FILE"
|
21
|
+
}
|
12
22
|
end
|
13
23
|
|
14
24
|
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
class Array
|
3
2
|
def to_pack_long
|
4
3
|
self.each_with_index.inject(0){|s, item| s = s | (item[0] << (56 - (item[1] * 8))); s }
|
@@ -9,7 +8,6 @@ class Array
|
|
9
8
|
end
|
10
9
|
end
|
11
10
|
|
12
|
-
|
13
11
|
class NilClass
|
14
12
|
def blank?
|
15
13
|
true
|
@@ -28,6 +26,11 @@ class Object
|
|
28
26
|
end
|
29
27
|
end
|
30
28
|
|
29
|
+
class Integer
|
30
|
+
def to_eight_buffer
|
31
|
+
8.times.map{|i| (self >> (56 - 8 * i)) & 255}
|
32
|
+
end
|
33
|
+
end
|
31
34
|
|
32
35
|
class Hash
|
33
36
|
|
@@ -20,7 +20,7 @@ module Fastdfs
|
|
20
20
|
SET_METADATA_FLAG_MERGE = "M"
|
21
21
|
|
22
22
|
def self.header_bytes(cmd, hex_long, erron=0)
|
23
|
-
hex_bytes =
|
23
|
+
hex_bytes = hex_long.to_eight_buffer
|
24
24
|
header = hex_bytes.fill(0, hex_bytes.length...HEAD_LEN)
|
25
25
|
header[8] = cmd
|
26
26
|
header[9] = erron
|
@@ -7,7 +7,7 @@ module Fastdfs
|
|
7
7
|
module Client
|
8
8
|
|
9
9
|
class Socket
|
10
|
-
attr_accessor :
|
10
|
+
attr_accessor :socket, :host, :port
|
11
11
|
|
12
12
|
def initialize(host, port, options = {})
|
13
13
|
@host, @port = host, port
|
@@ -19,7 +19,6 @@ module Fastdfs
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def write(*args)
|
22
|
-
debugger if args[1] == 119
|
23
22
|
@cmd = args.shift
|
24
23
|
pkg = args.shift
|
25
24
|
|
@@ -60,9 +59,9 @@ module Fastdfs
|
|
60
59
|
private
|
61
60
|
def parseHeader
|
62
61
|
err_msg = nil
|
63
|
-
err_msg = "recv package size #{@header} is not equal #{@header_len}, cmd: #{@cmd}" unless @header.length == @header_len || err_msg
|
64
|
-
err_msg = "recv cmd: #{@header[8]} is not correct, expect recv code: #{CMD::RESP_CODE}, cmd: #{@cmd}" unless @header[8] == CMD::RESP_CODE || err_msg
|
65
|
-
err_msg = "recv erron #{@header[9]}, 0 is correct cmd: #{@cmd}" unless @header[9] == 0 || err_msg
|
62
|
+
err_msg = "recv package size #{@header} is not equal #{@header_len}, cmd: #{CMD::MAPPING_NAME[@cmd]}" unless @header.length == @header_len || err_msg
|
63
|
+
err_msg = "recv cmd: #{@header[8]} is not correct, expect recv code: #{CMD::RESP_CODE}, cmd: #{CMD::MAPPING_NAME[@cmd]}" unless @header[8] == CMD::RESP_CODE || err_msg
|
64
|
+
err_msg = "recv erron #{@header[9]}, 0 is correct cmd: #{CMD::MAPPING_NAME[@cmd]}" unless @header[9] == 0 || err_msg
|
66
65
|
{status: err_msg.nil?, err_msg: err_msg}
|
67
66
|
end
|
68
67
|
|
@@ -4,7 +4,7 @@ module Fastdfs
|
|
4
4
|
module Client
|
5
5
|
|
6
6
|
class Storage
|
7
|
-
attr_accessor :
|
7
|
+
attr_accessor :proxy, :options, :socket, :store_path
|
8
8
|
|
9
9
|
def initialize(host, port, store_path = nil, options = {})
|
10
10
|
@options = options || {}
|
@@ -12,17 +12,15 @@ module Fastdfs
|
|
12
12
|
|
13
13
|
@proxy = ClientProxy.new(host, port, @options[:socket])
|
14
14
|
@socket = @proxy.socket
|
15
|
-
@extname_len = ProtoCommon::EXTNAME_LEN
|
16
|
-
@size_len = ProtoCommon::SIZE_LEN
|
17
15
|
@store_path = store_path || 0
|
18
16
|
end
|
19
17
|
|
20
|
-
def upload(
|
21
|
-
|
22
|
-
size_byte =
|
23
|
-
content_len =
|
18
|
+
def upload(_file, options = {})
|
19
|
+
file, ext_name_bytes = convert_file_info(_file)
|
20
|
+
size_byte = [@store_path].concat(file.size.to_eight_buffer).full_fill(0, file_size_len)
|
21
|
+
content_len = file_size_len + extname_len + file.size
|
24
22
|
|
25
|
-
@proxy.dispose(CMD::UPLOAD_FILE,
|
23
|
+
@proxy.dispose(CMD::UPLOAD_FILE, size_byte + ext_name_bytes, IO.read(file)) do |body|
|
26
24
|
group_name_max_len = ProtoCommon::GROUP_NAME_MAX_LEN
|
27
25
|
|
28
26
|
res = {group_name: body[0...group_name_max_len].strip, path: body[group_name_max_len..-1]}
|
@@ -32,13 +30,13 @@ module Fastdfs
|
|
32
30
|
end
|
33
31
|
|
34
32
|
def delete(path, group_name = nil)
|
35
|
-
|
36
|
-
@proxy.dispose(CMD::DELETE_FILE,
|
33
|
+
header_bytes = group_path_bytes(path, group_name).flatten
|
34
|
+
@proxy.dispose(CMD::DELETE_FILE, header_bytes)
|
37
35
|
end
|
38
36
|
|
39
37
|
def get_metadata(path, group_name = nil)
|
40
|
-
|
41
|
-
@proxy.dispose(CMD::GET_METADATA,
|
38
|
+
header_bytes = group_path_bytes(path, group_name).flatten
|
39
|
+
@proxy.dispose(CMD::GET_METADATA, header_bytes) do |body|
|
42
40
|
res = body.split(ProtoCommon::RECORD_SEPERATOR).map do |c|
|
43
41
|
c.split(ProtoCommon::FILE_SEPERATOR)
|
44
42
|
end.flatten
|
@@ -54,9 +52,8 @@ module Fastdfs
|
|
54
52
|
|
55
53
|
def download(path, group_name = nil)
|
56
54
|
path_bytes = group_path_bytes(path, group_name).flatten
|
57
|
-
|
58
|
-
|
59
|
-
@proxy.dispose(CMD::DOWNLOAD_FILE, data.length, data) do |body|
|
55
|
+
header_bytes = 0.to_eight_buffer.concat(0.to_eight_buffer).concat(path_bytes)
|
56
|
+
@proxy.dispose(CMD::DOWNLOAD_FILE, header_bytes) do |body|
|
60
57
|
create_tempfile(path, body) if body
|
61
58
|
end
|
62
59
|
end
|
@@ -87,10 +84,9 @@ module Fastdfs
|
|
87
84
|
group_bytes, path_bytes = group_path_bytes(path, group_name)
|
88
85
|
meta_bytes = meta_to_bytes(options)
|
89
86
|
|
90
|
-
size_bytes =
|
91
|
-
|
92
|
-
|
93
|
-
@proxy.dispose(CMD::SET_METADATA, total, (size_bytes + flag.bytes + group_bytes + path_bytes), meta_bytes.pack("C*"))
|
87
|
+
size_bytes = path_bytes.length.to_eight_buffer.concat(meta_bytes.length.to_eight_buffer).full_fill(0, 16)
|
88
|
+
# total = size_bytes.length + flag.length + group_bytes.length + path_bytes.length + meta_bytes.length
|
89
|
+
@proxy.dispose(CMD::SET_METADATA, (size_bytes + flag.bytes + group_bytes + path_bytes), meta_bytes.pack("C*"))
|
94
90
|
end
|
95
91
|
|
96
92
|
def convert_meta_flag(flag)
|
@@ -117,7 +113,21 @@ module Fastdfs
|
|
117
113
|
tmp.close
|
118
114
|
tmp
|
119
115
|
end
|
120
|
-
|
116
|
+
|
117
|
+
def extname_len; ProtoCommon::EXTNAME_LEN end;
|
118
|
+
def file_size_len; ProtoCommon::SIZE_LEN end;
|
119
|
+
|
120
|
+
def convert_file_info(file)
|
121
|
+
if file.class.name == "ActionDispatch::Http::UploadedFile"
|
122
|
+
return file.tempfile, convert_extname_bytes(file.original_filename)
|
123
|
+
else
|
124
|
+
return file, convert_extname_bytes(file.path)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def convert_extname_bytes(file_name)
|
129
|
+
File.extname(file_name)[1..extname_len].to_s.bytes.full_fill(0, extname_len)
|
130
|
+
end
|
121
131
|
end
|
122
132
|
|
123
133
|
end
|
@@ -4,8 +4,8 @@ module Fastdfs
|
|
4
4
|
module Client
|
5
5
|
|
6
6
|
class Tracker
|
7
|
-
|
8
|
-
attr_accessor :
|
7
|
+
|
8
|
+
attr_accessor :options, :socket
|
9
9
|
|
10
10
|
def initialize(host, port, options = {})
|
11
11
|
@options = options
|
@@ -15,7 +15,7 @@ module Fastdfs
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def get_storage
|
18
|
-
res = @proxy.dispose(@cmd
|
18
|
+
res = @proxy.dispose(@cmd) do |body|
|
19
19
|
storage_ip = body[ProtoCommon::IPADDR].strip
|
20
20
|
storage_port = body[ProtoCommon::PORT].unpack("C*").to_pack_long
|
21
21
|
store_path = body[ProtoCommon::TRACKER_BODY_LEN-1].unpack("C*")[0]
|
data/lib/fastdfs-client/utils.rb
CHANGED
@@ -1,9 +1,5 @@
|
|
1
1
|
module Utils
|
2
2
|
|
3
|
-
def self.number_to_buffer(num)
|
4
|
-
8.times.map{|i| (num >> (56 - 8 * i)) & 255}
|
5
|
-
end
|
6
|
-
|
7
3
|
def self.array_merge(arr1, arr2)
|
8
4
|
raise "argument must be array" unless arr1.is_a?(Array) || arr2.is_a?(Array)
|
9
5
|
arr2.each_with_index.map{|v, i| arr1[i] = v }
|
data/spec/mock_tcp_socket.rb
CHANGED
@@ -10,16 +10,28 @@ class MockTCPSocket
|
|
10
10
|
@recv_offset = 0
|
11
11
|
@connect_state = true
|
12
12
|
@cmd = nil
|
13
|
+
@content = []
|
14
|
+
@header = []
|
15
|
+
end
|
16
|
+
|
17
|
+
def connection
|
18
|
+
@content = []
|
19
|
+
@header = []
|
13
20
|
end
|
14
21
|
|
15
22
|
def write(*args)
|
16
23
|
pkg = args[0].unpack("C*")
|
24
|
+
if @header.length <= 0
|
25
|
+
@header = pkg
|
26
|
+
else
|
27
|
+
@content.concat(pkg)
|
28
|
+
end
|
17
29
|
@cmd ||= pkg[8]
|
18
30
|
sleep(rand(0..4))
|
19
31
|
end
|
20
32
|
|
21
33
|
def recv(len)
|
22
|
-
sleep(rand(0..
|
34
|
+
sleep(rand(0..2))
|
23
35
|
data = case @cmd
|
24
36
|
when 101
|
25
37
|
gate_tracker(len)
|
@@ -55,7 +67,7 @@ class MockTCPSocket
|
|
55
67
|
|
56
68
|
group_name = Utils.array_merge([].fill(0, 0...16), TestConfig::GROUP_NAME.bytes)
|
57
69
|
ip = Utils.array_merge([].fill(0, 0...15), TestConfig::STORAGE_IP.bytes)
|
58
|
-
port =
|
70
|
+
port = TestConfig::STORAGE_PORT.to_i.to_eight_buffer
|
59
71
|
store_path = Array(TestConfig::STORE_PATH)
|
60
72
|
|
61
73
|
(header+group_name+ip+port+store_path)[@recv_offset...@recv_offset+len].pack("C*")
|
@@ -64,8 +76,9 @@ class MockTCPSocket
|
|
64
76
|
def upload_file(len)
|
65
77
|
header = ProtoCommon.header_bytes(CMD::RESP_CODE, 0)
|
66
78
|
group_name = Utils.array_merge([].fill(0, 0...16), TestConfig::GROUP_NAME.bytes)
|
67
|
-
|
68
|
-
|
79
|
+
path = path_replace_extname
|
80
|
+
file_path_bytes = path.bytes
|
81
|
+
res = (group_name + file_path_bytes)
|
69
82
|
header[7] = (header + res).length
|
70
83
|
res = (header + res)
|
71
84
|
|
@@ -95,4 +108,12 @@ class MockTCPSocket
|
|
95
108
|
header[7] = body.length
|
96
109
|
(header + body)[@recv_offset...@recv_offset+len].pack("C*")
|
97
110
|
end
|
111
|
+
|
112
|
+
private
|
113
|
+
def path_replace_extname
|
114
|
+
path = TestConfig::FILE_PATH
|
115
|
+
extname = File.extname(path)
|
116
|
+
path.gsub!(extname, ".#{@header[19..-1].reject{|i| i.zero? }.pack('C*')}")
|
117
|
+
path
|
118
|
+
end
|
98
119
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -2,6 +2,7 @@ require 'debugger'
|
|
2
2
|
require 'rspec'
|
3
3
|
require 'rspec/core'
|
4
4
|
require 'rspec/mocks'
|
5
|
+
require 'upload'
|
5
6
|
require File.expand_path('../../lib/fastdfs-client', __FILE__)
|
6
7
|
require File.expand_path('../test_config', __FILE__)
|
7
8
|
require File.expand_path('../mock_tcp_socket', __FILE__)
|
data/spec/storage_spec.rb
CHANGED
@@ -7,6 +7,12 @@ describe Fastdfs::Client::Storage do
|
|
7
7
|
|
8
8
|
let(:tracker){ FC::Tracker.new(host, port) }
|
9
9
|
let(:storage){ tracker.get_storage }
|
10
|
+
let(:tempfile) do
|
11
|
+
file = Tempfile.new([nil, "1.txt"])
|
12
|
+
file.write("testtest")
|
13
|
+
file.close
|
14
|
+
file
|
15
|
+
end
|
10
16
|
|
11
17
|
it "initialize the server" do
|
12
18
|
expect(FC::Socket).to receive(:new).with(host, port, nil)
|
@@ -26,10 +32,16 @@ describe Fastdfs::Client::Storage do
|
|
26
32
|
end
|
27
33
|
|
28
34
|
it "tempfile upload " do
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
35
|
+
res = storage.upload(tempfile)
|
36
|
+
expect(res[:status]).to be_truthy
|
37
|
+
expect(File.extname(res[:result][:path])).to eq(".txt")
|
38
|
+
end
|
39
|
+
|
40
|
+
it "ActionDispatch::Http::UploadedFile upload" do
|
41
|
+
file = ActionDispatch::Http::UploadedFile.new(tempfile: tempfile, filename: "test.tt")
|
42
|
+
res = storage.upload(file)
|
43
|
+
expect(res[:status]).to be_truthy
|
44
|
+
expect(File.extname(res[:result][:path])).to eq(".tt")
|
33
45
|
end
|
34
46
|
|
35
47
|
describe "upload file test " do
|
@@ -64,11 +76,11 @@ describe Fastdfs::Client::Storage do
|
|
64
76
|
end
|
65
77
|
|
66
78
|
it "can set metadata" do
|
67
|
-
expect(storage.set_metadata(TestConfig::
|
79
|
+
expect(storage.set_metadata(TestConfig::FILE_PATH, TestConfig::GROUP_NAME, TestConfig::METADATA)).to be_truthy
|
68
80
|
end
|
69
81
|
|
70
82
|
it "download the file to the local" do
|
71
|
-
res = storage.download(TestConfig::
|
83
|
+
res = storage.download(TestConfig::FILE_PATH, TestConfig::GROUP_NAME)
|
72
84
|
expect(res[:status]).to be_truthy
|
73
85
|
expect(res[:result]).to be_an_instance_of(Tempfile)
|
74
86
|
expect(IO.read(res[:result])).to eq(IO.read(TestConfig::FILE))
|
data/spec/test_config.rb
CHANGED
data/spec/tracker_spec.rb
CHANGED
@@ -43,7 +43,7 @@ describe Fastdfs::Client::Tracker do
|
|
43
43
|
res = storage.upload(File.open(File.expand_path("../page.png", __FILE__)))
|
44
44
|
expect(res[:status]).to be_truthy
|
45
45
|
results = res[:result]
|
46
|
-
|
46
|
+
res = storage.delete(results[:path], results[:group_name])
|
47
47
|
expect(res[:status]).to be_truthy
|
48
48
|
end
|
49
49
|
end
|
data/spec/upload.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
module ActionDispatch
|
2
|
+
module Http
|
3
|
+
|
4
|
+
class UploadedFile
|
5
|
+
attr_accessor :original_filename
|
6
|
+
|
7
|
+
attr_accessor :content_type
|
8
|
+
|
9
|
+
attr_accessor :tempfile
|
10
|
+
alias :to_io :tempfile
|
11
|
+
|
12
|
+
attr_accessor :headers
|
13
|
+
|
14
|
+
def initialize(hash)
|
15
|
+
@tempfile = hash[:tempfile]
|
16
|
+
raise(ArgumentError, ":tempfile is required") unless @tempfile
|
17
|
+
|
18
|
+
@original_filename = hash[:filename]
|
19
|
+
if @original_filename
|
20
|
+
begin
|
21
|
+
@original_filename.encode!(Encoding::UTF_8)
|
22
|
+
rescue EncodingError
|
23
|
+
@original_filename.force_encoding(Encoding::UTF_8)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
@content_type = hash[:type]
|
27
|
+
@headers = hash[:head]
|
28
|
+
end
|
29
|
+
|
30
|
+
def read(length=nil, buffer=nil)
|
31
|
+
@tempfile.read(length, buffer)
|
32
|
+
end
|
33
|
+
|
34
|
+
def open
|
35
|
+
@tempfile.open
|
36
|
+
end
|
37
|
+
|
38
|
+
def close(unlink_now=false)
|
39
|
+
@tempfile.close(unlink_now)
|
40
|
+
end
|
41
|
+
|
42
|
+
def path
|
43
|
+
@tempfile.path
|
44
|
+
end
|
45
|
+
|
46
|
+
def rewind
|
47
|
+
@tempfile.rewind
|
48
|
+
end
|
49
|
+
|
50
|
+
def size
|
51
|
+
@tempfile.size
|
52
|
+
end
|
53
|
+
|
54
|
+
def eof?
|
55
|
+
@tempfile.eof?
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fastdfs-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ka Ka
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-10-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -81,6 +81,7 @@ files:
|
|
81
81
|
- spec/storage_spec.rb
|
82
82
|
- spec/test_config.rb
|
83
83
|
- spec/tracker_spec.rb
|
84
|
+
- spec/upload.rb
|
84
85
|
homepage: https://github.com/huxinghai1988/fastdfs-client-ruby.git
|
85
86
|
licenses:
|
86
87
|
- MIT
|
@@ -113,4 +114,5 @@ test_files:
|
|
113
114
|
- spec/storage_spec.rb
|
114
115
|
- spec/test_config.rb
|
115
116
|
- spec/tracker_spec.rb
|
117
|
+
- spec/upload.rb
|
116
118
|
has_rdoc:
|