cef 1.0.0 → 2.1.1.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -7
- data/.rspec +2 -1
- data/Guardfile +55 -0
- data/README.rdoc +3 -64
- data/VERSION +1 -1
- data/bin/cef_sender +0 -0
- data/cef.gemspec +17 -15
- data/conf/cef-schema.json +251 -0
- data/lib/cef.rb +39 -3
- data/lib/cef/event.rb +82 -134
- data/lib/cef/loggers/cef_file.rb +19 -0
- data/lib/cef/loggers/cef_syslog_udp.rb +40 -0
- data/lib/cef/time_extensions.rb +15 -0
- data/lib/cef/version.rb +1 -1
- metadata +83 -33
- data/lib/cef/constants.rb +0 -166
- data/lib/cef/sender.rb +0 -39
- data/spec/lib/cef/event_spec.rb +0 -44
- data/spec/lib/cef/sender_spec.rb +0 -24
- data/spec/lib/cef_spec.rb +0 -9
- data/spec/spec_helper.rb +0 -7
data/lib/cef.rb
CHANGED
@@ -1,10 +1,46 @@
|
|
1
|
+
require 'json'
|
1
2
|
require 'date'
|
2
3
|
require 'socket'
|
4
|
+
require 'hashie'
|
5
|
+
require 'ipaddr'
|
6
|
+
|
3
7
|
require 'cef/version'
|
4
|
-
require 'cef/
|
8
|
+
require 'cef/time_extensions'
|
5
9
|
require 'cef/event'
|
6
|
-
require 'cef/
|
10
|
+
require 'cef/loggers/cef_file'
|
11
|
+
require 'cef/loggers/cef_syslog_udp'
|
7
12
|
|
8
13
|
|
9
14
|
module CEF
|
10
|
-
|
15
|
+
def self.configure(path=File.join(ENV['HOME'],'.cef.json'))
|
16
|
+
configuration=Hashie.symbolize_keys(JSON.parse(File.read(path)))
|
17
|
+
self.logger(configuration)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.logger(config: {}, type: CEF::Loggers::SyslogUdp)
|
21
|
+
configuration = case config
|
22
|
+
when String
|
23
|
+
JSON.parse(File.read(config))
|
24
|
+
when Hash
|
25
|
+
config
|
26
|
+
when File,IO
|
27
|
+
JSON.parse(config.read)
|
28
|
+
else
|
29
|
+
fail ArgumentError, "#{config} is not a valid CEF configuration"
|
30
|
+
end
|
31
|
+
|
32
|
+
logger_type = case type
|
33
|
+
when Class
|
34
|
+
type
|
35
|
+
when String
|
36
|
+
Module.const_get(type)
|
37
|
+
else
|
38
|
+
fail ArgumentError, "#{type} is not a valid class"
|
39
|
+
end
|
40
|
+
|
41
|
+
logger_type.new(configuration)
|
42
|
+
end
|
43
|
+
def self.event(*args)
|
44
|
+
CEF::Event.new(*args)
|
45
|
+
end
|
46
|
+
end
|
data/lib/cef/event.rb
CHANGED
@@ -1,152 +1,100 @@
|
|
1
1
|
module CEF
|
2
|
-
class Event
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
2
|
+
class Event < Hashie::Dash
|
3
|
+
include Hashie::Extensions::Coercion
|
4
|
+
LOG_FORMAT = '<%d>%s %s CEF:0|%s|%s'
|
5
|
+
LOG_TIME_FORMAT = '%b %d %Y %H:%M:%S'
|
6
|
+
|
7
|
+
PREFIX_KEYS = [ :deviceVendor, :deviceProduct, :deviceVersion, :deviceEventClassId, :name, :deviceSeverity]
|
8
|
+
EXTENSION_ESCAPES = {
|
9
|
+
%r{=} => '\=',
|
10
|
+
%r{\n} => '\n',
|
11
|
+
%r{\r} => '\r',
|
12
|
+
%r{\\} => '\\'
|
13
|
+
}
|
14
|
+
|
15
|
+
PREFIX_ESCAPES = {
|
16
|
+
%r{(\||\\)} => '\\\\\&'
|
17
|
+
}
|
18
|
+
|
19
|
+
SCHEMA_CONFIG_FILE = File.join(File.expand_path(File.dirname(__FILE__)),'..','..','conf','cef-schema.json')
|
20
|
+
@@schema = config = JSON.parse(File.read(SCHEMA_CONFIG_FILE))
|
21
|
+
.extend(Hashie::Extensions::DeepMerge)
|
22
|
+
|
23
|
+
config['prefix'].each do |json_key, default_val|
|
24
|
+
self.class_eval do
|
25
|
+
key = json_key.to_sym
|
26
|
+
property key, { default: default_val, required: true }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
config['extension'].each do |key|
|
31
|
+
self.class_eval { property key.to_sym }
|
8
32
|
end
|
33
|
+
|
34
|
+
config['types'].each do |key,klass_name|
|
35
|
+
self.class_eval { coerce_key key.to_sym, Module.const_get(klass_name) }
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.schema
|
39
|
+
@@schema
|
9
40
|
end
|
10
41
|
|
11
|
-
def
|
12
|
-
|
42
|
+
def to_cef
|
43
|
+
if extension_data == {}
|
44
|
+
format('%s|',format_prefix)
|
45
|
+
else
|
46
|
+
format('%s|%s',format_prefix,format_extension)
|
47
|
+
end
|
13
48
|
end
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
@event_time = Time.new
|
18
|
-
@deviceVendor = "breed.org"
|
19
|
-
@deviceProduct = "CEF"
|
20
|
-
@deviceVersion = CEF::VERSION
|
21
|
-
@deviceEventClassId = "0:event"
|
22
|
-
@deviceSeverity = CEF::SEVERITY_LOW
|
23
|
-
@name = "unnamed event"
|
24
|
-
# used to avoid requiring syslog.h on windoze
|
25
|
-
#syslog_pri= Syslog::LOG_LOCAL0 | Syslog::LOG_NOTICE
|
26
|
-
@syslog_pri = 131
|
27
|
-
@my_hostname = Socket::gethostname
|
28
|
-
@other_attrs={}
|
29
|
-
@additional={}
|
30
|
-
Hash[*params].each { |k,v| self.send("%s="%k,v) }
|
31
|
-
yield self if block_given?
|
32
|
-
self
|
49
|
+
|
50
|
+
def format_prefix
|
51
|
+
prefix_values.map { |value| escape_prefix_value(value) }.join('|')
|
33
52
|
end
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
log_time=event_time.strftime(CEF::LOG_TIME_FORMAT)
|
38
|
-
|
39
|
-
sprintf(
|
40
|
-
CEF::LOG_FORMAT,
|
41
|
-
syslog_pri.to_s,
|
42
|
-
log_time,
|
43
|
-
my_hostname,
|
44
|
-
format_prefix,
|
45
|
-
format_extension
|
46
|
-
)
|
53
|
+
|
54
|
+
def prefix_values
|
55
|
+
[ 'CEF:0', *PREFIX_KEYS.map {|k| self.send(k) } ]
|
47
56
|
end
|
48
57
|
|
49
|
-
|
50
|
-
|
51
|
-
|
58
|
+
def format_extension
|
59
|
+
extension_keys.zip(extension_values)
|
60
|
+
.map {|k,v| format('%s=%s',k,v)}
|
61
|
+
.join(' ')
|
52
62
|
end
|
53
|
-
|
54
|
-
|
63
|
+
|
64
|
+
def extension_keys
|
65
|
+
extension_data.keys.map {|k| self.class.schema["key_names"].fetch(k.to_s,k.to_s)}
|
55
66
|
end
|
56
67
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
# bigger than epoch milliseconds when i wrote this.
|
61
|
-
# def time_convert(val)
|
62
|
-
#
|
63
|
-
# converted=case val
|
64
|
-
# when String
|
65
|
-
# if val.match(%r{\A[0-9]+\Z})
|
66
|
-
# converted=val.to_i
|
67
|
-
# else
|
68
|
-
# res=Chronic.parse(val)
|
69
|
-
# converted=Time.at(res).to_i * 1000
|
70
|
-
# end
|
71
|
-
# when Integer,Bignum
|
72
|
-
# if val < 1232589621000 #Wed Jan 21 20:00:21 -0600 2009
|
73
|
-
# val * 1000
|
74
|
-
# else
|
75
|
-
# val
|
76
|
-
# end
|
77
|
-
# end
|
78
|
-
#
|
79
|
-
# end
|
80
|
-
|
81
|
-
# escape only pipes and backslashes in the prefix. you bet your sweet
|
82
|
-
# ass there's a lot of backslashes in the substitution. you can thank
|
83
|
-
# the three levels of lexical analysis/substitution in the ruby interpreter
|
84
|
-
# for that.
|
85
|
-
|
86
|
-
def escape_prefix_value(val)
|
87
|
-
escapes={
|
88
|
-
%r{(\||\\)} => '\\\\\&'
|
89
|
-
}
|
90
|
-
escapes.reduce(val) do|memo,replace|
|
91
|
-
memo=memo.gsub(*replace)
|
92
|
-
end
|
93
|
-
end
|
68
|
+
def extension_values
|
69
|
+
extension_data.values.map {|v| escape_extension_value(v)}
|
70
|
+
end
|
94
71
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
escapes = {
|
99
|
-
%r{=} => '\=',
|
100
|
-
%r{\n} => ' ',
|
101
|
-
%r{\\} => '\\'
|
102
|
-
}
|
103
|
-
escapes.reduce(val) do |memo,replace|
|
104
|
-
memo=memo.gsub(*replace)
|
105
|
-
end
|
106
|
-
end
|
72
|
+
def extension_data
|
73
|
+
self.to_h.reject {|k,v| PREFIX_KEYS.include?(k)}
|
74
|
+
end
|
107
75
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
76
|
+
def escape_prefix_value(val)
|
77
|
+
case val
|
78
|
+
when String
|
79
|
+
PREFIX_ESCAPES.reduce(val) do|memo,replace|
|
80
|
+
memo=memo.gsub(*replace)
|
81
|
+
end
|
82
|
+
else
|
83
|
+
val.to_s
|
115
84
|
end
|
85
|
+
end
|
116
86
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
times = CEF::TIME_ATTRIBUTES.keys.map do |meth|
|
128
|
-
value = self.send(meth)
|
129
|
-
next if value.nil?
|
130
|
-
shortname = CEF::TIME_ATTRIBUTES[meth]
|
131
|
-
[shortname, escape_extension_value(value)].join("=")
|
132
|
-
end
|
133
|
-
(extensions + times).compact.join(" ")
|
87
|
+
def escape_extension_value(val)
|
88
|
+
case val
|
89
|
+
when String
|
90
|
+
EXTENSION_ESCAPES.reduce(val) do |memo,replace|
|
91
|
+
memo=memo.gsub(*replace)
|
92
|
+
end
|
93
|
+
when Time
|
94
|
+
val.to_i * 1000
|
95
|
+
else
|
96
|
+
val.to_s
|
134
97
|
end
|
98
|
+
end
|
135
99
|
end
|
136
100
|
end
|
137
|
-
|
138
|
-
# vendor= self.deviceVendor || "Breed"
|
139
|
-
# product= self.deviceProduct || "CEF Sender"
|
140
|
-
# version= self.deviceVersion || CEF::VERSION
|
141
|
-
# declid= self.deviceEventClassId || "generic:0"
|
142
|
-
# name= self.name || "Generic Event"
|
143
|
-
# sev= self.deviceSeverity || "1"
|
144
|
-
# %w{ deviceVendor deviceProduct deviceVersion deviceEvent}
|
145
|
-
# cef_prefix="%s|%s|%s|%s|%s|%s" % [
|
146
|
-
# prefix_escape(vendor),
|
147
|
-
# prefix_escape(product),
|
148
|
-
# prefix_escape(version),
|
149
|
-
# prefix_escape(declid),
|
150
|
-
# prefix_escape(name),
|
151
|
-
# prefix_escape(sev),
|
152
|
-
# ]
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module CEF
|
2
|
+
module Loggers
|
3
|
+
class CefFile
|
4
|
+
attr_accessor :path, :defaults, :append
|
5
|
+
attr_reader :fh
|
6
|
+
def initialize(*args)
|
7
|
+
Hash[*args].each {|k,v| self.send(format('%s=',k),v)}
|
8
|
+
@defaults ||= {}
|
9
|
+
@path ||= 'cef.log'
|
10
|
+
@append = false if @append.nil?
|
11
|
+
@fh = File.open(path, append ? 'w+' : 'w')
|
12
|
+
self
|
13
|
+
end
|
14
|
+
def emit(*events)
|
15
|
+
events.each {|e| fh.puts(e.to_cef)}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module CEF
|
2
|
+
module Loggers
|
3
|
+
class SyslogUdp
|
4
|
+
SYSLOG_TIME_FORMAT = '%b %d %Y %H:%M:%S'
|
5
|
+
SYSLOG_HEADER = '<%d>%s %s'
|
6
|
+
|
7
|
+
|
8
|
+
attr_accessor :receiver, :port, :defaults
|
9
|
+
attr_reader :sock
|
10
|
+
|
11
|
+
def initialize(*args)
|
12
|
+
Hash[*args].each {|k,v| self.send(format('%s=',k),v)}
|
13
|
+
@receiver ||= '127.0.0.1'
|
14
|
+
@port ||= 514
|
15
|
+
@defaults ||= {}
|
16
|
+
@sock = UDPSocket.new
|
17
|
+
@sock.connect(@receiver, @port)
|
18
|
+
self
|
19
|
+
end
|
20
|
+
|
21
|
+
def header(facility=0,priority=0)
|
22
|
+
format(SYSLOG_HEADER,
|
23
|
+
131, # facility|priority
|
24
|
+
Time.new.strftime(SYSLOG_TIME_FORMAT), # now
|
25
|
+
Socket::gethostname) # hostname
|
26
|
+
end
|
27
|
+
|
28
|
+
def formatted_message(event)
|
29
|
+
format('%s %s', header, event.to_cef )
|
30
|
+
end
|
31
|
+
|
32
|
+
def emit(*events)
|
33
|
+
events.each do |event|
|
34
|
+
defaults.each {|k,v| event.send(format("%s=",k),v) }
|
35
|
+
sock.send(formatted_message(event),0)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/cef/version.rb
CHANGED
metadata
CHANGED
@@ -1,87 +1,143 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cef
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 2.1.1.pre
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Breed
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-10-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: hashie
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: rake
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
16
30
|
requirements:
|
17
|
-
- -
|
31
|
+
- - ">="
|
18
32
|
- !ruby/object:Gem::Version
|
19
33
|
version: '0'
|
20
34
|
type: :development
|
21
35
|
prerelease: false
|
22
36
|
version_requirements: !ruby/object:Gem::Requirement
|
23
37
|
requirements:
|
24
|
-
- -
|
38
|
+
- - ">="
|
25
39
|
- !ruby/object:Gem::Version
|
26
40
|
version: '0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: rspec
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
30
44
|
requirements:
|
31
|
-
- -
|
45
|
+
- - ">="
|
32
46
|
- !ruby/object:Gem::Version
|
33
47
|
version: '0'
|
34
48
|
type: :development
|
35
49
|
prerelease: false
|
36
50
|
version_requirements: !ruby/object:Gem::Requirement
|
37
51
|
requirements:
|
38
|
-
- -
|
52
|
+
- - ">="
|
39
53
|
- !ruby/object:Gem::Version
|
40
54
|
version: '0'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: bundler
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
44
58
|
requirements:
|
45
|
-
- -
|
59
|
+
- - ">="
|
46
60
|
- !ruby/object:Gem::Version
|
47
61
|
version: '0'
|
48
62
|
type: :development
|
49
63
|
prerelease: false
|
50
64
|
version_requirements: !ruby/object:Gem::Requirement
|
51
65
|
requirements:
|
52
|
-
- -
|
66
|
+
- - ">="
|
53
67
|
- !ruby/object:Gem::Version
|
54
68
|
version: '0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: simplecov
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
58
72
|
requirements:
|
59
|
-
- -
|
73
|
+
- - ">="
|
60
74
|
- !ruby/object:Gem::Version
|
61
75
|
version: '0'
|
62
76
|
type: :development
|
63
77
|
prerelease: false
|
64
78
|
version_requirements: !ruby/object:Gem::Requirement
|
65
79
|
requirements:
|
66
|
-
- -
|
80
|
+
- - ">="
|
67
81
|
- !ruby/object:Gem::Version
|
68
82
|
version: '0'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: pry
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
72
86
|
requirements:
|
73
|
-
- -
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: guard
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: guard-bundler
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: guard-rspec
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
74
130
|
- !ruby/object:Gem::Version
|
75
131
|
version: '0'
|
76
132
|
type: :development
|
77
133
|
prerelease: false
|
78
134
|
version_requirements: !ruby/object:Gem::Requirement
|
79
135
|
requirements:
|
80
|
-
- -
|
136
|
+
- - ">="
|
81
137
|
- !ruby/object:Gem::Version
|
82
138
|
version: '0'
|
83
|
-
description:
|
84
|
-
email:
|
139
|
+
description: " format/send CEF logs via API+syslog or client program "
|
140
|
+
email: " opensource@breed.org "
|
85
141
|
executables:
|
86
142
|
- cef_sender
|
87
143
|
extensions: []
|
@@ -89,25 +145,24 @@ extra_rdoc_files:
|
|
89
145
|
- LICENSE.txt
|
90
146
|
- README.rdoc
|
91
147
|
files:
|
92
|
-
- .document
|
93
|
-
- .gitignore
|
94
|
-
- .rspec
|
148
|
+
- ".document"
|
149
|
+
- ".gitignore"
|
150
|
+
- ".rspec"
|
95
151
|
- Gemfile
|
152
|
+
- Guardfile
|
96
153
|
- LICENSE.txt
|
97
154
|
- README.rdoc
|
98
155
|
- Rakefile
|
99
156
|
- VERSION
|
100
157
|
- bin/cef_sender
|
101
158
|
- cef.gemspec
|
159
|
+
- conf/cef-schema.json
|
102
160
|
- lib/cef.rb
|
103
|
-
- lib/cef/constants.rb
|
104
161
|
- lib/cef/event.rb
|
105
|
-
- lib/cef/
|
162
|
+
- lib/cef/loggers/cef_file.rb
|
163
|
+
- lib/cef/loggers/cef_syslog_udp.rb
|
164
|
+
- lib/cef/time_extensions.rb
|
106
165
|
- lib/cef/version.rb
|
107
|
-
- spec/lib/cef/event_spec.rb
|
108
|
-
- spec/lib/cef/sender_spec.rb
|
109
|
-
- spec/lib/cef_spec.rb
|
110
|
-
- spec/spec_helper.rb
|
111
166
|
homepage: http://github.com/ryanbreed/cef
|
112
167
|
licenses:
|
113
168
|
- MIT
|
@@ -118,23 +173,18 @@ require_paths:
|
|
118
173
|
- lib
|
119
174
|
required_ruby_version: !ruby/object:Gem::Requirement
|
120
175
|
requirements:
|
121
|
-
- -
|
176
|
+
- - ">="
|
122
177
|
- !ruby/object:Gem::Version
|
123
178
|
version: '0'
|
124
179
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
125
180
|
requirements:
|
126
|
-
- -
|
181
|
+
- - ">"
|
127
182
|
- !ruby/object:Gem::Version
|
128
|
-
version:
|
183
|
+
version: 1.3.1
|
129
184
|
requirements: []
|
130
185
|
rubyforge_project:
|
131
|
-
rubygems_version: 2.
|
186
|
+
rubygems_version: 2.4.5.1
|
132
187
|
signing_key:
|
133
188
|
specification_version: 4
|
134
189
|
summary: CEF Generation Library and Client
|
135
|
-
test_files:
|
136
|
-
- spec/lib/cef/event_spec.rb
|
137
|
-
- spec/lib/cef/sender_spec.rb
|
138
|
-
- spec/lib/cef_spec.rb
|
139
|
-
- spec/spec_helper.rb
|
140
|
-
has_rdoc:
|
190
|
+
test_files: []
|