From c3fd98b25607d0f7f5977586d188f88ab226a9b8 Mon Sep 17 00:00:00 2001 From: m0gg Date: Tue, 21 Nov 2006 20:58:59 +0000 Subject: decoupling of nanohttp/libcsoap --- libcsoap/soap-server.c | 402 ++++++++++++------------------------------------- 1 file changed, 93 insertions(+), 309 deletions(-) (limited to 'libcsoap/soap-server.c') 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 +#include + #include #include #include #include -#include #include #include -#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, - "" - "" - "" - "

Error


" - "Error while sending fault object:" - "
Message: "); - http_output_stream_write_string(conn->out, herror_message(err)); - http_output_stream_write_string(conn->out, "
Function: "); - http_output_stream_write_string(conn->out, herror_func(err)); - http_output_stream_write_string(conn->out, "
Error code: "); - sprintf(buffer, "%d", herror_code(err)); - http_output_stream_write_string(conn->out, buffer); - http_output_stream_write_string(conn->out, ""); - - 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, - "" - "" - "" - "" - "

Sorry!

" - "
" - "
I only speak with 'POST' method.
" - "" - ""); - 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; } -- cgit v1.1-32-gdbae