fastdfs-client 1.0.0 → 1.0.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
- data/.gitignore +2 -1
- data/Gemfile +1 -6
- data/README.md +1 -1
- data/fastdfs-client.gemspec +3 -0
- data/lib/fastdfs-client/extend_core.rb +0 -7
- data/lib/fastdfs-client/socket.rb +10 -10
- data/lib/fastdfs-client/storage.rb +5 -6
- data/lib/fastdfs-client/tracker.rb +3 -2
- data/lib/fastdfs-client/utils.rb +4 -0
- data/lib/fastdfs-client/version.rb +1 -1
- data/spec/mock_tcp_socket.rb +58 -57
- data/spec/spec_helper.rb +6 -0
- data/spec/storage_spec.rb +1 -2
- data/spec/tracker_spec.rb +11 -0
- metadata +30 -3
- data/Gemfile.lock +0 -38
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b7c9c31e2cc224ba06f1ed3645106403401593f9
|
4
|
+
data.tar.gz: d6d383e70e70bc1ae9a4e89319728d2d2f631253
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6f7622606be3975880698f78691a4bd1fd61306fd0cf7495069199e6140810e8d95b5522aae45c153021b67dc8aa7bfcfb335d435adb74f27026e6cf7c800846
|
7
|
+
data.tar.gz: ae1834faa05d1e4c81faeefa1849fea0a8ca44909bf7ce44e10d1e331bf1a437314f56ba825e680aa8a36de1459b42f6a9e067f871eeec5d20a59cdf15e9fdfb
|
data/.gitignore
CHANGED
@@ -1 +1,2 @@
|
|
1
|
-
*.gem
|
1
|
+
*.gem
|
2
|
+
Gemfile.lock
|
data/Gemfile
CHANGED
data/README.md
CHANGED
data/fastdfs-client.gemspec
CHANGED
@@ -31,8 +31,8 @@ module Fastdfs
|
|
31
31
|
|
32
32
|
def connection
|
33
33
|
if @socket.nil? || !connected
|
34
|
-
Timeout.timeout(@connection_timeout) do
|
35
|
-
|
34
|
+
@socket = Timeout.timeout(@connection_timeout) do
|
35
|
+
TCPSocket.new(@host, @port)
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end
|
@@ -42,8 +42,8 @@ module Fastdfs
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def receive(&block)
|
45
|
-
timeout_recv do
|
46
|
-
@
|
45
|
+
@header = timeout_recv do
|
46
|
+
@socket.recv(@header_len).unpack("C*")
|
47
47
|
end
|
48
48
|
res_header = parseHeader
|
49
49
|
if res_header[:status]
|
@@ -56,11 +56,11 @@ module Fastdfs
|
|
56
56
|
|
57
57
|
private
|
58
58
|
def parseHeader
|
59
|
-
err_msg =
|
60
|
-
err_msg = "recv package size #{@header} is not equal #{@header_len}, cmd: #{@cmd}" unless @header.length == @header_len
|
61
|
-
err_msg = "recv cmd: #{@header[8]} is not correct, expect cmd: #{CMD::RESP_CODE}, cmd: #{@cmd}" unless @header[8] == CMD::RESP_CODE
|
62
|
-
err_msg = "recv erron #{@header[9]}, 0 is correct cmd: #{@cmd}" unless @header[9] == 0
|
63
|
-
{status: err_msg.
|
59
|
+
err_msg = nil
|
60
|
+
err_msg = "recv package size #{@header} is not equal #{@header_len}, cmd: #{@cmd}" unless @header.length == @header_len || err_msg
|
61
|
+
err_msg = "recv cmd: #{@header[8]} is not correct, expect cmd: #{CMD::RESP_CODE}, cmd: #{@cmd}" unless @header[8] == CMD::RESP_CODE || err_msg
|
62
|
+
err_msg = "recv erron #{@header[9]}, 0 is correct cmd: #{@cmd}" unless @header[9] == 0 || err_msg
|
63
|
+
{status: err_msg.nil?, err_msg: err_msg}
|
64
64
|
end
|
65
65
|
|
66
66
|
def timeout_recv
|
@@ -88,7 +88,7 @@ module Fastdfs
|
|
88
88
|
body_len -= len
|
89
89
|
end
|
90
90
|
end
|
91
|
-
@content = nil if @content
|
91
|
+
@content = nil if Utils.is_blank? @content
|
92
92
|
end
|
93
93
|
|
94
94
|
end
|
@@ -28,7 +28,7 @@ module Fastdfs
|
|
28
28
|
group_name_max_len = ProtoCommon::GROUP_NAME_MAX_LEN
|
29
29
|
|
30
30
|
res = {group_name: body[0...group_name_max_len].strip, path: body[group_name_max_len..-1]}
|
31
|
-
_set_metadata(res[:path], res[:group_name], options) unless
|
31
|
+
_set_metadata(res[:path], res[:group_name], options) unless Utils.is_blank?(options)
|
32
32
|
res
|
33
33
|
end
|
34
34
|
end
|
@@ -86,12 +86,11 @@ module Fastdfs
|
|
86
86
|
end
|
87
87
|
|
88
88
|
def extract_path!(path, group_name = nil)
|
89
|
-
raise "path arguments is empty!" if
|
90
|
-
if
|
89
|
+
raise "path arguments is empty!" if Utils.is_blank? path
|
90
|
+
if Utils.is_blank? group_name
|
91
91
|
group_name = /^\/?(\w+)/.match(path)[1]
|
92
92
|
path = path.gsub(Regexp.new("/?#{group_name}/?"), "")
|
93
93
|
end
|
94
|
-
raise "group_name arguments is empty!" if group_name.blank?
|
95
94
|
return group_name, path
|
96
95
|
end
|
97
96
|
|
@@ -114,7 +113,7 @@ module Fastdfs
|
|
114
113
|
cover: ProtoCommon::SET_METADATA_FLAG_OVERWRITE,
|
115
114
|
merge: ProtoCommon::SET_METADATA_FLAG_MERGE
|
116
115
|
}
|
117
|
-
flag
|
116
|
+
flag ||= :cover
|
118
117
|
data[flag.to_sym]
|
119
118
|
end
|
120
119
|
|
@@ -122,7 +121,7 @@ module Fastdfs
|
|
122
121
|
meta_bytes = options.map do |a|
|
123
122
|
a.join(ProtoCommon::FILE_SEPERATOR)
|
124
123
|
end.join(ProtoCommon::RECORD_SEPERATOR).bytes
|
125
|
-
meta_bytes << 0 if meta_bytes.
|
124
|
+
meta_bytes << 0 if meta_bytes.length <= 0
|
126
125
|
meta_bytes
|
127
126
|
end
|
128
127
|
|
@@ -8,7 +8,8 @@ module Fastdfs
|
|
8
8
|
attr_accessor :socket, :cmd, :options
|
9
9
|
|
10
10
|
def initialize(host, port, options = {})
|
11
|
-
@
|
11
|
+
@options = options
|
12
|
+
@socket = Socket.new(host, port, @options[:socket])
|
12
13
|
@cmd = CMD::STORE_WITHOUT_GROUP_ONE
|
13
14
|
end
|
14
15
|
|
@@ -19,7 +20,7 @@ module Fastdfs
|
|
19
20
|
storage_port = body[ProtoCommon::PORT].unpack("C*").to_pack_long
|
20
21
|
store_path = body[ProtoCommon::TRACKER_BODY_LEN-1].unpack("C*")[0]
|
21
22
|
|
22
|
-
Storage.new(storage_ip, storage_port, store_path, options)
|
23
|
+
Storage.new(storage_ip, storage_port, store_path, @options)
|
23
24
|
end
|
24
25
|
res[:status] ? res[:result] : res
|
25
26
|
end
|
data/lib/fastdfs-client/utils.rb
CHANGED
data/spec/mock_tcp_socket.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
|
2
|
-
class
|
2
|
+
class MockTCPSocket
|
3
3
|
include Fastdfs::Client
|
4
4
|
|
5
5
|
attr_accessor :host, :port, :cmd, :recv_offset, :connect_state
|
@@ -15,11 +15,24 @@ class TCPSocket
|
|
15
15
|
def write(*args)
|
16
16
|
pkg = args[0].unpack("C*")
|
17
17
|
@cmd ||= pkg[8]
|
18
|
+
sleep(2)
|
18
19
|
end
|
19
20
|
|
20
21
|
def recv(len)
|
21
|
-
|
22
|
-
|
22
|
+
data = case @cmd
|
23
|
+
when 101
|
24
|
+
gate_tracker(len)
|
25
|
+
when 11
|
26
|
+
upload_file(len)
|
27
|
+
when 12
|
28
|
+
delete_file(len)
|
29
|
+
when 15
|
30
|
+
get_metadata(len)
|
31
|
+
when 13
|
32
|
+
set_metadata(len)
|
33
|
+
when 14
|
34
|
+
download_file(len)
|
35
|
+
end
|
23
36
|
@recv_offset = len
|
24
37
|
data
|
25
38
|
end
|
@@ -35,62 +48,50 @@ class TCPSocket
|
|
35
48
|
end
|
36
49
|
|
37
50
|
private
|
51
|
+
def gate_tracker(len)
|
52
|
+
header = ProtoCommon.header_bytes(CMD::RESP_CODE, 0)
|
53
|
+
header[7] = ProtoCommon::TRACKER_BODY_LEN
|
38
54
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
header = ProtoCommon.header_bytes(CMD::RESP_CODE, 0)
|
44
|
-
header[7] = ProtoCommon::TRACKER_BODY_LEN
|
55
|
+
group_name = Utils.array_merge([].fill(0, 0...16), TestConfig::GROUP_NAME.bytes)
|
56
|
+
ip = Utils.array_merge([].fill(0, 0...15), TestConfig::STORAGE_IP.bytes)
|
57
|
+
port = Utils.number_to_buffer(TestConfig::STORAGE_PORT.to_i)
|
58
|
+
store_path = Array(TestConfig::STORE_PATH)
|
45
59
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
60
|
+
(header+group_name+ip+port+store_path)[@recv_offset...@recv_offset+len].pack("C*")
|
61
|
+
end
|
62
|
+
|
63
|
+
def upload_file(len)
|
64
|
+
header = ProtoCommon.header_bytes(CMD::RESP_CODE, 0)
|
65
|
+
group_name = Utils.array_merge([].fill(0, 0...16), TestConfig::GROUP_NAME.bytes)
|
66
|
+
file_name = TestConfig::FILE_NAME.bytes
|
67
|
+
res = (group_name + file_name)
|
68
|
+
header[7] = (header + res).length
|
69
|
+
res = (header + res)
|
70
|
+
|
71
|
+
res[@recv_offset...@recv_offset+len].pack("C*")
|
72
|
+
end
|
73
|
+
|
74
|
+
def delete_file(len)
|
75
|
+
header = ProtoCommon.header_bytes(CMD::RESP_CODE, 0)
|
76
|
+
header.pack("C*")
|
77
|
+
end
|
78
|
+
|
79
|
+
def get_metadata(len)
|
80
|
+
header = ProtoCommon.header_bytes(CMD::RESP_CODE, 0)
|
81
|
+
body = TestConfig::METADATA.map{|a| a.join(ProtoCommon::FILE_SEPERATOR)}.join(ProtoCommon::RECORD_SEPERATOR).bytes
|
82
|
+
header[7] = body.length
|
83
|
+
(header + body)[@recv_offset...@recv_offset+len].pack("C*")
|
84
|
+
end
|
85
|
+
|
86
|
+
def set_metadata(len)
|
87
|
+
header = ProtoCommon.header_bytes(CMD::RESP_CODE, 0)
|
88
|
+
header.pack("C*")
|
89
|
+
end
|
50
90
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
header = ProtoCommon.header_bytes(CMD::RESP_CODE, 0)
|
57
|
-
group_name = Utils.array_merge([].fill(0, 0...16), TestConfig::GROUP_NAME.bytes)
|
58
|
-
file_name = TestConfig::FILE_NAME.bytes
|
59
|
-
res = (group_name + file_name)
|
60
|
-
header[7] = (header + res).length
|
61
|
-
res = (header + res)
|
62
|
-
|
63
|
-
res[@recv_offset...@recv_offset+len].pack("C*")
|
64
|
-
end
|
65
|
-
},
|
66
|
-
"12" => {
|
67
|
-
recv_bytes: lambda do |len|
|
68
|
-
header = ProtoCommon.header_bytes(CMD::RESP_CODE, 0)
|
69
|
-
header.pack("C*")
|
70
|
-
end
|
71
|
-
},
|
72
|
-
"15" => {
|
73
|
-
recv_bytes: lambda do |len|
|
74
|
-
header = ProtoCommon.header_bytes(CMD::RESP_CODE, 0)
|
75
|
-
body = TestConfig::METADATA.map{|a| a.join(ProtoCommon::FILE_SEPERATOR)}.join(ProtoCommon::RECORD_SEPERATOR).bytes
|
76
|
-
header[7] = body.length
|
77
|
-
(header + body)[@recv_offset...@recv_offset+len].pack("C*")
|
78
|
-
end
|
79
|
-
},
|
80
|
-
"13" => {
|
81
|
-
recv_bytes: lambda do |len|
|
82
|
-
header = ProtoCommon.header_bytes(CMD::RESP_CODE, 0)
|
83
|
-
header.pack("C*")
|
84
|
-
end
|
85
|
-
},
|
86
|
-
"14" => {
|
87
|
-
recv_bytes: lambda do |len|
|
88
|
-
header = ProtoCommon.header_bytes(CMD::RESP_CODE, 0)
|
89
|
-
body = IO.read(TestConfig::FILE).bytes
|
90
|
-
header[7] = body.length
|
91
|
-
(header + body)[@recv_offset...@recv_offset+len].pack("C*")
|
92
|
-
end
|
93
|
-
}
|
94
|
-
}
|
91
|
+
def download_file(len)
|
92
|
+
header = ProtoCommon.header_bytes(CMD::RESP_CODE, 0)
|
93
|
+
body = IO.read(TestConfig::FILE).bytes
|
94
|
+
header[7] = body.length
|
95
|
+
(header + body)[@recv_offset...@recv_offset+len].pack("C*")
|
95
96
|
end
|
96
97
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -9,7 +9,13 @@ require File.expand_path('../mock_tcp_socket', __FILE__)
|
|
9
9
|
FC = Fastdfs::Client
|
10
10
|
|
11
11
|
RSpec.configure do |config|
|
12
|
+
config.before(:each) do
|
13
|
+
TCPSocket.stub(:new) do |h, p|
|
14
|
+
MockTCPSocket.new(h, p)
|
15
|
+
end
|
16
|
+
end
|
12
17
|
config.mock_with :rspec do |c|
|
13
18
|
c.syntax = [:should, :expect]
|
14
19
|
end
|
15
20
|
end
|
21
|
+
|
data/spec/storage_spec.rb
CHANGED
@@ -40,7 +40,7 @@ describe Fastdfs::Client::Storage do
|
|
40
40
|
it "can delete file raise exception" do
|
41
41
|
res = storage.upload(TestConfig::FILE)[:result]
|
42
42
|
result = FC::ProtoCommon.header_bytes(FC::CMD::RESP_CODE, 0, 22)
|
43
|
-
|
43
|
+
MockTCPSocket.any_instance.stub("recv").and_return(result.pack("C*"))
|
44
44
|
expect( storage.delete("fdsaf", res[:group_name])[:status] ).to be_falsey
|
45
45
|
end
|
46
46
|
|
@@ -58,6 +58,5 @@ describe Fastdfs::Client::Storage do
|
|
58
58
|
expect(res[:status]).to be_truthy
|
59
59
|
expect(res[:result]).to be_an_instance_of(Tempfile)
|
60
60
|
expect(IO.read(res[:result])).to eq(IO.read(TestConfig::FILE))
|
61
|
-
|
62
61
|
end
|
63
62
|
end
|
data/spec/tracker_spec.rb
CHANGED
@@ -29,7 +29,18 @@ describe Fastdfs::Client::Tracker do
|
|
29
29
|
expect(tracker.get_storage.store_path).to eq(TestConfig::STORE_PATH)
|
30
30
|
end
|
31
31
|
|
32
|
+
it "get to the server failed" do
|
33
|
+
result = FC::ProtoCommon.header_bytes(FC::CMD::RESP_CODE, 0, 22)
|
34
|
+
MockTCPSocket.any_instance.stub("recv").and_return(result.pack("C*"))
|
35
|
+
expect(tracker.get_storage).to be_a_kind_of(Hash)
|
36
|
+
expect(tracker.get_storage[:status]).to be_falsey
|
37
|
+
end
|
38
|
+
|
32
39
|
it "run server flow" do
|
40
|
+
1.times.map do
|
41
|
+
tracker.get_storage
|
42
|
+
end
|
43
|
+
|
33
44
|
# storage = tracker.get_storage
|
34
45
|
# puts "#{storage.host}, #{storage.port}"
|
35
46
|
# results = storage.upload(File.open("/Users/huxinghai/Documents/shark/app/assets/images/page.png"))
|
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.0.
|
4
|
+
version: 1.0.1
|
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-08-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -24,6 +24,34 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 3.4.0
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 3.4.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: debugger
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 1.6.8
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.6.8
|
27
55
|
description: fastdfs upload file client for ruby
|
28
56
|
email:
|
29
57
|
- huxinghai1988@gmail.com
|
@@ -33,7 +61,6 @@ extra_rdoc_files: []
|
|
33
61
|
files:
|
34
62
|
- ".gitignore"
|
35
63
|
- Gemfile
|
36
|
-
- Gemfile.lock
|
37
64
|
- README.md
|
38
65
|
- fastdfs-client.gemspec
|
39
66
|
- lib/fastdfs-client.rb
|
data/Gemfile.lock
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
fastdfs-client (1.0.0)
|
5
|
-
|
6
|
-
GEM
|
7
|
-
remote: http://gems.ruby-china.org/
|
8
|
-
specs:
|
9
|
-
columnize (0.9.0)
|
10
|
-
debugger (1.6.8)
|
11
|
-
columnize (>= 0.3.1)
|
12
|
-
debugger-linecache (~> 1.2.0)
|
13
|
-
debugger-ruby_core_source (~> 1.3.5)
|
14
|
-
debugger-linecache (1.2.0)
|
15
|
-
debugger-ruby_core_source (1.3.8)
|
16
|
-
diff-lcs (1.2.5)
|
17
|
-
rspec (3.4.0)
|
18
|
-
rspec-core (~> 3.4.0)
|
19
|
-
rspec-expectations (~> 3.4.0)
|
20
|
-
rspec-mocks (~> 3.4.0)
|
21
|
-
rspec-core (3.4.4)
|
22
|
-
rspec-support (~> 3.4.0)
|
23
|
-
rspec-expectations (3.4.0)
|
24
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
25
|
-
rspec-support (~> 3.4.0)
|
26
|
-
rspec-mocks (3.4.1)
|
27
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
28
|
-
rspec-support (~> 3.4.0)
|
29
|
-
rspec-support (3.4.1)
|
30
|
-
|
31
|
-
PLATFORMS
|
32
|
-
ruby
|
33
|
-
|
34
|
-
DEPENDENCIES
|
35
|
-
bundler (~> 1.3)
|
36
|
-
debugger
|
37
|
-
fastdfs-client!
|
38
|
-
rspec
|