summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar snowdrop2004-02-03 08:10:05 +0000
committerGravatar snowdrop2004-02-03 08:10:05 +0000
commit8f709590c9c3262b7934af33378ca9230956df47 (patch)
tree0fd28c734de61ec778462012e436411f7e0e64b0
parent65949d1c0eebfb52a1c860a2fc5acb2df7e8c299 (diff)
downloadcsoap-8f709590c9c3262b7934af33378ca9230956df47.tar.gz
csoap-8f709590c9c3262b7934af33378ca9230956df47.tar.bz2
initial
-rw-r--r--libcsoap/soap-client.c106
-rw-r--r--libcsoap/soap-client.h37
-rw-r--r--libcsoap/soap-env.c386
-rw-r--r--libcsoap/soap-env.h77
-rw-r--r--libcsoap/soap-router.c101
-rw-r--r--libcsoap/soap-router.h51
-rw-r--r--libcsoap/soap-server.c268
-rw-r--r--libcsoap/soap-server.h39
-rw-r--r--libcsoap/soap-service.c86
-rw-r--r--libcsoap/soap-service.h56
10 files changed, 1207 insertions, 0 deletions
diff --git a/libcsoap/soap-client.c b/libcsoap/soap-client.c
new file mode 100644
index 0000000..f9e964f
--- /dev/null
+++ b/libcsoap/soap-client.c
@@ -0,0 +1,106 @@
+/******************************************************************
+ * $Id: soap-client.c,v 1.1 2004/02/03 08:10:05 snowdrop 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
+ ******************************************************************/
+#include <libcsoap/soap-client.h>
+#include <nanohttp/nanohttp-client.h>
+
+
+/*--------------------------------- */
+static SoapEnv *_soap_client_build_result(hresponse_t *res);
+/*--------------------------------- */
+
+
+SoapEnv*
+soap_client_invoke(SoapEnv *call, const char *url, const char *soap_action)
+{
+ /* Result document */
+ xmlDocPtr doc;
+
+ /* Buffer variables*/
+ xmlBufferPtr buffer;
+ char *content;
+
+ /* Transport variables */
+ httpc_conn_t *conn;
+ hresponse_t *res;
+
+ /* Create buffer */
+ buffer = xmlBufferCreate();
+ xmlNodeDump(buffer, call->root->doc,call->root, 1 ,2);
+ content = (char*)xmlBufferContent(buffer);
+
+ /* Transport via HTTP */
+ conn = httpc_new();
+ if (soap_action != NULL) {
+ httpc_set_header(conn, "SoapAction", soap_action);
+ }
+ res = httpc_post(conn, url, strlen(content), content);
+
+ /* Free buffer */
+ xmlBufferFree(buffer);
+
+ /* Build result */
+ /* TODO: If res == NULL, find out where and why it is NULL! */
+ doc = _soap_client_build_result(res);
+
+ return doc;
+}
+
+
+static
+SoapEnv* _soap_client_build_result(hresponse_t *res)
+{
+ xmlDocPtr doc;
+ SoapEnv *env;
+
+ log_verbose2("Building result (%p)", res);
+
+ if (res == NULL)
+ return soap_env_new_with_fault(Fault_Client,
+ "Response is NULL","","");
+
+ if (res->body == NULL)
+ return soap_env_new_with_fault(Fault_Client,
+ "Empty response from server!","","");
+
+
+
+ doc = xmlParseDoc(res->body);
+ if (doc == NULL) {
+ return soap_env_new_with_fault(Fault_Client,
+ "Response is not in XML format!","","");
+ }
+
+ env = soap_env_new_from_doc(doc);
+
+ if (env == NULL) {
+ xmlFreeDoc(doc);
+ return soap_env_new_with_fault(Fault_Client,
+ "Can not create envelope","","");
+ }
+
+ return env;
+}
+
+
+
diff --git a/libcsoap/soap-client.h b/libcsoap/soap-client.h
new file mode 100644
index 0000000..690808c
--- /dev/null
+++ b/libcsoap/soap-client.h
@@ -0,0 +1,37 @@
+/******************************************************************
+ * $Id: soap-client.h,v 1.1 2004/02/03 08:10:05 snowdrop 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
+ ******************************************************************/
+#ifndef cSOAP_CLIENT_H
+#define cSOAP_CLIENT_H
+
+#include <libcsoap/soap-env.h>
+
+
+SoapEnv* soap_client_invoke(SoapEnv *env,
+ const char *url,
+ const char *soap_action);
+
+
+#endif
+
+
diff --git a/libcsoap/soap-env.c b/libcsoap/soap-env.c
new file mode 100644
index 0000000..f7c1449
--- /dev/null
+++ b/libcsoap/soap-env.c
@@ -0,0 +1,386 @@
+/******************************************************************
+ * $Id: soap-env.c,v 1.1 2004/02/03 08:10:05 snowdrop 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
+ ******************************************************************/
+#include <libcsoap/soap-env.h>
+#include <stdarg.h>
+
+
+static char *soap_env_ns = "http://schemas.xmlsoap.org/soap/envelope/";
+static char *soap_env_enc = "http://schemas.xmlsoap.org/soap/encoding/";
+static char *soap_xsi_ns = "http://www.w3.org/1999/XMLSchema-instance";
+static char *soap_xsd_ns = "http://www.w3.org/1999/XMLSchema";
+
+/*
+ Parameters:
+ 1- soap_env_ns
+ 2- soap_env_enc
+ 3- xsi_ns
+ 4- xsd_ns
+ 3- method name
+ 4- uri
+ 5- method name(again)
+ */
+#define _SOAP_MSG_TEMPLATE_ \
+ "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"%s\" SOAP-ENV:encoding=\"%s\"" \
+ " xmlns:xsi=\"%s\"" \
+ " xmlns:xsd=\"%s\">" \
+ " <SOAP-ENV:Body>"\
+ " <m:%s xmlns:m=\"%s\">"\
+ " </m:%s>" \
+ " </SOAP-ENV:Body>"\
+ "</SOAP-ENV:Envelope>"
+
+
+
+SoapEnv *soap_env_new_with_fault(fault_code_t faultcode,
+ const char *faultstring,
+ const char *faultactor,
+ const char *detail)
+{
+ xmlDocPtr doc;
+ doc = soap_fault_build(faultcode, faultstring,
+ faultactor, detail);
+ if (doc == NULL) return NULL;
+ return soap_env_new_from_doc(doc);
+}
+
+
+SoapEnv *soap_env_new_with_response(SoapEnv* request)
+{
+ char urn[100];
+ char methodname[150];
+ char methodname2[150];
+
+ if (request == NULL) {
+ log_error1("request object is NULL");
+ return NULL;
+ }
+
+ if (request->root == NULL) {
+ log_error1("request has no xml");
+ return NULL;
+ }
+
+ if (!soap_env_find_methodname(request, methodname)) {
+ return NULL;
+ }
+
+ if (!soap_env_find_urn(request, urn)) {
+
+ /* here we have no chance to find out the namespace */
+ /* try to continue without namespace (urn) */
+ urn[0] = '\0';
+ }
+
+ sprintf(methodname2, "%sResponse", methodname);
+ return soap_env_new_with_method(urn, methodname2);
+}
+
+
+SoapEnv *soap_env_new_with_method(const char *urn, const char *method)
+{
+ xmlNodePtr env;
+ xmlNodePtr node;
+ SoapEnv *call;
+ char buffer[1054];
+
+
+ log_verbose2("URN = '%s'", urn);
+ log_verbose2("Method = '%s'",method);
+
+ sprintf(buffer, _SOAP_MSG_TEMPLATE_,
+ soap_env_ns, soap_env_enc, soap_xsi_ns,
+ soap_xsd_ns, method, urn, method);
+
+ env = xmlParseDoc(buffer);
+ call = soap_env_new_from_doc(env);
+
+ return call;
+}
+
+
+
+xmlNodePtr
+soap_env_add_item(SoapEnv *call, const char *type,
+ const char *name, const char *value)
+{
+
+ xmlNodePtr newnode;
+
+ newnode = xmlNewTextChild(call->cur, NULL, name, value);
+
+ if (newnode == NULL) {
+ log_error1("Can not create new xml node");
+ return NULL;
+ }
+
+ if (type) {
+ if (!xmlNewProp(newnode, "xsi:type", type)) {
+ log_error1("Can not create new xml attribute");
+ return NULL;
+ }
+ }
+
+ return newnode;
+}
+
+
+xmlNodePtr
+soap_env_add_itemf(SoapEnv *call, const char *type,
+ const char *name, const char *format, ...)
+{
+
+ va_list ap;
+ char buffer[1054];
+ xmlNodePtr newnode;
+
+
+ va_start(ap, format);
+ vsprintf(buffer, format, ap);
+ va_end(ap);
+
+ return soap_env_add_item(call, type, name, buffer);
+}
+
+
+xmlNodePtr
+soap_env_push_item(SoapEnv *call, const char *type,
+ const char *name)
+{
+
+ xmlNodePtr node;
+
+ node = soap_env_add_item(call, type, name, "");
+
+ if (node) {
+ call->cur = node;
+ }
+
+ return node;
+}
+
+
+void
+soap_env_pop_item(SoapEnv *call)
+{
+ call->cur = call->cur->parent;
+}
+
+void soap_env_free(SoapEnv *env)
+{
+ if (env) {
+ if (env->root) {
+ xmlFreeDoc(env->root->doc);
+ }
+ free(env);
+ }
+}
+
+
+SoapEnv *soap_env_new_from_doc(xmlDocPtr doc)
+{
+ SoapEnv *env;
+ xmlNodePtr node;
+
+ if (doc == NULL) {
+ log_error1("Can not create xml document!");
+ return NULL;
+ }
+
+ node = xmlDocGetRootElement(doc);
+ if (node == NULL) {
+ log_error1("xml document is empty!");
+ return NULL;
+ }
+
+ env = (SoapEnv*)malloc(sizeof(SoapEnv));
+
+ /* set root */
+ env->root = node;
+
+ /* set method root
+ set call->cur (current node) to <method>.
+ xpath: //Envelope/Body/
+ */
+ node = soap_xml_get_children(env->root);
+ env->cur = soap_xml_get_children(node);
+
+ return env;
+}
+
+
+
+
+SoapEnv *soap_env_new_from_buffer(const char* buffer)
+{
+ xmlDocPtr doc;
+ SoapEnv *env;
+
+ if (buffer == NULL) return NULL;
+
+ doc = xmlParseDoc(buffer);
+ if (doc == NULL) return NULL;
+
+ env = soap_env_new_from_doc(doc);
+ if (env == NULL) {
+ xmlFreeDoc(doc);
+ return NULL;
+ }
+
+ return env;
+}
+
+
+xmlNodePtr
+soap_env_get_body(SoapEnv* env)
+{
+ xmlNodePtr node;
+
+ if (env == NULL) {
+ log_error1("env object is NULL");
+ return NULL;
+ }
+
+ if (env->root == NULL) {
+ log_error1("env has no xml");
+ return NULL;
+ }
+
+ node = soap_xml_get_children(env->root);
+
+ while (node != NULL) {
+ if (!strcmp(node->name, "Body"))
+ return node;
+ node = soap_xml_get_next(node);
+ }
+
+ log_error1("Node Body tag found!");
+ return NULL;
+}
+
+
+xmlNodePtr
+_soap_env_get_body(SoapEnv* env)
+{
+ xmlNodePtr node, body;
+ xmlNodeSetPtr nodeset;
+ xmlXPathObjectPtr xpathobj;
+ char *urn;
+ char methodname[150];
+
+ if (env == NULL) {
+ log_error1("env object is NULL");
+ return NULL;
+ }
+
+ if (env->root == NULL) {
+ log_error1("env has no xml");
+ return NULL;
+ }
+
+ /*
+ find <Body> tag find out namespace
+ xpath: //Envelope/Body/
+ */
+ xpathobj = soap_xpath_eval(env->root->doc, "//Envelope/Body");
+
+ if (!xpathobj) {
+ log_error1("No Body (xpathobj)!");
+ return NULL;
+ }
+
+ nodeset = xpathobj->nodesetval;
+ if (!nodeset) {
+ log_error1("No Body (nodeset)!");
+ return NULL;
+ }
+
+ if (nodeset->nodeNr < 1) {
+ log_error1("No Body (nodeNr)!");
+ xmlXPathFreeObject(nodeset);
+ return NULL;
+ }
+
+ body = nodeset->nodeTab[0]; /* body is <Body> */
+ xmlXPathFreeObject(nodeset);
+ return body;
+
+}
+
+
+int soap_env_find_urn(SoapEnv *env, char *urn)
+{
+ xmlNsPtr ns;
+ xmlNodePtr body, node;
+
+ body = soap_env_get_body(env);
+ if (body == NULL) {
+ log_verbose1("body is NULL");
+ return 0;
+ }
+
+ /* node is the first child */
+ node = soap_xml_get_children(body);
+
+ if (node == NULL) {
+ log_error1("No namespace found");
+ return 0;
+ }
+
+ if (node->ns && node->ns->prefix) {
+ ns = xmlSearchNs(body->doc, node, node->ns->prefix);
+ if (ns != NULL) {
+ strcpy(urn, (char*)ns->href);
+ return 1; /* namesapce found! */
+ }
+ }
+
+ log_error1("No namespace found. Returning 0");
+ return 0;
+}
+
+
+int soap_env_find_methodname(SoapEnv *env, char *method)
+{
+ xmlNodePtr body, node;
+
+ body = soap_env_get_body(env);
+ if (body == NULL) return 0;
+
+ node = soap_xml_get_children(body); /* node is the first child */
+
+ if (node == NULL) {
+ log_error1("No method found");
+ return 0;
+ }
+
+ if (node->name == NULL) {
+ log_error1("No methodname found");
+ return 0;
+
+ }
+
+ strcpy(method, node->name);
+
+ return 1;
+}
diff --git a/libcsoap/soap-env.h b/libcsoap/soap-env.h
new file mode 100644
index 0000000..af969f3
--- /dev/null
+++ b/libcsoap/soap-env.h
@@ -0,0 +1,77 @@
+/******************************************************************
+ * $Id: soap-env.h,v 1.1 2004/02/03 08:10:05 snowdrop 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
+ ******************************************************************/
+#ifndef cSOAP_ENV_H
+#define cSOAP_ENV_H
+
+#include <libcsoap/soap-xml.h>
+#include <libcsoap/soap-fault.h>
+
+
+typedef struct _SoapEnv
+{
+ xmlNodePtr root;
+ xmlNodePtr cur;
+}SoapEnv;
+
+
+
+SoapEnv *soap_env_new_with_fault(fault_code_t faultcode,
+ const char *faultstring,
+ const char *faultactor,
+ const char *detail);
+SoapEnv *soap_env_new_with_method(const char *urn, const char *method);
+SoapEnv *soap_env_new_with_response(SoapEnv *method);
+SoapEnv *soap_env_new_from_doc(xmlDocPtr doc);
+SoapEnv *soap_env_new_from_buffer(const char* buffer);
+
+
+xmlNodePtr
+soap_env_add_item(SoapEnv* env, const char *type,
+ const char *name, const char *value);
+xmlNodePtr
+soap_env_add_itemf(SoapEnv* env, const char *type,
+ const char *name, const char *value, ...);
+xmlNodePtr
+soap_env_push_item(SoapEnv *env, const char *type,
+ const char *name);
+void
+soap_env_pop_item(SoapEnv* env);
+
+
+xmlNodePtr
+soap_env_get_body(SoapEnv* env);
+xmlNodePtr
+soap_env_get_fault(SoapEnv* env);
+xmlNodePtr
+soap_env_get_header(SoapEnv* env);
+
+
+int soap_env_find_urn(SoapEnv *env, char *urn);
+int soap_env_find_methodname(SoapEnv *env, char *methodname);
+
+
+
+#endif
+
+
diff --git a/libcsoap/soap-router.c b/libcsoap/soap-router.c
new file mode 100644
index 0000000..1d2141e
--- /dev/null
+++ b/libcsoap/soap-router.c
@@ -0,0 +1,101 @@
+/******************************************************************
+ * $Id: soap-router.c,v 1.1 2004/02/03 08:10:05 snowdrop 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
+ ******************************************************************/
+#include <libcsoap/soap-router.h>
+
+
+SoapRouter *soap_router_new()
+{
+ SoapRouter *router;
+
+ router = (SoapRouter*)malloc(sizeof(SoapRouter));
+ router->service_head = NULL;
+ router->service_tail = NULL;
+
+ return router;
+}
+
+
+void soap_router_register_service(SoapRouter *router,
+ SoapServiceFunc func,
+ const char* method,
+ const char* urn)
+{
+ SoapService *service;
+
+ service = soap_service_new(urn, method, func);
+
+ if (router->service_tail == NULL) {
+ router->service_head =
+ router->service_tail = soap_service_node_new(service, NULL);
+ } else {
+ router->service_tail->next =
+ soap_service_node_new(service, NULL);
+ router->service_tail = router->service_tail->next;
+ }
+}
+
+
+SoapService* soap_router_find_service(SoapRouter *router,
+ const char* urn,
+ const char* method)
+{
+ SoapServiceNode *node;
+
+ if (router == NULL || urn == NULL || method == NULL)
+ return NULL;
+
+ node = router->service_head;
+
+ while (node) {
+ if (node->service && node->service->urn
+ && node->service->method) {
+
+ if (!strcmp(node->service->urn, urn)
+ && !strcmp(node->service->method, method))
+ return node->service;
+
+ }
+
+ node = node->next;
+ }
+
+ return NULL;
+}
+
+
+void soap_router_free(SoapRouter *router)
+{
+ SoapServiceNode *node;
+
+ if (router == NULL) return;
+
+ while (router->service_head) {
+ node = router->service_head->next;
+ soap_service_free(router->service_head->service);
+ free(router->service_head);
+ router->service_head = node;
+ }
+
+ free(router);
+}
diff --git a/libcsoap/soap-router.h b/libcsoap/soap-router.h
new file mode 100644
index 0000000..34de257
--- /dev/null
+++ b/libcsoap/soap-router.h
@@ -0,0 +1,51 @@
+/******************************************************************
+ * $Id: soap-router.h,v 1.1 2004/02/03 08:10:05 snowdrop 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
+ ******************************************************************/
+#ifndef cSOAP_ROUTER_H
+#define cSOAP_ROUTER_H
+
+
+#include <libcsoap/soap-service.h>
+
+typedef struct _SoapRouter
+{
+ SoapServiceNode *service_head;
+ SoapServiceNode *service_tail;
+}SoapRouter;
+
+
+SoapRouter *soap_router_new();
+
+void soap_router_register_service(SoapRouter *router,
+ SoapServiceFunc func,
+ const char* method,
+ const char* urn);
+
+
+SoapService* soap_router_find_service(SoapRouter *router,
+ const char* urn,
+ const char* method);
+
+void soap_router_free(SoapRouter *router);
+
+#endif
diff --git a/libcsoap/soap-server.c b/libcsoap/soap-server.c
new file mode 100644
index 0000000..edde627
--- /dev/null
+++ b/libcsoap/soap-server.c
@@ -0,0 +1,268 @@
+/******************************************************************
+ * $Id: soap-server.c,v 1.1 2004/02/03 08:10:05 snowdrop 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
+ ******************************************************************/
+#include <libcsoap/soap-server.h>
+#include <nanohttp/nanohttp-server.h>
+
+
+
+typedef struct _SoapRouterNode
+{
+ char *context;
+ SoapRouter *router;
+ struct _SoapRouterNode *next;
+
+}SoapRouterNode;
+
+SoapRouterNode *head = NULL;
+SoapRouterNode *tail = NULL;
+
+static
+SoapRouterNode *router_node_new(SoapRouter *router,
+ const char *context,
+ SoapRouterNode *next);
+
+static
+SoapRouter *router_find(const char *context);
+
+/*---------------------------------*/
+void soap_server_entry(httpd_conn_t *conn, hrequest_t *req);
+static
+void _soap_server_send_env(hsocket_t sock, SoapEnv* env);
+static
+void _soap_server_send_fault(httpd_conn_t *conn, hpair_t *header,
+ const char* errmsg);
+/*---------------------------------*/
+
+
+int soap_server_init_args(int argc, char *argv[])
+{
+ return !httpd_init(argc, argv);
+}
+
+
+int soap_server_register_router(SoapRouter *router, const char* context)
+{
+
+ if (!httpd_register(context, soap_server_entry)) {
+ return 0;
+ }
+
+ if (tail == NULL) {
+ head = tail = router_node_new(router, context, NULL);
+ } else {
+ tail->next = router_node_new(router, context, NULL);
+ tail = tail->next;
+ }
+
+ return 1;
+}
+
+
+int soap_server_run()
+{
+ return httpd_run();
+}
+
+
+void soap_server_destroy()
+{
+ SoapRouterNode *node = head;
+ SoapRouterNode *tmp;
+
+ while (node != NULL) {
+ tmp = node->next;
+ soap_router_free(node->router);
+ free(node->context);
+ free(node);
+ node = tmp;
+ }
+}
+
+
+void soap_server_entry(httpd_conn_t *conn, hrequest_t *req)
+{
+ hpair_t *header;
+ char *postdata;
+ char buffer[1054];
+ char urn[150];
+ char method[150];
+ long received;
+ SoapEnv *env, *envres;
+ SoapRouter *router;
+ SoapService *service;
+
+ if (strcmp(req->method, "POST")) {
+
+ httpd_send_header(conn, 200, "OK", header);
+ hsocket_send(conn->sock, "<html><head></head><body>");
+ hsocket_send(conn->sock, "<h1>Sorry! </h1><hr>");
+ hsocket_send(conn->sock, "I only speak with 'POST' method");
+ hsocket_send(conn->sock, "</body></html>");
+ return;
+ }
+
+ postdata = httpd_get_postdata(conn, req, &received, -1);
+
+ header = hpairnode_new(HEADER_CONTENT_TYPE, "text/xml", NULL);
+
+
+ if (postdata == NULL) {
+
+ _soap_server_send_fault(conn, header,"Can not receive POST data!");
+
+ } else {
+
+ env = soap_env_new_from_buffer(postdata);
+
+ if (env == NULL) {
+
+ _soap_server_send_fault(conn, header,"Can not parse POST data!");
+
+ } else {
+
+ /*soap_xml_doc_print(env->root->doc);*/
+
+ router = router_find(req->path);
+
+ if ( router == NULL) {
+
+ _soap_server_send_fault(conn, header, "Can not find router!");
+
+ } else {
+
+ if (!soap_env_find_urn(env, urn)) {
+
+ _soap_server_send_fault(conn, header, "No URN found!");
+ return;
+ } else {
+ log_verbose2("urn: '%s'", urn);
+ }
+
+ if (!soap_env_find_methodname(env, method)) {
+
+ _soap_server_send_fault(conn, header, "No method found!");
+ 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, header, buffer);
+ return;
+ } else {
+
+ log_verbose2("func: %p", service->func);
+ envres = service->func(env);
+ log_verbose2("func returned: (%p)", envres);
+ if (envres == NULL) {
+
+ sprintf(buffer, "Service '%s' returned no envelope", urn);
+ _soap_server_send_fault(conn, header, buffer);
+ return;
+
+ } else {
+
+ httpd_send_header(conn, 200, "OK", header);
+ _soap_server_send_env(conn->sock, envres);
+ /* free envres */
+ }
+
+ }
+
+ }
+ }
+ }
+}
+
+
+static
+void _soap_server_send_env(hsocket_t sock, SoapEnv* env)
+{
+ xmlBufferPtr buffer;
+ if (env == NULL || env->root == NULL) return;
+
+ buffer = xmlBufferCreate();
+ xmlNodeDump(buffer, env->root->doc, env->root, 1 ,1);
+ hsocket_send(sock, (const char*)xmlBufferContent(buffer));
+ xmlBufferFree(buffer);
+
+}
+
+static
+void _soap_server_send_fault(httpd_conn_t *conn, hpair_t *header,
+ const char* errmsg)
+{
+ SoapEnv *envres;
+ httpd_send_header(conn, 500, "FAILED", header);
+ envres = soap_env_new_with_fault(Fault_Server,
+ errmsg?errmsg:"General error",
+ "cSOAP_Server", NULL);
+ _soap_server_send_env(conn->sock, envres);
+
+}
+
+
+
+static
+SoapRouterNode *router_node_new(SoapRouter *router,
+ const char *context,
+ SoapRouterNode *next)
+{
+ SoapRouterNode *node;
+ const char *noname = "/lost_find";
+
+ node = (SoapRouterNode*)malloc(sizeof(SoapRouterNode));
+ if (context) {
+ node->context = (char*)malloc(strlen(context)+1);
+ strcpy(node->context, context);
+ } else {
+ log_warn2("context is null. Using '%s'", noname);
+ node->context = (char*)malloc(strlen(noname)+1);
+ strcpy(node->context, noname);
+ }
+
+ node->router = router;
+ node->next = next;
+
+ return node;
+}
+
+
+static
+SoapRouter *router_find(const char* context)
+{
+ SoapRouterNode *node = head;
+
+ while (node != NULL) {
+ if (!strcmp(node->context, context))
+ return node->router;
+ node = node->next;
+ }
+
+ return NULL;
+}
diff --git a/libcsoap/soap-server.h b/libcsoap/soap-server.h
new file mode 100644
index 0000000..c3f29f3
--- /dev/null
+++ b/libcsoap/soap-server.h
@@ -0,0 +1,39 @@
+/******************************************************************
+ * $Id: soap-server.h,v 1.1 2004/02/03 08:10:05 snowdrop 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
+ ******************************************************************/
+#ifndef cSOAP_SERVER_H
+#define cSOAP_SERVER_H
+
+#include <libcsoap/soap-env.h>
+#include <libcsoap/soap-router.h>
+
+
+int soap_server_init_args(int argc, char *argv[]);
+int soap_server_register_router(SoapRouter *router, const char* context);
+int soap_server_run();
+void soap_server_destroy();
+
+
+#endif
+
+
diff --git a/libcsoap/soap-service.c b/libcsoap/soap-service.c
new file mode 100644
index 0000000..b30c101
--- /dev/null
+++ b/libcsoap/soap-service.c
@@ -0,0 +1,86 @@
+/******************************************************************
+ * $Id: soap-service.c,v 1.1 2004/02/03 08:10:05 snowdrop 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
+ ******************************************************************/
+#include <libcsoap/soap-service.h>
+#include <nanohttp/nanohttp-common.h>
+
+
+SoapServiceNode *soap_service_node_new(SoapService *service,
+ SoapServiceNode *next)
+{
+ SoapServiceNode *node ;
+
+ node = (SoapServiceNode*)malloc(sizeof(SoapServiceNode));
+ node->service = service;
+ node->next = next;
+
+ return node;
+}
+
+
+
+
+SoapService *soap_service_new(const char* urn,
+ const char *method,
+ SoapServiceFunc f)
+{
+ SoapService *service;
+
+
+ service = (SoapService*)malloc(sizeof(SoapService));
+ service->func = f;
+
+ if (urn != NULL) {
+ service->urn = (char*)malloc(strlen(urn)+1);
+ strcpy(service->urn, urn);
+ } else {
+ log_warn1("urn is NULL");
+ service->urn = "";
+ }
+
+ if (method != NULL) {
+ service->method = (char*)malloc(strlen(method)+1);
+ strcpy(service->method, method);
+ } else {
+ log_warn1("method is NULL");
+ service->method = "";
+ }
+
+ return service;
+}
+
+
+
+void soap_service_free(SoapService *service)
+{
+
+ if (service == NULL) return;
+
+ if (strcmp(service->urn, ""))
+ free(service->urn);
+
+ if (strcmp(service->method, ""))
+ free(service->method);
+
+ free(service);
+}
diff --git a/libcsoap/soap-service.h b/libcsoap/soap-service.h
new file mode 100644
index 0000000..d4bf035
--- /dev/null
+++ b/libcsoap/soap-service.h
@@ -0,0 +1,56 @@
+/******************************************************************
+ * $Id: soap-service.h,v 1.1 2004/02/03 08:10:05 snowdrop 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
+ ******************************************************************/
+#ifndef cSOAP_SERVICE_H
+#define cSOAP_SERVICE_H
+
+
+#include <libcsoap/soap-env.h>
+
+typedef SoapEnv* (*SoapServiceFunc)(SoapEnv*);
+
+
+typedef struct _SoapService
+{
+ char *urn;
+ char *method;
+ SoapServiceFunc func;
+}SoapService;
+
+
+typedef struct _SoapServiceNode
+{
+ SoapService *service;
+ struct _SoapServiceNode *next;
+}SoapServiceNode;
+
+SoapServiceNode *soap_service_node_new(SoapService *service,
+ SoapServiceNode *next);
+
+SoapService *soap_service_new(const char* urn, const char *method,
+ SoapServiceFunc f);
+void soap_service_free(SoapService *service);
+
+
+
+#endif