summaryrefslogtreecommitdiffstats
path: root/libcsoap/soap-server.c
diff options
context:
space:
mode:
authorGravatar m0gg2006-11-21 20:58:59 +0000
committerGravatar m0gg2006-11-21 20:58:59 +0000
commitc3fd98b25607d0f7f5977586d188f88ab226a9b8 (patch)
treecc4976a3be9d3984e4ae62c08afd1dcf9530dc5e /libcsoap/soap-server.c
parentcd94b25993049a596b163f0ad8b3a2340e024cc3 (diff)
downloadcsoap-c3fd98b25607d0f7f5977586d188f88ab226a9b8.tar.gz
csoap-c3fd98b25607d0f7f5977586d188f88ab226a9b8.tar.bz2
decoupling of nanohttp/libcsoap
Diffstat (limited to 'libcsoap/soap-server.c')
-rw-r--r--libcsoap/soap-server.c402
1 files changed, 93 insertions, 309 deletions
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;
}