From 65985c4e6527c82a75367d9c5418b009dfbc6379 Mon Sep 17 00:00:00 2001 From: m0gg Date: Sun, 26 Nov 2006 20:13:05 +0000 Subject: soap.udp transport added (alpha) --- libcsoap/soap-addressing.c | 9 +- libcsoap/soap-admin.c | 3 +- libcsoap/soap-env.c | 15 ++- libcsoap/soap-nhttp.c | 19 ++-- libcsoap/soap-nhttp.h | 4 +- libcsoap/soap-nudp.c | 254 +++++++++++++++++++++++++++++++++++++++++++-- libcsoap/soap-nudp.h | 20 ++-- libcsoap/soap-server.c | 5 +- libcsoap/soap-transport.c | 20 ++-- libcsoap/soap-xml.c | 28 ++--- 10 files changed, 319 insertions(+), 58 deletions(-) (limited to 'libcsoap') diff --git a/libcsoap/soap-addressing.c b/libcsoap/soap-addressing.c index 9e89f49..2069bd7 100644 --- a/libcsoap/soap-addressing.c +++ b/libcsoap/soap-addressing.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: soap-addressing.c,v 1.6 2006/11/25 17:03:20 m0gg Exp $ +* $Id: soap-addressing.c,v 1.7 2006/11/26 20:13:05 m0gg Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2006 Heiko Ronsdorf @@ -41,6 +41,10 @@ #include #endif +#ifdef HAVE_STRING_H +#include +#endif + #ifdef HAVE_ERRNO_H #include #endif @@ -59,6 +63,7 @@ #include "soap-xml.h" #include "soap-fault.h" #include "soap-env.h" +#include "soap-server.h" #include "soap-addressing.h" static const xmlChar * @@ -189,7 +194,7 @@ _soap_addressing_set_content_uri(xmlNodePtr node, xmlURI *uri) xmlChar *buf; if (uri == NULL) - return; + return NULL; buf = xmlSaveUri(uri); xmlNodeSetContent(node, buf); diff --git a/libcsoap/soap-admin.c b/libcsoap/soap-admin.c index 81310ed..715e3ca 100644 --- a/libcsoap/soap-admin.c +++ b/libcsoap/soap-admin.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: soap-admin.c,v 1.9 2006/11/25 16:35:57 m0gg Exp $ +* $Id: soap-admin.c,v 1.10 2006/11/26 20:13:05 m0gg Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -46,6 +46,7 @@ #include #include +#include #include #include #include diff --git a/libcsoap/soap-env.c b/libcsoap/soap-env.c index 04146f4..99cf3ba 100644 --- a/libcsoap/soap-env.c +++ b/libcsoap/soap-env.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: soap-env.c,v 1.26 2006/11/25 15:06:57 m0gg Exp $ +* $Id: soap-env.c,v 1.27 2006/11/26 20:13:05 m0gg Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -167,7 +167,7 @@ xmlbuilder_end_element(const xmlChar * element_name, void *userData) herror_t soap_env_new_from_doc(xmlDocPtr doc, struct SoapEnv ** out) { - xmlNodePtr node; + xmlNodePtr root; struct SoapEnv *env; if (doc == NULL) @@ -178,7 +178,7 @@ soap_env_new_from_doc(xmlDocPtr doc, struct SoapEnv ** out) "XML Document (xmlDocPtr) is NULL"); } - if (!(node = xmlDocGetRootElement(doc))) + if (!(root = xmlDocGetRootElement(doc))) { log_error1("XML document is empty!"); return herror_new("soap_env_new_from_doc", @@ -191,7 +191,7 @@ soap_env_new_from_doc(xmlDocPtr doc, struct SoapEnv ** out) return herror_new("soap_env_from_doc", GENERAL_INVALID_PARAM, "malloc failed (%s)", strerror(errno)); } - env->root = node; + env->root = root; env->header = soap_env_get_header(env); env->body = soap_env_get_body(env); env->cur = soap_env_get_method(env); @@ -201,7 +201,6 @@ soap_env_new_from_doc(xmlDocPtr doc, struct SoapEnv ** out) return H_OK; } - herror_t soap_env_new_from_buffer(const char *buffer, struct SoapEnv **out) { @@ -446,13 +445,13 @@ soap_env_get_body(struct SoapEnv * env) if (env == NULL) { - log_error1("env object is NULL"); + log_error1("SOAP envelope is NULL"); return NULL; } if (env->root == NULL) { - log_error1("env has no xml"); + log_error1("SOAP envelope contains no XML"); return NULL; } @@ -525,7 +524,7 @@ soap_env_get_method(struct SoapEnv * env) if (!(body = soap_env_get_body(env))) { - log_verbose1("SoapEnv contains no Body"); + log_verbose1("SoapEnv contains no Body element"); return NULL; } diff --git a/libcsoap/soap-nhttp.c b/libcsoap/soap-nhttp.c index ce48394..84a9ddc 100644 --- a/libcsoap/soap-nhttp.c +++ b/libcsoap/soap-nhttp.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: soap-nhttp.c,v 1.4 2006/11/25 16:35:57 m0gg Exp $ +* $Id: soap-nhttp.c,v 1.5 2006/11/26 20:13:05 m0gg Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -415,25 +415,31 @@ _soap_nhttp_client_invoke(void *unused, struct SoapCtx *request, struct SoapCtx herror_t soap_nhttp_client_init_args(int argc, char **argv) { + herror_t status; + + if ((status = httpc_init(argc, argv)) != H_OK) + { + log_error2("httpc_init failed (%s)", herror_message(status)); + return status; + } + soap_transport_add("https", NULL, _soap_nhttp_client_invoke); soap_transport_add("http", NULL, _soap_nhttp_client_invoke); - return httpc_init(argc, argv); + return H_OK; } herror_t -soap_nhttp_register(const void *data) +soap_nhttp_register(const char *context) { herror_t status; - const char *context; - - context = (char *)data; if ((status = httpd_register(context, soap_nhttp_process)) != H_OK) { log_error2("httpd_register_secure failed (%s)", herror_message(status)); return status; } + return H_OK; } @@ -470,4 +476,3 @@ soap_nhttp_get_protocol(void) { return httpd_get_protocol(); } - diff --git a/libcsoap/soap-nhttp.h b/libcsoap/soap-nhttp.h index acb5dc3..ebf107d 100644 --- a/libcsoap/soap-nhttp.h +++ b/libcsoap/soap-nhttp.h @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: soap-nhttp.h,v 1.2 2006/11/23 15:27:33 m0gg Exp $ +* $Id: soap-nhttp.h,v 1.3 2006/11/26 20:13:05 m0gg Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2007 Heiko Ronsdorf @@ -47,7 +47,7 @@ extern herror_t soap_nhttp_server_init_args(int argc, char **argv); extern herror_t soap_nhttp_server_run(void); extern void soap_nhttp_server_destroy(void); -extern herror_t soap_nhttp_register(const void *data); +extern herror_t soap_nhttp_register(const char *context); extern short soap_nhttp_get_port(void); extern const char *soap_nhttp_get_protocol(void); diff --git a/libcsoap/soap-nudp.c b/libcsoap/soap-nudp.c index 61c3169..3c0cf70 100644 --- a/libcsoap/soap-nudp.c +++ b/libcsoap/soap-nudp.c @@ -1,8 +1,8 @@ /****************************************************************** -* $Id: soap-nudp.c,v 1.4 2006/11/25 17:03:20 m0gg Exp $ +* $Id: soap-nudp.c,v 1.5 2006/11/26 20:13:05 m0gg Exp $ * * CSOAP Project: A SOAP client/server library in C -* Copyright (C) 2003 Ferhat Ayaz +* Copyright (C) 2006 Heiko Ronsdorf * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -19,20 +19,56 @@ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * -* Email: ayaz@jprogrammer.net +* Email: hero@persua.de ******************************************************************/ #ifdef HAVE_CONFIG_H #include #endif +#ifdef HAVE_SYS_TYPES_H +#include +#endif + +#ifdef HAVE_SYS_SOCKET_H +#include +#endif + +#ifdef HAVE_STDLIB_H +#include +#endif + #ifdef HAVE_STDIO_H #include #endif +#ifdef HAVE_STRING_H +#include +#endif + #ifdef HAVE_ERRNO_H #include #endif +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_PTHREAD_H +#include +#endif + +#ifdef HAVE_NETDB_H +#include +#endif + +#ifdef HAVE_NETINET_IN_H +#include +#endif + +#ifdef HAVE_ARPA_INET_H +#include +#endif + #include #include @@ -45,11 +81,165 @@ #include "soap-service.h" #include "soap-router.h" #include "soap-server.h" +#include "soap-transport.h" #include "soap-addressing.h" +#include "soap-nudp.h" + +static short _soap_nudp_port = NUDP_DEFAULT_PORT; +static int _soap_nudp_socket; +static pthread_t _soap_nudp_thread; +static pthread_attr_t _soap_nudp_attr; + +static short +_soap_nudp_server_set_port(void) +{ + struct servent *entry; + + if (!(entry = getservbyname("soap", "udp"))) + { + log_warn1("getservbyname returned NULL"); + _soap_nudp_port = NUDP_DEFAULT_PORT; + } + else + { + _soap_nudp_port = entry->s_port; + } + return _soap_nudp_port; +} + +static void +_soap_nudp_server_parse_arguments(int argc, char **argv) +{ + int i; + + for (i=1; ienv))) + { + log_error1("soap_addressing_get_to_address returned NULL"); + return herror_new("soap_nudp_client_invoke", 0, "Destination address is missing"); + } + + bzero(&addr, sizeof(struct sockaddr_in)); + addr.sin_family = AF_INET; + if (to->port == 0) + addr.sin_port = htons(NUDP_DEFAULT_PORT); + else + addr.sin_port = htons(to->port); + + if (inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr) != 1) + { + log_error2("inet_pton failed (%s)", strerror(errno)); + return herror_new("soap_nudp_client_invoke", 0, "Cannot resolve destination address"); + } + + if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) + { + log_error2("socket failed (%s)", strerror(errno)); + return herror_new("soap_nudp_client_invoke", 0, "Cannot create socket"); + } + + _soap_nudp_send_document(sd, req->env->root->doc, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)); + + if ((status = _soap_nudp_receive_document(sd, &doc, NULL, NULL)) != H_OK) + { + log_error2("_soap_nudp_receive_document failed (%s)", herror_message(status)); + return status; + } + + if ((status = soap_env_new_from_doc(doc, &(*res)->env)) != H_OK) + { + log_error2("soap_env_new_from_doc failed (%s)", herror_message(status)); + return status; + } + + return H_OK; +} herror_t soap_nudp_server_init_args(int argc, char **argv) { + struct sockaddr_in addr; + + _soap_nudp_server_set_port(); + + _soap_nudp_server_parse_arguments(argc, argv); + + if ((_soap_nudp_socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) + { + log_error2("socket failed (%s)", strerror(errno)); + return herror_new("soap_nudp_server_init_args", 0, "Cannot create socket (%s)", strerror(errno)); + } + + memset(&addr, 0, sizeof(struct sockaddr_in)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(INADDR_ANY); + addr.sin_port = htons(_soap_nudp_port); + + if (bind(_soap_nudp_socket, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) + { + log_error2("bind failed (%s)", strerror(errno)); + return herror_new("soap_nudp_server_init_args", 0, "Cannot bind socket (%s)", strerror(errno)); + } + return H_OK; } @@ -59,27 +249,73 @@ soap_nudp_register(const void *data) return H_OK; } +void * +soap_nudp_server_run(void *unused) +{ + xmlDocPtr doc; + struct sockaddr addr; + socklen_t addr_len; + struct SoapCtx *req; + struct SoapCtx *res; + xmlURI *to; + + for(;;) + { + _soap_nudp_receive_document(_soap_nudp_socket, &doc, &addr, &addr_len); + + xmlDocFormatDump(stdout, doc, 1); + + req = soap_ctx_new(NULL); + + soap_env_new_from_doc(doc, &(req->env)); + + /* only local part is interesting */ + to = soap_addressing_get_to_address(req->env); + soap_addressing_set_to_address_string(req->env, to->path); + + xmlFreeDoc(doc); + + soap_transport_process(req, &res); + + _soap_nudp_send_document(_soap_nudp_socket, res->env->root->doc, &addr, addr_len); + + soap_ctx_free(res); + + soap_ctx_free(req); + } + + return NULL; +} + herror_t -soap_nudp_server_run(void) +soap_nudp_server_run_threaded(void) { + int err; + + if ((err = pthread_create(&_soap_nudp_thread, &_soap_nudp_attr, soap_nudp_server_run, NULL)) < 0) + { + log_error2("pthread_create failed (%s)", strerror(err)); + return herror_new("soap_nudp_server_run_threaded", 0, "pthread_create failed (%s)", strerror(err)); + } + return H_OK; } void soap_nudp_server_destroy(void) { + + close(_soap_nudp_socket); + return; } + herror_t soap_nudp_client_init_args(int argc, char **argv) { - return H_OK; -} + soap_transport_add("soap.udp", NULL, _soap_nudp_client_invoke); -herror_t -soap_nudp_client_invoke(struct SoapCtx *req, struct SoapCtx **res) -{ return H_OK; } diff --git a/libcsoap/soap-nudp.h b/libcsoap/soap-nudp.h index 9b703ae..8978b70 100644 --- a/libcsoap/soap-nudp.h +++ b/libcsoap/soap-nudp.h @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: soap-nudp.h,v 1.2 2006/11/23 15:27:33 m0gg Exp $ +* $Id: soap-nudp.h,v 1.3 2006/11/26 20:13:05 m0gg Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2007 Heiko Ronsdorf @@ -21,23 +21,27 @@ * * Email: hero@persua.de ******************************************************************/ -#ifndef __soap_nudp_h -#define __soap_nudp_h +#ifndef __csoap_nudp_h +#define __csoap_nudp_h + +#ifdef __CSOAP_INTERNAL + +#define NUDP_ARG_PORT "-NUDPport" + +#define NUDP_DEFAULT_PORT 10001 #ifdef __cplusplus extern "C" { #endif extern herror_t soap_nudp_server_init_args(int argc, char **argv); -extern herror_t soap_nudp_server_run(void); +extern void *soap_nudp_server_run(void *unused); +extern herror_t soap_nudp_server_run_threaded(void); extern void soap_nudp_server_destroy(void); -#ifdef __CSOAP_INTERNAL extern herror_t soap_nudp_register(const void *data); -#endif extern herror_t soap_nudp_client_init_args(int argc, char **argv); -extern herror_t soap_nudp_client_invoke(struct SoapCtx *req, struct SoapCtx **res); extern void soap_nudp_client_destroy(void); #ifdef __cplusplus @@ -45,3 +49,5 @@ extern void soap_nudp_client_destroy(void); #endif #endif + +#endif diff --git a/libcsoap/soap-server.c b/libcsoap/soap-server.c index 2f7a0b2..cee9643 100644 --- a/libcsoap/soap-server.c +++ b/libcsoap/soap-server.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: soap-server.c,v 1.32 2006/11/25 15:06:57 m0gg Exp $ +* $Id: soap-server.c,v 1.33 2006/11/26 20:13:05 m0gg Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -163,6 +163,7 @@ soap_server_process(struct SoapCtx *request, struct SoapCtx **response) log_verbose2("urn: \"%s\"", urn); if ((to = soap_addressing_get_to_address_string(request->env))) { + log_verbose2("searching router for \"%s\"", to); if ((router = soap_server_find_router(to))) { log_verbose2("router: %p", router); @@ -173,7 +174,7 @@ soap_server_process(struct SoapCtx *request, struct SoapCtx **response) { if ((*response)->env == NULL) { - sprintf(buffer, "Service \"%s\" returned no envelope", urn); + sprintf(buffer, "Service for \"%s\" returned no envelope", urn); _soap_server_env_new_with_fault("Internal service error", buffer, &((*response)->env)); } } diff --git a/libcsoap/soap-transport.c b/libcsoap/soap-transport.c index 6b0444b..3cd46e8 100644 --- a/libcsoap/soap-transport.c +++ b/libcsoap/soap-transport.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: soap-transport.c,v 1.4 2006/11/25 17:03:20 m0gg Exp $ +* $Id: soap-transport.c,v 1.5 2006/11/26 20:13:05 m0gg Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2007 Heiko Ronsdorf @@ -33,6 +33,10 @@ #include #endif +#ifdef HAVE_UNISTD_H +#include +#endif + #include #include @@ -85,7 +89,7 @@ _soap_transport_new(const char *scheme, void *data, msg_exchange invoke) return ret; } -static void * +/* static void * _soap_transport_destroy(struct soap_transport *transport) { void *ret; @@ -98,8 +102,7 @@ _soap_transport_destroy(struct soap_transport *transport) free(transport); return ret; -} - +} */ herror_t soap_transport_process(struct SoapCtx *request, struct SoapCtx **response) @@ -181,15 +184,16 @@ soap_transport_server_run(void) { herror_t status; - if ((status = soap_nhttp_server_run()) != H_OK) + if ((status = soap_nudp_server_run_threaded()) != H_OK) { - log_error2("soap_nhttp_server_run failed (%s)", herror_message(status)); + log_error2("soap_nudp_server_run failed (%s)", herror_message(status)); return status; } - if ((status = soap_nudp_server_run()) != H_OK) + /* nanoHTTP blocks in this call */ + if ((status = soap_nhttp_server_run()) != H_OK) { - log_error2("soap_nudp_server_run failed (%s)", herror_message(status)); + log_error2("soap_nhttp_server_run failed (%s)", herror_message(status)); return status; } diff --git a/libcsoap/soap-xml.c b/libcsoap/soap-xml.c index e4cc894..f718faf 100644 --- a/libcsoap/soap-xml.c +++ b/libcsoap/soap-xml.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: soap-xml.c,v 1.12 2006/11/23 15:27:33 m0gg Exp $ +* $Id: soap-xml.c,v 1.13 2006/11/26 20:13:05 m0gg Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -25,6 +25,7 @@ #include #endif +#include #include #include @@ -33,32 +34,35 @@ #include "soap-xml.h" xmlNodePtr -soap_xml_get_children(xmlNodePtr param) +soap_xml_get_children(xmlNodePtr node) { - xmlNodePtr children; + xmlNodePtr child; - if (param == NULL) + if (node == NULL) { - log_error1("Invalid parameter 'param' (null)"); + log_error1("Invalid node (null)"); return NULL; } - children = param->xmlChildrenNode; - while (children != NULL) + for (child = node->children; child; child=child->next) { - if (children->type != XML_ELEMENT_NODE) - children = children->next; - else - break; + if (child->type == XML_ELEMENT_NODE) + return child; } - return children; + return NULL; } xmlNodePtr soap_xml_get_next(xmlNodePtr param) { + if (param == NULL) + { + log_error1("Invalid node (null)"); + return NULL; + } + xmlNodePtr node = param->next; while (node != NULL) -- cgit v1.1-32-gdbae