soap-transport.c

Go to the documentation of this file.
00001 /******************************************************************
00002 *  $Id: soap-transport.c,v 1.9 2006/12/14 19:36:49 m0gg Exp $
00003 *
00004 * CSOAP Project:  A SOAP client/server library in C
00005 * Copyright (C) 2007 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_STDLIB_H
00029 #include <stdlib.h>
00030 #endif
00031 
00032 #ifdef HAVE_STRING_H
00033 #include <string.h>
00034 #endif
00035 
00036 #ifdef HAVE_ERRNO_H
00037 #include <errno.h>
00038 #endif
00039 
00040 #ifdef HAVE_UNISTD_H
00041 #include <unistd.h>
00042 #endif
00043 
00044 #include <libxml/tree.h>
00045 #include <libxml/uri.h>
00046 
00047 #include <nanohttp/nanohttp-error.h>
00048 #include <nanohttp/nanohttp-logging.h>
00049 
00050 #include "soap-fault.h"
00051 #include "soap-env.h"
00052 #include "soap-ctx.h"
00053 #include "soap-service.h"
00054 #include "soap-router.h"
00055 #include "soap-addressing.h"
00056 #include "soap-server.h"
00057 
00058 #include "soap-nhttp.h"
00059 #include "soap-nudp.h"
00060 
00061 #include "soap-transport.h"
00062 
00063 struct soap_transport
00064 {
00065   char *scheme;
00066   void *data;
00067   msg_exchange invoke;
00068   struct soap_transport *next;
00069 };
00070 
00071 static struct soap_transport *head = NULL;
00072 static char soap_transport_name[512] = "not set";
00073 
00074 static struct soap_transport *
00075 _soap_transport_new(const char *scheme, void *data, msg_exchange invoke)
00076 {
00077   struct soap_transport *ret;
00078 
00079   if (!(ret = (struct soap_transport *)malloc(sizeof(struct soap_transport))))
00080   {
00081     log_error2("malloc failed (%s)", strerror(errno));
00082     return NULL;
00083   }
00084 
00085   memset(ret, 0, sizeof(struct soap_transport));
00086 
00087   ret->scheme = strdup(scheme);
00088   ret->data = data;
00089   ret->invoke = invoke;
00090 
00091   log_verbose4("scheme=\"%s\", data=%p, invoke=%p", ret->scheme, ret->data, ret->invoke);
00092 
00093   return ret;
00094 }
00095 
00096 /* static void *
00097 _soap_transport_destroy(struct soap_transport *transport)
00098 {
00099   void *ret;
00100 
00101   if (transport->scheme)
00102     free(transport->scheme);
00103 
00104   ret = transport->data;
00105 
00106   free(transport);
00107 
00108   return ret;
00109 } */
00110 
00111 herror_t
00112 soap_transport_process(struct SoapCtx *request, struct SoapCtx **response)
00113 {
00114   return soap_server_process(request, response);
00115 }
00116 
00117 static herror_t
00118 _soap_transport_set_name(void)
00119 {
00120   static int set = 0;
00121   char hostname[256];
00122 
00123   if (set)
00124     return H_OK;
00125 
00126   gethostname(hostname, 256);
00127   sprintf(soap_transport_name, "%s://%s:%i", soap_nhttp_get_protocol(), hostname, soap_nhttp_get_port());
00128 
00129   set = 1;
00130 
00131   return H_OK;
00132 }
00133 
00134 herror_t
00135 soap_transport_server_init_args(int argc, char **argv)
00136 {
00137   herror_t status;
00138 
00139   if ((status = soap_nhttp_server_init_args(argc, argv)) != H_OK)
00140   {
00141     log_error2("soap_nhttp_server_init_args failed (%s)", herror_message(status));
00142     return status;
00143   }
00144 
00145   if ((status = soap_nudp_server_init_args(argc, argv)) != H_OK)
00146   {
00147     log_error2("soap_nudp_server_init_args failed (%s)", herror_message(status));
00148     return status;
00149   }
00150 
00151   if ((status = _soap_transport_set_name()) != H_OK)
00152   {
00153     log_error2("_soap_transport_set_name failed (%s)", herror_message(status));
00154     return status;
00155   }
00156 
00157   return H_OK;
00158 }
00159 
00160 herror_t
00161 soap_transport_register(const void *data)
00162 {
00163   herror_t status;
00164 
00165   if ((status = soap_nhttp_register(data)) != H_OK)
00166   {
00167     log_error2("soap_nhttp_register failed (%s)", herror_message(status));
00168     return status;
00169   }
00170 
00171   if ((status = soap_nudp_register(data)) != H_OK)
00172   {
00173     log_error2("soap_nudp_register failed (%s)", herror_message(status));
00174     return status;
00175   }
00176   
00177   return H_OK;
00178 }
00179 
00180 herror_t
00181 soap_transport_add(const char *scheme, void *data, msg_exchange invoke)
00182 {
00183   struct soap_transport *transport;
00184   struct soap_transport *walker;
00185 
00186   if (!(transport = _soap_transport_new(scheme, data, invoke)))
00187   {
00188     log_error1("_soap_transport_new failed");
00189     return herror_new("soap_transport_add", 0, "_soap_transport_new failed");
00190   }
00191 
00192   if (head == NULL)
00193   {
00194     head = transport;
00195   }
00196   else
00197   {
00198     for (walker=head; walker->next; walker=head->next);
00199       /* nothing */
00200     walker->next = transport;
00201   }
00202   return H_OK;
00203 }
00204 
00205 herror_t
00206 soap_transport_server_run(void)
00207 {
00208   herror_t status;
00209 
00210   if ((status = soap_nudp_server_run_threaded()) != H_OK)
00211   {
00212     log_error2("soap_nudp_server_run failed (%s)", herror_message(status));
00213     return status;
00214   }
00215 
00216   /* nanoHTTP blocks in this call */
00217   if ((status = soap_nhttp_server_run()) != H_OK)
00218   {
00219     log_error2("soap_nhttp_server_run failed (%s)", herror_message(status));
00220     return status;
00221   }
00222 
00223   return H_OK;
00224 }
00225  
00226 const char *
00227 soap_transport_get_name(void)
00228 {
00229   return soap_transport_name;
00230 }
00231 
00232 void
00233 soap_transport_server_destroy(void)
00234 {
00235   soap_nhttp_server_destroy();
00236 
00237   soap_nudp_server_destroy();
00238   
00239   return;
00240 }
00241 
00242 herror_t
00243 soap_transport_client_init_args(int argc, char **argv)
00244 {
00245   herror_t status;
00246 
00247   if ((status = soap_nhttp_client_init_args(argc, argv)) != H_OK)
00248   {
00249     log_error2("soap_nhttp_client_init_args failed (%s)", herror_message(status));
00250     return status;
00251   }
00252 
00253   if ((status = soap_nudp_client_init_args(argc, argv)) != H_OK)
00254   {
00255     log_error2("soap_nudp_client_init_args failed (%s)", herror_message(status));
00256     return status;
00257   }
00258 
00259   if ((status = _soap_transport_set_name()) != H_OK)
00260   {
00261     log_error2("_soap_transport_set_name failed (%s)", herror_message(status));
00262     return status;
00263   }
00264 
00265   return H_OK;
00266 }
00267 
00268 herror_t
00269 soap_transport_client_invoke(struct SoapCtx *request, struct SoapCtx **response)
00270 {
00271   struct soap_transport *walker;
00272   herror_t ret;
00273   xmlURI *dest;
00274   
00275   /* log_verbose1(__FUNCTION__);
00276    xmlDocFormatDump(stdout, request->env->root->doc, 1); */
00277 
00278   if (!(dest = soap_addressing_get_to_address(request->env)))
00279   {
00280     log_verbose1("soap_addressing_get_to_address failed");
00281     return herror_new("soap_transport_client_invoke", 0, "cannot find to address in SOAP envelope");
00282   }
00283 
00284   if (!dest->scheme)
00285   {
00286     log_verbose1("missing scheme (protocol) in to address");
00287     return herror_new("soap_transport_client_invoke", 0, "cannot find protocol in destination address");
00288   }
00289 
00290   log_verbose2("trying to contact \"%s\"", soap_addressing_get_to_address_string(request->env));
00291 
00292   for (walker=head; walker; walker=walker->next)
00293   {
00294     log_verbose3("testing transport server \"%s\" for \"%s\"", walker->scheme, dest->scheme);
00295     if (!strcmp(walker->scheme, dest->scheme))
00296     {
00297       log_verbose3("found transport layer for \"%s\" (%p)", dest->scheme, walker->invoke);
00298       ret = walker->invoke(walker->data, request, response);
00299       xmlFreeURI(dest);
00300       return ret;
00301     }
00302   }
00303 
00304   ret = herror_new("soap_transport_client_invoke", 0, "no transport service found for \"%s\"", dest->scheme);
00305   xmlFreeURI(dest);
00306 
00307   return ret;
00308 }
00309 
00310 void
00311 soap_transport_client_destroy(void)
00312 {
00313   soap_nhttp_client_destroy();
00314 
00315   soap_nudp_client_destroy();
00316 
00317   return;
00318 }

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