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_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
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
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
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
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
00276
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 }