xcapclient 1.1 → 1.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|