From 4fdb30f90c2d991a20335407f559cc0b0e946ddb Mon Sep 17 00:00:00 2001 From: snowdrop Date: Tue, 2 Nov 2004 22:18:50 +0000 Subject: develop --- doc/tutorial.xml | 611 +++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 408 insertions(+), 203 deletions(-) diff --git a/doc/tutorial.xml b/doc/tutorial.xml index 3db45bd..827bbb7 100755 --- a/doc/tutorial.xml +++ b/doc/tutorial.xml @@ -1,300 +1,504 @@ - +
- cSOAP Implementation Guide $Revision: 1.2 $ + cSOAP Implementation Guide $Revision: 1.3 $ FerhatAyaz 2004csoap +
- Introduction +Introduction - - This document gives you information about how to use the cSOAP API in your applications. - + + This document shows in short examples how to use cSOAP +for the client and server side implementation. + -
+ + cSOAP is a simple client/server SOAP library to implement standalone +and embedded SOAP applications. cSOAP was implemented in pure C to +support platforms as far as possible. + -
-Implementing a simple SOAP Client + + The underlying xml layer is libxml2 (http://xmlsoft.org). We used +this library because it is fast and still maintained. You can find also +some documentations about using libxml2. + - -A simple SOAP client + + The transport of SOAP messages will be established via HTTP. cSOAP +contains the subproject "nanohttp" which will do all the HTTP specific +stuff. It implements a simple HTTP client and a server which can also +be used outside the cSOAP project. + - +
- - - - - - - - - - +
+Nameconvention in cSOAP - -/* FILE: simpleclient.c */ -static const char *url = "http://csoap.sourceforge.net/cgi-bin/csoapserver"; -static const char *urn = "urn:examples"; -static const char *method = "sayHello"; + + cSOAP contains the following simple modules: + -int main(int argc, char *argv[]) -{ - SoapEnv *env, *res; + + + client : soap-client.h + + server : soap-server.h + + ctx : soap-ctx.h + + env : soap-env.h + + fault : soap-fault.h + + router : soap-router.h + + service : soap-service.h + - env = soap_env_new_with_method(urn, method); + + Each module declares the functions in the following name convention: + - soap_env_add_item(env, "xsd:string", - "name", "Jonny B. Good"); - res = soap_client_invoke(env, url , ""); +_(); +]]> - soap_xml_doc_print(res->root->doc); - - soap_env_free(res); - soap_env_free(env); - return 0; -} - + + For example: The function to invoke a SOAP call from the client side: + + + herror_t soap_client_invoke(....); + - +
- +
+Error handling - First we create a SOAP envelope (SoapEnv) using the - soap_env_new_with_method(). This creates the - following SOAP envelope. + Almost all function will return a "herror_t" object. If the function +returns with success this object is H_OK. Another herror_t object +will be returned otherwise. Following functions can be used with a +returned herror_t object: - -Generated SOAP envelope + + herror_code() : Returns the error code + herror_func() : Returns the function name, where the error occured + herror_message() : Returns the human readable error message + herror_release() : Frees the herror_t object. + + - - - - - - - - -]]> + herror_t err = soap_client_invoke(...); + if (err != H_OK) { + printf("Message: %s\n", herror_message(err)); + printf("Error code: %d\n", herror_code(err)); + printf("In function: %s\n", herror_func(err)); + herror_release(err); + } - - + + Note that you "must" call herror_release() to free the resources. + - + + The error codes are defined in "nanohttp-common.h". Here some examples: + -soap_env_add_item() will add a xml parameter to the envelope like follows + - -Added "name" parameter - - - - - - Jonny B. Good - - + - -]]> - - - - - Now we can send our soap call using soap_client_invoke(). The third argument -is the SoapAction header value. The result is also a SOAP envelope. -soap_client_invoke() will return always a SoapEnv object. It is -the result SOAP envelope or a fault object. +You can also create your own herror_t object with herror_new(). - - - - res->root is always the root xml element of the result SOAP envelope - and res->root->doc points always to the xmlDocPtr. - soap_xml_doc_print() is a helper function to print out a xml document. - - + +#define MY_ERROR_TEST 5001 - -Free both envelope objects - +herror_t err = herror_new("my_func()", + MY_ERROR_TEST, + "Size %d is greater then %d", 17, 13); + - + + User defined error codes must be greater then 5000. + - +
- +
+Implementing a simple client -
+ + One of the advantages of cSOAP is its simplicity. You can implement +a client or a server in a few minutes. The steps are always indentical. + + + +1. Initialize cSOAP client + soap_client_init_args() +2. Create a SoapCtx object + soap_ctx_new_with_method() -
-Implementing a simple SOAP Server +3. Fill the envelope + soap_env_add_item() + soap_env_add_itemf() + soap_env_add_attachment() + soap_env_add_custom() + soap_env_push_item() + soap_env_pop_item() + +4. Invoke + soap_client_invoke() + +5. Process returned SoapCtx object +6. Clean up cSOAP client + -A simple SOAP server + - - - - - - - - - - +static const char *url = "http://localhost:10000/csoapserver"; +static const char *urn = "urn:examples"; +static const char *method = "sayHello"; - -/* FILE: simpleserver.c */ int main(int argc, char *argv[]) { + SoapCtx *ctx, *ctx2; + herror_t err; + + /* 1. Initialize cSOAP client */ + soap_client_init_args(argc, argv); + + /* 2. Create a SoapCtx object */ + soap_ctx_new_with_method(urn, method, &ctx); - SoapRouter *router; + /* 3. Fill the envelope */ + soap_env_add_item(ctx->env, "xsd:string", "name", "Jonny B. Good"); - if (!soap_server_init_args(argc, argv)) { - return 0; + /* 4. Invoke */ + soap_client_invoke(ctx, &ctx2, url, ""); + if (err != H_OK) { + + log_error4("[%d] %s(): %s ", + herror_code(err), + herror_func(err), + herror_message(err)); + + herror_release(err); + soap_ctx_free(ctx); + return 1; } - - router = soap_router_new(); - soap_router_register_service(router, say_hello, "sayHello", "urn:examples"); - soap_server_register_router(router, "/csoapserver"); + /* 5. Process returned SoapCtx object */ + soap_xml_doc_print(ctx2->env->root->doc); - soap_server_run(); - soap_router_free(router); - soap_server_destroy(); + /* 6. Clean up cSOAP client */ + soap_ctx_free(ctx2); + soap_ctx_free(ctx); + + soap_client_destroy(); return 0; } +]]> + + + Important: Note that we have omitted error handling. The complete +code can be found under examples/csoap/simpleclient.c + + +
- +
+Implementing a simple server - -Init server with commandline arguments. The init argument at this time is only - -NHTTPport <portnum> . + Before you start to implement a SOAP server, you must understand +the architecture how you publish you web service . - - -Create a router - + + * Each URL represent a router service. + * Each router service contains one or more user services. + * Each user service is a C function with the following signature: + + typedef herror_t (*SoapServiceFunc)(SoapCtx*, SoapCtx*); + - - Register the service function say_hello under the methodname sayHello a - and urn urn:examples at the router object router. + The first SoapCtx object is the request, the second SoapCtx object +is the response, which must be filled by the service function +"SoapServiceFunc". The function must return H_OK if success. - - -Register the router under the context /csoapserver. -Now your service is avaiable at the address http://localhost:port/csoapserver. + +The steps to implement a SOAP server described below: + + +1. Init cSOAP server +2. Create and register a router +3. Register you service (C function) +4. Enter server loop +5. Clean up cSOAP server + + + + +The above steps can be shown in the the following example: + + + + +env, &res->env); + return H_OK; +} + + +int main(int argc, char *argv[]) +{ + + herror_t err; + SoapRouter *router; + + /* 1. Init cSOAP server */ + soap_server_init_args(argc, argv); + + /* 2. Create and register a router */ + router = soap_router_new(); + soap_server_register_router(router, url); + + /* 3. Register you service (C function) */ + soap_router_register_service(router, say_hello, method, urn); + + /* 4. Enter server loop */ + soap_server_run(); + + /* 5. Clean up cSOAP server */ + soap_server_destroy(); + + return 0; +} +]]> + + + + You can see how to implement a soap server easily! + + -Default http port is 10000 + Important: Note that we have omitted error handling. The complete +code can be found under examples/csoap/simpleserver.c - - +
+ +
+Implementing a simple client with attachment + - Enter the http server loop. after calling soap_server_run() , - the application will enter the http server (nanohttp) loop. + File are added to the context using soap_ctx_add_file(). + The following example is a little bit modified version of the above +simpleclient example. - - + + +env,"source", href); + + /* Send soap request to the server */ + soap_client_invoke(ctx, &ctx2, url, ""); + + /* Handle response (just print to the screen) */ + fault = soap_env_get_fault(ctx2->env); + if (fault) { + ... + } else { + ... + } + + /* Clean up */ + soap_ctx_free(ctx2); + soap_ctx_free(ctx); + + soap_client_destroy(); + + return 0; +} + +]]> + + - Free the router. +The difference between soap_ctx_add_file() and soap_env_add_attachment() +is, that soap_ctx_add_file() adds the file to the context. In our case, +this is a MIME message. soap_ctx_add_file() fills the "href" field with +a generated reference id. (Content-ID: [href]) This id can be used to +point to the added file from a SOAP message using soap_env_add_attachment(). - - - Destroy and free soap server stuff. +Here a simple example to understand. Look at the following MIME message: - - + + + + + +]]> + + +
-Compiling SOAP applications +Implementing a simple server with attachment + - csoap has pkg-config support. So you can can use -pkg-config with libcsoap parameter. + Attachments are represented as an "attachments_t" object. An +"attachments_t" object is a list of parts. A part is the physical file +on the filesystem. - -An example Makefile + +typedef struct _attachments +{ + part_t *parts; + part_t *last; + part_t *root_part; +}attachments_t; + - - + You don't have to care about this object becaus it is a part of +SoapCtx. + -simpleserver: $(SERVEROBJECTS) - $(CC) -o $@ $< $(LDFLAGS) + +typedef struct _SoapCtx +{ + SoapEnv *env; + attachments_t *attachments; +}SoapCtx; + -]]> - + +The following example shows how to use attachment in a service function +(C function). + + + + +env, &res->env); + if (err != H_OK) { + return err; + } + + if (req->attachments) + { + for (part = req->attachments->parts; part != NULL; part = part->next) + { + soap_ctx_add_file(res, part->filename, part->content_type, href); + soap_env_add_attachment(res->env, "echoFile", href); + } + } + + return H_OK; +} +]]>
-
-Building XML tree using libxml2 API +Building an envelope using the libxml2 API -One of the ways building a xml tree into an -SOAP envelope is to use directly the libxml2 API. -You can obtain the xmlNodePtr of an envelope -with the SoapEnv structure. +One of the ways building a xml tree into an SOAP envelope is to use +directly the libxml2 API. You can obtain the xmlNodePtr of an envelope +using the SoapEnv structure. @@ -306,13 +510,13 @@ typedef struct _SoapEnv -Here is "root" your xml node to <SOAP-ENV:Envelope>. +Here is "root" your xml node to ]]>.
-Building XML tree using csoap +Building an envelope using envelope functions You can build a xml tree using following functions @@ -322,26 +526,32 @@ You can build a xml tree using following functions 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); -soap_env_add_itemf() does the same thing like soap_env_add_item() +soap_env_add_itemf() does the same thing like soap_env_add_item() but with a C style argument list. (Max buffer for value is 1054) + +The next example shows, how to use the stack pattern of cSOAP. + + -Building xml using csoap stack pattern - -env; soap_env_push_item(env, "my:user", "User"); soap_env_add_item(env, "xsd:string", "id", "09189"); @@ -352,19 +562,18 @@ soap_env_push_item(env, "my:user", "User"); soap_env_add_item(env, "xsd:string", "name", "snowdrop"); soap_env_add_item(env, "xsd:string", "passwd", "passphrase64"); soap_env_pop_item(env); -]]> - + +]]> + This will create the following xml structure - -Generated SOAP envelope - - + -]]> - - +]]> -
-
-- cgit v1.1-32-gdbae