siffer 0.0.4

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.
Files changed (91) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +65 -0
  3. data/Rakefile +64 -0
  4. data/bin/siffer +71 -0
  5. data/doc/SIF ImplementationSpecification.pdf +0 -0
  6. data/doc/rdoc/classes/Siffer.html +374 -0
  7. data/doc/rdoc/classes/Siffer/Agent.html +296 -0
  8. data/doc/rdoc/classes/Siffer/Container.html +286 -0
  9. data/doc/rdoc/classes/Siffer/Messages.html +141 -0
  10. data/doc/rdoc/classes/Siffer/Messages/Ack.html +216 -0
  11. data/doc/rdoc/classes/Siffer/Messages/Acl.html +160 -0
  12. data/doc/rdoc/classes/Siffer/Messages/Error.html +248 -0
  13. data/doc/rdoc/classes/Siffer/Messages/Message.html +359 -0
  14. data/doc/rdoc/classes/Siffer/Messages/Message/Header.html +181 -0
  15. data/doc/rdoc/classes/Siffer/Messages/Register.html +257 -0
  16. data/doc/rdoc/classes/Siffer/Messages/RequestBody.html +300 -0
  17. data/doc/rdoc/classes/Siffer/Messages/Status.html +269 -0
  18. data/doc/rdoc/classes/Siffer/Messaging.html +331 -0
  19. data/doc/rdoc/classes/Siffer/Protocol.html +388 -0
  20. data/doc/rdoc/classes/Siffer/Protocol/NonPostRequest.html +111 -0
  21. data/doc/rdoc/classes/Siffer/Protocol/UnknownPath.html +111 -0
  22. data/doc/rdoc/classes/Siffer/Registration.html +391 -0
  23. data/doc/rdoc/classes/Siffer/Request.html +209 -0
  24. data/doc/rdoc/classes/Siffer/RequestLogger.html +211 -0
  25. data/doc/rdoc/classes/Siffer/Response.html +182 -0
  26. data/doc/rdoc/classes/Siffer/Server.html +242 -0
  27. data/doc/rdoc/created.rid +1 -0
  28. data/doc/rdoc/files/LICENSE.html +129 -0
  29. data/doc/rdoc/files/README_rdoc.html +184 -0
  30. data/doc/rdoc/files/lib/agent_rb.html +101 -0
  31. data/doc/rdoc/files/lib/container_rb.html +108 -0
  32. data/doc/rdoc/files/lib/messages/ack_rb.html +101 -0
  33. data/doc/rdoc/files/lib/messages/acl_rb.html +101 -0
  34. data/doc/rdoc/files/lib/messages/error_rb.html +101 -0
  35. data/doc/rdoc/files/lib/messages/message_rb.html +101 -0
  36. data/doc/rdoc/files/lib/messages/register_rb.html +101 -0
  37. data/doc/rdoc/files/lib/messages/request_body_rb.html +101 -0
  38. data/doc/rdoc/files/lib/messages/status_rb.html +101 -0
  39. data/doc/rdoc/files/lib/messages_rb.html +114 -0
  40. data/doc/rdoc/files/lib/messaging_rb.html +101 -0
  41. data/doc/rdoc/files/lib/protocol_rb.html +101 -0
  42. data/doc/rdoc/files/lib/registration_rb.html +101 -0
  43. data/doc/rdoc/files/lib/request_logger_rb.html +101 -0
  44. data/doc/rdoc/files/lib/request_rb.html +101 -0
  45. data/doc/rdoc/files/lib/response_rb.html +101 -0
  46. data/doc/rdoc/files/lib/server_rb.html +101 -0
  47. data/doc/rdoc/files/lib/siffer_rb.html +115 -0
  48. data/doc/rdoc/fr_class_index.html +47 -0
  49. data/doc/rdoc/fr_file_index.html +46 -0
  50. data/doc/rdoc/fr_method_index.html +96 -0
  51. data/doc/rdoc/index.html +24 -0
  52. data/doc/rdoc/rdoc-style.css +208 -0
  53. data/lib/agent.rb +43 -0
  54. data/lib/container.rb +96 -0
  55. data/lib/messages.rb +7 -0
  56. data/lib/messages/ack.rb +43 -0
  57. data/lib/messages/acl.rb +25 -0
  58. data/lib/messages/error.rb +174 -0
  59. data/lib/messages/message.rb +71 -0
  60. data/lib/messages/register.rb +60 -0
  61. data/lib/messages/request_body.rb +66 -0
  62. data/lib/messages/status.rb +55 -0
  63. data/lib/messaging.rb +96 -0
  64. data/lib/protocol.rb +159 -0
  65. data/lib/registration.rb +87 -0
  66. data/lib/request.rb +25 -0
  67. data/lib/request_logger.rb +31 -0
  68. data/lib/response.rb +26 -0
  69. data/lib/server.rb +40 -0
  70. data/lib/siffer.rb +44 -0
  71. data/spec/agent_spec.rb +53 -0
  72. data/spec/cli_spec.rb +40 -0
  73. data/spec/container_spec.rb +103 -0
  74. data/spec/default_agent +6 -0
  75. data/spec/default_server +5 -0
  76. data/spec/message_specs/ack_spec.rb +28 -0
  77. data/spec/message_specs/error_spec.rb +24 -0
  78. data/spec/message_specs/header_spec.rb +25 -0
  79. data/spec/message_specs/message_spec.rb +57 -0
  80. data/spec/message_specs/register_spec.rb +86 -0
  81. data/spec/message_specs/request_body_spec.rb +58 -0
  82. data/spec/message_specs/status_spec.rb +25 -0
  83. data/spec/messaging_spec.rb +88 -0
  84. data/spec/protocol_spec.rb +49 -0
  85. data/spec/registration_spec.rb +33 -0
  86. data/spec/request_logger_spec.rb +15 -0
  87. data/spec/request_spec.rb +10 -0
  88. data/spec/response_spec.rb +24 -0
  89. data/spec/server_spec.rb +35 -0
  90. data/spec/spec_helper.rb +26 -0
  91. metadata +191 -0
@@ -0,0 +1,88 @@
1
+ require File.join(File.dirname(__FILE__),"spec_helper")
2
+
3
+ # The messaging is best tested doing a full request/response
4
+ # cycle using both Server and Agent components
5
+
6
+ [Siffer::Server, Siffer::Agent].each do |component|
7
+
8
+ # Stage the component a little bit:
9
+ # Agents require Servers
10
+ # Both require central-admin
11
+ component = component.new("admin" => 'none', "servers" => '')
12
+ msg = Siffer::Messages::Message.new("source")
13
+ msg.content do |xml|
14
+ xml.SIF_BogusType
15
+ end
16
+
17
+ describe component, "Messaging - response" do
18
+ it "should always return Ack for proper SIF_Messages" do
19
+ for_every_path(:on => component, :input => msg) do |res|
20
+ res.body.should match(/SIF_Ack/)
21
+ end
22
+ end
23
+ end
24
+
25
+ describe component, "Messaging - content-type" do
26
+ it "should always respond with application/xml" do
27
+ for_every_path(:on => component, :input => msg) do |res|
28
+ res.content_type.should == Siffer::Messaging::MIME_TYPES["appxml"]
29
+ end
30
+ end
31
+
32
+ it "should only receive application/xml" do
33
+ for_every_path(:on => component,"CONTENT_TYPE" => "x") do |res|
34
+ res.should be_client_error
35
+ res.status.should == 406
36
+ end
37
+ end
38
+ end
39
+
40
+ describe component, "Messaging - validation" do
41
+
42
+ it "should return Xml Error code for bad message (xml)" do
43
+ %w[<Junk>>>> <Junk> </Junk> Junk !@ex].each do |msg|
44
+ for_every_path(:on => component, :input => msg) do |res|
45
+ res.body.should match(/SIF_Error/)
46
+ res.body.should match(/SIF_Category>1<\/SIF_Category/)
47
+ res.body.should match(/SIF_Code>2<\/SIF_Code>/)
48
+ res.body.should match(/Message is not well-formed/)
49
+ # spec says Oringals should be included and empty
50
+ res.body.should match(/SIF_OriginalSourceId\s*\/>/)
51
+ res.body.should match(/SIF_OriginalMsgId\s*\/>/)
52
+ end
53
+ end
54
+ end
55
+
56
+ it "should validaate message is SIF_Message" do
57
+ msg = "<someotherkind><of>XML</of></someotherkind>"
58
+ for_every_path(:on => component, :input => msg) do |res|
59
+ res.body.should match(/SIF_Category>12/)
60
+ res.body.should match(/SIF_Code>2/)
61
+ end
62
+ end
63
+
64
+ it "should validate message xmlns" do
65
+ msg = Siffer::Messages::Register.new(
66
+ "bad-xmlns",
67
+ component.name,
68
+ :xmlns => 'http://bogus.xmlns')
69
+ for_every_path(:on => component, :input => msg) do |res|
70
+ res.body.should match(/SIF_Category>1<\/SIF_Category/)
71
+ res.body.should match(/SIF_Code>4<\/SIF_Code/)
72
+ res.body.should match(/SIF_ExtendedDesc>XMLNS not compatible with SIF/)
73
+ end
74
+ end
75
+
76
+ it "should validate SIF version" do
77
+ msg = Siffer::Messages::Register.new(
78
+ "bad-version",
79
+ component.name,
80
+ :version => '99.99')
81
+ for_every_path(:on => component, :input => msg) do |res|
82
+ res.body.should match(/SIF_Category>12<\/SIF_Category/)
83
+ res.body.should match(/SIF_Code>3<\/SIF_Code>/)
84
+ end
85
+ end
86
+ end
87
+
88
+ end
@@ -0,0 +1,49 @@
1
+ require File.join(File.dirname(__FILE__), "spec_helper")
2
+
3
+ [Siffer::Server, Siffer::Agent].each do |component|
4
+
5
+ # Stage the component a little bit:
6
+ # Agents require Servers
7
+ # Both require central-admin
8
+ component = component.new("admin" => 'none', "servers" => '')
9
+ # setup messages to use for mock requests
10
+ ping = "<SIF_Message><SIF_SystemControl><SIF_Ping /></SIF_SystemControl></SIF_Message>"
11
+ status = "<SIF_Message><SIF_SystemControl><SIF_Status /></SIF_SystemControl></SIF_Message>"
12
+ register = "<SIF_Message><SIF_Register /></SIF_Message>"
13
+
14
+ describe component, "Protocol - /unknown_path" do
15
+ it "should return 404" do
16
+ res = Rack::MockRequest.new(component).post("/bad_path")
17
+ res.should be_not_found
18
+ end
19
+ end
20
+
21
+ describe component, "Protocol - Accepted Paths" do
22
+ it "should only allow POST method" do
23
+ Siffer::Protocol::ACCEPTABLE_PATHS.each do |name,path|
24
+ res = Rack::MockRequest.new(component).get(path)
25
+ res.should be_client_error
26
+ end
27
+ end
28
+
29
+ it "should be identified by predicate through body" do
30
+ Siffer::Protocol::ACCEPTABLE_PATHS.each do |name,path|
31
+ unless name == :root
32
+ component.call({"rack.input" => eval(name.to_s)})
33
+ component.should eval("be_#{name.to_s}")
34
+ end
35
+ end
36
+ end
37
+
38
+ it "should be identified by predicate through path-info" do
39
+ Siffer::Protocol::ACCEPTABLE_PATHS.each do |name,path|
40
+ unless name == :root
41
+ component.call({
42
+ "rack.input" => "<SIF_Message><SIF_#{name.to_s} /></SIF_Message>",
43
+ "PATH_INFO" => path})
44
+ component.should eval("be_#{name.to_s}")
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,33 @@
1
+ require File.join(File.dirname(__FILE__),"spec_helper")
2
+
3
+ # Registration is best tested through the Siffer::Server component
4
+
5
+ describe Siffer::Registration do
6
+
7
+ before(:each) do
8
+ @server = Siffer::Server.new("admin" => "none")
9
+ end
10
+
11
+ it "should determine agent registration" do
12
+ @server.registered?("Default Agent").should be_false
13
+ @server.agents["Default Agent"] = "http://localhost"
14
+ @server.registered?("Default Agent").should be_true
15
+ end
16
+
17
+ it "should return not registered message for non-registered agents" do
18
+ msg = Siffer::Messages::Message.new("Default Agent")
19
+ msg.content do |xml|
20
+ xml.SIF_Ping
21
+ end
22
+ res = Rack::MockRequest.new(@server).post("/",:input => msg)
23
+ res.body.should match(/SIF_Category>4/)
24
+ res.body.should match(/SIF_Code>9/)
25
+ end
26
+
27
+ it "should return ACL for successful registration" do
28
+ msg = Siffer::Messages::Register.new("Default Agent", "Default Agent")
29
+ res = Rack::MockRequest.new(@server).post("/",:input => msg)
30
+ res.body.should match(/SIF_Ack/)
31
+ res.body.should match(/SIF_Status/)
32
+ end
33
+ end
@@ -0,0 +1,15 @@
1
+ require File.join(File.dirname(__FILE__),"spec_helper")
2
+
3
+ describe Siffer::RequestLogger do
4
+ msg = "<SIF_Message><SIF_SystemControl><SIF_Ping /></SIF_SystemControl></SIF_Message>"
5
+
6
+ it "should log requests" do
7
+ log = []
8
+ app = Rack::Builder.new do
9
+ use Siffer::RequestLogger, log
10
+ run Siffer::Server.new("admin" => "none")
11
+ end
12
+ res = Rack::MockRequest.new(app).post("/", :input => msg)
13
+ log.size.should == 1
14
+ end
15
+ end
@@ -0,0 +1,10 @@
1
+ require File.join(File.dirname(__FILE__), "spec_helper")
2
+
3
+ describe Siffer::Request do
4
+ it "should provide access to the body as a SIF_Message (Siffer::Message)" do
5
+ msg = Siffer::Messages::Register.new("register-source","source-name")
6
+ request = Siffer::Request.new('rack.input' => msg)
7
+ request.message.type.should == "Register"
8
+ request.message.source_id.should == "register-source"
9
+ end
10
+ end
@@ -0,0 +1,24 @@
1
+ require File.join(File.dirname(__FILE__),"spec_helper")
2
+ require 'webrick'
3
+
4
+ Thread.abort_on_exception = true
5
+
6
+ describe Siffer::Response do
7
+ it "should default content-type to application/xml" do
8
+ response = Siffer::Response.new()
9
+ response.content_type.should == Siffer::Messaging::MIME_TYPES["appxml"]
10
+ end
11
+
12
+ it "should receive response from url,data" do
13
+ with_fake_server do |url|
14
+ response = Siffer::Response.from(url,"Hello World")
15
+ response.should be_successful
16
+ response.body.each { |line| line.should == "Hello World" }
17
+ end
18
+ end
19
+
20
+ it "should return 500 for bad url" do
21
+ response = Siffer::Response.from("http://localhost:9999","Hello World")
22
+ response.should be_server_error
23
+ end
24
+ end
@@ -0,0 +1,35 @@
1
+ require File.join(File.dirname(__FILE__), "spec_helper")
2
+
3
+ describe Siffer::Server do
4
+ it "should instantiate with default host, port, name, min_buffer" do
5
+ server = Siffer::Server.new("admin" => 'none')
6
+ server.host.should == "localhost"
7
+ server.port.should == 8300
8
+ server.name.should == "Default Server"
9
+ server.min_buffer.should == 1024
10
+ end
11
+
12
+ it "should allow defaults to be overriden" do
13
+ server = Siffer::Server.new("admin" => 'none',
14
+ "name" => "name",
15
+ "host" => "test",
16
+ "port" => 222,
17
+ "min_buffer" => 2048)
18
+ server.host.should == "test"
19
+ server.port.should == 222
20
+ server.name.should == "name"
21
+ server.min_buffer.should == 2048
22
+ end
23
+
24
+ it "should require an admin URL" do
25
+ lambda {
26
+ server = Siffer::Server.new
27
+ }.should raise_error("Administration URL required")
28
+ end
29
+
30
+ it "should respond to uri" do
31
+ server = Siffer::Server.new("admin" => 'none')
32
+ server.uri.should == "http://localhost:8300"
33
+ end
34
+
35
+ end
@@ -0,0 +1,26 @@
1
+ require File.join(File.dirname(__FILE__),"..", "lib","siffer")
2
+ require 'spec'
3
+
4
+ # Configures a WEBrick server and yields URL. When passed a block
5
+ # starts and stops the server for the context. It returns what it
6
+ # receives from the request.
7
+ def with_fake_server(app = nil)
8
+ fake_app = app || lambda { |env| [200,{},env["rack.input"].read] }
9
+ server = WEBrick::HTTPServer.new(:Host => '0.0.0.0',:Port => 9202)
10
+ server.mount "/", Rack::Handler::WEBrick, fake_app
11
+ Thread.new { server.start }
12
+ trap(:INT) { server.shutdown }
13
+ yield "http://localhost:9202/" if block_given?
14
+ server.shutdown
15
+ end
16
+
17
+ # Helper method to iterate all of the ACCEPTABLE_PATHS
18
+ # on the specified component(Server/Agent). Yields
19
+ # the Response object for each Request.
20
+ def for_every_path(options = {}, &block)
21
+ component = options.delete(:on)
22
+ Siffer::Protocol::ACCEPTABLE_PATHS.each do |name,path|
23
+ res = Rack::MockRequest.new(component).post(path,options)
24
+ yield res
25
+ end
26
+ end
metadata ADDED
@@ -0,0 +1,191 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: siffer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.4
5
+ platform: ruby
6
+ authors:
7
+ - Clint Hill
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-01-19 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: uuid
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: rack
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: hpricot
37
+ type: :runtime
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "0"
44
+ version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: builder
47
+ type: :runtime
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: "0"
54
+ version:
55
+ description:
56
+ email: clint.hill@h3osoftware.com
57
+ executables:
58
+ - siffer
59
+ extensions: []
60
+
61
+ extra_rdoc_files: []
62
+
63
+ files:
64
+ - LICENSE
65
+ - README.rdoc
66
+ - Rakefile
67
+ - spec/agent_spec.rb
68
+ - spec/cli_spec.rb
69
+ - spec/container_spec.rb
70
+ - spec/default_agent
71
+ - spec/default_server
72
+ - spec/message_specs
73
+ - spec/message_specs/ack_spec.rb
74
+ - spec/message_specs/error_spec.rb
75
+ - spec/message_specs/header_spec.rb
76
+ - spec/message_specs/message_spec.rb
77
+ - spec/message_specs/register_spec.rb
78
+ - spec/message_specs/request_body_spec.rb
79
+ - spec/message_specs/status_spec.rb
80
+ - spec/messaging_spec.rb
81
+ - spec/protocol_spec.rb
82
+ - spec/registration_spec.rb
83
+ - spec/request_logger_spec.rb
84
+ - spec/request_spec.rb
85
+ - spec/response_spec.rb
86
+ - spec/server_spec.rb
87
+ - spec/spec_helper.rb
88
+ - lib/agent.rb
89
+ - lib/container.rb
90
+ - lib/messages
91
+ - lib/messages/ack.rb
92
+ - lib/messages/acl.rb
93
+ - lib/messages/error.rb
94
+ - lib/messages/message.rb
95
+ - lib/messages/register.rb
96
+ - lib/messages/request_body.rb
97
+ - lib/messages/status.rb
98
+ - lib/messages.rb
99
+ - lib/messaging.rb
100
+ - lib/protocol.rb
101
+ - lib/registration.rb
102
+ - lib/request.rb
103
+ - lib/request_logger.rb
104
+ - lib/response.rb
105
+ - lib/server.rb
106
+ - lib/siffer.rb
107
+ - doc/rdoc
108
+ - doc/rdoc/classes
109
+ - doc/rdoc/classes/Siffer
110
+ - doc/rdoc/classes/Siffer/Agent.html
111
+ - doc/rdoc/classes/Siffer/Container.html
112
+ - doc/rdoc/classes/Siffer/Messages
113
+ - doc/rdoc/classes/Siffer/Messages/Ack.html
114
+ - doc/rdoc/classes/Siffer/Messages/Acl.html
115
+ - doc/rdoc/classes/Siffer/Messages/Error.html
116
+ - doc/rdoc/classes/Siffer/Messages/Message
117
+ - doc/rdoc/classes/Siffer/Messages/Message/Header.html
118
+ - doc/rdoc/classes/Siffer/Messages/Message.html
119
+ - doc/rdoc/classes/Siffer/Messages/Register.html
120
+ - doc/rdoc/classes/Siffer/Messages/RequestBody.html
121
+ - doc/rdoc/classes/Siffer/Messages/Status.html
122
+ - doc/rdoc/classes/Siffer/Messages.html
123
+ - doc/rdoc/classes/Siffer/Messaging.html
124
+ - doc/rdoc/classes/Siffer/Protocol
125
+ - doc/rdoc/classes/Siffer/Protocol/NonPostRequest.html
126
+ - doc/rdoc/classes/Siffer/Protocol/UnknownPath.html
127
+ - doc/rdoc/classes/Siffer/Protocol.html
128
+ - doc/rdoc/classes/Siffer/Registration.html
129
+ - doc/rdoc/classes/Siffer/Request.html
130
+ - doc/rdoc/classes/Siffer/RequestLogger.html
131
+ - doc/rdoc/classes/Siffer/Response.html
132
+ - doc/rdoc/classes/Siffer/Server.html
133
+ - doc/rdoc/classes/Siffer.html
134
+ - doc/rdoc/created.rid
135
+ - doc/rdoc/files
136
+ - doc/rdoc/files/lib
137
+ - doc/rdoc/files/lib/agent_rb.html
138
+ - doc/rdoc/files/lib/container_rb.html
139
+ - doc/rdoc/files/lib/messages
140
+ - doc/rdoc/files/lib/messages/ack_rb.html
141
+ - doc/rdoc/files/lib/messages/acl_rb.html
142
+ - doc/rdoc/files/lib/messages/error_rb.html
143
+ - doc/rdoc/files/lib/messages/message_rb.html
144
+ - doc/rdoc/files/lib/messages/register_rb.html
145
+ - doc/rdoc/files/lib/messages/request_body_rb.html
146
+ - doc/rdoc/files/lib/messages/status_rb.html
147
+ - doc/rdoc/files/lib/messages_rb.html
148
+ - doc/rdoc/files/lib/messaging_rb.html
149
+ - doc/rdoc/files/lib/protocol_rb.html
150
+ - doc/rdoc/files/lib/registration_rb.html
151
+ - doc/rdoc/files/lib/request_logger_rb.html
152
+ - doc/rdoc/files/lib/request_rb.html
153
+ - doc/rdoc/files/lib/response_rb.html
154
+ - doc/rdoc/files/lib/server_rb.html
155
+ - doc/rdoc/files/lib/siffer_rb.html
156
+ - doc/rdoc/files/LICENSE.html
157
+ - doc/rdoc/files/README_rdoc.html
158
+ - doc/rdoc/fr_class_index.html
159
+ - doc/rdoc/fr_file_index.html
160
+ - doc/rdoc/fr_method_index.html
161
+ - doc/rdoc/index.html
162
+ - doc/rdoc/rdoc-style.css
163
+ - doc/SIF ImplementationSpecification.pdf
164
+ has_rdoc: false
165
+ homepage: http://h3osoftware.com/siffer
166
+ post_install_message:
167
+ rdoc_options: []
168
+
169
+ require_paths:
170
+ - lib
171
+ required_ruby_version: !ruby/object:Gem::Requirement
172
+ requirements:
173
+ - - ">="
174
+ - !ruby/object:Gem::Version
175
+ version: "0"
176
+ version:
177
+ required_rubygems_version: !ruby/object:Gem::Requirement
178
+ requirements:
179
+ - - ">="
180
+ - !ruby/object:Gem::Version
181
+ version: "0"
182
+ version:
183
+ requirements: []
184
+
185
+ rubyforge_project: siffer
186
+ rubygems_version: 1.3.1
187
+ signing_key:
188
+ specification_version: 2
189
+ summary: Siffer - School Interoperability Framework by h3o(software)
190
+ test_files: []
191
+