diff options
author | snowdrop | 2004-02-03 08:10:05 +0000 |
---|---|---|
committer | snowdrop | 2004-02-03 08:10:05 +0000 |
commit | 8f709590c9c3262b7934af33378ca9230956df47 (patch) | |
tree | 0fd28c734de61ec778462012e436411f7e0e64b0 | |
parent | 65949d1c0eebfb52a1c860a2fc5acb2df7e8c299 (diff) | |
download | csoap-8f709590c9c3262b7934af33378ca9230956df47.tar.gz csoap-8f709590c9c3262b7934af33378ca9230956df47.tar.bz2 |
initial
-rw-r--r-- | libcsoap/soap-client.c | 106 | ||||
-rw-r--r-- | libcsoap/soap-client.h | 37 | ||||
-rw-r--r-- | libcsoap/soap-env.c | 386 | ||||
-rw-r--r-- | libcsoap/soap-env.h | 77 | ||||
-rw-r--r-- | libcsoap/soap-router.c | 101 | ||||
-rw-r--r-- | libcsoap/soap-router.h | 51 | ||||
-rw-r--r-- | libcsoap/soap-server.c | 268 | ||||
-rw-r--r-- | libcsoap/soap-server.h | 39 | ||||
-rw-r--r-- | libcsoap/soap-service.c | 86 | ||||
-rw-r--r-- | libcsoap/soap-service.h | 56 |
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 |