From d45b4bc26f330d2ce29e4a06ffdae74d82e8b43b Mon Sep 17 00:00:00 2001 From: snowdrop Date: Sat, 18 Feb 2006 20:14:35 +0000 Subject: added basic authentication and SOAP-Header capabilities for request objects Thanks to Heiko Ronsdorf --- libcsoap/soap-client.c | 4 +- libcsoap/soap-ctx.c | 9 +- libcsoap/soap-ctx.h | 8 +- libcsoap/soap-env.h | 5 +- libcsoap/soap-router.c | 34 ++++- libcsoap/soap-router.h | 8 +- libcsoap/soap-server.c | 361 ++++++++++++++++++++++++------------------------- 7 files changed, 226 insertions(+), 203 deletions(-) (limited to 'libcsoap') diff --git a/libcsoap/soap-client.c b/libcsoap/soap-client.c index 55fa6ca..f30018d 100644 --- a/libcsoap/soap-client.c +++ b/libcsoap/soap-client.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: soap-client.c,v 1.22 2006/02/08 11:13:14 snowdrop Exp $ +* $Id: soap-client.c,v 1.23 2006/02/18 20:14:36 snowdrop Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -95,7 +95,7 @@ soap_client_invoke(SoapCtx * call, SoapCtx ** response, const char *url, return herror_new("soap_client_invoke", SOAP_ERROR_CLIENT_INIT, "Unable to create SOAP client!"); } - conn->block = soap_client_get_blockmode(); + conn->sock.block = soap_client_get_blockmode(); /* Set soap action */ if (soap_action != NULL) diff --git a/libcsoap/soap-ctx.c b/libcsoap/soap-ctx.c index 7edefc3..dd68861 100755 --- a/libcsoap/soap-ctx.c +++ b/libcsoap/soap-ctx.c @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: soap-ctx.c,v 1.7 2006/01/10 11:29:04 snowdrop Exp $ + * $Id: soap-ctx.c,v 1.8 2006/02/18 20:14:36 snowdrop Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003-2004 Ferhat Ayaz @@ -21,16 +21,17 @@ * * Email: ferhatayaz@jprogrammer.net ******************************************************************/ -#include - #include +#include + SoapCtx * soap_ctx_new(SoapEnv * env) /* should only be used internally */ { SoapCtx *ctx = (SoapCtx *) malloc(sizeof(SoapCtx)); ctx->env = env; ctx->attachments = NULL; + ctx->action = NULL; return ctx; } @@ -133,6 +134,8 @@ soap_ctx_free(SoapCtx * ctx) attachments_free(ctx->attachments); if (ctx->env) soap_env_free(ctx->env); + if (ctx->action) + free(ctx->action); free(ctx); } diff --git a/libcsoap/soap-ctx.h b/libcsoap/soap-ctx.h index 1baabba..a4784f5 100755 --- a/libcsoap/soap-ctx.h +++ b/libcsoap/soap-ctx.h @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: soap-ctx.h,v 1.7 2006/01/10 11:29:04 snowdrop Exp $ + * $Id: soap-ctx.h,v 1.8 2006/02/18 20:14:36 snowdrop Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003-2004 Ferhat Ayaz @@ -24,10 +24,10 @@ #ifndef cSOAP_CTX_H #define cSOAP_CTX_H - -#include #include +#include +#include #define SOAP_ERROR_NO_FILE_ATTACHED 4001 #define SOAP_ERROR_EMPTY_ATTACHMENT 4002 @@ -37,6 +37,8 @@ typedef struct _SoapCtx { SoapEnv *env; + char *action; + hrequest_t *http; attachments_t *attachments; } SoapCtx; diff --git a/libcsoap/soap-env.h b/libcsoap/soap-env.h index 36305e1..ee53f3a 100644 --- a/libcsoap/soap-env.h +++ b/libcsoap/soap-env.h @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: soap-env.h,v 1.12 2006/01/27 20:23:40 mrcsys Exp $ + * $Id: soap-env.h,v 1.13 2006/02/18 20:14:36 snowdrop Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -24,9 +24,10 @@ #ifndef cSOAP_ENV_H #define cSOAP_ENV_H +#include + #include #include -#include /** diff --git a/libcsoap/soap-router.c b/libcsoap/soap-router.c index 1e57850..fc26916 100644 --- a/libcsoap/soap-router.c +++ b/libcsoap/soap-router.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: soap-router.c,v 1.5 2006/01/10 11:29:04 snowdrop Exp $ +* $Id: soap-router.c,v 1.6 2006/02/18 20:14:36 snowdrop Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -21,22 +21,23 @@ * * Email: ayaz@jprogrammer.net ******************************************************************/ -#include #include +#include + SoapRouter * -soap_router_new() +soap_router_new(void) { SoapRouter *router; router = (SoapRouter *) malloc(sizeof(SoapRouter)); router->service_head = NULL; router->service_tail = NULL; + router->default_service = NULL; return router; } - void soap_router_register_service(SoapRouter * router, SoapServiceFunc func, @@ -56,8 +57,31 @@ soap_router_register_service(SoapRouter * router, router->service_tail->next = soap_service_node_new(service, NULL); router->service_tail = router->service_tail->next; } + + return; } +void +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 (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; + } + + router->default_service = service; + + return; +} SoapService * soap_router_find_service(SoapRouter * router, @@ -84,7 +108,7 @@ soap_router_find_service(SoapRouter * router, node = node->next; } - return NULL; + return router->default_service; } diff --git a/libcsoap/soap-router.h b/libcsoap/soap-router.h index 5b0c7ab..2a37117 100644 --- a/libcsoap/soap-router.h +++ b/libcsoap/soap-router.h @@ -1,5 +1,5 @@ /****************************************************************** - * $Id: soap-router.h,v 1.4 2006/01/10 11:29:04 snowdrop Exp $ + * $Id: soap-router.h,v 1.5 2006/02/18 20:14:36 snowdrop Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -24,7 +24,6 @@ #ifndef cSOAP_ROUTER_H #define cSOAP_ROUTER_H - #include /** @@ -35,6 +34,7 @@ typedef struct _SoapRouter { SoapServiceNode *service_head; SoapServiceNode *service_tail; + SoapService *default_service; } SoapRouter; @@ -47,7 +47,7 @@ typedef struct _SoapRouter @returns Soap router @see soap_router_free */ -SoapRouter *soap_router_new(); +SoapRouter *soap_router_new(void); /** @@ -64,6 +64,8 @@ void 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); + /** Searches for a registered soap service. diff --git a/libcsoap/soap-server.c b/libcsoap/soap-server.c index af1d808..68d6f16 100644 --- a/libcsoap/soap-server.c +++ b/libcsoap/soap-server.c @@ -1,5 +1,5 @@ /****************************************************************** -* $Id: soap-server.c,v 1.16 2006/02/08 11:13:14 snowdrop Exp $ +* $Id: soap-server.c,v 1.17 2006/02/18 20:14:36 snowdrop Exp $ * * CSOAP Project: A SOAP client/server library in C * Copyright (C) 2003 Ferhat Ayaz @@ -21,10 +21,11 @@ * * Email: ayaz@jprogrammer.net ******************************************************************/ -#include -#include #include +#include + +#include typedef struct _SoapRouterNode { @@ -34,22 +35,139 @@ typedef struct _SoapRouterNode } SoapRouterNode; -SoapRouterNode *head = NULL; -SoapRouterNode *tail = NULL; +static SoapRouterNode *head = NULL; +static SoapRouterNode *tail = NULL; + +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); + +} + +static void +_soap_server_send_fault(httpd_conn_t * conn, hpair_t * header, + const char *errmsg) +{ + SoapEnv *envres; + herror_t err; + char buffer[45]; + + 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, ""); + http_output_stream_write_string(conn->out, "

Error


"); + http_output_stream_write_string(conn->out, + "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); + return; + } + else + { + _soap_server_send_env(conn->out, envres); + } + return; +} + +static void +_soap_server_send_ctx(httpd_conn_t * conn, SoapCtx * ctx) +{ + xmlBufferPtr buffer; + static int counter = 1; + char strbuffer[150]; + part_t *part; + + if (ctx->env == NULL || ctx->env->root == NULL) + return; + + buffer = xmlBufferCreate(); +/* xmlIndentTreeOutput = 1;*/ + xmlThrDefIndentTreeOutput(1); +/* xmlKeepBlanksDefault(0);*/ + 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); +#ifdef WIN32 +#define snprintf(buffer, num, s1, s2) sprintf(buffer, s1,s2) +#endif + snprintf(buflen, 100, "%d", + strlen((const char *) xmlBufferContent(buffer))); + httpd_set_header(conn, HEADER_CONTENT_LENGTH, buflen); + 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); -/*---------------------------------*/ -static void _soap_server_send_ctx(httpd_conn_t * conn, SoapCtx * ctxres); + } + xmlBufferFree(buffer); -void soap_server_entry(httpd_conn_t * conn, hrequest_t * req); -static void _soap_server_send_env(http_output_stream_t * out, SoapEnv * env); -static - void _soap_server_send_fault(httpd_conn_t * conn, hpair_t * header, - const char *errmsg); -/*---------------------------------*/ +} static SoapRouterNode * -router_node_new(SoapRouter * router, - const char *context, SoapRouterNode * next) +router_node_new(SoapRouter * router, const char *context, SoapRouterNode * next) { SoapRouterNode *node; const char *noname = "/lost_found"; @@ -88,68 +206,7 @@ router_find(const char *context) return NULL; } -herror_t -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; -} - - -herror_t -soap_server_run() -{ - return httpd_run(); -} - -int -soap_server_get_port(void) -{ - return httpd_get_port(); -} - -void -soap_server_destroy() -{ - SoapRouterNode *node = head; - SoapRouterNode *tmp; - - while (node != NULL) - { - tmp = node->next; - log_verbose2("soap_router_free(%p)", node->router); - soap_router_free(node->router); - free(node->context); - free(node); - node = tmp; - } - httpd_destroy(); -} - - -void +static void soap_server_entry(httpd_conn_t * conn, hrequest_t * req) { hpair_t *header = NULL; @@ -167,7 +224,7 @@ soap_server_entry(httpd_conn_t * conn, hrequest_t * req) httpd_send_header(conn, 200, "OK"); http_output_stream_write_string(conn->out, ""); - http_output_stream_write_string(conn->out, "

Sorry!


"); + http_output_stream_write_string(conn->out, "

Sorry!


"); http_output_stream_write_string(conn->out, "I only speak with 'POST' method"); http_output_stream_write_string(conn->out, ""); @@ -196,6 +253,8 @@ soap_server_entry(httpd_conn_t * conn, hrequest_t * req) { ctx = soap_ctx_new(env); + ctx->action = hpairnode_get_ignore_case(req->header, "SoapAction"); + ctx->http = req; soap_ctx_add_files(ctx, req->attachments); if (ctx->env == NULL) @@ -285,8 +344,8 @@ soap_server_entry(httpd_conn_t * conn, hrequest_t * req) else { -/* httpd_send_header(conn, 200, "OK"); - _soap_server_send_env(conn->out, ctxres->env); +/* httpd_send_header(conn, 200, "OK"); + _soap_server_send_env(conn->out, ctxres->env); */ _soap_server_send_ctx(conn, ctxres); /* free envctx */ @@ -301,131 +360,63 @@ soap_server_entry(httpd_conn_t * conn, hrequest_t * req) } } - -static void -_soap_server_send_ctx(httpd_conn_t * conn, SoapCtx * ctx) +herror_t +soap_server_init_args(int argc, char *argv[]) { - xmlBufferPtr buffer; - static int counter = 1; - char strbuffer[150]; - part_t *part; + return httpd_init(argc, argv); +} - if (ctx->env == NULL || ctx->env->root == NULL) - return; +int +soap_server_register_router(SoapRouter * router, const char *context) +{ - buffer = xmlBufferCreate(); -/* xmlIndentTreeOutput = 1;*/ - xmlThrDefIndentTreeOutput(1); -/* xmlKeepBlanksDefault(0);*/ - xmlNodeDump(buffer, ctx->env->root->doc, ctx->env->root, 1, 1); + if (!httpd_register(context, soap_server_entry)) + { + return 0; + } - if (ctx->attachments) + if (tail == NULL) { - 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); + head = tail = router_node_new(router, context, NULL); } else { - char buflen[100]; - xmlXPathContextPtr xpathCtx; - xmlXPathObjectPtr xpathObj; - xpathCtx = xmlXPathNewContext(ctx->env->root->doc); - xpathObj = xmlXPathEvalExpression("//Fault", xpathCtx); -#ifdef WIN32 -#define snprintf(buffer, num, s1, s2) sprintf(buffer, s1,s2) -#endif - snprintf(buflen, 100, "%d", - strlen((const char *) xmlBufferContent(buffer))); - httpd_set_header(conn, HEADER_CONTENT_LENGTH, buflen); - 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); - + tail->next = router_node_new(router, context, NULL); + tail = tail->next; } - xmlBufferFree(buffer); + return 1; } -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); +herror_t +soap_server_run() +{ + return httpd_run(); } -static void -_soap_server_send_fault(httpd_conn_t * conn, hpair_t * header, - const char *errmsg) +int +soap_server_get_port(void) { - SoapEnv *envres; - herror_t err; - char buffer[45]; - httpd_set_headers(conn, header); - err = httpd_send_header(conn, 500, "FAILED"); - if (err != H_OK) - { - /* WARNING: unhandled exception ! */ - log_error4("%s():%s [%d]", herror_func(err), herror_message(err), - herror_code(err)); - return; - } + return httpd_get_port(); +} - 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, ""); - http_output_stream_write_string(conn->out, "

Error


"); - http_output_stream_write_string(conn->out, - "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, ""); - return; +void +soap_server_destroy() +{ + SoapRouterNode *node = head; + SoapRouterNode *tmp; - herror_release(err); - } - else + while (node != NULL) { - _soap_server_send_env(conn->out, envres); + tmp = node->next; + log_verbose2("soap_router_free(%p)", node->router); + soap_router_free(node->router); + free(node->context); + free(node); + node = tmp; } - + httpd_destroy(); } - -- cgit v1.1-32-gdbae