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