clamav-client 1.0.0 → 2.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/.travis.yml +11 -0
- data/README.md +82 -32
- data/clamav-client.gemspec +2 -1
- data/lib/clamav/client.rb +12 -2
- data/lib/clamav/commands/command.rb +23 -9
- data/lib/clamav/commands/instream_command.rb +41 -0
- data/lib/clamav/commands/scan_command.rb +1 -18
- data/lib/clamav/connection.rb +28 -4
- data/lib/clamav/responses.rb +3 -1
- data/lib/clamav/responses/error_response.rb +1 -0
- data/lib/clamav/responses/success_response.rb +1 -0
- data/lib/clamav/responses/virus_response.rb +1 -0
- data/lib/clamav/wrapper.rb +9 -0
- data/lib/clamav/wrappers/new_line_wrapper.rb +1 -5
- data/lib/clamav/wrappers/null_termination_wrapper.rb +1 -5
- data/test/integration/clamav/client_test.rb +15 -0
- data/test/test_helper.rb +3 -1
- data/test/unit/clamav/commands/instream_command_test.rb +53 -0
- data/test/unit/clamav/connection_test.rb +8 -1
- metadata +20 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0e16bf843318d1ae3aec44e522c278143affc3d2
|
4
|
+
data.tar.gz: 100e606c288e5a6a3a46a0537e4d4f6f0d989b9c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 06d3e9d069ff7875b6f499c78adfbdaae9a29a030fd38f68435393e322cfa3c407c0d53a72d4067550cfa0b09c3da73858c4d944b8ce46f31c95ccb4d3484a0e
|
7
|
+
data.tar.gz: 141d5420ccd5fc6a90332b77184b5c1c593d2b27ce297a2b498677cc7b176a87aa3dffdd86f13173492912f47ed2906faba88daa17280407fbffb092d11df4a4
|
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -22,7 +22,7 @@ Alternatively, you can spawn a `pry` console right away by just running:
|
|
22
22
|
|
23
23
|
## Requirements
|
24
24
|
|
25
|
-
* Ruby >= 2
|
25
|
+
* Ruby >= 1.9.2
|
26
26
|
* clamd
|
27
27
|
|
28
28
|
## Usage
|
@@ -30,15 +30,17 @@ Alternatively, you can spawn a `pry` console right away by just running:
|
|
30
30
|
The `ClamAV::Client` class is responsible for opening a connection to a remote
|
31
31
|
ClamAV clam daemon.
|
32
32
|
|
33
|
-
|
33
|
+
See the implemented commands below.
|
34
34
|
|
35
35
|
### PING => Boolean
|
36
36
|
|
37
37
|
Pings the daemon to check whether it is alive.
|
38
38
|
|
39
|
-
|
40
|
-
|
41
|
-
|
39
|
+
```ruby
|
40
|
+
client = ClamAV::Client.new
|
41
|
+
client.execute(ClamAV::Commands::PingCommand.new)
|
42
|
+
# => true
|
43
|
+
```
|
42
44
|
|
43
45
|
### SCAN <file_or_directory> => Array[Response]
|
44
46
|
|
@@ -46,56 +48,73 @@ Scans a file or a directory for the existence of a virus.
|
|
46
48
|
|
47
49
|
The absolute path must be given to that command.
|
48
50
|
|
49
|
-
|
51
|
+
```ruby
|
52
|
+
client = ClamAV::Client.new
|
50
53
|
|
51
|
-
|
52
|
-
|
54
|
+
client.execute(ClamAV::Commands::ScanCommand.new('/tmp/path/foo.c'))
|
55
|
+
# => [#<ClamAV::SuccessResponse:0x007fbf314b9478 @file="/tmp/foo.c">]
|
53
56
|
|
54
|
-
|
55
|
-
|
56
|
-
#<ClamAV::SuccessResponse:0x007fc30c272910 @file="/tmp/path/foo.cpp">]
|
57
|
+
client.execute(ClamAV::Commands::ScanCommand.new('/tmp/path'))
|
58
|
+
# => [#<ClamAV::SuccessResponse:0x007fc30c273298 @file="/tmp/path/foo.c">,
|
59
|
+
# #<ClamAV::SuccessResponse:0x007fc30c272910 @file="/tmp/path/foo.cpp">]
|
60
|
+
```
|
57
61
|
|
62
|
+
### INSTREAM => Response
|
63
|
+
|
64
|
+
Scans an IO-like object for the existence of a virus.
|
65
|
+
|
66
|
+
```ruby
|
67
|
+
client = ClamAV::Client.new
|
68
|
+
|
69
|
+
io = StringIO.new('some data')
|
70
|
+
client.execute(ClamAV::Commands::InstreamCommand.new(io))
|
71
|
+
# => [#<ClamAV::SuccessResponse:0x007fe471cabe50 @file="stream">]
|
72
|
+
```
|
58
73
|
|
59
74
|
### Custom commands
|
60
75
|
|
61
76
|
Custom commands can be given to the client. The contract between the client
|
62
|
-
and the command is
|
63
|
-
|
64
|
-
|
65
|
-
Here's a simple example that implements the `VERSION` command:
|
77
|
+
and the command is through the `Command#call` method. The `call` method will
|
78
|
+
receive a `Connection` object.
|
66
79
|
|
67
|
-
|
68
|
-
client = ClamAV::Client.new
|
80
|
+
Here's a simple example implementing the `VERSION` command:
|
69
81
|
|
70
|
-
|
71
|
-
|
72
|
-
|
82
|
+
```ruby
|
83
|
+
# Build the client
|
84
|
+
client = ClamAV::Client.new
|
73
85
|
|
74
|
-
|
75
|
-
|
76
|
-
|
86
|
+
# Create the command lambda
|
87
|
+
version_command = lambda { |conn| conn.send_request("VERSION") }
|
88
|
+
# => #<Proc:0x007fc0d0c14b28>
|
77
89
|
|
90
|
+
# Execute the command
|
91
|
+
client.execute(version_command)
|
92
|
+
# => "1: ClamAV 0.98.1/18489/Tue Feb 18 16:00:05 2014"
|
93
|
+
```
|
78
94
|
|
79
95
|
## Defaults
|
80
96
|
|
81
97
|
The default values in use are:
|
82
98
|
|
83
|
-
* clamd socket: UNIX Socket, located at `/
|
99
|
+
* clamd socket: UNIX Socket, located at `/var/run/clamav/clamd.ctl`;
|
84
100
|
* New-line terminated commands.
|
85
101
|
|
86
|
-
These defaults can be changed
|
102
|
+
These defaults can be changed:
|
87
103
|
|
88
|
-
|
104
|
+
* by creating the object graph manually;
|
105
|
+
* by setting environment variables.
|
89
106
|
|
90
|
-
###
|
107
|
+
### The object graph
|
108
|
+
|
109
|
+
#### Client
|
91
110
|
|
92
111
|
The main object is the `Client` object. It is responsible for executing the commands.
|
93
|
-
|
112
|
+
It can receive a custom connection object.
|
94
113
|
|
95
|
-
|
114
|
+
#### Connection
|
96
115
|
|
97
|
-
The
|
98
|
-
protocol
|
116
|
+
The `Connection` object is the bridge between the raw socket object and the
|
117
|
+
protocol used between the client and the daemon.
|
99
118
|
|
100
119
|
`clamd` supports two kinds of delimiters:
|
101
120
|
|
@@ -104,12 +123,43 @@ protocol being used between the client and the daemon.
|
|
104
123
|
|
105
124
|
The management of those delimiters is done with the wrapper argument.
|
106
125
|
|
107
|
-
|
126
|
+
#### Wrapper
|
108
127
|
|
109
128
|
The wrapper is responsible for taking the incoming request with the
|
110
129
|
`wrap_request` method, and parsing the response with the `read_response`
|
111
130
|
method.
|
112
131
|
|
132
|
+
### Environment variables
|
133
|
+
|
134
|
+
The variables can be set programmatically in your Ruby programs like
|
135
|
+
|
136
|
+
```ruby
|
137
|
+
# from a ruby script
|
138
|
+
ENV['CLAMD_UNIX_SOCKET'] = '/some/path'
|
139
|
+
|
140
|
+
# Now the defaults are changed for any new ClamAV::Client instantiation
|
141
|
+
```
|
142
|
+
|
143
|
+
or by setting the variables before starting the Ruby process:
|
144
|
+
|
145
|
+
```
|
146
|
+
# from the command-line
|
147
|
+
export CLAMD_UNIX_SOCKET = '/some/path'
|
148
|
+
ruby my_program.rb
|
149
|
+
# or
|
150
|
+
CLAMD_UNIX_SOCKET = '/some/path' ruby my_program.rb
|
151
|
+
```
|
152
|
+
|
153
|
+
Please note that setting the `CLAMD_TCP_*` variables will have the precedence
|
154
|
+
over the `CLAMD_UNIX_SOCKET`.
|
155
|
+
|
156
|
+
#### CLAMD_UNIX_SOCKET
|
157
|
+
|
158
|
+
Sets the socket path of the ClamAV daemon.
|
159
|
+
|
160
|
+
#### CLAMD_TCP_HOST and CLAMD_TCP_PORT
|
161
|
+
|
162
|
+
Sets the host and port of the ClamAV daemon.
|
113
163
|
|
114
164
|
## Contributing
|
115
165
|
|
data/clamav-client.gemspec
CHANGED
@@ -3,7 +3,7 @@ $:<< 'lib'
|
|
3
3
|
|
4
4
|
Gem::Specification.new do |spec|
|
5
5
|
spec.name = "clamav-client"
|
6
|
-
spec.version = "
|
6
|
+
spec.version = "2.0.1"
|
7
7
|
spec.authors = ["Franck Verrot"]
|
8
8
|
spec.email = ["franck@verrot.fr"]
|
9
9
|
spec.summary = %q{ClamAV::Client connects to a Clam Anti-Virus clam daemon and send commands.}
|
@@ -19,4 +19,5 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.add_development_dependency "bundler", "~> 1.5"
|
20
20
|
spec.add_development_dependency "rake"
|
21
21
|
spec.add_development_dependency "pry"
|
22
|
+
spec.add_development_dependency "minitest"
|
22
23
|
end
|
data/lib/clamav/client.rb
CHANGED
@@ -18,6 +18,7 @@ require "clamav/connection"
|
|
18
18
|
require "clamav/commands/ping_command"
|
19
19
|
require "clamav/commands/quit_command"
|
20
20
|
require "clamav/commands/scan_command"
|
21
|
+
require "clamav/commands/instream_command"
|
21
22
|
require "clamav/util"
|
22
23
|
require "clamav/wrappers/new_line_wrapper"
|
23
24
|
require "clamav/wrappers/null_termination_wrapper"
|
@@ -30,14 +31,23 @@ module ClamAV
|
|
30
31
|
end
|
31
32
|
|
32
33
|
def execute(command)
|
33
|
-
command.(@connection)
|
34
|
+
command.call(@connection)
|
34
35
|
end
|
35
36
|
|
36
37
|
def default_connection
|
37
38
|
ClamAV::Connection.new(
|
38
|
-
socket:
|
39
|
+
socket: resolve_default_socket,
|
39
40
|
wrapper: ::ClamAV::Wrappers::NewLineWrapper.new
|
40
41
|
)
|
41
42
|
end
|
43
|
+
|
44
|
+
def resolve_default_socket
|
45
|
+
unix_socket, tcp_host, tcp_port = ENV.values_at('CLAMD_UNIX_SOCKET', 'CLAMD_TCP_HOST', 'CLAMD_TCP_PORT')
|
46
|
+
if tcp_host && tcp_port
|
47
|
+
::TCPSocket.new(tcp_host, tcp_port)
|
48
|
+
else
|
49
|
+
::UNIXSocket.new(unix_socket || '/var/run/clamav/clamd.ctl')
|
50
|
+
end
|
51
|
+
end
|
42
52
|
end
|
43
53
|
end
|
@@ -13,20 +13,34 @@
|
|
13
13
|
|
14
14
|
# You should have received a copy of the GNU General Public License
|
15
15
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
16
|
+
|
17
|
+
require 'clamav/responses/error_response'
|
18
|
+
require 'clamav/responses/success_response'
|
19
|
+
require 'clamav/responses/virus_response'
|
20
|
+
|
16
21
|
module ClamAV
|
17
22
|
module Commands
|
18
23
|
class Command
|
19
|
-
|
20
|
-
|
21
|
-
|
24
|
+
Statuses = {
|
25
|
+
'OK' => ClamAV::SuccessResponse,
|
26
|
+
'ERROR' => ClamAV::ErrorResponse,
|
27
|
+
'ClamAV-Test-Signature FOUND' => ClamAV::VirusResponse
|
28
|
+
}
|
29
|
+
|
30
|
+
def call; raise NotImplementedError.new; end
|
22
31
|
|
23
32
|
protected
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
33
|
+
|
34
|
+
def get_status_from_response(str)
|
35
|
+
case str
|
36
|
+
when 'Error processing command. ERROR'
|
37
|
+
ErrorResponse.new(str)
|
38
|
+
else
|
39
|
+
/(?<id>\d+): (?<filepath>.*): (?<status>.*)/ =~ str
|
40
|
+
Statuses[status].new(filepath)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
30
44
|
end
|
31
45
|
end
|
32
46
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# clamav-client - ClamAV client
|
2
|
+
# Copyright (C) 2014 Franck Verrot <franck@verrot.fr>
|
3
|
+
|
4
|
+
# This program is free software: you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
6
|
+
# the Free Software Foundation, either version 3 of the License, or
|
7
|
+
# (at your option) any later version.
|
8
|
+
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
16
|
+
|
17
|
+
require 'clamav/commands/command'
|
18
|
+
|
19
|
+
module ClamAV
|
20
|
+
module Commands
|
21
|
+
class InstreamCommand < Command
|
22
|
+
|
23
|
+
def initialize(io, max_chunk_size = 1024)
|
24
|
+
@io = begin io rescue raise ArgumentError, 'io is required', caller; end
|
25
|
+
@max_chunk_size = max_chunk_size
|
26
|
+
end
|
27
|
+
|
28
|
+
def call(conn)
|
29
|
+
conn.write_request("INSTREAM")
|
30
|
+
|
31
|
+
while(packet = @io.read(@max_chunk_size))
|
32
|
+
packet_size = [packet.size].pack("N")
|
33
|
+
conn.raw_write("#{packet_size}#{packet}")
|
34
|
+
end
|
35
|
+
conn.raw_write("\x00\x00\x00\x00")
|
36
|
+
get_status_from_response(conn.read_response)
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -15,17 +15,10 @@
|
|
15
15
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
16
16
|
|
17
17
|
require 'clamav/commands/command'
|
18
|
-
|
19
|
-
require 'clamav/responses/success_response'
|
20
|
-
require 'clamav/responses/virus_response'
|
18
|
+
|
21
19
|
module ClamAV
|
22
20
|
module Commands
|
23
21
|
class ScanCommand < Command
|
24
|
-
Statuses = {
|
25
|
-
'ERROR' => ClamAV::ErrorResponse,
|
26
|
-
'OK' => ClamAV::SuccessResponse,
|
27
|
-
'ClamAV-Test-Signature FOUND' => ClamAV::VirusResponse
|
28
|
-
}
|
29
22
|
|
30
23
|
def initialize(path, path_finder = Util)
|
31
24
|
@path, @path_finder = path, path_finder
|
@@ -35,20 +28,10 @@ module ClamAV
|
|
35
28
|
@path_finder.path_to_files(@path).map { |file| scan_file(conn, file) }
|
36
29
|
end
|
37
30
|
|
38
|
-
protected
|
39
31
|
def scan_file(conn, file)
|
40
32
|
get_status_from_response(conn.send_request("SCAN #{file}"))
|
41
33
|
end
|
42
34
|
|
43
|
-
def get_status_from_response(str)
|
44
|
-
case str
|
45
|
-
when 'Error processing command. ERROR'
|
46
|
-
ErrorResponse.new(str)
|
47
|
-
else
|
48
|
-
/(?<id>\d+): (?<filepath>.*): (?<status>.*)/ =~ str
|
49
|
-
Statuses[status].new(filepath)
|
50
|
-
end
|
51
|
-
end
|
52
35
|
end
|
53
36
|
end
|
54
37
|
end
|
data/lib/clamav/connection.rb
CHANGED
@@ -18,9 +18,16 @@ require 'socket'
|
|
18
18
|
|
19
19
|
module ClamAV
|
20
20
|
class Connection
|
21
|
-
def initialize(
|
22
|
-
|
23
|
-
|
21
|
+
def initialize(args)
|
22
|
+
socket = args.fetch(:socket) { missing_required_argument(:socket) }
|
23
|
+
wrapper = args.fetch(:wrapper) { missing_required_argument(:wrapper) }
|
24
|
+
|
25
|
+
if socket && wrapper
|
26
|
+
@socket = socket
|
27
|
+
@wrapper = wrapper
|
28
|
+
else
|
29
|
+
raise ArgumentError
|
30
|
+
end
|
24
31
|
end
|
25
32
|
|
26
33
|
def establish_connection
|
@@ -28,10 +35,27 @@ module ClamAV
|
|
28
35
|
@socket.write wrapped_request
|
29
36
|
end
|
30
37
|
|
31
|
-
def
|
38
|
+
def write_request(str)
|
32
39
|
wrapped_request = @wrapper.wrap_request(str)
|
33
40
|
@socket.write wrapped_request
|
41
|
+
end
|
42
|
+
|
43
|
+
def read_response
|
34
44
|
@wrapper.read_response(@socket)
|
35
45
|
end
|
46
|
+
|
47
|
+
def send_request(str)
|
48
|
+
write_request(str)
|
49
|
+
read_response
|
50
|
+
end
|
51
|
+
|
52
|
+
def raw_write(str)
|
53
|
+
@socket.write str
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
def missing_required_argument(key)
|
58
|
+
raise ArgumentError, "#{key} is required"
|
59
|
+
end
|
36
60
|
end
|
37
61
|
end
|
data/lib/clamav/responses.rb
CHANGED
data/lib/clamav/wrapper.rb
CHANGED
@@ -18,5 +18,14 @@ module ClamAV
|
|
18
18
|
class Wrapper
|
19
19
|
def wrap_request(request); raise NotImplementedError; end
|
20
20
|
def unwrap_response(response); raise NotImplementedError; end
|
21
|
+
|
22
|
+
protected
|
23
|
+
def read_until(socket, delimiter)
|
24
|
+
buff = ""
|
25
|
+
while (char = socket.getc) != delimiter
|
26
|
+
buff << char
|
27
|
+
end
|
28
|
+
buff
|
29
|
+
end
|
21
30
|
end
|
22
31
|
end
|
@@ -53,5 +53,20 @@ describe "ClamAV::Client Integration Tests" do
|
|
53
53
|
assert_equal expected_results, results
|
54
54
|
end
|
55
55
|
end
|
56
|
+
|
57
|
+
describe "instream" do
|
58
|
+
it "can be started" do
|
59
|
+
dir = File.expand_path('../../../../test/fixtures', __FILE__)
|
60
|
+
|
61
|
+
[
|
62
|
+
['clamavtest.txt', ClamAV::VirusResponse],
|
63
|
+
['innocent.txt', ClamAV::SuccessResponse]
|
64
|
+
].each do |file, response_class|
|
65
|
+
io = File.open(File.join(dir, file))
|
66
|
+
command = ClamAV::Commands::InstreamCommand.new(io)
|
67
|
+
client.execute(command).must_equal response_class.new("stream")
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
56
71
|
end
|
57
72
|
end
|
data/test/test_helper.rb
CHANGED
@@ -14,6 +14,8 @@
|
|
14
14
|
# You should have received a copy of the GNU General Public License
|
15
15
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
16
16
|
|
17
|
-
|
17
|
+
gem 'minitest'
|
18
18
|
|
19
|
+
require 'minitest/autorun'
|
19
20
|
require 'clamav/client'
|
21
|
+
require 'pry'
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# clamav-client - ClamAV client
|
2
|
+
# Copyright (C) 2014 Franck Verrot <franck@verrot.fr>
|
3
|
+
|
4
|
+
# This program is free software: you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
6
|
+
# the Free Software Foundation, either version 3 of the License, or
|
7
|
+
# (at your option) any later version.
|
8
|
+
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
16
|
+
|
17
|
+
require 'test_helper'
|
18
|
+
|
19
|
+
describe "INSTREAM command" do
|
20
|
+
before do
|
21
|
+
@conn = Minitest::Mock.new
|
22
|
+
@io = ::StringIO.new('hello')
|
23
|
+
end
|
24
|
+
|
25
|
+
after do
|
26
|
+
@conn.verify
|
27
|
+
end
|
28
|
+
|
29
|
+
it "can process an IO object" do
|
30
|
+
@conn.expect(:write_request, nil, ["INSTREAM"])
|
31
|
+
@conn.expect(:raw_write, nil, ["\x00\x00\x00\x05hello"])
|
32
|
+
@conn.expect(:raw_write, nil, ["\x00\x00\x00\x00"])
|
33
|
+
@conn.expect(:read_response, '1: stream: OK', [])
|
34
|
+
|
35
|
+
assert ClamAV::Commands::InstreamCommand.new(@io).call(@conn)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "can specify the size of read chunks" do
|
39
|
+
chunk_size = 1
|
40
|
+
|
41
|
+
@conn.expect(:write_request, nil, ["INSTREAM"])
|
42
|
+
@conn.expect(:raw_write, nil, ["\x00\x00\x00\x01h"])
|
43
|
+
@conn.expect(:raw_write, nil, ["\x00\x00\x00\x01e"])
|
44
|
+
@conn.expect(:raw_write, nil, ["\x00\x00\x00\x01l"])
|
45
|
+
@conn.expect(:raw_write, nil, ["\x00\x00\x00\x01l"])
|
46
|
+
@conn.expect(:raw_write, nil, ["\x00\x00\x00\x01o"])
|
47
|
+
@conn.expect(:raw_write, nil, ["\x00\x00\x00\x00"])
|
48
|
+
@conn.expect(:read_response, '1: stream: OK', [])
|
49
|
+
|
50
|
+
assert ClamAV::Commands::InstreamCommand.
|
51
|
+
new(@io, chunk_size).call(@conn)
|
52
|
+
end
|
53
|
+
end
|
@@ -18,7 +18,7 @@ require 'test_helper'
|
|
18
18
|
|
19
19
|
describe "ClamAV::Connection" do
|
20
20
|
let(:wrapper_mock) { Minitest::Mock.new }
|
21
|
-
let(:socket_mock)
|
21
|
+
let(:socket_mock) { Minitest::Mock.new }
|
22
22
|
|
23
23
|
it "requires a port and a wrapper" do
|
24
24
|
assert_raises(ArgumentError) { ClamAV::Connection.new }
|
@@ -29,4 +29,11 @@ describe "ClamAV::Connection" do
|
|
29
29
|
it "can be constructed with a port and wrapper class" do
|
30
30
|
ClamAV::Connection.new(socket: socket_mock, wrapper: wrapper_mock)
|
31
31
|
end
|
32
|
+
|
33
|
+
it "support raw writes" do
|
34
|
+
socket_mock.expect(:write, nil, ["foo"])
|
35
|
+
|
36
|
+
conn = ClamAV::Connection.new(socket: socket_mock, wrapper: wrapper_mock)
|
37
|
+
conn.raw_write("foo")
|
38
|
+
end
|
32
39
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: clamav-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Franck Verrot
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-02-
|
11
|
+
date: 2014-02-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: minitest
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
55
69
|
description: ClamAV::Client connects to a Clam Anti-Virus clam daemon and send commands.
|
56
70
|
email:
|
57
71
|
- franck@verrot.fr
|
@@ -60,6 +74,7 @@ extensions: []
|
|
60
74
|
extra_rdoc_files: []
|
61
75
|
files:
|
62
76
|
- ".gitignore"
|
77
|
+
- ".travis.yml"
|
63
78
|
- Gemfile
|
64
79
|
- LICENSE.txt
|
65
80
|
- README.md
|
@@ -67,6 +82,7 @@ files:
|
|
67
82
|
- clamav-client.gemspec
|
68
83
|
- lib/clamav/client.rb
|
69
84
|
- lib/clamav/commands/command.rb
|
85
|
+
- lib/clamav/commands/instream_command.rb
|
70
86
|
- lib/clamav/commands/ping_command.rb
|
71
87
|
- lib/clamav/commands/quit_command.rb
|
72
88
|
- lib/clamav/commands/scan_command.rb
|
@@ -87,6 +103,7 @@ files:
|
|
87
103
|
- test/integration/clamav/util_test.rb
|
88
104
|
- test/test_helper.rb
|
89
105
|
- test/unit/clamav/client_test.rb
|
106
|
+
- test/unit/clamav/commands/instream_command_test.rb
|
90
107
|
- test/unit/clamav/commands/ping_command_test.rb
|
91
108
|
- test/unit/clamav/commands/scan_command_test.rb
|
92
109
|
- test/unit/clamav/connection_test.rb
|
@@ -125,6 +142,7 @@ test_files:
|
|
125
142
|
- test/integration/clamav/util_test.rb
|
126
143
|
- test/test_helper.rb
|
127
144
|
- test/unit/clamav/client_test.rb
|
145
|
+
- test/unit/clamav/commands/instream_command_test.rb
|
128
146
|
- test/unit/clamav/commands/ping_command_test.rb
|
129
147
|
- test/unit/clamav/commands/scan_command_test.rb
|
130
148
|
- test/unit/clamav/connection_test.rb
|