xcapclient 1.0 → 1.1
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 +8 -2
- data/README.rdoc +16 -9
- data/lib/xcapclient/client.rb +113 -24
- data/lib/xcapclient/errors.rb +1 -0
- data/lib/xcapclient.rb +1 -1
- metadata +5 -3
data/ERRORS.rdoc
CHANGED
@@ -14,7 +14,7 @@ The XCAPClient library includes custom Ruby exceptions. All these exceptions inh
|
|
14
14
|
* WrongAUID
|
15
15
|
* DocumentError
|
16
16
|
* HTTPError
|
17
|
-
|
17
|
+
* HTTPAuthenticationError
|
18
18
|
* HTTPNoMatchingETag
|
19
19
|
* HTTPConflictError
|
20
20
|
* HTTPDocumentNotModified
|
@@ -22,6 +22,7 @@ The XCAPClient library includes custom Ruby exceptions. All these exceptions inh
|
|
22
22
|
* HTTPWrongContentType
|
23
23
|
* HTTPBadRequest
|
24
24
|
* HTTPServerError
|
25
|
+
* HTTPNotImplemented
|
25
26
|
* HTTPUnknownError
|
26
27
|
* XMLParsingError
|
27
28
|
|
@@ -109,7 +110,12 @@ The server replied "400 Bad Request". The request was malformed.
|
|
109
110
|
|
110
111
|
==== HTTPServerError < HTTPError
|
111
112
|
|
112
|
-
The server replied "500 Internal Server Error". The server encountered an unexpected condition which prevented it from fulfilling the request.
|
113
|
+
The server replied "500 Internal Server Error" or "503 Service Unavailable". The server encountered an unexpected condition which prevented it from fulfilling the request.
|
114
|
+
|
115
|
+
|
116
|
+
==== HTTPNotImplemented < HTTPError
|
117
|
+
|
118
|
+
The server replied "501 Not Implemented". The server doesn't implement the request method.
|
113
119
|
|
114
120
|
|
115
121
|
==== HTTPUnknownError < HTTPError
|
data/README.rdoc
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
= XCAPClient
|
1
|
+
= XCAPClient (version 1.1.X)
|
2
2
|
|
3
3
|
* http://dev.sipdoc.net/projects/ruby-xcapclient/wiki/
|
4
4
|
* http://rubyforge.org/projects/xcapclient/
|
@@ -15,11 +15,11 @@ XCAPClient library implements the XCAP protocol in client side, allowing the app
|
|
15
15
|
|
16
16
|
The library implements the following features:
|
17
17
|
|
18
|
-
* Fetch, create/replace and delete a document.
|
19
|
-
* Fetch, create/replace and delete a
|
20
|
-
* Fetch, create/replace and delete
|
18
|
+
* Fetch, create/replace and delete a XML document.
|
19
|
+
* Fetch, create/replace and delete a XML node.
|
20
|
+
* Fetch, create/replace and delete a XML node attribute.
|
21
21
|
* 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
|
-
* Fetch the namespaces and prefixes of a document node as they are used in the server.
|
22
|
+
* Fetch the namespaces and prefixes of a document/node node as they are used in the server.
|
23
23
|
* Manage of multiple documents per XCAP application.
|
24
24
|
* Fetch the XCAP server auids, extensions and namespaces ("xcap-caps" application).
|
25
25
|
* SSL.
|
@@ -115,20 +115,27 @@ By default, the methods accesing the XCAP server include the ETag if it's availa
|
|
115
115
|
@xcapclient.put("pres-rules", "vacation-rules")
|
116
116
|
|
117
117
|
|
118
|
-
==== Fetch
|
118
|
+
==== Fetch a node (with "id" = "sip:alice@example.org")
|
119
119
|
|
120
|
-
@xcapclient.
|
120
|
+
@xcapclient.get_node("pres-rules", nil,
|
121
121
|
'/cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:conditions/cp:identity/cp:one[@id="sip:alice@example.org"]',
|
122
122
|
{"cp" => "urn:ietf:params:xml:ns:common-policy"})
|
123
123
|
|
124
124
|
|
125
|
-
==== Add a new
|
125
|
+
==== Add a new node (a new allowed user in "pres-rules" document)
|
126
126
|
|
127
|
-
@xcapclient.
|
127
|
+
@xcapclient.put_node("pres-rules", nil,
|
128
128
|
'/cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:conditions/cp:identity/cp:one[@id="sip:bob@example.org"]',
|
129
129
|
'<cp:one id="sip:bob@example.org"/>',
|
130
130
|
{"cp"=>"urn:ietf:params:xml:ns:common-policy"})
|
131
131
|
|
132
|
+
==== Fetch a node attribute (node "name" from node with "id" = "sip:alice@example.org")
|
133
|
+
|
134
|
+
@xcapclient.get_attribute("pres-rules", nil,
|
135
|
+
'/cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:conditions/cp:identity/cp:one[@id="sip:alice@example.org"]',
|
136
|
+
"name",
|
137
|
+
{"cp" => "urn:ietf:params:xml:ns:common-policy"})
|
138
|
+
|
132
139
|
|
133
140
|
== ToDo
|
134
141
|
|
data/lib/xcapclient/client.rb
CHANGED
@@ -40,7 +40,7 @@ module XCAPClient
|
|
40
40
|
USER_AGENT = "Ruby-XCAPClient"
|
41
41
|
COMMON_HEADERS = {
|
42
42
|
"User-Agent" => "#{USER_AGENT}/#{VERSION}",
|
43
|
-
"Connection" => "
|
43
|
+
"Connection" => "open"
|
44
44
|
}
|
45
45
|
GLOBAL_XUI = "global"
|
46
46
|
XCAP_CAPS_XMLNS = "urn:ietf:params:xml:ns:xcap-caps"
|
@@ -247,18 +247,18 @@ module XCAPClient
|
|
247
247
|
end
|
248
248
|
|
249
249
|
|
250
|
-
# Fetch
|
250
|
+
# Fetch a node from the document stored in the server.
|
251
251
|
#
|
252
|
-
# Example:
|
252
|
+
# Example, fetching the node with "id" = "sip:alice@example.org":
|
253
253
|
#
|
254
|
-
# @xcapclient.
|
254
|
+
# @xcapclient.get_node("pres-rules", nil,
|
255
255
|
# '/cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:conditions/cp:identity/cp:one[@id="sip:alice@example.org"]',
|
256
256
|
# {"cp" => "urn:ietf:params:xml:ns:common-policy"})
|
257
257
|
#
|
258
258
|
# If success:
|
259
|
-
# * The method returns the
|
259
|
+
# * The method returns the node as a String.
|
260
260
|
#
|
261
|
-
def
|
261
|
+
def get_node(auid, document, selector, xml_namespaces=nil, check_etag=true)
|
262
262
|
|
263
263
|
application, document = get_app_doc(auid, document)
|
264
264
|
response = send_request(:get, application, document, selector, nil, xml_namespaces, nil, check_etag)
|
@@ -270,11 +270,11 @@ module XCAPClient
|
|
270
270
|
|
271
271
|
end
|
272
272
|
|
273
|
-
# Create/replace
|
273
|
+
# Create/replace a node in the document stored in the server.
|
274
274
|
#
|
275
|
-
# Example:
|
275
|
+
# Example, creating/replacing the node with "id" = "sip:alice@example.org":
|
276
276
|
#
|
277
|
-
# @xcapclient.
|
277
|
+
# @xcapclient.put_node("pres-rules", nil,
|
278
278
|
# '/cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:conditions/cp:identity/cp:one[@id="sip:bob@example.org"]',
|
279
279
|
# '<cp:one id="sip:bob@example.org"/>',
|
280
280
|
# {"cp"=>"urn:ietf:params:xml:ns:common-policy"})
|
@@ -283,7 +283,7 @@ module XCAPClient
|
|
283
283
|
# * The method returns true.
|
284
284
|
# * Local plain document and ETag are deleted (as the document has changed).
|
285
285
|
#
|
286
|
-
def
|
286
|
+
def put_node(auid, document, selector, selector_body, xml_namespaces=nil, check_etag=true)
|
287
287
|
|
288
288
|
application, document = get_app_doc(auid, document)
|
289
289
|
response = send_request(:put, application, document, selector, selector_body, xml_namespaces, "application/xcap-el+xml", check_etag)
|
@@ -297,11 +297,11 @@ module XCAPClient
|
|
297
297
|
end
|
298
298
|
|
299
299
|
|
300
|
-
# Delete
|
300
|
+
# Delete a node in the document stored in the server.
|
301
301
|
#
|
302
|
-
# Example:
|
302
|
+
# Example, deleting the node with "id" = "sip:alice@example.org":
|
303
303
|
#
|
304
|
-
# @xcapclient.
|
304
|
+
# @xcapclient.delete_node("pres-rules", nil,
|
305
305
|
# '/cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:conditions/cp:identity/cp:one[@id="sip:alice@example.org"]',
|
306
306
|
# {"cp" => "urn:ietf:params:xml:ns:common-policy"})
|
307
307
|
#
|
@@ -309,7 +309,7 @@ module XCAPClient
|
|
309
309
|
# * The method returns true.
|
310
310
|
# * Local plain document and ETag are deleted (as the document has changed).
|
311
311
|
#
|
312
|
-
def
|
312
|
+
def delete_node(auid, document, selector, xml_namespaces=nil, check_etag=true)
|
313
313
|
|
314
314
|
application, document = get_app_doc(auid, document)
|
315
315
|
response = send_request(:delete, application, document, selector, nil, xml_namespaces, nil, check_etag)
|
@@ -323,15 +323,101 @@ module XCAPClient
|
|
323
323
|
end
|
324
324
|
|
325
325
|
|
326
|
-
# Fetch the
|
326
|
+
# Fetch a node attribute from the document stored in the server.
|
327
|
+
#
|
328
|
+
# Example, fetching the "name" attribute of the node with
|
329
|
+
# "id" = "sip:alice@example.org":
|
330
|
+
#
|
331
|
+
# @xcapclient.get_attribute("pres-rules", nil,
|
332
|
+
# '/cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:conditions/cp:identity/cp:one[@id="sip:alice@example.org"]',
|
333
|
+
# "name",
|
334
|
+
# {"cp" => "urn:ietf:params:xml:ns:common-policy"})
|
335
|
+
#
|
336
|
+
# If success:
|
337
|
+
# * The method returns the attribute as a String.
|
338
|
+
#
|
339
|
+
def get_attribute(auid, document, selector, attribute_name, xml_namespaces=nil, check_etag=true)
|
340
|
+
|
341
|
+
application, document = get_app_doc(auid, document)
|
342
|
+
response = send_request(:get, application, document, selector + "/@#{attribute_name}", nil, xml_namespaces, nil, check_etag)
|
343
|
+
|
344
|
+
# Check Content-Type.
|
345
|
+
check_content_type(response, "application/xcap-att+xml")
|
346
|
+
|
347
|
+
return response.body.content
|
348
|
+
|
349
|
+
end
|
350
|
+
|
351
|
+
|
352
|
+
# Create/replace a node attribute in the document stored in the server.
|
353
|
+
#
|
354
|
+
# Example, creating/replacing the "name" attribute of the node with
|
355
|
+
# "id" = "sip:alice@example.org" with new value "Alice Yeah":
|
356
|
+
#
|
357
|
+
# @xcapclient.put_attribute("pres-rules", nil,
|
358
|
+
# '/cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:conditions/cp:identity/cp:one[@id="sip:alice@example.org"]',
|
359
|
+
# "name",
|
360
|
+
# "Alice Yeah",
|
361
|
+
# {"cp" => "urn:ietf:params:xml:ns:common-policy"})
|
327
362
|
#
|
328
|
-
# If
|
363
|
+
# If success:
|
364
|
+
# * The method returns true.
|
365
|
+
# * Local plain document and ETag are deleted (as the document has changed).
|
366
|
+
#
|
367
|
+
def put_attribute(auid, document, selector, attribute_name, attribute_value, xml_namespaces=nil, check_etag=true)
|
368
|
+
|
369
|
+
application, document = get_app_doc(auid, document)
|
370
|
+
response = send_request(:put, application, document, selector + "/@#{attribute_name}", attribute_value, xml_namespaces, "application/xcap-att+xml", check_etag)
|
371
|
+
|
372
|
+
# Reset local plain document and ETag as we have modified it.
|
373
|
+
document.plain = nil
|
374
|
+
document.etag = nil
|
375
|
+
|
376
|
+
return true
|
377
|
+
|
378
|
+
end
|
379
|
+
|
380
|
+
|
381
|
+
# Delete a node attribute in the document stored in the server.
|
382
|
+
#
|
383
|
+
# Example, deleting the "name" attribute of the node with
|
384
|
+
# "id" = "sip:alice@example.org":
|
385
|
+
#
|
386
|
+
# @xcapclient.delete_attribute("pres-rules", nil,
|
387
|
+
# '/cp:ruleset/cp:rule[@id="pres_whitelist"]/cp:conditions/cp:identity/cp:one[@id="sip:alice@example.org"]',
|
388
|
+
# "name",
|
389
|
+
# {"cp" => "urn:ietf:params:xml:ns:common-policy"})
|
390
|
+
#
|
391
|
+
# If success:
|
392
|
+
# * The method returns true.
|
393
|
+
# * Local plain document and ETag are deleted (as the document has changed).
|
394
|
+
#
|
395
|
+
def delete_attribute(auid, document, selector, attribute_name, xml_namespaces=nil, check_etag=true)
|
396
|
+
|
397
|
+
application, document = get_app_doc(auid, document)
|
398
|
+
response = send_request(:delete, application, document, selector + "/@#{attribute_name}", nil, xml_namespaces, nil, check_etag)
|
399
|
+
|
400
|
+
# Reset local plain document and ETag as we have modified it
|
401
|
+
document.plain = nil
|
402
|
+
document.etag = nil
|
403
|
+
|
404
|
+
return true
|
405
|
+
|
406
|
+
end
|
407
|
+
|
408
|
+
|
409
|
+
# Fetch the namespace prefixes of a node.
|
410
|
+
#
|
411
|
+
# If the client wants to create/replace a node, the body of the PUT
|
412
|
+
# request must use the same namespaces and prefixes as those used in
|
413
|
+
# the document stored in the server. This methods allows the client
|
414
|
+
# to fetch these namespaces and prefixes.
|
329
415
|
#
|
330
416
|
# Related documentation: {RFC 4825 section 7.10}[http://tools.ietf.org/html/rfc4825#section-7.10], {RFC 4825 section 10}[http://tools.ietf.org/html/rfc4825#section-10]
|
331
417
|
#
|
332
418
|
# Example:
|
333
419
|
#
|
334
|
-
# @xcapclient.
|
420
|
+
# @xcapclient.get_node_namespaces("pres-rules", nil,
|
335
421
|
# '/ccpp:ruleset/ccpp:rule[@id="pres_whitelist"]',
|
336
422
|
# { "ccpp" => "urn:ietf:params:xml:ns:common-policy" })
|
337
423
|
#
|
@@ -347,7 +433,7 @@ module XCAPClient
|
|
347
433
|
# {"pr"=>"urn:ietf:params:xml:ns:pres-rules", "cp"=>"urn:ietf:params:xml:ns:common-policy"}
|
348
434
|
# If not, the method returns the response body as a String and the application must parse it.
|
349
435
|
#
|
350
|
-
def
|
436
|
+
def get_node_namespaces(auid, document, selector, xml_namespaces=nil, check_etag=true)
|
351
437
|
|
352
438
|
application, document = get_app_doc(auid, document)
|
353
439
|
response = send_request(:get, application, document, selector + "/namespace::*", nil, xml_namespaces, nil, check_etag)
|
@@ -373,7 +459,7 @@ module XCAPClient
|
|
373
459
|
#
|
374
460
|
def get_xcap_auids
|
375
461
|
|
376
|
-
body =
|
462
|
+
body = get_node("xcap-caps", nil, '/xcap-caps/auids')
|
377
463
|
|
378
464
|
return case NOKOGIRI_INSTALLED
|
379
465
|
when true
|
@@ -391,7 +477,7 @@ module XCAPClient
|
|
391
477
|
#
|
392
478
|
def get_xcap_extensions
|
393
479
|
|
394
|
-
body =
|
480
|
+
body = get_node("xcap-caps", nil, '/xcap-caps/extensions')
|
395
481
|
|
396
482
|
return case NOKOGIRI_INSTALLED
|
397
483
|
when true
|
@@ -409,7 +495,7 @@ module XCAPClient
|
|
409
495
|
#
|
410
496
|
def get_xcap_namespaces
|
411
497
|
|
412
|
-
body =
|
498
|
+
body = get_node("xcap-caps", nil, '/xcap-caps/namespaces')
|
413
499
|
|
414
500
|
return case NOKOGIRI_INSTALLED
|
415
501
|
when true
|
@@ -498,7 +584,7 @@ module XCAPClient
|
|
498
584
|
|
499
585
|
# Body (just in case of PUT).
|
500
586
|
body = ( selector_body || document.plain || nil ) if method == :put
|
501
|
-
raise ArgumentError, "PUT body
|
587
|
+
raise ArgumentError, "PUT body must be a String" unless String === body if method == :put
|
502
588
|
|
503
589
|
begin
|
504
590
|
response = @http_client.request(method, uri, nil, body, extra_headers)
|
@@ -532,11 +618,14 @@ module XCAPClient
|
|
532
618
|
when "412"
|
533
619
|
raise HTTPNoMatchingETag
|
534
620
|
|
535
|
-
when
|
621
|
+
when /^50[03]$/
|
536
622
|
raise HTTPServerError
|
623
|
+
|
624
|
+
whe "501"
|
625
|
+
raise HTTPNotImplemented
|
537
626
|
|
538
627
|
else
|
539
|
-
raise HTTPUnknownError, "Unknown
|
628
|
+
raise HTTPUnknownError, "Unknown Error [#{response.status} #{response.reason}]"
|
540
629
|
|
541
630
|
end
|
542
631
|
|
data/lib/xcapclient/errors.rb
CHANGED
@@ -15,6 +15,7 @@ module XCAPClient
|
|
15
15
|
class HTTPWrongContentType < HTTPError ; end
|
16
16
|
class HTTPBadRequest < HTTPError ; end
|
17
17
|
class HTTPServerError < HTTPError ; end
|
18
|
+
class HTTPNotImplemented < HTTPError ; end
|
18
19
|
class HTTPUnknownError < HTTPError ; end
|
19
20
|
class XMLParsingError < XCAPClientError ; end
|
20
21
|
|
data/lib/xcapclient.rb
CHANGED
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.1"
|
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-
|
12
|
+
date: 2009-11-09 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -44,11 +44,13 @@ files:
|
|
44
44
|
- README.rdoc
|
45
45
|
- ERRORS.rdoc
|
46
46
|
has_rdoc: true
|
47
|
-
homepage: http://dev.sipdoc.net/projects/ruby-
|
47
|
+
homepage: http://dev.sipdoc.net/projects/ruby-xcapclient/wiki/
|
48
48
|
post_install_message:
|
49
49
|
rdoc_options:
|
50
50
|
- --main
|
51
51
|
- README.rdoc
|
52
|
+
- --title
|
53
|
+
- XCAPClient Documentation
|
52
54
|
require_paths:
|
53
55
|
- lib
|
54
56
|
required_ruby_version: !ruby/object:Gem::Requirement
|