00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef HAVE_CONFIG_H
00025 #include <config.h>
00026 #endif
00027
00028 #ifdef HAVE_SYS_TYPES_H
00029 #include <sys/types.h>
00030 #endif
00031
00032 #ifdef HAVE_UUID_H
00033 #include <uuid.h>
00034 #endif
00035
00036 #ifdef HAVE_STDIO_H
00037 #include <stdio.h>
00038 #endif
00039
00040 #ifdef HAVE_STDLIB_H
00041 #include <stdlib.h>
00042 #endif
00043
00044 #ifdef HAVE_STRING_H
00045 #include <string.h>
00046 #endif
00047
00048 #ifdef HAVE_PTHREAD_H
00049 #include <pthread.h>
00050 #endif
00051
00052 #ifdef HAVE_ERRNO_H
00053 #include <errno.h>
00054 #endif
00055
00056 #ifdef HAVE_NETINET_IN_H
00057 #include <netinet/in.h>
00058 #endif
00059
00060 #include <libxml/tree.h>
00061 #include <libxml/xpath.h>
00062 #include <libxml/uri.h>
00063
00064 #include <nanohttp/nanohttp-error.h>
00065 #include <nanohttp/nanohttp-logging.h>
00066
00067 #include "soap-xml.h"
00068 #include "soap-fault.h"
00069 #include "soap-env.h"
00070 #include "soap-server.h"
00071 #include "soap-addressing.h"
00072
00073 #ifdef HAVE_UUID_CREATE
00074 static const xmlChar *
00075 _soap_addressing_uuid_error(uint32_t status)
00076 {
00077 switch(status)
00078 {
00079 case uuid_s_bad_version:
00080 return "The UUID does not have a known version";
00081 case uuid_s_invalid_string_uuid:
00082 return "The string representation of an UUID is not valid";
00083 case uuid_s_no_memory:
00084
00085 return "The meaning of the code escaped the writers mind";
00086 default:
00087 return "Unkown error during UUID creation";
00088 }
00089 }
00090
00091 static char *
00092 _soap_addressing_generate_id(void)
00093 {
00094 uuid_t uuid;
00095 uint32_t status;
00096 char *ret, *buf;
00097
00098 uuid_create(&uuid, &status);
00099 if (status != uuid_s_ok)
00100 {
00101 log_error2("uuidcreate failed (%s)", _soap_addressing_uuid_error(status));
00102 return NULL;
00103 }
00104
00105 uuid_to_string(&uuid, &buf, &status);
00106 if (status != uuid_s_ok)
00107 {
00108 log_error2("uuid_to_string failed (%s)", _soap_addressing_uuid_error(status));
00109 return NULL;
00110 }
00111
00112 if (!(ret = (char *)malloc(128)))
00113 {
00114 log_error2("malloc failed (%s)", strerror(errno));
00115 free(buf);
00116 return NULL;
00117 }
00118
00119 sprintf(ret, "%s/%s", soap_server_get_name(), buf);
00120
00121 free(buf);
00122
00123 return ret;
00124 }
00125 #else
00126 static char *
00127 _soap_addressing_generate_id(void)
00128 {
00129 char *ret;
00130 static long counter = 0;
00131 static pthread_mutex_t counter_lock = PTHREAD_MUTEX_INITIALIZER;
00132
00133 if (!(ret = (char *)malloc(128)))
00134 {
00135 log_error2("malloc failed (%s)", strerror(errno));
00136 return NULL;
00137 }
00138
00139 pthread_mutex_lock(&counter_lock);
00140 sprintf("%s/%li", soap_server_get_name(), counter);
00141 pthread_mutex_unlock(&counter_lock);
00142
00143 return ret;
00144 }
00145 #endif
00146
00147 static xmlNsPtr
00148 _soap_addressing_get_namespace(xmlNodePtr node)
00149 {
00150 xmlNsPtr ns;
00151
00152 if (!(ns = xmlSearchNsByHref(node->doc, node, BAD_CAST WSA_NAMESPACE)))
00153 {
00154 ns = xmlNewNs(node, BAD_CAST WSA_NAMESPACE, BAD_CAST WSA_NAMESPACE_PREFIX);
00155 }
00156 return ns;
00157 }
00158
00159 static xmlNodePtr
00160 _soap_addressing_add_node(xmlNodePtr parent, const xmlChar *name, const xmlChar *content)
00161 {
00162 xmlNsPtr ns;
00163
00164 ns = _soap_addressing_get_namespace(parent);
00165 return xmlNewChild(parent, ns, name, content);
00166 }
00167
00168 static xmlAttrPtr
00169 _soap_addressing_set_property(xmlNodePtr node, const xmlChar *name, const xmlChar *value)
00170 {
00171 xmlNsPtr ns;
00172
00173 ns = _soap_addressing_get_namespace(node);
00174 return xmlSetNsProp(node, ns, name, value);
00175 }
00176
00177 static xmlAttrPtr
00178 _soap_addressing_set_property_uri(xmlNodePtr node, const xmlChar *name, xmlURI *uri)
00179 {
00180 xmlChar *buf;
00181 xmlAttrPtr ret;
00182
00183 buf = xmlSaveUri(uri);
00184 ret = _soap_addressing_set_property(node, name, buf);
00185 xmlFree(buf);
00186
00187 return ret;
00188 }
00189
00190 static xmlNodePtr
00191 _soap_addressing_get_child_element(xmlNodePtr parent, const xmlChar *name)
00192 {
00193 xmlNodePtr walker;
00194
00195 for (walker = soap_xml_get_children(parent); walker; walker = soap_xml_get_next(walker))
00196 {
00197 if (!xmlStrcmp(walker->name, name) && !xmlStrcmp(walker->ns->href, WSA_NAMESPACE))
00198 return walker;
00199 }
00200 return NULL;
00201 }
00202
00203 static xmlURI *
00204 _soap_addressing_extract_uri(xmlNodePtr node)
00205 {
00206 xmlChar *content;
00207 xmlURI *uri = NULL;
00208
00209 if ((content = xmlNodeGetContent(node)))
00210 {
00211 uri = xmlParseURI(content);
00212 xmlFree(content);
00213 }
00214 return uri;
00215 }
00216
00217 static xmlNodePtr
00218 _soap_addressing_set_content_uri(xmlNodePtr node, xmlURI *uri)
00219 {
00220 xmlChar *buf;
00221
00222 if (uri == NULL)
00223 return NULL;
00224
00225 buf = xmlSaveUri(uri);
00226 xmlNodeSetContent(node, buf);
00227 xmlFree(buf);
00228
00229 return node;
00230 }
00231
00232 xmlURI *
00233 soap_addressing_get_address(xmlNodePtr endpoint_reference)
00234 {
00235 xmlNodePtr address;
00236
00237 address = _soap_addressing_get_child_element(endpoint_reference, WSA_ADDRESS);
00238 if (address == NULL)
00239 return NULL;
00240
00241 return _soap_addressing_extract_uri(address);
00242 }
00243
00244 xmlNodePtr
00245 soap_addressing_set_address(xmlNodePtr endpoint_reference, xmlURI *address)
00246 {
00247 xmlNodePtr node;
00248
00249 node = _soap_addressing_get_child_element(endpoint_reference, WSA_ADDRESS);
00250 if (node == NULL)
00251 node = _soap_addressing_add_node(endpoint_reference, WSA_ADDRESS, NULL);
00252
00253 return _soap_addressing_set_content_uri(node, address);
00254 }
00255
00256 xmlNodePtr
00257 soap_addressing_get_reference_properties(xmlNodePtr endpoint_reference)
00258 {
00259 return _soap_addressing_get_child_element(endpoint_reference, WSA_REFERENCE_PROPERTIES);
00260 }
00261
00262 xmlNodePtr
00263 soap_addressing_set_reference_properties(xmlNodePtr endpoint_reference, xmlNodePtr properties)
00264 {
00265 xmlNodePtr node;
00266
00267 node = soap_addressing_get_reference_properties(endpoint_reference);
00268 if (node != NULL)
00269 {
00270 xmlUnlinkNode(node);
00271 xmlFreeNode(node);
00272 }
00273
00274 node = xmlCopyNode(properties, 1);
00275 xmlUnlinkNode(node);
00276 xmlAddChild(endpoint_reference, node);
00277
00278 return node;
00279 }
00280
00281 xmlNodePtr
00282 soap_addressing_get_metadata(xmlNodePtr endpoint_reference)
00283 {
00284 return _soap_addressing_get_child_element(endpoint_reference, WSA_METADATA);
00285 }
00286
00287 xmlNodePtr
00288 soap_addressing_set_metadata(xmlNodePtr endpoint_reference, xmlNodePtr metadata)
00289 {
00290 xmlNodePtr node;
00291
00292 node = soap_addressing_get_metadata(endpoint_reference);
00293 if (node != NULL)
00294 {
00295 xmlUnlinkNode(node);
00296 xmlFreeNode(node);
00297 }
00298
00299 node = xmlCopyNode(metadata, 1);
00300 xmlUnlinkNode(node);
00301 xmlAddChild(endpoint_reference, node);
00302
00303 return node;
00304 }
00305
00306 xmlURI *
00307 soap_addressing_get_message_id(struct SoapEnv *envelope)
00308 {
00309 xmlNodePtr id;
00310
00311 id = _soap_addressing_get_child_element(envelope->header, WSA_MESSAGE_ID);
00312 if (id == NULL)
00313 return NULL;
00314
00315 return _soap_addressing_extract_uri(id);
00316 }
00317
00318 xmlNodePtr
00319 soap_addressing_set_message_id(struct SoapEnv *envelope, xmlURI *id)
00320 {
00321 xmlNodePtr node;
00322
00323 node = _soap_addressing_get_child_element(envelope->header, WSA_MESSAGE_ID);
00324 if (node == NULL)
00325 node = _soap_addressing_add_node(envelope->header, WSA_MESSAGE_ID, NULL);
00326
00327 return _soap_addressing_set_content_uri(node, id);
00328 }
00329
00330 xmlNodePtr
00331 soap_addressing_set_message_id_string(struct SoapEnv *envelope, xmlChar *id)
00332 {
00333 xmlNodePtr node;
00334 xmlChar *tmp;
00335
00336 if (id == NULL)
00337 tmp = _soap_addressing_generate_id();
00338 else
00339 tmp = id;
00340
00341 log_verbose2("setting message id = \"%s\"", tmp);
00342
00343 node = _soap_addressing_get_child_element(envelope->header, WSA_MESSAGE_ID);
00344 if (node == NULL)
00345 node = _soap_addressing_add_node(envelope->header, WSA_MESSAGE_ID, tmp);
00346 else
00347 xmlNodeSetContent(node, tmp);
00348
00349 if (id == NULL)
00350 xmlFree(tmp);
00351
00352 return node;
00353 }
00354
00355 xmlChar *soap_addressing_get_message_id_string(struct SoapEnv *envelope)
00356 {
00357 xmlURI *uri;
00358 xmlChar *ret;
00359
00360 if (!(uri = soap_addressing_get_message_id(envelope)))
00361 return NULL;
00362
00363 ret = xmlSaveUri(uri);
00364 xmlFreeURI(uri);
00365
00366 return ret;
00367 }
00368
00369 xmlNodePtr
00370 soap_addressing_get_relates_to(struct SoapEnv *envelope)
00371 {
00372 return _soap_addressing_get_child_element(envelope->header, WSA_RELATES_TO);
00373 }
00374
00375 xmlNodePtr
00376 soap_addressing_add_relates_to(struct SoapEnv *envelope, xmlURI *id, xmlURI *type)
00377 {
00378 xmlNodePtr node;
00379
00380 node = soap_addressing_get_relates_to(envelope);
00381 if (node != NULL)
00382 {
00383 xmlUnlinkNode(node);
00384 xmlFreeNode(node);
00385 }
00386
00387 node = _soap_addressing_add_node(envelope->header, WSA_RELATES_TO, NULL);
00388 _soap_addressing_set_content_uri(node, id);
00389 _soap_addressing_set_property_uri(node, WSA_RELATIONSHIP_TYPE, type);
00390
00391 return node;
00392 }
00393
00394 xmlNodePtr
00395 soap_addressing_get_reply_to(struct SoapEnv *envelope)
00396 {
00397 return _soap_addressing_get_child_element(envelope->header, WSA_REPLY_TO);
00398 }
00399
00400 xmlNodePtr
00401 soap_addressing_set_reply_to(struct SoapEnv *envelope, xmlNodePtr address)
00402 {
00403 xmlNodePtr ret;
00404 xmlNodePtr node;
00405
00406 node = soap_addressing_get_reply_to(envelope);
00407 if (node != NULL)
00408 {
00409 xmlUnlinkNode(node);
00410 xmlFreeNode(node);
00411 }
00412
00413 ret = _soap_addressing_add_node(envelope->header, WSA_REPLY_TO, NULL);
00414 node = xmlCopyNode(address, 1);
00415 xmlUnlinkNode(node);
00416 xmlAddChild(ret, node);
00417
00418 return ret;
00419 }
00420
00421 xmlURI *
00422 soap_addressing_get_reply_to_address(struct SoapEnv *envelope)
00423 {
00424 xmlNodePtr reply_to;
00425
00426 reply_to = soap_addressing_get_reply_to(envelope);
00427 if (reply_to == NULL)
00428 return NULL;
00429
00430 return soap_addressing_get_address(reply_to);
00431 }
00432
00433 xmlNodePtr
00434 soap_addressing_set_reply_to_address(struct SoapEnv *envelope, xmlURI *address)
00435 {
00436 xmlNodePtr ret;
00437 xmlNodePtr node;
00438
00439 node = soap_addressing_get_reply_to(envelope);
00440 if (node != NULL)
00441 {
00442 xmlUnlinkNode(node);
00443 xmlFreeNode(node);
00444 }
00445
00446 ret = _soap_addressing_add_node(envelope->header, WSA_REPLY_TO, NULL);
00447 soap_addressing_set_address(ret, address);
00448
00449 return ret;
00450 }
00451
00452 xmlNodePtr
00453 soap_addressing_set_from(struct SoapEnv *envelope, xmlNodePtr address)
00454 {
00455 xmlNodePtr ret;
00456 xmlNodePtr node;
00457
00458 node = soap_addressing_get_from(envelope);
00459 if (node != NULL)
00460 {
00461 xmlUnlinkNode(node);
00462 xmlFreeNode(node);
00463 }
00464
00465 ret = _soap_addressing_add_node(envelope->header, WSA_FROM, NULL);
00466 node = xmlCopyNode(address, 1);
00467 xmlUnlinkNode(node);
00468 xmlAddChild(ret, node);
00469
00470 return ret;
00471 }
00472
00473 xmlNodePtr
00474 soap_addressing_set_from_address_string(struct SoapEnv *envelope, const char *from)
00475 {
00476 xmlURI *uri;
00477 xmlNodePtr ret;
00478
00479 uri = xmlParseURI(from);
00480 ret = soap_addressing_set_from_address(envelope, uri);
00481 xmlFreeURI(uri);
00482
00483 return ret;
00484 }
00485
00486 xmlNodePtr
00487 soap_addressing_get_from(struct SoapEnv *envelope)
00488 {
00489 return _soap_addressing_get_child_element(envelope->header, WSA_FROM);
00490 }
00491
00492 xmlURI *
00493 soap_addressing_get_from_address(struct SoapEnv *envelope)
00494 {
00495 xmlNodePtr from;
00496
00497 from = soap_addressing_get_from(envelope);
00498 if (from == NULL)
00499 return NULL;
00500
00501 return soap_addressing_get_address(from);
00502 }
00503
00504 xmlChar *
00505 soap_addressing_get_from_address_string(struct SoapEnv *envelope)
00506 {
00507 xmlURI *uri;
00508 xmlChar *ret;
00509
00510 if (!(uri = soap_addressing_get_from_address(envelope)))
00511 return NULL;
00512
00513 ret = xmlSaveUri(uri);
00514 xmlFreeURI(uri);
00515
00516 return ret;
00517 }
00518
00519 xmlNodePtr
00520 soap_addressing_set_from_address(struct SoapEnv *envelope, xmlURI *address)
00521 {
00522 xmlNodePtr ret;
00523 xmlNodePtr node;
00524
00525 node = soap_addressing_get_from(envelope);
00526 if (node != NULL)
00527 {
00528 xmlUnlinkNode(node);
00529 xmlFreeNode(node);
00530 }
00531
00532 ret = _soap_addressing_add_node(envelope->header, WSA_FROM, NULL);
00533 soap_addressing_set_address(ret, address);
00534
00535 return ret;
00536 }
00537
00538 xmlNodePtr
00539 soap_addressing_get_fault_to(struct SoapEnv *envelope)
00540 {
00541 return _soap_addressing_get_child_element(envelope->header, WSA_FAULT_TO);
00542 }
00543
00544 xmlNodePtr
00545 soap_addressing_set_fault_to(struct SoapEnv *envelope, xmlNodePtr address)
00546 {
00547 xmlNodePtr ret;
00548 xmlNodePtr node;
00549
00550 node = soap_addressing_get_fault_to(envelope);
00551 if (node != NULL)
00552 {
00553 xmlUnlinkNode(node);
00554 xmlFreeNode(node);
00555 }
00556
00557 ret = _soap_addressing_add_node(envelope->header, WSA_FAULT_TO, NULL);
00558 node = xmlCopyNode(address, 1);
00559 xmlUnlinkNode(node);
00560 xmlAddChild(ret, node);
00561
00562 return ret;
00563 }
00564
00565 xmlURI *
00566 soap_addressing_get_fault_to_address(struct SoapEnv *envelope)
00567 {
00568 xmlNodePtr fault_to;
00569
00570 fault_to = soap_addressing_get_fault_to(envelope);
00571 if (fault_to == NULL)
00572 return NULL;
00573
00574 return soap_addressing_get_address(fault_to);
00575 }
00576
00577 xmlNodePtr
00578 soap_addressing_set_fault_to_address(struct SoapEnv *envelope, xmlURI *address)
00579 {
00580 xmlNodePtr ret;
00581 xmlNodePtr node;
00582
00583 node = soap_addressing_get_fault_to(envelope);
00584 if (node != NULL)
00585 {
00586 xmlUnlinkNode(node);
00587 xmlFreeNode(node);
00588 }
00589
00590 ret = _soap_addressing_add_node(envelope->header, WSA_FAULT_TO, NULL);
00591 soap_addressing_set_address(ret, address);
00592
00593 return ret;
00594 }
00595
00596 xmlNodePtr
00597 soap_addressing_get_to(struct SoapEnv *envelope)
00598 {
00599 return _soap_addressing_get_child_element(envelope->header, WSA_TO);
00600 }
00601
00602 xmlNodePtr
00603 soap_addressing_set_to(struct SoapEnv *envelope, xmlNodePtr address)
00604 {
00605 xmlNodePtr ret;
00606 xmlNodePtr node;
00607
00608 node = soap_addressing_get_to(envelope);
00609 if (node != NULL)
00610 {
00611 xmlUnlinkNode(node);
00612 xmlFreeNode(node);
00613 }
00614
00615 ret = _soap_addressing_add_node(envelope->header, WSA_TO, NULL);
00616 node = xmlCopyNode(address, 1);
00617 xmlUnlinkNode(node);
00618 xmlAddChild(ret, node);
00619
00620 return ret;
00621 }
00622
00623 xmlURI *
00624 soap_addressing_get_to_address(struct SoapEnv *envelope)
00625 {
00626 xmlNodePtr to;
00627
00628 if (!(to = soap_addressing_get_to(envelope)))
00629 return NULL;
00630
00631 return soap_addressing_get_address(to);
00632 }
00633
00634 xmlChar *
00635 soap_addressing_get_to_address_string(struct SoapEnv *envelope)
00636 {
00637 xmlURI *uri;
00638 xmlChar *ret;
00639
00640 if (!(uri = soap_addressing_get_to_address(envelope)))
00641 return NULL;
00642
00643 ret = xmlSaveUri(uri);
00644 xmlFreeURI(uri);
00645
00646 return ret;
00647 }
00648
00649 xmlNodePtr
00650 soap_addressing_set_to_address_string(struct SoapEnv *envelope, const char *to)
00651 {
00652 xmlURI *uri;
00653 xmlNodePtr ret;
00654
00655 if (!(uri = xmlParseURI(to)))
00656 return NULL;
00657
00658 ret = soap_addressing_set_to_address(envelope, uri);
00659 xmlFreeURI(uri);
00660
00661 return ret;
00662 }
00663
00664 xmlNodePtr
00665 soap_addressing_set_to_address(struct SoapEnv *envelope, xmlURI *address)
00666 {
00667 xmlNodePtr ret;
00668 xmlNodePtr node;
00669
00670 node = soap_addressing_get_to(envelope);
00671 if (node != NULL)
00672 {
00673 xmlUnlinkNode(node);
00674 xmlFreeNode(node);
00675 }
00676
00677 ret = _soap_addressing_add_node(envelope->header, WSA_TO, NULL);
00678 soap_addressing_set_address(ret, address);
00679
00680 return ret;
00681 }
00682
00683 xmlURI *
00684 soap_addressing_get_action(struct SoapEnv *envelope)
00685 {
00686 xmlNodePtr action;
00687
00688 action = _soap_addressing_get_child_element(envelope->header, WSA_ACTION);
00689 if (action == NULL)
00690 return NULL;
00691
00692 return _soap_addressing_extract_uri(action);
00693 }
00694
00695 xmlChar *
00696 soap_addressing_get_action_string(struct SoapEnv *envelope)
00697 {
00698 xmlURI *uri;
00699 xmlChar *ret;
00700
00701 if (!(uri = soap_addressing_get_action(envelope)))
00702 return NULL;
00703
00704 ret = xmlSaveUri(uri);
00705 xmlFreeURI(uri);
00706
00707 return ret;
00708 }
00709
00710 xmlNodePtr
00711 soap_addressing_set_action(struct SoapEnv *envelope, xmlURI *action)
00712 {
00713 xmlNodePtr node;
00714
00715 node = _soap_addressing_get_child_element(envelope->header, WSA_ACTION);
00716 if (node == NULL)
00717 node = _soap_addressing_add_node(envelope->header, WSA_ACTION, NULL);
00718
00719 return _soap_addressing_set_content_uri(node, action);
00720 }
00721
00722 xmlNodePtr
00723 soap_addressing_set_action_string(struct SoapEnv *envelope, const char *action)
00724 {
00725 xmlURI *uri;
00726 xmlNodePtr ret;
00727
00728 if (!(uri = xmlParseURI(action)))
00729 return NULL;
00730
00731 ret = soap_addressing_set_action(envelope, uri);
00732 xmlFreeURI(uri);
00733
00734 return ret;
00735 }