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_STDIO_H
00029 #include <stdio.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 #include <libxml/tree.h>
00041 #include <libxml/uri.h>
00042
00043 #include <nanohttp/nanohttp-error.h>
00044 #include <nanohttp/nanohttp-logging.h>
00045
00046 #include "soap-fault.h"
00047 #include "soap-env.h"
00048 #include "soap-ctx.h"
00049 #include "soap-service.h"
00050 #include "soap-router.h"
00051 #include "soap-addressing.h"
00052 #include "soap-transport.h"
00053 #ifdef HAVE_XMLSEC1
00054 #include "soap-xmlsec.h"
00055 #endif
00056 #include "soap-server.h"
00057
00058 static SoapRouterNode *head = NULL;
00059 static SoapRouterNode *tail = NULL;
00060
00061 static SoapRouterNode *
00062 router_node_new(struct SoapRouter * router, const char *context, SoapRouterNode * next)
00063 {
00064 const char *noname = "/lost_found";
00065 SoapRouterNode *node;
00066
00067 if (!(node = (SoapRouterNode *) malloc(sizeof(SoapRouterNode))))
00068 {
00069 log_error2("malloc failed (%s)", strerror(errno));
00070 return NULL;
00071 }
00072
00073 if (context)
00074 {
00075 node->context = strdup(context);
00076 }
00077 else
00078 {
00079 log_warn2("context is null, using '%s'", noname);
00080 node->context = strdup(noname);
00081 }
00082
00083 node->router = router;
00084 node->next = next;
00085
00086 return node;
00087 }
00088
00089 static herror_t
00090 _soap_server_env_new_with_fault(const char *fault_string, const char *detail, struct SoapEnv **out)
00091 {
00092 return soap_env_new_with_fault(SOAP_FAULT_RECEIVER, fault_string, soap_server_get_name(), detail, out);
00093 }
00094
00095 static void
00096 _soap_server_fillup_header(struct SoapEnv *envelope)
00097 {
00098 xmlURI *uri;
00099
00100 log_verbose1(__FUNCTION__);
00101
00102 if (!(uri = soap_addressing_get_message_id(envelope)))
00103 soap_addressing_set_message_id_string(envelope, NULL);
00104 else
00105 xmlFreeURI(uri);
00106
00107 if (!(uri = soap_addressing_get_from_address(envelope)))
00108 soap_addressing_set_from_address_string(envelope, soap_server_get_name());
00109 else
00110 xmlFreeURI(uri);
00111
00112 return;
00113 }
00114
00115 struct SoapRouter *
00116 soap_server_find_router(const char *context)
00117 {
00118 SoapRouterNode *node;
00119
00120 for (node = head; node; node = node->next)
00121 {
00122 if (!strcmp(node->context, context))
00123 return node->router;
00124 }
00125
00126 return NULL;
00127 }
00128
00129
00130
00131 herror_t
00132 soap_server_process(struct SoapCtx *request, struct SoapCtx **response)
00133 {
00134 char buffer[1054];
00135 const char *urn;
00136 xmlURI *uri;
00137 const char *method;
00138 struct SoapRouter *router;
00139 SoapService *service;
00140 herror_t err;
00141
00142 log_verbose1("**** processing ****");
00143 xmlDocDump(stdout, request->env->root->doc);
00144 log_verbose1("********************");
00145
00146 *response = soap_ctx_new(NULL);
00147
00148 #ifdef HAVE_XMLSEC1
00149 if ((err = soap_xmlsec_verify(request)) != H_OK)
00150 {
00151 log_error2("soap_xmlsec_verify failed (%s)", herror_message(err));
00152 sprintf(buffer, "Verification of message signature failed (%s)", herror_message(err));
00153
00154 _soap_server_env_new_with_fault("Internal server error", buffer, &((*response)->env));
00155 return H_OK;
00156 }
00157
00158 if ((err = soap_xmlsec_decrypt(request)) != H_OK)
00159 {
00160 log_error2("soap_xmlsec_decrypt failed (%s)", herror_message(err));
00161 sprintf(buffer, "Decryption of message body failed (%s)", herror_message(err));
00162 _soap_server_env_new_with_fault("Internal server error", buffer, &((*response)->env));
00163 return H_OK;
00164 }
00165 #endif
00166
00167 if ((method = soap_env_find_methodname(request->env)))
00168 {
00169 log_verbose2("method: \"%s\"", method);
00170 if ((urn = soap_env_find_urn(request->env)))
00171 {
00172 log_verbose2("urn: \"%s\"", urn);
00173 if ((uri = soap_addressing_get_to_address(request->env)))
00174 {
00175 log_verbose2("searching router for \"%s\"", uri->path);
00176 if ((router = soap_server_find_router(uri->path)))
00177 {
00178 log_verbose2("router: %p", router);
00179 if ((service = soap_router_find_service(router, urn, method)))
00180 {
00181 log_verbose3("service (%p) found, function (%p)", service, service->func);
00182 switch (service->status)
00183 {
00184 case CSOAP_SERVICE_UP:
00185
00186 if ((err = service->func(request, *response)) == H_OK)
00187 {
00188 if ((*response)->env == NULL)
00189 {
00190 sprintf(buffer, "Service for \"%s\" returned no envelope", urn);
00191 _soap_server_env_new_with_fault("Internal service error", buffer, &((*response)->env));
00192 }
00193 }
00194 else
00195 {
00196 sprintf(buffer, "Service returned following error message: \"%s\"", herror_message(err));
00197 herror_release(err);
00198 _soap_server_env_new_with_fault("Internal service error", buffer, &((*response)->env));
00199 }
00200 break;
00201 case CSOAP_SERVICE_DOWN:
00202 default:
00203 sprintf(buffer, "Service for \"%s\" is down", urn);
00204 _soap_server_env_new_with_fault("Internal service error", buffer, &((*response)->env));
00205 break;
00206 }
00207 }
00208 else
00209 {
00210 sprintf(buffer, "no service for URN \"%s\" found", urn);
00211 _soap_server_env_new_with_fault(buffer, "The URN is not known by the server", &((*response)->env));
00212 }
00213 }
00214 else
00215 {
00216 sprintf(buffer, "no router for context \"%s\" found", uri->path);
00217 _soap_server_env_new_with_fault(buffer, "The method is unknown by the server", &((*response)->env));
00218 }
00219 xmlFreeURI(uri);
00220 }
00221 else
00222 {
00223 _soap_server_env_new_with_fault(buffer, "The destination address is missing", &((*response)->env));
00224 }
00225 }
00226 else
00227 {
00228 _soap_server_env_new_with_fault("No method found", "The method is missing in the SOAP envelope", &((*response)->env));
00229 }
00230 }
00231 else
00232 {
00233 _soap_server_env_new_with_fault("No URN found", "The URN is missing in the SOAP envelope", &((*response)->env));
00234 }
00235
00236 _soap_server_fillup_header((*response)->env);
00237
00238 #ifdef HAVE_XMLSEC1
00239 soap_xmlsec_encrypt(*response);
00240
00241 soap_xmlsec_sign(*response);
00242 #endif
00243
00244 return H_OK;
00245 }
00246
00247 herror_t
00248 soap_server_init_args(int argc, char **argv)
00249 {
00250 herror_t status;
00251
00252 if ((status = soap_transport_server_init_args(argc, argv)) != H_OK)
00253 {
00254 log_error2("soap_transport_server_init_args failed (%s)", herror_message(status));
00255 return status;
00256 }
00257
00258 #ifdef HAVE_XMLSEC1
00259 if ((status = soap_xmlsec_server_init_args(argc, argv)) != H_OK)
00260 {
00261 log_error2("soap_xmlsec_server_init_args failed (%s)", herror_message(status));
00262 return status;
00263 }
00264 #endif
00265
00266 return H_OK;
00267 }
00268
00269 const char *
00270 soap_server_get_name(void)
00271 {
00272 return soap_transport_get_name();
00273 }
00274
00275 herror_t
00276 soap_server_register_router(struct SoapRouter *router, const char *context)
00277 {
00278 herror_t status;
00279
00280 if ((status = soap_transport_register(context)) != H_OK)
00281 {
00282 log_error2("soap_transport_register failed (%s)", herror_message(status));
00283 return status;
00284 }
00285
00286 if (tail == NULL)
00287 {
00288 head = tail = router_node_new(router, context, NULL);
00289 }
00290 else
00291 {
00292 tail->next = router_node_new(router, context, NULL);
00293 tail = tail->next;
00294 }
00295
00296 return H_OK;
00297 }
00298
00299 SoapRouterNode *
00300 soap_server_get_routers(void)
00301 {
00302 return head;
00303 }
00304
00305 herror_t
00306 soap_server_run(void)
00307 {
00308 herror_t status;
00309
00310 if ((status = soap_transport_server_run()) != H_OK)
00311 return status;
00312
00313 return H_OK;
00314 }
00315
00316 void
00317 soap_server_destroy(void)
00318 {
00319 SoapRouterNode *node = head;
00320 SoapRouterNode *tmp;
00321
00322 while (node != NULL)
00323 {
00324 tmp = node->next;
00325 log_verbose2("soap_router_free(%p)", node->router);
00326 soap_router_free(node->router);
00327 free(node->context);
00328 free(node);
00329 node = tmp;
00330 }
00331
00332 soap_transport_server_destroy();
00333
00334 return;
00335 }