siffer 0.0.5 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +1 -1
- data/README +93 -0
- data/lib/siffer.rb +13 -16
- data/lib/siffer/agent.rb +39 -31
- data/lib/siffer/core_ext/hash.rb +15 -0
- data/lib/siffer/messages.rb +38 -4
- data/lib/siffer/messages/ack.rb +160 -35
- data/lib/siffer/messages/event.rb +20 -0
- data/lib/siffer/messages/message.rb +47 -58
- data/lib/siffer/messages/provide.rb +25 -0
- data/lib/siffer/messages/provision.rb +17 -0
- data/lib/siffer/messages/register.rb +42 -52
- data/lib/siffer/messages/request.rb +138 -0
- data/lib/siffer/messages/response.rb +48 -0
- data/lib/siffer/messages/subscribe.rb +17 -0
- data/lib/siffer/messages/system_control.rb +94 -0
- data/lib/siffer/models.rb +1 -0
- data/lib/siffer/models/address.rb +39 -0
- metadata +25 -146
- data/README.rdoc +0 -65
- data/Rakefile +0 -64
- data/bin/siffer +0 -71
- data/doc/SIF ImplementationSpecification.pdf +0 -0
- data/doc/rdoc/classes/Siffer.html +0 -259
- data/doc/rdoc/classes/Siffer/Agent.html +0 -177
- data/doc/rdoc/classes/Siffer/Container.html +0 -165
- data/doc/rdoc/classes/Siffer/Messages.html +0 -81
- data/doc/rdoc/classes/Siffer/Messages/Ack.html +0 -115
- data/doc/rdoc/classes/Siffer/Messages/Acl.html +0 -83
- data/doc/rdoc/classes/Siffer/Messages/Error.html +0 -157
- data/doc/rdoc/classes/Siffer/Messages/Message.html +0 -235
- data/doc/rdoc/classes/Siffer/Messages/Message/Header.html +0 -107
- data/doc/rdoc/classes/Siffer/Messages/Register.html +0 -154
- data/doc/rdoc/classes/Siffer/Messages/RequestBody.html +0 -185
- data/doc/rdoc/classes/Siffer/Messages/Status.html +0 -156
- data/doc/rdoc/classes/Siffer/Messaging.html +0 -212
- data/doc/rdoc/classes/Siffer/Protocol.html +0 -254
- data/doc/rdoc/classes/Siffer/Protocol/NonPostRequest.html +0 -54
- data/doc/rdoc/classes/Siffer/Protocol/UnknownPath.html +0 -54
- data/doc/rdoc/classes/Siffer/Registration.html +0 -251
- data/doc/rdoc/classes/Siffer/Request.html +0 -103
- data/doc/rdoc/classes/Siffer/RequestLogger.html +0 -109
- data/doc/rdoc/classes/Siffer/Response.html +0 -91
- data/doc/rdoc/classes/Siffer/Server.html +0 -156
- data/doc/rdoc/created.rid +0 -1
- data/doc/rdoc/files/LICENSE.html +0 -76
- data/doc/rdoc/files/README_rdoc.html +0 -131
- data/doc/rdoc/files/lib/siffer/agent_rb.html +0 -49
- data/doc/rdoc/files/lib/siffer/container_rb.html +0 -57
- data/doc/rdoc/files/lib/siffer/messages/ack_rb.html +0 -49
- data/doc/rdoc/files/lib/siffer/messages/acl_rb.html +0 -49
- data/doc/rdoc/files/lib/siffer/messages/error_rb.html +0 -49
- data/doc/rdoc/files/lib/siffer/messages/message_rb.html +0 -49
- data/doc/rdoc/files/lib/siffer/messages/register_rb.html +0 -49
- data/doc/rdoc/files/lib/siffer/messages/request_body_rb.html +0 -49
- data/doc/rdoc/files/lib/siffer/messages/status_rb.html +0 -49
- data/doc/rdoc/files/lib/siffer/messages_rb.html +0 -63
- data/doc/rdoc/files/lib/siffer/messaging_rb.html +0 -49
- data/doc/rdoc/files/lib/siffer/protocol_rb.html +0 -49
- data/doc/rdoc/files/lib/siffer/registration_rb.html +0 -49
- data/doc/rdoc/files/lib/siffer/request_logger_rb.html +0 -49
- data/doc/rdoc/files/lib/siffer/request_rb.html +0 -49
- data/doc/rdoc/files/lib/siffer/response_rb.html +0 -49
- data/doc/rdoc/files/lib/siffer/server_rb.html +0 -49
- data/doc/rdoc/files/lib/siffer_rb.html +0 -64
- data/doc/rdoc/fr_class_index.html +0 -25
- data/doc/rdoc/fr_file_index.html +0 -39
- data/doc/rdoc/fr_method_index.html +0 -4539
- data/doc/rdoc/index.html +0 -15
- data/doc/rdoc/rdoc-style.css +0 -319
- data/lib/siffer/container.rb +0 -94
- data/lib/siffer/messages/acl.rb +0 -25
- data/lib/siffer/messages/error.rb +0 -174
- data/lib/siffer/messages/request_body.rb +0 -66
- data/lib/siffer/messages/status.rb +0 -55
- data/lib/siffer/messaging.rb +0 -99
- data/lib/siffer/protocol.rb +0 -164
- data/lib/siffer/registration.rb +0 -87
- data/lib/siffer/request.rb +0 -28
- data/lib/siffer/request_logger.rb +0 -32
- data/lib/siffer/response.rb +0 -26
- data/lib/siffer/server.rb +0 -42
- data/spec/agent_spec.rb +0 -48
- data/spec/cli_spec.rb +0 -40
- data/spec/container_spec.rb +0 -103
- data/spec/default_agent +0 -6
- data/spec/default_server +0 -5
- data/spec/message_specs/ack_spec.rb +0 -28
- data/spec/message_specs/error_spec.rb +0 -24
- data/spec/message_specs/header_spec.rb +0 -25
- data/spec/message_specs/message_spec.rb +0 -57
- data/spec/message_specs/register_spec.rb +0 -86
- data/spec/message_specs/request_body_spec.rb +0 -58
- data/spec/message_specs/status_spec.rb +0 -25
- data/spec/messaging_spec.rb +0 -85
- data/spec/protocol_spec.rb +0 -50
- data/spec/registration_spec.rb +0 -33
- data/spec/request_logger_spec.rb +0 -28
- data/spec/request_spec.rb +0 -25
- data/spec/response_spec.rb +0 -24
- data/spec/server_spec.rb +0 -30
- data/spec/spec_helper.rb +0 -35
@@ -1,174 +0,0 @@
|
|
1
|
-
module Siffer
|
2
|
-
module Messages
|
3
|
-
class Error
|
4
|
-
|
5
|
-
attr_reader :category, :code, :description
|
6
|
-
|
7
|
-
def initialize(category, code, desc = nil)
|
8
|
-
@category = CATEGORY[category]
|
9
|
-
@category_index = category
|
10
|
-
@code = CODE[@category][code]
|
11
|
-
@code_index = code
|
12
|
-
@description = desc
|
13
|
-
end
|
14
|
-
|
15
|
-
def read
|
16
|
-
xml = Builder::XmlMarkup.new
|
17
|
-
xml.SIF_Error { |error|
|
18
|
-
error.SIF_Category(@category_index)
|
19
|
-
error.SIF_Code(@code_index)
|
20
|
-
error.SIF_Desc(@code)
|
21
|
-
error.SIF_ExtendedDesc(@description) unless @description.nil?
|
22
|
-
}
|
23
|
-
end
|
24
|
-
alias :to_str :read
|
25
|
-
|
26
|
-
|
27
|
-
# Categories of Errors specified by SIF
|
28
|
-
CATEGORY = [
|
29
|
-
"Unknown (This should NEVER be used if possible)",
|
30
|
-
"XML Validation",
|
31
|
-
"Encryption",
|
32
|
-
"Authentication",
|
33
|
-
"Access and Permissions",
|
34
|
-
"Registration",
|
35
|
-
"Provision",
|
36
|
-
"Subscription",
|
37
|
-
"Request and Response",
|
38
|
-
"Event Reporting and Processing",
|
39
|
-
"Transport",
|
40
|
-
"System (OS, Database, Vendor localized, etc.)",
|
41
|
-
"Generic Message Handling",
|
42
|
-
"SMB Handling"
|
43
|
-
]
|
44
|
-
|
45
|
-
# Codes related to CATEGORY
|
46
|
-
# Some codes are blank to match the SIF Spec
|
47
|
-
CODE = {
|
48
|
-
CATEGORY[1] => [ # Xml Validation
|
49
|
-
"",
|
50
|
-
"Generic error",
|
51
|
-
"Message is not well-formed",
|
52
|
-
"Generic validation error",
|
53
|
-
"Invalid value for element/attribute",
|
54
|
-
"",
|
55
|
-
"Missing mandatory element/attribute"
|
56
|
-
],
|
57
|
-
CATEGORY[2] => [ # Encryption
|
58
|
-
"",
|
59
|
-
"Generic error"
|
60
|
-
],
|
61
|
-
CATEGORY[3] => [ # Authentication
|
62
|
-
"",
|
63
|
-
"Generic error",
|
64
|
-
"Generic authentication error (with signature)",
|
65
|
-
"Missing sender's certificate",
|
66
|
-
"Invalid certificate",
|
67
|
-
"Sender's certificate is not trusted",
|
68
|
-
"Expired certificate",
|
69
|
-
"Invalid signature",
|
70
|
-
"Invalid encryption algorithm (only accepts MD4)",
|
71
|
-
"Missing public key of the receiver (when decrypting message)",
|
72
|
-
"Missing receiver's private key (when decrypting message)"
|
73
|
-
],
|
74
|
-
CATEGORY[4] => [ # Access and Permissions
|
75
|
-
"",
|
76
|
-
"Generic error",
|
77
|
-
"No permission to register",
|
78
|
-
"No permission to provide this object",
|
79
|
-
"No permission to subscribe to this SIF_Event",
|
80
|
-
"No permission to request this object",
|
81
|
-
"No permission to respond to this object request",
|
82
|
-
"No permission to publish SIF_Event",
|
83
|
-
"No permission to administer policies",
|
84
|
-
"SIF_SourceId is not registered",
|
85
|
-
"No permission to publish SIF_Event Add",
|
86
|
-
"No permission to publish SIF_Event Change",
|
87
|
-
"No permission to publish SIF_Event Delete"
|
88
|
-
],
|
89
|
-
CATEGORY[5] => [ # Registration
|
90
|
-
"",
|
91
|
-
"Generic error",
|
92
|
-
"The SIF_SourceId is invalid",
|
93
|
-
"Requested transport protocol is unsupported",
|
94
|
-
"Requested SIF_Version(s) not supported",
|
95
|
-
"",
|
96
|
-
"Requested SIF_MaxBufferSize is too small",
|
97
|
-
"ZIS requires a secure transport",
|
98
|
-
"",
|
99
|
-
"Agent is registered for push mode (returned when a push-mode agent sends a SIF_GetMessage)",
|
100
|
-
"ZIS does not support the requested Accept-Encoding value"
|
101
|
-
],
|
102
|
-
CATEGORY[6] => [ # Provision
|
103
|
-
"",
|
104
|
-
"Generic error",
|
105
|
-
"",
|
106
|
-
"Invalid object",
|
107
|
-
"Object already has a provider (SIF_Provide message)"
|
108
|
-
],
|
109
|
-
CATEGORY[7] => [ # Subscription
|
110
|
-
"",
|
111
|
-
"Generic error",
|
112
|
-
"",
|
113
|
-
"Invalid object"
|
114
|
-
],
|
115
|
-
CATEGORY[8] => [ # Request and Response
|
116
|
-
"",
|
117
|
-
"Generic error",
|
118
|
-
"",
|
119
|
-
"Invalid object",
|
120
|
-
"No provider",
|
121
|
-
"",
|
122
|
-
"",
|
123
|
-
"Responder does not support requested SIF_Version",
|
124
|
-
"Responder does not support requested SIF_MaxBufferSize",
|
125
|
-
"Unsupported query in request",
|
126
|
-
"Invalid SIF_RequestMsgId specified in SIF_Response",
|
127
|
-
"SIF_Response is larger than requested SIF_MaxBufferSize",
|
128
|
-
"SIF_PacketNumber is invalid in SIF_Response",
|
129
|
-
"SIF_Response does not match any SIF_Version from SIF_Request",
|
130
|
-
"SIF_DestinationId does not match SIF_SourceId from SIF_Request",
|
131
|
-
"No support for SIF_ExtendedQuery",
|
132
|
-
"SIF_RequestMsgId deleted from cache due to timeout",
|
133
|
-
"SIF_RequestMsgId deleted from cache by administrator",
|
134
|
-
"SIF_Request cancelled by requesting agent"
|
135
|
-
],
|
136
|
-
CATEGORY[9] => [ # Event Reporting and Processing
|
137
|
-
"",
|
138
|
-
"Generic error",
|
139
|
-
"",
|
140
|
-
"Invalid event"
|
141
|
-
],
|
142
|
-
CATEGORY[10] => [ # Transport
|
143
|
-
"",
|
144
|
-
"Generic error",
|
145
|
-
"Requested protocol is not supported",
|
146
|
-
"Secure channel requested and no secure path exists",
|
147
|
-
"Unable to establish connection"
|
148
|
-
],
|
149
|
-
CATEGORY[11] => [ # System
|
150
|
-
"",
|
151
|
-
"Generic Error"
|
152
|
-
],
|
153
|
-
CATEGORY[12] => [ # Generic Message Handling
|
154
|
-
"",
|
155
|
-
"Generic error",
|
156
|
-
"Message not supported",
|
157
|
-
"Version not supported",
|
158
|
-
"Context not supported",
|
159
|
-
"Protocol error",
|
160
|
-
"No such message (as identified by SIF_OriginalMsgId)",
|
161
|
-
"Multiple contexts not supported"
|
162
|
-
],
|
163
|
-
CATEGORY[13] => [ # SMB Handling
|
164
|
-
"",
|
165
|
-
"Generic error",
|
166
|
-
"SMB can only be invoked during a SIF_Event acknowledgement",
|
167
|
-
"Final SIF_Ack expected from Push-Mode Agent",
|
168
|
-
"Incorrect SIF_MsgId in final SIF_Ack"
|
169
|
-
]
|
170
|
-
}
|
171
|
-
|
172
|
-
end
|
173
|
-
end
|
174
|
-
end
|
@@ -1,66 +0,0 @@
|
|
1
|
-
module Siffer
|
2
|
-
|
3
|
-
module Messages
|
4
|
-
|
5
|
-
# This class is used to parse the SIF Message information
|
6
|
-
# out of the Request Body. It parses enough information to redirect
|
7
|
-
# to other processes. It does not parse details of the Message such as
|
8
|
-
# Protocol if a Register message, or Error if an Ack message. Each
|
9
|
-
# message type will inherit this class in order to provide a #parse
|
10
|
-
# method that will allow access to those specific attributes.
|
11
|
-
# It provides access to:
|
12
|
-
# * source_id
|
13
|
-
# * msg_id
|
14
|
-
# * type
|
15
|
-
class RequestBody
|
16
|
-
|
17
|
-
def initialize(xml_string)
|
18
|
-
@xml = xml_string
|
19
|
-
@doc = Hpricot(@xml, :xml => true)
|
20
|
-
end
|
21
|
-
|
22
|
-
# Will return the name of the element found just inside the root
|
23
|
-
# or just inside SIF_SystemControl if present.
|
24
|
-
def type
|
25
|
-
begin
|
26
|
-
msg_type = (@doc/:SIF_Message).first.children[0].name
|
27
|
-
if msg_type == "SIF_SystemControl"
|
28
|
-
msg_type = (@doc/:SIF_Message/:SIF_SystemControl).first.children[0].name
|
29
|
-
end
|
30
|
-
drop_sif msg_type
|
31
|
-
rescue
|
32
|
-
raise "Failed to parse #{@xml} for SIF Type"
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
# The SIF_SourceId from the SIF_Header
|
37
|
-
def source_id
|
38
|
-
(@doc/"//SIF_Header/SIF_SourceId/").text
|
39
|
-
end
|
40
|
-
|
41
|
-
# The SIF_MsgId from the SIF_Header
|
42
|
-
def msg_id
|
43
|
-
(@doc/"//SIF_Header/SIF_MsgId/").text
|
44
|
-
end
|
45
|
-
|
46
|
-
# Parses the xml provided and returns a RequestBody.
|
47
|
-
# Xml must respond to read or be a String.
|
48
|
-
def self.parse(xml)
|
49
|
-
unless xml.respond_to?("read") or xml.is_a?(String)
|
50
|
-
raise ArgumentError, "Unable to read Xml"
|
51
|
-
end
|
52
|
-
xml = xml.read if xml.respond_to?("read")
|
53
|
-
self.new(xml) # use self because we are going to inherit this class
|
54
|
-
end
|
55
|
-
|
56
|
-
private
|
57
|
-
# Drops the SIF_ from the front of the string provided
|
58
|
-
def drop_sif(string)
|
59
|
-
string.gsub!("SIF_","")
|
60
|
-
end
|
61
|
-
|
62
|
-
end
|
63
|
-
|
64
|
-
end
|
65
|
-
|
66
|
-
end
|
@@ -1,55 +0,0 @@
|
|
1
|
-
module Siffer
|
2
|
-
module Messages
|
3
|
-
|
4
|
-
class Status
|
5
|
-
|
6
|
-
attr_reader :code, :description, :data
|
7
|
-
|
8
|
-
def initialize(code,data)
|
9
|
-
@code = code
|
10
|
-
@description = CODES[code]
|
11
|
-
@data = data
|
12
|
-
end
|
13
|
-
|
14
|
-
def read
|
15
|
-
xml = Builder::XmlMarkup.new
|
16
|
-
xml.SIF_Status { |status|
|
17
|
-
status.SIF_Code(code)
|
18
|
-
status.SIF_Description(description)
|
19
|
-
if data.nil?
|
20
|
-
status.SIF_Data
|
21
|
-
else
|
22
|
-
status.SIF_Data{ |data_node| data_node << data.read }
|
23
|
-
end
|
24
|
-
}
|
25
|
-
end
|
26
|
-
alias :to_str :read
|
27
|
-
|
28
|
-
def self.method_missing(sym,*args)
|
29
|
-
data = args.first
|
30
|
-
status = nil
|
31
|
-
CODES.each do |key, val|
|
32
|
-
if val.downcase.to_sym == sym
|
33
|
-
status = Status.new(key,data)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
if status
|
37
|
-
return status
|
38
|
-
else
|
39
|
-
super(sym,*args)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
CODES = {
|
44
|
-
0 => "Success",
|
45
|
-
1 => "Immediate",
|
46
|
-
2 => "Intermediate",
|
47
|
-
3 => "Final",
|
48
|
-
7 => "Duplicate",
|
49
|
-
8 => "Sleeping",
|
50
|
-
9 => "No Messages"
|
51
|
-
}
|
52
|
-
end
|
53
|
-
|
54
|
-
end
|
55
|
-
end
|
data/lib/siffer/messaging.rb
DELETED
@@ -1,99 +0,0 @@
|
|
1
|
-
module Siffer
|
2
|
-
# The Messaging module takes care of all of the Message handling for
|
3
|
-
# Siffer. It will check messages against content-type constraints as
|
4
|
-
# well as validate the message XML against constraints outlined in the
|
5
|
-
# SIF Implementation Specification.
|
6
|
-
module Messaging
|
7
|
-
|
8
|
-
include Siffer::Messages
|
9
|
-
|
10
|
-
class BadContentType < Exception #:nodoc:
|
11
|
-
end
|
12
|
-
class MalformedXml < Exception #:nodoc:
|
13
|
-
end
|
14
|
-
class MalformedSIFMessage < Exception #:nodoc:
|
15
|
-
end
|
16
|
-
class XmlNsMismatch < Exception #:nodoc:
|
17
|
-
end
|
18
|
-
class VersionMismatch < Exception #:nodoc:
|
19
|
-
end
|
20
|
-
|
21
|
-
# Checks the request against the messaging constraints:
|
22
|
-
# * check_content_type
|
23
|
-
# * validate_message
|
24
|
-
# Raises exceptions accordingly.
|
25
|
-
def request_failed_messaging?
|
26
|
-
begin
|
27
|
-
check_content_type
|
28
|
-
validate_message
|
29
|
-
rescue BadContentType
|
30
|
-
# Make a better Not Acceptable response
|
31
|
-
@response = Response.new(Siffer::Protocol::HTTP_STATUS_CODES[406],
|
32
|
-
406,
|
33
|
-
{"Content-Type" => MIME_TYPES["htm"]})
|
34
|
-
rescue MalformedXml; error_response(1,2,"There was no XML body to parse.");
|
35
|
-
rescue MalformedSIFMessage; error_response(12,2,"The XML was not a recognizable SIF Message.");
|
36
|
-
rescue VersionMismatch; error_response(12,3,"The SIF version did not match supported versions.");
|
37
|
-
rescue XmlNsMismatch; error_response(1,4,"XMLNS not compatible with SIF")
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
# Provides a context for the original message.
|
42
|
-
def using_message_from(request, &block)
|
43
|
-
yield if block_given?
|
44
|
-
end
|
45
|
-
|
46
|
-
# Reads request content type and validates it's either text/xml
|
47
|
-
# or application/xml;charset=utf-8. If it isn't it will raise a
|
48
|
-
# BadContentType exception.
|
49
|
-
def check_content_type
|
50
|
-
content_type = @request.content_type
|
51
|
-
unless [MIME_TYPES["xml"],
|
52
|
-
MIME_TYPES["appxml"],
|
53
|
-
MIME_TYPES["appxmlencoded"]].include? content_type
|
54
|
-
raise BadContentType
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
# Validates the Request Body against the constraints of SIF Messaging.
|
59
|
-
# The word "validate" is used loosely as there is no XML validation
|
60
|
-
# currently.
|
61
|
-
#
|
62
|
-
# Currently validates:
|
63
|
-
# * <tt>well-formed XML</tt> - XML must be well formed.
|
64
|
-
# * <tt>message root</tt> - XML must be a SIF message.
|
65
|
-
# * <tt>version</tt> - Must match SIF version implemented.
|
66
|
-
# * <tt>xmlns</tt> - Must match xmlns implemented.
|
67
|
-
#
|
68
|
-
# Does not validate:
|
69
|
-
# * valid XML
|
70
|
-
# * different versions of SIF
|
71
|
-
def validate_message
|
72
|
-
begin
|
73
|
-
body = (@request.body.respond_to? :read) ? @request.body.read : @request.body
|
74
|
-
xml = REXML::Document.new(body)
|
75
|
-
# validate Message Root
|
76
|
-
raise MalformedXml if xml.root.nil?
|
77
|
-
# validate Message Root is a SIF_Message
|
78
|
-
raise MalformedSIFMessage if xml.root.name != "SIF_Message"
|
79
|
-
# validate SIF version
|
80
|
-
raise VersionMismatch if xml.root.attributes["version"] != Siffer.sif_version
|
81
|
-
# validate SIF xmlns
|
82
|
-
raise XmlNsMismatch if xml.root.attributes["xmlns"] != Siffer.sif_xmlns
|
83
|
-
# any others?
|
84
|
-
rescue REXML::ParseException
|
85
|
-
raise MalformedXml
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
# MIME Types used in Siffer
|
90
|
-
MIME_TYPES = {
|
91
|
-
"appxmlencoded" => "application/xml;charset=utf-8",
|
92
|
-
"appxml" => "application/xml",
|
93
|
-
"htm" => "text/html",
|
94
|
-
"html" => "text/html",
|
95
|
-
"xml" => "text/xml"
|
96
|
-
}
|
97
|
-
|
98
|
-
end
|
99
|
-
end
|
data/lib/siffer/protocol.rb
DELETED
@@ -1,164 +0,0 @@
|
|
1
|
-
module Siffer
|
2
|
-
# The Protocol module deals with the transport validation. Provides
|
3
|
-
# constants for HTTP statuses as well as acceptable paths for Siffer
|
4
|
-
# Servers and Agents.
|
5
|
-
module Protocol
|
6
|
-
|
7
|
-
include Siffer::Messages
|
8
|
-
include Siffer::Messaging
|
9
|
-
|
10
|
-
class UnknownPath < Exception; end #:nodoc:
|
11
|
-
class NonPostRequest < Exception; end #:nodoc:
|
12
|
-
|
13
|
-
# Checks the incoming request against the following protocol constraints:
|
14
|
-
# * Unknown PATH
|
15
|
-
# * Non-POST request
|
16
|
-
def request_failed_protocol?
|
17
|
-
if @request.get? and @request.path_info == ACCEPTABLE_PATHS[:root]
|
18
|
-
root_response
|
19
|
-
else
|
20
|
-
begin
|
21
|
-
check_path_against_protocol
|
22
|
-
rescue UnknownPath
|
23
|
-
# TODO: Make a better Not Found response
|
24
|
-
@response = Response.new(HTTP_STATUS_CODES[404],
|
25
|
-
404,
|
26
|
-
{"Content-Type" => MIME_TYPES["htm"]})
|
27
|
-
rescue NonPostRequest
|
28
|
-
# TODO: Make a better Method Not Allowed response
|
29
|
-
@response = Response.new(HTTP_STATUS_CODES[405],
|
30
|
-
405,
|
31
|
-
{"Content-Type" => MIME_TYPES["htm"]})
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
# Validates the request object against the Acceptable Paths (Siffer spec)
|
37
|
-
# and that the request is a POST.
|
38
|
-
def check_path_against_protocol
|
39
|
-
unless ACCEPTABLE_PATHS.has_value? @request.path_info
|
40
|
-
raise UnknownPath
|
41
|
-
end
|
42
|
-
unless @request.post?
|
43
|
-
raise NonPostRequest
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
# Returns the URI of the component (Server or Agent)
|
48
|
-
def uri
|
49
|
-
URI.parse("http://#{host.gsub(/(http|https):\/\//,"")}:#{port}").to_s
|
50
|
-
end
|
51
|
-
|
52
|
-
# Provides a context for each request. Creates the @request, @response and
|
53
|
-
# @original objects to use throughout the call.
|
54
|
-
# Validates against Protocol as well as Messaging using #request_failed
|
55
|
-
# predicates respectively.
|
56
|
-
#
|
57
|
-
# Yields the block if provided to allow further processing.
|
58
|
-
#
|
59
|
-
#Finishes by calling #finish on the response object or returns the generic
|
60
|
-
# response message.
|
61
|
-
def with_each_request(env, &block)
|
62
|
-
@request = Request.new(env)
|
63
|
-
unless request_failed_protocol? or request_failed_messaging?
|
64
|
-
using_message_from @request do # possibly a concurrency issue here
|
65
|
-
yield if block_given?
|
66
|
-
end
|
67
|
-
end
|
68
|
-
@response.finish unless no_response_available
|
69
|
-
end
|
70
|
-
|
71
|
-
# Sets the @response to a Siffer::Messages::Ack message with the
|
72
|
-
# appropriate Error category and code. Optional description is allowed
|
73
|
-
# and placed in the ExtendedDesc node.
|
74
|
-
def error_response(category,code, desc = nil)
|
75
|
-
error = Error.new(category,code,desc)
|
76
|
-
ack = Ack.new(self.name, @request.original, :error => error)
|
77
|
-
@response = Response.new(ack)
|
78
|
-
end
|
79
|
-
|
80
|
-
# Determines if there is a response instance created. If not
|
81
|
-
# it creates one with an Ack/Error describing not having
|
82
|
-
# anything to process.
|
83
|
-
def no_response_available
|
84
|
-
if @response.nil?
|
85
|
-
err = <<"ERR"
|
86
|
-
You are receiving this message because you failed to
|
87
|
-
provide enough information to respond to. This message
|
88
|
-
went completely through the messaging stack and
|
89
|
-
failed to instigate a response.
|
90
|
-
|
91
|
-
Please check the message you are sending and resend after
|
92
|
-
any corrections.
|
93
|
-
ERR
|
94
|
-
!error_response(12,1,err)
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
def root_response
|
99
|
-
html = <<"HTML"
|
100
|
-
<html>
|
101
|
-
<body>
|
102
|
-
<h1>Siffer Endpoint</h1>
|
103
|
-
<p>You have reached a Siffer component.</p>
|
104
|
-
</body>
|
105
|
-
</html>
|
106
|
-
HTML
|
107
|
-
@response = Response.new(html,200,{"Content-Type" => MIME_TYPES["htm"]})
|
108
|
-
end
|
109
|
-
|
110
|
-
# Paths that comply with the messaging protocol determined
|
111
|
-
# by the SIF Specification. These are Siffer specific and not
|
112
|
-
# spelled out in SIF Specification (rather implied).
|
113
|
-
ACCEPTABLE_PATHS = {
|
114
|
-
:root => "/",
|
115
|
-
:ping => "/ping",
|
116
|
-
:status => "/status",
|
117
|
-
:register => "/register"
|
118
|
-
}
|
119
|
-
|
120
|
-
|
121
|
-
# Every standard HTTP code mapped to the appropriate message.
|
122
|
-
# Stolen from Mongrel.
|
123
|
-
HTTP_STATUS_CODES = {
|
124
|
-
100 => 'Continue',
|
125
|
-
101 => 'Switching Protocols',
|
126
|
-
200 => 'OK',
|
127
|
-
201 => 'Created',
|
128
|
-
202 => 'Accepted',
|
129
|
-
203 => 'Non-Authoritative Information',
|
130
|
-
204 => 'No Content',
|
131
|
-
205 => 'Reset Content',
|
132
|
-
206 => 'Partial Content',
|
133
|
-
300 => 'Multiple Choices',
|
134
|
-
301 => 'Moved Permanently',
|
135
|
-
302 => 'Moved Temporarily',
|
136
|
-
303 => 'See Other',
|
137
|
-
304 => 'Not Modified',
|
138
|
-
305 => 'Use Proxy',
|
139
|
-
400 => 'Bad Request',
|
140
|
-
401 => 'Unauthorized',
|
141
|
-
402 => 'Payment Required',
|
142
|
-
403 => 'Forbidden',
|
143
|
-
404 => 'Not Found',
|
144
|
-
405 => 'Method Not Allowed',
|
145
|
-
406 => 'Not Acceptable',
|
146
|
-
407 => 'Proxy Authentication Required',
|
147
|
-
408 => 'Request Time-out',
|
148
|
-
409 => 'Conflict',
|
149
|
-
410 => 'Gone',
|
150
|
-
411 => 'Length Required',
|
151
|
-
412 => 'Precondition Failed',
|
152
|
-
413 => 'Request Entity Too Large',
|
153
|
-
414 => 'Request-URI Too Large',
|
154
|
-
415 => 'Unsupported Media Type',
|
155
|
-
500 => 'Internal Server Error',
|
156
|
-
501 => 'Not Implemented',
|
157
|
-
502 => 'Bad Gateway',
|
158
|
-
503 => 'Service Unavailable',
|
159
|
-
504 => 'Gateway Time-out',
|
160
|
-
505 => 'HTTP Version not supported'
|
161
|
-
}
|
162
|
-
|
163
|
-
end
|
164
|
-
end
|