| Module | Jabber::Caps |
| In: |
lib/xmpp4r/caps/c.rb
lib/xmpp4r/caps/helper/generator.rb lib/xmpp4r/caps/helper/helper.rb |
| NS_CAPS | = | 'http://jabber.org/protocol/caps' |
Implementation of the algorithm defined at: www.xmpp.org/extensions/xep-0115.html#ver-gen
# File lib/xmpp4r/caps/helper/generator.rb, line 114
114: def self.generate_ver(identities, features, forms=[], hash='sha-1')
115: s = generate_ver_str(identities, features, forms)
116:
117: # 9. Compute the verification string by hashing S using the
118: # algorithm specified in the 'hash' attribute (e.g., SHA-1 as
119: # defined in RFC 3174 [17]). The hashed data MUST be generated
120: # with binary output and encoded using Base64 as specified in
121: # Section 4 of RFC 4648 [18] (note: the Base64 output MUST NOT
122: # include whitespace and MUST set padding bits to zero). [19]
123:
124: # See http://www.iana.org/assignments/hash-function-text-names
125: hash_klass = case hash
126: when 'md2' then nil
127: when 'md5' then Digest::MD5
128: when 'sha-1' then Digest::SHA1
129: when 'sha-224' then nil
130: when 'sha-256' then Digest::SHA256
131: when 'sha-384' then Digest::SHA384
132: when 'sha-512' then Digest::SHA512
133: end
134: if hash_klass
135: Base64::encode64(hash_klass::digest(s)).strip
136: else
137: nil
138: end
139: end
Generate a ver hash from a Jabber::Discovery::IqQueryDiscoInfo result
| query: | [Jabber::Discovery::IqQueryDiscoInfo] |
# File lib/xmpp4r/caps/helper/generator.rb, line 144
144: def self.generate_ver_from_discoinfo(query, hash='sha-1')
145: identities = []
146: features = []
147: forms = []
148: query.each_element do |element|
149: if element.kind_of? Discovery::Identity
150: identities << element
151: elsif element.kind_of? Discovery::Feature
152: features << element
153: elsif element.kind_of? Dataforms::XData
154: forms << element
155: end
156: end
157: generate_ver(identities, features, forms, hash)
158: end
# File lib/xmpp4r/caps/helper/generator.rb, line 14
14: def self.generate_ver_str(identities, features, forms=[])
15: # 1. Initialize an empty string S.
16: s = ''
17:
18: # 2. Sort the service discovery identities [14] by category and
19: # then by type (if it exists) and then by xml:lang (if it
20: # exists), formatted as CATEGORY '/' [TYPE] '/' [LANG] '/'
21: # [NAME]. Note that each slash is included even if the TYPE,
22: # LANG, or NAME is not included.
23: identities.sort! do |identity1,identity2|
24: cmp_result = nil
25: [:category, :type, :xml_lang, :iname].each do |field|
26: value1 = identity1.send(field)
27: value2 = identity2.send(field)
28:
29: if value1 != value2
30: cmp_result = value1 <=> value2
31: break
32: end
33: end
34:
35:
36: cmp_result
37: end
38:
39: # 3. For each identity, append the 'category/type/lang/name' to
40: # S, followed by the '<' character.
41: s += identities.collect do |identity|
42: [:category, :type, :xml_lang, :iname].collect do |field|
43: identity.send(field).to_s
44: end.join('/') + '<'
45: end.join
46:
47: # 4. Sort the supported service discovery features. [15]
48: features.sort! do |feature1,feature2|
49: feature1.var <=> feature2.var
50: end
51:
52: # 5. For each feature, append the feature to S, followed by the
53: # '<' character.
54: s += features.collect do |feature|
55: feature.var.to_s + '<'
56: end.join
57:
58: # 6. If the service discovery information response includes
59: # XEP-0128 data forms, sort the forms by the FORM_TYPE (i.e., by
60: # the XML character data of the <value/> element).
61: forms.sort! do |form1,form2|
62: fform_type1 = form1.field('FORM_TYPE')
63: fform_type2 = form2.field('FORM_TYPE')
64: form_type1 = fform_type1 ? fform_type1.values.to_s : nil
65: form_type2 = fform_type2 ? fform_type2.values.to_s : nil
66: form_type1 <=> form_type2
67: end
68:
69: # 7. For each extended service discovery information form:
70: forms.each do |form|
71: # 7.1. Append the XML character data of the FORM_TYPE field's
72: # <value/> element, followed by the '<' character.
73: fform_type = form.field('FORM_TYPE')
74: form_type = fform_type ? fform_type.values.to_s : nil
75: s += "#{form_type}<"
76:
77: # 7.2. Sort the fields by the value of the "var" attribute.
78: fields = form.fields(false).sort do |field1,field2|
79: field1.var <=> field2.var
80: end
81:
82: # 7.3. For each field:
83:
84: fields.each do |field|
85: # 7.3.1. Append the value of the "var" attribute, followed by
86: # the '<' character.
87: s += "#{field.var}<"
88:
89: # 7.3.2. Sort values by the XML character data of the <value/>
90: # element.
91: values = field.values.sort do |value1,value2|
92: value1 <=> value2
93: end
94:
95: # 7.3.3. For each <value/> element, append the XML character
96: # data, followed by the '<' character.
97: s += values.collect do |value|
98: "#{value}<"
99: end.join
100: end
101: end
102:
103: # 8. Ensure that S is encoded according to the UTF-8 encoding
104: # (RFC 3269 [16]).
105:
106: # (given in XMPP4R)
107:
108: s
109: end