diff options
author | m0gg | 2006-11-21 20:58:59 +0000 |
---|---|---|
committer | m0gg | 2006-11-21 20:58:59 +0000 |
commit | c3fd98b25607d0f7f5977586d188f88ab226a9b8 (patch) | |
tree | cc4976a3be9d3984e4ae62c08afd1dcf9530dc5e | |
parent | cd94b25993049a596b163f0ad8b3a2340e024cc3 (diff) | |
download | csoap-c3fd98b25607d0f7f5977586d188f88ab226a9b8.tar.gz csoap-c3fd98b25607d0f7f5977586d188f88ab226a9b8.tar.bz2 |
decoupling of nanohttp/libcsoap
38 files changed, 1679 insertions, 903 deletions
@@ -1,10 +1,8 @@ -
+
------------------------------------------------------------
ERROR HANDLING !!!!
------------------------------------------------------------
-Merge
-
mime_message_t *
mime_message_parse(http_input_stream_t *in,
@@ -16,4 +14,3 @@ and try to optimize mime API ------------------------------------------------------------
check socket API again
-
diff --git a/examples/csoap/echoattachments-client.c b/examples/csoap/echoattachments-client.c index 49d1931..b128563 100755 --- a/examples/csoap/echoattachments-client.c +++ b/examples/csoap/echoattachments-client.c @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: echoattachments-client.c,v 1.12 2006/11/19 09:40:14 m0gg Exp $ + * $Id: echoattachments-client.c,v 1.13 2006/11/21 20:58:59 m0gg Exp $ * * CSOAP Project: CSOAP examples project * Copyright (C) 2003-2004 Ferhat Ayaz @@ -24,6 +24,8 @@ #include <stdio.h> #include <netinet/in.h> +#include <libxml/tree.h> + #include <nanohttp/nanohttp-common.h> #include <nanohttp/nanohttp-socket.h> #include <nanohttp/nanohttp-stream.h> @@ -32,6 +34,8 @@ #include <nanohttp/nanohttp-client.h> #include <nanohttp/nanohttp-logging.h> +#include <libcsoap/soap-env.h> +#include <libcsoap/soap-ctx.h> #include <libcsoap/soap-client.h> diff --git a/examples/csoap/echoattachments-server.c b/examples/csoap/echoattachments-server.c index 5543984..a065cc5 100755 --- a/examples/csoap/echoattachments-server.c +++ b/examples/csoap/echoattachments-server.c @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: echoattachments-server.c,v 1.9 2006/11/19 09:40:14 m0gg Exp $ + * $Id: echoattachments-server.c,v 1.10 2006/11/21 20:58:59 m0gg Exp $ * * CSOAP Project: CSOAP examples project * Copyright (C) 2003-2004 Ferhat Ayaz @@ -20,10 +20,12 @@ * * Email: ferhatayaz@yahoo.com ******************************************************************/ -#include <sys/time.h> #include <stdio.h> +#include <stdlib.h> #include <netinet/in.h> +#include <libxml/tree.h> + #include <nanohttp/nanohttp-common.h> #include <nanohttp/nanohttp-socket.h> #include <nanohttp/nanohttp-stream.h> @@ -32,16 +34,16 @@ #include <nanohttp/nanohttp-server.h> #include <nanohttp/nanohttp-logging.h> +#include <libcsoap/soap-env.h> +#include <libcsoap/soap-ctx.h> +#include <libcsoap/soap-service.h> +#include <libcsoap/soap-router.h> #include <libcsoap/soap-server.h> - static const char *url = "/echoattachments"; static const char *urn = "urn:examples"; static const char *method = "echo"; - - - herror_t echo_attachments(SoapCtx * req, SoapCtx * res) { diff --git a/examples/csoap/simpleclient.c b/examples/csoap/simpleclient.c index 47ffd32..6a4451e 100644 --- a/examples/csoap/simpleclient.c +++ b/examples/csoap/simpleclient.c @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: simpleclient.c,v 1.13 2006/11/19 09:40:14 m0gg Exp $ + * $Id: simpleclient.c,v 1.14 2006/11/21 20:58:59 m0gg Exp $ * * CSOAP Project: CSOAP examples project * Copyright (C) 2003-2004 Ferhat Ayaz @@ -20,10 +20,12 @@ * * Email: ferhatayaz@yahoo.com ******************************************************************/ -#include <sys/time.h> #include <stdio.h> +#include <stdlib.h> #include <netinet/in.h> +#include <libxml/tree.h> + #include <nanohttp/nanohttp-common.h> #include <nanohttp/nanohttp-socket.h> #include <nanohttp/nanohttp-stream.h> @@ -34,11 +36,9 @@ #include <libcsoap/soap-client.h> - -static const char *url = "http://localhost:10000/csoapserver"; -static const char *urn = "urn:examples"; -static const char *method = "sayHello"; - +static char *url = "http://localhost:10000/csoapserver"; +static char *urn = "urn:examples"; +static char *method = "sayHello"; int main(int argc, char *argv[]) @@ -46,45 +46,48 @@ main(int argc, char *argv[]) SoapCtx *ctx, *ctx2; herror_t err; - /* log_set_level(HLOG_VERBOSE); */ + // hlog_set_level(HLOG_VERBOSE); + err = soap_client_init_args(argc, argv); if (err != H_OK) { - log_error4("%s():%s [%d]", herror_func(err), herror_message(err), - herror_code(err)); + printf("%s():%s [%d]", herror_func(err), herror_message(err), herror_code(err)); herror_release(err); - return 1; + exit(1); } err = soap_ctx_new_with_method(urn, method, &ctx); if (err != H_OK) { - log_error4("%s():%s [%d]", herror_func(err), herror_message(err), - herror_code(err)); + printf("%s():%s [%d]", herror_func(err), herror_message(err), herror_code(err)); herror_release(err); - return 1; + exit(1); } soap_env_add_item(ctx->env, "xsd:string", "name", "Jonny B. Good"); + printf("**** sending ****\n"); + soap_xml_doc_print(ctx->env->root->doc); + if (argc > 1) - err = soap_client_invoke(ctx, &ctx2, argv[1], ""); - else - err = soap_client_invoke(ctx, &ctx2, url, ""); + url = argv[1]; + printf("destination: \"%s\"\n", url); - if (err != H_OK) + if ((err = soap_client_invoke(ctx, &ctx2, url, "")) != H_OK) { - log_error4("[%d] %s(): %s ", herror_code(err), herror_func(err), - herror_message(err)); + printf("[%d] %s(): %s ", herror_code(err), herror_func(err), herror_message(err)); herror_release(err); soap_ctx_free(ctx); - return 1; + exit(1); } + printf("**** received ****\n"); soap_xml_doc_print(ctx2->env->root->doc); + soap_ctx_free(ctx2); soap_ctx_free(ctx); soap_client_destroy(); + return 0; } diff --git a/examples/csoap/simpleserver.c b/examples/csoap/simpleserver.c index 33e1a3c..a433783 100644 --- a/examples/csoap/simpleserver.c +++ b/examples/csoap/simpleserver.c @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: simpleserver.c,v 1.20 2006/11/19 09:40:14 m0gg Exp $ + * $Id: simpleserver.c,v 1.21 2006/11/21 20:59:02 m0gg Exp $ * * CSOAP Project: CSOAP examples project * Copyright (C) 2003-2004 Ferhat Ayaz @@ -20,10 +20,12 @@ * * Email: ferhatayaz@yahoo.com ******************************************************************/ -#include <sys/time.h> #include <stdio.h> +#include <stdlib.h> #include <netinet/in.h> +#include <libxml/tree.h> + #include <nanohttp/nanohttp-common.h> #include <nanohttp/nanohttp-socket.h> #include <nanohttp/nanohttp-stream.h> @@ -32,21 +34,25 @@ #include <nanohttp/nanohttp-server.h> #include <nanohttp/nanohttp-logging.h> +#include <libcsoap/soap-xml.h> +#include <libcsoap/soap-env.h> +#include <libcsoap/soap-ctx.h> +#include <libcsoap/soap-service.h> +#include <libcsoap/soap-router.h> #include <libcsoap/soap-server.h> - -static const char *url = "/csoapserver"; -static const char *urn = "urn:examples"; -static const char *method = "sayHello"; - +static const char const *url = "/csoapserver"; +static const char const *urn = "urn:examples"; +static const char const *method = "sayHello"; herror_t say_hello(SoapCtx * req, SoapCtx * res) { - herror_t err; char *name; + log_verbose1("service request"); + xmlNodePtr method, node; err = soap_env_new_with_response(req->env, &res->env); @@ -69,7 +75,6 @@ say_hello(SoapCtx * req, SoapCtx * res) return H_OK; } - int main(int argc, char *argv[]) { @@ -77,25 +82,46 @@ main(int argc, char *argv[]) herror_t err; SoapRouter *router; - hlog_set_level(HLOG_INFO); + // hlog_set_level(HLOG_VERBOSE); - err = soap_server_init_args(argc, argv); - if (err != H_OK) + if ((err = soap_server_init_args(argc, argv)) != H_OK) + { + printf("%s(): %s [%d]\n", herror_func(err), herror_message(err), herror_code(err)); + herror_release(err); + exit(1); + } + + if (!(router = soap_router_new())) { - log_error4("%s():%s [%d]", herror_func(err), herror_message(err), - herror_code(err)); + printf("soap_router_new failed (%p)\n", router); herror_release(err); - return 1; + exit(1); } - router = soap_router_new(); - soap_router_register_service(router, say_hello, method, urn); - soap_server_register_router(router, url); + if ((err = soap_router_register_service(router, say_hello, method, urn)) != H_OK) + { + printf("%s(): %s [%d]\n", herror_func(err), herror_message(err), herror_code(err)); + herror_release(err); + exit(1); + } - log_info1("press ctrl-c to shutdown"); - soap_server_run(); + if ((err = soap_server_register_router(router, url))) + { + printf("%s(): %s [%s]\n", herror_func(err), herror_message(err), herror_code(err)); + herror_release(err); + exit(1); + } + printf("router (%p) registered for \"%s\"\n", router, url); - log_info1("shutting down\n"); + printf("press ctrl-c to shutdown\n"); + if ((err = soap_server_run()) != H_OK) + { + printf("%s(): %s [%s]\n", herror_func(err), herror_message(err), herror_code(err)); + herror_release(err); + exit(1); + } + + printf("shutting down\n"); soap_server_destroy(); return 0; diff --git a/examples/csoap/soapclient.c b/examples/csoap/soapclient.c index 131ceac..c7d55f3 100644 --- a/examples/csoap/soapclient.c +++ b/examples/csoap/soapclient.c @@ -4,21 +4,26 @@ */ /* Author: Adrianus Warmenhoven */ -#include <sys/time.h> #include <stdio.h> #include <string.h> #include <ctype.h> #include <netinet/in.h> +#include <libxml/tree.h> +#include <libxml/uri.h> + #include <nanohttp/nanohttp-common.h> #include <nanohttp/nanohttp-socket.h> #include <nanohttp/nanohttp-stream.h> #include <nanohttp/nanohttp-request.h> #include <nanohttp/nanohttp-response.h> #include <nanohttp/nanohttp-client.h> - #include <nanohttp/nanohttp-logging.h> + +#include <libcsoap/soap-fault.h> +#include <libcsoap/soap-env.h> +#include <libcsoap/soap-ctx.h> #include <libcsoap/soap-client.h> #define MAX_LINE_LENGTH 65535 diff --git a/examples/nanohttp/http_client.c b/examples/nanohttp/http_client.c index d2ff4c9..4fa5bed 100644 --- a/examples/nanohttp/http_client.c +++ b/examples/nanohttp/http_client.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: http_client.c,v 1.3 2006/11/19 09:40:14 m0gg Exp $ +* $Id: http_client.c,v 1.4 2006/11/21 20:59:02 m0gg Exp $ * * CSOAP Project: A http client/server library in C (example) * Copyright (C) 2003-2004 Ferhat Ayaz @@ -22,8 +22,8 @@ * Email: hero@persua.de ******************************************************************/ #include <stdio.h> +#include <stdlib.h> #include <string.h> -#include <sys/time.h> #include <netinet/in.h> #include <nanohttp/nanohttp-common.h> @@ -116,7 +116,7 @@ int main(int argc, char **argv) { /* Initialize httpc module */ if (httpc_init(argc, argv)) { - log_error1("Can not init httpc"); + log_error1("Cannot init httpc"); exit(1); } diff --git a/examples/nanohttp/http_server.c b/examples/nanohttp/http_server.c index 5801312..420c32f 100644 --- a/examples/nanohttp/http_server.c +++ b/examples/nanohttp/http_server.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: http_server.c,v 1.5 2006/11/19 09:40:14 m0gg Exp $ +* $Id: http_server.c,v 1.6 2006/11/21 20:59:02 m0gg Exp $ * * CSOAP Project: A http client/server library in C (example) * Copyright (C) 2003 Ferhat Ayaz @@ -21,7 +21,6 @@ * * Email: hero@persua.de ******************************************************************/ -#include <sys/time.h> #include <stdio.h> #include <string.h> #include <netinet/in.h> diff --git a/libcsoap/Makefile.am b/libcsoap/Makefile.am index ecd212a..b2c73f5 100644 --- a/libcsoap/Makefile.am +++ b/libcsoap/Makefile.am @@ -5,12 +5,14 @@ libcsoap_ladir=$(includedir)/libcsoap-@csoap_release@/libcsoap libcsoap_la_SOURCES=soap-xml.c soap-fault.c soap-env.c soap-service.c \ soap-router.c soap-client.c soap-server.c soap-ctx.c \ - soap-admin.c soap-addressing.c + soap-admin.c soap-addressing.c soap-transport.c \ + soap-nudp.c soap-nhttp.c libcsoap_la_HEADERS=soap-xml.h soap-fault.h soap-env.h soap-service.h \ soap-router.h soap-client.h soap-server.h soap-ctx.h \ - soap-admin.h soap-addressing.h + soap-admin.h soap-addressing.h soap-transport.h \ + soap-nudp.h soap-nhttp.c libcsoap_la_LDFLAGS= -version-info @csoap_version@ -release @csoap_release@ -libcsoap_la_CFLAGS=-I${top_srcdir} +libcsoap_la_CFLAGS=-I${top_srcdir} -D__CSOAP_INTERNAL=1 diff --git a/libcsoap/soap-addressing.c b/libcsoap/soap-addressing.c index bd542fd..b1b9d30 100644 --- a/libcsoap/soap-addressing.c +++ b/libcsoap/soap-addressing.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: soap-addressing.c,v 1.1 2006/11/21 08:34:34 m0gg Exp $ +* $Id: soap-addressing.c,v 1.2 2006/11/21 20:59:02 m0gg Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2006 Heiko Ronsdorf @@ -54,15 +54,15 @@ #include <libxml/uri.h> #include <nanohttp/nanohttp-common.h> -#include <nanohttp/nanohttp-socket.h> -#include <nanohttp/nanohttp-stream.h> #include <nanohttp/nanohttp-logging.h> #include "soap-xml.h" +#include "soap-fault.h" #include "soap-env.h" #include "soap-addressing.h" -static const char *_soap_addressing_uuid_error(uint32_t status) +static const char * +_soap_addressing_uuid_error(uint32_t status) { switch(status) { @@ -78,7 +78,8 @@ static const char *_soap_addressing_uuid_error(uint32_t status) } } -static char * _soap_addressing_generate_id(void) +static char * +_soap_addressing_generate_id(void) { uuid_t uuid; uint32_t status; @@ -100,7 +101,8 @@ static char * _soap_addressing_generate_id(void) return ret; } -static xmlNsPtr _soap_addressing_get_namespace(xmlNodePtr node) +static xmlNsPtr +_soap_addressing_get_namespace(xmlNodePtr node) { xmlNsPtr ns; @@ -111,7 +113,8 @@ static xmlNsPtr _soap_addressing_get_namespace(xmlNodePtr node) return ns; } -static xmlNodePtr _soap_addressing_add_node(xmlNodePtr parent, const xmlChar *name, const xmlChar *content) +static xmlNodePtr +_soap_addressing_add_node(xmlNodePtr parent, const xmlChar *name, const xmlChar *content) { xmlNsPtr ns; @@ -119,7 +122,8 @@ static xmlNodePtr _soap_addressing_add_node(xmlNodePtr parent, const xmlChar *na return xmlNewChild(parent, ns, name, content); } -static xmlAttrPtr _soap_addressing_set_property(xmlNodePtr node, const xmlChar *name, const xmlChar *value) +static xmlAttrPtr +_soap_addressing_set_property(xmlNodePtr node, const xmlChar *name, const xmlChar *value) { xmlNsPtr ns; @@ -127,7 +131,8 @@ static xmlAttrPtr _soap_addressing_set_property(xmlNodePtr node, const xmlChar * return xmlSetNsProp(node, ns, name, value); } -static xmlAttrPtr _soap_addressing_set_property_uri(xmlNodePtr node, const xmlChar *name, xmlURI *uri) +static xmlAttrPtr +_soap_addressing_set_property_uri(xmlNodePtr node, const xmlChar *name, xmlURI *uri) { xmlChar *buf; xmlAttrPtr ret; @@ -139,7 +144,8 @@ static xmlAttrPtr _soap_addressing_set_property_uri(xmlNodePtr node, const xmlCh return ret; } -static xmlNodePtr _soap_addressing_get_child_element(xmlNodePtr parent, const xmlChar *name) +static xmlNodePtr +_soap_addressing_get_child_element(xmlNodePtr parent, const xmlChar *name) { xmlNodePtr walker; @@ -151,7 +157,8 @@ static xmlNodePtr _soap_addressing_get_child_element(xmlNodePtr parent, const xm return NULL; } -static xmlURI *_soap_addressing_extract_uri(xmlNodePtr node) +static xmlURI * +_soap_addressing_extract_uri(xmlNodePtr node) { xmlChar *content; xmlURI *uri = NULL; @@ -164,10 +171,14 @@ static xmlURI *_soap_addressing_extract_uri(xmlNodePtr node) return uri; } -static xmlNodePtr _soap_addressing_set_content_uri(xmlNodePtr node, xmlURI *uri) +static xmlNodePtr +_soap_addressing_set_content_uri(xmlNodePtr node, xmlURI *uri) { xmlChar *buf; + if (uri == NULL) + return; + buf = xmlSaveUri(uri); xmlNodeSetContent(node, buf); xmlFree(buf); @@ -175,7 +186,8 @@ static xmlNodePtr _soap_addressing_set_content_uri(xmlNodePtr node, xmlURI *uri) return node; } -xmlURI *soap_addressing_get_address(xmlNodePtr endpoint_reference) +xmlURI * +soap_addressing_get_address(xmlNodePtr endpoint_reference) { xmlNodePtr address; @@ -186,7 +198,8 @@ xmlURI *soap_addressing_get_address(xmlNodePtr endpoint_reference) return _soap_addressing_extract_uri(address); } -xmlNodePtr soap_addressing_set_address(xmlNodePtr endpoint_reference, xmlURI *address) +xmlNodePtr +soap_addressing_set_address(xmlNodePtr endpoint_reference, xmlURI *address) { xmlNodePtr node; @@ -197,12 +210,14 @@ xmlNodePtr soap_addressing_set_address(xmlNodePtr endpoint_reference, xmlURI *ad return _soap_addressing_set_content_uri(node, address); } -xmlNodePtr soap_addressing_get_reference_properties(xmlNodePtr endpoint_reference) +xmlNodePtr +soap_addressing_get_reference_properties(xmlNodePtr endpoint_reference) { return _soap_addressing_get_child_element(endpoint_reference, WSA_REFERENCE_PROPERTIES); } -xmlNodePtr soap_addressing_set_reference_properties(xmlNodePtr endpoint_reference, xmlNodePtr properties) +xmlNodePtr +soap_addressing_set_reference_properties(xmlNodePtr endpoint_reference, xmlNodePtr properties) { xmlNodePtr node; @@ -220,12 +235,14 @@ xmlNodePtr soap_addressing_set_reference_properties(xmlNodePtr endpoint_referenc return node; } -xmlNodePtr soap_addressing_get_metadata(xmlNodePtr endpoint_reference) +xmlNodePtr +soap_addressing_get_metadata(xmlNodePtr endpoint_reference) { return _soap_addressing_get_child_element(endpoint_reference, WSA_METADATA); } -xmlNodePtr soap_addressing_set_metadata(xmlNodePtr endpoint_reference, xmlNodePtr metadata) +xmlNodePtr +soap_addressing_set_metadata(xmlNodePtr endpoint_reference, xmlNodePtr metadata) { xmlNodePtr node; @@ -243,7 +260,8 @@ xmlNodePtr soap_addressing_set_metadata(xmlNodePtr endpoint_reference, xmlNodePt return node; } -xmlURI *soap_addressing_get_message_id(SoapEnv *envelope) +xmlURI * +soap_addressing_get_message_id(SoapEnv *envelope) { xmlNodePtr id; @@ -254,7 +272,8 @@ xmlURI *soap_addressing_get_message_id(SoapEnv *envelope) return _soap_addressing_extract_uri(id); } -xmlNodePtr soap_addressing_set_message_id(SoapEnv *envelope, xmlURI *id) +xmlNodePtr +soap_addressing_set_message_id(SoapEnv *envelope, xmlURI *id) { xmlNodePtr node; @@ -265,12 +284,14 @@ xmlNodePtr soap_addressing_set_message_id(SoapEnv *envelope, xmlURI *id) return _soap_addressing_set_content_uri(node, id); } -xmlNodePtr soap_addressing_get_relates_to(SoapEnv *envelope) +xmlNodePtr +soap_addressing_get_relates_to(SoapEnv *envelope) { return _soap_addressing_get_child_element(envelope->header, WSA_RELATES_TO); } -xmlNodePtr soap_addressing_add_relates_to(SoapEnv *envelope, xmlURI *id, xmlURI *type) +xmlNodePtr +soap_addressing_add_relates_to(SoapEnv *envelope, xmlURI *id, xmlURI *type) { xmlNodePtr node; @@ -288,12 +309,14 @@ xmlNodePtr soap_addressing_add_relates_to(SoapEnv *envelope, xmlURI *id, xmlURI return node; } -xmlNodePtr soap_addressing_get_reply_to(SoapEnv *envelope) +xmlNodePtr +soap_addressing_get_reply_to(SoapEnv *envelope) { return _soap_addressing_get_child_element(envelope->header, WSA_REPLY_TO); } -xmlNodePtr soap_addressing_set_reply_to(SoapEnv *envelope, xmlNodePtr address) +xmlNodePtr +soap_addressing_set_reply_to(SoapEnv *envelope, xmlNodePtr address) { xmlNodePtr ret; xmlNodePtr node; @@ -313,7 +336,8 @@ xmlNodePtr soap_addressing_set_reply_to(SoapEnv *envelope, xmlNodePtr address) return ret; } -xmlURI *soap_addressing_get_reply_to_address(SoapEnv *envelope) +xmlURI * +soap_addressing_get_reply_to_address(SoapEnv *envelope) { xmlNodePtr reply_to; @@ -324,7 +348,8 @@ xmlURI *soap_addressing_get_reply_to_address(SoapEnv *envelope) return soap_addressing_get_address(reply_to); } -xmlNodePtr soap_addressing_set_reply_to_address(SoapEnv *envelope, xmlURI *address) +xmlNodePtr +soap_addressing_set_reply_to_address(SoapEnv *envelope, xmlURI *address) { xmlNodePtr ret; xmlNodePtr node; @@ -342,12 +367,14 @@ xmlNodePtr soap_addressing_set_reply_to_address(SoapEnv *envelope, xmlURI *addre return ret; } -xmlNodePtr soap_addressing_get_from(SoapEnv *envelope) +xmlNodePtr +soap_addressing_get_from(SoapEnv *envelope) { return _soap_addressing_get_child_element(envelope->header, WSA_FROM); } -xmlNodePtr soap_addressing_set_from(SoapEnv *envelope, xmlNodePtr address) +xmlNodePtr +soap_addressing_set_from(SoapEnv *envelope, xmlNodePtr address) { xmlNodePtr ret; xmlNodePtr node; @@ -367,7 +394,8 @@ xmlNodePtr soap_addressing_set_from(SoapEnv *envelope, xmlNodePtr address) return ret; } -xmlURI *soap_addressing_get_from_address(SoapEnv *envelope) +xmlURI * +soap_addressing_get_from_address(SoapEnv *envelope) { xmlNodePtr from; @@ -378,7 +406,8 @@ xmlURI *soap_addressing_get_from_address(SoapEnv *envelope) return soap_addressing_get_address(from); } -xmlNodePtr soap_addressing_set_from_address(SoapEnv *envelope, xmlURI *address) +xmlNodePtr +soap_addressing_set_from_address(SoapEnv *envelope, xmlURI *address) { xmlNodePtr ret; xmlNodePtr node; @@ -396,12 +425,14 @@ xmlNodePtr soap_addressing_set_from_address(SoapEnv *envelope, xmlURI *address) return ret; } -xmlNodePtr soap_addressing_get_fault_to(SoapEnv *envelope) +xmlNodePtr +soap_addressing_get_fault_to(SoapEnv *envelope) { return _soap_addressing_get_child_element(envelope->header, WSA_FAULT_TO); } -xmlNodePtr soap_addressing_set_fault_to(SoapEnv *envelope, xmlNodePtr address) +xmlNodePtr +soap_addressing_set_fault_to(SoapEnv *envelope, xmlNodePtr address) { xmlNodePtr ret; xmlNodePtr node; @@ -421,7 +452,8 @@ xmlNodePtr soap_addressing_set_fault_to(SoapEnv *envelope, xmlNodePtr address) return ret; } -xmlURI *soap_addressing_get_fault_to_address(SoapEnv *envelope) +xmlURI * +soap_addressing_get_fault_to_address(SoapEnv *envelope) { xmlNodePtr fault_to; @@ -432,7 +464,8 @@ xmlURI *soap_addressing_get_fault_to_address(SoapEnv *envelope) return soap_addressing_get_address(fault_to); } -xmlNodePtr soap_addressing_set_fault_to_address(SoapEnv *envelope, xmlURI *address) +xmlNodePtr +soap_addressing_set_fault_to_address(SoapEnv *envelope, xmlURI *address) { xmlNodePtr ret; xmlNodePtr node; @@ -450,12 +483,14 @@ xmlNodePtr soap_addressing_set_fault_to_address(SoapEnv *envelope, xmlURI *addre return ret; } -xmlNodePtr soap_addressing_get_to(SoapEnv *envelope) +xmlNodePtr +soap_addressing_get_to(SoapEnv *envelope) { return _soap_addressing_get_child_element(envelope->header, WSA_TO); } -xmlNodePtr soap_addressing_set_to(SoapEnv *envelope, xmlNodePtr address) +xmlNodePtr +soap_addressing_set_to(SoapEnv *envelope, xmlNodePtr address) { xmlNodePtr ret; xmlNodePtr node; @@ -475,18 +510,49 @@ xmlNodePtr soap_addressing_set_to(SoapEnv *envelope, xmlNodePtr address) return ret; } -xmlURI *soap_addressing_get_to_address(SoapEnv *envelope) +xmlURI * +soap_addressing_get_to_address(SoapEnv *envelope) { xmlNodePtr to; - to = soap_addressing_get_to(envelope); - if (to == NULL) - return NULL; + if (!(to = soap_addressing_get_to(envelope))) + return NULL; return soap_addressing_get_address(to); } -xmlNodePtr soap_addressing_set_to_address(SoapEnv *envelope, xmlURI *address) +xmlChar * +soap_addressing_get_to_address_string(SoapEnv *envelope) +{ + xmlURI *uri; + xmlChar *ret; + + if (!(uri = soap_addressing_get_to_address(envelope))) + return NULL; + + ret = xmlSaveUri(uri); + xmlFreeURI(uri); + + return ret; +} + +xmlNodePtr +soap_addressing_set_to_address_string(SoapEnv *envelope, const char *to) +{ + xmlURI *uri; + xmlNodePtr ret; + + if (!(uri = xmlParseURI(to))) + return NULL; + + ret = soap_addressing_set_to_address(envelope, uri); + xmlFreeURI(uri); + + return ret; +} + +xmlNodePtr +soap_addressing_set_to_address(SoapEnv *envelope, xmlURI *address) { xmlNodePtr ret; xmlNodePtr node; @@ -504,7 +570,8 @@ xmlNodePtr soap_addressing_set_to_address(SoapEnv *envelope, xmlURI *address) return ret; } -xmlURI *soap_addressing_get_action(SoapEnv *envelope) +xmlURI * +soap_addressing_get_action(SoapEnv *envelope) { xmlNodePtr action; @@ -515,7 +582,23 @@ xmlURI *soap_addressing_get_action(SoapEnv *envelope) return _soap_addressing_extract_uri(action); } -xmlNodePtr soap_addressing_set_action(SoapEnv *envelope, xmlURI *action) +xmlChar * +soap_addressing_get_action_string(SoapEnv *envelope) +{ + xmlURI *uri; + xmlChar *ret; + + if (!(uri = soap_addressing_get_action(envelope))) + return NULL; + + ret = xmlSaveUri(uri); + xmlFreeURI(uri); + + return ret; +} + +xmlNodePtr +soap_addressing_set_action(SoapEnv *envelope, xmlURI *action) { xmlNodePtr node; @@ -525,3 +608,18 @@ xmlNodePtr soap_addressing_set_action(SoapEnv *envelope, xmlURI *action) return _soap_addressing_set_content_uri(node, action); } + +xmlNodePtr +soap_addressing_set_action_string(SoapEnv *envelope, const char *action) +{ + xmlURI *uri; + xmlNodePtr ret; + + if (!(uri = xmlParseURI(action))) + return NULL; + + ret = soap_addressing_set_action(envelope, uri); + xmlFreeURI(uri); + + return ret; +} diff --git a/libcsoap/soap-addressing.h b/libcsoap/soap-addressing.h index 8ffbd41..0677244 100644 --- a/libcsoap/soap-addressing.h +++ b/libcsoap/soap-addressing.h @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: soap-addressing.h,v 1.1 2006/11/21 08:34:34 m0gg Exp $ + * $Id: soap-addressing.h,v 1.2 2006/11/21 20:59:02 m0gg Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2006 Heiko Ronsdorf @@ -35,7 +35,7 @@ * in a transport-neutral manner. * * @author H. Ronsdorf - * @version $Revision: 1.1 $ + * @version $Revision: 1.2 $ * @see http://www.w3.org/TR/ws-addr-core/ * */ @@ -209,25 +209,32 @@ xmlURI *soap_addressing_get_reply_to_address(SoapEnv *envelope); xmlNodePtr soap_addressing_set_reply_to_address(SoapEnv *envelope, xmlURI *address); xmlNodePtr soap_addressing_get_from(SoapEnv *envelope); -xmlNodePtr soap_addressing_set_from(SoapEnv *envelope, xmlNodePtr address); - xmlURI *soap_addressing_get_from_address(SoapEnv *envelope); + +xmlNodePtr soap_addressing_set_from(SoapEnv *envelope, xmlNodePtr address); xmlNodePtr soap_addressing_set_from_address(SoapEnv *envelope, xmlURI *address); +xmlNodePtr soap_addressing_set_from_string(SoapEnv *envelope, const char *from); xmlNodePtr soap_addressing_get_fault_to(SoapEnv *envelope); -xmlNodePtr soap_addressing_set_fault_to(SoapEnv *envelope, xmlNodePtr address); - xmlURI *soap_addressing_get_fault_to_address(SoapEnv *envelope); + +xmlNodePtr soap_addressing_set_fault_to(SoapEnv *envelope, xmlNodePtr address); xmlNodePtr soap_addressing_set_fault_to_address(SoapEnv *envelope, xmlURI *address); +xmlNodePtr soap_addressing_set_fault_to_string(SoapEnv *envelope, const char *fault_to); xmlNodePtr soap_addressing_get_to(SoapEnv *envelope); -xmlNodePtr soap_addressing_set_to(SoapEnv *envelope, xmlNodePtr address); - xmlURI *soap_addressing_get_to_address(SoapEnv *envelope); +xmlChar *soap_addressing_get_to_address_string(SoapEnv *envelope); + +xmlNodePtr soap_addressing_set_to(SoapEnv *envelope, xmlNodePtr address); xmlNodePtr soap_addressing_set_to_address(SoapEnv *envelope, xmlURI *address); +xmlNodePtr soap_addressing_set_to_address_string(SoapEnv *envelope, const char *to); xmlURI *soap_addressing_get_action(SoapEnv *envelope); +xmlChar *soap_addressing_get_action_string(SoapEnv *envelope); + xmlNodePtr soap_addressing_set_action(SoapEnv *envelope, xmlURI *action); +xmlNodePtr soap_addressing_set_action_string(SoapEnv *envelope, const char *action); #ifdef __cplusplus } diff --git a/libcsoap/soap-admin.c b/libcsoap/soap-admin.c index 7b2c9e8..5558c75 100644 --- a/libcsoap/soap-admin.c +++ b/libcsoap/soap-admin.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: soap-admin.c,v 1.5 2006/11/19 09:40:14 m0gg Exp $ +* $Id: soap-admin.c,v 1.6 2006/11/21 20:59:02 m0gg Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -33,10 +33,17 @@ #include <stdio.h> #endif +#ifdef HAVE_STRING_H +#include <string.h> +#endif + #ifdef HAVE_NETINET_IN_H #include <netinet/in.h> #endif +#include <libxml/tree.h> +#include <libxml/uri.h> + #include <nanohttp/nanohttp-common.h> #include <nanohttp/nanohttp-socket.h> #include <nanohttp/nanohttp-stream.h> @@ -44,6 +51,12 @@ #include <nanohttp/nanohttp-server.h> #include <nanohttp/nanohttp-admin.h> +#define __CSOAP_INTERNAL + +#include "soap-fault.h" +#include "soap-env.h" +#include "soap-ctx.h" +#include "soap-service.h" #include "soap-router.h" #include "soap-server.h" #include "soap-admin.h" diff --git a/libcsoap/soap-client.c b/libcsoap/soap-client.c index 3513d36..4e12650 100644 --- a/libcsoap/soap-client.c +++ b/libcsoap/soap-client.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: soap-client.c,v 1.28 2006/11/19 09:40:14 m0gg Exp $ +* $Id: soap-client.c,v 1.29 2006/11/21 20:59:02 m0gg Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -25,230 +25,51 @@ #include <config.h> #endif -#ifdef HAVE_SYS_TIME_H -#include <sys/time.h> -#endif - -#ifdef HAVE_STRING_H -#include <string.h> -#endif - -#ifdef HAVE_STDIO_H -#include <stdio.h> -#endif - #ifdef HAVE_NETINET_IN_H #include <netinet/in.h> #endif +#include <libxml/tree.h> +#include <libxml/uri.h> + #include <nanohttp/nanohttp-common.h> #include <nanohttp/nanohttp-socket.h> #include <nanohttp/nanohttp-stream.h> #include <nanohttp/nanohttp-request.h> -#include <nanohttp/nanohttp-response.h> -#include <nanohttp/nanohttp-client.h> +#include <nanohttp/nanohttp-server.h> #include <nanohttp/nanohttp-logging.h> +#include "soap-fault.h" +#include "soap-env.h" +#include "soap-ctx.h" +#include "soap-addressing.h" +#include "soap-service.h" +#include "soap-router.h" +#include "soap-transport.h" #include "soap-client.h" -static herror_t -_soap_client_build_result(hresponse_t * res, SoapEnv ** env) -{ - log_verbose2("Building result (%p)", res); - - if (res == NULL) - return herror_new("_soap_client_build_result", - GENERAL_INVALID_PARAM, "hresponse_t is NULL"); - - - if (res->in == NULL) - return herror_new("_soap_client_build_result", - GENERAL_INVALID_PARAM, "Empty response from server"); - - if (res->errcode != 200) - return herror_new("_soap_client_build_result", - GENERAL_INVALID_PARAM, "HTTP code is not OK (%i)", res->errcode); - - return soap_env_new_from_stream(res->in, env); -} - herror_t -soap_client_init_args(int argc, char *argv[]) +soap_client_init_args(int argc, char **argv) { - - return httpc_init(argc, argv); + return soap_transport_client_init_args(argc, argv); } void soap_client_destroy(void) { - httpc_destroy(); - + soap_transport_client_destroy(); + return; } herror_t -soap_client_invoke(SoapCtx * call, SoapCtx ** response, const char *url, - const char *soap_action) +soap_client_invoke(SoapCtx *req, SoapCtx **res, const char *url, const char *action) { - /* Status */ - herror_t status; - - /* Result document */ - SoapEnv *res_env; - - /* Buffer variables */ - xmlBufferPtr buffer; - char *content; - char tmp[15]; - - /* Transport variables */ - httpc_conn_t *conn; - hresponse_t *res; - - /* multipart/related start id */ - char start_id[150]; - static int counter = 1; - part_t *part; - - /* for copy attachments */ - char href[MAX_HREF_SIZE]; + log_verbose2("action = \"%s\"", action); + soap_addressing_set_action_string(req->env, action); - /* Create buffer */ - buffer = xmlBufferCreate(); - xmlNodeDump(buffer, call->env->root->doc, call->env->root, 1, 0); - content = (char *) xmlBufferContent(buffer); + log_verbose2("url = \"%s\"", url); + soap_addressing_set_to_address_string(req->env, url); - /* Transport via HTTP */ - if (!(conn = httpc_new())) - { - return herror_new("soap_client_invoke", SOAP_ERROR_CLIENT_INIT, - "Unable to create SOAP client!"); - } - - /* Set soap action */ - if (soap_action != NULL) - httpc_set_header(conn, "SoapAction", soap_action); - - httpc_set_header(conn, HEADER_CONNECTION, "Close"); - - /* check for attachments */ - if (!call->attachments) - { - /* content-type is always 'text/xml' */ - httpc_set_header(conn, HEADER_CONTENT_TYPE, "text/xml"); - - sprintf(tmp, "%d", (int) strlen(content)); - httpc_set_header(conn, HEADER_CONTENT_LENGTH, tmp); - - if ((status = httpc_post_begin(conn, url)) != H_OK) - { - httpc_close_free(conn); - xmlBufferFree(buffer); - return status; - } - - if ((status = http_output_stream_write_string(conn->out, content)) != H_OK) - { - httpc_close_free(conn); - xmlBufferFree(buffer); - return status; - } - - if ((status = httpc_post_end(conn, &res)) != H_OK) - { - httpc_close_free(conn); - xmlBufferFree(buffer); - return status; - } - } - else - { - - /* Use chunked transport */ - httpc_set_header(conn, HEADER_TRANSFER_ENCODING, - TRANSFER_ENCODING_CHUNKED); - - sprintf(start_id, "289247829121218%d", counter++); - if ((status = httpc_mime_begin(conn, url, start_id, "", "text/xml")) != H_OK) - { - httpc_close_free(conn); - xmlBufferFree(buffer); - return status; - } - - if ((status = httpc_mime_next(conn, start_id, "text/xml", "binary")) != H_OK) - { - httpc_close_free(conn); - xmlBufferFree(buffer); - return status; - } - - if ((status = http_output_stream_write(conn->out, content, strlen(content))) != H_OK) - { - httpc_close_free(conn); - xmlBufferFree(buffer); - return status; - } - - - for (part = call->attachments->parts; part; part = part->next) - { - status = httpc_mime_send_file(conn, part->id, - part->content_type, - part->transfer_encoding, part->filename); - if (status != H_OK) - { - log_error2("Send file failed. Status:%d", status); - httpc_close_free(conn); - xmlBufferFree(buffer); - return status; - } - } - - if ((status = httpc_mime_end(conn, &res)) != H_OK) - { - httpc_close_free(conn); - xmlBufferFree(buffer); - return status; - } - } - - /* Free buffer */ - xmlBufferFree(buffer); - - /* Build result */ - if ((status = _soap_client_build_result(res, &res_env)) != H_OK) - { - hresponse_free(res); - httpc_close_free(conn); - return status; - } - - /* Create Context */ - *response = soap_ctx_new(res_env); -/* soap_ctx_add_files(*response, res->attachments);*/ - - if (res->attachments != NULL) - { - part = res->attachments->parts; - while (part) - { - soap_ctx_add_file(*response, part->filename, part->content_type, href); - part->deleteOnExit = 0; - part = part->next; - } - part = (*response)->attachments->parts; - while (part) - { - part->deleteOnExit = 1; - part = part->next; - } - } - - hresponse_free(res); - httpc_close_free(conn); - - return H_OK; + return soap_transport_client_invoke(req, res); } - diff --git a/libcsoap/soap-ctx.c b/libcsoap/soap-ctx.c index 28c779f..2db0e7e 100755 --- a/libcsoap/soap-ctx.c +++ b/libcsoap/soap-ctx.c @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: soap-ctx.c,v 1.11 2006/11/19 09:40:14 m0gg Exp $ + * $Id: soap-ctx.c,v 1.12 2006/11/21 20:59:02 m0gg Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003-2004 Ferhat Ayaz @@ -25,10 +25,6 @@ #include <config.h> #endif -#ifdef HAVE_SYS_TIME_H -#include <sys/time.h> -#endif - #ifdef HAVE_STDIO_H #include <stdio.h> #endif @@ -45,12 +41,13 @@ #include <netinet/in.h> #endif +#include <libxml/tree.h> + #include <nanohttp/nanohttp-common.h> -#include <nanohttp/nanohttp-socket.h> -#include <nanohttp/nanohttp-stream.h> -#include <nanohttp/nanohttp-request.h> #include <nanohttp/nanohttp-logging.h> +#include "soap-fault.h" +#include "soap-env.h" #include "soap-ctx.h" SoapCtx * @@ -66,7 +63,6 @@ soap_ctx_new(SoapEnv * env) /* should only be used internally */ ctx->env = env; ctx->attachments = NULL; - ctx->action = NULL; return ctx; } @@ -171,9 +167,6 @@ soap_ctx_free(SoapCtx * ctx) if (ctx->env) soap_env_free(ctx->env); - if (ctx->action) - free(ctx->action); - free(ctx); return; diff --git a/libcsoap/soap-ctx.h b/libcsoap/soap-ctx.h index a70a88f..93631d2 100755 --- a/libcsoap/soap-ctx.h +++ b/libcsoap/soap-ctx.h @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: soap-ctx.h,v 1.10 2006/11/19 09:40:14 m0gg Exp $ + * $Id: soap-ctx.h,v 1.11 2006/11/21 20:59:02 m0gg Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003-2004 Ferhat Ayaz @@ -21,10 +21,8 @@ * * Email: ferhatayaz@jprogrammer.net ******************************************************************/ -#ifndef cSOAP_CTX_H -#define cSOAP_CTX_H - -#include <libcsoap/soap-env.h> +#ifndef __csoap_context_h +#define __csoap_context_h #define SOAP_ERROR_NO_FILE_ATTACHED 4001 #define SOAP_ERROR_EMPTY_ATTACHMENT 4002 @@ -34,8 +32,6 @@ typedef struct _SoapCtx { SoapEnv *env; - char *action; - hrequest_t *http; attachments_t *attachments; } SoapCtx; @@ -43,8 +39,16 @@ typedef struct _SoapCtx extern "C" { #endif -SoapCtx *soap_ctx_new(SoapEnv * env); /* should only be used internally */ +/* should only be used internally */ +extern SoapCtx *soap_ctx_new(SoapEnv * env); + +/** + Creates a new soap context object. +*/ +extern herror_t soap_ctx_new_with_method(const char *urn, const char *method, + SoapCtx ** out); +extern void soap_ctx_free(SoapCtx * ctx); /** Returns the attached file if any found. @param ctx the SoapCtx object which should contain the part @@ -53,23 +57,16 @@ SoapCtx *soap_ctx_new(SoapEnv * env); /* should only be used internally */ @returns a part_t object of attachment was found, NULL otherwise. */ -part_t *soap_ctx_get_file(SoapCtx * ctx, xmlNodePtr node); - -/** - Creates a new soap context object. -*/ -herror_t soap_ctx_new_with_method(const char *urn, const char *method, - SoapCtx ** out); +extern part_t *soap_ctx_get_file(SoapCtx * ctx, xmlNodePtr node); /* Size of destination dest_href should be MAX_HREF_SIZE */ -herror_t soap_ctx_add_file(SoapCtx * ctx, const char *filename, +extern herror_t soap_ctx_add_file(SoapCtx * ctx, const char *filename, const char *content_type, char *dest_href); /* Used internally. Will switch the deleteOnExit flag from the given one to the added part. */ -void soap_ctx_add_files(SoapCtx * ctx, attachments_t * attachments); -void soap_ctx_free(SoapCtx * ctx); +extern void soap_ctx_add_files(SoapCtx * ctx, attachments_t * attachments); #ifdef __cplusplus } diff --git a/libcsoap/soap-env.c b/libcsoap/soap-env.c index dc64d98..9882cfb 100644 --- a/libcsoap/soap-env.c +++ b/libcsoap/soap-env.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: soap-env.c,v 1.22 2006/11/21 08:34:34 m0gg Exp $ +* $Id: soap-env.c,v 1.23 2006/11/21 20:59:02 m0gg Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -49,20 +49,14 @@ #include <netinet/in.h> #endif -#ifdef WIN32 -#define USE_XMLSTRING -#endif - -#ifdef USE_XMLSTRING +#include <libxml/tree.h> #include <libxml/xmlstring.h> -#endif #include <nanohttp/nanohttp-common.h> -#include <nanohttp/nanohttp-socket.h> -#include <nanohttp/nanohttp-stream.h> #include <nanohttp/nanohttp-logging.h> #include "soap-xml.h" +#include "soap-fault.h" #include "soap-env.h" /* @@ -230,23 +224,16 @@ soap_env_new_from_buffer(const char *buffer, SoapEnv ** out) herror_t -soap_env_new_with_fault(fault_code_t faultcode, - const char *faultstring, - const char *faultactor, const char *detail, - SoapEnv ** out) +soap_env_new_with_fault(int faultcode, const char *faultstring, const char *faultactor, const char *detail, SoapEnv **out) { xmlDocPtr doc; herror_t err; - doc = soap_fault_build(faultcode, faultstring, faultactor, detail); - if (doc == NULL) - return herror_new("soap_env_new_with_fault", - XML_ERROR_PARSE, "Can not parse fault xml"); + if (!(doc = soap_fault_build(faultcode, faultstring, faultactor, detail))) + return herror_new("soap_env_new_with_fault", XML_ERROR_PARSE, "Can not parse fault xml"); if ((err = soap_env_new_from_doc(doc, out)) != H_OK) - { xmlFreeDoc(doc); - } return err; } @@ -312,28 +299,15 @@ soap_env_new_with_method(const char *urn, const char *method, SoapEnv ** out) if (!strcmp(urn, "")) { -#ifdef USE_XMLSTRING xmlStrPrintf(buffer, 1054, BAD_CAST _SOAP_MSG_TEMPLATE_EMPTY_TARGET_, soap_env_ns, soap_env_enc, soap_xsi_ns, soap_xsd_ns, BAD_CAST method, BAD_CAST urn, BAD_CAST method); -#else - sprintf(buffer, _SOAP_MSG_TEMPLATE_EMPTY_TARGET_, - soap_env_ns, soap_env_enc, soap_xsi_ns, - soap_xsd_ns, method, urn, method); -#endif } else { -#ifdef USE_XMLSTRING xmlStrPrintf(buffer, 1054, BAD_CAST _SOAP_MSG_TEMPLATE_, soap_env_ns, soap_env_enc, soap_xsi_ns, soap_xsd_ns, BAD_CAST method, BAD_CAST urn, BAD_CAST method); -#else - sprintf(buffer, _SOAP_MSG_TEMPLATE_, - soap_env_ns, soap_env_enc, soap_xsi_ns, - soap_xsd_ns, method, urn, method); -#endif - } if (!(env = xmlParseDoc(buffer))) @@ -344,48 +318,6 @@ soap_env_new_with_method(const char *urn, const char *method, SoapEnv ** out) } -static int -_soap_env_xml_io_read(void *ctx, char *buffer, int len) -{ - int readed; - - http_input_stream_t *in = (http_input_stream_t *) ctx; - if (!http_input_stream_is_ready(in)) - return 0; - - readed = http_input_stream_read(in, buffer, len); - if (readed == -1) - return 0; - return readed; -} - -static int -_soap_env_xml_io_close(void *ctx) -{ - /* do nothing */ - return 0; -} - - -herror_t -soap_env_new_from_stream(http_input_stream_t * in, SoapEnv ** out) -{ - xmlDocPtr doc; - - doc = xmlReadIO(_soap_env_xml_io_read, - _soap_env_xml_io_close, in, "", NULL, 0); - - if (in->err != H_OK) - return in->err; - - if (doc == NULL) - return herror_new("soap_env_new_from_stream", - XML_ERROR_PARSE, "Trying to parse not valid xml"); - - return soap_env_new_from_doc(doc, out); -} - - xmlNodePtr soap_env_add_item(SoapEnv * call, const char *type, const char *name, const char *value) { diff --git a/libcsoap/soap-env.h b/libcsoap/soap-env.h index 53d8ce5..2da9528 100644 --- a/libcsoap/soap-env.h +++ b/libcsoap/soap-env.h @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: soap-env.h,v 1.15 2006/11/21 08:34:34 m0gg Exp $ + * $Id: soap-env.h,v 1.16 2006/11/21 20:59:02 m0gg Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -24,9 +24,6 @@ #ifndef cSOAP_ENV_H #define cSOAP_ENV_H -#include <libcsoap/soap-xml.h> -#include <libcsoap/soap-fault.h> - /** The SOAP envelope object. */ @@ -77,7 +74,7 @@ extern "C" { */ herror_t -soap_env_new_with_fault(fault_code_t faultcode, +soap_env_new_with_fault(int faultcode, const char *faultstring, const char *faultactor, const char *detail, SoapEnv ** out); @@ -167,15 +164,6 @@ herror_t soap_env_new_from_doc(xmlDocPtr doc, SoapEnv ** out); herror_t soap_env_new_from_buffer(const char *buffer, SoapEnv ** out); -/** - Create an envelope from input stream - - @param in the input stream object to read from - @param out the output envelope object - @returns H_OK if success -*/ -herror_t soap_env_new_from_stream(http_input_stream_t * in, SoapEnv ** out); - /* --------------------------------------------------- */ /* XML Serializer functions and typedefs */ /* --------------------------------------------------- */ diff --git a/libcsoap/soap-fault.c b/libcsoap/soap-fault.c index c4768e6..6781e1e 100644 --- a/libcsoap/soap-fault.c +++ b/libcsoap/soap-fault.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: soap-fault.c,v 1.11 2006/07/09 16:24:19 snowdrop Exp $ +* $Id: soap-fault.c,v 1.12 2006/11/21 20:59:02 m0gg Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -29,10 +29,12 @@ #include <string.h> #endif +#include <nanohttp/nanohttp-common.h> #include <nanohttp/nanohttp-logging.h> -#include "soap-fault.h" #include "soap-xml.h" +// #include "soap-server.h" +#include "soap-fault.h" /* Parameters: @@ -46,7 +48,9 @@ Parameters: 8- detail */ #define _SOAP_FAULT_TEMPLATE_ \ - "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"%s\" SOAP-ENV:encoding=\"%s\"" \ + "<SOAP-ENV:Envelope" \ + " xmlns:SOAP-ENV=\"%s\"" \ + " SOAP-ENV:encoding=\"%s\"" \ " xmlns:xsi=\"%s\"" \ " xmlns:xsd=\"%s\">" \ " <SOAP-ENV:Header />" \ @@ -61,60 +65,64 @@ Parameters: "</SOAP-ENV:Envelope>" - -static char *fault_vm = "VersionMismatch"; -static char *fault_mu = "MustUnderstand"; -static char *fault_client = "Client"; -static char *fault_server = "Server"; +static const char const *fault_vm = "VersionMismatch"; +static const char const *fault_mu = "MustUnderstand"; +static const char const *fault_deu = "DataEncodingUnkown"; +static const char const *fault_client = "Client"; +static const char const *fault_server = "Server"; xmlDocPtr -soap_fault_build(fault_code_t fcode, - const char *faultstring, - const char *faultactor, const char *detail) +soap_fault_build(int fault_code, const char *fault_string, const char *fault_actor, const char *detail) { /* variables */ - char *faultcode; + const char *faultcode; int bufferlen = 2000; char *buffer; xmlDocPtr fault; /* result */ log_verbose1("Build fault"); - switch (fcode) + switch (fault_code) { - case Fault_VersionMismatch: + case SOAP_FAULT_VERSION_MISMATCH: faultcode = fault_vm; break; - case Fault_MustUnderstand: + case SOAP_FAULT_MUST_UNDERSTAND: faultcode = fault_mu; break; - case Fault_Client: - faultcode = fault_client; + case SOAP_FAULT_DATA_ENCODING_UNKOWN: + faultcode = fault_deu; break; - case Fault_Server: + case SOAP_FAULT_RECEIVER: faultcode = fault_server; break; + case SOAP_FAULT_SENDER: default: faultcode = fault_client; + break; } /* calculate buffer length */ - if (faultstring) - bufferlen += strlen(faultstring); - if (faultactor) - bufferlen += strlen(faultactor); + if (fault_string) + bufferlen += strlen(fault_string); + if (fault_actor) + bufferlen += strlen(fault_actor); if (detail) bufferlen += strlen(detail); log_verbose2("Creating buffer with %d bytes", bufferlen); - buffer = (char *) malloc(bufferlen); + if (!(buffer = (char *) malloc(bufferlen))) + { + log_error2("malloc failed (%s)", errno); + return NULL; + } sprintf(buffer, _SOAP_FAULT_TEMPLATE_, soap_env_ns, soap_env_enc, soap_xsi_ns, soap_xsd_ns, faultcode, - faultstring ? faultstring : "error", - faultactor ? faultactor : "", detail ? detail : ""); + fault_string ? fault_string : "error", + fault_actor ? fault_actor : "", detail ? detail : ""); fault = xmlParseDoc(BAD_CAST buffer); free(buffer); @@ -123,11 +131,9 @@ soap_fault_build(fault_code_t fcode, { log_error1("Can not create xml document!"); - return soap_fault_build(fcode, "Can not create fault object in xml", - "soap_fault_build()", NULL); + return soap_fault_build(fault_code, "Cannot create fault object in XML", soap_server_get_name(), NULL); } log_verbose2("Returning fault (%p)", fault); return fault; - } diff --git a/libcsoap/soap-fault.h b/libcsoap/soap-fault.h index 5aad5ed..1a11365 100644 --- a/libcsoap/soap-fault.h +++ b/libcsoap/soap-fault.h @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: soap-fault.h,v 1.5 2006/03/06 13:37:38 m0gg Exp $ + * $Id: soap-fault.h,v 1.6 2006/11/21 20:59:02 m0gg Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -21,28 +21,104 @@ * * Email: ayaz@jprogrammer.net ******************************************************************/ -#ifndef cSOAP_FAULT_H -#define cSOAP_FAULT_H +#ifndef __csoap_fault_h +#define __csoap_fault_h -#include <libcsoap/soap-xml.h> +/** + * + * The SOAP Fault element is used to carry error and/or status information within + * a SOAP message. If present, the SOAP Fault element MUST appear as a body entry + * and MUST NOT appear more than once within a Body element. + * + * The SOAP Fault element defines the following four subelements: + * + * # faultcode - The faultcode element is intended for use by software to provide + * an algorithmic mechanism for identifying the fault. The faultcode MUST be + * present in a SOAP Fault element and the faultcode value MUST be a qualified + * name as defined in "Namespaces in XML", section 3. SOAP defines a small set + * of SOAP fault codes covering basic SOAP faults (see section 4.4.1). + * # faultstring - The faultstring element is intended to provide a human + * readable explanation of the fault and is not intended for algorithmic + * processing. The faultstring element is similar to the 'Reason-Phrase' defined + * by HTTP (see RFC2616, section 6.1). It MUST be present in a SOAP Fault + * element and SHOULD provide at least some information explaining the nature + * of the fault. + * # faultactor - The faultactor element is intended to provide information about + * who caused the fault to happen within the message path (see section 2). It is + * similar to the SOAP actor attribute (see section 4.2.2) but instead of + * indicating the destination of the header entry, it indicates the source of + * the fault. The value of the faultactor attribute is a URI identifying the + * source. Applications that do not act as the ultimate destination of the SOAP + * message MUST include the faultactor element in a SOAP Fault element. The + * ultimate destination of a message MAY use the faultactor element to indicate + * explicitly that it generated the fault (see also the detail element below). + * # detail - The detail element is intended for carrying application specific + * error information related to the Body element. It MUST be present if the + * contents of the Body element could not be successfully processed. It MUST + * NOT be used to carry information about error information belonging to header + * entries. Detailed error information belonging to header entries MUST be + * carried within header entries. + * + */ + +/** + * + * The faulting node found an invalid element information item instead of the + * expected Envelope element information item. The namespace, local name or both + * did not match the Envelope element information item required by this + * recommendation (see 2.8 SOAP Versioning Model and 5.4.7 VersionMismatch + * Faults) + * + */ +#define SOAP_FAULT_VERSION_MISMATCH 0 +/** + * + * An immediate child element information item of the SOAP Header element + * information item targeted at the faulting node that was not understood by the + * faulting node contained a SOAP mustUnderstand attribute information item with + * a value of "true" (see 5.2.3 SOAP mustUnderstand Attribute and 5.4.8 SOAP + * mustUnderstand Faults) + * + */ +#define SOAP_FAULT_MUST_UNDERSTAND 1 +/** + * + * A SOAP header block or SOAP body child element information item targeted at + * the faulting SOAP node is scoped (see 5.1.1 SOAP encodingStyle Attribute) with + * a data encoding that the faulting node does not support. + * + */ +#define SOAP_FAULT_DATA_ENCODING_UNKOWN 2 -typedef enum _fault_code -{ - Fault_VersionMismatch, - Fault_MustUnderstand, - Fault_Client, - Fault_Server -} fault_code_t; +/** + * + * The message could not be processed for reasons attributable to the processing + * of the message rather than to the contents of the message itself. For example, + * processing could include communicating with an upstream SOAP node, which did + * not respond. The message could succeed if resent at a later point in time (see + * also 5.4 SOAP Fault for a description of the SOAP fault detail sub-element). + * + */ +#define SOAP_FAULT_RECEIVER 4 + +/** + * + * The message was incorrectly formed or did not contain the appropriate + * information in order to succeed. For example, the message could lack the + * proper authentication or payment information. It is generally an indication + * that the message is not to be resent without change (see also 5.4 SOAP Fault + * for a description of the SOAP fault detail sub-element). + * + */ +#define SOAP_FAULT_SENDER 3 #ifdef __cplusplus extern "C" { #endif -xmlDocPtr soap_fault_build(fault_code_t faultcode, - const char *faultstring, - const char *faultactor, const char *detail); +extern xmlDocPtr soap_fault_build(int fault_code, const char *fault_string, const char *fault_actor, const char *detail); #ifdef __cplusplus } diff --git a/libcsoap/soap-nhttp.c b/libcsoap/soap-nhttp.c new file mode 100644 index 0000000..a49800b --- /dev/null +++ b/libcsoap/soap-nhttp.c @@ -0,0 +1,470 @@ +/****************************************************************** +* $Id: soap-nhttp.c,v 1.1 2006/11/21 20:59:02 m0gg Exp $ +* +* CSOAP Project: A SOAP client/server library in C +* Copyright (C) 2003 Ferhat Ayaz +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Library General Public +* License as published by the Free Software Foundation; either +* version 2 of the License, or (at your option) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Library General Public License for more details. +* +* You should have received a copy of the GNU Library General Public +* License along with this library; if not, write to the +* Free Software Foundation, Inc., 59 Temple Place - Suite 330, +* Boston, MA 02111-1307, USA. +* +* Email: ayaz@jprogrammer.net +******************************************************************/ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#ifdef HAVE_STDIO_H +#include <stdio.h> +#endif + +#ifdef HAVE_STRING_H +#include <string.h> +#endif + +#ifdef HAVE_ERRNO_H +#include <errno.h> +#endif + +#ifdef HAVE_NETINET_IN_H +#include <netinet/in.h> +#endif + +#ifdef WIN32 +#define snprintf(buffer, num, s1, s2) sprintf(buffer, s1,s2) +#endif + +#include <libxml/tree.h> +#include <libxml/uri.h> + +#include <nanohttp/nanohttp-common.h> +#include <nanohttp/nanohttp-logging.h> + +#include <nanohttp/nanohttp-socket.h> +#include <nanohttp/nanohttp-stream.h> +#include <nanohttp/nanohttp-request.h> +#include <nanohttp/nanohttp-response.h> + +#include <nanohttp/nanohttp-client.h> +#include <nanohttp/nanohttp-server.h> + +#include "soap-admin.h" +#include "soap-fault.h" +#include "soap-env.h" +#include "soap-ctx.h" +#include "soap-service.h" +#include "soap-router.h" +#include "soap-server.h" +#include "soap-client.h" +#include "soap-addressing.h" + +#include "soap-nhttp.h" + +static herror_t +_soap_nhttp_send_document(httpd_conn_t *conn, xmlDocPtr doc) +{ + char length[16]; + xmlBufferPtr buf; + + buf = xmlBufferCreate(); + xmlNodeDump(buf, doc, xmlDocGetRootElement(doc), 1, 1); + + sprintf(length, "%d", xmlBufferLength(buf)); + httpd_set_header(conn, HEADER_CONTENT_TYPE, "text/xml"); + httpd_set_header(conn, HEADER_CONTENT_LENGTH, length); + httpd_send_header(conn, 200, "OK"); + + http_output_stream_write_string(conn->out, xmlBufferContent(buf)); + + xmlBufferFree(buf); + + return H_OK; +} + +static herror_t +_soap_nhttp_send_fault(httpd_conn_t *conn, const char *message) +{ + xmlDocPtr doc; + herror_t ret; + + doc = soap_fault_build(SOAP_FAULT_SENDER, message, soap_server_get_name(), NULL); + ret = _soap_nhttp_send_document(conn, doc); + xmlFreeDoc(doc); + + return ret; +} + +static herror_t +_soap_nhttp_send(httpd_conn_t *conn, SoapCtx *context, SoapEnv *env) +{ + return _soap_nhttp_send_document(conn, env->root->doc); +} + +static int +_soap_nhttp_xml_io_read(void *ctx, char *buffer, int len) +{ + int ret; + + http_input_stream_t *in = (http_input_stream_t *)ctx; + if (!http_input_stream_is_ready(in)) + return 0; + + if ((ret = http_input_stream_read(in, buffer, len)) == -1) + return 0; + + return ret; +} + +static int +_soap_nhttp_xml_io_close(void *ctx) +{ + /* nothing */ + return 0; +} + +static herror_t +_soap_nhttp_env_new_from_stream(http_input_stream_t *in, SoapEnv **out) +{ + xmlDocPtr doc; + + doc = xmlReadIO(_soap_nhttp_xml_io_read, _soap_nhttp_xml_io_close, in, "", NULL, 0); + if (in->err != H_OK) + return in->err; + + if (doc == NULL) + return herror_new("_soap_nhttp_env_new_from_stream", XML_ERROR_PARSE, "Trying to parse not valid xml"); + + return soap_env_new_from_doc(doc, out); +} + +static void +soap_nhttp_process(httpd_conn_t * conn, hrequest_t * req) +{ + char *action; + SoapEnv *env; + SoapCtx *ctx; + SoapCtx *response; + herror_t err; + +/* if (req->method == HTTP_REQUEST_GET && router->wsdl) + { + _soap_nhttp_send_document(conn, router->wsdl); + return; + } */ + + if (req->method != HTTP_REQUEST_POST) + { + httpd_send_header(conn, 200, "OK"); + http_output_stream_write_string(conn->out, + "<html>" + "<head>" + "</head>" + "<body>" + "<h1>Sorry!</h1>" + "<hr />" + "<div>I only speak with 'POST' method.</div>" + "</body>" + "</html>"); + return; + } + + if ((err = _soap_nhttp_env_new_from_stream(req->in, &env)) != H_OK) + { + _soap_nhttp_send_fault(conn, herror_message(err)); + herror_release(err); + return; + } + + if (env == NULL) + { + _soap_nhttp_send_fault(conn, "Can not receive POST data!"); + return; + } + + ctx = soap_ctx_new(env); + + if ((action = hpairnode_get_ignore_case(req->header, SOAP_NHTTP_SOAP_ACTION))) + { + xmlURI *uri; + + uri = xmlParseURI(action); + soap_addressing_set_action(env, uri); + xmlFree(uri); + } + + soap_xml_doc_print(ctx->env->root->doc); + + soap_ctx_add_files(ctx, req->attachments); + + /* only local part is interesting... */ + soap_addressing_set_to_address_string(ctx->env, req->path); + + soap_server_process(ctx, &response); + + _soap_nhttp_send_document(conn, response->env->root->doc); + + soap_ctx_free(response); + + soap_ctx_free(ctx); + + return; +} + +herror_t +soap_nhttp_server_init_args(int argc, char **argv) +{ + herror_t err; + + if ((err = httpd_init(argc, argv)) != H_OK) + return err; + + return soap_admin_init_args(argc, argv); +} + +static herror_t +_soap_nhttp_client_build_result(hresponse_t * res, SoapEnv ** env) +{ + log_verbose2("Building result (%p)", res); + + if (res == NULL) + return herror_new("_soap_client_build_result", + GENERAL_INVALID_PARAM, "hresponse_t is NULL"); + + if (res->in == NULL) + return herror_new("_soap_client_build_result", + GENERAL_INVALID_PARAM, "Empty response from server"); + + if (res->errcode != 200) + return herror_new("_soap_client_build_result", + GENERAL_INVALID_PARAM, "HTTP code is not OK (%i)", res->errcode); + + return _soap_nhttp_env_new_from_stream(res->in, env); +} + +static herror_t +_soap_nhttp_client_invoke(void *unused, SoapCtx *request, SoapCtx **response) +{ + herror_t status; + + /* Buffer variables */ + xmlBufferPtr buffer; + char *content; + char tmp[15]; + char *action; + char *url; + SoapEnv *res_env; + + /* Transport variables */ + httpc_conn_t *conn; + hresponse_t *res; + + /* multipart/related start id */ + char start_id[150]; + static int counter = 1; + part_t *part; + + /* for copy attachments */ + char href[MAX_HREF_SIZE]; + + log_verbose1("nanohttp client"); + + /* Create buffer */ + buffer = xmlBufferCreate(); + xmlNodeDump(buffer, request->env->root->doc, request->env->root, 1, 0); + content = (char *) xmlBufferContent(buffer); + + soap_xml_doc_print(request->env->root->doc); + + /* Transport via HTTP */ + if (!(conn = httpc_new())) + { + return herror_new("soap_client_invoke", SOAP_ERROR_CLIENT_INIT, "Unable to create HTTP client!"); + } + + if ((action = soap_addressing_get_action_string(request->env))) + httpc_set_header(conn, SOAP_NHTTP_SOAP_ACTION, action); + else + httpc_set_header(conn, SOAP_NHTTP_SOAP_ACTION, ""); + log_verbose2("action is \"%s\"", action); + free(action); + + httpc_set_header(conn, HEADER_CONNECTION, "Close"); + + if (!(url = soap_addressing_get_to_address_string(request->env))) + return herror_new("soap_nhttp_client_invoke", 0, "Missing client URL"); + log_verbose2("url is \"%s\"", url); + + if (!request->attachments) + { + /* content-type is always 'text/xml' */ + httpc_set_header(conn, HEADER_CONTENT_TYPE, "text/xml"); + + sprintf(tmp, "%d", (int) strlen(content)); + httpc_set_header(conn, HEADER_CONTENT_LENGTH, tmp); + + if ((status = httpc_post_begin(conn, url)) != H_OK) + { + httpc_close_free(conn); + xmlBufferFree(buffer); + return status; + } + + if ((status = http_output_stream_write_string(conn->out, content)) != H_OK) + { + httpc_close_free(conn); + xmlBufferFree(buffer); + return status; + } + + if ((status = httpc_post_end(conn, &res)) != H_OK) + { + httpc_close_free(conn); + xmlBufferFree(buffer); + return status; + } + } + else + { + httpc_set_header(conn, HEADER_TRANSFER_ENCODING, TRANSFER_ENCODING_CHUNKED); + + sprintf(start_id, "289247829121218%d", counter++); + if ((status = httpc_mime_begin(conn, url, start_id, "", "text/xml")) != H_OK) + { + httpc_close_free(conn); + xmlBufferFree(buffer); + return status; + } + + if ((status = httpc_mime_next(conn, start_id, "text/xml", "binary")) != H_OK) + { + httpc_close_free(conn); + xmlBufferFree(buffer); + return status; + } + + if ((status = http_output_stream_write(conn->out, content, strlen(content))) != H_OK) + { + httpc_close_free(conn); + xmlBufferFree(buffer); + return status; + } + + for (part=request->attachments->parts; part; part=part->next) + { + status = httpc_mime_send_file(conn, part->id, part->content_type, part->transfer_encoding, part->filename); + + if (status != H_OK) + { + log_error2("Send file failed. Status: %d", status); + httpc_close_free(conn); + xmlBufferFree(buffer); + return status; + } + } + + if ((status = httpc_mime_end(conn, &res)) != H_OK) + { + httpc_close_free(conn); + xmlBufferFree(buffer); + return status; + } + } + + xmlBufferFree(buffer); + free(url); + + if ((status = _soap_nhttp_client_build_result(res, &res_env)) != H_OK) + { + hresponse_free(res); + httpc_close_free(conn); + return status; + } + + *response = soap_ctx_new(res_env); + /* soap_ctx_add_files(*response, res->attachments) */ + + if (res->attachments != NULL) + { + part = res->attachments->parts; + while (part) + { + soap_ctx_add_file(*response, part->filename, part->content_type, href); + part->deleteOnExit = 0; + part = part->next; + } + } + + hresponse_free(res); + httpc_close_free(conn); + + log_verbose1("done"); + + return H_OK; +} +herror_t +soap_nhttp_client_init_args(int argc, char **argv) +{ + soap_transport_add("https", NULL, _soap_nhttp_client_invoke); + soap_transport_add("http", NULL, _soap_nhttp_client_invoke); + + return httpc_init(argc, argv); +} + +herror_t +soap_nhttp_register_router(SoapRouter * router, const char *context) +{ + + if (!httpd_register_secure(context, soap_nhttp_process, router->auth)) + { + return /* XXX */ H_OK; + } + + return H_OK; +} + +herror_t +soap_nhttp_server_run(void) +{ + return httpd_run(); +} + +void +soap_nhttp_server_destroy(void) +{ + httpd_destroy(); + + return; +} + + +void +soap_nhttp_client_destroy(void) +{ + httpc_destroy(); + + return; +} + +short +soap_nhttp_get_port(void) +{ + return httpd_get_port(); +} + +const char * +soap_nhttp_get_protocol(void) +{ + return httpd_get_protocol(); +} + diff --git a/libcsoap/soap-nhttp.h b/libcsoap/soap-nhttp.h new file mode 100644 index 0000000..fb060b5 --- /dev/null +++ b/libcsoap/soap-nhttp.h @@ -0,0 +1,63 @@ +/****************************************************************** +* $Id: soap-nhttp.h,v 1.1 2006/11/21 20:59:02 m0gg Exp $ +* +* CSOAP Project: A SOAP client/server library in C +* Copyright (C) 2007 Heiko Ronsdorf +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Library General Public +* License as published by the Free Software Foundation; either +* version 2 of the License, or (at your option) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Library General Public License for more details. +* +* You should have received a copy of the GNU Library General Public +* License along with this library; if not, write to the +* Free Software Foundation, Inc., 59 Temple Place - Suite 330, +* Boston, MA 02111-1307, USA. +* +* Email: hero@persua.de +******************************************************************/ +#ifndef __soap_nhttp_h +#define __soap_nhttp_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * + * The SOAPAction HTTP request header field can be used to indicate the intent of + * the SOAP HTTP request. The value is a URI identifying the intent. SOAP places + * no restrictions on the format or specificity of the URI or that it is + * resolvable. An HTTP client MUST use this header field when issuing a SOAP + * HTTP Request. The presence and content of the SOAPAction header field can be + * used by servers such as firewalls to appropriately filter SOAP request + * messages in HTTP. The header field value of empty string ("") means that the + * intent of the SOAP message is provided by the HTTP Request-URI. No value + * means that there is no indication of the intent of the message. + * + */ +#define SOAP_NHTTP_SOAP_ACTION "SoapAction" + +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_router(SoapRouter *router, const char *context); + +extern short soap_nhttp_get_port(void); +extern const char *soap_nhttp_get_protocol(void); + +extern herror_t soap_nhttp_client_init_args(int argc, char **argv); +extern herror_t soap_nhttp_client_invoke(void *unused, SoapCtx *req, SoapCtx **res); +extern void soap_nhttp_client_destroy(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libcsoap/soap-nudp.c b/libcsoap/soap-nudp.c new file mode 100644 index 0000000..985cfd8 --- /dev/null +++ b/libcsoap/soap-nudp.c @@ -0,0 +1,98 @@ +/****************************************************************** +* $Id: soap-nudp.c,v 1.1 2006/11/21 20:59:02 m0gg Exp $ +* +* CSOAP Project: A SOAP client/server library in C +* Copyright (C) 2003 Ferhat Ayaz +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Library General Public +* License as published by the Free Software Foundation; either +* version 2 of the License, or (at your option) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Library General Public License for more details. +* +* You should have received a copy of the GNU Library General Public +* License along with this library; if not, write to the +* Free Software Foundation, Inc., 59 Temple Place - Suite 330, +* Boston, MA 02111-1307, USA. +* +* Email: ayaz@jprogrammer.net +******************************************************************/ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#ifdef HAVE_STDIO_H +#include <stdio.h> +#endif + +#ifdef HAVE_ERRNO_H +#include <errno.h> +#endif + +#ifdef HAVE_NETINET_IN_H +#include <netinet/in.h> +#endif + +#include <libxml/tree.h> +#include <libxml/uri.h> + +#include <nanohttp/nanohttp-common.h> +#include <nanohttp/nanohttp-socket.h> +#include <nanohttp/nanohttp-stream.h> +#include <nanohttp/nanohttp-request.h> +#include <nanohttp/nanohttp-server.h> +#include <nanohttp/nanohttp-logging.h> + +#include "soap-fault.h" +#include "soap-env.h" +#include "soap-ctx.h" +#include "soap-service.h" +#include "soap-router.h" +#include "soap-server.h" +#include "soap-addressing.h" + +herror_t +soap_nudp_server_init_args(int argc, char **argv) +{ + return H_OK; +} + +herror_t +soap_nudp_register_router(SoapRouter *router, const char *context) +{ + return H_OK; +} + +herror_t +soap_nudp_server_run(void) +{ + return H_OK; +} + +void +soap_nudp_server_destroy(void) +{ + return; +} + +herror_t +soap_nudp_client_init_args(int argc, char **argv) +{ + return H_OK; +} + +herror_t +soap_nudp_client_invoke(SoapCtx *req, SoapCtx **res) +{ + return H_OK; +} + +void +soap_nudp_client_destroy(void) +{ + return; +} diff --git a/libcsoap/soap-nudp.h b/libcsoap/soap-nudp.h new file mode 100644 index 0000000..73bc612 --- /dev/null +++ b/libcsoap/soap-nudp.h @@ -0,0 +1,47 @@ +/****************************************************************** +* $Id: soap-nudp.h,v 1.1 2006/11/21 20:59:02 m0gg Exp $ +* +* CSOAP Project: A SOAP client/server library in C +* Copyright (C) 2007 Heiko Ronsdorf +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Library General Public +* License as published by the Free Software Foundation; either +* version 2 of the License, or (at your option) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Library General Public License for more details. +* +* You should have received a copy of the GNU Library General Public +* License along with this library; if not, write to the +* Free Software Foundation, Inc., 59 Temple Place - Suite 330, +* Boston, MA 02111-1307, USA. +* +* Email: hero@persua.de +******************************************************************/ +#ifndef __soap_nudp_h +#define __soap_nudp_h + +#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_destroy(void); + +#ifdef __CSOAP_INTERNAL +extern herror_t soap_nudp_register_router(SoapRouter *router, const char *context); +#endif + +extern herror_t soap_nudp_client_init_args(int argc, char **argv); +extern herror_t soap_nudp_client_invoke(SoapCtx *req, SoapCtx **res); +extern void soap_nudp_client_destroy(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libcsoap/soap-router.c b/libcsoap/soap-router.c index 9f67460..0a9ee63 100644 --- a/libcsoap/soap-router.c +++ b/libcsoap/soap-router.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: soap-router.c,v 1.11 2006/11/19 09:40:14 m0gg Exp $ +* $Id: soap-router.c,v 1.12 2006/11/21 20:59:02 m0gg Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -25,10 +25,6 @@ #include <config.h> #endif -#ifdef HAVE_SYS_TIME_H -#include <sys/time.h> -#endif - #ifdef HAVE_STDIO_H #include <stdio.h> #endif @@ -45,6 +41,8 @@ #include <errno.h> #endif +#include <libxml/tree.h> + #include <nanohttp/nanohttp-common.h> #include <nanohttp/nanohttp-socket.h> #include <nanohttp/nanohttp-stream.h> @@ -52,6 +50,11 @@ #include <nanohttp/nanohttp-server.h> #include <nanohttp/nanohttp-logging.h> +#include "soap-fault.h" +#include "soap-env.h" +#include "soap-ctx.h" +#include "soap-service.h" + #include "soap-router.h" SoapRouter * @@ -69,14 +72,15 @@ soap_router_new(void) return router; } -void -soap_router_register_service(SoapRouter * router, - SoapServiceFunc func, - const char *method, const char *urn) +herror_t +soap_router_register_service(SoapRouter *router, SoapServiceFunc func, const char *method, const char *urn) { SoapService *service; - service = soap_service_new(urn, method, func); + log_verbose4("registering service (router=%p, method=\"%s\", urn=\"%s\")", router, method, urn); + + if (!(service = soap_service_new(urn, method, func))) + return herror_new("soap_router_register_service", 0, "soap_service_new failed"); if (router->service_tail == NULL) { @@ -89,7 +93,7 @@ soap_router_register_service(SoapRouter * router, router->service_tail = router->service_tail->next; } - return; + return H_OK; } void @@ -111,12 +115,13 @@ soap_router_register_description(SoapRouter * router, xmlDocPtr wsdl) return; } -void +herror_t soap_router_register_default_service(SoapRouter *router, SoapServiceFunc func, const char *method, const char *urn) { SoapService *service; - service = soap_service_new(urn, method, func); + if (!(service = soap_service_new(urn, method, func))) + return herror_new("soap_router_register_default_service", 0, "soap_service_new failed"); if (router->service_tail == NULL) { @@ -130,17 +135,34 @@ soap_router_register_default_service(SoapRouter *router, SoapServiceFunc func, c router->default_service = service; - return; + return H_OK; } SoapService * -soap_router_find_service(SoapRouter * router, - const char *urn, const char *method) +soap_router_find_service(SoapRouter *router, const char *urn, const char *method) { SoapServiceNode *node; - if (router == NULL || urn == NULL || method == NULL) + if (router == NULL) + { + log_verbose1("router is null"); return NULL; + } + + if (urn == NULL) + { + log_verbose1("URN is null"); + return NULL; + } + + if (method == NULL) + { + log_verbose1("method is null"); + return NULL; + } + + log_verbose2("router = %p", router); + log_verbose2("router->service_head = %p", router->service_head); node = router->service_head; @@ -148,20 +170,15 @@ soap_router_find_service(SoapRouter * router, { if (node->service && node->service->urn && node->service->method) { - - if (!strcmp(node->service->urn, urn) - && !strcmp(node->service->method, method)) + log_verbose4("checking service (node=%p, method=\"%s\", urn=\"%s\")", node->service, node->service->method, node->service->urn); + if (!strcmp(node->service->urn, urn) && !strcmp(node->service->method, method)) return node->service; - } - node = node->next; } - return router->default_service; } - void soap_router_free(SoapRouter * router) { diff --git a/libcsoap/soap-router.h b/libcsoap/soap-router.h index 3c8b6f7..da6199f 100644 --- a/libcsoap/soap-router.h +++ b/libcsoap/soap-router.h @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: soap-router.h,v 1.9 2006/11/19 09:40:14 m0gg Exp $ + * $Id: soap-router.h,v 1.10 2006/11/21 20:59:02 m0gg Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -21,10 +21,8 @@ * * Email: ayaz@jprogrammer.net ******************************************************************/ -#ifndef cSOAP_ROUTER_H -#define cSOAP_ROUTER_H - -#include <libcsoap/soap-service.h> +#ifndef __csoap_router_h +#define __csoap_router_h /** The router object. A router can store a set of @@ -52,7 +50,7 @@ extern "C" { @returns Soap router @see soap_router_free */ -SoapRouter *soap_router_new(void); +extern SoapRouter *soap_router_new(void); /** @@ -65,16 +63,16 @@ SoapRouter *soap_router_new(void); the client side. @param urn The urn for this service */ -void soap_router_register_service(SoapRouter * router, +extern herror_t soap_router_register_service(SoapRouter * router, SoapServiceFunc func, const char *method, const char *urn); -void soap_router_register_default_service(SoapRouter * router, SoapServiceFunc func, const char *method, const char *urn); +extern herror_t soap_router_register_default_service(SoapRouter * router, SoapServiceFunc func, const char *method, const char *urn); -void soap_router_register_description(SoapRouter *router, xmlDocPtr doc); +extern void soap_router_register_description(SoapRouter *router, xmlDocPtr doc); -void soap_router_register_security(SoapRouter *router, httpd_auth auth); +extern void soap_router_register_security(SoapRouter *router, httpd_auth auth); /** Searches for a registered soap service. @@ -85,16 +83,14 @@ void soap_router_register_security(SoapRouter *router, httpd_auth auth); @return The service if found, NULL otherwise. */ -SoapService *soap_router_find_service(SoapRouter * router, - const char *urn, const char *method); - +extern SoapService *soap_router_find_service(SoapRouter * router, const char *urn, const char *method); /** Frees the router object. @param router The router object to free */ -void soap_router_free(SoapRouter * router); +extern void soap_router_free(SoapRouter * router); #ifdef __cplusplus } diff --git a/libcsoap/soap-server.c b/libcsoap/soap-server.c index 638105f..11dbf53 100644 --- a/libcsoap/soap-server.c +++ b/libcsoap/soap-server.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: soap-server.c,v 1.28 2006/11/21 08:34:34 m0gg Exp $ +* $Id: soap-server.c,v 1.29 2006/11/21 20:59:02 m0gg Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -49,180 +49,29 @@ #define snprintf(buffer, num, s1, s2) sprintf(buffer, s1,s2) #endif +#include <libxml/tree.h> +#include <libxml/uri.h> + #include <nanohttp/nanohttp-common.h> #include <nanohttp/nanohttp-socket.h> #include <nanohttp/nanohttp-stream.h> #include <nanohttp/nanohttp-request.h> -#include <nanohttp/nanohttp-response.h> #include <nanohttp/nanohttp-server.h> #include <nanohttp/nanohttp-logging.h> -#include "soap-admin.h" +#include "soap-fault.h" +#include "soap-env.h" +#include "soap-ctx.h" +#include "soap-service.h" +#include "soap-router.h" +#include "soap-addressing.h" +#include "soap-transport.h" + #include "soap-server.h" static SoapRouterNode *head = NULL; static SoapRouterNode *tail = NULL; -// static SoapRouter *router_find(const char *context); - -static void -_soap_server_send_env(http_output_stream_t * out, SoapEnv * env) -{ - xmlBufferPtr buffer; - if (env == NULL || env->root == NULL) - return; - - buffer = xmlBufferCreate(); - xmlNodeDump(buffer, env->root->doc, env->root, 1, 1); - http_output_stream_write_string(out, - (const char *) xmlBufferContent(buffer)); - xmlBufferFree(buffer); - - return; -} - -static void -_soap_server_send_fault(httpd_conn_t * conn, const char *errmsg) -{ - SoapEnv *envres; - hpair_t *header; - herror_t err; - char buffer[45]; - - header = hpairnode_new(HEADER_CONTENT_TYPE, "text/xml", NULL); - - httpd_set_headers(conn, header); - - if ((err = httpd_send_header(conn, 500, "FAILED")) != H_OK) - { - /* WARNING: unhandled exception ! */ - log_error4("%s():%s [%d]", herror_func(err), herror_message(err), - herror_code(err)); - - herror_release(err); - return; - } - - err = soap_env_new_with_fault(Fault_Server, - errmsg ? errmsg : "General error", - "cSOAP_Server", NULL, &envres); - if (err != H_OK) - { - log_error1(herror_message(err)); - http_output_stream_write_string(conn->out, - "<html>" - "<head></head>" - "<body>" - "<h1>Error</h1><hr/>" - "Error while sending fault object:" - "<br />Message: "); - http_output_stream_write_string(conn->out, herror_message(err)); - http_output_stream_write_string(conn->out, "<br />Function: "); - http_output_stream_write_string(conn->out, herror_func(err)); - http_output_stream_write_string(conn->out, "<br />Error code: "); - sprintf(buffer, "%d", herror_code(err)); - http_output_stream_write_string(conn->out, buffer); - http_output_stream_write_string(conn->out, "</body></html>"); - - herror_release(err); - } - else - { - _soap_server_send_env(conn->out, envres); - } - - hpairnode_free(header); - - return; -} - -static void -_soap_server_send_ctx(httpd_conn_t * conn, SoapCtx * ctx) -{ - static int counter = 1; - xmlBufferPtr buffer; - char strbuffer[32]; - part_t *part; - - if (ctx->env == NULL || ctx->env->root == NULL || ctx->env->root->doc == NULL) - return; - - xmlThrDefIndentTreeOutput(1); -/* xmlKeepBlanksDefault(0);*/ - - buffer = xmlBufferCreate(); - xmlNodeDump(buffer, ctx->env->root->doc, ctx->env->root, 1, 1); - - if (ctx->attachments) - { - sprintf(strbuffer, "000128590350940924234%d", counter++); - httpd_mime_send_header(conn, strbuffer, "", "text/xml", 200, "OK"); - httpd_mime_next(conn, strbuffer, "text/xml", "binary"); - http_output_stream_write_string(conn->out, - (const char *) xmlBufferContent(buffer)); - part = ctx->attachments->parts; - while (part) - { - httpd_mime_send_file(conn, part->id, part->content_type, - part->transfer_encoding, part->filename); - part = part->next; - } - httpd_mime_end(conn); - } - else - { - char buflen[100]; - xmlXPathContextPtr xpathCtx; - xmlXPathObjectPtr xpathObj; - - xpathCtx = xmlXPathNewContext(ctx->env->root->doc); - xpathObj = xmlXPathEvalExpression("//Fault", xpathCtx); - - snprintf(buflen, 100, "%d", xmlBufferLength(buffer)); - httpd_set_header(conn, HEADER_CONTENT_LENGTH, buflen); - httpd_set_header(conn, HEADER_CONTENT_TYPE, "text/xml"); - - if ((xpathObj->nodesetval) ? xpathObj->nodesetval->nodeNr : 0) - { - httpd_send_header(conn, 500, "FAILED"); - } - else - { - httpd_send_header(conn, 200, "OK"); - } - - http_output_stream_write_string(conn->out, - (const char *) xmlBufferContent(buffer)); - xmlXPathFreeObject(xpathObj); - xmlXPathFreeContext(xpathCtx); - - } - xmlBufferFree(buffer); - - return; -} - -static void -_soap_server_send_description(httpd_conn_t *conn, xmlDocPtr wsdl) -{ - char length[16]; - xmlBufferPtr buf; - - buf = xmlBufferCreate(); - xmlNodeDump(buf, wsdl, xmlDocGetRootElement(wsdl), 0, 0); - - sprintf(length, "%d", xmlBufferLength(buf)); - httpd_set_header(conn, HEADER_CONTENT_TYPE, "text/xml"); - httpd_set_header(conn, HEADER_CONTENT_LENGTH, length); - httpd_send_header(conn, 200, "OK"); - - http_output_stream_write_string(conn->out, xmlBufferContent(buf)); - - xmlBufferFree(buf); - - return; -} - static SoapRouterNode * router_node_new(SoapRouter * router, const char *context, SoapRouterNode * next) { @@ -241,7 +90,7 @@ router_node_new(SoapRouter * router, const char *context, SoapRouterNode * next) } else { - log_warn2("context is null. Using '%s'", noname); + log_warn2("context is null, using '%s'", noname); node->context = strdup(noname); } @@ -265,170 +114,111 @@ soap_server_find_router(const char *context) return NULL; } -static void -soap_server_entry(httpd_conn_t * conn, hrequest_t * req) +static herror_t +_soap_server_env_new_with_fault(const char *fault_string, const char *detail, SoapEnv **out) +{ + return soap_env_new_with_fault(SOAP_FAULT_RECEIVER, fault_string, soap_server_get_name(), detail, out); +} + +herror_t +soap_server_process(SoapCtx *request, SoapCtx **response) { char buffer[1054]; char *urn; char *method; - SoapCtx *ctx, *ctxres; + char *to; SoapRouter *router; SoapService *service; - SoapEnv *env; herror_t err; - if (!(router = soap_server_find_router(req->path))) + log_verbose1("processing"); + soap_xml_doc_print(request->env->root->doc); + + *response = soap_ctx_new(NULL); + + if (!(method = soap_env_find_methodname(request->env))) { - _soap_server_send_fault(conn, "Cannot find router"); - return; + _soap_server_env_new_with_fault("No method found", "The method is missing in the SOAP envelope", &((*response)->env)); + return H_OK; } - else if (req->method == HTTP_REQUEST_GET && router->wsdl) + log_verbose2("method: \"%s\"", method); + + if (!(urn = soap_env_find_urn(request->env))) { - _soap_server_send_description(conn, router->wsdl); - return; + _soap_server_env_new_with_fault("No URN found", "The URN is missing in the SOAP envelope", &((*response)->env)); + return H_OK; } + log_verbose2("urn: \"%s\"", urn); - if (req->method != HTTP_REQUEST_POST) + if ((to = soap_addressing_get_to_address_string(request->env))) { - httpd_send_header(conn, 200, "OK"); - http_output_stream_write_string(conn->out, - "<html>" - "<head>" - "</head>" - "<body>" - "<h1>Sorry!</h1>" - "<hr />" - "<div>I only speak with 'POST' method.</div>" - "</body>" - "</html>"); - return; + if (!(router = soap_server_find_router(to))) + { + sprintf(buffer, "no router for context \"%s\" found", to); + _soap_server_env_new_with_fault(buffer, "The method is unknown by the server", &((*response)->env)); + free(to); + return H_OK; + } + free(to); + } + else + { + _soap_server_env_new_with_fault(buffer, "The destination address is missing", &((*response)->env)); + return H_OK; } + log_verbose2("router: %p", router); - if ((err = soap_env_new_from_stream(req->in, &env)) != H_OK) + if (!(service = soap_router_find_service(router, urn, method))) { - _soap_server_send_fault(conn, herror_message(err)); - herror_release(err); - return; + sprintf(buffer, "no service for URN \"%s\" found", urn); + _soap_server_env_new_with_fault(buffer, "The URN is not known by the server", &((*response)->env)); + return H_OK; } + log_verbose2("service found (%p)", service); - if (env == NULL) + log_verbose2("service function: %p", service->func); + if ((err = service->func(request, *response)) != H_OK) { - _soap_server_send_fault(conn, "Can not receive POST data!"); + sprintf(buffer, "Service returned following error message: \"%s\"", herror_message(err)); + herror_release(err); + _soap_server_env_new_with_fault("Internal service error", buffer, &((*response)->env)); + return H_OK; } - else + + if ((*response)->env == NULL) { + sprintf(buffer, "Service \"%s\" returned no envelope", urn); + _soap_server_env_new_with_fault("Internal service error", buffer, &((*response)->env)); + return H_OK; + } - ctx = soap_ctx_new(env); - ctx->action = hpairnode_get_ignore_case(req->header, "SoapAction"); - if (ctx->action) - ctx->action = strdup(ctx->action); + return H_OK; +} - ctx->http = req; - soap_ctx_add_files(ctx, req->attachments); +herror_t +soap_server_init_args(int argc, char *argv[]) +{ + herror_t status; - if (ctx->env == NULL) - { - _soap_server_send_fault(conn, "Can not parse POST data!"); - } - else - { + if ((status = soap_transport_server_init_args(argc, argv)) != H_OK) + return status; - /* soap_xml_doc_print(env->root->doc); */ - - if (!(urn=soap_env_find_urn(ctx->env))) - { - - _soap_server_send_fault(conn, "No URN found!"); - soap_ctx_free(ctx); - return; - } - else - { - log_verbose2("urn: '%s'", urn); - } - - if (!(method=soap_env_find_methodname(ctx->env))) - { - _soap_server_send_fault(conn, "No method found!"); - soap_ctx_free(ctx); - return; - } - else - { - log_verbose2("method: '%s'", method); - } - - service = soap_router_find_service(router, urn, method); - - if (service == NULL) - { - - sprintf(buffer, "URN '%s' not found", urn); - _soap_server_send_fault(conn, buffer); - soap_ctx_free(ctx); - return; - } - else - { - - log_verbose2("func: %p", service->func); - ctxres = soap_ctx_new(NULL); - /* ===================================== */ - /* CALL SERVICE FUNCTION */ - /* ===================================== */ - if ((err = service->func(ctx, ctxres)) != H_OK) - { - sprintf(buffer, "Service returned following error message: '%s'", - herror_message(err)); - herror_release(err); - _soap_server_send_fault(conn, buffer); - soap_ctx_free(ctx); - return; - } - - if (ctxres->env == NULL) - { - - sprintf(buffer, "Service '%s' returned no envelope", urn); - _soap_server_send_fault(conn, buffer); - soap_ctx_free(ctx); - return; - } - else - { - -/* httpd_send_header(conn, 200, "OK"); - _soap_server_send_env(conn->out, ctxres->env); -*/ - _soap_server_send_ctx(conn, ctxres); - /* free envctx */ - soap_ctx_free(ctxres); - } - } - } - soap_ctx_free(ctx); - } + return H_OK; } -herror_t -soap_server_init_args(int argc, char *argv[]) +const char * +soap_server_get_name(void) { - herror_t err; - - if ((err = httpd_init(argc, argv)) != H_OK) - return err; - - return soap_admin_init_args(argc, argv); + return soap_transport_get_name(); } -int -soap_server_register_router(SoapRouter * router, const char *context) +herror_t +soap_server_register_router(SoapRouter *router, const char *context) { + herror_t status; - if (!httpd_register_secure(context, soap_server_entry, router->auth)) - { - return 0; - } + if ((status = soap_transport_register_router(router, context)) != H_OK) + return status; if (tail == NULL) { @@ -440,7 +230,7 @@ soap_server_register_router(SoapRouter * router, const char *context) tail = tail->next; } - return 1; + return H_OK; } SoapRouterNode * @@ -452,23 +242,16 @@ soap_server_get_routers(void) herror_t soap_server_run(void) { - return httpd_run(); -} + herror_t status; -int -soap_server_get_port(void) -{ - return httpd_get_port(); -} + if ((status = soap_transport_server_run()) != H_OK) + return status; -const char * -soap_server_get_protocol(void) -{ - return httpd_get_protocol(); + return H_OK; } void -soap_server_destroy() +soap_server_destroy(void) { SoapRouterNode *node = head; SoapRouterNode *tmp; @@ -482,7 +265,8 @@ soap_server_destroy() free(node); node = tmp; } - httpd_destroy(); + + soap_transport_server_destroy(); return; } diff --git a/libcsoap/soap-server.h b/libcsoap/soap-server.h index 738db1a..70fc6aa 100644 --- a/libcsoap/soap-server.h +++ b/libcsoap/soap-server.h @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: soap-server.h,v 1.11 2006/11/19 09:40:14 m0gg Exp $ + * $Id: soap-server.h,v 1.12 2006/11/21 20:59:02 m0gg Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -21,75 +21,85 @@ * * Email: ferhatayaz@yahoo.com ******************************************************************/ -#ifndef cSOAP_SERVER_H -#define cSOAP_SERVER_H - -#include <libcsoap/soap-env.h> -#include <libcsoap/soap-router.h> -#include <libcsoap/soap-ctx.h> - -typedef struct _SoapRouterNode -{ - char *context; - SoapRouter *router; - struct _SoapRouterNode *next; - -} SoapRouterNode; +#ifndef __csoap_server_h +#define __csoap_server_h #ifdef __cplusplus extern "C" { #endif /** - Initializes the soap server with commandline arguments. - - <TABLE border=1> - <TR><TH>Argument</TH><TH>Description</TH></TR> - <TR><TD>-NHTTPport [port]</TD><TD>Port to listen (default: 10000)</TD></TR> - <TR><TD>-NHTTPmaxconn [num]</TD><TD>Maximum thread connections</TD></TR> - <TR><TD>-NHTTPlog [logfilename]</TD><TD>logfile</TD></TR> - </TABLE> + * + * Initializes the soap server with commandline arguments. + * + * @param argc commandline arg count + * @param argv commandline arg vector + * + * @returns H_OK on success + * + * @see httpd_init_args + * @see udpd_init_args + * + */ +herror_t soap_server_init_args(int argc, char **argv); - @param argc commandline arg count - @param argv commandline arg vector - @returns 1 if success, 0 otherwise +/** + * + * Register a router to the soap server. + * + * <p><i>scheme</i>://<i>host</i>:<i>port</i>/<b>[context]</b> + * + * @param router The router to register + * @param context the url context + * + * @returns H_OK on success + * + * @see soap_router_new + * @see soap_router_register_service + * */ -herror_t soap_server_init_args(int argc, char *argv[]); +extern herror_t soap_server_register_router(SoapRouter * router, const char *context); +extern const char *soap_server_get_name(void); /** - Register a router to the soap server. - - <P>http://<I>host</I>:<I>port</I>/<B>[context]</B> + * + * Enters the server loop and starts to listen to incoming requests. + * + * @see httpd_run + * @see udpd_run + * + */ +extern herror_t soap_server_run(void); +/** + * + * Frees the soap server. + * + * @see httpd_destroy + * @see udpd_destroy + * + */ +extern void soap_server_destroy(void); - @param router The router to register - @param context the url context - @returns 1 if success, 0 otherwise - - @see soap_router_new - @see soap_router_register_service +#ifdef __CSOAP_INTERNAL - */ -int soap_server_register_router(SoapRouter * router, const char *context); +typedef struct _SoapRouterNode +{ + char *context; + SoapRouter *router; + struct _SoapRouterNode *next; -SoapRouter *soap_server_find_router(const char *context); +} SoapRouterNode; -SoapRouterNode * soap_server_get_routers(void); +extern SoapRouter *soap_server_find_router(const char *context); -/** - Enters the server loop and starts to listen to - http requests. - */ -herror_t soap_server_run(void); +extern SoapRouterNode * soap_server_get_routers(void); -int soap_server_get_port(void); +extern herror_t soap_server_process(SoapCtx *request, SoapCtx **response); -/** - Frees the soap server. - */ -void soap_server_destroy(void); +#endif #ifdef __cplusplus } diff --git a/libcsoap/soap-service.c b/libcsoap/soap-service.c index dc3a2a5..7a422c5 100644 --- a/libcsoap/soap-service.c +++ b/libcsoap/soap-service.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: soap-service.c,v 1.9 2006/11/19 09:40:14 m0gg Exp $ +* $Id: soap-service.c,v 1.10 2006/11/21 20:59:02 m0gg Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -25,8 +25,8 @@ #include <config.h> #endif -#ifdef HAVE_SYS_TIME_H -#include <sys/time.h> +#ifdef HAVE_STDLIB_H +#include <stdlib.h> #endif #ifdef HAVE_STDIO_H @@ -37,16 +37,23 @@ #include <string.h> #endif +#ifdef HAVE_ERRNO_H +#include <errno.h> +#endif + #ifdef HAVE_NETINET_IN_H #include <netinet/in.h> #endif +#include <libxml/tree.h> +#include <libxml/uri.h> + #include <nanohttp/nanohttp-common.h> -#include <nanohttp/nanohttp-socket.h> -#include <nanohttp/nanohttp-stream.h> -#include <nanohttp/nanohttp-request.h> #include <nanohttp/nanohttp-logging.h> +#include "soap-fault.h" +#include "soap-env.h" +#include "soap-ctx.h" #include "soap-service.h" SoapServiceNode * @@ -98,11 +105,14 @@ soap_service_new(const char *urn, const char *method, SoapServiceFunc f) void soap_service_free(SoapService * service) { - if (service == NULL) + if (!service) return; - free(service->urn); - free(service->method); + if (service->urn) + free(service->urn); + + if (service->method) + free(service->method); free(service); diff --git a/libcsoap/soap-service.h b/libcsoap/soap-service.h index 594b994..f507d77 100644 --- a/libcsoap/soap-service.h +++ b/libcsoap/soap-service.h @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: soap-service.h,v 1.6 2006/03/06 13:37:38 m0gg Exp $ + * $Id: soap-service.h,v 1.7 2006/11/21 20:59:02 m0gg Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -21,15 +21,11 @@ * * Email: ferhatayaz@jprogrammer.net ******************************************************************/ -#ifndef cSOAP_SERVICE_H -#define cSOAP_SERVICE_H - -#include <libcsoap/soap-env.h> -#include <libcsoap/soap-ctx.h> +#ifndef __csoap_service_h +#define __csoap_service_h typedef herror_t(*SoapServiceFunc) (SoapCtx *, SoapCtx *); - typedef struct _SoapService { char *urn; diff --git a/libcsoap/soap-transport.c b/libcsoap/soap-transport.c new file mode 100644 index 0000000..6c84e35 --- /dev/null +++ b/libcsoap/soap-transport.c @@ -0,0 +1,255 @@ +/****************************************************************** +* $Id: soap-transport.c,v 1.1 2006/11/21 20:59:02 m0gg Exp $ +* +* CSOAP Project: A SOAP client/server library in C +* Copyright (C) 2007 Heiko Ronsdorf +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Library General Public +* License as published by the Free Software Foundation; either +* version 2 of the License, or (at your option) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Library General Public License for more details. +* +* You should have received a copy of the GNU Library General Public +* License along with this library; if not, write to the +* Free Software Foundation, Inc., 59 Temple Place - Suite 330, +* Boston, MA 02111-1307, USA. +* +* Email: hero@persua.de +******************************************************************/ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif + +#ifdef HAVE_STRING_H +#include <string.h> +#endif + +#ifdef HAVE_NETINET_IN_H +#include <netinet/in.h> +#endif + +#include <libxml/tree.h> +#include <libxml/uri.h> + +#include <nanohttp/nanohttp-common.h> +#include <nanohttp/nanohttp-socket.h> +#include <nanohttp/nanohttp-stream.h> +#include <nanohttp/nanohttp-request.h> +#include <nanohttp/nanohttp-server.h> +#include <nanohttp/nanohttp-logging.h> + +#include "soap-fault.h" +#include "soap-env.h" +#include "soap-ctx.h" +#include "soap-service.h" +#include "soap-router.h" +#include "soap-addressing.h" +#include "soap-server.h" + +#include "soap-nhttp.h" +#include "soap-nudp.h" + +#include "soap-transport.h" + +struct soap_transport +{ + char *scheme; + void *data; + msg_exchange invoke; + struct soap_transport *next; +}; + +static struct soap_transport *head = NULL; +static char soap_transport_name[512] = "not set"; + +herror_t +soap_transport_receive(SoapCtx *request, SoapCtx **response) +{ + return soap_server_process(request, response); +} + +static struct soap_transport * +_soap_transport_new(const char *scheme, void *data, msg_exchange invoke) +{ + struct soap_transport *ret; + + if (!(ret = (struct soap_transport *)malloc(sizeof(struct soap_transport)))) + { + log_error2("malloc failed (%s)", strerror(errno)); + return NULL; + } + + memset(ret, 0, sizeof(struct soap_transport)); + + ret->scheme = strdup(scheme); + ret->data = data; + ret->invoke = invoke; + + log_verbose4("scheme=%s, data=%p, invoke=%p", ret->scheme, ret->data, ret->invoke); + + return ret; +} + +static void * +_soap_transport_destroy(struct soap_transport *transport) +{ + void *ret; + + if (transport->scheme) + free(transport->scheme); + + ret = transport->data; + + free(transport); + + return ret; +} + +herror_t +soap_transport_server_init_args(int argc, char **argv) +{ + herror_t status; + char hostname[256]; + + if ((status = soap_nhttp_server_init_args(argc, argv)) != H_OK) + return status; + + if ((status = soap_nudp_server_init_args(argc, argv)) != H_OK) + return status; + + gethostname(hostname, 256); + sprintf(soap_transport_name, "%s://%s:%i/csoap", soap_nhttp_get_protocol(), hostname, soap_nhttp_get_port()); + + return H_OK; +} + +herror_t +soap_transport_register_router(SoapRouter *router, const char *context) +{ + herror_t status; + + if ((status = soap_nhttp_register_router(router, context)) != H_OK) + return status; + + if ((status = soap_nudp_register_router(router, context)) != H_OK) + return status; + + return H_OK; +} + +herror_t +soap_transport_add(const char *scheme, void *data, msg_exchange invoke) +{ + struct soap_transport *transport; + struct soap_transport *walker; + + if (!(transport = _soap_transport_new(scheme, data, invoke))) + { + log_error1("_soap_transport_new failed"); + return H_OK; + } + + if (head == NULL) + { + head = transport; + } + else + { + for (walker=head; walker->next; walker=head->next); + /* nothing */ + walker->next = transport; + } + return H_OK; +} + +herror_t +soap_transport_server_run(void) +{ + herror_t status; + + if ((status = soap_nhttp_server_run()) != H_OK) + return status; + + if ((status = soap_nudp_server_run()) != H_OK) + return status; + + return H_OK; +} + +const char * +soap_transport_get_name(void) +{ + return soap_transport_name; +} + +void +soap_transport_server_destroy(void) +{ + soap_nhttp_server_destroy(); + + soap_nudp_server_destroy(); + + return; +} + +herror_t +soap_transport_client_init_args(int argc, char **argv) +{ + herror_t status; + + if ((status = soap_nhttp_client_init_args(argc, argv)) != H_OK) + return status; + + if ((status = soap_nudp_client_init_args(argc, argv)) != H_OK) + return status; + + return H_OK; +} + +herror_t +soap_transport_client_invoke(SoapCtx *request, SoapCtx **response) +{ + struct soap_transport *walker; + herror_t ret; + xmlURI *dest; + + log_verbose1(__FUNCTION__); + soap_xml_doc_print(request->env->root->doc); + + dest = soap_addressing_get_to_address(request->env); + + log_verbose2("trying to contact \"%s\"", soap_addressing_get_to_address_string(request->env)); + + for (walker = head; walker; walker = walker->next) + { + if (!strcmp(walker->scheme, dest->scheme)) + { + log_verbose3("found transport layer for \"%s\" (%p)", dest->scheme, walker->invoke); + ret = walker->invoke(walker->data, request, response); + xmlFreeURI(dest); + return ret; + } + } + ret = herror_new("soap_transport_client_invoke", 0, "no transport service found for \"%s\"", dest->scheme); + xmlFreeURI(dest); + return ret; +} + +void +soap_transport_client_destroy(void) +{ + soap_nhttp_client_destroy(); + + soap_nudp_client_destroy(); + + return; +} diff --git a/libcsoap/soap-transport.h b/libcsoap/soap-transport.h new file mode 100644 index 0000000..8c31454 --- /dev/null +++ b/libcsoap/soap-transport.h @@ -0,0 +1,56 @@ +/****************************************************************** +* $Id: soap-transport.h,v 1.1 2006/11/21 20:59:02 m0gg Exp $ +* +* CSOAP Project: A SOAP client/server library in C +* Copyright (C) 2007 Heiko Ronsdorf +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Library General Public +* License as published by the Free Software Foundation; either +* version 2 of the License, or (at your option) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Library General Public License for more details. +* +* You should have received a copy of the GNU Library General Public +* License along with this library; if not, write to the +* Free Software Foundation, Inc., 59 Temple Place - Suite 330, +* Boston, MA 02111-1307, USA. +* +* Email: hero@persua.de +******************************************************************/ +#ifndef __csoap_transport_h +#define __csoap_transport_h + +#ifdef __CSOAP_INTERNAL +typedef herror_t (*msg_exchange)(void *data, SoapCtx *request, SoapCtx **response); + +#ifdef __cplusplus +extern "C" { +#endif + +extern herror_t soap_transport_server_init_args(int argc, char **argv); +extern herror_t soap_transport_server_run(void); +extern void soap_transport_server_destroy(void); + +extern const char *soap_transport_get_name(void); +extern herror_t soap_transport_add(const char *protocol, void *data, msg_exchange invoke); +extern herror_t soap_transport_remove(const char *protocol, void *data); +extern herror_t soap_transport_register_router(SoapRouter *router, const char *context); + +extern herror_t soap_transport_send(SoapCtx *request, SoapCtx **response); +extern herror_t soap_transport_receive(SoapCtx *request, SoapCtx **response); + +extern herror_t soap_transport_client_init_args(int argc, char **argv); +extern herror_t soap_transport_client_invoke(SoapCtx *req, SoapCtx **res); +extern void soap_transport_client_destroy(void); + +#ifdef __cplusplus +} +#endif + +#endif + +#endif diff --git a/libcsoap/soap-xml.h b/libcsoap/soap-xml.h index 801091d..9b0a7a5 100644 --- a/libcsoap/soap-xml.h +++ b/libcsoap/soap-xml.h @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: soap-xml.h,v 1.9 2006/11/21 08:34:34 m0gg Exp $ + * $Id: soap-xml.h,v 1.10 2006/11/21 20:59:02 m0gg Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -27,8 +27,6 @@ #include <libxml/xpath.h> #include <libxml/xpathInternals.h> -#include <nanohttp/nanohttp-common.h> - static const char * const soap_env_ns = "http://schemas.xmlsoap.org/soap/envelope/"; static const char * const soap_env_enc = "http://schemas.xmlsoap.org/soap/encoding/"; static const char * const soap_xsi_ns = "http://www.w3.org/1999/XMLSchema-instance"; diff --git a/nanohttp/Makefile.am b/nanohttp/Makefile.am index 311f1f1..18ccaf6 100644 --- a/nanohttp/Makefile.am +++ b/nanohttp/Makefile.am @@ -15,5 +15,5 @@ libnanohttp_la_HEADERS=nanohttp-common.h nanohttp-socket.h nanohttp-client.h nanohttp-admin.h libnanohttp_la_LDFLAGS= -version-info @nanohttp_version@ -release @nanohttp_release@ -libnanohttp_la_CFLAGS=-I${top_srcdir} +libnanohttp_la_CFLAGS=-I${top_srcdir} -D__NHTTP_INTERNAL=1 diff --git a/nanohttp/nanohttp-admin.c b/nanohttp/nanohttp-admin.c index 6ca9255..83c2931 100644 --- a/nanohttp/nanohttp-admin.c +++ b/nanohttp/nanohttp-admin.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: nanohttp-admin.c,v 1.2 2006/11/21 08:34:34 m0gg Exp $ +* $Id: nanohttp-admin.c,v 1.3 2006/11/21 20:59:02 m0gg Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -86,7 +86,7 @@ _httpd_admin_list_services(httpd_conn_t *conn) http_output_stream_write_string(conn->out, "<ul>"); for (node = httpd_get_services(); node; node = node->next) { - sprintf(buffer, "<li><a href=\"?" NHTTPD_ADMIN_QUERY_STATISTICS "=%s\">%s</a></li>", node->ctx, node->ctx); + sprintf(buffer, "<li><a href=\"%s\">%s</a> <a href=\"?" NHTTPD_ADMIN_QUERY_STATISTICS "=%s\">[Statistics]</a></li>", node->ctx, node->ctx, node->ctx); http_output_stream_write_string(conn->out, buffer); } http_output_stream_write_string(conn->out, "</ul>"); diff --git a/nanohttp/nanohttp-request.c b/nanohttp/nanohttp-request.c index 449bb7a..30c79df 100755 --- a/nanohttp/nanohttp-request.c +++ b/nanohttp/nanohttp-request.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: nanohttp-request.c,v 1.16 2006/11/21 08:34:34 m0gg Exp $ +* $Id: nanohttp-request.c,v 1.17 2006/11/21 20:59:02 m0gg Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -33,6 +33,10 @@ #include <stdio.h> #endif +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif + #ifdef HAVE_STRING_H #include <string.h> #endif diff --git a/nanohttp/nanohttp-request.h b/nanohttp/nanohttp-request.h index d34466a..ba1b907 100755 --- a/nanohttp/nanohttp-request.h +++ b/nanohttp/nanohttp-request.h @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: nanohttp-request.h,v 1.8 2006/11/19 09:40:14 m0gg Exp $ + * $Id: nanohttp-request.h,v 1.9 2006/11/21 20:59:02 m0gg Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003-2004 Ferhat Ayaz @@ -24,12 +24,14 @@ #ifndef NANO_HTTP_REQUEST_H #define NANO_HTTP_REQUEST_H +#ifdef __NHTTP_INTERNAL struct request_statistics { unsigned long bytes_transmitted; unsigned long bytes_received; struct timeval time; }; +#endif /* request object diff --git a/nanohttp/nanohttp-server.c b/nanohttp/nanohttp-server.c index c75eacf..269e741 100644 --- a/nanohttp/nanohttp-server.c +++ b/nanohttp/nanohttp-server.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: nanohttp-server.c,v 1.63 2006/11/19 09:40:14 m0gg Exp $ +* $Id: nanohttp-server.c,v 1.64 2006/11/21 20:59:03 m0gg Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -259,7 +259,7 @@ httpd_register_secure(const char *ctx, httpd_service func, httpd_auth auth) service->func = func; strcpy(service->ctx, ctx); - log_verbose3("register service:t(%p):%s", service, SAVE_STR(ctx)); + log_verbose3("register service (%p) for \"%s\"", service, SAVE_STR(ctx)); if (_httpd_services_head == NULL) { _httpd_services_head = _httpd_services_tail = service; @@ -280,8 +280,7 @@ httpd_register(const char *ctx, httpd_service service) } int -httpd_register_default_secure(const char *ctx, httpd_service service, - httpd_auth auth) +httpd_register_default_secure(const char *ctx, httpd_service service, httpd_auth auth) { int ret; @@ -648,7 +647,7 @@ httpd_session_main(void *data) done = 0; while (!done) { - log_verbose3("starting HTTP request on socket %p (%d)", conn->sock, conn->sock.sock); + log_verbose3("starting HTTP request on socket %d (%p)", conn->sock, conn->sock.sock); /* XXX: only used in WSAreaper */ conn->atime = time(NULL); diff --git a/nanohttp/nanohttp-server.h b/nanohttp/nanohttp-server.h index f132285..eb3a06b 100644 --- a/nanohttp/nanohttp-server.h +++ b/nanohttp/nanohttp-server.h @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: nanohttp-server.h,v 1.22 2006/11/19 09:40:14 m0gg Exp $ + * $Id: nanohttp-server.h,v 1.23 2006/11/21 20:59:03 m0gg Exp $ * * CSOAP Project: A http client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -42,6 +42,7 @@ typedef void (*httpd_service) (httpd_conn_t *, hrequest_t *); typedef int (*httpd_auth) (hrequest_t * req, const char *user, const char *password); +#ifdef __NHTTP_INTERNAL struct service_statistics { unsigned long requests; unsigned long bytes_transmitted; @@ -49,6 +50,7 @@ struct service_statistics { struct timeval time; pthread_rwlock_t lock; }; +#endif /* * Service representation object |