soap-addressing.c

Go to the documentation of this file.
00001 /******************************************************************
00002 *  $Id: soap-addressing.c,v 1.11 2006/12/14 19:39:05 m0gg Exp $
00003 *
00004 * CSOAP Project:  A SOAP client/server library in C
00005 * Copyright (C) 2006 Heiko Ronsdorf
00006 *
00007 * This library is free software; you can redistribute it and/or
00008 * modify it under the terms of the GNU Library General Public
00009 * License as published by the Free Software Foundation; either
00010 * version 2 of the License, or (at your option) any later version.
00011 *
00012 * This library is distributed in the hope that it will be useful,
00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015 * Library General Public License for more details.
00016 *
00017 * You should have received a copy of the GNU Library General Public
00018 * License along with this library; if not, write to the
00019 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00020 * Boston, MA  02111-1307, USA.
00021 * 
00022 * Email: hero@persua.de
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       /* XXX: From FreeBSD 6.2 UUID(3) ??? */  
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 }

Generated on Thu Jan 25 23:36:03 2007 for csoap by  doxygen 1.4.6