xcapclient 1.1 → 1.2
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.
- data/ERRORS.rdoc +6 -1
- data/README.rdoc +7 -6
- data/lib/xcapclient.rb +1 -1
- data/lib/xcapclient/client.rb +35 -16
- data/lib/xcapclient/errors.rb +1 -0
- data/test/test_unit_01.rb +12 -12
- metadata +9 -5
data/ERRORS.rdoc
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
== Errors
|
3
2
|
|
4
3
|
The XCAPClient library includes custom Ruby exceptions. All these exceptions inherit from XCAPClient::XCAPClientError exception.
|
@@ -18,6 +17,7 @@ The XCAPClient library includes custom Ruby exceptions. All these exceptions inh
|
|
18
17
|
* HTTPNoMatchingETag
|
19
18
|
* HTTPConflictError
|
20
19
|
* HTTPDocumentNotModified
|
20
|
+
* HTTPForbidden
|
21
21
|
* HTTPDocumentNotFound
|
22
22
|
* HTTPWrongContentType
|
23
23
|
* HTTPBadRequest
|
@@ -80,6 +80,11 @@ Example:
|
|
80
80
|
The server replied "409 Conflict". It occurs when the request couldn't be performed in the server.
|
81
81
|
|
82
82
|
|
83
|
+
==== HTTPForbidden < HTTPError
|
84
|
+
|
85
|
+
The server rejects the request with "403 Forbidden".
|
86
|
+
|
87
|
+
|
83
88
|
==== HTTPDocumentNotModified < HTTPError
|
84
89
|
|
85
90
|
The server replied "304 Not Modified". It occurs when using ETag in "If-None-Match" header for a GET request. It means that the document has not been modified in the server so it's not fetched again (as the client already has it in a local cache).
|
data/README.rdoc
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
= XCAPClient (version 1.
|
1
|
+
= XCAPClient (version 1.2)
|
2
2
|
|
3
3
|
* http://dev.sipdoc.net/projects/ruby-xcapclient/wiki/
|
4
4
|
* http://rubyforge.org/projects/xcapclient/
|
@@ -18,8 +18,9 @@ The library implements the following features:
|
|
18
18
|
* Fetch, create/replace and delete a XML document.
|
19
19
|
* Fetch, create/replace and delete a XML node.
|
20
20
|
* Fetch, create/replace and delete a XML node attribute.
|
21
|
+
* Fetch node namespace bindings as they are used in the server ({RFC 4825 Section 7.10}[http://tools.ietf.org/html/rfc4825#section-7.10]).
|
21
22
|
* Full configurable parameters allowing customized fields for each XCAP application, such auid, XML namespace, MIME-Type, scope (:user or :global) and default document name ("index" if not set).
|
22
|
-
*
|
23
|
+
* Custom identity header (as "X-XCAP-Preferred-Identity") required in some XCAP/XDM environments.
|
23
24
|
* Manage of multiple documents per XCAP application.
|
24
25
|
* Fetch the XCAP server auids, extensions and namespaces ("xcap-caps" application).
|
25
26
|
* SSL.
|
@@ -108,7 +109,7 @@ By default, the methods accesing the XCAP server include the ETag if it's availa
|
|
108
109
|
|
109
110
|
==== Create a new document and upload it (a new "vacation-rules" document for "pres-rules" application)
|
110
111
|
|
111
|
-
my_pres_rules_2 = @xcapclient.application("pres-rules).add_document("vacation-rules")
|
112
|
+
my_pres_rules_2 = @xcapclient.application("pres-rules").add_document("vacation-rules")
|
112
113
|
my_pres_rules_2.plain = "<?xml version='1.0' encoding='UTF-8'?> ..."
|
113
114
|
@xcapclient.put("pres-rules", my_pres_rules_2)
|
114
115
|
# or
|
@@ -118,21 +119,21 @@ By default, the methods accesing the XCAP server include the ETag if it's availa
|
|
118
119
|
==== Fetch a node (with "id" = "sip:alice@example.org")
|
119
120
|
|
120
121
|
@xcapclient.get_node("pres-rules", nil,
|
121
|
-
'
|
122
|
+
'cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:conditions/cp:identity/cp:one[@id="sip:alice@example.org"]',
|
122
123
|
{"cp" => "urn:ietf:params:xml:ns:common-policy"})
|
123
124
|
|
124
125
|
|
125
126
|
==== Add a new node (a new allowed user in "pres-rules" document)
|
126
127
|
|
127
128
|
@xcapclient.put_node("pres-rules", nil,
|
128
|
-
'
|
129
|
+
'cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:conditions/cp:identity/cp:one[@id="sip:bob@example.org"]',
|
129
130
|
'<cp:one id="sip:bob@example.org"/>',
|
130
131
|
{"cp"=>"urn:ietf:params:xml:ns:common-policy"})
|
131
132
|
|
132
133
|
==== Fetch a node attribute (node "name" from node with "id" = "sip:alice@example.org")
|
133
134
|
|
134
135
|
@xcapclient.get_attribute("pres-rules", nil,
|
135
|
-
'
|
136
|
+
'cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:conditions/cp:identity/cp:one[@id="sip:alice@example.org"]',
|
136
137
|
"name",
|
137
138
|
{"cp" => "urn:ietf:params:xml:ns:common-policy"})
|
138
139
|
|
data/lib/xcapclient.rb
CHANGED
data/lib/xcapclient/client.rb
CHANGED
@@ -40,23 +40,25 @@ module XCAPClient
|
|
40
40
|
USER_AGENT = "Ruby-XCAPClient"
|
41
41
|
COMMON_HEADERS = {
|
42
42
|
"User-Agent" => "#{USER_AGENT}/#{VERSION}",
|
43
|
-
"Connection" => "
|
43
|
+
"Connection" => "close"
|
44
44
|
}
|
45
45
|
GLOBAL_XUI = "global"
|
46
46
|
XCAP_CAPS_XMLNS = "urn:ietf:params:xml:ns:xcap-caps"
|
47
47
|
HTTP_TIMEOUT = 6
|
48
|
-
CONF_PARAMETERS = [:xcap_root, :user, :auth_user, :password, :ssl_verify_cert]
|
48
|
+
CONF_PARAMETERS = [:xcap_root, :user, :auth_user, :password, :identity_header, :identity_user, :ssl_verify_cert]
|
49
49
|
|
50
50
|
|
51
|
-
attr_reader :xcap_root, :user, :auth_user, :password, :ssl_verify_cert
|
51
|
+
attr_reader :xcap_root, :user, :auth_user, :password, :identity_header, :identity_user, :ssl_verify_cert
|
52
52
|
|
53
53
|
|
54
54
|
# Create a new XCAP client. It requires two parameters:
|
55
55
|
#
|
56
56
|
# * _conf_: A hash containing settings related to the server:
|
57
57
|
# * _xcap_root_: The URL where the documents hold.
|
58
|
-
# * _user_: The client username. Depending on the server it could look like "sip:alice@domain.org", "alice@domain.org"
|
59
|
-
# * _auth_user_: Username for authentication (if required).
|
58
|
+
# * _user_: The client username. Depending on the server it could look like "sip:alice@domain.org", "alice@domain.org", "alice", "tel:+12345678"...
|
59
|
+
# * _auth_user_: Username, SIP URI or TEL URI for HTTP Digest authentication (if required). If not set it takes the value of _user_ field.
|
60
|
+
# * _identity_header_: Header required in some XCAP networks containing the user identity (i.e. "X-XCAP-Preferred-Identity").
|
61
|
+
# * _identity_user_: Value for the _identity_header_. It could be a SIP or TEL URI. If not set it takes teh value of _user_ field.
|
60
62
|
# * _ssl_verify_cert_: If true and the server uses SSL, the certificate is inspected (expiration time, signature...).
|
61
63
|
#
|
62
64
|
# * _applications_: A hash of hashes containing each XCAP application available for the client. Each application is an entry of the hash containing a key whose value is the "auid" of the application and whose value is a hast with the following fields:
|
@@ -91,6 +93,16 @@ module XCAPClient
|
|
91
93
|
#
|
92
94
|
# @client = Client.new(xcap_conf, xcap_apps)
|
93
95
|
#
|
96
|
+
# Example:
|
97
|
+
# xcap_conf = {
|
98
|
+
# :xcap_root => "https://xcap.domain.net",
|
99
|
+
# :user => "tel:+12345678",
|
100
|
+
# :auth_user => "tel:+12345678",
|
101
|
+
# :password => "1234",
|
102
|
+
# :identity_header => "X-XCAP-Preferred-Identity",
|
103
|
+
# :ssl_verify_cert => true
|
104
|
+
# }
|
105
|
+
#
|
94
106
|
# A XCAP application called "xcap-caps" is automatically added to the list of applications of the new client. This application is defined in the {RFC 4825}[http://tools.ietf.org/html/rfc4825].
|
95
107
|
#
|
96
108
|
def initialize(conf={}, applications={})
|
@@ -104,7 +116,7 @@ module XCAPClient
|
|
104
116
|
end
|
105
117
|
|
106
118
|
# Check xcap_root parameter.
|
107
|
-
@xcap_root = URI.parse(conf[:xcap_root].
|
119
|
+
@xcap_root = ( conf[:xcap_root] =~ /\/$/ ) ? URI.parse(conf[:xcap_root][0..-2]) : URI.parse(conf[:xcap_root])
|
108
120
|
raise ConfigError, "`xcap_root' must be http or https URI" unless [URI::HTTP, URI::HTTPS].include?(@xcap_root.class)
|
109
121
|
|
110
122
|
# Check user.
|
@@ -114,6 +126,10 @@ module XCAPClient
|
|
114
126
|
@auth_user = conf[:auth_user].freeze || @user
|
115
127
|
@password = conf[:password].freeze
|
116
128
|
|
129
|
+
@identity_header = conf[:identity_header].freeze
|
130
|
+
@identity_user = ( conf[:identity_user].freeze || @user ) if @identity_header
|
131
|
+
COMMON_HEADERS[@identity_header] = @identity_user if @identity_header
|
132
|
+
|
117
133
|
# Initialize the HTTP client.
|
118
134
|
@http_client = HTTPClient.new
|
119
135
|
@http_client.set_auth(@xcap_root, @auth_user, @password)
|
@@ -252,7 +268,7 @@ module XCAPClient
|
|
252
268
|
# Example, fetching the node with "id" = "sip:alice@example.org":
|
253
269
|
#
|
254
270
|
# @xcapclient.get_node("pres-rules", nil,
|
255
|
-
# '
|
271
|
+
# 'cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:conditions/cp:identity/cp:one[@id="sip:alice@example.org"]',
|
256
272
|
# {"cp" => "urn:ietf:params:xml:ns:common-policy"})
|
257
273
|
#
|
258
274
|
# If success:
|
@@ -275,7 +291,7 @@ module XCAPClient
|
|
275
291
|
# Example, creating/replacing the node with "id" = "sip:alice@example.org":
|
276
292
|
#
|
277
293
|
# @xcapclient.put_node("pres-rules", nil,
|
278
|
-
# '
|
294
|
+
# 'cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:conditions/cp:identity/cp:one[@id="sip:bob@example.org"]',
|
279
295
|
# '<cp:one id="sip:bob@example.org"/>',
|
280
296
|
# {"cp"=>"urn:ietf:params:xml:ns:common-policy"})
|
281
297
|
#
|
@@ -302,7 +318,7 @@ module XCAPClient
|
|
302
318
|
# Example, deleting the node with "id" = "sip:alice@example.org":
|
303
319
|
#
|
304
320
|
# @xcapclient.delete_node("pres-rules", nil,
|
305
|
-
# '
|
321
|
+
# 'cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:conditions/cp:identity/cp:one[@id="sip:alice@example.org"]',
|
306
322
|
# {"cp" => "urn:ietf:params:xml:ns:common-policy"})
|
307
323
|
#
|
308
324
|
# If success:
|
@@ -329,7 +345,7 @@ module XCAPClient
|
|
329
345
|
# "id" = "sip:alice@example.org":
|
330
346
|
#
|
331
347
|
# @xcapclient.get_attribute("pres-rules", nil,
|
332
|
-
# '
|
348
|
+
# 'cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:conditions/cp:identity/cp:one[@id="sip:alice@example.org"]',
|
333
349
|
# "name",
|
334
350
|
# {"cp" => "urn:ietf:params:xml:ns:common-policy"})
|
335
351
|
#
|
@@ -355,7 +371,7 @@ module XCAPClient
|
|
355
371
|
# "id" = "sip:alice@example.org" with new value "Alice Yeah":
|
356
372
|
#
|
357
373
|
# @xcapclient.put_attribute("pres-rules", nil,
|
358
|
-
# '
|
374
|
+
# 'cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:conditions/cp:identity/cp:one[@id="sip:alice@example.org"]',
|
359
375
|
# "name",
|
360
376
|
# "Alice Yeah",
|
361
377
|
# {"cp" => "urn:ietf:params:xml:ns:common-policy"})
|
@@ -384,7 +400,7 @@ module XCAPClient
|
|
384
400
|
# "id" = "sip:alice@example.org":
|
385
401
|
#
|
386
402
|
# @xcapclient.delete_attribute("pres-rules", nil,
|
387
|
-
# '
|
403
|
+
# 'cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:conditions/cp:identity/cp:one[@id="sip:alice@example.org"]',
|
388
404
|
# "name",
|
389
405
|
# {"cp" => "urn:ietf:params:xml:ns:common-policy"})
|
390
406
|
#
|
@@ -418,7 +434,7 @@ module XCAPClient
|
|
418
434
|
# Example:
|
419
435
|
#
|
420
436
|
# @xcapclient.get_node_namespaces("pres-rules", nil,
|
421
|
-
# '
|
437
|
+
# 'ccpp:ruleset/ccpp:rule[@id="pres_whitelist"]',
|
422
438
|
# { "ccpp" => "urn:ietf:params:xml:ns:common-policy" })
|
423
439
|
#
|
424
440
|
# Assuming the server uses "cp" for that namespace, it would reply:
|
@@ -541,7 +557,7 @@ module XCAPClient
|
|
541
557
|
#
|
542
558
|
def get_xmlns_query(xml_namespaces)
|
543
559
|
|
544
|
-
return ""
|
560
|
+
return "" if ( ! xml_namespaces || xml_namespaces.empty? )
|
545
561
|
|
546
562
|
xmlns_query="?"
|
547
563
|
xml_namespaces.each do |prefix, uri|
|
@@ -578,8 +594,8 @@ module XCAPClient
|
|
578
594
|
end
|
579
595
|
|
580
596
|
# URI.
|
581
|
-
uri = "#{@xcap_root}/#{application.auid}/#{xui}/#{document.name}"
|
582
|
-
uri += "
|
597
|
+
uri = "#{@xcap_root}/#{application.auid}/#{xui}/#{percent_encode(document.name)}"
|
598
|
+
uri += "/~~/#{percent_encode(selector)}" if selector
|
583
599
|
uri += get_xmlns_query(xml_namespaces) if xml_namespaces
|
584
600
|
|
585
601
|
# Body (just in case of PUT).
|
@@ -606,6 +622,9 @@ module XCAPClient
|
|
606
622
|
when "400"
|
607
623
|
raise HTTPBadRequest
|
608
624
|
|
625
|
+
when "403"
|
626
|
+
raise HTTPForbidden
|
627
|
+
|
609
628
|
when "404"
|
610
629
|
raise HTTPDocumentNotFound
|
611
630
|
|
data/lib/xcapclient/errors.rb
CHANGED
@@ -8,6 +8,7 @@ module XCAPClient
|
|
8
8
|
class DocumentError < XCAPClientError ; end
|
9
9
|
class HTTPError < XCAPClientError ; end
|
10
10
|
class HTTPAuthenticationError < HTTPError ; end
|
11
|
+
class HTTPForbidden < HTTPError ; end
|
11
12
|
class HTTPNoMatchingETag < HTTPError ; end
|
12
13
|
class HTTPConflictError < HTTPError ; end
|
13
14
|
class HTTPDocumentNotModified < HTTPError ; end
|
data/test/test_unit_01.rb
CHANGED
@@ -153,7 +153,7 @@ class TestXCAPClient < Test::Unit::TestCase
|
|
153
153
|
def test_10_get_element
|
154
154
|
show "Fetching a node (no ETag) => 200"
|
155
155
|
assert @client.get_element("pres-rules", nil,
|
156
|
-
'
|
156
|
+
'cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:conditions/cp:identity/cp:one[@id="sip:bob@example.org"]',
|
157
157
|
NS,
|
158
158
|
check_etag=false)
|
159
159
|
end
|
@@ -163,7 +163,7 @@ class TestXCAPClient < Test::Unit::TestCase
|
|
163
163
|
show "Fetching a node (correct ETag) => 304"
|
164
164
|
begin
|
165
165
|
@client.get_element("pres-rules", nil,
|
166
|
-
'
|
166
|
+
'cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:conditions/cp:identity/cp:one[@id="sip:alice@example.org"]',
|
167
167
|
NS,
|
168
168
|
check_etag=true)
|
169
169
|
rescue => e
|
@@ -179,7 +179,7 @@ class TestXCAPClient < Test::Unit::TestCase
|
|
179
179
|
def test_12_get_element
|
180
180
|
show "Fetching an attribute (no ETag) => 200 (fails in OpenXCAP, bug http://openxcap.org/ticket/122)"
|
181
181
|
assert @client.get_element("pres-rules", nil,
|
182
|
-
'
|
182
|
+
'cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:conditions/cp:identity/cp:one[@id="sip:alice@example.org"]/@id',
|
183
183
|
NS,
|
184
184
|
check_etag=false)
|
185
185
|
end
|
@@ -188,7 +188,7 @@ class TestXCAPClient < Test::Unit::TestCase
|
|
188
188
|
def test_13_put_element
|
189
189
|
show "Creating a node (no ETag) => 201"
|
190
190
|
assert @client.put_element("pres-rules", nil,
|
191
|
-
'
|
191
|
+
'cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:conditions/cp:identity/cp:one[@id="sip:new-1@new.net"]',
|
192
192
|
'<cp:one id="sip:new-1@new.net"/>',
|
193
193
|
NS,
|
194
194
|
check_etag=false)
|
@@ -200,7 +200,7 @@ class TestXCAPClient < Test::Unit::TestCase
|
|
200
200
|
begin
|
201
201
|
@doc.etag = "wrongETag"
|
202
202
|
@client.put_element("pres-rules", nil,
|
203
|
-
'
|
203
|
+
'cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:condition/cp:identity/cp:one[@id="sip:new-2@new.net"]',
|
204
204
|
'<cp:one id="sip:new-2@new.net"/>',
|
205
205
|
NS,
|
206
206
|
check_etag=true)
|
@@ -216,7 +216,7 @@ class TestXCAPClient < Test::Unit::TestCase
|
|
216
216
|
show "Creating a node in wrong position => 409"
|
217
217
|
begin
|
218
218
|
@client.put_element("pres-rules", nil,
|
219
|
-
'
|
219
|
+
'cp:ruleset/cp:rule[@id="non_existing"]/cp:condition/cp:identity/cp:one[@id="sip:new-3@new.net"]',
|
220
220
|
'<cp:one id="sip:new-3@new.net"/>',
|
221
221
|
NS,
|
222
222
|
check_etag=false)
|
@@ -232,7 +232,7 @@ class TestXCAPClient < Test::Unit::TestCase
|
|
232
232
|
show "Creating a node using different NS prefixes than the used in the server document (no ETag) => 409/500"
|
233
233
|
begin
|
234
234
|
@client.put_element("pres-rules", nil,
|
235
|
-
'
|
235
|
+
'ccpp:ruleset/ccpp:rule[@id="pres_whitelist"]/ccpp:conditions/ccpp:identity/ccpp:one[@id="sip:new-4@new.net"]',
|
236
236
|
'<ccpp:one id="sip:new-4@new.net"/>',
|
237
237
|
{"pprr"=>"urn:ietf:params:xml:ns:pres-rules", "ccpp"=>"urn:ietf:params:xml:ns:common-policy"},
|
238
238
|
check_etag=false)
|
@@ -250,7 +250,7 @@ class TestXCAPClient < Test::Unit::TestCase
|
|
250
250
|
show "Creating a node using using a non unique selector (no ETag) => 409 (fails in OpenXCAP, bug http://openxcap.org/ticket/123)"
|
251
251
|
begin
|
252
252
|
@client.put_element("pres-rules", nil,
|
253
|
-
'
|
253
|
+
'cp:ruleset/cp:rule/cp:conditions/cp:identity/cp:one[@id="sip:new-5@new.net"]',
|
254
254
|
'<cp:one id="sip:new-5@new.net"/>',
|
255
255
|
NS,
|
256
256
|
check_etag=false)
|
@@ -265,7 +265,7 @@ class TestXCAPClient < Test::Unit::TestCase
|
|
265
265
|
def test_18_delete_element
|
266
266
|
show "Deleting an element (no ETag) => 200"
|
267
267
|
assert @client.delete_element("pres-rules", nil,
|
268
|
-
'
|
268
|
+
'cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:conditions/cp:identity/cp:one[@id="sip:bob@example.org"]',
|
269
269
|
NS,
|
270
270
|
check_etag=false)
|
271
271
|
end
|
@@ -276,7 +276,7 @@ class TestXCAPClient < Test::Unit::TestCase
|
|
276
276
|
begin
|
277
277
|
@doc.etag = "wrongETag"
|
278
278
|
@client.delete_element("pres-rules", nil,
|
279
|
-
'
|
279
|
+
'cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:condition/cp:identity/cp:one[@id="sip:bob@example.org"]',
|
280
280
|
NS,
|
281
281
|
check_etag=true)
|
282
282
|
rescue => e
|
@@ -290,7 +290,7 @@ class TestXCAPClient < Test::Unit::TestCase
|
|
290
290
|
def test_20_delete_element
|
291
291
|
show "Deleting a no existing element (correct ETag) => 404"
|
292
292
|
@client.delete_element("pres-rules", nil,
|
293
|
-
'
|
293
|
+
'cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:conditions/cp:identity/cp:one[@id="sip:alice@example.org"]',
|
294
294
|
NS)
|
295
295
|
begin
|
296
296
|
@client.delete_element("pres-rules", nil,
|
@@ -309,7 +309,7 @@ class TestXCAPClient < Test::Unit::TestCase
|
|
309
309
|
def test_21_get_element_namespaces
|
310
310
|
show "Fetching the namespaces associated to a document node => 200 (fails in OpenXCAP, bug http://openxcap.org/ticket/124)"
|
311
311
|
assert @client.get_element_namespaces("pres-rules", nil,
|
312
|
-
'
|
312
|
+
'ccpp:ruleset/ccpp:rule[@id="pres_whitelist"]/ccpp:conditions/ccpp:identity',
|
313
313
|
{"ccpp"=>"urn:ietf:params:xml:ns:common-policy"},
|
314
314
|
check_etag=false)
|
315
315
|
assert_equal( @client.application("pres-rules").document.last_response.header["Content-Type"], "application/xcap-ns+xml" )
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xcapclient
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: "1.
|
4
|
+
version: "1.2"
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- "I\xC3\xB1aki Baz Castillo"
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-11-
|
12
|
+
date: 2009-11-23 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -22,7 +22,9 @@ dependencies:
|
|
22
22
|
- !ruby/object:Gem::Version
|
23
23
|
version: "0"
|
24
24
|
version:
|
25
|
-
description:
|
25
|
+
description: "\t\tXCAP (RFC 4825) is a protocol on top of HTTP which allows a client (usually a VoIP/SIP device) to manipulate the contents of Presence Information Data Format (PIDF) based presence documents. These documents are stored in a server in XML format.\n\
|
26
|
+
\t\t\n\
|
27
|
+
\t\tRuby xcapclient library implements the XCAP protocol in client side, allowing the applications to get, store, modify and delete XML documents in the server.'\n"
|
26
28
|
email: ibc@aliax.net
|
27
29
|
executables: []
|
28
30
|
|
@@ -45,6 +47,8 @@ files:
|
|
45
47
|
- ERRORS.rdoc
|
46
48
|
has_rdoc: true
|
47
49
|
homepage: http://dev.sipdoc.net/projects/ruby-xcapclient/wiki/
|
50
|
+
licenses: []
|
51
|
+
|
48
52
|
post_install_message:
|
49
53
|
rdoc_options:
|
50
54
|
- --main
|
@@ -68,9 +72,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
68
72
|
requirements: []
|
69
73
|
|
70
74
|
rubyforge_project: xcapclient
|
71
|
-
rubygems_version: 1.3.
|
75
|
+
rubygems_version: 1.3.5
|
72
76
|
signing_key:
|
73
|
-
specification_version:
|
77
|
+
specification_version: 3
|
74
78
|
summary: XCAP client library
|
75
79
|
test_files:
|
76
80
|
- test/test_unit_01.rb
|