cef 1.0.0 → 2.1.1.pre
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 +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: []
|