1 gSOAP user guide {#mainpage}
6 # Introduction {#intro}
8 The gSOAP tools provide an automated SOAP and XML data binding for C and C++
9 based on compiler technologies. The tools simplify the development of SOAP/XML
10 Web services and XML application in C and C++ using autocode generation and
11 advanced mapping methods. Most toolkits for Web services adopt a
12 WSDL/SOAP-centric view and offer APIs that require the use of class libraries
13 for XML-specific data structures. This forces a user to adapt the application
14 logic to these libraries because users have to write code to populate XML and
15 extract data from XML using a vendor-specific API. This often leads to fragile
16 solutions with little or no assurances for data consistency, type safety, and
17 XML validation. By contrast, gSOAP provides a type-safe and transparent
18 solution through the use of compiler technology that hides irrelevant WSDL-,
19 SOAP-, REST-, and XML-specific protocol details from the user, while
20 automatically ensuring XML validity checking, memory management, and type-safe
21 serialization. The gSOAP tools automatically map native and user-defined C and
22 C++ data types to semantically equivalent XML data types and vice-versa. As a
23 result, full SOAP/REST XML interoperability is achieved with a simple API
24 relieving the user from the burden of WSDL/SOAP/XML details, thus enabling him
25 or her to concentrate on the application-essential logic.
27 The gSOAP tools support the integration of (legacy) C/C++ codes (and other
28 programming languages when a C interface is available), embedded systems, and
29 real-time software in SOAP/XML applications that share computational resources
30 and information with other SOAP applications, possibly across different
31 platforms, language environments, and disparate organizations located behind
34 The gSOAP tools are also popular to implement XML data binding in C and C++.
35 This means that application-native data structures can be encoded in XML
36 automatically, without the need to write conversion code. The tools also
37 produce XML schemas for the XML data binding, so external applications can
38 consume the XML data based on the schemas.
40 🔝 [Back to table of contents](#)
42 # Getting Started {#start}
44 To start building Web services applications or automate XML data bindings with
47 * The gSOAP software from <https://www.genivia.com/Products/downloads.html> and
48 select the gSOAP toolkit commercial edition, or download the GPL open source
49 version from SourceForge <https://sourceforge.net/projects/gsoap2>.
51 * A C or C++ compiler.
53 * You may want to install OpenSSL and the Zlib libraries to enable SSL (HTTPS)
54 and compression. These libraries are available for most platforms and are
55 often already installed.
57 The gSOAP software is self-contained, so there is no need to download any
58 third-party software, except when you want to use OpenSSL for HTTPS and/or Zlib
61 The gSOAP distribution package includes:
63 * The `wsdl2h` WSDL/schema converter and data binding tool.
65 * The `soapcpp2` stub/skeleton compiler and code generator.
67 Binaries of these two tools are included in the gSOAP package in `gsoap/bin`
68 for Windows and Mac OS plarforms, see also the README files in the package for
71 Although gSOAP tools are available in binary format for several platforms, the
72 code generated by these tools are all equivalent. This means that the generated
73 source codes can be transferred to other platforms and locally compiled.
75 If you don't have the binaries or if you want to rebuild them, you need
77 * Bison (or Yacc) to build `soapcpp2`.
79 * Flex (or Lex) to build `soapcpp2`.
81 * A C++ compiler to build `wsdl2h`.
83 Bison and Flex are preferred. Both are released under open source licenses that
84 are compatible with gSOAP's licenses:
86 * Bison is available from <http://www.gnu.org/software/bison>
88 * Flex is available from <http://flex.sourceforge.net>
90 You can also build `soapcpp2` without Bison and Flex installed, see
91 installation instructions on the gSOAP web site.
93 The gSOAP engine is built as a library `libgsoap.a` and `libgsoap++.a` with
94 separate versions of these two `libgsoapssl.a` and `libgsoapssl++.a` that
95 support SSL. See the `README.txt` instructions on how to build these libraries
96 with the platform-independent gSOAP package's autoconf and automake.
97 Alternatively, you can compile and link the engine's source code `stdsoap2.c`
98 (or `stdsoap2.cpp` for C++) directly with your code.
100 The gSOAP packages contain numerous examples in the `samples` directory. Run
101 `make` to build the example applications. The examples are also meant to
102 demonstrate different features of gSOAP. A streaming MTOM attachment server
103 and client application demonstrate efficient file exchanges in
104 `samples/mtom-stream`. An SSL-secure Web server application demonstrates the
105 generation of dynamic content for Web browsing and Web services functionality
106 at the same time, see `samples/webservice`. And much more.
108 ## Creating a client app {#start-client}
110 The gSOAP tools minimize application adaptation efforts for building Web
111 Services by using a XML data binding for C and C++ implemented by advanced XML
112 schema analyzers and source-to-source code generation tools. The gSOAP
113 `wsdl2h` tool imports one or more WSDLs and XML schemas and generates a gSOAP
114 header file with familiar C/C++ syntax to define the Web service operations and
115 the C/C++ data types. The gSOAP `soapcpp2` compiler then takes this header file
116 and generates XML serializers for the data types (`soapH.h` and `soapC.cpp`),
117 the client-side stubs (`soapClient.cpp`), and server-side skeletons
120 The gSOAP `soapcpp2` compiler can also generate WSDL definitions for
121 implementing a service from scratch, i.e. without defining a WSDL first. This
122 "closes the loop" in that it enables Web services development from WSDL or
123 directly from a set op C/C++ operations in a header file without the need for
124 users to analyze Web service details.
126 You only need to follow a few steps to execute the tools from the command line
127 or Makefile (see also MSVC++ project examples in the `samples` directory
128 with tool integration in the MSVC++ IDE). For example, to generate code for the
129 calculator Web service, we run the `wsdl2h` tool from the
130 command line on the URL of the WSDL and use option `-o` to specify the
133 > wsdl2h -o calc.h http://www.genivia.com/calc.wsdl
135 This generates the `calc.h` service definition header file with service
136 operation definitions and types for the operation's data. This header file is
137 then to be processed with `soapcpp2` to generate the stub and/or skeleton code
138 and XML serialization routines. The `calc.h` file includes all documentation,
139 so you can use Doxygen (<http://www.doxygen.org>) to automatically generate the
140 documentation pages for your development.
142 The `wsdl2h`-generated service definitions header file also contains information on the use of the service, such as WS-Policy assertions when applicable.
144 In this example we are developing a C++ API for the calculator service. By
145 default, gSOAP assumes you will use C++ with STL. To build without STL, use option
148 > wsdl2h -s -o calc.h http://www.genivia.com/calc.wsdl
150 To build a pure C application, use option `-c`:
152 > wsdl2h -c -o calc.h http://www.genivia.com/calc.wsdl
154 @note Visual Studio users shopuld make sure to compile all gSOAP
155 source files in C++ compilation mode. If you migrate to a project file
156 `.vcproj`, please set *`CompileAs="2"`* in your `.vcproj` file.
158 We have not yet generated the stubs for the C/C++ API. To do so, run the `soapcpp2` compiler:
160 > soapcpp2 -i -C -Iimport calc.h
162 Option `-i` (and alternatively option `-j`) indicates that we want C++ proxy and server objects that
163 include the client (and server) code, `-C` indicates client-side only files
164 (`soapcpp2` generates both client and server stubs and skeletons by
165 default). Option `-I` is needed to import the `stlvector.h` file from the `import` directory in the gSOAP package to support serialization of STL vectors.
167 Suppose we develop a C++ client for the calculator service using `wsdl2h -o calc.h http://www.genivia.com/calc.wsdl` and `soapcpp2 -i -C calc.h`.
169 We use the generated `soapcalcProxy` class and
170 `calc.nsmap` XML namespace mapping table to access the Web
171 service. The `soapcalcProxy` class is a proxy to invoke the
175 #include "soapcalcProxy.h"
176 #include "calc.nsmap"
181 if (service.add(1.0, 2.0, result) == SOAP_OK)
182 std::cout << "The sum of 1.0 and 2.0 is " << result << std::endl;
184 service.soap_stream_fault(std::cerr);
185 service.destroy(); // delete data and release memory
189 To complete the build, compile the code above and compile and link this with the generated `soapC.cpp`,
190 `soapcalcProxy.cpp`, and the run-time gSOAP engine `-lgsoap++` (or use source `stdsoap2.cpp` in case `libgsoap++.a` is not installed) with your code.
192 Suppose we develop a client in C using `wsdl2h -c -o calc.h http://www.genivia.com/calc.wsdl` and `soapcpp2 -C calc.h`. In this case our code uses a simple C function call to invoke the service and we also need to explicitly delete data and the context with `soap_end` and `soap_free`:
196 #include "calc.nsmap"
199 struct soap *soap = soap_new();
201 if (soap_call_ns__add(soap, 1.0, 2.0, &result) == SOAP_OK)
202 printf("The sum of 1.0 and 2.0 is %lg\n", result);
204 soap_print_fault(soap, stderr);
210 The calculator example is fairly simple and used here to illustrate the
211 development process. The development process for large-scale XML applications
212 is similar. More extensive examples can be found in the `samples` directory
213 in the gSOAP package.
215 ## Creating a service app {#start-service}
217 Developing a service application is easy too. We will use CGI here because it
218 is a simple mechanism. This is not the preferred deployment mechanism. Because
219 CGI is slow and stateless. Faster services can be developed as a stand-alone
220 gSOAP HTTP/HTTPS server (but see comments at the end of this section) or, as
221 preferred, the use of Apache module or IIS with the mod_gsoap ISAPI extension (included in the gSOAP package under
222 `gsoap/mod_gsoap` with instructions).
224 Suppose we implement a CGI-based service that returns the time in GMT. The
225 Common Gateway Interface (CGI) is a simple mechanism to publish services on
228 For this example we start with a gSOAP header file, `currentTime.h` which contains the service definitions. Such a file can be obtained from a WSDL using `wsdl2h` when a WSDL is available. When a WSDL is not available, you can define the service in C/C++ definitions in a newly created header file and let the gSOAP tools generate the source code and WSDL for you.
230 Our `currentTime` service only has an output parameter, which is the
231 current time defined in our `currentTime.h` gSOAP service specification:
234 // File: currentTime.h
235 //gsoap ns service name: currentTime
236 //gsoap ns service namespace: urn:currentTime
237 //gsoap ns service location: http://www.yourdomain.com/currentTime.cgi
238 int ns__currentTime(time_t& response);
241 Note that we associate an XML namespace prefix `ns` and namespace name `urn:currentTime` with the service WSDL and SOAP/XML messages. The gSOAP tools
242 use a special convention for identifier names that are part of a namespace: a
243 namespace prefix (`ns` in this case) followed by a double underscore
244 `__`. This convention is used to resolve namespaces and to avoid name
245 clashes. The `ns` namespace prefix is bound to the `urn:currentTime`
246 namespace name with the `//gsoap` directive. The `//gsoap` directives
247 are used to set the properties of the service, in this case the name,
248 namespace, and location endpoint.
250 The service implementation for CGI requires a `soap_serve` call on a soap context created with `soap_new`. The service operations are implemented as functions, which are called by the RPC dispatcher `soap_serve`:
253 // File: currentTime.cpp
254 #include "soapH.h" // include the generated declarations
255 #include "currentTime.nsmap" // include the XML namespace mappings
258 // create soap context and serve one CGI-based request:
259 return soap_serve(soap_new());
262 int ns__currentTime(struct soap *soap, time_t& response)
269 Note that we pass the soap struct with the gSOAP context information to the
270 service routine. This can come in handy to determine properties of the connection
271 and to dynamically allocate data with `soap_malloc(soap, num_bytes)` that
272 will be automatically deleted when the service is finished.
274 We run the `soapcpp2` compiler on the header file to generate the
277 > soapcpp2 -S currentTime.h
279 and then compile the CGI binary:
281 > c++ -o currentTime.cgi currentTime.cpp soapC.cpp soapServer.cpp stdsoap2.cpp
283 You will find `stdsoap2.cpp` in the `gsoap` dir. Or after installation
284 you can link with `libgsoap++` instead of using the `stdsoap2.cpp`
287 > c++ -o currentTime.cgi currentTime.cpp soapC.cpp soapServer.cpp -lgsoap++
289 To activate the service, copy the `currentTime.cgi` binary to your
290 `bin-cgi` directory using the proper file permissions.
292 The `soapcpp2` tool generated the WSDL definitions
293 `currentTime.wsdl`. You can use the WSDL to advertize your service.
294 You don't need to use this WSDL to develop a gSOAP client. You can use the
295 `currentTime.h` file with `soapcpp2` option ` -C` to generate
298 A convenient aspect of CGI is that it exchanges messages over standard
299 input/output. Therefore, you can run the CGI binary on the auto-generated
300 example request XML file to test your server:
302 > ./currentTime.cgi < currentTime.currentTime.req.xml
304 and this displays the server response in SOAP XML.
306 The above approach works also for C. Just use `soapcpp2` option `-c` in
307 addition to the `-S` option to generate ANSI C code. Of course, in C we use
308 pointers instead of references and the `currentTime.h` file should be
309 adjusted to use C-only types.
311 A more elegant server implementation in C++ can be obtained by using the
312 `soapcpp2` option `-i` (or `-j`) to generate C++ client-side proxy and
313 server-side service objects as classes that you can use to build clients and
314 services in C++. The option removes the generation of `soapClient.cpp` and
315 `soapServer.cpp`, since these are no longer needed when we have classes
316 that implement the client and server logic:
318 > soapcpp2 -i -S currentTime.h
320 This generates `soapcurrentTimeService.h` and
321 `soapcurrentTimeService.cpp` files, as well as auxiliary files
322 `soapStub.h` (included by default by all codes) and `currentTime.nsmap`.
324 Using the `currentTimeService` object we rewrite the CGI server as:
327 // File: currentTime.cpp
328 #include "soapcurrentTimeService.h" // include the proxy declarations
329 #include "currentTime.nsmap" // include the XML namespace mappings
332 // create server and serve one CGI-based request:
333 currentTimeService server;
338 int currentTimeService::currentTime(time_t& response)
347 > c++ -o currentTime.cgi currentTime.cpp soapC.cpp soapcurrentTimeService.cpp -lgsoap++
349 and install the binary as CGI. To install the CGI binary please consult your
350 Web server documentation on how to deploy CGI applications.
352 To run the server as a stand-alone iterative (non-multithreaded) server on port 8080:
354 while (server.run(8080) != SOAP_TCP_ERROR)
355 server.soap_stream_fault(std::cerr);
358 To implement threaded services, please see Section \ref mt . These
359 stand-alone Web Services that handle multiple SOAP requests by spawning a
360 thread for each request. Thread pooling is also an option. The use of Apache
361 and IIS modules to deploy gSOAP services is preferred to ensure load balancing, access control, tracing, and so on.
363 For more information on server-side service classes, see
364 Section \ref object . For more information on client-side proxy classes,
365 see Section \ref proxy .
367 # XML data bindings {#databindings}
369 Or in other words, how to map schemas (XSD files) to C/C++ bindings for
370 automatically reading and writing XML data.
372 The XML C/C++ data binding in gSOAP provides and automated mechanism to encode
373 any C and C++ data type in XML (and decode XML back to C/C++ data). An XML
374 schema (XSD file) can be transformed into a set of C or C++ definitions
375 that can be readily incorporated into your application to manipulate XML with
376 much more ease than DOM or SAX. Essentially, each XML component definition in
377 an XML schema has a C/C++ data type representation that has equivalent type
378 properties. The advantage of this approach is immediately apparent when we look
379 at an XSD complexType that maps to a class as shown:
383 <complexType name="Address"> class ns__Address {
385 <element name="name" type="string"/> std::string name;
386 <element name="home" type="tns:Location" minOccurs="0"/> ns__Location *home;
387 <element name="phone" type="unsignedLong"/> ULONG64 phone;
388 <element name="dob" type="dateTime"/> time_t dob;
390 <attribute name="ID" type="int" use="required"/> @ int ID;
395 In this way, an automatic mapping
396 between XML elements of the XML schema and members of a class is created.
397 No DOM traversals and SAX events are needed.
398 In addition, the XML C/C++ data binding makes XML manipulation type safe. That
399 is, the type safety of C/C++ ensures that only valid XML documents can be
400 parsed and generated.
402 The `wsdl2h` tool performs the mapping of WSDL and XML schemas to C and/or C++ automatically. The output of `wsdl2h` is an annotated header file that includes comments and documentation on the use of the C/C++ declarations in a SOAP/XML client/server or in a generic application for reading and writing XML using the auto-generated serializers.
404 We will illustrate this further with an example. Suppose we have an XML document with a book record:
408 <book isbn="1234567890">
409 <title>Farewell John Doe</title>
410 <publisher>ABC's is our Name</publisher>
415 An example XML schema that defines the book element and type could be
420 <element name="book">
423 <element name="title" type="string" minOccurs="1"/>
424 <element name="publisher" type="string" minOccurs="1"/>
426 <attribute name="isbn" type="unsignedLong" use="required"/>
433 Using `wsdl2h` we translate the XML schema that defines the book type and root element to a class definition:
441 std::string publisher;
445 Note that annotations such as `@` are used to distinguish attributes
446 from elements. These annotations are gSOAP-specific and are handled by the `soapcpp2` tool to generate serializers for the data type(s) for reading and writing XML.
448 The `soapcpp2` tool generates all
449 the necessary code to parse and generate XML for `book` objects. Validation
450 constraints such as *`minOccurs="1"`* and *`use="required"`* are included
451 in the generated code as checks.
453 To write the XML representation of a book, we first create a `soap` engine context and use it with `soap_write_book` (generated by `soapcpp2`) to write the object in XML to standard output:
456 soap *ctx = soap_new1(SOAP_XML_INDENT); // new context with option
458 bk.isbn = 1234567890;
459 bk.title = "Farewell John Doe";
460 bk.publisher = "ABC's is our Name";
461 if (soap_write_book(ctx, &bk) != SOAP_OK)
466 soap_destroy(ctx); // clean up allocated class instances
467 soap_end(ctx); // clean up allocated temporaries
468 soap_free(ctx); // delete context
471 The `ctx` gSOAP engine context (type `struct soap`) controls settings
472 and holds state, such as XML formatting, (e.g. `SOAP_XML_INDENT`),
473 serialization options, current state, and I/O settings. Simply set the output
474 stream (std::ostream) `ctx->os` of the context to redirect the
475 content, e.g. to a file or string. Also, when serializing a graph rather than an XML tree (`SOAP_XML_TREE` option forces trees) the XML output conforms to SOAP encoding for object graphs based on id-ref, see Section \ref bindings for details.
477 To read the XML representation from standard input into a book object, use:
480 soap *ctx = soap_new1(SOAP_XML_STRICT); // new context with option
482 if (soap_read_book(ctx, &bk) != SOAP_OK)
488 cout << bk.isbn << ", " << bk.title << ", " << bk.publisher << endl;
489 ... further use of bk ...
491 soap_destroy(ctx); // delete deserialized objects
492 soap_end(ctx); // delete temporaries
493 soap_free(ctx); // delete context
496 Automatic built-in strict XML validation (enabled with `SOAP_XML_STRICT`)
497 ensures that data members are present so we can safely print them in this
498 example, thus ensuring consistency of data with the XML schema. Set the
499 `ctx->is` input stream to read from a file/string stream
502 The `soap_destroy` and `soap_end` calls deallocate the deserialized
503 content, so use with care. In general, memory management is automatic in gSOAP
506 The above uses a very simple example schema. The gSOAP toolkit handles all XML schema constructs defined by the XML schema standard. The toolkit is also able to (de)serialize pointer-based C/C++
507 data structures (including cyclic graphs), structs/classes, unions, enums, STL
508 containers, and even special data types such as `struct tm`. Therefore, the toolkit works in two directions: from WSDL/schema to C/C++ and from C/C++ to WSDL/schema.
510 The gSOAP toolkit also handles multiple schemas defined in multiple namespaces. Normally the namespace prefixes of XML namespaces are added to the C/C++ type
511 definitions to ensure type uniqueness. For example, if we would combine two
512 schemas in the same application where both schemas define a `book` object,
513 we need to resolve this conflict. In gSOAP this is done using namespace
514 prefixes, rather than C++ namespaces (research has pointed out that XML
515 namespaces are not equivalent to C++ namespaces). Thus, the `book` class
516 might actually be bound to an XML namespace and the class would be named
517 `ns__book`, where `ns` is bound to the corresponding namespace.
519 The following options are available to control serialization:
522 soap->encodingStyle = NULL; // to remove SOAP 1.1/1.2 encodingStyle
523 soap_mode(soap, SOAP_XML_TREE); // XML without id-ref (no cycles!)
524 soap_mode(soap, SOAP_XML_GRAPH); // XML with id-ref (including cycles)
525 soap_set_namespaces(soap, struct Namespace *nsmap); //to set xmlns bindings
528 Other flags can be used to format XML, see Section \ref flags .
530 For more details on XML databinding support for C and C++, see
531 Section \ref bindings .
535 The highlights of gSOAP are:
537 * Unique interoperability features: the tools generate type-safe SOAP marshalling
538 routines to (de)serialize native and user-defined C and C++ data structures.
541 * Support WSDL 1.1, WSDL 2.0, REST, SOAP 1.1, SOAP 1.2, SOAP RPC encoding style, and document/literal style.
542 gSOAP is one of the few SOAP toolkits that support the **full** range of SOAP 1.1
543 RPC encoding features including sparse multi-dimensional arrays and polymorphic
544 types. For example, a service operation with a base class parameter may accept
545 derived class instances from a client. Derived class instances keep their
546 identity through dynamic binding. The toolkit also supports **all XSD
547 1.0 and 1.1 schema type** constructs and has been tested against the W3C XML
548 Schema Patterns for Databinding Interoperability working group and of gSOAP
549 release 2.8.x passes all tests.
552 * Supports WS-Security, WS-Addressing, WS-ReliableMessaging, C14N exclusive
553 canonicalization. The protocols are implemented using code generation with
554 wsdl2h and soapcpp2. The gSOAP tools can be used to generate messaging
555 protocols for other WS-* protocols.
558 * gSOAP supports XML-RPC and RSS protocols. Examples are provided.
561 * JSON support is included in the XML-RPC library to switch between XML-RPC
562 and JSON protocols. For more details, see the `samples/xml-rpc-json` folder in the package.
565 * The `wsdl2h` tool supports WS-Policy. Policy assertions are included in
566 the generated service description header file with recommendations and usage
570 * gSOAP supports MIME (SwA), DIME, and MTOM attachments and has streaming
571 capabilities to direct the data stream to/from resources.
572 gSOAP is the only toolkit that supports *streaming* MIME, DIME, and MTOM
573 attachment transfers, which allows you to exchange binary data of practically
574 unlimited size in the fastest possible way (streaming) while ensuring the
575 usefulness of XML interoperability.
578 * gSOAP supports SOAP-over-UDP.
581 * gSOAP supports IPv4 and IPv6.
584 * gSOAP supports Zlib deflate and gzip compression (for HTTP, TCP/IP, and XML file storage).
587 * gSOAP supports SSL (HTTPS) using OpenSSL and optionally using GNUTLS.
590 * gSOAP supports HTTP/1.0, HTTP/1.1 keep-alive, chunking, basic authentication, and digest authentication using a plugin.
593 * gSOAP supports SOAP one-way messaging.
596 * The schema-specific XML pull parser is fast and efficient and does not require intermediate data storage for
597 demarshalling to save space and time.
600 * The `soapcpp2` compiler includes a WSDL and schema generator for convenient
601 Web Service publishing.
604 * The `soapcpp2` compiler generates sample input and output messages
605 for verification and testing (before writing any code). An option (`-T`)
606 can be used to automatically implement echo message services for testing.
609 * The `wsdl2h` tool converts WSDL and XSD files to gSOAP header files for automated client and server development.
612 * Generates source code for stand-alone Web Services and client applications.
615 * Ideal for small devices such as Palm OS, Symbian, Pocket PC, because the memory footprint is small.
618 * Ideal for building web services that are compute-intensive and are therefore best written in C and C++.
621 * Platform independent: Windows, Unix, Linux, Mac OS X, Pocket PC, Palm OS, Symbian, VXWorks, etc.
624 * Supports serializing of application's native C and C++ data structures, which allows you to save and load XML serialized data structures to and from files.
627 * Selective input and output buffering is used to increase efficiency, but full message buffering to determine HTTP message length
628 is not used. Instead, a three-phase serialization method is used to determine message length. As a result, large data sets
629 such as base64-encoded images can be transmitted with or without DIME attachments by small-memory devices such as PDAs.
632 * Supports C++ single class inheritance, dynamic binding, overloading, arbitrary pointer structures such as lists, trees, graphs,
633 cyclic graphs, fixed-size arrays, (multi-dimensional) dynamic arrays, enumerations, built-in XSD Schema types including
634 base64Binary encoding, and hexBinary encoding.
637 * No need to rewrite existing C/C++ applications for Web service deployment. However, parts of an application that use unions,
638 pointers to sequences of elements in memory, and `void*` need to be modified, but **only** if the data structures that
639 adopt them are required to be serialized or deserialized as part of a service operation invocation.
642 * Three-phase marshalling: 1) analysis of pointers, single-reference, multi-reference, and cyclic data structures, 2) HTTP
643 message-length determination, and 3) serialization as per SOAP 1.1 encoding style or user-defined encoding styles.
646 * Two-phase demarshalling: 1) SOAP parsing and decoding, which involves the reconstruction of multi-reference and cyclic data
647 structures from the payload, and 2) resolution of "forward" pointers (i.e. resolution of the forward *`href`* attributes in SOAP).
650 * Full and customizable SOAP Fault processing (client receive and service send).
653 * Customizable SOAP Header processing (send and receive), which for example enables easy transaction processing for the service to
654 keep state information.
656 # Notational Conventions
658 The typographical conventions used by this document are:
660 * `Courier` denotes C and C++ source code, XML data, JSON data, file names, and shell/batch commands.
662 * `[optional: ...]` denotes an optional construct.
664 The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and
665 "OPTIONAL" in this document are to be interpreted as described in RFC-2119.
667 # Differences Between gSOAP Versions 2.4 (and Earlier) and 2.5
669 To comply with WS-I Basic Profile 1.0a, gSOAP 2.5 and higher adopts SOAP document/literal by default.
670 There is no need for concern, because the WSDL parser `wsdl2h` automatically takes care of the differences when you provide a WSDL document, because SOAP RPC encoding, literal, and document style are supported.
671 A new soapcpp2 compiler option was added `-e` for backward compatibility with gSOAP 2.4 and earlier to adopt SOAP RPC encoding by default in case you want to develop a service that uses SOAP encoding. You can also use the gSOAP `soapcpp2` compiler directives to specify SOAP encoding for individual operarations, when desired.
673 # Differences Between gSOAP Versions 2.1 (and Earlier) and 2.2
675 You should read this section only if you are upgrading from gSOAP 2.1 to 2.2 and later.
677 Run-time options and flags have been changed to enable separate recv/send
678 settings for transport, content encodings, and mappings. The flags are divided
679 into four classes: transport (IO), content encoding (ENC), XML marshalling
680 (XML), and C/C++ data mapping (C). The old-style flags `soap_disable_X`
681 and `soap_enable_X`, where `X` is a particular feature, are
682 deprecated. See Section \ref flags for more details.
684 Before a client can invoke service operations or before a service can accept requests, a runtime context needs to be allocated and
687 * `soap_init(struct soap *soap)` & Initializes a context (required only once)
689 * `struct soap *soap_new()` & Allocates, initializes, and returns a pointer to a runtime context
691 * `struct soap *soap_copy(struct soap *soap)` & Allocates a new runtime context and copies contents of
692 the context such that the new environment does not share any data with the
695 A context can be reused as many times as necessary and does not need to be
696 reinitialized in doing so. A dynamically allocated context is deallocated
697 with `soap_free(soap)`.
699 A new context is only required for each new thread to guarantee exclusive access
700 to a new runtime context by each thread.
701 For example, the following code stack-allocates the runtime context which is used for multiple service operation calls:
708 soap_init(&soap); // initialize runtime context
710 soap_call_ns__method1(&soap, ...); // make a remote call
712 soap_call_ns__method2(&soap, ...); // make another remote call
714 soap_destroy(&soap); // remove deserialized class instances (C++ only)
715 soap_end(&soap); // clean up and remove deserialized data
716 soap_done(&soap); // detach context (last use and no longer in scope)
721 The runtime context can also be heap allocated:
728 soap = soap_new(); // allocate and initialize runtime context
729 if (!soap) // couldn't allocate: stop
731 soap_call_ns__method1(soap, ...); // make a remote call
733 soap_call_ns__method2(soap, ...); // make another remote call
735 soap_destroy(soap); // remove deserialized class instances (C++ only)
736 soap_end(soap); // clean up and remove deserialized data
737 soap_free(soap); // detach and free runtime context
741 A service needs to allocate and initialize an context before calling `soap_serve`:
757 soap_serve(soap_new());
761 The `soap_serve` dispatcher handles one request or multiple requests when HTTP keep-alive is enabled (with the `SOAP_IO_KEEPALIVE` flag see Section \ref keepalive ).
763 A service can use multi-threading to handle requests while running some other code that invokes service operations:
768 struct soap soap1, soap2;
772 if (soap_bind(&soap1, host, port, backlog) < 0) exit(1);
773 if (soap_accept(&soap1) < 0) exit(1);
774 pthread_create(&tid, NULL, (void*(*)(void*))soap_serve, (void*)&soap1);
777 soap_call_ns__method(&soap2, ...); // make a remote call
781 pthread_join(tid, NULL); // wait for thread to terminate
782 soap_end(&soap1); // release its data
786 In the example above, two runtime contexts are required.
787 In comparison, gSOAP 1.X statically allocates the runtime context, which prohibits multi-threading (only one thread can invoke
788 service operations and/or accept requests due to the single runtime context).
790 Section \ref mt presents a multi-threaded stand-alone Web Service that handles multiple SOAP requests by spawning a thread for each request.
794 gSOAP interoperability has been verified with the following SOAP implementations and toolkits:
796 Apache 2.2, Apache Axis, ASP.NET, Cape Connect, Delphi, easySOAP++, eSOAP, Frontier, GLUE, Iona XMLBus, kSOAP, MS SOAP, Phalanx, SIM, SOAP::Lite, SOAP4R, Spray, SQLData, WCF, White Mesa, xSOAP, ZSI
800 This user guide offers a quick way to get started with gSOAP. This section
801 requires a basic understanding of the SOAP protocol and some familiarity
802 with C and/or C++. In principle, SOAP clients and SOAP Web services can be
803 developed in C and C++ with the gSOAP `soapcpp2` compiler without a detailed understanding
804 of the SOAP protocol when gSOAP client-server applications are built as an
805 ensamble and only communicate within this group (i.e. meaning that you don't
806 have to worry about interoperability with other SOAP implementations). This
807 section is intended to illustrate the implementation of gSOAP Web services and
808 clients that connect to and interoperate with other SOAP implementations such
809 as Apache Axis, SOAP::Lite, and .NET. This requires some details of the SOAP
810 and WSDL protocols to be understood.
812 ## How to Build SOAP/XML Clients {#client}
814 In general, the implementation of a SOAP client application requires a
815 *stub* (also called *service proxy*) for each service operation that the client invokes. The primary stub's responsibility is to marshall the parameter data,
816 send the request with the parameters to the designated SOAP service over the
817 wire, to wait for the
818 response, and to demarshall the parameter data of the response when it arrives. The client
819 application invokes the stub routine for a service operation as if it would invoke
820 a local function. To write a stub routine in C or C++ by hand is a tedious task,
821 especially if the input and/or output parameters of a service operation contain
822 elaborate data structures such as objects, structs, containers, arrays, and pointer-linked graph structures. Fortunately, the
823 gSOAP `wsdl2h` WSDL parser tool and `soapcpp2` stub/skeleton and serialization code generator tool automate the
824 development of SOAP/XML Web service client and server applications.
826 The `soapcpp2` tool generates the necessary gluing code (also called stubs and skeletons) to build web service clients and services. The input to the `soapcpp2`
827 tool consists of an service definition-annotated C/C++ **header file**. The
828 header file can be generated from a WSDL (Web Service Description Language)
829 documentation of a service with the gSOAP `wsdl2h` WSDL parser tool.
831 Consider the following command (entered at the Linux/Unix/Windows command line prompt):
833 > wsdl2h -o calc.h http://www.genivia.com/calc.wsdl
835 This generates the file Web service description `calc.h` in an annotated C++ header file.
836 The WSDL specification (possibly consisting of multiple imported WSDL files and XSD schema files) is mapped to C++ using C++ databindings for
837 SOAP/XML. The generated header file contains data types and messages to operate
838 the service, and meta information related to WSDL and XML schemas.
840 To generate a service definition header file to develop a pure C client application, use the `-c` option:
842 > wsdl2h -c -o calc.h http://www.genivia.com/calc.wsdl
844 For more details on the WSDL parser and its options, see \ref wsdlin .
846 The service definition `calc.h` header file is further processed by the
847 gSOAP `soapcpp2` compiler to generate the gluing code's logic to invoke
848 the Web service from a client.
850 Looking into the file `calc.h` we see that the SOAP service methods are
851 specified as **function prototypes**. For example, the `add` function to add two double floats:
854 int ns2__add(double a, double b, double& result);
857 The `ns2__add` function uses an XML namespace prefix to distinguish it
858 from operations defined in other namespaces, thus preventing name clashes. The
859 convention to add an XML namespace prefix to the names of operations, types,
860 and `struct` and `class` members is universally used by the gSOAP
861 tools and automatically created by `wsdl2h`, but it is not mandatory when
862 translating existing C/C++ types and operations to web services. Thus, the
863 prefix notation can be omitted from type names defined in an header file with
864 to run `soapcpp2` to create clients and services that exchange existing
865 (i.e. application-native) data types.
867 These function prototypes are translated by the gSOAP `soapcpp2` tool to stubs and proxies for remote calls:
869 * `soapStub.h` annotated copy of the input definitions
871 * `soapH.h` serializers
873 * `soapC.cpp` serializers
875 * `soapClient.cpp` client calling stubs
877 Thus, the logic of the generated stub routines allow C and
878 C++ client applications to seamlessly interact with existing SOAP Web services as illustrated by the client code example in the next section.
880 The input and output parameters of a SOAP service operation may be primitive data
881 types or complex compound data types such as containers and pointer-based linked data structures. These are defined in the header file that is either generated by the WSDL parser or specified by hand.
882 The gSOAP `soapcpp2` tool automatically generates
883 **XML serializers** and **XML deserializers** for the data types to enable the generated
884 stub routines to encode and decode the contents of the parameters of the service operations
887 Note that the gSOAP `soapcpp2` tool also generates **skeleton**
888 routines `soapServer.cpp` for each of the service operations specified in the header file. The
890 can be readily used to implement one or more of the service operations in a new
891 SOAP Web service. These skeleton routines are not used for building SOAP
892 clients in C++, although they can be used to build mixed SOAP client/server
893 applications (peer applications).
895 ### Example {#example1}
897 The `add` service operation (declared in the `calc.h` file obtained
898 with the `wsdl2h` tool in the previous section) adds two float values.
899 The WSDL description of the service provides the endpoint to invoke the service operations and the XML namespace used by the operations:
901 * Endpoint URL: *`http://websrv.cs.fsu.edu/~engelen/calcserver.cgi`*
903 * XML namespace: *`urn:calc`*
905 Each service operation has a SOAP action, which is an optional string to
906 identify the operation (mainly used with WS-Addressing), an operation request
907 message and a response message. The request and response messages for SOAP
908 RPC-encoded services are simply represented by C functions with input and
909 output parameters. For the `add` operation, the SOAP binding details are:
913 * SOAP encoding: encoded
915 * SOAP action: *`""`* (empty string)
917 This information is translated to the `wsdl2h`-generated header file with the service definitions.
918 The `calc.h` header file for C++ generated by `wsdl2h` contains the following directives and declarations:
919 (the actual contents may vary depending on the release version and the options used to control the output):
922 //gsoap ns2 service name: calc
923 //gsoap ns2 service type: calcPortType
924 //gsoap ns2 service port: http://websrv.cs.fsu.edu/~engelen/calcserver.cgi
925 //gsoap ns2 service namespace: urn:calc
927 //gsoap ns2 service method-protocol: add SOAP
928 //gsoap ns2 service method-style: add rpc
929 //gsoap ns2 service method-encoding: add http://schemas.xmlsoap.org/soap/encoding/
930 //gsoap ns2 service method-action: add ""
931 int ns2__add(double a, double b, double& result);
934 The other calculator operations are similar and elided here for clarity.
936 The `//gsoap` directives are required for the
937 `soapcpp2` tool to generate code that is compliant to the SOAP protocol. For this service the SOAP protocol with the common "RPC encoding style" is used. For `//gsoap` directive details, see Section \ref directives .
939 The service operations are declared as
940 function prototypes, with all non-primitive parameter types needed by the
941 operation declared in the header file (all parameter types are primitive in
944 The calculator `add` operation takes two double floats `a` and `b`,
945 and returns the sum in `result`. By convention, **all parameters are input
946 parameters except the last**. The last parameter is al**ways the output parameter.
947 A `struct` or `class` is used to wrap multiple output parameters, see
948 also Section \ref multiple . This last parameter must be a pointer or
949 reference. By contrast, the input parameters support pass by value or by
950 pointer, but not pass by C++ reference.
952 The function prototype associated with a service operation always returns an
953 `int`. The value indicates success (`0` or equivalently
954 `SOAP_OK`) or failure (any nonzero value). See Section \ref errcodes
955 for the nonzero error codes.
957 The role of the namespace prefix (`ns2__`) in the service operation name in the
958 function prototype declaration is discussed in detail in \ref namespace .
959 Basically, a namespace prefix is added to a function name or type name with a **pair of underscores**,
960 as in `ns2__add`, where `ns2` is the
961 namespace prefix and `add` is the service operation name. This mechanism ensures uniqueness of operations and types associated with a service.
963 It is strongly recommended to set the namespace prefix to a name of your
964 choice. This avoids problems when running `wsdl2h` on multiple WSDLs where
965 the sequence of prefixes `ns1`, `ns2`, and so on are arbitrarily
966 assigned to the services. To choose a prefix name for all the operations and types of a service, say prefix `c__` for the calculator service, add the following line to `typemap.dat`:
974 and rerun `wsdl2h`. The `typemap.dat` configures `wsdl2h` to use
975 specific bindings and data types for services. The result is that `c__add` is used to uniquely identify the operation rather than the more arbitrary name `ns2__add`.
977 Note on the use of underscores in names: a single
978 underscore in an identifier name will be translated into a dash in XML, because
979 dashes are more frequently used in XML compared to underscores, see
980 Section \ref idtrans .
982 Next, the gSOAP `soapcpp2` tool is invoked from the command line to process the `calc.h` service definitions:
986 The tool generates the stub routines for the service operations.
987 Stub routines can be invoked
988 by a client program to invoke the remote service operations.
989 The interface of the generated stub routine is identical to the function prototype in the `calc.h` service defintion file, but with additional parameters to pass the gSOAP engine's runtime context `soap`, an endpoint URL (or NULL for the default), and a SOAP action (or NULL for the default):
992 int soap_call_c__add(struct soap *soap, char *URL, char *action, double a, double b, double& result);
995 This stub routine is saved in `soapClient.cpp`. The file `soapC.cpp`
996 contains the **serializer** and **deserializer** routines for the data
997 types used by the stub. You can use option `-c` for the `soapcpp2` tool to
998 generate pure C code, when needed.
1000 Note: the `soap` parameter must be a valid pointer to a gSOAP runtime
1001 context. The `URL` can be set to override the default endpoint address (the endpoint defined by the WSDL).
1002 The `action` parameter can be set to override the default SOAP action.
1004 The following example C/C++ client program uses the stub:
1007 #include "soapH.h" // include all interfaces (library and generated)
1008 #include "calc.nsmap" // import the generated namespace mapping table
1012 struct soap soap; // the gSOAP runtime context
1013 soap_init(&soap); // initialize the context (only once!)
1014 if (soap_call_c__add(&soap, NULL, NULL, 1.0, 2.0, &sum) == SOAP_OK)
1015 std::cout << "Sum = " << sum << std::endl;
1016 else // an error occurred
1017 soap_print_fault(&soap, stderr); // display the SOAP fault message on the stderr stream
1018 soap_destroy(&soap); // delete deserialized class instances (for C++)
1019 soap_end(&soap); // remove deserialized data and clean up
1020 soap_done(&soap); // detach the gSOAP context
1025 The call returns `SOAP_OK` (zero) on success and a nonzero error on
1026 failure. When an error occurred the fault is displayed with the
1027 `soap_print_fault` function. Use `soap_sprint_fault(struct soap*, char *buf, size_t len)` to print the error to a string, and use `soap_stream_fault(struct soap*, std::ostream&)` to send it to a stream (C++ only).
1029 The following functions can be used to explicitly setup a gSOAP runtime context (`struct soap`):
1031 * `soap_init(struct soap *soap)` Initializes a runtime context
1033 * `soap_init1(struct soap *soap, soap_mode iomode)` Initializes a runtime context and set in/out mode flags
1035 * `soap_init2(struct soap *soap, soap_mode imode, soap_mode omode)` Initializes a runtime context and set in/out mode flags
1037 * `struct soap *soap_new()` Allocates, initializes, and returns a pointer to a runtime context
1039 * `struct soap *soap_new1(soap_mode iomode)` Allocates, initializes, and returns a pointer to a runtime context and set in/out mode flags
1041 * `struct soap *soap_new2(soap_mode imode, soap_mode omode)` Allocates, initializes, and returns a pointer to a runtime context and set in/out mode flags
1043 * `struct soap *soap_copy(struct soap *soap)` Allocates a new runtime context and copies a context (deep copy, i.e. the new context does not share any data with the other context)
1045 * `soap_done(struct soap *soap)` Reset, close communications, and remove callbacks
1047 * `soap_free(struct soap *soap)` Reset and deallocate the context created with `soap_new` or `soap_copy`
1049 A runtime context can be reused as many times as necessary for client-side remote calls and does not need to be reinitialized in doing so.
1050 A new context is required for each new thread to guarantee exclusive access
1051 to runtime context by threads. Also the use of any client calls within an active service method requires a new context.
1053 The `soapcpp2` code generator tool also generates a service proxy class for C++ client applications (and service objects for server applications) with the `-i` (or `-j`) option:
1055 > soapcpp2 -i calc.h
1057 The proxy is defined in:
1059 * `soapcalcProxy.h` client proxy class
1061 * `soapcalcProxy.cpp` client proxy class
1063 Note: without the `-i` option only old-style service proxies and objects
1064 are generated, which are less flexible and no longer recommended. Use `-j`
1065 as an alternative to `-i` to generate classes with the same functionality,
1066 but that are not inherited from `struct soap` and use a pointer to a
1067 `struct soap` engine context that can be shared with other proxy and
1068 service class instances. This choice is also important when services are chained, see Section \ref chaining .
1070 The generated C++ proxy class initializes the gSOAP runtime context and offers the service interface as a collection of methods:
1073 #include "soapcalcProxy.h" // get proxy
1074 #include "calc.nsmap" // import the generated namespace mapping table
1077 calcProxy calc(SOAP_XML_INDENT);
1079 if (calc.add(1.0, 2.0, sum) == SOAP_OK)
1080 std::cout << "Sum = " << sum << std::endl;
1082 calc.soap_stream_fault(std::cerr);
1083 return calc.error; // nonzero when error
1087 The proxy class is derived from the gSOAP runtime context structure
1088 `struct soap` and thus inherits (option `-i`) all state information
1089 of the runtime. The proxy constructor takes context mode parameters to initialize the context, e.g. `SOAP_XML_INDENT` in this example.
1091 The code is compiled and linked with `soapcalcProxy.cpp`, `soapC.cpp`,
1092 and `stdsoap2.cpp` (or use `libgsoap++.a`).
1094 The proxy class name is extracted from the WSDL content and may not always be in a short format. Feel free to change the entry
1097 //gsoap ns2 service name: calc
1100 and rerun `soapcpp2` to generate code that uses the new name.
1102 When the example client application is invoked, a SOAP request is performed:
1106 POST /~engelen/calcserver.cgi HTTP/1.1
1107 Host: websrv.cs.fsu.edu
1108 User-Agent: gSOAP/2.7
1109 Content-Type: text/xml; charset=utf-8
1114 <?xml version="1.0" encoding="UTF-8"?>
1116 xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
1117 xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
1118 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1119 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
1121 <SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
1127 </SOAP-ENV:Envelope>
1131 The SOAP response message:
1136 Date: Wed, 05 May 2010 16:02:21 GMT
1137 Server: Apache/2.0.52 (Scientific Linux)
1140 Content-Type: text/xml; charset=utf-8
1142 <?xml version="1.0" encoding="UTF-8"?>
1144 xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
1145 xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
1146 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1147 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
1148 xmlns:ns="urn:calc">
1149 <SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
1154 </SOAP-ENV:Envelope>
1158 A client can invoke a sequence of service operations:
1161 #include "soapcalcProxy.h" // get proxy
1162 #include "calc.nsmap" // import the generated namespace mapping table
1165 calcProxy calc(SOAP_IO_KEEPALIVE); // keep-alive improves connection performance
1167 double val[] = { 5.0, 3.5, 7.1, 1.2 };
1168 for (int i = 0; i < 4; i++)
1169 if (calc.add(sum, val[i], sum))
1171 std::cout << "Sum = " << sum << std::endl;
1176 In the above, no data is deallocated until the proxy is deleted. To deallocate deserialized data between the calls, use:
1179 for (int i = 0; i < 4; i++)
1181 if (calc.add(sum, val[i], sum))
1187 Deallocation is safe here, since the float values were copied and saved in
1188 `sum`. In other scenarios one must make sure data is copied or removed from
1189 the deallocation chain with:
1192 soap_unlink(struct soap *soap, const void *data)
1195 which is to be invoked on each data item to be preserved, before destroying deallocated data. When the proxy is deleted, also all deserialized data is deleted. To delegate deletion to another runtime context for later removal, use:
1198 soap_delegate_deletion(struct soap *soap_from, struct soap *soap_to)
1208 ... data generated ...
1209 soap_delegate_deletion(&calc, &soap);
1212 soap_destroy(&soap);
1217 In C (use `wsdl2h -c`) the example program would be written as:
1221 #include "calc.nsmap"
1226 double val[] = { 5.0, 3.5, 7.1, 1.2 };
1228 for (i = 0; i < 4; i++)
1229 soap_init1(&soap, SOAP_IO_KEEPALIVE);
1230 if (soap_call_c__add(&soap, NULL, NULL, sum, val[i], &sum))
1232 printf("Sum = %lg\n", sum);
1239 The code above is compiled and linked with `soapClient.c`, `soapC.c`,
1240 and `stdsoap2.c` (or use `libgsoap.a`).
1242 ### XML Namespace Considerations {#namespace}
1244 The declaration of the `ns2__add` function prototype (discussed in the previous section) uses the namespace prefix
1245 `ns2__` of the service operation namespace, which is distinguished by a **pair of underscores** in the function name to
1246 separate the namespace prefix from the service operation name. The purpose of a namespace prefix is to associate a service
1247 operation name with a service in order to prevent naming conflicts, e.g. to distinguish identical service operation names used
1248 by different services.
1250 Note that the XML response of the service example uses a **namespace prefix** that may be different (e.g. *`ns`*) as long as it bound to the same **namespace name** *`urn:calc`* through the *`xmlns:ns="{`*urn:calc}
1251 binding. The use of namespace prefixes and namespace names is also required to enable SOAP applications to validate the content of
1252 SOAP messages. The namespace name in the service response is verified by the stub routine by using the
1253 information supplied in a **namespace mapping table** that is required to be part of gSOAP client and service application codes. The table is accessed
1254 at run time to resolve namespace bindings, both by the generated stub's data structure serializer for encoding the client request
1255 and by the generated stub's data structure deserializer to decode and validate the service response. The namespace mapping table
1256 should **not** be part of the header file input to the gSOAP `soapcpp2` tool. Service details including namespace bindings may be provided with gSOAP directives in a header file, see Section \ref directives .
1258 The namespace mapping table is:
1261 struct Namespace namespaces[] =
1262 { // {"ns-prefix", "ns-name"}
1263 {"SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/"}, // MUST be first
1264 {"SOAP-ENC", "http://schemas.xmlsoap.org/soap/encoding/"}, // MUST be second
1265 {"xsi", "http://www.w3.org/2001/XMLSchema-instance"}, // MUST be third
1266 {"xsd", "http://www.w3.org/2001/XMLSchema"}, // 2001 XML Schema
1267 {"ns2", "urn:calc"}, // given by the service description
1268 {NULL, NULL} // end of table
1272 The first four namespace entries in the table consist of the standard namespaces used by the SOAP 1.1 protocol. In fact, the
1273 namespace mapping table is explicitly declared to enable a programmer to specify the SOAP encoding style and to allow the
1274 inclusion of namespace-prefix with namespace-name bindings to comply to the namespace requirements of a specific SOAP service. For
1275 example, the namespace prefix *`ns2`*, which is bound to *`urn:calc`* by the namespace mapping table shown
1276 above, is used by the generated stub routine to encode the `add` request. This is performed automatically by the gSOAP `soapcpp2`
1277 tool by using the `ns2` prefix of the `ns2__add` method name specified in the `calc.h` header file. In
1278 general, if a function name of a service operation, `struct` name, `class` name, `enum` name, or field name of a
1279 `struct` or `class` has a pair of underscores, the name has a namespace prefix that must be defined in the namespace
1282 The namespace mapping table will be output as part of the SOAP Envelope by the stub routine. For example:
1287 <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
1288 xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
1289 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1290 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
1291 xmlns:ns2="urn:calc"
1292 SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
1297 The namespace bindings will be used by a SOAP service to validate the SOAP request.
1299 ### Example {#example2}
1301 The incorporation of namespace prefixes into C++ identifier names is necessary to distinguish service operations that
1302 share the same name but are provided by separate Web services and/or
1303 organizations. It avoids potential name clashes, while sticking to the C
1304 syntax. The C++ proxy classes generated with `soapcpp2 -i` (or `-j`) drop the
1305 namespace prefix from the method names
1307 The namespace prefix convention is also be applied to non-primitive types. For example, `class` names are prefixed to avoid name clashes when the same name is used by multiple XML schemas. This ensures that the XML databinding never suffers from conflicting schema content. For example:
1310 class e__Address // an electronic address from schema 'e'
1315 class s__Address // a street address from schema 's'
1323 The namespace prefix is separated from the name of a data type by a pair of underscores (`__`).
1325 An instance of `e__Address` is encoded by the generated serializer for this type as an Address element with namespace prefix `e`:
1329 <e:Address xsi:type="e:Address">
1330 <email xsi:type="string">me@home</email>
1331 <url xsi:type="string">www.me.com</url>
1336 While an instance of `s__Address` is encoded by the generated serializer for this type as an Address element with namespace prefix `s`:
1340 <s:Address xsi:type="s:Address">
1341 <street xsi:type="string">Technology Drive</street>
1342 <number xsi:type="int">5</number>
1343 <city xsi:type="string">Softcity</city>
1348 The namespace mapping table of the client program must have entries for `e` and `s` that refer to the XML Schemas of the data types:
1351 struct Namespace namespaces[] =
1353 {"e", "http://www.me.com/schemas/electronic-address"},
1354 {"s", "http://www.me.com/schemas/street-address"},
1358 This table is required to be part of the client application to allow access by the serializers and deserializers of the data types at run time.
1360 ### How to Generate C++ Client Proxy Classes {#proxy}
1362 Proxy classes for C++ client applications are automatically generated by the gSOAP `soapcpp2` tool, as was shown in Section \ref example1 .
1364 There is a new and improved code generation capability for proxy classes, which
1365 is activated with the `soapcpp2 -i` (or `j`) option. These new proxy classes are
1366 derived from the soap structure, have a cleaner interface and offer more
1369 With C++, you can also use `wsdl2h` option `-q`*name* to generate
1370 the proxy in a C++ namespace *name*. This is very useful if you want to
1371 create multiple proxies for services by repeated use of `wsdl2h` and
1372 combine them in one code. Alternatively, you can run `wsdl2h` just once on
1373 all service WSDLs and have `soapcpp2` generate multiple proxies for you.
1374 The latter approach does not use C++ namespaces and may reduce the overall
1377 To illustrate the generation of a "standard" (old-style) proxy class, the
1378 `calc.h` header file example of the previous section is augmented with
1379 the appropriate directives to enable the gSOAP `soapcpp2` tool to generate the proxy
1380 class. Directives are included in the generated header file by the `wsdl2h` WSDL importer:
1383 // Content of file "calc.h":
1384 //gsoap ns2 service name: calc
1385 //gsoap ns2 service port: http://websrv.cs.fsu.edu/~engelen/calcserver.cgi
1386 //gsoap ns2 service protocol: SOAP1.1
1387 //gsoap ns2 service style: rpc
1388 //gsoap ns2 service encoding: encoded
1389 //gsoap ns2 service namespace: urn:calc
1391 //gsoap ns2 service method-protocol: add SOAP
1392 //gsoap ns2 service method-style: add rpc
1393 //gsoap ns2 service method-encoding: add encoded
1394 //gsoap ns2 service method-action: add ""
1395 int ns2__add(double a, double b, double& result);
1397 //gsoap ns2 service method-protocol: sub SOAP
1398 //gsoap ns2 service method-style: sub rpc
1399 //gsoap ns2 service method-encoding: sub encoded
1400 //gsoap ns2 service method-action: sub ""
1401 int ns2__sub(double a, double b, double& result);
1403 //gsoap ns2 service method-protocol: mul SOAP
1404 //gsoap ns2 service method-style: mul rpc
1405 //gsoap ns2 service method-encoding: mul encoded
1406 //gsoap ns2 service method-action: mul ""
1407 int ns2__mul(double a, double b, double& result);
1412 The first three directives provide the service details, which is used to name the proxy class, the service location port (endpoint), and
1413 the XML namespace. The subsequent groups of three directives per method define the operation's SOAP style (RPC) and encoding (SOAP encoded), and SOAP action string.
1414 These directives can be provided for each service operation when the SOAPAction is required, such as with SOAP1.1 RPC encoded and when WS-Addressing is used.
1415 In this example, the service protocol is set by default for all operations to use SOAP 1.1 RPC encoding.
1416 For `//gsoap` directive details, see Section \ref directives .
1418 The `soapcpp2` tool takes this header file and generates a proxy `soapcalcProxy.h` with the
1419 following contents (not using option `-i`):
1426 const char *endpoint;
1429 virtual int ns2__add(double a, double b, double& result) { return soap ? soap_call_ns2__add(soap, endpoint, NULL, a, b, result) : SOAP_EOM; };
1430 virtual int ns2__sub(double a, double b, double& result) { return soap ? soap_call_ns2__sub(soap, endpoint, NULL, a, b, result) : SOAP_EOM; };
1431 virtual int ns2__mul(double a, double b, double& result) { return soap ? soap_call_ns2__mul(soap, endpoint, NULL, a, b, result) : SOAP_EOM; };
1436 The gSOAP context and endpoint are declared public to enable access.
1438 This generated proxy class can be included into a client application together with the generated namespace table as shown in this example:
1441 #include "soapcalcProxy.h" // get proxy
1442 #include "calc.nsmap" // get namespace bindings
1447 if (s.ns2__add(1.0, 2.0, r) == SOAP_OK)
1448 std::cout << r << std::endl;
1450 soap_print_fault(s.soap, stderr);
1455 The constructor allocates and initializes a gSOAP context for the instance.
1457 You can use `soapcpp2` option `-n` together with `-p` to create
1458 a local namespaces table to avoid link conflicts when you need multiple
1459 namespace tables or need to combine multiple clients, see also
1460 Sections \ref options and \ref dylibs , and you can use a C++ code
1461 `namespace` to create a namespace qualified proxy class, see
1462 Section \ref codenamespace .
1464 The `soapcpp2 -i` option to generate proxy classes
1465 derived from the base soap structure. In addition, these classes offer more
1466 functionality as illustrated in Section \ref example1 .
1468 ### XSD Type Encoding Considerations {#encoding}
1470 Many SOAP services require the explicit use of XML Schema types in the SOAP payload. The default encoding, which is also adopted
1471 by the gSOAP `soapcpp2` tool, assumes SOAP RPC encoding which only requires the use of types to handle polymorphic cases.
1472 Nevertheless, the use of XSD typed messages is advised to improve interoperability.
1473 XSD types are introduced with `typedef` definitions in
1474 the header file input to the gSOAP `soapcpp2` tool. The type name defined by a `typedef` definition corresponds to an XML Schema
1475 type (XSD type). For example, the following `typedef` declarations
1476 define various built-in XSD types implemented as primitive C/C++ types:
1479 // Contents of header file:
1481 typedef char *xsd__string; // encode xsd__string value as the *`xsd:string`* schema type
1482 typedef char *xsd__anyURI; // encode xsd__anyURI value as the *`xsd:anyURI`* schema type
1483 typedef float xsd__float; // encode xsd__float value as the *`xsd:float`* schema type
1484 typedef long xsd__int; // encode xsd__int value as the *`xsd:int`* schema type
1485 typedef bool xsd__boolean; // encode xsd__boolean value as the *`xsd:boolean`* schema type
1486 typedef unsigned long long xsd__positiveInteger; // encode xsd__positiveInteger value as the *`xsd:positiveInteger`* schema type
1490 This easy-to-use mechanism informs the gSOAP `soapcpp2` tool to generate serializers and deserializers that explicitly encode and decode the
1491 primitive C++ types as built-in primitive XSD types when the `typedef`ed type is used in the parameter signature of a
1492 service operation (or when used nested within structs, classes, and arrays). At the same time, the use of `typedef`
1493 does not force any recoding of a C++ client or Web service application as the internal C++ types used by the application
1494 are not required to be changed (but still have to be primitive C++ types, see Section \ref primclass for alternative class
1495 implementations of primitive XSD types which allows for the marshalling of polymorphic primitive types).
1497 ### Example {#example3}
1499 Reconsider the calculator example, now rewritten with explicit XSD types to illustrate the effect:
1502 // Contents of file "calc.h":
1503 typedef double xsd__double;
1504 int ns2__add(xsd__string a, xsd__double b, xsd__double &Result);
1507 When processed by the gSOAP `soapcpp2` tool it generates source code for the function
1508 `soap_call_ns2__add`, which is identical to the C-style SOAP call:
1511 int soap_call_ns2__add(struct soap *soap, char *URL, char *action, double a, double b, double& result);
1514 The client application does not need to be rewritten and can still call the proxy using the "old" C-style function signatures. In contrast to
1515 the previous implementation of the stub however, the encoding and decoding of the data types by the stub has been changed to
1516 explicitly use the XSD types in the message payload.
1518 For example, when the client application calls the proxy, the proxy produces a SOAP request with an *`xsd:double`* (the *`xsi:type`* is shown when the `soapcpp2 -t` option is used):
1525 <a xsi:type="xsd:string">1.0</a>
1526 <b xsi:type="xsd:string">2.0</b>
1533 The service response is:
1539 <n:addResponse xmlns:n="urn:calc">
1540 <result xsi:type="xsd:double">3.0</result>
1547 The validation of this service response by the stub routine takes place by matching the namespace names (URIs) that are bound to the
1548 *`xsd`* namespace prefix. The stub also expects the *`addResponse`* element to be associated with URI
1549 *`urn:calc`* through the binding of the namespace prefix *`ns2`* in the namespace mapping table. The
1550 service response uses namespace prefix *`n`* for the *`addResponse`* element. This namespace prefix is bound to the same
1551 URI *`urn:calc`* and therefore the service response is valid. When the XML is not well formed or does not pass validation, the response is
1552 rejected and a SOAP fault is generated. The validation level can be increased with the `SOAP_XML_STRICT` flag, but this is not advised for SOAP RPC encoded messaging.
1554 ### How to Change the Response Element Name {#response}
1556 There is no standardized convention for the response element name in a SOAP RPC encoded response message, although it is recommended that the response
1557 element name is the method name ending with "*`Response`*". For example, the response element of *`add`* is
1560 The response element name can be specified explicitly using a `struct` or
1561 `class` declaration in the header file. This name must be qualified by a
1562 namespace prefix, just as the operation name should use a namespace prefix. The
1563 `struct` or `class` name represents the SOAP response element name
1564 used by the service. Consequently, the output
1565 parameter of the service operation must be declared as a field of the `struct` or `class`. The use of a `struct` or a
1566 `class` for the service response is fully SOAP 1.1 compliant. In fact, the absence of a `struct` or `class`
1567 indicates to the `soapcpp2` tool to automatically generate a `struct` for the response which is internally used by a stub.
1569 ### Example {#example4}
1571 Reconsider the calculator service operation specification which can be rewritten with an explicit declaration of a SOAP response
1575 // Contents of "calc.h":
1576 typedef double xsd__double;
1577 struct ns2__addResponse {xsd__double result;};
1578 int ns2__add(xsd__string a, xsd__double b, struct ns2__addResponse &r);
1581 The SOAP request and response messages are the same as before:
1588 <a xsi:type="xsd:string">1.0</a>
1589 <b xsi:type="xsd:string">2.0</b>
1596 The difference is that the service response is required to match the specified `addResponse` name and its namespace URI:
1602 <n:addResponse xmlns:n='urn:calc'>
1603 <result xsi:type="xsd:double">3.0</result>
1610 This use of a `struct` or `class` enables the adaptation of the default SOAP response element name and/or namespace URI when required.
1612 ### How to Specify Multiple Output Parameters {#multiple}
1614 The gSOAP `soapcpp2` tool compiler uses the convention that the
1615 **last parameter** of the function prototype declaration of a service operation in a header file
1616 is also the **only single output parameter** of the method.
1617 All other parameters are considered input parameters of the service operation. To specify a service operation
1618 with **multiple output parameters**, a `struct` or `class` must be declared for the service operation response, see
1619 also \ref response . The name of the `struct` or `class` must have a namespace prefix, just as the service method name. The fields of the `struct` or `class` are the output parameters of the service operation.
1620 Both the order of the input parameters in the function prototype and the order of the output parameters (the fields in the
1621 `struct` or `class`) is not significant. However, the SOAP 1.1 specification states that input and output parameters may be
1622 treated as having anonymous parameter names which requires a particular ordering, see Section \ref anonymous .
1624 ### Example {#example5}
1626 As an example, consider a hypothetical service operation `getNames` with a single input parameter `SSN`
1627 and two output parameters `first` and `last`. This can be specified as:
1630 // Contents of file "getNames.h":
1631 int ns3__getNames(char *SSN, struct ns3__getNamesResponse {char *first; char *last;} &r);
1634 The gSOAP `soapcpp2` tool takes this header file as input and generates source code for the function `soap_call_ns3__getNames`. When invoked by a client application, the proxy produces the SOAP request:
1639 <SOAP-ENV:Envelope ... xmlns:ns3="urn:names" ...>
1642 <SSN>999 99 9999</SSN>
1648 The response by a SOAP service:
1653 <m:getNamesResponse xmlns:m="urn:names">
1656 </m:getNamesResponse>
1661 where *`first`* and *`last`* are the output parameters of the `getNames` service operation of the service.
1663 As another example, consider a service operation `copy` with an input parameter and an output parameter with identical
1664 parameter names (this is not prohibited by the SOAP 1.1 protocol). This can be specified as well using a response `struct`:
1667 // Content of file "copy.h":
1668 int X_rox__copy_name(char *name, struct X_rox__copy_nameResponse {char *name;} &r);
1671 The use of a `struct` or `class` for the service operation response enables the declaration of service operations that have
1672 parameters that are passed both as input and output parameters.
1674 The gSOAP `soapcpp2` compiler takes the `copy.h` header file as input and generates the `soap_call_X_rox__copy_name` proxy. When invoked by a client application, the proxy produces the SOAP request:
1679 <SOAP-ENV:Envelope ... xmlns:X-rox="urn:copy" ...>
1688 The response by a SOAP copy service could be something like:
1693 <m:copy-nameResponse xmlns:m="urn:copy">
1695 </m:copy-nameResponse>
1700 The name will be parsed and decoded by the proxy and returned in the `name` field of the `struct X_rox__copy_nameResponse &r` parameter.
1702 ### How to Specify Output Parameters With struct/class Compound Data Types {#compound}
1704 If the single output parameter of a service operation is a complex data type such as a `struct` or `class` it is necessary to
1705 specify the response element of the service operation as a `struct` or `class` **at all times**.
1706 Otherwise, the output parameter will
1707 be considered the response element (!), because of the response element specification convention used by gSOAP,
1708 as discussed in \ref response .
1710 ### Example {#example6}
1712 This is best illustrated with an example. The Flighttracker service by ObjectSpace provides real time flight information for
1713 flights in the air. It requires an airline code and flight number as parameters.
1714 The service operation name is `getFlightInfo` and
1715 the method has two string parameters: the airline code and flight number, both of which must be encoded as *`xsd:string`* types.
1716 The method returns a `getFlightResponse` response element with a `return` output parameter that is of complex type
1717 `FlightInfo`. The type `FlightInfo` is represented by a `class` in the header file, whose field names correspond to
1718 the `FlightInfo` accessors:
1721 // Contents of file "flight.h":
1722 typedef char *xsd__string;
1723 class ns2__FlightInfo
1726 xsd__string airline;
1727 xsd__string flightNumber;
1728 xsd__string altitude;
1729 xsd__string currentLocation;
1730 xsd__string equipment;
1733 struct ns1__getFlightInfoResponse {ns2__FlightInfo return_;};
1734 int ns1__getFlightInfo(xsd__string param1, xsd__string param2, struct ns1__getFlightInfoResponse &r);
1737 The response element `ns1__getFlightInfoResponse` is explicitly declared and it has one field: `return_` of type
1738 `ns2__FlightInfo`. Note that `return_` has a trailing underscore to avoid a name clash with the `\return` keyword,
1739 see Section \ref idtrans for details on the translation of C++ identifiers to XML element names.
1741 The gSOAP `soapcpp2` compiler generates the `soap_call_ns1__getFlightInfo` proxy. Here is an example fragment of a client application that uses this proxy to request flight information:
1748 soap_call_ns1__getFlightInfo(&soap, "testvger.objectspace.com/soap/servlet/rpcrouter",
1749 "urn:galdemo:flighttracker", "UAL", "184", r);
1751 struct Namespace namespaces[] =
1753 {"SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/"},
1754 {"SOAP-ENC","http://schemas.xmlsoap.org/soap/encoding/"},
1755 {"xsi", "http://www.w3.org/2001/XMLSchema-instance"},
1756 {"xsd", "http://www.w3.org/2001/XMLSchema"},
1757 {"ns1", "urn:galdemo:flighttracker"},
1758 {"ns2", "http://galdemo.flighttracker.com"},
1763 When invoked by a client application, the proxy produces the SOAP request:
1767 POST /soap/servlet/rpcrouter HTTP/1.1
1768 Host: testvger.objectspace.com
1769 Content-Type: text/xml
1771 SOAPAction: "urn:galdemo:flighttracker"
1773 <?xml version="1.0" encoding="UTF-8"?>
1774 <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
1775 xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
1776 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1777 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
1778 xmlns:ns1="urn:galdemo:flighttracker"
1779 xmlns:ns2="http://galdemo.flighttracker.com"
1780 SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
1782 <ns1:getFlightInfo xsi:type="ns1:getFlightInfo">
1783 <param1 xsi:type="xsd:string">UAL</param1>
1784 <param2 xsi:type="xsd:string">184</param2>
1785 </ns1:getFlightInfo>
1787 </SOAP-ENV:Envelope>
1791 The Flighttracker service responds with:
1796 Date: Thu, 30 Aug 2001 00:34:17 GMT
1797 Server: IBM_HTTP_Server/1.3.12.3 Apache/1.3.12 (Win32)
1798 Set-Cookie: sesessionid=2GFVTOGC30D0LGRGU2L4HFA;Path=/
1799 Cache-Control: no-cache="set-cookie,set-cookie2"
1800 Expires: Thu, 01 Dec 1994 16:00:00 GMT
1802 Content-Type: text/xml; charset=utf-8
1803 Content-Language: en
1805 <?xml version="1.0" encoding="UTF-8"?>
1806 <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
1807 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1808 xmlns:xsd="http://www.w3.org/2001/XMLSchema">
1810 <ns1:getFlightInfoResponse xmlns:ns1="urn:galdemo:flighttracker"
1811 SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
1812 <return xmlns:ns2="http://galdemo.flighttracker.com" xsi:type="ns2:FlightInfo">
1813 <equipment xsi:type="xsd:string">A320</equipment>
1814 <airline xsi:type="xsd:string">UAL</airline>
1815 <currentLocation xsi:type="xsd:string">188 mi W of Lincoln, NE</currentLocation>
1816 <altitude xsi:type="xsd:string">37000</altitude>
1817 <speed xsi:type="xsd:string">497</speed>
1818 <flightNumber xsi:type="xsd:string">184</flightNumber>
1820 </ns1:getFlightInfoResponse>
1822 </SOAP-ENV:Envelope>
1826 The proxy returns the service response in variable `r` of type `struct ns1__getFlightInfoResponse` and this information can be displayed by the client application with the following code fragment:
1829 cout << r.return_.equipment << " flight " << r.return_.airline << r.return_.flightNumber
1830 << " traveling " << r.return_.speed << " mph " << " at " << r.return_.altitude
1831 << " ft, is located " << r.return_.currentLocation << endl;
1834 This code displays the service response as:
1836 A320 flight UAL184 traveling 497 mph at 37000 ft, is located 188 mi W of Lincoln, NE
1838 Note: the flight tracker service is no longer available since 9/11/2001. It is kept in the documentation as an example to illustrate the use of structs/classes and response types.
1840 ### How to Specify Anonymous Parameter Names {#anonymous}
1842 The SOAP RPC encoding protocol allows parameter names to be anonymous. That is, the name(s) of the output
1843 parameters of a service operation are not strictly required to match a client's view of the parameters names. Also, the
1844 input parameter names of a service operation are not strictly required to match a service's view of the parameter names.
1845 The gSOAP `soapcpp2` compiler can generate stub and skeleton
1846 routines that support anonymous parameters. Parameter names are implicitly
1847 anonymous by omitting the parameter names in the function prototype of the
1848 service operation. For example:
1851 // Contents of "calc.h":
1852 typedef double xsd__double;
1853 int ns2__add(xsd__string, xsd__double, xsd__double &);
1856 To make parameter names explicitly anonymous on the receiving side (client or service),
1857 the parameter names should start with an underscore (`_`) in the function prototype in the header file.
1862 // Contents of "calc.h":
1863 typedef double xsd__double;
1864 int ns2__add(xsd__string _a, xsd__double _b, xsd__double & _return);
1867 In this example, the `_a`, `_b`, and `_return` are anonymous parameters.
1868 As a consequence, the service response to a request made by a client created with gSOAP using this header file specification
1869 may include any name for the output parameter in the SOAP payload.
1870 The input parameters may also be anonymous. This affects the implementation of Web services in gSOAP
1871 and the matching of parameter names by the service.
1873 @warning when anonymous parameter names are used, the order of the parameters in the function prototype of a service operation is
1876 ### How to Specify a Method with No Input Parameters
1878 To specify a service operation that has no input parameters, just provide a function prototype with one parameter which is the output
1879 parameter (some C/C++ compilers will not compile and complain about an empty
1880 `struct`: use compile flag `-DWITH_NOEMPTYSTRUCT` to compile the generated code for these cases). This `struct` is generated by gSOAP to contain the SOAP request message. To fix this, provide one input
1881 parameter of type `void*` (gSOAP can not serialize `void*` data). For example:
1884 struct ns3__SOAPService
1894 char *methodNamespaceURI;
1895 char *serviceStatus;
1902 char *serverImplementation;
1904 struct ArrayOfSOAPService {struct ns3__SOAPService *__ptr; int __size;};
1905 int ns__getAllSOAPServices(void *_, struct ArrayOfSOAPService &_return);
1908 The `ns__getAllSOAPServices` method has one `void*` input parameter which is ignored by the serializer to produce the
1911 Most C/C++ compilers allow empty `struct`s and therefore the `void*` parameter is not required.
1913 ### How to Specify a Method with No Output Parameters
1915 To specify a service operation that has no output parameters, just define a function prototype with a response struct that is
1919 enum ns__event { off, on, stand_by };
1920 int ns__signal(enum ns__event in, struct ns__signalResponse { } *out);
1923 Since the response struct is empty, no output parameters are specified.
1925 Some SOAP resources refer to SOAP RPC with empty responses as **one way** SOAP messaging. However, we refer to one-way massaging
1926 by asynchronous explicit send and receive operations as described in Section \ref oneway1 . The latter view of one-way SOAP messaging is also in line with Basic Profile 1.0.
1928 ## How to Build SOAP/XML Web Services
1930 The gSOAP `soapcpp2` compiler generates **skeleton** routines in C++ source form for each of the service operations specified
1931 as function prototypes in the header file processed by the gSOAP `soapcpp2` compiler. The skeleton routines can be readily used to implement
1932 the service operations in a new SOAP Web service. The compound data types used by the input and output parameters of service operations
1933 must be declared in the header file, such as structs, classes, arrays, and pointer-based data structures (graphs) that are
1934 used as the data types of the parameters of a service operation. The gSOAP `soapcpp2` compiler automatically generates serializers and
1935 deserializers for the data types to enable the generated skeleton routines to encode and decode the contents of the parameters of
1936 the service operations. The gSOAP `soapcpp2` compiler also generates a service operation request dispatcher routine that will serve requests by
1937 calling the appropriate skeleton when the SOAP service application is installed as a CGI application on a Web server.
1939 ### Example {#example7}
1941 The following example specifies three service operations to be implemented by a new SOAP Web service:
1944 // Contents of file "calc.h":
1945 typedef double xsd__double;
1946 int ns__add(xsd__double a, xsd__double b, xsd__double &result);
1947 int ns__sub(xsd__double a, xsd__double b, xsd__double &result);
1948 int ns__sqrt(xsd__double a, xsd__double &result);
1951 The `add` and `sub` methods are intended to add and subtract two double floating point numbers stored in input parameters
1952 `a` and `b` and should return the result of the operation in the `result` output parameter. The `sqrt` method is
1953 intended to take the square root of input parameter `a` and to return the result in the output parameter `result`.
1954 The `xsd__double` type is recognized by the gSOAP `soapcpp2` compiler as the *`xsd:double`* XSD Schema data type.
1955 The use of `typedef` is a convenient way to associate primitive C types with primitive XML Schema data types.
1957 To generate the skeleton routines, the gSOAP `soapcpp2` compiler is invoked from the command line with:
1961 The compiler generates the skeleton routines for the `add`, `sub`, and `sqrt` service operations specified in the
1962 `calc.h` header file. The skeleton routines are respectively, `soap_serve_ns__add`, `soap_serve_ns__sub`, and
1963 `soap_serve_ns__sqrt` and saved in the file `soapServer.cpp`. The generated file `soapC.cpp` contains serializers
1964 and deserializers for the skeleton. The compiler also generates a service dispatcher: the `soap_serve` function handles
1965 client requests on the standard input stream and dispatches the service operation requests to the appropriate skeletons to serve the
1966 requests. The skeleton in turn calls the service operation implementation function. The function prototype of the service operation
1967 implementation function is specified in the header file that is input to the gSOAP `soapcpp2` compiler.
1969 Here is an example Calculator service application that uses the generated `soap_serve` routine to handle client requests:
1972 // Contents of file "calc.cpp":
1974 #include <math.h> // for sqrt()
1977 return soap_serve(soap_new()); // use the service operation request dispatcher
1979 // Implementation of the "add" service operation:
1980 int ns__add(struct soap *soap, double a, double b, double &result)
1985 // Implementation of the "sub" service operation:
1986 int ns__sub(struct soap *soap, double a, double b, double &result)
1991 // Implementation of the "sqrt" service operation:
1992 int ns__sqrt(struct soap *soap, double a, double &result)
2000 return soap_receiver_fault(soap, "Square root of negative number", "I can only take the square root of a non-negative number");
2002 // As always, a namespace mapping table is needed:
2003 struct Namespace namespaces[] =
2004 { // {"ns-prefix", "ns-name"}
2005 {"SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/"},
2006 {"SOAP-ENC", "http://schemas.xmlsoap.org/soap/encoding/"},
2007 {"xsi", "http://www.w3.org/2001/XMLSchema-instance"},
2008 {"xsd", "http://www.w3.org/2001/XMLSchema"},
2009 {"ns", "urn:simple-calc"}, // bind "ns" namespace prefix
2014 Note that the service operations have an extra input parameter which is a pointer to the gSOAP runtime context.
2015 The implementation of the service operations MUST return a SOAP error code. The code `SOAP_OK` denotes success, while
2016 `SOAP_FAULT` denotes an exception with details that can be defined by the user. The exception description can be assigned to
2017 the `soap->fault->faultstring` string and details can be assigned to the
2018 `soap->fault->detail` string. This is SOAP 1.1 specific. SOAP 1.2 requires
2019 the `soap->fault->SOAP_ENV__Reason` and the
2020 `soap->fault->SOAP_ENV__Detail` strings to be assigned.
2021 Better is to use the
2022 `soap_receiver_fault` function that allocates a fault struct and sets the SOAP Fault string and details
2023 regardless of the SOAP 1.1 or SOAP 1.2 version used. The `soap_receiver_fault` function returns
2024 `SOAP_FAULT`, i.e. an application-specific fault. The fault exception will be passed on to the client of this service.
2026 This service application can be readily installed as a CGI application. The service description would be:
2028 * Endpoint URL: the URL of the CGI application
2030 * SOAP action: "" (2 quotes)
2032 * Remote method namespace: *`urn:simple-calc`*
2034 * Remote method name: *`add`*
2035 * Input parameters: *`a`* of type *`xsd:double`* and *`b`* of type *`xsd:double`*
2036 * Output parameter: *`result`* of type *`xsd:double`*
2038 * Remote method name: *`sub`*
2039 * Input parameters: *`a`* of type *`xsd:double`* and *`b`* of type *`xsd:double`*
2040 * Output parameter: *`result`* of type *`xsd:double`*
2042 * Remote method name: *`sqrt`*
2043 * Input parameter: *`a`* of type *`xsd:double`*
2044 * Output parameter: *`result`* of type *`xsd:double`* or a SOAP Fault
2046 The `soapcpp2` compile generates a WSDL file for this service, see Section \ref wsdl .
2048 Unless the CGI application inspects and checks the environment variable `SOAPAction` which contains the SOAP action request by
2049 a client, the SOAP action is ignored by the CGI application. SOAP actions are specific to the SOAP protocol and provide a means
2050 for routing requests and for security reasons (e.g. firewall software can inspect SOAP action headers to grant or deny the
2051 SOAP request. Note that this requires the SOAP service to check the SOAP action header as well to match it with the service operation.)
2053 The header file input to the gSOAP `soapcpp2` compiler does not need to be modified to generate client stubs for accessing this
2054 service. Client applications can be developed by using the same header file as for which the service application
2055 was developed. For example, the `soap_call_ns__add` stub routine is available from the `soapClient.cpp` file after invoking
2056 the gSOAP `soapcpp2` compiler on the `calc.h` header file. As a result, client and service applications can be developed without
2057 the need to know the details of the SOAP encoding used.
2063 * Win32 builds need winsock2 (MS Visual C++ "ws2_32.lib")
2064 To do this in Visual C++ 6.0, go to "Project", "settings", select the "Link"
2065 tab (the project file needs to be selected in the file view) and add
2066 "`ws2_32.lib`" to the "`Object/library modules`" entry.
2069 * Use files with extension .cpp only (don't mix .c with .cpp).
2072 * Turn pre-compiled headers off.
2075 * When creating a new project, you can specify a custom build step to automatically invoke the gSOAP `soapcpp2` compiler on a gSOAP header file. In this way you can incrementally build a new service by adding new operations and data types to the header file. To specify a custom build step, select the "Project" menu item "Settings" and select the header file in the File view pane. Select the "Custom Build" tab and enter '`soapcpp2.exe "$(inputPath)"`' in the "Command" pane. Enter '`soapStub.h soapH.h soapC.cpp soapClient.cpp soapServer.cpp`'. Don't forget to add the `soapXYZProxy.h soapXYZObject.h` files that are generated for C++ class proxies and server objects named XYZ. Click "OK". Run `soapcpp2` once to generate these files (you can simply do this by selecting your header file and select "Compile"). Add the files to your project. Each time you make a change to the header file, the project sources are updated automatically.
2078 * You may want to use the WinInet interface available in the `mod_gsoap` directory of the gSOAP package to simplify Internet access and deal with encryption, proxies, and authentication. API instructions are included in the source.
2081 * For the PocketPC, run the `wsdl2h` WSDL parser with option `-s` to prevent the generation of STL code. In addition, `time_t` serialization is not supported, which means that you should add the following line to `typemap.dat` indicating a mapping of `xsd__dateTime` to `char*`: *`xsd__dateTime = | char* | char*`*.
2085 ### How to Create a Stand-Alone Server {#stand-alone}
2087 The deployment of a Web service as a CGI application is an easy means to
2088 provide your service on the Internet. However, the performance of CGI is not
2089 great. Also, gSOAP services can be run as stand-alone services on any port by
2090 utilizing the built-in HTTP and TCP/IP stacks. However, the preferred
2091 mechanism to deploy a service is through an Apache module or IIS module. These
2092 servers and modules are designed for server load balancing and access control.
2094 To create a stand-alone service, only the `main` routine of the service needs to be modified as follows. Instead of just calling the
2095 `soap_serve` routine, the `main` routine is changed into:
2101 int m, s; // master and slave sockets
2103 m = soap_bind(&soap, "machine.genivia.com", 18083, 100);
2105 soap_print_fault(&soap, stderr);
2108 fprintf(stderr, "Socket connection successful: master socket = %d\n", m);
2109 for (int i = 1; ; i++)
2111 s = soap_accept(&soap);
2114 soap_print_fault(&soap, stderr);
2117 fprintf(stderr, "%d: accepted connection from IP=%d.%d.%d.%d socket=%d", i,
2118 (soap.ip>>24)&0xFF, (soap.ip>>16)&0xFF, (soap.ip>>8)&0xFF, soap.ip&0xFF, s);
2119 if (soap_serve(&soap) != SOAP_OK) // process RPC request
2120 soap_print_fault(&soap, stderr); // print error
2121 fprintf(stderr, "request served\n");
2122 soap_destroy(&soap); // clean up class instances
2123 soap_end(&soap); // clean up everything and close socket
2126 soap_done(&soap); // close master socket and detach context
2130 The `soap_serve` dispatcher handles one request or multiple requests when HTTP keep-alive is enabled (with the `SOAP_IO_KEEPALIVE` flag see Section \ref keepalive ).
2132 The gSOAP functions that are frequently used for server-side coding are:
2134 * `soap_new()` Allocates and Initializes gSOAP context
2136 * `soap_init(struct soap *soap)` Initializes a stack-allocated gSOAP context (required once)
2138 * `soap_bind(struct soap *soap, char *host, int port, int backlog)` Returns master socket (backlog = max. queue
2140 * size for requests). When `host==NULL`: host is the machine on which the service runs
2142 * `soap_accept(struct soap *soap)` Returns slave socket
2144 * `soap_end(struct soap *soap)` Clean up deserialized data (except class instances) and temporary data
2146 * `soap_free_temp(struct soap *soap)` Clean up temporary data only
2148 * `soap_destroy(struct soap *soap)` Clean up deserialized class instances (note: this function will be renamed with option `-n`
2150 * `soap_done(struct soap *soap)` Reset and detach context: close master/slave sockets and remove callbacks
2152 * `soap_free(struct soap *soap)` Detach and deallocate context (`soap_new`())
2154 The *host* name in `soap_bind` may be NULL to indicate that the current host should be used.
2156 The `soap.accept_timeout` context attribute of the gSOAP runtime context specifies the timeout value for a non-blocking
2157 `soap_accept(&soap)` call. See Section \ref timeout for more details on timeout management.
2159 See Section \ref memory for more details on memory management.
2161 A client application connects to this stand-alone service with the endpoint
2162 `machine.genivia.com:18083`.
2163 A client may use the `http://` prefix. When absent, no HTTP header is sent
2164 and no HTTP-based information will be communicated to the service.
2166 ### How to Create a Multi-Threaded Stand-Alone Service {#mt}
2168 Stand-alone multi-threading a Web Service is essential when the response times for handling requests by the service are (potentially) long or when keep-alive is enabled, see Section \ref keepalive .
2169 In case of long response times, the latencies introduced by the unrelated
2170 requests may become prohibitive for a successful deployment of a stand-alone
2171 service. When HTTP keep-alive is enabled, a client may not close the socket on
2172 time, thereby preventing other clients from connecting.
2174 However, the preferred mechanism to deploy a service is through an Apache
2175 module or IIS module. These servers and modules are designed for server load
2176 balancing and access control.
2178 The following example illustrates the use of threads to improve the quality of service by handling new requests in separate threads:
2182 #include <pthread.h>
2183 #define BACKLOG (100) // Max. request backlog
2184 int main(int argc, char **argv)
2188 if (argc < 2) // no args: assume this is a CGI application
2190 soap_serve(&soap); // serve request, one thread, CGI style
2191 soap_destroy(&soap); // dealloc C++ data
2192 soap_end(&soap); // dealloc data and clean up
2196 soap.send_timeout = 10; // 10 seconds max socket delay
2197 soap.recv_timeout = 10; // 10 seconds max socket delay
2198 soap.accept_timeout = 3600; // server stops after 1 hour of inactivity
2199 soap.max_keep_alive = 100; // max keep-alive sequence
2200 void *process_request(void*);
2203 int port = atoi(argv[1]); // first command-line arg is port
2205 m = soap_bind(&soap, NULL, port, BACKLOG);
2206 if (!soap_valid_socket(m))
2208 fprintf(stderr, "Socket connection successful %d\n", m);
2211 s = soap_accept(&soap);
2212 if (!soap_valid_socket(s))
2216 soap_print_fault(&soap, stderr);
2219 fprintf(stderr, "server timed out\n");
2222 fprintf(stderr, "Thread %d accepts socket %d connection from IP %d.%d.%d.%d\n", i, s, (soap.ip>>24)&0xFF,
2223 (soap.ip>>16)&0xFF, (soap.ip>>8)&0xFF, soap.ip&0xFF);
2224 tsoap = soap_copy(&soap); // make a safe copy
2227 pthread_create(&tid, NULL, (void*(*)(void*))process_request, (void*)tsoap);
2230 soap_done(&soap); // detach soap struct
2233 void *process_request(void *soap)
2235 pthread_detach(pthread_self());
2236 soap_serve((struct soap*)soap);
2237 soap_destroy((struct soap*)soap); // dealloc C++ data
2238 soap_end((struct soap*)soap); // dealloc data and clean up
2239 soap_done((struct soap*)soap); // detach soap struct
2245 Note: the code does not wait for threads to join the main thread upon program termination.
2247 The `soap_serve` dispatcher handles one request or multiple requests when
2248 HTTP keep-alive is set with `SOAP_IO_KEEPALIVE`. The
2249 `soap.max_keep_alive` value can be set to the maximum keep-alive calls
2250 allowed, which is important to avoid a client from holding a thread
2251 indefinitely. The send and receive timeouts are set to avoid (intentionally)
2252 slow clients from holding a socket connection too long. The accept timeout is used
2253 to let the server terminate automatically after a period of inactivity.
2255 The following example uses a pool of servers to limit the machine's resource utilization:
2259 #include <pthread.h>
2260 #define BACKLOG (100) // Max. request backlog
2261 #define MAX_THR (10) // Max. threads to serve requests
2262 int main(int argc, char **argv)
2266 if (argc < 2) // no args: assume this is a CGI application
2268 soap_serve(&soap); // serve request, one thread, CGI style
2269 soap_destroy(&soap); // dealloc C++ data
2270 soap_end(&soap); // dealloc data and clean up
2274 struct soap *soap_thr[MAX_THR]; // each thread needs a runtime context
2275 pthread_t tid[MAX_THR];
2276 int port = atoi(argv[1]); // first command-line arg is port
2279 m = soap_bind(&soap, NULL, port, BACKLOG);
2280 if (!soap_valid_socket(m))
2282 fprintf(stderr, "Socket connection successful %d\n", m);
2283 for (i = 0; i < MAX_THR; i++)
2287 for (i = 0; i < MAX_THR; i++)
2289 s = soap_accept(&soap);
2290 if (!soap_valid_socket(s))
2294 soap_print_fault(&soap, stderr);
2299 fprintf(stderr, "Server timed out\n");
2303 fprintf(stderr, "Thread %d accepts socket %d connection from IP %d.%d.%d.%d\n", i, s, (soap.ip>>24)&0xFF,
2304 (soap.ip>>16)&0xFF, (soap.ip>>8)&0xFF, soap.ip&0xFF);
2305 if (!soap_thr[i]) // first time around
2307 soap_thr[i] = soap_copy(&soap);
2309 exit(1); // could not allocate
2311 else // recycle soap context
2313 pthread_join(tid[i], NULL);
2314 fprintf(stderr, "Thread %d completed\n", i);
2315 soap_destroy(soap_thr[i]); // deallocate C++ data of old thread
2316 soap_end(soap_thr[i]); // deallocate data of old thread
2318 soap_thr[i]->socket = s; // new socket fd
2319 pthread_create(&tid[i], NULL, (void*(*)(void*))soap_serve, (void*)soap_thr[i]);
2322 for (i = 0; i < MAX_THR; i++)
2325 soap_done(soap_thr[i]); // detach context
2326 free(soap_thr[i]); // free up
2333 The following functions can be used to setup a gSOAP runtime context (`struct soap`):
2335 * `soap_init(struct soap *soap)` Initializes a runtime context (required only once)
2337 * `struct soap *soap_new()` Allocates, initializes, and returns a pointer to a runtime context
2339 * `struct soap *soap_copy(struct soap *soap)` Allocates a new runtime context and copies a context (deep copy, i.e. the new context does not share any data with the other context)
2341 the argument context such that the new context does not share data with the argument context
2342 * `soap_done(struct soap *soap)` Reset, close communications, and remove callbacks
2344 A new context is initiated for each thread to guarantee exclusive access
2345 to runtime contexts.
2347 For clean termination of the server, the master socket can be closed and callbacks removed with `soap_done(struct soap *soap)`.
2349 The advantage of the code shown above is that the machine cannot be overloaded with requests, since the number of active services is limited. However, threads are still started and terminated. This overhead can be eliminated using a queue of requests (open sockets) as is shown in the code below.
2353 #include <pthread.h>
2354 #define BACKLOG (100) // Max. request backlog
2355 #define MAX_THR (10) // Size of thread pool
2356 #define MAX_QUEUE (1000) // Max. size of request queue
2357 SOAP_SOCKET queue[MAX_QUEUE]; // The global request queue of sockets
2358 int head = 0, tail = 0; // Queue head and tail
2359 void *process_queue(void*);
2360 int enqueue(SOAP_SOCKET);
2361 SOAP_SOCKET dequeue();
2362 pthread_mutex_t queue_cs;
2363 pthread_cond_t queue_cv;
2364 int main(int argc, char **argv)
2368 if (argc < 2) // no args: assume this is a CGI application
2370 soap_serve(&soap); // serve request, one thread, CGI style
2371 soap_destroy(&soap); // dealloc C++ data
2372 soap_end(&soap); // dealloc data and clean up
2376 struct soap *soap_thr[MAX_THR]; // each thread needs a runtime context
2377 pthread_t tid[MAX_THR];
2378 int port = atoi(argv[1]); // first command-line arg is port
2381 m = soap_bind(&soap, NULL, port, BACKLOG);
2382 if (!soap_valid_socket(m))
2384 fprintf(stderr, "Socket connection successful %d\n", m);
2385 pthread_mutex_init(&queue_cs, NULL);
2386 pthread_cond_init(&queue_cv, NULL);
2387 for (i = 0; i < MAX_THR; i++)
2389 soap_thr[i] = soap_copy(&soap);
2390 fprintf(stderr, "Starting thread %d\n", i);
2391 pthread_create(&tid[i], NULL, (void*(*)(void*))process_queue, (void*)soap_thr[i]);
2395 s = soap_accept(&soap);
2396 if (!soap_valid_socket(s))
2400 soap_print_fault(&soap, stderr);
2405 fprintf(stderr, "Server timed out\n");
2409 fprintf(stderr, "Thread %d accepts socket %d connection from IP %d.%d.%d.%d\n", i, s, (soap.ip>>24)&0xFF, (soap.ip>>16)&0xFF, (soap.ip>>8)&0xFF, soap.ip&0xFF);
2410 while (enqueue(s) == SOAP_EOM)
2413 for (i = 0; i < MAX_THR; i++)
2415 while (enqueue(SOAP_INVALID_SOCKET) == SOAP_EOM)
2418 for (i = 0; i < MAX_THR; i++)
2420 fprintf(stderr, "Waiting for thread %d to terminate... ", i);
2421 pthread_join(tid[i], NULL);
2422 fprintf(stderr, "terminated\n");
2423 soap_done(soap_thr[i]);
2426 pthread_mutex_destroy(&queue_cs);
2427 pthread_cond_destroy(&queue_cv);
2432 void *process_queue(void *soap)
2434 struct soap *tsoap = (struct soap*)soap;
2437 tsoap->socket = dequeue();
2438 if (!soap_valid_socket(tsoap->socket))
2441 soap_destroy(tsoap);
2443 fprintf(stderr, "served\n");
2447 int enqueue(SOAP_SOCKET sock)
2449 int status = SOAP_OK;
2451 pthread_mutex_lock(&queue_cs);
2453 if (next >= MAX_QUEUE)
2461 pthread_cond_signal(&queue_cv);
2463 pthread_mutex_unlock(&queue_cs);
2466 SOAP_SOCKET dequeue()
2469 pthread_mutex_lock(&queue_cs);
2470 while (head == tail)
2471 pthread_cond_wait(&queue_cv, &queue_cs);
2472 sock = queue[head++];
2473 if (head >= MAX_QUEUE)
2475 pthread_mutex_unlock(&queue_cs);
2480 Note: the `plugin/threads.h` and `plugin/threads.c` code can be used
2481 for a portable implementation. Instead of POSIX calls, use `MUTEX_LOCK`,
2482 `MUTEX_UNLOCK`, and `COND_WAIT`. These are wrappers for Win API calls
2485 ### How to Pass Application Data to Service Methods
2487 The `void *soap.user` field can be used to pass application data to
2488 service methods. This field should be set before the `soap_serve()` call.
2489 The service method can access this field to use the application-dependent data.
2490 The following example shows how a non-static database handle is initialized and
2491 passed to the service methods:
2496 database_handle_type database_handle;
2498 soap.user = (void*)database_handle;
2500 soap_serve(&soap); // call the service operation dispatcher to handle request
2503 int ns__myMethod(struct soap *soap, ...)
2505 fetch((database_handle_type*)soap->user); // get data
2511 Another way to pass application data around in a more organized way is accomplished with plugins, see Section \ref plugins .
2513 ### Web Service Implementation Aspects
2515 The same client header file specification issues apply to the specification and implementation of a SOAP Web service. Refer to
2518 * \ref namespace for namespace considerations.
2520 * \ref encoding for an explanation on how to change the encoding of the primitive types.
2522 * \ref response for a discussion on how the response element format can be controlled.
2524 * \ref multiple for details on how to pass multiple output parameters from a service operation.
2526 * \ref compound for passing complex data types as output parameters.
2528 * \ref anonymous for anonymizing the input and output parameter names.
2531 ### How to Generate C++ Server Object Classes {#object}
2533 Server object classes for C++ server applications are automatically generated
2534 by the gSOAP `soapcpp2` compiler.
2536 There are two modes for generating classes. Use `soapcpp2` option `-i`
2537 (or `-j`) to generate improved class definitions where the class' member
2538 functions are the service methods.
2540 The older examples (without the use of `soapcpp2` option `-i` and
2541 `-j`) use a C-like approach with globally defined service methods,
2542 which is illustated here with a calculator example:
2545 // Content of file "calc.h":
2546 //gsoap ns service name: Calculator
2547 //gsoap ns service protocol: SOAP
2548 //gsoap ns service style: rpc
2549 //gsoap ns service encoding: encoded
2550 //gsoap ns service location: http://www.cs.fsu.edu/~engelen/calc.cgi
2551 //gsoap ns schema namespace: urn:calc
2552 //gsoap ns service method-action: add ""
2553 int ns__add(double a, double b, double &result);
2554 int ns__sub(double a, double b, double &result);
2555 int ns__mul(double a, double b, double &result);
2556 int ns__div(double a, double b, double &result);
2559 The first three directives provide the service name which is used to name the service class, the service location (endpoint), and
2560 the schema. The fourth directive defines the optional SOAPAction for the method, which is a string associated with SOAP 1.1 operations.
2561 Compilation of this header file with `soapcpp2 -i` creates a new file `soapCalculatorObject.h` with the
2566 class CalculatorObject : public soap
2568 Calculator() { ... };
2569 ~Calculator() { ... };
2570 int serve() { return soap_serve(\this); };
2574 This generated server object class can be included into a server application together with the generated namespace table as shown in this example:
2577 #include "soapCalculatorObject.h" // get server object
2578 #include "Calculator.nsmap" // get namespace bindings
2582 return c.serve(); // calls `soap_serve` to serve as CGI application (using stdin/out)
2584 // C-style global functions implement server operations (soapcpp2 w/o option -i)
2585 int ns__add(struct soap *soap, double a, double b, double &result)
2590 ... sub(), mul(), and div() implementations ...
2593 You can use `soapcpp2` option `-n` together with `-p` to create a
2594 local namespace table to avoid link conflict when you need to combine multiple
2595 tables and/or multiple servers, see also Sections \ref options
2596 and \ref dylibs , and you can use a C++ code `namespace` to create a
2597 namespace qualified server object class, see Section \ref codenamespace .
2599 The example above serves requests over stdin/out. Use the bind and accept calls
2600 to create a stand-alone server to service inbound requests over sockets, see
2601 also \ref stand-alone .
2603 A better alternative is to use the `soapcpp2` option `-i`. The C++ proxy and server objects are
2604 derived from the soap context struct, which simplifies the proxy invocation and
2605 service operation implementations.
2607 Compilation of the above header file with the gSOAP compiler `soapcpp2` option `-i` creates new files `soapCalculatorService.h` and `soapCalculatorService.cpp` (rather than the C-style `soapServer.cpp`).
2609 This generated server object class can be included into a server application together with the generated namespace table as shown in this example:
2612 #include "soapCalculatorService.h" // get server object
2613 #include "Calculator.nsmap" // get namespace bindings
2616 soapCalculatorService c;
2617 return c.serve(); // calls `soap_serve` to serve as CGI application (using stdin/out)
2619 // The 'add' service method (soapcpp2 w/ option -i)
2620 int soapCalculatorService::add(double a, double b, double &result)
2625 ... sub(), mul(), and div() implementations ...
2628 Note that the service operation does not need a prefix (`ns__`) and there
2629 is no soap context struct passed to the service operation since the service
2630 object itself is the context (it is derived from the soap struct).
2632 ### How to Chain C++ Server Classes to Accept Messages on the Same Port {#chaining}
2634 When combining multiple services into one application, you can run `wsdl2h`
2635 on multiple WSDLs to generate the single all-inclusive service definitions
2636 header file. This header file is then processed with `soapcpp2`, for
2637 example to generate server class objects with option `-i` and `-q` to separate the service codes with C++ namespaces, see Section \ref codenamespace .
2639 This works well, but the problem is that we end up with multiple classes, each
2640 for a collection of service operations the class is supposed to implement. But
2641 what if we need to provide one endpoint port for all services and operations?
2642 In this case invoking the server object's `serve` method is not sufficient, since only one
2643 service can accept requests while we want multiple services to listen to the
2646 The approach is to chain the service dispatchers, as shown below:
2649 #include "AbcABCService.h"
2650 #include "UvwUVWService.h"
2651 #include "XyzXYZService.h"
2652 #include "envH.h" // include this file last, if this file is needed
2654 Abc::soapABCService abc; // generated with soapcpp2 -i -S -qAbc
2655 Uvw::soapUVWService uvw; // generated with soapcpp2 -i -S -qUvw
2656 Xyz::soapXYZService xyz; // generated with soapcpp2 -i -S -qXyz
2658 abc.bind(NULL, 8080, 100);
2661 // when using SSL: ssl_accept(&abc);
2663 if (soap_begin_serve(&abc)) // available in 2.8.2 and later
2664 abc.soap_stream_fault(std::cerr);
2665 else if (abc.dispatch() == SOAP_NO_METHOD)
2667 soap_copy_stream(&uvw, &abc);
2668 soap_free_stream(&abc); // abc no longer uses this stream
2669 if (uvw.dispatch() == SOAP_NO_METHOD)
2671 soap_copy_stream(&xyz, &uvw);
2672 soap_free_stream(&uvw); // uvw no longer uses this stream
2675 soap_send_fault(&xyz); // send fault to client
2676 xyz.soap_stream_fault(std::cerr);
2682 soap_send_fault(&uvw); // send fault to client
2683 uvw.soap_stream_fault(std::cerr);
2688 abc.soap_stream_fault(std::cerr);
2693 The `dispatch` method parses the SOAP/XML request and invokes the service
2694 operations, unless there is no matching operation and `SOAP_NO_METHOD` is
2695 returned. The `soap_copy_stream` ensures that the service object uses the
2696 currently open socket. The copied streams are freed with
2697 `soap_free_stream`. Do not enable keep-alive support, as the socket may
2698 stay open indefinitely afterwards as a consequence. Also, the `dispatch`
2699 method does not send a fault to the client, which has to be explicitly done
2700 with the `soap_send_fault` operation when an error occurs.
2702 In this way, multiple services can be chained to accept messages on the same port. This approach also works with SSL for HTTPS services.
2704 However, this approach is not recommended for certain plugins, because plugins
2705 must be registered with all service objects and some plugins require state
2706 information to be used across the service objects, which will add significantly
2709 When plugin complications arise, it is best to have all services share the same
2710 context. This means that `soapcpp2` option `-j` should be used instead of option `-i`.
2711 Each service class has a pointer member to a soap struct
2712 context. This member pointer should point to the same soap context.
2714 With option `-j` and `-q` the code to chain the services is as follows, based on a single `struct soap` engine context:
2717 #include "AbcABCService.h"
2718 #include "UvwUVWService.h"
2719 #include "XyzXYZService.h"
2720 #include "envH.h" // include this file last, if it is needed
2722 struct soap *soap = soap_new();
2723 Abc::soapABCService abc(soap); // generated with soapcpp2 -j -S -qAbc
2724 Uvw::soapUVWService uvw(soap); // generated with soapcpp2 -j -S -qUvw
2725 Xyz::soapXYZService xyz(soap); // generated with soapcpp2 -j -S -qXyz
2727 soap_bind(soap, NULL, 8080, 100);
2729 if (soap_begin_serve(soap))
2731 else if (abc.dispatch() == SOAP_NO_METHOD)
2733 if (uvw.dispatch() == SOAP_NO_METHOD)
2735 if (xyz.dispatch() == SOAP_NO_METHOD)
2741 soap_free(soap); // safe to delete when abc, uvw, xyz are also deleted
2745 ### How to Generate WSDL Service Descriptions {#wsdl}
2747 The gSOAP stub and skeleton compiler `soapcpp2` generates WSDL (Web Service Description Language) service descriptions and XML Schema files
2748 when processing a header file. The tool produces one WSDL file for a set of service operations, which must be provided. The names of the function
2749 prototypes of the service operations must use the same namespace prefix and the namespace prefix is used to name the WSDL file. If
2750 multiple namespace prefixes are used to define service operations, multiple WSDL files will be created and each file describes the set
2751 of service operations belonging to a namespace prefix.
2753 In addition to the generation of the *`ns.wsdl`* file, a file with a namespace mapping table is generated by the gSOAP
2754 compiler. An example mapping table is shown below:
2757 struct Namespace namespaces[] =
2759 {"SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/"},
2760 {"SOAP-ENC", "http://schemas.xmlsoap.org/soap/encoding/"},
2761 {"xsi", "http://www.w3.org/2001/XMLSchema-instance", \"http://www.w3.org/*/XMLSchema-instance"},
2762 {"xsd", "http://www.w3.org/2001/XMLSchema", \"http://www.w3.org/*/XMLSchema"},
2763 {"ns", "http://tempuri.org"},
2768 This file can be incorporated in the
2769 client/service application, see Section \ref nstable for details on namespace mapping tables.
2771 To deploy a Web service, copy the compiled CGI service application to the designated CGI directory of your Web server.
2772 Make sure the proper file permissions are set (*`chmod 755 calc.cgi`* for Unix/Linux).
2773 You can then publish the WSDL file on the Web by placing it in the appropriate Web server directory.
2775 The gSOAP `soapcpp2` compiler also generates XML Schema files for all C/C++
2776 complex types (e.g. `struct`s and `class`es) when declared with a namespace prefix.
2777 These files are named *`ns.xsd`*, where *`ns`* is the namespace prefix used in the declaration of the complex type.
2778 The XML Schema files do not have to be published as the WSDL file already contains the appropriate XML Schema definitions.
2780 To customize the WSDL output, it is essential to use `//gsoap` directives to declare the service name, the endpoint port, and namespace:
2783 //gsoap ns service name: example
2784 //gsoap ns servire port: http://www.mydomain.com/example
2785 //gsoap ns service namespace: urn:example
2788 These are minimal settings. More details and settings for the service operations should be declared as well. See Section \ref directives for more details.
2790 ### Example {#example8}
2792 For example, suppose the following methods are defined in the header file:
2795 typedef double xsd__double;
2796 int ns__add(xsd__double a, xsd__double b, xsd__double &result);
2797 int ns__sub(xsd__double a, xsd__double b, xsd__double &result);
2798 int ns__sqrt(xsd__double a, xsd__double &result);
2801 Then, one WSDL file will be created with the file name *`ns.wsdl`* that describes all three service operations:
2805 <?xml version="1.0" encoding="UTF-8"?>
2806 <definitions name="Service"
2807 xmlns="http://schemas.xmlsoap.org/wsdl/"
2808 targetNamespace="http://location/Service.wsdl"
2809 xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
2810 xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
2811 xmlns:SOAP="http://schemas.xmlsoap.org/wsdl/soap/"
2812 xmlns:WSDL="http://schemas.xmlsoap.org/wsdl/"
2813 xmlns:xsd="http://www.w3.org/2000/10/XMLSchema"
2814 xmlns:tns="http://location/Service.wsdl"
2815 xmlns:ns="http://tempuri.org">
2818 xmlns="http://www.w3.org/2000/10/XMLSchema"
2819 targetNamespace="http://tempuri.org"
2820 xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
2821 xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
2822 <complexType name="addResponse">
2824 <element name="result" type="double" minOccurs="0" maxOccurs="1"/>
2826 <anyAttribute namespace="##other"/>
2828 <complexType name="subResponse">
2830 <element name="result" type="double" minOccurs="0" maxOccurs="1"/>
2832 <anyAttribute namespace="##other"/>
2834 <complexType name="sqrtResponse">
2836 <element name="result" type="double" minOccurs="0" maxOccurs="1"/>
2838 <anyAttribute namespace="##other"/>
2842 <message name="addRequest">
2843 <part name="a" type="xsd:double"/>
2844 <part name="b" type="xsd:double"/>
2846 <message name="addResponse">
2847 <part name="result" type="xsd:double"/>
2849 <message name="subRequest">
2850 <part name="a" type="xsd:double"/>
2851 <part name="b" type="xsd:double"/>
2853 <message name="subResponse">
2854 <part name="result" type="xsd:double"/>
2856 <message name="sqrtRequest">
2857 <part name="a" type="xsd:double"/>
2859 <message name="sqrtResponse">
2860 <part name="result" type="xsd:double"/>
2862 <portType name="ServicePortType">
2863 <operation name="add">
2864 <input message="tns:addRequest"/>
2865 <output message="tns:addResponse"/>
2867 <operation name="sub">
2868 <input message="tns:subRequest"/>
2869 <output message="tns:subResponse"/>
2871 <operation name="sqrt">
2872 <input message="tns:sqrtRequest"/>
2873 <output message="tns:sqrtResponse"/>
2876 <binding name="ServiceBinding" type="tns:ServicePortType">
2877 <SOAP:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
2878 <operation name="add">
2879 <SOAP:operation soapAction="http://tempuri.org#add"/>
2881 <SOAP:body use="encoded" namespace="http://tempuri.org"
2882 encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
2885 <SOAP:body use="encoded" namespace="http://tempuri.org"
2886 encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
2889 <operation name="sub">
2890 <SOAP:operation soapAction="http://tempuri.org#sub"/>
2892 <SOAP:body use="encoded" namespace="http://tempuri.org"
2893 encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
2896 <SOAP:body use="encoded" namespace="http://tempuri.org"
2897 encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
2900 <operation name="sqrt">
2901 <SOAP:operation soapAction="http://tempuri.org#sqrt"/>
2903 <SOAP:body use="encoded" namespace="http://tempuri.org"
2904 encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
2907 <SOAP:body use="encoded" namespace="http://tempuri.org"
2908 encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
2912 <service name="Service">
2913 <port name="ServicePort" binding="tns:ServiceBinding">
2914 <SOAP:address location="http://location/Service.cgi"/>
2921 The above uses all default settings for the service name, port, and namespace which should be set in the header file with `//gsoap` directives (Section \ref directives ).
2923 ### How to Use Client Functionalities Within a Service
2925 A gSOAP service implemented with CGI may make direct client calls to other services from within its service operations, without setting up a new context. A stand-alone service application must setup a new soap struct context, e.g. using `soap_copy` and delete it after the call.
2927 The server-side client call is best illustrated with an example. The following example is a
2928 more sophisticated example that combines the functionality of two Web services
2929 into one new SOAP Web service. The service provides a currency-converted stock
2930 quote. To serve a request, the service in turn requests the stock quote and
2931 the currency-exchange rate from two XMethods services (these services are no longer available by XMethods, but are used here as an example).
2933 In addition to being a client of two XMethods services, this service
2934 application can also be used as a client of itself to test the implementation.
2935 As a client invoked from the command-line, it will return a currency-converted
2936 stock quote by connecting to a copy of itself installed as a CGI application on
2937 the Web to retrieve the quote after which it will print the quote on the
2940 The header file input to the gSOAP `soapcpp2` compiler is given below. The example is for illustrative purposes only (the XMethods services are not operational):
2943 // Contents of file "quotex.h":
2944 int ns1__getQuote(char *symbol, float &result); // XMethods delayed stock quote service service operation
2945 int ns2__getRate(char *country1, char *country2, float &result); // XMethods currency-exchange service service operation
2946 int ns3__getQuote(char *symbol, char *country, float &result); // the new currency-converted stock quote service
2949 The `quotex.cpp` client/service application source is:
2952 // Contents of file "quotex.cpp":
2953 #include "soapH.h" // include generated proxy and SOAP support
2954 int main(int argc, char **argv)
2961 else if (soap_call_ns3__getQuote(&soap, "http://www.cs.fsu.edu/~engelen/quotex.cgi", "", argv[1], argv[2], q))
2962 soap_print_fault(&soap, stderr);
2964 printf("\nCompany %s: %f (%s)\n", argv[1], q, argv[2]);
2967 int ns3__getQuote(struct soap *soap, char *symbol, char *country, float &result)
2970 int socket = soap->socket; // save socket (stand-alone service only, does not support keep-alive)
2971 if (soap_call_ns1__getQuote(soap, "http://services.xmethods.net/soap", "", symbol, &q) == 0 &&
2972 soap_call_ns2__getRate(soap, "http://services.xmethods.net/soap", NULL, "us", country, &r) == 0)
2975 soap->socket = socket;
2978 soap->socket = socket;
2979 return SOAP_FAULT; // pass soap fault messages on to the client of this app
2981 /* Since this app is a combined client-server, it is put together with
2982 * one header file that describes all service operations. However, as a consequence we
2983 * have to implement the methods that are not ours. Since these implementations are
2984 * never called (this code is client-side), we can make them dummies as below.
2986 int ns1__getQuote(struct soap *soap, char *symbol, float &result)
2987 { return SOAP_NO_METHOD; } // dummy: will never be called
2988 int ns2__getRate(struct soap *soap, char *country1, char *country2, float &result)
2989 { return SOAP_NO_METHOD; } // dummy: will never be called
2991 struct Namespace namespaces[] =
2993 {"SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/"},
2994 {"SOAP-ENC", "http://schemas.xmlsoap.org/soap/encoding/"},
2995 {"xsi", "http://www.w3.org/2001/XMLSchema-instance", "http://www.w3.org/*/XMLSchema-instance"},
2996 {"xsd", "http://www.w3.org/2001/XMLSchema", "http://www.w3.org/*/XMLSchema"},
2997 {"ns1", "urn:xmethods-delayed-quotes"},
2998 {"ns2", "urn:xmethods-CurrencyExchange"},
2999 {"ns3", "urn:quotex"},
3007 > c++ -o quotex.cgi quotex.cpp soapC.cpp soapClient.cpp soapServer.cpp stdsoap2.cpp -lsocket -lxnet -lnsl
3009 Note: under Linux and Mac OS X you can often omit the *`-l`* libraries.
3011 The `quotex.cgi` executable is installed as a CGI application on the Web by
3012 copying it in the designated directory specific to your Web server. After
3013 this, the executable can also serve to test the service. For example
3017 returns the quote of `IBM` in `uk` pounds by communicating the request
3018 and response quote from the CGI application. See
3019 <http://xmethods.com/detail.html?id=5> for details on the currency
3022 When combining clients and service functionalities, it is required to use one
3023 header file input to the compiler. As a consequence, however, stubs and
3024 skeletons are available for **all** service operations, while the client part
3025 will only use the stubs and the service part will use the skeletons. Thus,
3026 dummy implementations of the unused service operations need to be given which are
3029 Three WSDL files are created by gSOAP: *`ns1.wsdl`*, *`ns2.wsdl`*, and
3030 *`ns3.wsdl`*. Only the *`ns3.wsdl`* file is required to be published as it
3031 contains the description of the combined service, while the others are
3032 generated as a side-effect (and in case you want to develop these separate
3035 ## Asynchronous One-Way Message Passing {#oneway1}
3037 SOAP RPC client-server interaction is synchronous: the client blocks until the server responds to the request.
3038 gSOAP also supports asynchronous one-way message passing and the interoperable synchronous one-way message passing over HTTP. The two styles are similar, but only the latter is interoperable and is compliant to Basic Profile 1.0. The interoperable synchronous one-way message passing style over HTTP is discussed in Section \ref oneway2 below.
3040 SOAP messaging routines are declared as function prototypes, just like service operations for SOAP RPC. However, the output parameter is a
3041 `void` type to indicate the absence of a return value.
3043 For example, the following header file specifies an event message for SOAP messaging:
3046 int ns__event(int eventNo, void);
3049 The gSOAP `soapcpp2` tool generates the following functions in `soapClient.cpp`:
3052 int soap_send_ns__event(struct soap *soap, const char URL, const char action, int event);
3053 int soap_recv_ns__event(struct soap *soap, struct ns__event *dummy);
3056 The `soap_send_ns__event` function transmits the message to the destination URL by opening a socket and sending the SOAP encoded
3057 message. The socket will remain
3058 open after the send and has to be closed with `soap_closesock()`. The open socket connection can also be used to obtain a service
3059 response, e.g. with a `soap_recv` function call.
3061 The `soap_recv_ns__event` function waits for a SOAP message on the currently open socket (`soap.socket`) and fills the
3062 `struct ns__event` with the `ns__event` parameters (e.g. `int eventNo`).
3063 The `struct ns__event` is automatically created by gSOAP and is a mirror image of the `ns__event` parameters:
3071 The gSOAP generated `soapServer.cpp` code includes a skeleton routine to accept the message.
3072 (The skeleton routine does not respond with a SOAP response message.)
3075 int soap_serve_ns__event(struct soap *soap);
3078 The skeleton routine calls the user-implemented `ns__event(struct soap *soap, int eventNo)` routine (note the absence of the void
3081 As usual, the skeleton will be automatically called by the service operation request dispatcher that handles both the service operation
3082 requests (RPCs) and messages:
3086 { soap_serve(soap_new());
3088 int ns__event(struct soap *soap, int eventNo)
3095 ## Implementing Synchronous One-Way Message Passing over HTTP {#oneway2}
3097 One-way SOAP message passing over HTTP as defined by the SOAP specification and
3098 Basic Profile 1.0 is synchrounous, meaning that the server must respond with an
3099 HTTP OK header (or HTTP 202 Accepted) and an empty body. To implement
3100 synchrounous one-way messaging, the same setup for asynchrounous one-way
3101 messaing discussed in Section \ref oneway1 is used, but with one simple
3102 addition at the client and server side for HTTP transfer.
3104 At the server side, we have to return an empty HTTP OK response. Normally with
3105 one-way messaging the gSOAP engine closes the socket when the service operation
3106 is finished, which is not desirable for synchronous one-way message exchanges
3107 over HTTP: an HTTP response should be send. This is accomplished as follows.
3108 For each one-way operation implemented in C/C++, we
3109 replace the `return SOAP_OK` with:
3112 int ns__event(struct soap *soap, int eventNo)
3115 return soap_send_empty_response(soap, SOAP_OK); // SOAP_OK: return HTTP 202 ACCEPTED
3119 At the client side, the empty response header must be parsed as follows:
3122 if (soap_send_ns__event(soap, eventNo) != SOAP_OK
3123 || soap_recv_empty_response(soap) != SOAP_OK)
3124 soap_print_fault(soap, stderr);
3128 The synchronous (and asynchronous) one-way messaging supports HTTP keep-alive and chunking.
3130 Note: `soap_send_empty_response` returns the error code `SOAP_STOP`
3131 to force the engine to stop producing a response message after the service
3132 operation completed, which allows `soap_send_empty_response` to be used
3133 with any service operation that should return HTTP 202.
3135 ## How to Use the SOAP Serializers and Deserializers to Save and Load Application Data using XML Data Bindings {#bindings}
3137 The gSOAP XML databindings for C and C++ allow a seamless integration of XML in
3138 C and C++ applications. Data can be serialized in XML and vice versa. WSDL and
3139 XML schema files can be converted to C or C++ definitions. C and C++
3140 definitions can be translated to WSDL and schemas to support legacy ANSI C
3141 applications for example.
3143 Learn more about XML data binding for C and C++ with gSOAP by visiting the
3144 Developer Center <https://www.genivia.com/dev.html> and the new and most
3145 up-to-date XML data binding documentation
3146 <https://www.genivia.com/doc/databinding/html>.
3148 ### Mapping XML Schema to C/C++ with wsdl2h
3152 > wsdl2h [options] XSD and WSDL files ...
3154 The WSDL 1.1 and 2.0 standards are supported. If you have trouble
3155 with WSDL 2.0 please contact the author. The entire XML schema 1.1 standard is
3156 supported, except XPath expressions and assertions. This covers all of the
3157 following schema components with their optional [ attributes ] shown:
3161 <xs:any [minOccurs, maxOccurs] >
3164 <xs:choice [minOccurs, maxOccurs] >
3165 <xs:sequence [minOccurs, maxOccurs] >
3166 <xs:group [name, ref] >
3167 <xs:attributeGroup [name, ref] >
3168 <xs:attribute [name, ref, type, use, default, fixed, form, wsdl:arrayType] >
3169 <xs:element [name, ref, type, default, fixed, form, nillable, abstract, substitutionGroup, minOccurs, maxOccurs] >
3170 <xs:simpleType [name] >
3171 <xs:complexType [name, abstract, mixed] >
3175 The supported facets are:
3188 <xs:minInclusive> validated only for integer types
3189 <xs:maxInclusive> validated only for integer types
3190 <xs:minExclusive> validated only for integer types
3191 <xs:maxExclusive> validated only for integer types
3192 <xs:precision> maps to float/double with C formatted output
3193 <xs:scale> maps to float/double with C formatted output
3194 <xs:totalDigits> maps to float/double with C formatted output
3195 <xs:fractionDigits> maps to float/double with C formatted output
3196 <xs:pattern> not automatically validated, see note below
3197 <xs:union> maps to string, content not validated
3213 All primitive XSD types are supported. A subset of the default type mappings is shown below.
3214 User-defined mappings can be added to `typemap.dat` to let `wsdl2h`
3215 (re)map XSD types to C/C++ types.
3219 xsd:string maps to string (char*,wchar_t*,std::string,std::wstring)
3220 xsd:boolean maps to bool (C++) or enum xsd__boolean (C)
3221 xsd:float maps to float
3222 xsd:double maps to double
3223 xsd:decimal maps to string, or use #import "custom/decimal.h"
3224 xsd:duration maps to string, or use #import "custom/duration.h"
3225 xsd:dateTime maps to time_t, or use #import "custom/struct_tm.h"
3226 xsd:time maps to string (white space collapse applied)
3227 xsd:date maps to string (white space collapse applied)
3228 xsd:gYearMonth maps to string (white space collapse applied)
3229 xsd:gYear maps to string (white space collapse applied)
3230 xsd:gMonth maps to string (white space collapse applied)
3231 xsd:hexBinary maps to struct xsd__hexBinary
3232 xsd:base64Bianry maps to struct xsd__base64Binary
3233 xsd:anyURI maps to string (white space collapse applied)
3234 xsd:anyType maps to an XML string or DOM with wsdl2h -d
3235 xsd:anyAtomicType maps to string
3236 xsd:anySimpleType maps to string
3237 xsd:QName maps to _QName (QName normalization applied)
3238 xsd:NOTATION maps to string (white space collapse applied)
3242 Note: automatic validation of *`xs:pattern`* restricted content is possible with a hook to a regex pattern matching engine, see the `fsvalidate` and `fwvalidate` callbacks in Section \ref callback .
3244 Note: string targets are defined in the `typemap.dat` file used by
3245 `wsdl2h` to map XSD types. This allows the use of `char*`,
3246 `wsha_t*`, `std::string`, and `std::wstring` string types for
3247 all XSD types mapped to strings.
3249 All non-primitive XSD types are supported (with the default mapping shown):
3253 xsd:normalizedString maps to string
3254 xsd:token maps to string
3255 xsd:language maps to string
3256 xsd:IDREFS maps to string
3257 xsd:ENTITIES maps to string
3258 xsd:NMTOKEN maps to string
3259 xsd:NMTOKENS maps to string
3260 xsd:Name maps to string
3261 xsd:NCName maps to string
3262 xsd:ID maps to string
3263 xsd:IDREF maps to string
3264 xsd:ENTITY maps to string
3265 xsd:integer maps to string
3266 xsd:nonPositiveInteger maps to string
3267 xsd:negativeInteger maps to string
3268 xsd:long maps to LONG64
3270 xsd:short maps to short
3271 xsd:byte maps to byte
3272 xsd:nonNegativeInteger maps to string
3273 xsd:unsignedLong maps to ULONG64
3274 xsd:unsignedInt maps to unsigned int
3275 xsd:unsignedShort maps to unsigned short
3276 xsd:unsignedByte maps to unsigned byte
3277 xsd:positiveInteger maps to string
3278 xsd:yearMonthDuration maps to string
3279 xsd:dayTimeDuration maps to string
3280 xsd:dateTimeStamp maps to string
3284 There are several initialization flags to control XML serialization at runtime:
3286 * XML validation is more stricly enforced with `SOAP_XML_STRICT`.
3288 * XML namespaces are supported, unless disabled with `SOAP_XML_IGNORENS`.
3290 * XML exclusive canonicalization is enabled with `SOAP_XML_CANONICAL`.
3292 * XML default `xmlns="..."` namespace bindings are enforced with `SOAP_XML_DEFAULTNS`.
3294 * XML is indented for enhanced readability with `SOAP_XML_INDENT`.
3296 * XML `xsi:nil` for NULL elements is serialized with `SOAP_XML_NIL`.
3298 Strict validation catches all **structural** XML validation violations. For
3299 primitive type values, it depends on the C/C++ target type that XSD types are
3300 mapped to, to catch primitive value content pattern violations. Primitive value
3301 content validation is performed on non-string types such as numerical and time
3302 values. String values are not automatocally validated, unless a
3303 *`xs:pattern`* is given and the `fsvalidate` and `fwvalidate`
3304 callbacks are implemented by the user. Alternatively, deserialized string
3305 content can be checked at the application level.
3307 To obtain C and/or C++ type definitions for XML schema components, run
3308 `wsdl2h` on the schemas to generate a header file. This header file defines
3309 the C/C++ type representations of the XML schema components. The header file
3310 is then processed by the `soapcpp2` tool to generate
3311 the serializers for these types. See Section \ref databindings for an overview to use `wsdl2h` and `soapcpp2` to map schemas to C/C++ types to obtain XML data bindings.
3313 ### Mapping C/C++ to XML Schema with soapcpp2
3315 To generate serialization code, execute:
3317 > soapcpp2 [options] header_file.h
3319 The following C/C++ types are supported in the header file:
3323 enum, enum* ('enum*' indicates serialized as a bitmask)
3324 (unsigned) char, short, int, long, long long (also LONG64), size_t
3325 float, double, long double (#import "custom/long_double.h")
3326 std::string, std::wstring, char[], char*, wchar_t*
3327 _XML (a char* type to hold literal XML string content)
3328 _QName (a char* type with normalized QName content of the form prefix:name)
3329 struct, class (with single inheritance)
3330 std::vector, std::list, std::deque, std::set (#import "import/stl.h")
3331 union (requires preceding discriminant member field)
3334 template <> class (requires begin(), end(), size(), and insert() methods)
3335 void* (requires a preceding __type field to indicate the object pointed to)
3336 struct xsd__hexBinary (special pre-defined type to hold binary content)
3337 struct xsd__base64Binary (special pre-defined type to hold binary content)
3338 struct tm (#import "custom/struct_tm.h")
3339 struct timeval (#import "custom/struct_timeval.h")
3340 pointers to any of the above (any pointer-linked structures are serializable, including cyclic graphs)
3341 fixed-size arrays of all of the above
3344 Additional features and C/C++ syntax requirements:
3346 * A header file should not include any code statements, only data type declarations.
3348 * Nested classes and nested types are unnested.
3350 * Use `#import "file.h"` instead of `#include` to import other header files. The
3351 `#include` and `#define` directives are accepted, but deferred to the generated
3354 * C++ namespaces are supported (must cover entire header file content)
3356 * Optional DOM support can be used to store mixed content or literal XML
3357 content. Otherwise, mixed content may be lost. Use soapcpp2 option -d for DOM
3358 support. Learn more about the DOM API for C and C++ by visiting the
3359 Developer Center <https://www.genivia.com/doc/dom/html>.
3361 * Types are denoted transient using the 'extern' qualifier, which prevents
3362 serialization as desired:
3365 extern class name; // class 'name' is not serialized
3366 struct name { extern char *name; int num; }; // 'name' is not serialized
3369 * Only public members of a class can be serialized:
3372 class name { private: char *secret; }; // 'secret' is not serialized
3375 * Types declared "volatile" means that they are declared elsewhere
3376 in the project's code base and should not be redefined in the `soapcpp2`-generated code nor changed/augmented by the `soapcpp2` tool:
3379 volatile class name { ... }; // defined here just to generate the serializers
3382 * Classes and structs declared "mutable" means that they can be augmented with additional members, rather than leading to a redefinition error:
3385 mutable class name { int n; }; // class has a member 'n'
3386 mutable class name { float x; }; // and also a member 'x'
3389 The `SOAP_ENV__Header` struct is mutable as well as the `SOAP_ENV__Fault`, `SOAP_ENV__Detail`, `SOAP_ENV__Reason`, and `SOAP_ENV__Code` structs.
3391 * struct/class members are serialized as attributes when qualified with '@':
3394 struct record { @ char *name; int num; }; // attribute name, element num
3397 * Strings with 8-bit content can hold ASCII (default) or UTF8. The latter is
3398 possible by enabling the `SOAP_C_UTFSTRING` flag. When enabled, all `std::string` and `char*` strings MUST contain UTF8.
3400 The soapcpp2 tool generates serializers and deserializers
3401 for all wsdl2h-generated or user-defined data structures that are specified in
3402 the header file input to the compiler. The serializers and deserializers can be
3403 found in the generated
3404 `soapC.cpp` file. These serializers and deserializers can be used separately by an application without the need to build a
3405 full client or service application. This is useful for applications that need to save or export their data in XML or need to
3406 import or load data stored in XML format.
3408 ### Serializing C/C++ Data to XML {#serialize}
3410 We assume that the `wsdl2h` tool was used to map XML schema types to C/C++ data types. The `soapcpp2` tool then generates the (de)serializers for the C/C++ types. You can also use `soapcpp2` directly on a header file that declares annotated C/C++ data types to serialize.
3412 The following context attributes can be set to control the destination and source for serialization and deserialization:
3414 * `int soap.socket` socket file descriptor for input and output (or set to `SOAP_INVALID_SOCKET`)
3416 * `ostream *soap.os` C++ only: output stream used for send operations
3418 * `const char **soap.os` C only: points to a string pointer to be set with the managed string content
3420 * `istream *soap.is` C++ only: input stream used for receive operations
3422 * `const char *soap.is` C only: string with input to parse (this pointer advances)
3424 * `int soap.sendfd` when `soap.socket`=`SOAP_INVALID_SOCKET`, this fd is used for send operations
3426 * `int soap.recvfd` when `soap.socket`=`SOAP_INVALID_SOCKET`, this fd is used for receive operations
3428 The following initializing and finalizing functions can be used:
3430 * `void soap_begin_send(struct soap*)` start a send/write phase
3432 * `int soap_end_send(struct soap*)` flush the buffer
3434 * `int soap_begin_recv(struct soap*)` start a rec/read phase (if an HTTP header is present, parse it first)
3436 * `int soap_end_recv(struct soap*)` perform a id/href consistency check on deserialized data
3438 These operations do not open or close the connections. The application should open and close connections or files and set the `soap.socket`, `soap.os` or `soap.sendfd`, `soap.is` or `soap.recvfd` streams or descriptors.
3439 When `soap.socket`<0 and none of the streams and descriptors are set, then the standard input and output will be used.
3441 The following options are available to control serialization:
3444 soap->encodingStyle = NULL; // to remove SOAP 1.1/1.2 encodingStyle
3445 soap_mode(soap, SOAP_XML_TREE); // XML without id-ref (no cycles!)
3446 soap_mode(soap, SOAP_XML_GRAPH); // XML with id-ref (including cycles)
3447 soap_set_namespaces(soap, struct Namespace *nsmap); //to set xmlns bindings
3450 See also Section \ref flags to control the I/O buffering and content encoding such as compression and DIME encoding.
3452 We assume that the `wsdl2h` tool was used to map XML schema types to C/C++ data types. The `soapcpp2` tool then generates the (de)serializers for the C/C++ types.
3454 To serialize data to an XML stream, two functions should be called to prepare
3455 for serialization of the data and to send the data, respectively. The first function,
3456 `soap_serialize`, analyzes pointers and determines if multi-references
3457 are required to encode the data and if cycles are present the object graph.
3458 The second function, `soap_put`, produces the XML output on a stream.
3460 The `soap_serialize` and `soap_put` (and both combined by `soap_write`) functions are statically generated specific to a
3461 data type. For example, `soap_serialize_float(&soap, &d)` is called to
3462 serialize an `float` value and `soap_put_float(&soap, &d, "number", NULL)` is called to output the floating point value in SOAP tagged
3463 with the name *`<number>`*. The `soap_write_float(&soap, &d)` conveniently combines the initialization of output, writing the data, and finalizing the output.
3465 To initialize data, the `soap_default`
3466 function of a data type can be used. For example,
3467 `soap_default_float(&soap, &d)` initializes the float to 0.0. The
3468 `soap_default` functions are useful to initialize complex data types such
3469 as arrays, `struct`s, and `class` instances. Note that the
3470 `soap_default` functions do not need the gSOAP runtime context as a
3473 The following table lists the type naming conventions used by gSOAP:
3478 `wchar_t*` | `wstring`
3479 `std::string` | `std__string`
3480 `std::wstring` | `std__wstring`
3487 `long long` | `LONG64`
3490 `unsigned char` | `unsignedByte`
3491 `unsigned int` | `unsignedInt`
3492 `unsigned long` | `unsignedLong`
3493 `unsigned long long` | `ULONG64`
3494 `unsigned short` | `unsignedShort`
3495 `T`[N] | `ArrayN`OfType where Type is the type name of T
3496 `T`* | `PointerToType` where Type is the type name of T
3497 `std::vector<T>` | `TemplateOfType` where Type is the type name of T
3498 `struct Name` | `Name`
3499 `class Name` | `Name`
3500 `enum Name` | `Name`
3502 Consider for example the following C code with a declaration of `p` as a
3503 pointer to a `struct ns__Person`:
3506 struct ns__Person { char *name; } *p;
3509 To serialize `p`, its address is passed to the function
3510 `soap_serialize_PointerTons__Person` generated for this type by the
3511 gSOAP `soapcpp2` compiler:
3514 soap_serialize_PointerTons__Person(&soap, &p);
3517 The **address of** `p` is passed, so the serializer can determine whether
3518 `p` was already serialized and to discover co-referenced objects and cycles in graph data structures that require SOAP encoding with id-ref serialization.
3519 To generate the output, the address of `p` is passed to the function
3520 `soap_put_PointerTons__Person` together with the name of an XML element
3521 and an optional type string (to omit a type, use `NULL`):
3524 soap_begin_send(&soap);
3525 soap_put_PointerTons__Person(&soap, &p, "ns:element-name", "ns:type-name");
3526 soap_end_send(&soap);
3529 or the shorthand for the above (without the xsi type):
3532 soap_write_PointerTons__Person(&soap, &p);
3539 <ns:element-name xmlns:SOAP-ENV="..." xmlns:SOAP-ENC="..." xmlns:ns="..."
3540 ... xsi:type="ns:type-name">
3541 <name xsi:type="xsd:string">...</name>
3546 The serializer is initialized with the `soap_begin_send(soap)` function
3547 and closed with `soap_end_send(soap)`. All temporary data structures and
3548 data structures deserialized on the heap are destroyed with the
3549 `soap_destroy` and `soap_end` functions (in this order).
3551 The `soap_done` function should be used to reset the context, i.e. the last use of the context. To detach and deallocate the context, use `soap_free`.
3553 To remove the temporary data only and keep the deserialized data on the heap, use `soap_free_temp`.
3554 Temporary data structures are only created if the encoded data uses pointers.
3555 Each pointer in the encoded data has an internal hash table entry to determine
3556 all multi-reference parts and cyclic parts of the complete data structure.
3559 output stream in C++ to `soap.os` and in C an output string `soap.os`, or a file descriptor to `soap.sendfd`.
3561 For example, to assign a file descriptor:
3564 soap.sendfd = open(file, O_RDWR|O_CREAT, S_IWUSR|S_IRUSR);
3565 soap_serialize_PointerTons__Person(&soap, &p);
3566 soap_begin_send(&soap);
3567 soap_put_PointerTons__Person(&soap, &p, "ns:element-name", "ns:type-name");
3568 soap_end_send(&soap);
3571 The above can be abbreviated to
3574 soap.sendfd = open(file, O_RDWR|O_CREAT, S_IWUSR|S_IRUSR);
3575 soap_write_PointerTons__Person(&soap, &p);
3578 The `soap_serialize` function is optional. It MUST be used when
3579 the object graph contains cycles.
3580 It MUST be called to preserve the logical coherence of pointer-based
3581 data structures, where pointers may refer to co-referenced objects.
3582 By calling `soap_serialize`, data structures shared through pointers are serialized only once and
3583 referenced in XML using id-refs attributes.
3584 The actual id-refs used depend on the SOAP encoding. To turn off SOAP encoding,
3585 remove or avoid using the SOAP-ENV and SOAP-ENC namespace bindings in the namespace table.
3586 In addition, the `SOAP_XML_TREE` and `SOAP_XML_GRAPH` flags can be used
3587 to control the output by restricting serialization to XML trees or by enabling
3588 multi-ref graph serialization with id-ref attribuation.
3590 To save the data as an XML tree (with one root) without any id-ref attributes, use the
3591 `SOAP_XML_TREE` flag. The data structure MUST NOT contain pointer-based cycles.
3593 To preserve the exact structure of the data object graph and create XML with one root, use
3594 the `SOAP_XML_GRAPH` output-mode flag (see
3595 Section \ref flags ). Use this flag and the `soap_serialize` function
3596 to prepare the serialization of data with in-line id-ref attributes.
3597 Using the `SOAP_XML_GRAPH` flag assures the preservation of the logical structure of the data
3599 For example, to encode the contents of two variables `var1` and `var2`
3600 that may share data through pointer structures,
3601 the serializers are called before the output routines:
3608 soap_init(&soap); // initialize
3609 [optional: soap_omode(&soap, flags);] // set output-mode flags (e.g. SOAP_ENC_PLAIN|SOAP_ENC_ZLIB)
3610 soap_begin(&soap); // start new (de)serialization phase
3611 soap_set_omode(&soap, SOAP_XML_GRAPH);
3612 soap_serialize_Type1(&soap, &var1);
3613 soap_serialize_Type2(&soap, &var2);
3615 [optional: soap.socket = a_socket_file_descriptor;] // when using sockets
3616 [optional: soap.os = an_output_stream;] // C++
3617 [optional: soap.sendfd = an_output_file_descriptor;] // C
3618 soap_begin_send(&soap);
3619 soap_put_Type1(&soap, &var1, "[optional: namespace-prefix:]element-name1", "[optional: namespace-prefix:]type-name1");
3620 soap_put_Type2(&soap, &var2, "[optional: namespace-prefix:]element-name2", "[optional: namespace-prefix:]type-name2");
3622 soap_end_send(&soap); // flush
3623 soap_destroy(&soap); // remove deserialized C++ objects
3624 soap_end(&soap); // remove deserialized data structures
3625 soap_done(&soap); // finalize last use of this context
3629 where Type1 is the type name of T1 and
3630 Type2 is the type name of T2 (see table above). The
3631 strings `[optional: namespace-prefix:]type-name1` and
3632 `[optional: namespace-prefix:]type-name2` describe the schema types of the
3633 elements. Use `NULL` to omit this type information.
3635 For serializing class instances, method invocations MUST be used instead of function calls, for example
3636 `obj.soap_serialize(&soap)` and `obj.soap_put(&soap, "elt", "type")`. This ensures that the proper serializers are used for
3637 serializing instances of derived classes.
3639 You can serialize a class instance to a stream as follows:
3645 soap_init(&soap); // initialize
3646 soap_begin(&soap); // start new (de)serialization phase
3647 soap_set_omode(&soap, SOAP_XML_GRAPH);
3648 obj.serialize(&soap);
3649 soap.os = &cout; // send to cout
3650 soap_begin_send(&soap);
3651 obj.put(&soap, "[optional: namespace-prefix:]element-name1", "[optional: namespace-prefix:]type-name1");
3652 soap_end_send(&soap); // flush
3654 soap_destroy(&soap); // remove deserialized C++ objects
3655 soap_end(&soap); // remove deserialized data
3656 soap_done(&soap); // finalize last use of this context
3659 For gSOAP 2.8.28 and later, in C we use `soap.os` to obtain a string with the XML serialized data:
3666 soap_init(&soap); // initialize
3667 soap_begin(&soap); // start new (de)serialization phase
3668 soap_set_omode(&soap, SOAP_XML_GRAPH);
3669 soap_serialize(&soap, &obj);
3670 soap.os = &out; // string to set
3671 soap_begin_send(&soap);
3672 soap_put(&soap, &obj, "[optional: namespace-prefix:]element-name1", "[optional: namespace-prefix:]type-name1");
3673 soap_end_send(&soap); // flush
3674 ... // out has XML content string managed by context
3675 soap.os = NULL; // stop sending to string
3677 soap_end(&soap); // remove deserialized data
3678 soap_done(&soap); // finalize last use of this context
3681 When you declare a soap struct pointer as a data member in a class, you can overload the << operator to serialize the class to streams:
3684 ostream &operator<<(ostream &o, const myClass &e)
3687 ... error: need a soap struct to serialize (could use global struct) ...
3690 ostream *os = e.soap->os;
3692 soap_set_omode(e.soap, SOAP_XML_GRAPH);
3693 e.serialize(e.soap);
3694 soap_begin_send(e.soap);
3695 e.put(e.soap, "myClass", NULL);
3696 soap_end_send(e.soap);
3698 soap_clr_omode(e.soap, SOAP_XML_GRAPH);
3704 Of course, when you construct an instance you must set its soap struct to a valid context. Deserialized class instances with a soap struct data member will have their soap structs set automatically, see Section \ref classmemory .
3706 In principle, XML output for a data structure can be produced with `soap_put`
3707 without calling the `soap_serialize` function first.
3708 In this case, the result is similar to `SOAP_XML_TREE` which
3709 means that no id-refs are output. Cycles in the data structure will crash the serialization
3710 algorithm, even when the `SOAP_XML_GRAPH` is set.
3712 Consider the following `struct`:
3715 // Contents of file "tricky.h":
3724 The following fragment initializes the pointer fields `p` and `q` to the value of field `n`:
3734 soap_serialize_Tricky(&soap, &X);
3735 soap_put_Tricky(&soap, &X, "Tricky", NULL);
3736 soap_end(&soap); // Clean up temporary data used by the serializer
3739 What is special about this data structure is that `n` is 'fixed' in the `Tricky` structure, and `p` and `q` both point to `n`. The gSOAP serializers strategically place the id-ref attributes such that `n` will be identified as the primary data source, while `p` and `q` are serialized with ref/href attributes.
3741 The resulting output is:
3745 <Tricky xsi:type="Tricky">
3747 <n xsi:type="int">1</n>
3749 <r xsi:type="int">2</r>
3751 <id id="2" xsi:type="int">1</id>
3755 which uses an independent element at the end to represent the multi-referenced integer, assuming the `SOAP-ENV` and `SOAP-ENC` namespaces indicate SOAP 1.1 encoding.
3757 With the `SOAP_XML_GRAPH` flag the output is:
3761 <Tricky xsi:type="Tricky">
3763 <n id="2" xsi:type="int">1</n>
3769 In this case, the XML is self-contained and multi-referenced data is accurately serialized.
3770 The gSOAP generated deserializer for this data type will be able to accurately reconstruct the data from the XML (on the heap).
3772 ### Deserializing C/C++ Data from XML {#deserialize}
3774 We assume that the `wsdl2h` tool was used to map XML schema types to C/C++ data types. The `soapcpp2` tool then generates the (de)serializers for the C/C++ types. You can also use `soapcpp2` directly on a header file that declares annotated C/C++ data types to serialize.
3776 To deserialize a data type from XML, the `soap_get` (or the simpler `soap_read`) function for the data type to be deserialized is used. The outline of a program that deserializes two variables `var1` and `var2` is for example:
3783 soap_init(&soap); // initialize at least once
3784 [optional: soap_imode(&soap, flags);] // set input-mode flags
3785 soap_begin(&soap); // begin new decoding phase
3786 [optional: soap.is = an_input_stream;] // C++
3787 [optional: soap.recvfd = an_input_file_desriptpr;] // C
3788 soap_begin_recv(&soap); // if HTTP/MIME/DIME/GZIP headers are present, parse them
3789 if (!soap_get_Type1(&soap, &var1, "[optional: namespace-prefix:]element-name1", "[optional: namespace-prefix:]type-name1"))
3791 if (!soap_get_Type2(&soap, &var2, "[optional: namespace-prefix:]element-name2", "[optional: namespace-prefix:]type-name1"))
3794 soap_end_recv(&soap); // check consistency of id/hrefs
3795 soap_destroy(&soap); // remove deserialized C++ objects
3796 soap_end(&soap); // remove deserialized data
3797 soap_done(&soap); // finalize last use of the context
3800 The strings `[optional: namespace-prefix:`type-name1] and
3801 `[optional: namespace-prefix:`type-name2] are the schema types of the elements
3802 and should match the *`xsi:type`* attribute of the receiving message. To omit
3803 the match, use `NULL` as the type. For class instances, method invocation
3804 can be used instead of a function call if the object is already instantiated,
3805 i.e. `obj.soap_get(&soap, "...", "...")`.
3807 The `soap_begin` call resets the deserializers. The `soap_destroy`
3808 and `soap_end` calls remove the temporary data structures **and** the
3809 decoded data that was placed on the heap.
3811 To remove temporary data while retaining the deserialized data on the heap, the
3812 function `soap_free_temp` should be called instead of `soap_destroy` and
3815 One call to the `soap_get_Type` function of a type `Type` scans the
3816 entire input to process its XML content and to capture SOAP 1.1 independent
3817 elements (which contain multi-referenced objects). As a result, `soap.error` will set to `SOAP_EOF`.
3819 multiple objects into one file will fail to decode them properly with multiple `soap_get` calls. A well-formed XML document should
3820 only have one root anyway, so don't save multiple objects into one file. If you
3821 must save multiple objects, create a linked list or an array of objects and save
3822 the linked list or array. You could use the `soap_in_Type` function instead of the `soap_get_Type` function. The `soap_in_Type` function parses one XML element at a time.
3824 You can deserialize class instances from a stream as follows:
3829 soap_init(&soap); // initialize
3830 soap.is = &cin; // read from cin
3831 soap_begin_recv(&soap); // if HTTP header is present, parse it
3832 if (soap_get_myClass(&soap, &obj, "myClass", NULL) == NULL)
3834 soap_end_recv(&soap); // check consistency of id/hrefs
3836 soap_destroy(&soap); // remove deserialized C++ objects
3837 soap_end(&soap); // remove deserialized data
3838 soap_done(&soap); // finalize last use of the context
3841 This can be abbreviated to:
3846 soap_init(&soap); // initialize
3847 soap.is = &cin; // read from cin
3848 if (soap_read_myClass(&soap, &obj, NULL) != SOAP_OK)
3851 soap_destroy(&soap); // remove deserialized C++ objects
3852 soap_end(&soap); // remove deserialized data
3853 soap_done(&soap); // finalize last use of the context
3856 When declaring a soap struct pointer as a data member in a class, you can overload the >> operator to parse and deserialize a class instance from a stream:
3859 istream &operator>>(istream &i, myClass &e)
3862 ... error: need soap struct to deserialize (could use global struct)...
3863 istream *is = e.soap->is;
3865 if (soap_read_myClass(e.soap, &e) != SOAP_OK)
3872 For gSOAP 2.8.28 and later, you can parse XML from strings as follows:
3877 soap_init(&soap); // initialize
3878 soap.is = "..."; // this is the string with XML to parse
3879 if (soap_read_myClass(&soap, &obj, NULL) != SOAP_OK)
3881 soap.is = NULL; // stop parsing from strings
3883 soap_end(&soap); // remove deserialized data
3884 soap_done(&soap); // finalize last use of the context
3887 When declaring a soap struct pointer as a data member in a class, you can overload the >> operator to parse and deserialize a class instance from a stream or string stream:
3890 istream &operator>>(istream &i, myClass &e)
3893 ... error: need soap struct to deserialize (could use global struct)...
3894 istream *is = e.soap->is;
3896 if (soap_read_myClass(e.soap, &e) != SOAP_OK)
3903 ### Example {#example9}
3905 As an example, consider the following data type declarations:
3908 // Contents of file "person.h":
3909 typedef char *xsd__string;
3910 typedef char *xsd__Name;
3911 typedef unsigned int xsd__unsignedInt;
3912 enum ns__Gender {male, female};
3917 xsd__unsignedInt number;
3924 enum ns__Gender gender;
3925 ns__Address address;
3931 The following program uses these data types to write to standard output a data structure that contains the data of a person named "John" living at Downing st. 10 in Londen. He has a mother
3932 "Mary" and a father "Stuart". After initialization, the class instance for "John" is serialized and encoded in XML to the
3933 standard output stream using gzip compression (requires the Zlib library, compile sources with -DWITH_GZIP):
3936 // Contents of file "person.cpp":
3941 ns__Person mother, father, john;
3942 mother.name = "Mary";
3943 mother.gender = female;
3944 mother.address.street = "Downing st.";
3945 mother.address.number = 10;
3946 mother.address.city = "London";
3947 mother.mother = NULL;
3948 mother.father = NULL;
3949 father.name = "Stuart";
3950 father.gender = male;
3951 father.address.street = "Main st.";
3952 father.address.number = 5;
3953 father.address.city = "London";
3954 father.mother = NULL;
3955 father.father = NULL;
3958 john.address = mother.address;
3959 john.mother = &mother;
3960 john.father = &father;
3962 soap_omode(&soap, SOAP_ENC_ZLIB|SOAP_XML_GRAPH); // see \ref flags
3964 soap_begin_send(&soap);
3965 john.soap_serialize(&soap);
3966 john.soap_put(&soap, "johnnie", NULL);
3967 soap_end_send(&soap);
3968 soap_destroy(&soap);
3972 struct Namespace namespaces[] =
3974 {"SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/"},
3975 {"SOAP-ENC","http://schemas.xmlsoap.org/soap/encoding/"},
3976 {"xsi", "http://www.w3.org/2001/XMLSchema-instance"},
3977 {"xsd", "http://www.w3.org/2001/XMLSchema"},
3978 {"ns", "urn:person"}, // Namespace URI of the "Person" data type
3983 The header file is processed and the application compiled on Linux/Unix with:
3986 > c++ -DWITH_GZIP -o person person.cpp soapC.cpp stdsoap2.cpp -lsocket -lxnet -lnsl -lz
3988 (Depending on your system configuration, the libraries `libsocket.a`,
3989 `libxnet.a`, `libnsl.a`
3990 are required. Compiling on Linux typically does not require the inclusion of those
3992 See \ref compression for details on compression with gSOAP.
3994 Running the `person` application results in the compressed XML output:
3998 <johnnie xsi:type="ns:Person" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
3999 xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
4000 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4001 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
4002 xmlns:ns="urn:person"
4003 SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
4004 <name xsi:type="xsd:Name">John</name>
4005 <gender xsi:type="ns:Gender">male</gender>
4006 <address xsi:type="ns:Address">
4007 <street id="3" xsi:type="xsd:string">Dowling st.</street>
4008 <number xsi:type="unsignedInt">10</number>
4009 <city id="4" xsi:type="xsd:string">London</city>
4011 <mother xsi:type="ns:Person">
4012 <name xsi:type="xsd:Name">Mary</name>
4013 <gender xsi:type="ns:Gender">female</gender>
4014 <address xsi:type="ns:Address">
4016 <number xsi:type="unsignedInt">5</number>
4020 <father xsi:type="ns:Person">
4021 <name xsi:type="xsd:Name">Stuart</name>
4022 <gender xsi:type="ns:Gender">male</gender>
4023 <address xsi:type="ns:Address">
4024 <street xsi:type="xsd:string">Main st.</street>
4025 <number xsi:type="unsignedInt">13</number>
4033 The following program fragment decodes this content from standard input and reconstructs the original data structure on the heap:
4040 ns__Person *mother, *father, *john = NULL;
4042 soap_imode(&soap, SOAP_ENC_ZLIB); // optional: gzip is detected automatically
4044 if ((john = soap_get_ns__Person(&soap, NULL, NULL, NULL)) == NULL)
4046 mother = john->mother;
4047 father = john->father;
4049 soap_end_recv(&soap);
4050 soap_free_temp(&soap); // Clean up temporary data but keep deserialized data
4052 struct Namespace namespaces[] =
4054 {"SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/"},
4055 {"SOAP-ENC","http://schemas.xmlsoap.org/soap/encoding/"},
4056 {"xsi", "http://www.w3.org/2001/XMLSchema-instance"},
4057 {"xsd", "http://www.w3.org/2001/XMLSchema"},
4058 {"ns", "urn:person"}, // Namespace URI of the "Person" data type
4063 It is REQUIRED to either pass `NULL` to the `soap_get` routine, or a valid pointer to a data structure that can
4064 hold the decoded content. If the data `john` was already allocated then it does not need to be allocated again as the following demonstrates.
4065 The following program fragment decodes the SOAP content in a `struct ns__Person` allocated on the stack:
4072 ns__Person *mother, *father, john;
4074 soap_default_ns__Person(&soap, &john);
4075 soap_imode(&soap, SOAP_ENC_ZLIB); // optional
4077 soap_begin_recv(&soap);
4078 if (soap_get_ns__Person(&soap, &john, "johnnie", NULL) == NULL)
4082 struct Namespace namespaces[] =
4086 Note the use of `soap_default_ns__Person`. This routine is generated by the gSOAP `soapcpp2` tool and assigns default
4087 values to the fields of `john`.
4089 ### Serializing and Deserializing Class Instances to Streams
4091 C++ applications can define appropriate stream operations on objects for (de)serialization of objects on streams.
4092 This is best illustrated with an example. Section \ref serialize gives details on serializing types in general.
4099 struct soap *soap; // we need this, see below
4105 The `struct soap` member is used to bind the instances to a gSOAP
4106 context for (de)serialization. We use the gSOAP `soapcpp2` compiler from the command
4107 prompt to generate the class (de)serializers (assuming that `person.h`
4108 contains the class declaration):
4112 gSOAP generates the (de)serializers and an instantiation function for the class
4113 `soap_new_ns__person(struct soap *soap, int num)` to instantiate
4114 one or more objects and associate them with a gSOAP context for deallocation with `soap_destroy(soap)`. To instantiate a single object, omit
4115 the `num` parameter or set to -1. To instantiate an array of objects, set `num >= 0`.
4121 struct soap *soap = soap_new();
4122 ns__person *p = soap_new_ns__person(soap);
4124 cout << p; // serialize p in XML
4126 in >> p; // parse XML and deserialize p
4128 soap_destroy(soap); // deletes p too
4133 The stream operations are implemented as follows
4136 ostream &\operator<<(ostream &o, const ns__person &p)
4139 return o; // need a gSOAP context to serialize
4141 soap_omode(p.soap, SOAP_XML_TREE); // XML tree or graph
4142 p.soap_serialize(p.soap);
4143 soap_begin_send(p.soap);
4144 if (p.soap_put(p.soap, "person", NULL)
4145 || soap_end_send(p.soap))
4146 ; // handle I/O error
4149 istream &\operator>>(istream &i, ns__person &p)
4152 return o; // need a gSOAP context to parse XML and deserialize
4154 if (soap_begin_recv(p.soap)
4155 || p.soap_in(p.soap, NULL, NULL)
4156 || soap_end_recv(p.soap))
4157 ; // handle I/O error
4162 ### How to Specify Default Values for Omitted Data {#default}
4164 The gSOAP `soapcpp2` compiler generates `soap_default` functions for all data types. The default values of the primitive types can be
4165 easily changed by defining any of the following macros in the `stdsoap2.h` file:
4168 #define SOAP_DEFAULT_bool
4169 #define SOAP_DEFAULT_byte
4170 #define SOAP_DEFAULT_double
4171 #define SOAP_DEFAULT_float
4172 #define SOAP_DEFAULT_int
4173 #define SOAP_DEFAULT_long
4174 #define SOAP_DEFAULT_LONG64
4175 #define SOAP_DEFAULT_short
4176 #define SOAP_DEFAULT_string
4177 #define SOAP_DEFAULT_time
4178 #define SOAP_DEFAULT_unsignedByte
4179 #define SOAP_DEFAULT_unsignedInt
4180 #define SOAP_DEFAULT_unsignedLong
4181 #define SOAP_DEFAULT_unsignedLONG64
4182 #define SOAP_DEFAULT_unsignedShort
4183 #define SOAP_DEFAULT_wstring
4186 Instead of adding these to `stdsoap2.h`, you can also compile with option `-DWITH_SOAPDEFS_H` and include your
4187 definitions in file `soapdefs.h`.
4188 The absence of a data value in a receiving SOAP message will result in the assignment of a default value to a primitive type upon
4191 Default values can also be assigned to individual `struct` and `class` fields of primitive type. For example,
4196 char *name = "Unknown";
4198 enum Status { active, passive } status = passive;
4202 Default values are assigned to the fields on receiving a SOAP/XML message in which the data values are absent.
4204 Because method requests and responses are essentially structs, default values can also be assigned to method parameters. The
4205 default parameter values do not control the parameterization of C/C++ function calls, i.e. all actual parameters must be present
4206 when calling a function. The default parameter values are used in case an inbound request or response message lacks the XML
4207 elements with parameter values. For example, a Web service can use default values to fill-in absent parameters in a
4211 int ns__login(char *uid = "anonymous", char *pwd = "guest", bool granted);
4214 When the request message lacks uid and pwd parameters, e.g.:
4218 <?xml version="1.0" encoding="UTF-8"?>
4220 xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
4221 xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
4222 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4223 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
4224 xmlns:ns="http://tempuri.org">
4225 <SOAP-ENV:Body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
4229 </SOAP-ENV:Envelope>
4233 then the service uses the default values.
4234 In addition, the default values will show up in the SOAP/XML request and response message examples generated by the gSOAP
4237 # The wsdl2h WSDL and Schema Importer {#wsdlin}
4239 The `wsdl2h` tool is an advanced application that converts one or more
4240 WSDLs to C/C++. It can also be used without WSDLs to convert XML schemas (XSD
4241 files) to C/C++ to implement XML data bindings in C and C++.
4243 The creation of C and C++ applications from one of more WSDL service
4244 descriptions is a two-step process.
4246 To convert a WSDL to C++, use:
4250 to generate a C++ header file `file`.h.
4251 This generated header file is a Web service specification that contains the parameter types and service function definitions in an understandable format in C++ (or ANSI C as shown below).
4252 Web service operations are represented as function prototypes. Schema types are
4253 represented by semantically equivalent C/C++ types that are convenient and
4254 natural to use in a C/C++ application. The generated header file also contains
4255 various annotations related to the Web service properties defined in the WSDL.
4257 To generate ANSI C, use option `-c`:
4259 > wsdl2h -c file.wsdl
4261 Multiple WSDL specifications can be processed at once and saved to one file with the `-o` option:
4263 > wsdl2h -o file.h file1.wsdl file2.wsdl file3.wsdl
4265 You can retrieve WSDLs from one of more URLs:
4267 > wsdl2h -o file.h http://www.example.com/example.wsdl
4269 To convert XML schemas to C or C++ XML data binding code, use:
4271 > wsdl2h -o file.h file1.xsd file2.xsd file3.xsd
4273 The `wsdl2h`-generated header file `file.h` is processed by the
4274 `soapcpp2` tool to auto-generate the advanced data binding logic to
4275 convert the C/C++ data to XML and vice versa at runtime for your SOAP/XML
4278 To process a gSOAP header file `file.h` (generated by `wsdl2h`) to generate advanced XML data bindings for C++, use:
4280 > soapcpp2 -i -Iimport file.h
4282 When the header file `file.h` was generated for C++, then this command
4283 generates a couple of C++ source files (more details will follow in
4284 Section \ref soapcpp2 ) that implement XML encoders for the data binding.
4285 Option `-i` generates a client proxy objects and service objects to invoke
4286 and serve SOAP/XML operations, respectively. Option `-Iimport` sets the
4287 import directory for imported files from the package's `import`, such as
4288 `stlvector.h` for STL vector serialization support.
4290 When the header file `file.h` was generated for ANSI C, then the above
4291 command generates a couple of C files that implement XML encoders, client stubs
4292 for remote invocation, and service skeletons for service operations.
4294 Consider for example the following commands to implement a c++ client of a service:
4296 > wsdl2h -o calc.h http://www.genivia.com/calc.wsdl
4297 > soapcpp2 -i -Iimport calc.h
4299 The first command generates `calc.h` from the WSDL at the specified URL.
4300 The header file is then processed by the `soapcpp2` tool to generate the
4301 proxies (and service objects that we will not use) for the client application.
4303 The C++ client application uses the auto-generated `soapcalcProxy.h` class and
4304 `calc.nsmap` XML namespace table to access the Web
4305 service. Both need to be `#include`-d in your source. Then compile and link
4306 the `soapcalcProxy.cpp`, `soapC.cpp` and `stdsoap2.cpp` sources to complete the build.
4310 The `wsdl2h` tool is an advanced XML data binding tool for converting WSDLs
4311 and XML schemas (XSD files) to C or C++. The tool takes WSDL and/or XSD files
4312 or URLs and converts these to a C or C++ specification in one easy-to-read
4313 C/C++ header file. **The header file is not intended to be included in your
4314 code directly!**. It should be converted by `soapcpp2` to generate the logic
4315 for the data bindings. It can however be safely converted by a documentation
4316 tool such as Doxygen to analyze and represent the service operations and data
4317 in a convenient layout. To this end, the header file is self-explanatory.
4319 The `wsdl2h` tool generates only one file, the header file that includes
4320 all of the information obtained from all WSDL and schema files provided to the
4321 tool at the command-line prompt. The default output file name of `wsdl2h`
4322 is the first WSDL/schema input file name but with extension `.h` instead of
4323 `.wsdl` (or `.xsd`). When an input file is absent or a WSDL file from a
4324 Web location is accessed, the header output will be produced on the standard
4325 output unless option `-o` is used to direct the output to a file.
4327 The `wsdl2h` command-line options are:
4330 ------------------------ | ------
4331 `-a` | generate indexed struct names for local elements with anonymous types
4332 `-b` | bi-directional operations to serve one-way response messages (duplex)
4333 `-c` | generate C source code
4334 `-d` | use DOM to populate xs:any and xsd:anyType elements
4335 `-e` | don't qualify enum names
4336 `-f` | generate flat C++ class hierarchy for schema extensions
4337 `-g` | generate global top-level element declarations
4338 `-h` | print help information
4339 `-I path` | use path to locate source files for `#import`
4340 `-i` | don't import (advanced option)
4341 `-j` | don't generate `SOAP_ENV__Header` and `SOAP_ENV__Detail` definitions
4342 `-k` | don't generate `SOAP_ENV__Header` `mustUnderstand` qualifiers
4343 `-l` | include license information in output
4344 `-m` | use xsd.h module to import primitive types
4345 `-N name` | use `name` for service prefixes to produce a service for each binding
4346 `-n name` | use `name` as the base namespace prefix name instead of `ns`
4347 `-o file` | output to file
4348 `-P` | don't create polymorphic types inherited from `xsd__anyType`
4349 `-p` | create polymorphic types inherited from base `xsd__anyType` (this is automatically performed when WSDL contains polymorphic definitions)
4350 `-q name` | use `name` for the C++ namespace of all declarations
4351 `-r host[:port[:id:pw]]` | connect via proxy host, port, and proxy credentials
4352 `-r:uid:pwd` | connect with authentication credentials (digest auth requires SSL)
4353 `-R` | generate REST operations for REST bindings in the WSDL
4354 `-s` | don't generate STL code (no std::string and no std::vector)
4355 `-t file` | use type map file instead of the default file typemap.dat
4356 `-U` | map Unicode XML names to UTF8-encoded Unicode C/C++ identifiers
4357 `-u` | don't generate unions
4358 `-V` | display the current version and exit
4359 `-v` | verbose output
4360 `-W` | suppress warnings
4361 `-w` | always wrap response parameters in a response struct
4362 `-x` | don't generate `_XML any/anyAttribute` extensibility elements
4363 `-y` | generate typedef synonyms for structs and enums
4364 `-z1` | compatibility with 2.7.6e: generate pointer-based arrays
4365 `-z2` | compatibility with 2.7.15: qualify element/attribute referenced members
4366 `-z3` | compatibility with 2.7.16 to 2.8.7: qualify element/attribute references
4367 `-z4` | compatibility up to 2.8.11: don't generate union structs in std::vector
4368 `-z5` | compatibility up to 2.8.15
4369 `-z6` | compatibility up to 2.8.17
4370 `-_` | don't generate `_USCORE` (replace with Unicode _x005f)
4372 Note: see `README.txt` in the `wsdl` directory for the latest
4373 information on installation and options to of the `wsdl2h` WSDL/schema importer.
4375 ## Customizing Data Bindings With The typemap.dat File {#typemap}
4377 The `typemap.dat` file for the `wsdl2h` tool is intended to customize or optimize
4378 the type bindings by mapping schema types to C/C++ types. It contains custom
4379 XML Schema to C/C++ type bindings and a few bindings are defined for
4382 Here is an example typemap file's content:
4386 # This file contains custom definitions of the XML Schema types and
4387 # C/C++ types for your project, and XML namespace prefix definitions.
4388 # The wsdl2h WSDL importer consults this file to determine bindings.
4391 // This comment will be included in the generated .h file
4392 // You can include any additional declarations, includes, imports, etc.
4393 // within [ ] sections. The brackets MUST appear at the start of a line
4395 # XML namespace prefix definitions can be provided to override the
4396 # default choice of ns1, ns2, ... prefixes. For example:
4398 i = "http://www.soapinterop.org/"
4399 s = "http://www.soapinterop.org/xsd"
4403 Type bindings can be provided to bind XML schema types to C/C++
4404 types for your project.
4405 Type bindings have four parts:
4409 prefix__type = declaration | use | ptr-use
4413 where 'prefix__type' is the C/C++-translation of the schema type,
4414 'declaration' introduces the C/C++ type in the header file, the optional
4415 'use' specifies how the type is used directly, and the optional
4416 'ptr-use' specifies how the type is used as a pointer type.
4420 # Example XML Schema and C/C++ type bindings:
4423 xsd__string = | char* | char*
4424 xsd__boolean = enum xsd__boolean { false_, true_ }; | enum xsd__boolean
4425 xsd__base64Binary = class xsd__base64Binary { unsigned char *__ptr; int __size; }; | xsd__base64Binary | xsd__base64Binary
4426 # You can extend structs and classes with member data and functions.
4427 # For example, adding a constructor to ns__myClass:
4428 ns__myClass = $ ns__myClass();
4429 # The general form is
4430 # class_name = $ member;
4434 The `i` and `s` prefixes are declared such that the header file output by the WSDL parser will use these to produce C/C++ code.
4435 XML Schema types are associated with an optional C/C++ type declaration, a use reference, and a pointer-use reference. The pointer-use reference of the `xsd__byte` type for example, is `int*` because `char*` is reserved for strings.
4437 When a type binding requires only the usage to be changed, the
4438 declaration part can be given by an elipsis ..., as in:
4442 prefix__type = ... | use | ptr-use
4446 This ensures that the wsdl2h-generated type definition is preserved,
4447 while the use and ptr-use are remapped.
4449 This method is useful to serialize dynamic types in C, where elements types int
4450 XML carry the *`xsi:type`* attribute.
4452 The following example illustrates an "any" type mapping for the
4453 *`ns:sometype`* XSD type in a schema. This type will be replaced with a "any"
4454 type wrapper that supports dynamic serialization with *`xsi:type`*:
4465 xsd__anyType = ... | struct __any | struct __any
4469 where *`__type`* and *`__item`* are used to (de)serialize any data type in the wrapper,
4470 including base and its derived types based on *`xsi:type`* attribuation.
4472 To support complexType extensions that are dynamically bound in C code, i.e.
4473 polymorphic types based on inheritance hierarchies, we can redeclare the base
4474 type of a hierarchy as a wrapper type and use the `__type` to serialize
4475 base or derived types. One addition is needed to support base type
4476 serialization without the use of *`xsi:type`* attributes. The absence of this attribute requires the serialization of the base type.
4478 Basically, we need to be able to both handle a base type and its extensions
4479 as per schema extensibility. Say base type *`ns:base`* is a complexType that is extended by several other complexTypes. To implement dynamic binding in C to serialize the base type and derived types, we define:
4488 struct ns__base *__self;
4491 ns__base = ... | struct __ns__base | struct __ns__base
4495 The *`__self`* field refers to the element tag (basically a struct member name)
4496 to which the *`ns:base`* type is associated. So for example, we see in the soapcpp2-generated output:
4502 struct __ns__base name;
4507 where `__item` represents `name` when the `__ns__base` is
4508 serialized with an *`xsi:type`* attribute, and `__self` represents
4509 `name` when the `__ns__base` is serialized wwithout an *`xsi:type`*
4510 attribute. Therefore, the dynamic binding defaults to `struct ns__base *__self` when no dynamic type information in XML is available.
4512 Additional data and function members can be provided to extend a
4513 generated struct or class.
4514 Class and struct extensions are of the form:
4518 prefix__type = $ member-declaration
4522 For example, to add a constructor and destructor to class myns__record:
4526 myns__record = $ myns__record();
4527 myns__record = $ ~myns__record();
4531 Type remappings can be given to map a type to another type:
4535 prefix__type1 == prefix__type2
4539 which replaces *`prefix__type1`* by *`prefix__type2`* in the wsdl2h output.
4544 SOAP_ENC__boolean == xsd__boolean
4548 where *`SOAP_ENC__boolean`* is mapped to *`xsd__boolean`*, which in turn may be mapped to a C *`enum xsd__boolean`* type or C++ *`bool`* type.
4550 # Using the soapcpp2 Compiler and Code Generator {#soapcpp2}
4552 The `soapcpp2` compiler and code generator is invoked from the command line
4553 and optionally takes the name of a header file as an argument or, when the file
4554 name is absent, parses the standard input:
4556 > soapcpp2 headerfile.h
4558 where `aheaderfile.h` is a C/C++ header file generated by `wsdl2h` or
4559 developed manually to specify the SOAP/XML service operations as function
4560 prototypes and the C/C++ data types to be auto-mapped to XML.
4562 The `soapcpp2` tool produces C/C++ source files. These files are used to
4563 implement SOAP/XML clients and services, and to implement the advanced XML data
4564 binding logic to convert C/C++ data into XML and vice versa.
4566 The type of files generated by `soapcpp2` are:
4568 * `soapStub.h` A modified and annotated header file produced from the input header file
4570 * `soapH.h` Main header file to be included by all client and service sources
4572 * `soapC.cpp` Serializers and deserializers for the specified data structures
4574 * `soapClient.cpp` Client stub routines for remote operations
4576 * `soapServer.cpp` Service skeleton routines
4578 * `soapClientLib.cpp` Client stubs combined with local static (de)serializers
4580 * `soapServerLib.cpp` Service skeletons combined with local static (de)serializers
4582 * `soapXYZProxy.h` A C++ proxy object (link with soapC.cpp soapClient.cpp)
4584 * `soapXYZProxy.h` With option -i: proxy object (link with soapC.cpp and soapXYZProxy.cpp)
4586 * `soapXYZProxy.cpp` With option -i: proxy code
4588 * `soapXYZObject.h` A C++ server object (link with soapC.cpp and soapServer.cpp)
4590 * `soapXYZService.h` With option -i: server object (link with soapC.cpp and soapXYZService.cpp)
4592 * `soapXYZService.cpp` With option -i: server code
4594 * `.xsd` An `ns.xsd` file is generated with an XML Schema for each namespace prefix `ns` used by a data structure in the header file input to the compiler, see Section \ref wsdl
4596 * `.wsdl` A `ns.wsdl` file is generated with an WSDL description for each namespace prefix `ns` used by a service operation in the header file input to the compiler, see Section \ref wsdl
4598 * `.xml` Several SOAP/XML request and response files are generated. These are example message files are valid provided that sufficient schema namespace directives are added to the header file or the generated .nsmap namespace table for the
4599 client/service is not modified by hand
4601 * `.nsmap` A `ns.nsmap` file is generated for each namespace prefix `ns` used by a service operation in the header file input to the compiler, see Section \ref wsdl . The file contains a namespace mapping table that can be used in the client/service sources
4603 Both client and service applications are developed from a header file that
4604 specifies the service operations. If client and service applications are
4605 developed with the same header file, the applications are guaranteed to be
4606 compatible because the stub and skeleton routines use the same serializers and
4607 deserializers to encode and decode the parameters. Note that when client and
4608 service applications are developed together, an application developer does not
4609 need to know the details of the internal SOAP encoding used by the client and
4612 The `soapClientLib.cpp` and `soapServerLib.cpp` can be used to build (dynamic) client and server libraries. The serialization routines are local (static) to avoid link symbol conflicts. You must create a separate library for SOAP Header and Fault handling, as described in Section \ref dylibs .
4614 The following files are part of the gSOAP package and are required to build client and service applications:
4616 * `stdsoap2.h` Header file of `stdsoap2.cpp` runtime library
4618 * `stdsoap2.c` Runtime C library with XML parser and run-time support routines
4620 * `stdsoap2.cpp` Runtime C++ library identical to `stdsoap2.c`
4622 ## soapcpp2 Options {#options}
4624 The `soapcpp2` source-to-source compiler supports the following command-line options:
4627 ----------- | ------
4628 `-1` | generate SOAP 1.1 bindings
4629 `-2` | generate SOAP 1.2 bindings
4630 `-0` | no SOAP bindings, use REST
4631 `-C` | generate client-side code only
4632 `-S` | generate server-side code only
4633 `-T` | generate server auto-test code
4634 `-Ec` | generate extra routines for deep data copying
4635 `-Ed` | generate extra routines for deep data deletion
4636 `-Et` | generate extra routines for data traversals with walker functions
4637 `-L` | do not generate soapClientLib/soapServerLib
4638 `-a` | use SOAPAction with WS-Addressing to invoke server-side operations
4639 `-A` | require SOAPAction to invoke server-side operations
4640 `-b` | serialize byte arrays `char[N]` as string
4641 `-c` | generate pure C code
4642 `-d <path>` | save sources in directory specified by `<path>`
4643 `-e` | generate SOAP RPC encoding style bindings
4644 `-f N` | multiple soapC files, with N serializer definitions per file (N>=10)
4645 `-h` | print a brief usage message
4646 `-i` | generate service proxies and objects inherited from soap struct
4647 `-j` | generate C++ service proxies and objects that can share a soap struct
4648 `-I <path>` | use `<path>` for `#import` (paths separated with ':' or ';' for windows)
4649 `-l` | generate linkable modules (experimental)
4650 `-m` | generate Matlab code for MEX compiler
4651 `-n` | when used with `-p`, enables multi-client and multi-server builds: sets compiler option `WITH_NONAMESPACES`, see Section \ref compilerflags saves the namespace mapping table with name `<name>_namespaces` instead of `namespaces`
4652 | renames `soap_serve()` into `<name>_serve()` and `soap_destroy()` into `<name>_destroy()`
4653 `-p <name>` | save sources with file name prefix `<name>` instead of "`soap`"
4654 `-q <name>` | use `name` for the C++ namespace of all declarations
4655 `-r` | generate soapReadme.md report
4656 `-s` | generates deserialization code with strict XML validation checks
4657 `-t` | generates code to send typed messages (with the *`xsi:type`* attribute)
4658 `-u` | uncomment comments in WSDL/schema output by suppressing XML comments
4659 `-V` | display the current version and exit
4660 `-v` | verbose output
4661 `-w` | do not generate WSDL and schema files
4662 `-x` | do not generate sample XML message files
4663 `-y` | include C/C++ type access information in sample XML messages
4664 `-z1` | compatibility: generate old-style C++ service proxies and objects
4665 `-z2` | compatibility with 2.7.x: omit XML output for NULL pointers
4666 `-z3` | compatibility with 2.8.30 and earlier: _param_N is indexed globally
4670 > soapcpp2 -c -d 'projects' -pmy file.h
4678 * `projects/myClient.c`
4680 * `projects/myServer.c`
4682 * `projects/myStub.h`
4684 MS Windows users can use the usual "`/`" for options, for example:
4686 soapcpp2 /cd '..\projects' /pmy file.h
4688 Compiler options `c, i, n, l, w` can be set in the gSOAP header file using the `//gsoapopt` directive. For example,
4691 // Generate pure C and do not produce WSDL output:
4693 int ns__myMethod(char*, char**); // takes a string and returns a string (as pointed to)
4696 ## SOAP 1.1 Versus SOAP 1.2 and Dynamic Switching
4698 gSOAP supports SOAP 1.1 by default. SOAP 1.2 support is automatically turned on when the appropriate SOAP 1.2 namespace is used, which shows up in
4699 the namespace mapping table:
4702 struct Namespace namespaces[] =
4704 {"SOAP-ENV", "http://www.w3.org/2003/05/soap-envelope", ... },
4705 {"SOAP-ENC", "http://www.w3.org/2003/05/soap-encoding, ... "},
4710 Normally the `soapcpp2`-generated namespace table allows dynamic switching between SOAP 1.1 to SOAP 1.2 by providing the SOAP 1.2 namespace
4711 as a **pattern** in the third column of a namespace table:
4714 struct Namespace namespaces[] =
4716 {"SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/", "http://www.w3.org/*/soap-encoding"},
4717 {"SOAP-ENC", "http://schemas.xmlsoap.org/soap/encoding/", "http://www.w3.org/*/soap-envelope"},
4722 where the "`*`" in the third column of the namespace URI pattern is a meta wildcard. This is used to match and accept inbound namespaces.
4724 This way, gSOAP Web services can respond to either SOAP 1.1 or SOAP 1.2 requests. gSOAP will automatically return SOAP 1.2 responses for SOAP 1.2 requests.
4726 The gSOAP `soapcpp2` tool generates a `.nsmap` file with `SOAP-ENV` and `SOAP-ENC` namespace patterns similar to the above.
4727 Since clients issue a send first, they will always use SOAP 1.1 for requests when the namespace table is similar as shown above.
4728 Clients can accept SOAP 1.2 responses by inspecting the response message.
4730 To use SOAP 1.2 by default and allow SOAP 1.1 messages to be received, use the `soapcpp2 -2` option to generate SOAP 1.2 conformant `.nsmap` and `.wsdl` files. Alternatively, add the following line to your service definitions header file (generated by `wsdl2h`) for `soapcpp2`:
4733 #import "import/soap12.h"
4736 @warning SOAP 1.2 does not support partially transmitted arrays. So the `__offset` field of a dynamic array is meaningless.
4738 @warning SOAP 1.2 requires the use of `SOAP_ENV__Code`, `SOAP_ENV__Reason`, and `SOAP_ENV__Detail` fields
4739 in a `SOAP_ENV__Fault` fault struct, while SOAP 1.1 uses `faultcode`, `faultstring`, and `detail` fields.
4740 Use `soap_receiver_fault_subcode(struct soap *soap, const char *subcode, const char *faultstring, const char *detail)` to set a SOAP 1.1/1.2
4741 fault at the server-side with a fault subcode (SOAP 1.2).
4742 Use `soap_sender_fault_subcode(struct soap *soap, const char *subcode, const char *faultstring, const char *detail)` to set a SOAP 1.1/1.2
4743 unrecoverable Bad Request fault at the server-side with a fault subcode (SOAP 1.2).
4745 ## The soapdefs.h Header File {#soapdefs}
4747 The `soapdefs.h` header file is included in `stdsoap2.h` when compiling with option `-DWITH_SOAPDEFS_H`:
4749 > c++ -DWITH_SOAPDEFS_H -c stdsoap2.cpp
4751 The `soapdefs.h` file allows users to include definitions and add includes without requiring changes to `stdsoap2.h`. You can also specify the header file name to include as a macro `SOAPDEFS_h` to override the name `soapdefs.h`:
4753 > c++ -DSOAPDEFS_H=mydefs.h -c stdsoap2.cpp
4758 // Contents of soapdefs.h
4760 #define SOAP_BUFLEN 65536 // use large send/recv buffer
4763 The following header file can now refer to `ostream`:
4766 extern class ostream; // ostream can't be (de)serialized, but need to be declared to make it visible to gSOAP
4769 virtual void print(ostream &s) const; // need ostream here
4774 See also Section \ref transient .
4776 ## How to Build Modules and Libraries with the #module Directive {#module}
4778 The `#module` directive is used to build modules. A library can be built from a module and linked with multiple Web services applications. The directive should appear at the top of the header file and has the following formats:
4787 #module "name" "fullname"
4790 where *name* must be a unique short name for the module. The name is case insensitive and MUST not exceed 4 characters in length. The *fullname*, when present, represents the full name of the module.
4792 The rest of the content of the header file includes type declarations and optionally the declarations of service operations and SOAP Headers/Faults. When the gSOAP `soapcpp2` compiler processes the header file module, it will generate the source codes for a library. The Web services application that uses the library should use a header file that imports the module with the `#import` directive.
4797 /* Contents of module.h */
4805 The `module.h` header file declares a long, char*, and a `struct ns__X`. The module name is "test", so the gSOAP `soapcpp2` compiler produces a `testC.cpp` file with the (de)serializers for these types. The `testC.cpp` library can be separately compiled and linked with an application that is built from a header file that imports "module.h" using `#import "module.h"`. You should also compile `testClient.cpp` when you want to build a library that includes the service operations that you defined in the module header file.
4807 There are some limitations on a sequence of module imports. A module MUST be imported into another header to use the module content and you MUST place this import statement before all other statements in the file, including other imports (except when these are also modules). It is also advised to put all basic data type definitions in the root module of a module import hierarchy, e.g. using `typedef` to declare XSD types (see also Section \ref primitive ).
4809 You cannot use a module alone to build a SOAP or XML application. That is, the final gSOAP header file in the import chain SHOULD NOT be a module.
4811 When multiple modules are linked, the types that they declare MUST be declared in one module only to avoid name clashes and link errors. You cannot create two modules that share the same type declaration and link the modules. When necessary, you should consider creating a module hierarchy such that types are declared only once and by only one module when these modules must be linked.
4813 ## How to use the #import Directive {#import}
4815 The `#import` directive is used to include gSOAP header files into other gSOAP header files for processing with
4816 the gSOAP compiler `soapcpp2`.
4817 The C `#include` directive cannot be used to include gSOAP header files.
4818 The `#include` directive is reserved to control the post-gSOAP compilation process, see \ref pragmas .
4820 The `#import` directive is used for two purposes: you can use it to include the contents of a header file into another header file and you can use it to import a module, see \ref module .
4822 An example of the `#import` directive:
4825 #import "mydefs.gsoap"
4826 int ns__mymethod(xsd__string in, xsd__int *out);
4829 where `"mydefs.gsoap"` is a gSOAP header file that defines `xsd__string` and `xsd__int`:
4832 typedef char *xsd__string;
4833 typedef int xsd__int;
4836 When importing a module, where the module content is declared with `#module`, then note that this module MUST place the import statement before all other statements in the header file, including other imports (except when these are also modules).
4838 ## How to Use #include and #define Directives {#pragmas}
4840 The `#include` and `#define` directives are normally ignored by the gSOAP `soapcpp2` compiler and just passed on to the generated code.
4841 Thus, the gSOAP compiler will not actually parse the contents of the header files provided by the `#include` directives in a header file.
4842 Instead, the `#include` and `#define` directives will be added to the generated `soapH.h` header file **before**
4843 any other header file is included. Therefore, `#include` and `#define` directives can be used to control the C/C++
4844 compilation process of the sources of an application. However, they have no effect on `soapcpp2`.
4846 The following example header file refers to `ostream` by including `<ostream>`:
4850 #define WITH_COOKIES // use HTTP cookie support (you must compile stdsoap2.cpp with -DWITH_COOKIES)
4851 #define WITH_OPENSSL // enable HTTPS/SSL support (you must compile stdsoap2.cpp with -DWITH_OPENSSL)
4852 #define WITH_GNUTLS // enable HTTPS/SSL support (you must compile stdsoap2.cpp with -DWITH_GNUTLS)
4853 #define SOAP_DEFAULT_float FLT_NAN // use NaN instead of 0.0
4854 extern class ostream; // ostream can't be (de)serialized, but need to be declared to make it visible to gSOAP
4857 virtual void print(ostream &s) const; // need ostream here
4862 This example also uses `#define` directives for various settings in the target source code.
4864 @warning Note that the use of `#define` in the header file does not automatically result in compiling
4865 `stdsoap2.cpp` with these directives. You MUST use the `-DWITH_COOKIES` and `-DWITH_OPENSSL` (or `-DWITH_GNUTLS` options when
4866 compiling `stdsoap2.cpp` before linking the object file with your codes. As an alternative, you can use `#define WITH_SOAPDEFS_H` and put the `#define` directives in the `soapdefs.h` file.
4868 ## Compiling a SOAP/XML Client Application with soapcpp2
4870 After invoking the gSOAP `soapcpp2` tool on a header file description of a service, the client application can be compiled on a Linux machine as follows:
4872 > c++ -o myclient myclient.cpp stdsoap2.cpp soapC.cpp soapClient.cpp
4874 Or on a Unix machine:
4876 > c++ -o myclient myclient.cpp stdsoap2.cpp soapC.cpp soapClient.cpp -lsocket -lxnet -lnsl
4878 (Depending on your system configuration, the libraries `libsocket.a`,
4879 `libxnet.a`, `libnsl.a` or dynamic `*.so` versions of those libraries are required.)
4881 The `myclient.cpp` file must include `soapH.h` and must define a global namespace mapping table. A typical client program layout with namespace mapping table is shown below:
4884 // Contents of file "myclient.cpp"
4887 // A service operation invocation:
4888 soap_call_some_remote_method(...);
4890 struct Namespace namespaces[] =
4891 { // {"ns-prefix", "ns-name"}
4892 {"SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/"},
4893 {"SOAP-ENC", "http://schemas.xmlsoap.org/soap/encoding/"},
4894 {"xsi", "http://www.w3.org/2001/XMLSchema-instance"},
4895 {"xsd", "http://www.w3.org/2001/XMLSchema"},
4896 {"ns1", "urn:my-remote-method"},
4902 A mapping table is generated by the gSOAP `soapcpp2` compiler that can be used in the source, see Section \ref wsdl .
4904 ## Compiling a SOAP/XML Web Service with soapcpp2
4906 After invoking the gSOAP `soapcpp2` tool on a header file description of the service, the server application can be compiled on a Linux machine as follows:
4908 > c++ -o myserver myserver.cpp stdsoap2.cpp soapC.cpp soapServer.cpp
4910 Or on a Unix machine:
4912 > c++ -o myserver myserver.cpp stdsoap2.cpp soapC.cpp soapServer.cpp -lsocket -lxnet -lnsl
4914 (Depending on your system configuration, the libraries `libsocket.a`,
4915 `libxnet.a`, `libnsl.a` or dynamic `*.so` versions of those libraries are required.)
4917 The `myserver.cpp` file must include `soapH.h` and must define a global namespace mapping table. A typical service program layout with namespace mapping table is shown below:
4920 // Contents of file "myserver.cpp"
4924 soap_serve(soap_new());
4927 // Implementations of the service operations as C++ functions
4929 struct Namespace namespaces[] =
4930 { // {"ns-prefix", "ns-name"}
4931 {"SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/"},
4932 {"SOAP-ENC", "http://schemas.xmlsoap.org/soap/encoding/"},
4933 {"xsi", "http://www.w3.org/2001/XMLSchema-instance"},
4934 {"xsd", "http://www.w3.org/2001/XMLSchema"},
4935 {"ns1", "urn:my-remote-method"},
4941 When the gSOAP service is compiled and installed as a CGI application, the `soap_serve` function acts as a service dispatcher. It listens to standard input and
4942 invokes the method via a skeleton routine to serve a SOAP client request. After the request is served, the response is encoded in
4943 SOAP and send to standard output. The method must be implemented in the server application and the type signature of the method
4944 must be identical to the service operations specified in the header file. That is, the function prototype in the header file must be a
4945 valid prototype of the method implemented as a C/C++ function.
4947 ## Compiling Web Services and Clients in ANSI C
4949 The gSOAP `soapcpp2` compiler can be used to create pure C Web services and clients. The gSOAP stub and skeleton compiler
4950 `soapcpp2` generates `.cpp` files by default. The compiler generates `.c` files with the `-c` option.
4951 However, these files only use C syntax and data types **if** the header
4952 file input to `soapcpp2` uses C syntax and data types. For example:
4954 > soapcpp2 -c quote.h
4955 > cc -o quote quote.c stdsoap2.c soapC.c soapClient.c
4957 Warnings will be issued by the compiler when C++ class declarations occur in the header file.
4959 ## Limitations of gSOAP {#limitations}
4961 gSOAP is SOAP 1.1 and SOAP 1.2 compliant and supports SOAP RPC and document/literal operations.
4963 From the perspective of the C/C++ language, a few C++ language features are not supported by gSOAP and these features cannot be used in the specification of SOAP service operations.
4965 There are certain limitations for the following C++ language constructs:
4967 * STL and STL templates: The gSOAP `soapcpp2` compiler supports C++ strings `std::string` and `std::wstring` (see Section \ref strings ) and the STL containers `std::deque`, `std::list`, `std::vector`, and `std::set`, (see Section \ref templates ).
4969 * Templates; The gSOAP `soapcpp2` compiler is a preprocessor that cannot determine the template instantiations used by the main program, nor can it generate templated code. You can however implement containers similar to the STL containers.
4971 * Multiple inheritance: Single class inheritance is supported. Multiple inheritance cannot be supported due to limitations of the SOAP protocol.
4973 * Abstract methods: A class must be instantiatable to allow decoding of instances of the class.
4975 * Directives: Directives and pragmas such as `#include` and `#define` are interpreted by the gSOAP `soapcpp2` compiler.
4976 However, the interpretation is different compared to the usual handling of directives, see Section \ref pragmas . If necessary, a traditional C++
4977 preprocessor can be used for the interpretation of directives. For example, Unix and Linux users can use "*`cpp -B`*"
4978 to expand the header file, e.g. *`cpp -B myfile.h | soapcpp2`*.
4979 Use the gSOAP `#import` directive to import gSOAP header files, see \ref import .
4981 * [C and C++ programming statements] All class methods of a class should be declared within the class declaration in the header file, but the methods should not be implemented in code. All class method implementations must be defined within another C++ source file and linked to the application.
4983 The following data types require some attention to ensure they are serialized:
4986 * `union` types: A `union` data type can not be serialized unless run-time information is associated with a `union` in a struct/class as discussed in Section \ref union . An alternative is to use a `struct` with a pointer type for each field. Because `NULL` pointers are not encoded, the resulting encoding will appear as a union type if only one pointer field is valid (i.e. non-`NULL`) at the time that the data type is encoded.
4988 * `void` and `void *` types: The `void` data type cannot be serialized unless run-time type information is associated with the pointer using a `int __type` field in the struct/class that contains the `void*`. The `void *` data type is typically used to point to some object or to some array of some type of objects at run-time. The compiler cannot determine the type of data pointed to and the size of the array pointed to. A struct or class with a `void*` field can be augmented to support the (de)serialization of the `void*` using a `int __type` field as described in Section \ref void .
4990 * Pointers to sequences of elements in memory: Any pointer, except for C strings which are pointers to a sequence of
4991 characters, are treated by the compiler as if the pointer points to **only one element in memory** at run-time. Consequently,
4992 the encoding and decoding routines will ignore any subsequent elements that follow the first in memory. For the same reason,
4993 arrays of undetermined length, e.g. `float a[]` cannot be used. gSOAP supports dynamic arrays using a special type convention,
4994 see Section \ref dynarray .
4996 * Uninitialized pointers: Obviously, all pointers that are part of a data structure must be valid or `NULL` to enable
4997 serialization of the data structure at run time.
4999 There are a number of programming solutions that can be adopted to circumvent these limitations. Instead of using `void *`, a program
5000 can in some cases be modified to use a pointer to a known type. If the pointer is intended to point to different types of objects, a generic
5001 base class can be declared and the pointer is declared to point to the base class. All the other types are declared to be derived
5002 classes of this base class. For pointers that point to a sequence of elements in memory dynamic arrays should be used instead,
5005 ## Library Build Flags {#compilerflags}
5007 The following macros (`#define`s) can be used to enable certain optional features by compiling all of the source code files with compiler option `-D` to set the macro:
5010 --------------------------- | ------
5011 `WITH_SOAPDEFS_H` | includes the `soapdefs.h` file for custom settings, see Section \ref soapdefs
5012 `SOAPDEFS_H` | the header file to include, if different from `soapdefs.h` (see above)
5013 `WITH_COOKIES` | enables HTTP cookies, see Sections \ref clientcookie \ref servercookie
5014 `WITH_OPENSSL` | enables OpenSSL, see Sections \ref clientopenssl \ref serveropenssl
5015 `WITH_GNUTLS` | enables GNUTLS, see Sections \ref clientopenssl \ref serveropenssl
5016 `WITH_IPV6` | enables IPv6 support (compile ALL sources with this macro set)
5017 `WITH_IPV6_V6ONLY` | IPv6-only server option (compile ALL sources with this macro set)
5018 `WITH_NO_IPV6_V6ONLY` | permits IPv4 and IPv6 (compile ALL sources with this macro set)
5019 `WITH_TCPFIN` | use TCP FIN after sends when socket is ready to close
5020 `WITH_FASTCGI` | enables FastCGI, see Sections \ref fastcgi
5021 `WITH_GZIP` | enables gzip and deflate compression, see Section \ref compression
5022 `WITH_ZLIB` | enables deflate compression only, see Section \ref compression
5023 `WITH_NOIO` | eliminates need for file IO and BSD socket library, see Section \ref noio
5024 `WITH_NOIDREF` | eliminates href/ref and id attributes to (de)serialize multi-ref data, or use the `SOAP_XML_TREE` runtime flag
5025 `WITH_NOHTTP` | eliminates HTTP stack to reduce code size
5026 `WITH_NOZONE` | removes and ignores the timezone in xsd:dateTime
5027 `WITH_LEAN` | creates a small-footprint executable, see Section \ref lean
5028 `WITH_LEANER` | creates an even smaller footprint executable, see Section \ref lean
5029 `WITH_FAST` | use faster memory allocation when used with `WITH_LEAN`/`WITH_LEANER`
5030 `WITH_COMPAT` | removes dependency on C++ stream libraries, eliminating C++ exceptions
5031 `WITH_NONAMESPACES` | removes dependence on global `namespaces` table, MUST set it explicitly with `soap_set_.namespaces()` see also Section \ref nstable
5032 `WITH_PURE_VIRTUAL` | to generate C++ abstract service classes with pure virtual methods
5033 `WITH_NOEMPTYSTRUCT` | inserts a dummy member in empty structs to allow compilation
5034 `WITH_NOGLOBAL` | omit SOAP Header and Fault serialization code, prevents duplicate definitions with generated soapXYZLib code
5035 `WITH_CDATA` | retain the parsed CDATA sections in literal XML strings (no conversion, default)
5036 `WITH_C_LOCALE` | use locale functions when available to ensure locale-independent number conversions (force the use of C locale)
5037 `WITH_CASEINSENSITIVETAGS` | enable case insensitive XML parsing
5038 `WITH_REPLACE_ILLEGAL_UTF8` | strict UTF-8: replaces UTF8 content that is outside the allowed range, with U+FFFD
5039 `SOCKET_CLOSE_ON_EXIT` | prevents a server port from staying in listening mode after exit by internally setting `fcntl(sock, F_SETFD, FD_CLOEXEC)`
5041 Compile-time flags to change the default engine settings:
5044 --------------------------- | ------
5045 `SOAP_BUFLEN` | the length of the internal message buffer (affects socket comms)
5046 `SOAP_TAGLEN` | maximum length of XML tags and URL domain names (buffering)
5047 `SOAP_SSL_RSA_BITS` | the length of the RSA key (2048 by default)
5048 `SOAP_UNKNOWN_CHAR` | an 8 bit code that represents a character that could not be converted to an ASCII `char` (e.g. from Unicode, applicable when `SOAP_C_UTFSTRING` is off)
5050 @warning it is important that all of these macros MUST be consistently defined to
5051 compile all sources, such as `stdsoap2.cpp`, `soapC.cpp`,
5052 `soapClient.cpp`, `soapServer.cpp`, and all application sources that
5053 include `stdsoap2.h` or `soapH.h`. If the macros are not consistently
5054 used, the application will crash due to a mismatches in the declaration and
5055 access of the gSOAP context.
5057 ## Run Time Flags {#flags}
5059 gSOAP provides flags to control the input and output mode settings at runtime.
5060 These flags are divided into four categories: transport (IO), content encoding
5061 (ENC), XML marshalling (XML), and C/C++ data mapping (C).
5063 Although gSOAP is fully SOAP 1.1 compliant, some SOAP implementations may have
5064 trouble accepting multi-reference data and/or require explicit nil data so
5065 these flags can be used to put gSOAP in "safe mode". In addition, the
5066 embedding (or inlining) of multi-reference data is adopted in the SOAP 1.2
5067 specification, which gSOAP automatically supports when handling with SOAP 1.2
5070 To set and clear flags for inbound message processing use:
5073 soap_set_imode(soap, inflag);
5074 soap_clr_imode(soap, inflag);
5077 To set and clear the flags for outbound message processing use:
5080 soap_set_omode(soap, outflag);
5081 soap_clr_imode(soap, outflag);
5084 To allocate and initialize a gSOAP context with inbound and outbound flags use:
5087 soap_new2(soap, inflag, outflag);
5090 To initialize an unitialized gSOAP context with inbound and outbound flags use:
5093 soap_init2(soap, inflag, outflag);
5096 The input-mode and output-mode flags for inbound and outbound message processing are:
5098 flag | in, out, or in+out result
5099 -------------------- | -------------------------
5100 `SOAP_IO_FLUSH` | in: disable buffering and flush output (default for all file-based output)
5101 `SOAP_IO_BUFFER` | in: enable buffering (default for all socket-oriented connections)
5102 `SOAP_IO_STORE` | in: store entire message to calculate HTTP content length
5103 `SOAP_IO_CHUNK` | out: use HTTP chunking
5104 `SOAP_IO_LENGTH` | out: (internal flag) require apriori calculation of content length
5105 `SOAP_IO_KEEPALIVE` | in+out: attempt to keep socket connections alive (open)
5106 `SOAP_IO_UDP` | in+out: use UDP (datagram) transport, maximum message length is `SOAP_BUFLEN`
5107 `SOAP_ENC_PLAIN` | in+out: use plain messages without parsing or emitting HTTP headers
5108 `SOAP_ENC_XML` | deprecated, alias for `SOAP_ENC_PLAIN`
5109 `SOAP_ENC_DIME` | out: use DIME encoding (automatic when DIME attachments are used)
5110 `SOAP_ENC_MIME` | out: use MIME encoding (activate using `soap_set_mime`)
5111 `SOAP_ENC_MTOM` | out: use MTOM XOP attachments (instead of DIME)
5112 `SOAP_ENC_ZLIB` | out: compress encoding with Zlib (deflate or gzip format)
5113 `SOAP_ENC_SSL` | in+out: encrypt with SSL (automatic with "https:" endpoints)
5114 `SOAP_XML_INDENT` | out: produces indented XML output
5115 `SOAP_XML_CANONICAL` | out: produces canonical XML output
5116 `SOAP_XML_DEFAULTNS` | out: forces output of xmlns="..." default namespace declarations
5117 `SOAP_XML_IGNORENS` | in: ignores the use of XML namespaces in input
5118 `SOAP_XML_STRICT` | in: XML strict validation
5119 `SOAP_XML_TREE` | out: serialize data as XML trees (no multi-ref, duplicate data when necessary); in: ignore id attributes (do not resolve id-ref)
5120 `SOAP_XML_GRAPH` | out: serialize data as an XML graph with inline multi-ref (SOAP 1.2 default)
5121 `SOAP_XML_NIL` | out: serialize NULL data as xsi:nil attributed elements
5122 `SOAP_XML_NOTYPE` | out: disable *`xsi:type`* attributes
5123 `SOAP_C_NOIOB` | in: do not fault with `SOAP_IOB`
5124 `SOAP_C_UTFSTRING` | in+out: (de)serialize 8-bit strings "as is" (strings MUST have UTF-8 encoded content)
5125 `SOAP_C_MBSTRING` | in+out: enable multibyte character support (depends on locale)
5126 `SOAP_C_NILSTRING` | out: serialize empty strings as nil (ommited element)
5128 The flags can be selectively turned on/off at any time, for example when
5129 multiple Web services are accessed by a client that require special treatment.
5131 All flags are orthogonal, except
5134 `SOAP_IO_STORE`, and
5136 which are enumerations and only one of these I/O flags can be used. Also the
5137 XML serialization flags
5139 `SOAP_XML_GRAPH` should not be mixed.
5141 The flags control the inbound and outbound message transport, encoding, and
5142 (de)serialization. The following functions are used to set and reset the flags
5143 for input and output modes:
5145 * `soap_init2(struct soap *soap, int imode, int omode)` Initialize the runtime and set flags
5147 * `soap_imode(struct soap *soap, int imode)` Set all input mode flags
5149 * `soap_omode(struct soap *soap, int omode)` Set all output mode flags
5151 * `soap_set_imode(struct soap *soap, int imode)` Enable input mode flags
5153 * `soap_set_omode(struct soap *soap, int omode)` Enable output mode flags
5155 * `soap_clr_imode(struct soap *soap, int omode)` Disable input mode flags
5157 * `soap_clr_omode(struct soap *soap, int omode)` Disable output mode flags
5159 The default setting is `SOAP_IO_DEFAULT` for both input and output modes.
5165 soap_init2(&soap, SOAP_IO_KEEPALIVE,
5166 SOAP_IO_KEEPALIVE|SOAP_ENC_ZLIB|SOAP_XML_TREE|SOAP_XML_CANONICAL);
5167 if (soap_call_ns__myMethod(&soap, ...))
5171 sends a compressed client request with keep-alive enabled and all data serialized as canonical XML trees.
5173 In many cases, setting the input mode will have no effect, especially with HTTP
5174 transport because gSOAP will determine the optimal input buffering and the
5175 encoding used for an inbound message. The flags that have an effect on
5176 handling inbound messages are `SOAP_IO_KEEPALIVE`, `SOAP_ENC_SSL`
5177 (but automatic when "https:" endpoints are used or `soap_ssl_accept`),
5178 `SOAP_C_NOIOB`, `SOAP_C_UTFSTRING`, and `SOAP_C_MBSTRING`.
5180 @warning The `SOAP_XML_TREE` serialization flag can be used to
5181 improve interoperability with SOAP implementations that are not fully SOAP 1.1
5182 compliant. However, a tree serialization will duplicate data when necessary
5183 and will crash the serializer for cyclic data structures.
5185 Additional run-time flags to control sockets.
5187 Use the following selection of flags that are OS dependent to control sockets for send/sendto/recv/recvfrom operations:
5189 * `MSG_NOSIGNAL` disables sigpipe (check your OS, this is not portable)
5191 * `MSG_DONTROUTE` bypass routing, use direct interface
5193 Use the following selection of flags to set client-side socket connection flags (setsockopt):
5195 * `SO_NOSIGPIPE` disables sigpipe (check your OS, this is not portable)
5197 * `SO_DEBUG` turns on recording of debugging information in the underlying protocol modules
5199 * `SO_BROADCAST` permits sending of broadcast messages (e.g. with UDP) when permitted
5201 * `SO_LINGER` set `soap.linger_time` (set this value as needed)
5203 Use the following selection of flags to set server-side socket connection accept flags (setsockopt):
5205 * `SO_NOSIGPIPE` disables sigpipe (check your OS, this is not portable)
5207 * `SO_DEBUG` turns on recording of debugging information in the underlying protocol modules
5209 * `SO_REUSEADDR` reuse bind address immediately (prevents bind reject)
5211 * `SO_LINGER` set `soap.linger_time` (set this value as needed)
5213 For example, `soap.accept_flags = (SO_NOSIGPIPE | SO_LINGER)` disables sigpipe signals and set linger time value given by `soap.linger_time` (zero by default).
5215 The `SO_SNDBUF` and `SO_RCVBUF` socket options can be set by assigning `soap.sndbuf` and `soap.rcvbuf` after the context initialization, respectively. The default value is `SOAP_BUFLEN`, which is the same as the size of the internal buffer. A zero value omits the internal `setsockopt` call to set these options. Setting these values to zero enables autotuning with Linux 2.4 and up.
5217 ## Memory Management {#memory}
5219 Understanding gSOAP's run-time memory management is important to optimize
5220 client and service applications by eliminating memory leaks and/or dangling
5223 There are two forms of dynamic (heap) allocations made by gSOAP's runtime for
5224 serialization and deserialization of data. Temporary data is created by the
5225 runtime such as hash tables to keep pointer reference information for
5226 serialization and hash tables to keep XML id/href information for
5227 multi-reference object deserialization. Deserialized data is created upon
5228 receiving SOAP messages. This data is stored on the heap and requires several
5229 calls to the `malloc` library function to allocate space for the data and
5230 `new` to create class instances. All such allocations are tracked by
5231 gSOAP's runtime by linked lists for later deallocation. The linked list for
5232 `malloc` allocations uses some extra space in each `malloc`ed block to
5233 form a chain of pointers through the `malloc`ed blocks. A separate
5234 `malloc`ed linked list is used to keep track of class instance allocations.
5236 If you want to preserve the deserialized data before deleting a soap context, you can assign management of the data and delegate responsibility of deletion to another soap context using `soap_delegate_deletion(struct soap *soap_from, struct soap *soap_to)`. This moves all deserialized and temporary data to the other soap context `soap_to`, which will delete its data and all the delegated data it is responsible for when you call `soap_destroy` and `soap_end`. This can be particularly useful for making client calls inside a server operation, i.e. a mixed server/client. The client call inside the server operation requires a new soap context, e.g. copied from the server's with `soap_copy`. Before destroying the client context with `soap_free`, the data can be delegated to the server's context with `soap_delegate_deletion`. See `samples/mashup/machupserver.c` code for an example.
5238 Note that gSOAP does not per se enforce a deallocation policy and the user can
5239 adopt a deallocation policy that works best for a particular application. As a
5240 consequence, deserialized data is never deallocated by the gSOAP runtime unless
5241 the user explicitly forces deallocation by calling functions to deallocate data
5242 collectively or individually.
5244 The deallocation functions are:
5246 * `soap_destroy(struct soap *soap)` Remove all dynamically allocated C++ objects. must be called before `soap_end()`
5248 * `soap_end(struct soap *soap)` Remove temporary data and deserialized data except class instances
5250 * `soap_free_temp(struct soap *soap)` Instead of `soap_destroy` and `soap_end`: remove temporary data only
5252 * `soap_dealloc(struct soap *soap, void *p)` Remove malloced data at `p`. When `p==NULL`: remove all dynamically allocated (deserialized) data except class instances
5254 * `soap_delete(struct soap *soap, void *p)` Remove class instance at `p`. When `p==NULL`: remove all dynamically allocated (deserialized) class instances (this is identical to calling soap_destroy(struct soap *soap))
5256 * `soap_unlink(struct soap *soap, void *p)` Unlink data/object at `p` from gSOAP's deallocation chain so gSOAP won't deallocate it
5258 * `soap_done(struct soap *soap)` Detach context (reset runtime context)
5260 * `soap_free(struct soap *soap)` Detach and free context (allocated with `soap_new`)
5262 Temporary data (i.e. the hash tables) are automatically removed with calls to
5263 the `soap_free_temp` function which is also made by `soap_end` and
5264 `soap_done` or when the next call to a stub or skeleton routine is made to
5265 send a message or receive a message. Deallocation of non-class based data is
5266 straightforward: `soap_end` removes all dynamically allocated deserialized
5267 data (data allocated with `soap_malloc`. That is, when the client/service
5268 application does not use any class instances that are (de)marshalled, but uses
5269 structs, arrays, etc., then calling the `soap_end` function is safe to
5270 remove all deserialized data. The function can be called after processing the
5271 deserialized data of a service operation call or after a number of service operation
5272 calls have been made. The function is also typically called after
5273 `soap_serve`, when the service finished sending the response to a client
5274 and the deserialized client request data can be removed.
5276 Individual data objects can be unlinked from the deallocation chain if
5277 necessary, to prevent deallocation by the collective `soap_end` or
5278 `soap_destroy` functions.
5280 ### Memory Allocation and Management Policies
5282 There are three situations to consider for memory deallocation policies for class instances:
5285 * the program code deletes the class
5286 instances and the class destructors in turn SHOULD delete and free any dynamically allocated data (deep deallocation) without
5287 calling the `soap_end` and `soap_destroy` functions,
5290 destructors SHOULD NOT deallocate any data and the `soap_end` and `soap_destroy` functions can be called to remove
5294 destructors SHOULD mark their own deallocation and mark the deallocation of any other data deallocated by it's destructors
5295 by calling the `soap_unlink` function. This allows
5296 `soap_destroy` and `soap_end` to remove the remaining instances and data without causing duplicate deallocations.
5298 It is advised to use pointers to class instances that are used within other structs and classes to avoid the creation of temporary
5299 class instances during deserialization. The problem with temporary class instances is that the destructor of the temporary may affect data used by
5300 other instances through the sharing of data parts accessed with pointers. Temporaries and even whole copies of class instances
5301 can be created when deserializing SOAP multi-referenced objects.
5302 A dynamic array of class instances is similar: temporaries may be created to fill the array upon deserialization. To avoid
5303 problems, use dynamic arrays of pointers to class instances. This also enables the exchange of polymorphic arrays when the
5304 elements are instances of classes in an inheritance hierarchy.
5305 In addition, allocate data and class instances with `soap_malloc` and `soap_new_X` functions (more details below).
5307 To summarize, it is advised to pass class data types by pointer to a service operation. For example:
5311 ns__remoteMethod(X *in, ...);
5314 Response elements that are class data types can be passed by reference, as in:
5318 class ns__remoteMethodResponse { ... };
5319 ns__remoteMethod(X *in, ns__remoteMethodResponse &out);
5322 But dynamic arrays declared as class data types should use a pointer to a valid object that will be overwritten when the
5323 function is called, as in:
5326 typedef int xsd__int;
5328 class ArrayOfint { xsd__int *__ptr; int __size; };
5329 ns__remoteMethod(X *in, ArrayOfint *out);
5332 Or a reference to a valid or `NULL` pointer, as in:
5335 typedef int xsd__int;
5337 class ArrayOfint { xsd__int *__ptr; int __size; };
5338 ns__remoteMethod(X *in, ArrayOfint *&out);
5341 The gSOAP memory allocation functions can be used in client and/or service code to allocate temporary data that will be
5342 automatically deallocated.
5343 These functions are:
5345 * `void *soap_malloc(struct soap *soap, size_t n)` return pointer to `n` bytes
5347 * `Type *soap_new_Type(struct soap *soap)` allocate and instantiate
5349 * `Type *soap_new_Type(struct soap *soap, int n)` instantiate array of `n` objects
5351 * `Type *soap_new_set_Type(struct soap *soap, m1, ..., mn)` instantiate and set members
5353 * `Type *soap_new_req_Type(struct soap *soap, m1, ..., mn)` instantiate and set required-only members
5355 The `soap_new_X` functions are generated by the gSOAP `soapcpp2` compiler for every type in the header file.
5357 Space allocated with `soap_malloc` will be released with the `soap_end` and `soap_dealloc` functions.
5358 All objects instantiated with `soap_new_X(struct soap*)` are removed altogether with `soap_destroy(struct soap*)`.
5360 For example, the following service uses temporary data in the service operation implementation:
5374 An example service operation that allocates a temporary string is:
5377 int ns__itoa(struct soap *soap, int i, char **a)
5379 *a = (char*)soap_malloc(soap, 11);
5380 sprintf(*a, "%d", i);
5385 This temporary allocation can also be used to allocate strings for the SOAP Fault data structure. For example:
5388 int ns__mymethod(...)
5392 char *msg = (char*)soap_malloc(soap, 1024); // allocate temporary space for detailed message
5393 sprintf(msg, "...", ...); // produce the detailed message
5394 return soap_receiver_fault(soap, "An exception occurred", msg); // return the server-side fault
5400 Use `soap_receiver_fault(struct soap *soap, const char *faultstring, const char *detail)` to set a SOAP 1.1/1.2 fault at the server-side.
5401 Use `soap_sender_fault(struct soap *soap, const char *faultstring, const char *detail)` to set a SOAP 1.1/1.2 unrecoverable Bad Request fault
5402 at the server-side. Sending clients are not supposed to retry messages after a
5403 Bad Request, while errors at the receiver-side indicate temporary problems.
5405 The above functions do not include a SOAP 1.2 Subcode element. To include Subcode element, use `soap_receiver_fault_subcode(struct soap *soap, const char *subcode, const char *faultstring, const char *detail)` to set a SOAP 1.1/1.2 fault with Subcode at the server-side.
5406 Use `soap_sender_fault_subcode(struct soap *soap, const char *subcode, const char *faultstring, const char *detail)` to set a SOAP 1.1/1.2 unrecoverable Bad Request fault with Subcode at the server-side.
5408 gSOAP provides a function to duplicate a string into gSOAP's memory space:
5411 char *soap_strdup(struct soap *soap, const char *s)
5414 The function allocates space for `s` with `soap_malloc`, copies the
5415 string, and returns a pointer to the duplicated string. When `s` is NULL,
5416 the function does not allocate and copy the string and returns NULL.
5418 ### Intra-Class Memory Management {#classmemory}
5420 When a class declaration has a `struct soap *` field, this field will be set to point to the current gSOAP runtime context by
5421 gSOAP's deserializers and by the `soap_new_Class` functions.
5422 This simplifies memory management for class instances.
5423 The `struct soap*` pointer is implicitly set by the gSOAP deserializer for
5424 the class or explicitly by calling the `soap_new_X` function for class `X`.
5430 struct soap *soap; // reference to gSOAP's run-time
5437 The constructor and destructor for class `Sample` are:
5441 { this->soap = NULL;
5444 { soap_unlink(this->soap, this);
5448 The `soap_unlink()` call removes the object from gSOAP's deallocation chain.
5449 In that way, `soap_destroy` can be safely called to remove all class instances.
5450 The following code illustrates the explicit creation of a `Sample` object and cleanup:
5453 struct soap *soap = soap_new(); // new gSOAP runtime
5454 Sample *obj = soap_new_Sample(soap); // new Sample object with obj->soap set to runtime
5456 delete obj; // also calls soap_unlink to remove obj from the deallocation chain
5457 soap_destroy(soap); // deallocate all (other) class instances
5458 soap_end(soap); // clean up
5461 Here is another example:
5466 struct soap *soap; // set by soap_new_ns__myClass()
5468 void setName(const char *s);
5473 Calls to `soap_new_ns__myClass(soap)` will set the `soap` field in the class instance to the current gSOAP
5474 context. Because the deserializers invoke the `soap_new` functions, the `soap` field of the `ns__myClass`
5475 instances are set as well.
5476 This mechanism is convenient when Web Service methods need to return objects that are instantiated in the methods.
5480 int ns__myMethod(struct soap *soap, ...)
5482 ns__myClass *p = soap_new_ns__myClass(soap);
5486 void ns__myClass::ns__setName(const char *s)
5489 name = (char*)soap_malloc(soap, strlen(s)+1);
5491 name = (char*)malloc(strlen(s)+1);
5494 ns__myClass::ns__myClass()
5499 ns__myClass::~ns__myClass()
5501 if (!soap && name) free(name);
5502 soap_unlink(soap, this);
5506 Calling `soap_destroy` right after `soap_serve` in the Web Service will destroy all dynamically allocated
5511 To activate debugging and message logging, set the `#define DEBUG` macro
5512 on the compiler's command line (typically as a compiler option `-DDEBUG`)
5513 or in `stdsoap2.h`, and recompile your code together with `stdsoap2.c`
5514 or `stdsoap2.cpp` (instead of `libgsoap`). When using
5515 `libgsoap` and `libgsoap++`, reinstall the software with
5516 `./configure --enable-debug`.
5518 When your client and server applications run, they will log their activity in three
5521 * `SENT.log` the SOAP content transmitted by the application
5523 * `RECV.log` the SOAP content received by the application
5525 * `TEST.log` a log containing various activities performed by the application
5527 @warning The client and server applications may run slow due to the logging activity.
5529 @note: Set macro `DEBUG_STAMP` instead of `DEBUG` to add time
5530 stamps to `TEST.log`. This works on platforms supporting the
5531 `gettimeofday` function.
5533 @warning When installing a CGI application on the Web with debugging activated, the log files may sometimes not be created due to file
5534 access permission restrictions imposed on CGI applications. To get around this, create empty log files with universal write
5535 permissions. Be careful about the security implication of this.
5537 You can test a service CGI application without deploying it on the Web.
5538 To do this, create a client application for the service and activate message logging by this client.
5539 Remove any old `SENT.log` file and run the client (which connects to the Web service or to another dummy, but valid address)
5540 and copy the `SENT.log` file to another file, e.g. `SENT.tst`.
5541 Then redirect the `SENT.tst` file to the service CGI application. For example,
5543 > ./myservice.cgi < SENT.tst
5545 This should display the service response on the terminal.
5547 The file names of the log files and the logging activity can be controlled at the application level. This allows the creation of
5548 separate log files by separate services, clients, and threads.
5549 For example, the following service logs all SOAP messages (but no debug messages) in separate directories:
5555 soap_set_recv_logfile(&soap, "logs/recv/service12.log"); // append all messages received in /logs/recv/service12.log
5556 soap_set_sent_logfile(&soap, "logs/sent/service12.log"); // append all messages sent in /logs/sent/service12.log
5557 soap_set_test_logfile(&soap, NULL); // no file name: do not save debug messages
5563 Likewise, messages can be logged for individual client-side service operation calls.
5565 ## Generating an Auto Test Server for Client Testing
5567 The `soapcpp2 -T` option generates an auto-test server application in `soapTester.cpp`, which is to be compiled and linked with the code generated for a server implementation, i.e. `soapServer.cpp` (or with the generated server object class) and `soapC.cpp`. The feature also supports C, so use the `soapcpp2 -c` option to generate C.
5569 The auto-test server can be used to test a client application. Suppose the
5570 generated code is compiled into the executable named `tester` (compile `soapServer.cpp`, `soapC.cpp`, and `stdsoap2.cpp` or link `libgsoap++`). We can use the IO
5571 redirect to "send" it a message saved in a file, for example one of the
5572 sample request messages generated by `soapcpp2`:
5574 > ./tester < example.req.xml
5576 which then returns the response with default XML values displayed on the terminal.
5578 To run the auto test service on a port to test a client against, use two command-line arguments. The first argument is the OR-ed values of the gSOAP runtime context flags such as `SOAP_IO_KEEPALIVE` (0x10 = 16) and the second argument is the port number:
5582 This starts an iterative stand-alone server on port 8080. This way, messages
5583 can be sent to *`http://localhost:8080`* to test the client. The data in the
5584 response messages are copied from the request messages
5585 when possible, or XML default values, or empty otherwise.
5587 ## Generating Deep Copy and Deletion Code
5589 The `soapcpp2 -Ec` option generates deep copy code for each type `T`:
5591 `T * soap_dup_T(struct soap*, T *dst, const T *src)` deep copy `src`
5592 into `dst`, replicating all deep cycles and shared pointers when a managing
5593 soap context is provided as argument. When `dst` is NULL, allocates space
5594 for `dst`. Deep copy is a tree when argument is NULL, but the presence of
5595 deep cycles will lead to non-termination. Use flag `SOAP_XML_TREE` with
5596 managing context to copy into a tree without cycles and
5597 pointers to shared objects. Returns `dst` (or allocated space when
5600 For classes `T`, also a deep copy method is generated with option `-Ec`:
5602 `virtual T * T::soap_dup(struct soap*) const` returns a duplicate of this
5603 object by deep copying, replicating all deep cycles and shared pointers when a
5604 managing soap context is provided as argument. Deep copy is a tree when
5605 argument is NULL, but the presence of deep cycles will lead to non-termination.
5606 Use flag `SOAP_XML_TREE` with managing context to copy into a tree
5607 without cycles and pointers to shared objects.
5609 The `soapcpp2 -Ed` option generates deep deletion code for each type
5612 `void soap_del_T(const T*)` deletes all heap-allocated members of
5613 this object by deep deletion ONLY IF this object and all of its (deep) members
5614 are not managed by a soap context AND the deep structure is a tree (no cycles
5615 and co-referenced objects by way of multiple
5616 (non-smart) pointers pointing to the same data). Can be safely used after
5617 `soap_dup(NULL)` to delete the deep copy. Does not delete the object
5620 For classes `T`, also a deep deletion method is generated with option
5623 `virtual void T::soap_del() const` deletes all
5624 heap-allocated members of this object by deep deletion ONLY IF this object
5625 and all of its (deep) members are not managed by a soap context AND the deep
5626 structure is a tree (no cycles and co-referenced objects by way of multiple
5627 (non-smart) pointers pointing to the same data).Can be safely used after
5628 `soap_dup(NULL)` to delete the deep copy. Does not delete the object
5631 ## Required Libraries
5635 * The socket library is essential and requires the inclusion of the appropriate libraries with the compile command for Sun
5638 > c++ -o myclient myclient.cpp stdsoap2.cpp soapC.cpp soapClient.cpp -lsocket -lxnet -lnsl
5640 These library loading options are not required with Linux.
5642 * The gSOAP runtime uses the math library for the *`NaN`*, *`INF`*, and *`-INF`* floating point representations. The library
5643 is not strictly necessary and the `<math.h>` header file import can be commented out from the `stdsoap2.h` header file.
5644 The application can be linked without the `-lm` math library e.g. under Sun Solaris:
5646 > c++ -o myclient myclient.cpp stdsoap2.cpp soapC.cpp soapClient.cpp -lsocket -lxnet -lnsl
5648 # The gSOAP Service Operation Specification Format
5650 A service operation is specified as a C/C++ function prototype in a header
5651 file. The function is REQUIRED to return `int`, which is used to represent
5652 a SOAP error code, see Section \ref errcodes . Multiple service operations MAY
5653 be declared together in one header file.
5655 The general format of a service operation specification is:
5658 [optional: int] [optional: namespace_prefix__]method_name([optional: inparam1, inparam2, ...,] outparam);
5663 * `namespace_prefix__` is the optional namespace prefix of the method (see identifier translation rules \ref idtrans )
5665 * `method_name` it the service operation name (see identifier translation rules \ref idtrans )
5667 * `inparam` is the declaration of an input parameter of the service operation
5669 * `outparam` is the declaration of the output parameter of the service operation
5671 This simple form can only pass a single, non-`struct` and non-`class`
5672 type output parameter. See \ref param for passing multiple output
5673 parameters. The name of the declared function `namespace_prefix__method_name` must be unique and cannot match the name of a `struct`,
5674 `class`, or `enum` declared in the same header file.
5676 The method request is encoded in SOAP as an XML element and the namespace prefix, method name, and input parameters are encoded using the format:
5680 <[optional: namespace-prefix:]method_name xsi:type="[optional: namespace-prefix:]method_name>
5681 <inparam-name1 xsi:type="...">...</inparam-name1>
5682 <inparam-name2 xsi:type="...">...</inparam-name2>
5684 </[optional: namespace-prefix:]method_name>
5688 where the *`inparam-name`* accessors are the element-name representations of the `inparam` parameter name declarations, see
5689 Section \ref idtrans . (The optional parts are shown enclosed in [optional: ].)
5691 The XML response by the Web service is of the form:
5695 <[optional: namespace-prefix:]method-nameResponse xsi:type="[optional: namespace-prefix:]method-nameResponse>
5696 <outparam-name xsi:type="...">...</outparam-name>
5697 </[optional: namespace-prefix:]method-nameResponse>
5701 where the *`outparam-name`* accessor is the element-name representation of the `outparam` parameter name declaration, see
5702 Section \ref idtrans . By convention, the response element name is the method name ending in *`Response`*.
5703 See \ref param on how to change the declaration if the service response element name is different.
5705 The gSOAP `soapcpp2` tool generates a stub routine for the service
5706 operation. This stub is of the form:
5709 int soap_call_[optional: namespace_prefix__]method_name(struct soap *soap, char *URL, char *action, [optional: inparam1, inparam2, ...,] outparam);
5712 This proxy can be called by a client application to perform the service operation
5715 The gSOAP `soapcpp2` tool generates a skeleton routine for the
5716 service operation. The skeleton function is:
5719 int soap_serve_[optional: namespace_prefix__]method_name(struct soap *soap);
5722 The skeleton routine, when called by a service application, will attempt to
5723 serve a request on the standard input. If no request is present or if the
5724 request does not match the method name, `SOAP_NO_METHOD` is returned.
5725 The skeleton routines are automatically called by the generated
5726 `soap_serve` routine that handles all requests.
5728 ## Service Operation Parameter Passing {#param}
5730 The input parameters of a service operation MUST be passed by value. Input
5731 parameters cannot be passed by reference with the `&` reference operator,
5732 but an input parameter value MAY be passed by a pointer to the data. Of
5733 course, passing a pointer to the data is preferred when the size of the data of
5734 the parameter is large. Also, to pass instances of (derived) classes, pointers
5735 to the instance need to be used to avoid passing the instance by value which
5736 requires a temporary and prohibits passing derived class instances. When two
5737 input parameter values are identical, passing them using a pointer has the
5738 advantage that the value will be encoded only once as multi-reference (hence,
5739 the parameters are aliases). When input parameters are passed using a pointer,
5740 the data pointed to will not be modified by the service operation and returned to
5743 The output parameter MUST be passed by reference using `&` or by using a
5744 pointer. Arrays are passed by reference by default and do not require the use
5745 of the reference operator `&`.
5747 The input and output parameter types have certain limitations, see
5748 Section \ref limitations
5750 If the output parameter is a `struct` or `class` type, it is
5751 considered a service operation response element instead of a simple output
5752 parameter value. That is, the name of the `struct` or `class` is the
5753 name of the response element and the `struct` or `class` fields are
5754 the output parameters of the service operation, see also \ref response . Hence,
5755 if the output parameter has to be a `struct` or `class`, a response
5756 `struct` or `class` MUST be declared as well. In addition, if a
5757 service operation returns multiple output parameters, a response `struct` or
5758 `class` MUST be declared. By convention, the response element is the
5759 service operation name ending with "*`Response`*".
5761 The general form of a response element declaration is:
5764 struct [optional: namespace_prefix__]response_element_name
5774 * `namespace_prefix__` is the optional namespace prefix of the response element (see identifier translation rules \ref idtrans )
5776 * `response_element_name` it the name of the response element (see identifier translation rules \ref idtrans )
5778 * `outparam` is the declaration of an output parameter of the service operation
5780 The general form of a service operation specification with a response element declaration for (multiple) output parameters is:
5783 [optional: int] [optional: namespace_prefix__]method_name([optional: inparam1, inparam2, ...,] struct [optional: namespace_prefix__]response_element_name {outparam1[optional: , outparam2, ...]} &anyparam);
5786 The choice of name for `anyparam` has no effect on the SOAP encoding and decoding and is only used as a place holder for the
5789 The method request is encoded in SOAP as an independent element and the
5790 namespace prefix, method name, and input parameters are encoded using the
5795 <[optional: namespace-prefix:]method-name xsi:type="[optional: namespace-prefix:]method-name>
5796 <inparam-name1 xsi:type="...">...</inparam-name1>
5797 <inparam-name2 xsi:type="...">...</inparam-name2>
5799 </[optional: namespace-prefix:]method-name>
5803 where the *`inparam-name`* accessors are the element-name representations of
5804 the `inparam` parameter name declarations, see Section \ref idtrans .
5805 (The optional parts resulting from the specification are shown enclosed in
5808 The method response is expected to be of the form:
5812 <[optional: namespace-prefix:]response-element-name xsi:type="[optional: namespace-prefix:]response-element-name>
5813 <outparam-name1 xsi:type="...">...</outparam-name1>
5814 <outparam-name2 xsi:type="...">...</outparam-name2>
5816 </[optional: namespace-prefix:]response-element-name>
5820 where the *`outparam-name`* accessors are the element-name representations of
5821 the `outparam` parameter name declarations, see Section \ref idtrans .
5822 (The optional parts resulting from the specification are shown enclosed in
5825 The input and/or output parameters can be made anonymous, which allows the
5826 deserialization of requests/responses with different parameter names as is
5827 endorsed by the SOAP 1.1 specification, see Section \ref anonymous .
5829 ## Error Codes {#errcodes}
5831 The error codes returned by the stub and skeleton routines are listed below.
5834 -------------------------- | -----------
5835 `SOAP_OK` | No error (code is zero)
5836 `SOAP_CLI_FAULT`* | The service returned a client fault (SOAP 1.2 Sender fault)
5837 `SOAP_SVR_FAULT`* | The service returned a server fault (SOAP 1.2 Receiver fault)
5838 `SOAP_TAG_MISMATCH` | Element found didn't correspond to anything expected
5839 `SOAP_TYPE` | XML Schema type mismatch
5840 `SOAP_SYNTAX_ERROR` | An XML syntax error occurred on the input
5841 `SOAP_NO_TAG` | Begin of an element expected, but not found
5842 `SOAP_IOB` | Array index out of bounds
5843 `SOAP_MUSTUNDERSTAND`* | An element needs to be ignored that need to be understood
5844 `SOAP_NAMESPACE` | Namespace name mismatch (validation error)
5845 `SOAP_FATAL_ERROR` | Internal error
5846 `SOAP_USER_ERROR` | User error (reserved for `soap.user` usage
5847 `SOAP_FAULT` | An exception raised by the service
5848 `SOAP_NO_METHOD` | The dispatcher did not find a matching operation for a request
5849 `SOAP_NO_DATA` | No data in HTTP message
5850 `SOAP_GET_METHOD` | HTTP GET operation not handled, see Section \ref get
5851 `SOAP_EOM` | Out of memory
5852 `SOAP_MOE` | Memory overflow/corruption error (DEBUG mode)
5853 `SOAP_NULL` | An element was null, while it is not supposed to be null
5854 `SOAP_DUPLICATE_ID` | Element's ID duplicated (multi-ref encoding)
5855 `SOAP_MISSING_ID` | Element ID missing for an href/ref (multi-ref encoding)
5856 `SOAP_HREF` | Reference to object is incompatible with the object refered to
5857 `SOAP_UTF_ERROR` | An UTF-encoded message decoding error occured
5858 `SOAP_UDP_ERROR` | Message too large to store in UDP packet
5859 `SOAP_TCP_ERROR` | A connection error occured
5860 `SOAP_HTTP_ERROR` | An HTTP error occured
5861 `SOAP_NTLM_ERROR` | An NTLM authentication handshake error occured
5862 `SOAP_SSL_ERROR` | An SSL error occured
5863 `SOAP_ZLIB_ERROR` | A Zlib error occured
5864 `SOAP_PLUGIN_ERROR` | Failed to register plugin
5865 `SOAP_MIME_ERROR` | MIME parsing error
5866 `SOAP_MIME_HREF` | MIME attachment has no href from SOAP body error
5867 `SOAP_MIME_END` | End of MIME attachments protocol error
5868 `SOAP_DIME_ERROR` | DIME formatting error or DIME size exceeds SOAP_MAXDIMESIZE
5869 `SOAP_DIME_END` | End of DIME attachments protocol error
5870 `SOAP_DIME_HREF` | DIME attachment has no href from SOAP body (and no DIME callbacks were defined to save the attachment)
5871 `SOAP_DIME_MISMATCH` | DIME version/transmission error
5872 `SOAP_VERSIONMISMATCH`* | SOAP version mismatch or no SOAP message
5873 `SOAP_DATAENCODINGUNKNOWN` | SOAP 1.2 DataEncodingUnknown fault
5874 `SOAP_REQUIRED` | Attributed is required
5875 `SOAP_PROHIBITED` | Attributed is prohibited
5876 `SOAP_LEVEL` | XML nesting depth level exceeds `SOAP_MAXLEVEL`
5877 `SOAP_OCCURS` | Element minOccurs/maxOccurs validation error or `SOAP_MAXOCCURS` exceeded
5878 `SOAP_LENGTH` | Element length validation error or `SOAP_MAXLENGTH` exceeded
5879 `SOAP_FIXED` | Element or attribute value is fixed
5880 `SOAP_EMPTY` | Element or attribute is empty when a value is expected
5881 `SOAP_FD_EXCEEDED` | Too many open sockets (for non-win32 systems not supporting `poll()`)
5882 `SOAP_EOM` | Out of memory
5883 `SOAP_EOF` | Unexpected end of file, no input, or timeout receiving data
5884 `SOAP_ERR` | Error (for internal use)
5886 The error codes that are returned by a stub routine (proxy) upon receiving a
5887 SOAP Fault from the server are marked (*). The remaining error codes are
5888 generated by the proxy itself as a result of problems with a SOAP payload. The
5889 error code is `SOAP_OK` when the service operation call was successful (the
5890 `SOAP_OK` predefined constant is guaranteed to be `0`). The error
5891 code is also stored in `soap.error`, where `soap` is a variable that
5892 contains the current runtime context. The function
5893 `soap_print_fault(struct soap *soap, FILE *fd)` can be called to
5894 display an error message on `fd` where current value of the
5895 `soap.error` variable is used by the function to display the error.
5896 Use `soap_stream_fault(struct soap *soap, std::ostream& os)` in C++.
5897 The function `soap_print_fault_location(struct soap *soap, FILE *fd)`
5898 prints the location of the error if the error is a result from parsing XML.
5899 Use `soap_print_stream_location(struct soap *soap, std::ostream& os)` in C++.
5900 Use `soap_sprint_fault(struct soap*, char *buf, size_t len)` to print the error to a string.
5902 A service operation implemented in a SOAP service MUST return an error code as the
5903 function's return value. `SOAP_OK` denotes success and `SOAP_FAULT`
5904 denotes an exception. The exception details can be assigned with the
5905 `soap_receiver_fault(struct soap *soap, const char *faultstring, const char *detail)` which sets the strings
5906 `soap.fault->faultstring` and
5907 `soap.fault->detail` for SOAP 1.1, and
5908 `soap.fault->SOAP_ENV__Reason` and
5909 `soap.fault->SOAP_ENV__Detail` for SOAP 1.2, where
5910 `soap` is a variable that contains the current runtime context, see
5911 Section \ref fault .
5912 A receiver error indicates that the service can't handle the request, but can possibly recover from the error.
5913 To return an unrecoverable SOAP 1.1/1.2 error, use `soap_sender_fault(struct soap *soap, const char *faultstring, const char *detail)`.
5915 To return a HTTP error code a service method can simply return the HTTP error code number.
5916 For example, `return 404;` returns a "404 Not Found" HTTP error back to the client. The `soap.error`
5917 is set to the HTTP error code at the client side.
5918 The HTTP 1.1 error codes are:
5924 203 | Non-Authoritative Information
5927 206 | Partial Content
5928 300 | Multiple Choices
5929 301 | Moved Permanently
5934 307 | Temporary Redirect
5937 402 | Payment Required
5940 405 | Method Not Allowed
5941 406 | Not Acceptable
5942 407 | Proxy Authentication Required
5943 408 | Request Time-out
5946 411 | Length Required
5947 412 | Precondition Failed
5948 413 | Request Entity Too Large
5949 414 | Request-URI Too Large
5950 415 | Unsupported Media Type
5951 416 | Requested range not satisfiable
5952 417 | Expectation Failed
5953 500 | Internal Server Error
5954 501 | Not Implemented
5956 503 | Service Unavailable
5957 504 | Gateway Time-out
5958 505 | HTTP Version not supported
5960 The error codes are given for informational purposes only. The HTTP protocol requires the proper actions after an error is issued. gSOAP's HTTP 1.0/1.1 handling is automatic.
5962 ## C/C++ Identifier Name to XML Tag Name Mapping {#idtrans}
5964 One of the "secrets" behind the power and flexibility of gSOAP's encoding and
5965 decoding of service operation names, class names, type identifiers, and struct or
5966 class fields is the ability to specify namespace prefixes with these names that
5967 are used to denote their encoding style. More specifically, a C/C++ identifier
5971 [optional: namespace_prefix__]element_name
5974 where the prefix and the element name are separated by double underscores will be encoded in XML as
5978 <[optional: namespace-prefix:]element-name ...>
5982 The **underscore pair** (`__`) separates the namespace prefix from the
5983 element name. Each namespace prefix has a namespace URI specified by a
5984 namespace mapping table \ref nstable , see also
5985 Section \ref namespace . The namespace URI is a unique identification that
5986 can be associated with the service operations and data types. The namespace URI
5987 disambiguates potentially identical service operation names and data type names
5988 used by disparate organizations.
5990 XML element names are NCNames (restricted strings) that MAY contain
5991 **hyphens**, **dots**, and **underscores**. The special characters in the XML
5992 element names of service operations, structs, classes, typedefs, and fields can be
5993 controlled using the following conventions: A **single underscore** in a
5994 namespace prefix or identifier name is replaced by a hyphen (*`-`*) in the
5995 XML element name. For example, the identifier name `SOAP_ENC__ur_type`
5996 is represented in XML as *`SOAP-ENC:ur-type`*. The sequence `_DOT` is
5997 replaced by a dot (*`.`*), and the sequence `_USCORE` is replaced by
5998 an underscore (*`_`*) in the corresponding XML element name. For example:
6001 class n_s__biz_DOTcom
6003 char *n_s__biz_USCOREname;
6007 is encoded in XML as:
6011 <n-s:biz.com xsi:type="n-s:biz.com">
6012 <n-s:biz_name xsi:type="string">Bizybiz</n-s:biz_name>
6017 Trailing underscores of an identifier name are not translated into the XML
6018 representation. This is useful when an identifier name clashes with a C++
6019 keyword. For example, *`return`* is often used as an accessor name in a SOAP
6020 response element. The *`return`* element can be specified as `return_`
6021 in the C++ source code. Note that XML should be treated as case sensitive, so
6022 the use of e.g. `Return` may not always work to avoid a name clash with the
6023 `\return` keyword. The use of trailing underscores also allows for
6024 defining `struct`s and `class`es with essentially the same XML Schema
6025 type name, but that have to be distinguished as seperate C/C++ types.
6027 For decoding, the underscores in identifier names act as wildcards. An XML
6028 element is parsed and matches the name of an identifier if the name is
6029 identical to the element name (case insensitive) and the underscores in the
6030 identifier name are allowed to match any character in the element name. For
6031 example, the identifier name `I_want__soap_fun_the_bea___DOTcom`
6032 matches the element name *`I-want:SOAP4fun@the-beach.com`*.
6034 By default, `soapcpp2` generates data bindings in which all XML elements are and attributes are unqualified:
6037 //gsoap x schema namespace: urn:x
6045 where the `name` element and the `type` attribute are unqualified in the XML content (for example to facilitate SOAP RPC encoding).
6047 To force qualification of elements and attributes, use the "form" directive:
6050 //gsoap x schema namespace: urn:x
6051 //gsoap x schema form: qualified
6059 You can also use "elementForm" and "attributeForm" directives to (un)qualify local element and attributes, respectively.
6061 Because the `soapcpp2`-generated serializers follow the
6062 qualified/unqualified forms of the schemas, there is normally no need to
6063 explicitly qualify struct/class members because automatic encoding rules will
6066 If explicit qualification is needed, this can be done using the prefix convention:
6069 //gsoap x schema namespace: urn:x
6070 //gsoap y schema namespace: urn:y
6078 which ensures that there cannot be any name clashes between members of the same name defined in different schemas (consider for example `name` and `y__name`), but this can clutter the representation when clashes do not occur.
6080 An alternative to the prefix convention is the use of "**colon notation**" in the
6081 gSOAP header file. This deviation from the C/C++ syntax allows you to bind
6082 type names and struct and class members to qualified and unqualified XML tag names explicitly,
6083 thus bypassing the default mechanism that automatically qualifies or
6084 unqualifies element and attribute tag names based on the schema
6085 element/attribute form.
6087 The colon notation for type names, struct/class names and members overrides the prefix qualification rules explicitly:
6090 //gsoap x schema namespace: urn:x
6091 //gsoap y schema namespace: urn:y
6099 where `x` and `y` are namespace prefixes that MUST be declared with a directive. The `xsi:type` member is an XML attribute in the `xsi` namespace.
6100 The `soapcpp2` tool maps this to the following struct without the annotations:
6103 // This code is generated from the above by soapcpp2 in soapStub.h:
6106 char *type; /* optional attribute of type xsd:string */
6107 char *name; /* optional element of type xsd:string */
6111 The `soapcpp2` tool also generates XML schemas with element and attribute
6112 references. That is, `y:name` is referenced from the `y` schema by the
6113 *`x:record`* complexType defined in the `x` schema.
6115 The colon notation also allows you to override the element/attribute form to unqualified for qualified schemas:
6118 //gsoap x schema namespace: urn:x
6119 //gsoap x schema form: qualified
6127 where the colon notation ensures that both `type` and `name` are
6128 unqualified in the XML content, which overrides the default qualified forms of
6131 Note that the use of colon notation to bind namespace prefixes to type names
6132 (typedef, enum, struct, and class names) translates to code without the
6133 prefixes. This means that name clashes can occur between types with identical unquaified names:
6136 enum x:color { RED, WHITE, BLUE };
6137 enum y:color { YELLOW, ORANGE }; // illegal enum name: name clash with x:color
6140 while prefixing with double underscores never lead to clashes:
6143 enum x__color { RED, WHITE, BLUE };
6144 enum y__color { YELLOW, ORANGE }; // no name clash
6147 Also note that colon notation has a very different role than the C++ scope
6148 operator `::`. The scope operator cannot be used in places where we need
6149 colon notation, such as struct/class member fields.
6151 The default mechanism that associates XML tag names with the names of struct
6152 and class member fields can be overriden by "**retagging**" names with the
6153 annotation of ``*tag``* placed next to the member field name. This is particularly useful to support legacy code for which the fixed naming of member fields cannot be easily changed. For example:
6156 //gsoap x schema namespace: urn:x
6157 //gsoap x schema form: qualified
6160 @ char * t `type{}`;
6161 char * s `full-name{}`;
6165 This maps the `t` member to the *`x:type`* XML attribute tag and `s`
6166 member to the *`x:full-name`* XML element tag. Note that both tags are namespace
6167 qualified as per schema declaration.
6169 As of gSOAP 2.8.23, Unicode characters in C/C++ identifiers are accepted by `soapcpp2` when the source file is encoded in UTF8. C/C++ Unicode names are mapped to Unicode XML tags. For C/C++ source code portability reasons, the `wsdl2h` tool still converts Unicode XML tag names to ASCII C/C++ identifiers using the `_xHHHH` naming convention for `HHHH` character code points. Option `wsdl2h -U` maps Unicode letters in XML tag names to UTF8-encoded Unicode letters in C/C++ identifiers.
6171 ## Namespace Mapping Table {#nstable}
6173 A namespace mapping table MUST be defined by clients and service applications.
6174 The mapping table is used by the serializers and deserializers of the stub and
6175 skeleton routines to produce a valid SOAP payload and to validate an incoming
6176 SOAP payload. A typical mapping table is shown below:
6179 struct Namespace namespaces[] =
6180 { // {"ns-prefix", "ns-name"}
6181 {"SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/"}, // MUST be first
6182 {"SOAP-ENC", "http://schemas.xmlsoap.org/soap/encoding/"}, // MUST be second
6183 {"xsi", "http://www.w3.org/2001/XMLSchema-instance"}, // MUST be third
6184 {"xsd", "http://www.w3.org/2001/XMLSchema"}, // Required for XML Schema types
6185 {"ns1", "urn:my-service-URI"}, // The namespace URI of the service operations
6186 {NULL, NULL} // end of table
6190 Each namespace prefix used by a identifier name in the header file
6191 specification (see Section \ref idtrans ) MUST have a binding to a
6192 namespace URI in the mapping table. The end of the namespace mapping table MUST
6193 be indicated by the `NULL` pair. The namespace URI matching is case
6194 insensitive. A namespace prefix is distinguished by the occurrence of a pair
6195 of underscores (`__`) in an identifier.
6197 An optional namespace pattern MAY be provided with each namespace mapping table
6198 entry. The patterns provide an alternative namespace matching for the
6199 validation of decoded SOAP messages. In this pattern, dashes (`-`) are
6200 single-character wildcards and asterisks (`*`) are multi-character
6201 wildcards. For example, to decode different versions of XML Schema type with
6202 different authoring dates, four dashes can be used in place of the specific
6203 dates in the namespace mapping table pattern:
6206 struct Namespace namespaces[] =
6207 { // {"ns-prefix", "ns-name", "ns-name validation pattern"}
6209 {"xsi", "http://www.w3.org/2001/XMLSchema-instance", "http://www.w3.org/----/XMLSchema-instance"},
6210 {"xsd", "http://www.w3.org/2001/XMLSchema", "http://www.w3.org/----/XMLSchema"},
6214 Or alternatively, asterisks can be used as wildcards for multiple characters:
6217 struct Namespace namespaces[] =
6218 { // {"ns-prefix", "ns-name", "ns-name validation pattern"}
6220 {"xsi", "http://www.w3.org/2001/XMLSchema-instance", "http://www.w3.org/*/XMLSchema-instance"},
6221 {"xsd", "http://www.w3.org/2001/XMLSchema", "http://www.w3.org/*/XMLSchema"},
6225 A namespace mapping table is automatically generated together with a WSDL file
6226 for each namespace prefix that is used for a service operation specified in the header file.
6227 This namespace mapping table has entries for all namespace prefixes. The
6228 namespace URIs need to be filled in. These appear as `http://tempuri.org`
6229 in the table. See Section \ref directives on how to specify the namespace
6230 URIs in the header file.
6232 For decoding elements with namespace prefixes, the namespace URI associated with the namespace prefix (through the *`xmlns`*
6233 attribute of an XML element) is searched from the
6234 beginning to the end in a namespace mapping table,
6235 and for every row the following tests are performed as part of the validation process:
6238 * the string in the second column matches the namespace URI (case insensitive)
6240 * the string in the optional third column matches the namespace URI (case insensitive), where `-` is a one-character wildcard and `*` is a
6241 multi-character wildcard
6243 When a match is found, the namespace prefix in the first column of the table is considered semantically identical to the namespace prefix used
6244 by the XML element to be decoded, though the prefix names may differ.
6245 A service will respond with the namespace that it received from a client in case it matches a pattern in the third column.
6247 For example, let's say we have the following structs:
6250 struct a__elt { ... };
6251 struct b__elt { ... };
6252 struct k__elt { ... };
6255 and a namespace mapping table in the program:
6258 struct Namespace namespaces[] =
6259 { // {"ns-prefix", "ns-name", "ns-name validation pattern"}
6263 {"c", "his uri", "* uri"},
6267 Then, the following XML elements will match the structs:
6271 <n:elt xmlns:n="some URI"> \qquad\mbox{matches the struct name `a__elt`}
6273 <m:elt xmlns:m="other URI"> \qquad\mbox{matches the struct name `b__elt`}
6275 <k:elt xmlns:k="my URI"> \qquad\mbox{matches the struct name `c__elt`}
6280 The response of a service to a client request that uses the namespaces listed above,
6281 will include *`my URI`* for the name space of element *`k`*.
6283 It is possible to use a number of different namespace tables and select the one that is appropriate.
6284 For example, an application might contact many different Web services all using different namespace URIs.
6285 If all the URIs are stored in one table, each service operation invocation will dump the whole namespace
6286 table in the SOAP payload. There is no technical problem with that, but it can be ugly when the table is large.
6287 To use different namespace tables, declare a pointer to a table and set the pointer to a particular table before service operation
6288 invocation. For example:
6291 struct Namespace namespacesTable1[] = { ... };
6292 struct Namespace namespacesTable2[] = { ... };
6293 struct Namespace namespacesTable3[] = { ... };
6294 struct Namespace *namespaces;
6299 soap_set_namespaces(&soap, namespaceTable1);
6300 soap_call_remote_method(&soap, URL, Action, ...);
6304 # gSOAP Serialization and Deserialization Rules
6306 This section describes the serialization and deserialization of C and C++ data types for SOAP 1.1 and 1.2 compliant encoding and decoding.
6308 ## SOAP RPC Encoding Versus Document/Literal and xsi:type Info
6310 The wsdl2h tool automatically generates a header file specialized for SOAP RPC
6311 encoding or document/literal style. The serialization and deserialization rules
6312 for C/C++ objects is almost identical for these styles, except for the
6313 following important issues.
6315 With SOAP RPC encoding style, care must be taken to ensure typed messages are
6316 produced for interoperability and compatibility reasons. To ensure that the
6317 gSOAP engine automatically generates typed (*`xsi:type`* attributed)
6318 messages, use `soapcpp2` option -t, see also Section \ref options .
6319 While gSOAP can handle untyped messages, some toolkits fail to find
6320 deserializers when the *`xsi:type`* information is absent.
6322 When starting the development of a gSOAP application from a header file, the
6323 `soapcpp2` compiler will generate WSDL and schema files for SOAP 1.1
6324 document/literal style by default (use the `//gsoap` directives to control
6325 this, see Section \ref directives ). Use `soapcpp2` options -2, -e, and
6326 -t to generate code for SOAP 1.2, RPC encoding, and typed messages.
6328 With SOAP RPC encoding, generic *`complexTypes`* with
6329 *`maxOccurs="unbounded"`* are not allowed and SOAP encoded arrays must be
6330 used. Also XML attributes and unions (XML schema *`choice`*) are not allowed
6331 with SOAP RPC encoding.
6333 Also with SOAP RPC encoding, multi-reference accessors are common to encode
6334 co-referenced objects and object digraphs. Multi-reference encoding is not
6335 supported in document/literal style, which means that cyclic object digraphs
6336 cannot be serialized (the engine will crash). Also DAGs are represented as XML
6337 trees in document/literal style messaging.
6339 ## Primitive Type Encoding
6341 The default encoding rules for the primitive C and C++ data types are given in the table below:
6343 C/C++ type | XML schema type
6344 -------------------- | ---------------
6345 `bool` | *`boolean`*
6346 `char*` | *`string`*
6348 `long double` | *`decimal`* with `#import "custom/long_double.h"`
6349 `double` | *`double`*
6354 `long long` | *`long`*
6356 `time_t` | *`dateTime`*
6357 `std::string` | *`string`*
6358 `std::wstring` | *`string`*
6359 `struct tm` | *`dateTime`* with `#import "custom/struct_tm.h"`
6360 `struct timeval` | *`dateTime`* with `#import "custom/struct_timeval.h"`
6361 `unsigned char` | *`unsignedByte`*
6362 `unsigned int` | *`unsignedInt`*
6363 `unsigned long` | *`unsignedLong`*
6364 `ULONG64` | *`unsignedLong`*
6365 `unsigned long long` | *`unsignedLong`*
6366 `unsigned short` | *`unsignedShort`*
6367 `wchar_t*` | *`string`*
6369 Objects of type `void` and `void *` cannot be encoded.
6370 Enumerations and bit masks are supported as well, see \ref enum .
6372 ## How to Represent Primitive C/C++ Types as XSD Types {#primitive}
6374 By default, encoding of the primitive types will take place as per SOAP
6375 encoding style. The encoding can be changed to any XML Schema type (XSD type) with an
6376 optional namespace prefix by using a `typedef` in the header file input to
6377 the gSOAP `soapcpp2` tool. The declaration enables the
6378 implementation of built-in XML Schema types (also known as XSD types) such as
6379 *`positiveInteger`*, *`xsd:anyURI`*, and *`xsd:date`* for which no
6380 built-in data structures in C and C++ exist but which can be represented using
6381 standard data structures such as strings, integers, and floats.
6383 The `typedef` declaration is frequently used for convenience in C. A
6384 `typedef` declares a type name for a (complex) type expression. The type
6385 name can then be used in other declarations in place of the more complex type
6386 expression, which often improves the readability of the program code.
6388 The gSOAP `soapcpp2` compiler interprets `typedef` declarations the same way as a
6389 regular C compiler interprets them, i.e. as types in declarations. In addition
6390 however, the gSOAP `soapcpp2` compiler will also use the type name in the encoding of the
6391 data in SOAP. The `typedef` name will appear as the XML element name of
6392 an independent element and as the value of the *`xsi:type`* attribute in the
6395 Many built-in primitive and derived XSD types such as *`xsd:anyURI`*,
6396 *`positiveInteger`*, and *`decimal`* can be stored by standard primitive
6397 data structures in C++, such as strings, integers, floats, and doubles.
6398 To serialize strings, integers, floats, and doubles as built-in primitive and
6399 derived XSD types, a `typedef` declaration can be used
6400 to declare an XSD type.
6402 For example, the declaration
6405 typedef unsigned int xsd__positiveInteger;
6408 creates a named type `positiveInteger` which is represented by `unsigned int` in C++. For example, the encoding of a
6409 `positiveInteger` value `3` is
6413 <positiveInteger xsi:type="xsd:positiveInteger">3</positiveInteger>
6417 <img src="https://www.w3.org/TR/xmlschema-2/type-hierarchy.gif"/>
6419 The built-in primitive and derived numerical XML Schema types are listed below together with their recommended `typedef`
6420 declarations. Note that the SOAP encoding schemas for primitive types are derived from the built-in XML Schema types, so
6421 `SOAP_ENC__` can be used as a namespace prefix instead of `xsd__`.
6424 Represents a Uniform Resource Identifier Reference (URI).
6425 Each URI scheme imposes specialized syntax rules for URIs in that scheme, including restrictions
6426 on the syntax of allowed fragment identifiers.
6427 It is recommended to use strings to store *`xsd:anyURI`* XML Schema types. The recommended type declaration is:
6430 typedef char *xsd__anyURI;
6433 * *`xsd:base64Binary`*
6434 Represents Base64-encoded arbitrary binary data.
6435 For using the *`xsd:base64Binary`* XSD Schema type, the use of the base64Binary representation of a dynamic array is **strongly** recommended,
6436 see Section \ref base64binary . However, the
6437 type can also be declared as a string and the encoding will be string-based:
6440 typedef char *xsd__base64Binary;
6443 With this approach, it is the responsibility of the application to make sure the string content is according to the Base64 Content-Transfer-Encoding defined in Section 6.8 of RFC 2045.
6447 For declaring an *`xsd:boolean`* XSD Schema type, the use of a bool is **strongly** recommended.
6448 If a pure C compiler is used that does not support the `bool` type, see Section \ref boolean .
6449 The corresponding type declaration is:
6452 typedef bool xsd__boolean;
6455 Type `xsd__boolean` declares a Boolean (0 or 1), which is encoded as
6459 <xsd:boolean xsi:type="xsd:boolean">...</xsd:boolean>
6465 Represents a byte (-128...127). The corresponding type declaration is:
6467 typedef char xsd__byte;
6470 Type `xsd__byte` declares a byte which is encoded as
6474 <xsd:byte xsi:type="xsd:byte">...</xsd:byte>
6480 Represents a date and time. The lexical representation is according to the ISO 8601 extended format CCYY-MM-DDThh:mm:ss where "CC"
6481 represents the century, "YY" the year, "MM" the month and "DD" the day, preceded by an optional leading "-" sign to indicate a
6482 negative number. If the sign is omitted, "+" is assumed. The letter "T" is the date/time separator and "hh", "mm", "ss" represent
6483 hour, minute and second respectively.
6484 It is recommended to use the `time_t` type to store *`xsd:dateTime`* XSD Schema types and the type declaration is:
6487 typedef time_t xsd__dateTime;
6490 However, note that calendar times before the year 1902 or after
6491 the year 2037 cannot be represented. Upon receiving a date outside this range,
6492 the `time_t` value will be set to -1.
6494 Strings (`char*`) can be used to store *`xsd:dateTime`* XSD Schema types. The type declaration is:
6497 typedef char *xsd__dateTime;
6499 In this case, it is up to the application to read and set the dateTime representation.
6504 The lexical representation for date is the reduced (right truncated) lexical representation for dateTime: CCYY-MM-DD.
6505 It is recommended to use strings (`char*`) to store *`xsd:date`* XSD Schema types. The type declaration is:
6508 typedef char *xsd__date;
6513 Represents arbitrary precision decimal numbers.
6514 It is recommended to use the {double} type to store *`xsd:decimal`* XSD Schema types and the type declaration is:
6517 typedef double xsd__decimal;
6520 Type `xsd__decimal` declares a double floating point number which is encoded as
6524 <xsd:double xsi:type="xsd:decimal">...</xsd:double>
6530 Corresponds to the IEEE double-precision 64-bit floating point type. The type declaration is:
6533 typedef double xsd__double;
6536 Type `xsd__double` declares a double floating point number which is encoded as
6540 <xsd:double xsi:type="xsd:double">...</xsd:double>
6546 Represents a duration of time.
6547 The lexical representation for duration is the ISO 8601 extended format PnYn MnDTnH nMnS, where nY represents
6548 the number of years, nM the number of months, nD the number of days, T is the date/time separator, nH the number of
6549 hours, nM the number of minutes and nS the number of seconds. The number of seconds can include decimal digits to
6550 arbitrary precision.
6551 It is recommended to use strings (`char*`) to store *`xsd:duration`* XSD Schema types. The type declaration is:
6554 typedef char *xsd__duration;
6559 Corresponds to the IEEE single-precision 32-bit floating point type. The type declaration is:
6562 typedef float xsd__float;
6565 Type `xsd__float` declares a floating point number which is encoded as
6569 <xsd:float xsi:type="xsd:float">...</xsd:float>
6575 Represents arbitrary hex-encoded binary data. It has a lexical representation where each binary octet is encoded as a character
6576 tuple, consisting of two hexadecimal digits ([0-9a-fA-F]) representing the octet code. For example, "0FB7" is a hex encoding for
6577 the 16-bit integer 4023 (binary representation is 111110110111.
6578 For using the *`xsd:hexBinary`* XSD Schema type, the use of the hexBinary representation of a dynamic array is **strongly** recommended,
6579 see Section \ref hexbinary . However, the
6580 type can also be declared as a string and the encoding will be string-based:
6583 typedef char *xsd__hexBinary;
6586 With this approach, it is solely the responsibility of the application to make sure the string content consists of a sequence of octets.
6590 Corresponds to a 32-bit integer in the range -2147483648 to 2147483647.
6593 typedef int xsd__int;
6596 Type `xsd__int` declares a 32-bit integer which is encoded as
6600 <xsd:int xsi:type="xsd:int">...</xsd:int>
6606 Corresponds to an unbounded integer.
6607 Since C++ does not support unbounded integers as a standard feature, the recommended type declaration is:
6610 typedef long long xsd__integer;
6613 Type `xsd__integer` declares a 64-bit integer which is encoded as an unbounded *`xsd:integer`*:
6617 <xsd:integer xsi:type="xsd:integer">...</xsd:integer>
6621 Another possibility is to use strings to represent unbounded integers and do the translation in code.
6625 Corresponds to a 64-bit integer in the range -9223372036854775808 to 9223372036854775807.
6626 The type declaration is:
6629 typedef long long xsd__long;
6635 typedef LONG64 xsd__long;
6641 typedef int64_t xsd__long;
6644 Type `xsd__long` declares a 64-bit integer which is encoded as
6648 <xsd:long xsi:type="xsd:long">...</xsd:long>
6653 * *`xsd:negativeInteger`*
6654 Corresponds to a negative unbounded integer (<0).
6655 Since C++ does not support unbounded integers as a standard feature, the recommended type declaration is:
6658 typedef long long xsd__negativeInteger;
6661 Type `xsd__negativeInteger` declares a 64-bit integer which is encoded as a *`xsd:negativeInteger`*:
6665 <xsd:negativeInteger xsi:type="xsd:negativeInteger">...</xsd:negativeInteger>
6669 Another possibility is to use strings to represent unbounded integers and do the translation in code.
6672 * *`xsd:nonNegativeInteger`*
6673 Corresponds to a non-negative unbounded integer (>0).
6674 Since C++ does not support unbounded integers as a standard feature, the recommended type declaration is:
6677 typedef unsigned long long xsd__nonNegativeInteger;
6680 Type `xsd__nonNegativeInteger` declares a 64-bit unsigned integer which is encoded as a non-negative unbounded *`xsd:nonNegativeInteger`*:
6684 <xsd:nonNegativeInteger xsi:type="xsd:nonNegativeInteger">...</xsd:nonNegativeInteger>
6688 Another possibility is to use strings to represent unbounded integers and do the translation in code.
6691 * *`xsd:nonPositiveInteger`*
6692 Corresponds to a non-positive unbounded integer (<=0).
6693 Since C++ does not support unbounded integers as a standard feature, the recommended type declaration is:
6696 typedef long long xsd__nonPositiveInteger;
6699 Type `xsd__nonPositiveInteger` declares a 64-bit integer which is encoded as a *`xsd:nonPositiveInteger`*:
6703 <xsd:nonPositiveInteger xsi:type="xsd:nonPositiveInteger">...</xsd:nonPositiveInteger>
6707 Another possibility is to use strings to represent unbounded integers and do the translation in code.
6710 * *`xsd:normalizedString`*
6711 Represents normalized character strings.
6712 Normalized character strings do not contain the carriage return (#xD), line feed (#xA) nor tab (#x9) characters.
6713 It is recommended to use strings to store *`xsd:normalizeString`* XSD Schema types.
6714 The type declaration is:
6717 typedef char *xsd__normalizedString;
6720 Type `xsd__normalizedString` declares a string type which is encoded as
6724 <xsd:normalizedString xsi:type="xsd:normalizedString">...</xsd:normalizedString>
6728 It is solely the responsibility of the application to make sure the strings do not contain carriage return (#xD), line feed (#xA)
6729 and tab (#x9) characters.
6732 * *`xsd:positiveInteger`*
6733 Corresponds to a positive unbounded integer (>=0).
6734 Since C++ does not support unbounded integers as a standard feature, the recommended type declaration is:
6737 typedef unsigned long long xsd__positiveInteger;
6740 Type `xsd__positiveInteger` declares a 64-bit unsigned integer which is encoded as a *`xsd:positiveInteger`*:
6744 <xsd:positiveInteger xsi:type="xsd:positiveInteger">...</xsd:positiveInteger>
6748 Another possibility is to use strings to represent unbounded integers and do the translation in code.
6752 Corresponds to a 16-bit integer in the range -32768 to 32767.
6753 The type declaration is:
6756 typedef short xsd__short;
6759 Type `xsd__short` declares a short 16-bit integer which is encoded as
6763 <xsd:short xsi:type="xsd:short">...</xsd:short>
6769 Represents character strings. The type declaration is:
6772 typedef char *xsd__string;
6775 Type `xsd__string` declares a string type which is encoded as
6779 <xsd:string xsi:type="xsd:string">...</xsd:string>
6783 The type declaration for wide character strings is:
6786 typedef wchar_t *xsd__string;
6789 Both type of strings can be used at the same time, but requires one typedef name to be changed by appending an underscore which is
6790 invisible in XML. For example:
6793 typedef wchar_t *xsd__string_;
6798 Represents a time. The lexical representation for time is the left truncated lexical representation for dateTime: hh:mm:ss.sss
6799 with optional following time zone indicator.
6800 It is recommended to use strings (`char*`) to store *`xsd:time`* XSD Schema types. The type declaration is:
6803 typedef char *xsd__time;
6807 Represents tokenized strings.
6808 Tokens are strings that do not contain the
6809 line feed (#xA) nor tab (#x9) characters, that have no leading or trailing spaces (#x20) and that have no internal
6810 sequences of two or more spaces.
6811 It is recommended to use strings to store *`xsd:token`* XSD Schema types.
6812 The type declaration is:
6815 typedef char *xsd__token;
6818 Type `xsd__token` declares a string type which is encoded as
6822 <xsd:token xsi:type="xsd:token">...</xsd:token>
6826 It is solely the responsibility of the application to make sure the strings do not contain the line feed (#xA) nor tab (#x9)
6827 characters, that have no leading or trailing spaces (#x20) and that have no internal sequences of two or more spaces.
6830 * *`xsd:unsignedByte`*
6831 Corresponds to an 8-bit unsigned integer in the range 0 to 255.
6832 The type declaration is:
6835 typedef unsigned char xsd__unsignedByte;
6838 Type `xsd__unsignedByte` declares a unsigned 8-bit integer which is encoded as
6842 <xsd:unsignedByte xsi:type="xsd:unsignedByte">...</xsd:unsignedByte>
6847 * *`xsd:unsignedInt`*
6848 Corresponds to a 32-bit unsigned integer in the range 0 to 4294967295.
6849 If the C++ compiler supports 32-bit `int` types, the type declaration can use the `int` type:
6852 typedef unsigned int xsd__unsignedInt;
6855 Otherwise, the C++ compiler supports 16-bit `int` types and the type declaration should use the `long` type:
6858 typedef unsigned long xsd__unsignedInt;
6861 Type `xsd__unsignedInt` declares an unsigned 32-bit integer which is encoded as
6865 <xsd:unsignedInt xsi:type="xsd:unsignedInt">...</xsd:unsignedInt>
6870 * *`xsd:unsignedLong`*
6871 Corresponds to a 64-bit unsigned integer in the range 0 to 18446744073709551615.
6872 The type declaration is:
6875 typedef unsigned long long xsd__unsignedLong;
6881 typedef ULONG64 xsd__unsignedLong;
6884 Type `xsd__unsignedLong` declares an unsigned 64-bit integer which is encoded as
6888 <xsd:unsignedLong xsi:type="xsd:unsignedLong">...</xsd:unsignedLong>
6893 * *`xsd:unsignedShort`*
6894 Corresponds to a 16-bit unsigned integer in the range 0 to 65535.
6895 The type declaration is:
6898 typedef unsigned short xsd__unsignedShort;
6901 Type `xsd__unsginedShort` declares an unsigned short 16-bit integer which is encoded as
6905 <xsd:unsignedShort xsi:type="xsd:unsignedShort">...</xsd:unsignedShort>
6909 Other XSD Schema types such as *`gYearMonth`*, *`gYear`*, *`gMonthDay`*, *`gDay`*, *`xsd:gMonth`*, *`QName`*,
6910 *`NOTATION`*, etc., can be encoded similarly using a `typedef` declaration.
6912 ### How to Use Multiple C/C++ Types for a Single Primitive XSD Type
6914 Trailing underscores (see Section \ref idtrans ) can be used in the type
6915 name in a `typedef` to enable the declaration of multiple storage formats
6916 for a single XML Schema type. For example, one part of a C/C++ application's
6917 data structure may use plain strings while another part may use wide character
6918 strings. To enable this simultaneous use, declare:
6921 typedef char *xsd__string;
6922 typedef wchar_t *xsd__string_;
6925 Now, the `xsd__string` and `xsd__string_` types will both be encoded
6926 and decoded as XML string types and the use of trailing underscores allows
6927 multiple declarations for a single XML Schema type.
6929 ### How to use C++ Wrapper Classes to Specify Polymorphic Primitive Types {#primclass}
6931 SOAP 1.1 supports polymorphic types, because XSD Schema types form a hierarchy.
6932 The root of the hierarchy is called *`xsd:anyType`* (*`xsd:ur-type`* in the
6933 older 1999 schema). So, for example, an array of *`xsd:anyType`* in SOAP may
6934 actually contain any mix of element types that are the derived types of the
6935 root type. The use of polymorphic types is indicated by the WSDL and schema
6936 descriptions of a Web service and can therefore be predicted/expected for each
6939 On the one hand, the `typedef` construct provides a convenient way to
6940 associate C/C++ types with XML Schema types and makes it easy to incorporate
6941 these types in a (legacy) C/C++ application. However, on the other hand the
6942 `typedef` declarations cannot be used to support polymorphic XML Schema
6943 types. Most SOAP clients and services do not use polymorphic types. In case
6944 they do, the primitive polymorphic types can be declared as a hierarchy of C++
6945 `class`es that can be used simultaneously with the `typedef`
6948 The general form of a primitive type declaration that is derived from a super type is:
6951 class xsd__type_name: [optional: public xsd__super_type_name]
6952 { public: Type __item;
6953 [optional: public:] [optional: private] [optional: protected:]
6960 where Type is a primitive C type. The `__item` field MUST be the first
6961 field in this wrapper class.
6963 For example, the XML Schema type hierarchy can be copied to C++ with the following declarations:
6966 class xsd__anyType { };
6967 class xsd__anySimpleType: public xsd__anyType { };
6968 typedef char *xsd__anyURI;
6969 class xsd__anyURI_: public xsd__anySimpleType { public: xsd__anyURI __item; };
6970 typedef bool xsd__boolean;
6971 class xsd__boolean_: public xsd__anySimpleType { public: xsd__boolean __item; };
6972 typedef char *xsd__date;
6973 class xsd__date_: public xsd__anySimpleType { public: xsd__date __item; };
6974 typedef time_t xsd__dateTime;
6975 class xsd__dateTime_: public xsd__anySimpleType { public: xsd__dateTime __item; };
6976 typedef double xsd__double;
6977 class xsd__double_: public xsd__anySimpleType { public: xsd__double __item; };
6978 typedef char *xsd__duration;
6979 class xsd__duration_: public xsd__anySimpleType { public: xsd__duration __item; };
6980 typedef float xsd__float;
6981 class xsd__float_: public xsd__anySimpleType { public: xsd__float __item; };
6982 typedef char *xsd__time;
6983 class xsd__time_: public xsd__anySimpleType { public: xsd__time __item; };
6984 typedef char *xsd__decimal;
6985 class xsd__decimal_: public xsd__anySimpleType { public: xsd__decimal __item; };
6986 typedef char *xsd__integer;
6987 class xsd__integer_: public xsd__decimal_ { public: xsd__integer __item; };
6988 typedef LONG64 xsd__long;
6989 class xsd__long_: public xsd__integer_ { public: xsd__long __item; };
6990 typedef long xsd__int;
6991 class xsd__int_: public xsd__long_ { public: xsd__int __item; };
6992 typedef short xsd__short;
6993 class xsd__short_: public xsd__int_ { public: xsd__short __item; };
6994 typedef char xsd__byte;
6995 class xsd__byte_: public xsd__short_ { public: xsd__byte __item; };
6996 typedef char *xsd__nonPositiveInteger;
6997 class xsd__nonPositiveInteger_: public xsd__integer_ { public: xsd__nonPositiveInteger __item; };
6998 typedef char *xsd__negativeInteger;
6999 class xsd__negativeInteger_: public xsd__nonPositiveInteger_ { public: xsd__negativeInteger __item; };
7000 typedef char *xsd__nonNegativeInteger;
7001 class xsd__nonNegativeInteger_: public xsd__integer_ { public: xsd__nonNegativeInteger __item; };
7002 typedef char *xsd__positiveInteger;
7003 class xsd__positiveInteger_: public xsd__nonNegativeInteger_ { public: xsd__positiveInteger __item; };
7004 typedef ULONG64 xsd__unsignedLong;
7005 class xsd__unsignedLong_: public xsd__nonNegativeInteger_ { public: xsd__unsignedLong __item; };
7006 typedef unsigned long xsd__unsignedInt;
7007 class xsd__unsignedInt_: public xsd__unsginedLong_ { public: xsd__unsignedInt __item; };
7008 typedef unsigned short xsd__unsignedShort;
7009 class xsd__unsignedShort_: public xsd__unsignedInt_ { public: xsd__unsignedShort __item; };
7010 typedef unsigned char xsd__unsignedByte;
7011 class xsd__unsignedByte_: public xsd__unsignedShort_ { public: xsd__unsignedByte __item; };
7012 typedef char *xsd__string;
7013 class xsd__string_: public xsd__anySimpleType { public: xsd__string __item; };
7014 typedef char *xsd__normalizedString;
7015 class xsd__normalizedString_: public xsd__string_ { public: xsd__normalizedString __item; };
7016 typedef char *xsd__token;
7017 class xsd__token_: public xsd__normalizedString_ { public: xsd__token __item; };
7020 Note the use of the trailing underscores for the `class` names to distinguish the `typedef` type names from the
7021 `class` names. Only the most frequently used built-in schema types are shown.
7022 It is also allowed to include the `xsd:base64Binary` and `xsd:hexBinary` types in the hierarchy:
7025 class xsd__base64Binary: public xsd__anySimpleType { public: unsigned char *__ptr; int __size; };
7026 class xsd__hexBinary: public xsd__anySimpleType { public: unsigned char *__ptr; int __size; };
7029 See Sections \ref base64binary and \ref hexbinary .
7031 Methods are allowed to be added to the classes above, such as constructors and getter/setter methods, see Section \ref gettersetter .
7033 Wrapper structs are supported as well, similar to wrapper classes. But they cannot be used
7034 to implement polymorphism. Rather, the wrapper structs facilitate the use of XML attributes
7035 with a primitive typed object, see \ref attributes .
7037 ### Multi-Reference Strings
7039 If more than one `char` pointer points to the same string, the string is encoded as a multi-reference value.
7040 Consider for example
7043 char *s = "hello", *t = s;
7046 The `s` and `t` variables are assigned the same string, and when serialized, `t` refers to the content of `s`:
7050 <string id="123" xsi:type="string">hello</string>
7052 <string href="#123"/>
7056 The example assumed that `s` and `t` are encoded as independent elements.
7058 Note: the use of `typedef` to declare a string type such as `xsd__string` will not affect the multi-reference string
7059 encoding. However, strings declared with different `typedef`s will never be considered multi-reference even when they point
7060 to the same string. For example
7063 typedef char *xsd__string;
7064 typedef char *xsd__anyURI;
7065 xsd__anyURI *s = "http://www.myservice.com";
7069 The variables `s` and `t` point to the same string, but since they are considered different types their content will not
7070 be shared in the SOAP payload through a multi-referenced string.
7072 ### "Smart String" Mixed-Content Decoding {#smart}
7074 The implementation of string decoding in gSOAP allows for mixed content decoding. If the SOAP payload contains a complex data type in place of
7075 a string, the complex data type is decoded in the string as plain XML text.
7077 For example, suppose the `getInfo` service operation returns some detailed information. The service operation is declared as:
7080 // Contents of header file "getInfo.h":
7081 getInfo(char *detail);
7084 The proxy of the service is used by a client to request a piece of information and the service responds with:
7089 Content-Type: text/xml
7092 <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
7093 xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
7094 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
7095 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
7099 <picture>Mona Lisa by <i>Leonardo da Vinci</i></picture>
7103 </SOAP-ENV:Envelope>
7107 As a result of the mixed content decoding, the `detail` string contains "*`<picture>Mona Lisa by <i>Leonardo da Vinci</i></picture>`*".
7109 ### C++ Strings {#strings}
7111 gSOAP supports C++ strings `std::string` and `std::wstring` wide character strings.
7115 typedef std::string xsd__string;
7118 xsd__string s; // serialized with xsi:type="xsd:string"
7119 std::string t; // serialized without xsi:type
7124 @warning Please avoid mixing `std::string` and C strings (`char*`) in the header file when using SOAP 1.1 encoding. The problem is that multi-referenced strings in SOAP encoded messages cannot be assigned simultaneously to a `std::string` and a `char*` string.
7126 ### Changing the Encoding Precision of float and double Types
7128 The `double` encoding format is by default set to "`%.18G`" (see a manual on `printf` text formatting in C),
7129 i.e. at most 18 digits of precision to limit a loss in accuracy.
7130 The `float` encoding format is by default "`%.9G`", i.e. at most 9 digits of precision.
7132 The encoding format of a double type can be set by assigning a format string to `soap.double_format`, where `soap` is a
7133 variable that contains the
7134 current runtime context. For example:
7138 soap_init(&soap); // sets double_format = "%.18G"
7139 soap.double_format = "%e"; // redefine
7142 which causes all doubles to be encoded in scientific notation.
7143 Likewise, the encoding format of a float type can be set by assigning a format string to the static `soap_float_format` string variable. For example:
7147 soap_init(&soap); // sets float_format = "%.9G"
7148 soap.float_format = "%.4f"; // redefine
7151 which causes all floats to be encoded with four digits precision.
7153 @warning The format strings are not automatically reset before or after
7154 SOAP communications. An error in the format string may result in the incorrect
7155 encoding of floating point values.
7157 A special case for C format string patterns is introduced in gSOAP 2.8.18. A
7158 C format string that is used as a pattern for a typedef float or double in the
7159 gSOAP header file is used to format the output of the floating point value in
7163 typedef float time__ratio "%5.2f";
7166 This will output the float with 5 digits total and 2 digits after the decimal
7169 When *`xs:totalDigits`* and *`xs:fractionDigits`* are given in a XSD file,
7170 then also a C format string is produced to output floating point values with
7171 the proper precision and scale. For example:
7175 <simpleType name="ratio">
7176 <restriction base="xsd:float">
7177 <totalDigits value="5"/>
7178 <fractionDigits value="2"/>
7184 ### INF, -INF, and NaN Values of float and double Types
7186 The gSOAP runtime `stdsoap2.cpp` and header file `stdsoap2.h` support the marshalling of IEEE INF, -INF, and NaN
7187 representations. Under certain circumstances this may break if the hardware and/or C/C++ compiler does not support these
7189 To remove the representations, remove the inclusion of the `<math.h>` header file from the `stdsoap2.h` file.
7190 You can control the representations as well, which are defined by the macros:
7201 ## Enumeration Serialization {#enum}
7203 Enumerations are generally useful for the declaration of named integer-valued constants, also called enumeration constants.
7205 ### Serialization of Symbolic Enumeration Constants
7207 The gSOAP `soapcpp2` tool encodes the constants of enumeration-typed variables in symbolic form using the names of the constants when possible to comply to SOAP's enumeration encoding style. Consider for example the following enumeration of weekdays:
7210 enum weekday {Mon, Tue, Wed, Thu, Fri, Sat, Sun};
7213 The enumeration-constant `Mon`, for example, is encoded as
7217 <weekday xsi:type="weekday">Mon</weekday>
7221 The value of the *`xsi:type`* attribute is the enumeration-type identifier's name. If the element is independent as in the example above, the element name is the enumeration-type identifier's name.
7223 The encoding of complex types such as enumerations requires a reference to an XML Schema through the use of a namespace prefix. The namespace prefix can be specified as part of the enumeration-type identifier's name, with the usual namespace prefix conventions for identifiers. This can be used to explicitly specify the encoding style. For example:
7226 enum ns1__weekday {Mon, Tue, Wed, Thu, Fri, Sat, Sun};
7229 The enumeration-constant `Sat`, for example, is encoded as:
7233 <ns1:weekday xsi:type="ns1:weekday">Sat</ns1:weekday>
7237 The corresponding XML Schema for this enumeration data type would be:
7241 <xsd:element name="weekday" type="tns:weekday"/>
7242 <xsd:simpleType name="weekday">
7243 <xsd:restriction base="xsd:string">
7244 <xsd:enumeration value="Mon"/>
7245 <xsd:enumeration value="Tue"/>
7246 <xsd:enumeration value="Wed"/>
7247 <xsd:enumeration value="Thu"/>
7248 <xsd:enumeration value="Fri"/>
7249 <xsd:enumeration value="Sat"/>
7250 <xsd:enumeration value="Sun"/>
7256 ### Encoding of Enumeration Constants
7258 If the value of an enumeration-typed variable has no corresponding named constant, the value is encoded as a signed integer literal. For example, the following declaration of a `workday` enumeration type lacks named constants for Saturday and Sunday:
7261 enum ns1__workday {Mon, Tue, Wed, Thu, Fri};
7264 If the constant `5` (Saturday) or `6` (Sunday) is assigned to a variable of the `workday` enumeration type, the variable will be encoded with the integer literals *`5`* and *`6`*, respectively. For example:
7268 <ns1:workday xsi:type="ns1:workday">5</ns1:workday>
7272 Since this is legal in C++ and SOAP allows enumeration constants to be integer literals, this method ensures that non-symbolic
7273 enumeration constants are correctly communicated to another party if the other party accepts literal enumeration constants (as
7274 with the gSOAP `soapcpp2` tool).
7276 Both symbolic and literal enumeration constants can be decoded.
7278 To enforce the literal enumeration constant encoding and to get the literal constants in the WSDL file, use the following trick:
7281 enum ns1__nums { _1 = 1, _2 = 2, _3 = 3 };
7284 The difference with an enumeration type without a list of values and the enumeration type above is that the enumeration constants
7285 will appear in the WSDL service description.
7287 ### Initialized Enumeration Constants
7289 The gSOAP `soapcpp2` compiler supports the initialization of enumeration constants, as in:
7291 enum ns1__relation {LESS = -1, EQUAL = 0, GREATER = 1};
7293 The symbolic names *`LESS`*, *`EQUAL`*, and *`GREATER`* will appear in the SOAP payload for the encoding of the `ns1__relation` enumeration values `-1`, `0`, and `1`, respectively.
7295 ### How to "Reuse" Symbolic Enumeration Constants
7297 A well-known deficiency of C and C++ enumeration types is the lack of support for the reuse of symbolic names by multiple enumerations. That is, the names of all the symbolic constants defined by an enumeration cannot be reused by another enumeration. To force encoding of the same symbolic name by different enumerations, the identifier of the symbolic name can end in an underscore (`_`) or any number of underscores to distinguish it from other symbolic names in C++. This guarantees that the SOAP encoding will use the same name, while the symbolic names can be distinguished in C++. Effectively, the underscores are removed from a symbolic name prior to encoding.
7299 Consider for example:
7302 enum ns1__workday {Mon, Tue, Wed, Thu, Fri};
7303 enum ns1__weekday {Mon_, Tue_, Wed_, Thu_, Fri_, Sat_, Sun_};
7306 which will result in the encoding of the constants of `enum ns1__weekday` without the underscore, for example as *`Mon`*.
7308 As an alternative to the trailing underscores that can get quite long for commonly used symbolic enum names, you can use the following convention with double underscores to add the enum name to the enum constants:
7311 enum prefixedname { prefixedname__enumconst1, prefixedname__enumconst2, ... };
7314 where the type name of the enumeration `prefixedname` is a prefixed name,
7323 ns1__workday__Fri };
7335 This ensures that the XML schema enumeration values are still simply *`Mon`*, *`Tue`*, *`Wed`*, *`Thu`*, *`Fri`*, *`Sat`*, and *`Sun`*.
7337 @warning The following declaration:
7340 enum ns1__workday {Mon, Tue, Wed, Thu, Fri};
7341 enum ns1__weekday {Sat = 5, Sun = 6};
7344 will not properly encode the `weekday` enumeration when you assume that workdays are part of weekdays, because it lacks the named constants for `workday` in its enumeration list. All enumerations must be self-contained and cannot use enum constants of other enumerations.
7346 ### Boolean Enumeration Serialization for C {#boolean}
7348 When developing a C Web service application, the C++ `bool` type should not be used since it is not usually supported by the C compiler.
7349 Instead, an enumeration type should be used to serialize true/false values as *`xsd:boolean`* Schema type enumeration values.
7350 The *`xsd:boolean`* XML Schema type is defined as:
7353 enum xsd__boolean {false_, true_};
7356 The value `false_`, for example, is encoded as:
7360 <xsd:boolean xsi:type="xsd:boolean">false</xsd:boolean>
7364 Peculiar of the SOAP boolean type encoding is that it only defines the values *`0`* and *`1`*, while the built-in XML Schema boolean type also defines the *`false`* and *`true`* symbolic constants as valid values. The following example declaration of an enumeration type lacks named constants altogether to force encoding of the enumeration values as literal constants:
7367 enum SOAP_ENC__boolean {};
7370 The value `0`, for example, is encoded with an integer literal:
7374 <SOAP-ENC:boolean xsi:type="SOAP-ENC:boolean">0<SOAP-ENC:boolean>
7378 ### Bitmask Enumeration Serialization
7380 A bitmask is an enumeration of flags such as declared with C#'s [Flags] `enum` annotation.
7381 gSOAP supports bitmask encoding and decoding for interoperability. However, bitmask types are not standardized with SOAP RPC.
7383 A special syntactic convention is used in the header file input to the gSOAP `soapcpp2` compiler to indicate the use of bitmasks with an
7387 enum * *name* { *enum-constant*, *enum-constant*, ... };
7390 The gSOAP `soapcpp2` compiler will encode the enumeration constants as flags, i.e. as a series of powers of 2 starting with 1.
7391 The enumeration constants can be or-ed to form a bitvector (bitmask) which is encoded and decoded as a list of symbolic values
7396 enum * ns__machineStatus { ON, BELT, VALVE, HATCH};
7397 int ns__getMachineStatus(char *name, char *enum ns__machineStatus result);
7400 Note that the use of the `enum` does not require the asterisk, only the definition.
7401 The gSOAP `soapcpp2` compiler generates the enumeration:
7404 enum ns__machineStatus { ON=1, BELT=2, VALVE=4, HATCH=8};
7407 A service operation implementation in a Web service can return:
7410 int ns__getMachineStatus(struct soap *soap, char *name, enum ns__machineStatus result)
7412 *result = BELT | HATCH;
7417 ## Struct Serialization {#struct}
7419 A `struct` data type is encoded as an XML Schema complexType such that the
7420 `struct` name is the XML Schema type name and the
7421 fields of the `struct` are the type's accessors. This encoding is
7422 identical to the `class` instance encoding without inheritance and method
7423 declarations, see Section \ref class for further details. However, the
7424 encoding and decoding of `struct`s is more efficient compared to
7425 `class` instances due to the lack of inheritance and the requirement by
7426 the serialization routines to check inheritance properties at run time.
7428 Certain type of fields of a `struct` can be (de)serialized as XML
7429 attributes using the `@` type qualifier. See Section \ref attributes
7432 See Section \ref idtrans for more details on the struct/class member field
7433 serialization and the resulting element and attribute qualified forms.
7435 ## Class Instance Serialization {#class}
7437 A `class` instance is serialized as an XML Schema complexType (SOAP-encoded compound data type) such that the
7438 `class` name forms the data type's element name and schema type and the
7439 data member fields are the data type's accessors. Only the data member fields
7440 are encoded in the SOAP payload. Class methods are not encoded.
7442 The general form of a `class` declaration is:
7445 class [optional: namespace_prefix__]class_name1 [optional: :[optional: public:] [optional: private:] [optional: protected:] [optional: namespace_prefix__]class_name2]
7447 [optional: public:] [optional: private:] [optional: protected:]
7451 [optional: public:] [optional: private:] [optional: protected:]
7460 * `namespace_prefix__` is the optional namespace prefix of the compound data type (see identifier translation rules \ref idtrans )
7462 * `class_name1` is the element name of the compound data type (see identifier translation rules \ref idtrans ).
7464 * `class_name2` is an optional base class.
7466 * `field` is a field declaration (data member). A field MAY be declared `static` and `const` and MAY be initialized.
7468 * `method` is a method declaration. A method MAY be declared `virtual`, but abstract methods are not allowed. The method parameter declarations are REQUIRED to have parameter identifier names.
7470 * [optional: public:] [optional: private:] [optional: protected:] are OPTIONAL. Only members with `public` acces permission can be serialized.
7472 A class name is REQUIRED to be unique and cannot have the same name as a
7473 `struct`, `enum`, or service operation name specified in the header file
7474 input to the gSOAP `soapcpp2` compiler. The reason is that service operation requests are
7475 encoded similarly to class instances in SOAP and they are in principle
7476 undistinguishable (the method parameters are encoded just as the fields of a
7479 Only single inheritance is supported by the gSOAP `soapcpp2` compiler. Multiple
7480 inheritance is not supported, because of the limitations of the SOAP protocol.
7482 If a constructor method is present, there MUST also be a constructor
7483 declaration with empty parameter list.
7485 Classes should be declared "volatile" if you don't want gSOAP to add serialization methods to these classes, see Section \ref volatile for more details.
7487 Class templates are not supported by the gSOAP `soapcpp2` compiler, but you can use STL containers,
7488 see Section \ref templates . You can also define your own
7489 containers similar to STL containers.
7491 Certain type of fields of a `struct` can be (de)serialized as XML
7492 attributes using the `@` type qualifier. See Section \ref attributes
7495 See Section \ref idtrans for more details on the struct/class member field
7496 serialization and the resulting element and attribute qualified forms.
7498 Arrays may be embedded within a class (and struct) using a pointer field and
7499 size information, see Section \ref list . This defines what is sometimes
7500 referred to in SOAP as "generics".
7502 Void pointers may be used in a class (or struct), but you have to add a type
7503 field so the gSOAP runtime can determine the type of object pointed to, see
7506 A `class` instance is encoded as:
7510 <[optional: namespace-prefix:]class-name xsi:type="[optional: namespace-prefix:]class-name">
7511 <basefield-name1 xsi:type="...">...</basefield-name1>
7512 <basefield-name2 xsi:type="...">...</basefield-name2>
7514 <field-name1 xsi:type="...">...</field-name1>
7515 <field-name2 xsi:type="...">...</field-name2>
7517 </[optional: namespace-prefix:]class-name>
7521 where the *`field-name`* accessors have element-name representations of the
7522 class fields and the *`basefield-name`* accessors have element-name
7523 representations of the base class fields. (The optional parts resulting from
7524 the specification are shown enclosed in [optional: ].)
7526 The decoding of a class instance allows any ordering of the accessors in the
7527 SOAP payload. However, if a base class field name is identical to a derived
7528 class field name because the field is overloaded, the base class field name
7529 MUST precede the derived class field name in the SOAP payload for decoding.
7530 gSOAP guarantees this, but interoperability with other SOAP implementations is
7531 cannot be guaranteed.
7535 The following example declares a base class `ns__Object` and a derived class `ns__Shape`:
7538 // Contents of file "shape.h":
7544 class ns__Shape : public ns__Object
7548 enum ns__Color {Red, Green, Blue} color;
7550 ns__Shape(int sides, enum ns__Green color);
7555 The implementation of the methods of `class ns__Shape` must not be part of the header file and need to be defined elsewhere.
7557 An instance of `class ns__Shape` with name Triangle, 3 sides, and color Green is encoded as:
7561 <ns:Shape xsi:type="ns:Shape">
7562 <name xsi:type="string">Triangle</name>
7563 <sides xsi:type="int">3</sides>
7564 <color xsi:type="ns:Color">Green</color>
7569 The namespace URI of the namespace prefix *`ns`* must be defined by a namespace mapping table, see Section \ref nstable .
7571 ### Initialized static const Fields
7573 A data member field of a class declared as `static const` is initialized
7574 with a constant value at compile time. This field is encoded in the
7575 serialization process, but is not decoded in the deserialization process. For
7579 // Contents of file "triangle.h":
7580 class ns__Triangle : public ns__Object
7584 static const int sides = 3;
7588 An instance of `class ns__Triangle` is encoded in SOAP as:
7592 <ns:Triangle xsi:type="ns:Triangle">
7593 <name xsi:type="string">Triangle</name>
7594 <size xsi:type="int">15</size>
7595 <sides xsi:type="int">3>/sides>
7600 Decoding will ignore the `sides` field's value.
7602 @warning The current gSOAP implementation does not support encoding
7603 `static const` fields, due to C++ compiler compatibility differences.
7604 This feature may be provided the future.
7608 A `class` declaration in the header file input to the gSOAP `soapcpp2` compiler MAY
7609 include method declarations. The method implementations MUST NOT be part of
7610 the header file but are required to be defined in another C++ source that is
7611 externally linked with the application. This convention is also used for the
7612 constructors and destructors of the `class`.
7614 Dynamic binding is supported, so a method MAY be declared `virtual`.
7616 ### Getter and Setter Methods {#gettersetter}
7618 Setter and getter methods are invoked at run time upon serialization and
7619 deserialization of class instances, respectively. The use of setter and getter methods adds more flexibility to the serialization and deserialization process.
7621 A setter method is called in the serialization phase from the virtual
7622 `soap_serialization` method generated by the gSOAP `soapcpp2` compiler. You can use
7623 setter methods to process a class instance just before it is serialized. A
7624 setter method can be used to convert application data, such as translating
7625 transient application data into serializable data, for example. You can also
7626 use setter methods to retrieve dynamic content and use it to update a class
7627 instance right before serialization. Remember setters
7628 as "set to serialize" operations.
7630 Getter methods are invoked after deserialization of the instance. You can use
7631 them to adjust the contents of class instances after all their members have been
7632 deserialized. Getters can be used to convert deserialized members into
7633 transient members and even invoke methods to process the deserialized data on
7636 Getter and setter methods have the following signature:
7639 [optional: virtual] int get(struct soap *soap) [optional: const];
7640 [optional: virtual] int set(struct soap *soap);
7643 The active soap struct will be passed to the `get` and `set` methods. The methods should return `SOAP_OK` when successful. A setter method should prepare the contents of the class instance for serialization. A getter method should process the instance after deserialization.
7645 Here is an example of a base64 binary class:
7648 class xsd__base64Binary
7650 unsigned char *__ptr;
7652 int get(struct soap *soap);
7653 int set(struct soap *soap);
7657 Suppose that the type and options members of the attachment should be set when
7658 the class is about to be serialized. This can be accomplished with the
7659 `set` method from the information provided by the `__ptr` to the data
7660 and the soap struct passed to the `set` method (you can pass data via the
7661 `void *soap.user` field).
7663 The `get` method is invoked after the base64 data has been processed. You
7664 can use it for post-processing purposes.
7666 Here is another example. It defines a primitive `update` type. The class is a wrapper for the `time_t` type, see Section \ref primclass . Therefore, elements of this type contain *`xsd:dateType`* data.
7672 int set(struct soap *soap);
7676 The setter method assigns the current time:
7679 int update::set(struct soap *soap)
7681 this->__item = time(NULL);
7686 Therefore, serialization results in the inclusion of a time stamp in XML.
7688 @warning a `get` method is invoked only when the XML element with its data
7689 was completely parsed. The method is not invoked when the element is an *`xsi:nil`* element or has an
7692 @warning The `soap_out` method of a class calls the setter (when
7693 provided). However, the `soap_out` method is declared `const`
7694 while the setter should be allowed to modify the contents of the class
7695 instance. Therefore, the gSOAP-generated code recasts the instance and the
7696 `const` is removed when invoking the setter.
7698 ### Streaming XML with Getter and Setter Methods {#streaming}
7700 Getter methods enable streaming XML operations. A getter method is invoked
7701 when the object is deserialized and the rest of the SOAP/XML message has not
7702 been processed yet. For example, you can add a getter method to the SOAP Header
7703 class to implement header processing logic that is activated as soon as the
7704 SOAP Header is received. An example code is shown below:
7707 class h__Authentication
7710 int get(struct soap *soap);
7712 class SOAP_ENV__Header
7714 h__Authentication *h__authentication;
7718 The `Authentication` SOAP Header field is instantiated and decoded. After
7719 decoding, the getter method is invoked, which can be used to check the `id`
7720 before the rest of the SOAP message is processed.
7722 ### Polymorphism, Derived Classes, and Dynamic Binding {#polymorph}
7724 Interoperability between client and service applications developed with gSOAP
7725 is established even when clients and/or services use derived classes instead of
7726 the base classes used in the declaration of the service operation parameters. A
7727 client application MAY use pointers to instances of derived classes for the
7728 input parameters of a service operation. If the service was compiled with a
7729 declaration and implementation of the derived class, the service operation base
7730 class input parameters are demarshalled and a derived class instance is created
7731 instead of a base class instance. If the service did not include a declaration
7732 of the derived class, the derived class fields are ignored and a base class
7733 instance is created. Therefore, interoperability is guaranteed even when the
7734 client sends an instance of a derived classes and when a service returns an
7735 instance of a derived class.
7737 The following example declares Base and Derived classes and a service operation
7738 that takes a pointer to a Base class instance and returns a Base class
7742 // Contents of file "derived.h"
7748 virtual void print();
7750 class Derived : public Base
7755 virtual void print();
7757 int method(Base *in, struct methodResponse { Base *out; } &result);
7760 This header file specification is processed by the gSOAP `soapcpp2` compiler to produce the stub and skeleton routines which are used to implement a client and service.
7761 The pointer of the service operation is also allowed to point to Derived class instances and these instances will be marshalled as Derived class instances and send to a service, which is in accord to the usual semantics of parameter passing in C++ with dynamic binding.
7763 The Base and Derived class method implementations are:
7766 // Method implementations of the Base and Derived classes:
7771 cout << "created a Base class instance" << endl;
7775 cout << "created a Derived class instance" << endl;
7779 cout << "print(): Base class instance " << name << endl;
7783 cout << "print(): Derived class instance " << name << " " << num << endl;
7787 Below is an example `CLIENT` application that creates a Derived class instance that is passed as the input parameter of the service operation:
7798 struct methodResponse r;
7801 soap_call_method(&soap, url, action, &obj1, r);
7807 The following example `SERVER1` application copies a class instance (Base or Derived class) from the input to the output parameter:
7814 soap_serve(soap_new());
7816 int method(struct soap *soap, Base *obj1, struct methodResponse &result)
7825 The following messages are produced by the `CLIENT` and `SERVER1` applications:
7827 CLIENT: created a Derived class instance
7828 SERVER1: created a Derived class instance
7829 SERVER1: print(): Derived class instance X 3
7830 CLIENT: created a Derived class instance
7831 CLIENT: print(): Derived class instance X 3
7833 Which indicates that the derived class kept its identity when it passed through `SERVER1`. Note that instances are created both by the `CLIENT` and `SERVER1` by the demarshalling process.
7835 Now suppose a service application is developed that only accepts Base class instances. The header file is:
7838 // Contents of file "base.h":
7844 virtual void print();
7846 int method(Base *in, Base *out);
7849 This header file specification is processed by the gSOAP `soapcpp2` tool to produce skeleton routine which is used to implement a service (so the client will still use the derived classes).
7851 The method implementation of the Base class are:
7854 // Method implementations of the Base class:
7859 cout << "created a Base class instance" << endl;
7863 cout << "print(): Base class instance " << name << endl;
7867 And the `SERVER2` application is that uses the Base class is:
7874 soap_serve(soap_new());
7876 int method(struct soap *soap, Base *obj1, struct methodResponse &result)
7885 Here are the messages produced by the `CLIENT` and `SERVER2` applications:
7887 CLIENT: created a Derived class instance
7888 SERVER2: created a Base class instance
7889 SERVER2: print(): Base class instance X
7890 CLIENT: created a Base class instance
7891 CLIENT: print(): Base class instance X
7893 In this example, the object was passed as a Derived class instance to `SERVER2`. Since `SERVER2` only implements the Base class, this object is converted to a Base class instance and send back to `CLIENT`.
7895 ### XML Attributes {#attributes}
7897 The SOAP RPC/LIT and SOAP DOC/LIT encoding styles support XML attributes in
7898 SOAP messages while SOAP RPC with "Section 5" encoding does not support XML
7899 attributes other than the SOAP and XSD specific attributes. SOAP RPC Section
7900 5 encoding has advantages for cross-language interoperability and data
7901 encodings such as graph serialization. However, RPC/LIT and DOC/LIT enables
7902 direct exchange of XML documents, which may include encoded application data
7903 structures. Language interoperability is compromised, because no mapping
7904 between XML and the typical language data types is defined. The meaning of the
7905 RPC/LIT and DOC/LIT XML content is Schema driven rather than
7906 application/language driven.
7908 gSOAP supports XML attribute (de)serialization of members in structs and classes.
7909 Attributes are primitive XSD types, such as strings, enumerations, boolean, and
7910 numeric types. To declare an XML attribute in a struct/class, the qualifier
7911 `@` is used with the type of the attribute. The type must be
7912 primitive type (including enumerations and strings), which can be declared with or without
7913 a `typedef` to associate a XSD type with the C/C+ type. For example
7916 typedef char *xsd__string;
7917 typedef bool *xsd__boolean;
7918 enum ns__state { _0, _1, _2 };
7921 @ xsd__string ns__type;
7922 @ xsd__boolean ns__flag = false;
7923 @ enum ns__state ns__state = _2;
7924 struct ns__myStruct *next;
7928 The `@` qualifier indicates XML attribute encoding for the
7929 `ns__type`, `ns__flag`, and `ns__state` fields. Note that the
7930 namespace prefix `ns` is used to distinguish these attributes from any
7931 other attributes such as *`xsi:type`* (*`ns:type`* is not to be confused
7934 Default values can be associated with any field that has
7935 a primitive type in a struct/class, as is illustrated in this example. The
7936 default values are used when the receiving message does not contain the
7937 corresponding values.
7939 String attributes are optional. Other type of attributes should be declared as pointers to make them optional:
7944 @ int *a; // omitted when NULL
7948 Because a service operation request and response is essentially a struct, XML
7949 attributes can also be associated with method requests and responses. For
7953 int ns__myMethod(@ char *ns__name, ...);
7956 Attributes can also be attached to the dynamic arrays, binary types, and wrapper classes/structs of primitive
7957 types. Wrapper classes are described in Section \ref primclass . For
7964 @ xsd__boolean flag;
7971 struct xsd__base64Binary
7973 unsigned char *__ptr;
7975 @ xsd__boolean flag;
7979 The attribute declarations MUST follow the `__item`, `__ptr`, and `__size` fields
7980 which define the characteristics of wrapper structs/classes and dynamic arrays.
7982 @warning Do not use XML attributes with SOAP RPC encoding. You can only use attributes with RPC literal encoding.
7984 ### QName Attributes and Elements
7986 gSOAP ensures the proper decoding of XSD QNames.
7987 An element or attribute with type QName (Qualified Name) contains a namespace prefix and a local name.
7988 You can declare a QName type as a `typedef char *xsd__QName`. Values of type QName
7989 are internally handled as regular strings.
7990 gSOAP takes care of the proper namespace prefix mappings when deserializing QName values.
7994 typedef char *xsd__QName;
7997 xsd__QName elt = "ns:xyz"; // QName element with default value "ns:xyz"
7998 @ xsd__QName att = "ns:abc"; // QName attribute with default value "ns:abc"
8002 When the `elt` and `att` fields are serialized,
8003 their string contents are just transmitted (which means that the application is responsible to
8004 ensure proper formatting of the QName strings prior to transmission). When the
8005 fields are deserialized however, gSOAP takes care mapping the qualifiers to the
8006 appropriate namespace prefixes. Suppose that the inbound value
8007 for the `elt` is *`x:def`*, where the namespace name associated with the
8008 prefix *`x`* matches the namespace name of the prefix *`ns`* (as defined in
8009 the namespace mapping table). Then, the value is automatically converted into *`ns:def`*.
8010 If the namespace name is not in the table, then
8011 *`x:def`* is converted to `"{`URI":def} where *`"{`*URI"} is the namespace
8012 URI bound to *`x`* in the message received. This enables an application to
8013 retrieve the namespace information, whether it is in the namespace mapping
8016 Note: `QName` is a pre-defined typedef type and used by gSOAP to
8017 (de)serialize SOAP Fault codes which are QName elements.
8019 ## Union Serialization {#union}
8021 A `union` is only serialized if the `union` is used within a
8022 `struct` or `class` declaration that includes a `int __union`
8023 field that acts as a *discriminant* or *selector* for the `union`
8024 fields. The selector stores run-time usage information about the `union`
8025 fields. That is, the selector is used to enumerate the `union` fields such
8026 that the gSOAP engine is able to select the correct `union` field to
8029 A `union` within a `struct` or `class` with a selector field
8030 represents *`xs:choice`* within a Schema complexType component. For example:
8037 union ns__PO_or_Invoice
8040 struct ns__Invoice invoice;
8042 struct ns__composite
8046 union ns__PO_or_Invoice value;
8050 The `union ns__PO_or_Invoice` is expanded as a *`xs:choice`*:
8054 <complexType name="composite">
8056 <element name="name" type="xsd:string"/>
8058 <element name="po" type="ns:PO"/>
8059 <element name="invoice" type="ns:Invoice"/>
8066 Therefore, the name of the `union` and field can be freely chosen.
8067 However, the `union` name should be qualified (as shown in the example) to
8068 ensure instances of XML Schemas with *`elementFormDefault="qualified"`* are
8069 correctly serialized (`po` and `invoice` are *`ns:`* qualified).
8071 The `int __union` field selector's values are determined by the
8072 `soapcpp2` compiler. Each `union` field name has a selector value
8076 SOAP_UNION_*union-name*_*field-name*
8079 These selector values enumerate the `union` fields starting with 1. The
8080 value 0 (or any negative value) can be assigned to omit the serialization of the `union`, but only
8081 if explicitly allowed by validation rules, which requires *`minOccurs="0"`*
8082 for the *`xs:choice`* as follows:
8085 struct ns__composite
8088 int __union 0; // *`<choice minOccurs="0"{`*>}
8089 union ns__PO_or_Invoice value;
8093 This way we can treat the `union` as an optional data item by setting `__union=0`.
8095 Since 2.7.16 it is also possible to use a '`$`' as a special marker to annotate a
8096 selector field that must be of type `int` and the field name is no longer
8100 struct ns__composite
8103 $int select 0; // *`<choice minOccurs="0"{`*>}
8104 union ns__PO_or_Invoice value;
8108 The following example shows how the `struct ns__composite` instance is
8109 initialized for serialization using the above declaration:
8112 struct ns__composite data;
8114 data.select = SOAP_UNION_ns__PO_or_Invoice_po; // select PO
8115 data.value.po.number = ...; // populate the PO
8118 Note that failing to set the selector to a valid `union` field can lead to
8119 a crash of the gSOAP serializer because it will attempt to serialize an invalid
8122 For deserialization of `union` types, the selector will be
8124 `union` field selector values, as determined by the XML payload.
8125 The selector will be set to 0 or -1 when no union member was deserialized,
8126 where a negative value indicates that a member was required by validation rules.
8127 Strict validation enabled with `SOAP_XML_STRICT` results in a validation fault.
8129 When more than one `union` is used in a `struct` or `class`, the
8130 `__union` selectors must be renamed to avoid name clashes by using
8134 struct ns__composite
8137 $int sel_value; // = SOAP_UNION_ns__PO_or_Invoice_[po|invoice]
8138 union ns__PO_or_Invoice value;
8139 $int sel_data; // = SOAP_UNIO_ns__Email_or_Fax_[email|fax]
8140 union ns__Email_or_Fax data;
8144 ## Serializing Pointer Types {#pointer}
8146 The serialization of a pointer to a data type amounts to the serialization of
8147 the data type in SOAP and the SOAP encoded representation of a pointer to the
8148 data type is indistinguishable from the encoded representation of the data
8151 ### Multi-Referenced Data
8153 A data structure pointed to by more than one pointer is serialized as SOAP
8154 multi-reference data. This means that the data will be serialized only once and
8155 identified with a unique *`id`* attribute. The encoding of the pointers to
8156 the shared data is done through the use of *`href`* or *`ref`* attributes
8157 to refer to the multi-reference data. See Section \ref flags on
8158 options to control the serialization of multi-reference data. To turn multi-ref off, use `SOAP_XML_TREE` to process plain tree-based XML. To completely eliminate multi-ref (de)serialization use the `WITH_NOIDREF` compile-time flag with all source code (including `stdsoap2.c` and `stdsoap2.cpp`) to permanently disable id-href processing. Cyclic C/C++
8159 data structures are encoded with multi-reference SOAP encoding. Consider for
8160 example the following a linked list data structure:
8163 typedef char *xsd__string;
8167 struct ns__list *next;
8171 Suppose a cyclic linked list is created. The first node contains the value "abc" and points to a node with value
8172 "def" which in turn points to the first node. This is encoded as:
8176 <ns:list id="1" xsi:type="ns:list">
8177 <value xsi:type="xsd:string">abc</value>
8178 <next xsi:type="ns:list">
8179 <value xsi:type="xsd:string">def</value>
8186 In case multi-referenced data is received that "does not fit in a pointer-based structure", the data is copied.
8187 For example, the following two `struct`s are similar, except that the first uses pointer-based fields while the other uses
8188 non-pointer-based fields:
8191 typedef long xsd__int;
8208 Since both `a` and `b` fields of `P` point to the same integer, the encoding of `P` is multi-reference:
8212 <ns:record xsi:type="ns:record">
8216 <id id="1" xsi:type="xsd:int">123</id>
8220 Now, the decoding of the content in the `R` data structure that does not use pointers to integers results in a copy of each
8221 multi-reference integer. Note that the two `struct`s resemble the same XML data type because the trailing underscore will be
8222 ignored in XML encoding and decoding.
8224 ### NULL Pointers and Nil Elements
8226 A `NULL` pointer is **not** serialized, unless the pointer itself is pointed to by another pointer (but see
8227 Section \ref flags to control the serialization of NULLs).
8238 Suppose pointer `q` points to pointer `p` and suppose `p=NULL`.
8239 In that case the `p` pointer is serialized as
8243 <... id="123" xsi:nil="true"/>
8247 and the serialization of `q` refers to *`href="#123"`*.
8248 Note that SOAP 1.1 does not support
8249 pointer to pointer types (!), so this encoding is specific to gSOAP. The pointer to pointer encoding is rarely used in codes
8250 anyway. More common is a pointer to a data type such as a `struct` with pointer fields.
8252 @warning When the deserializer encounters an XML element that has a *`xsi:nil="true"`* attribute but the corresponding C++ data is not a pointer or reference,
8253 the deserializer will terminate with a `SOAP_NULL` fault when the `SOAP_XML_STRICT` flag is set.
8254 The types section of a WSDL description contains information on the "nilability" of data.
8256 ## Void Pointers {#void}
8258 In general, void pointers (`void*`) cannot be (de)serialized because the
8259 type of data referred to is untyped. To enable the (de)serialization of the
8260 void pointers that are members of structs or classes, you can insert a
8261 `int __type` field right before the void pointer field. The `int __type` field contains run time information on the type of the data pointed to by
8262 `void*` member in a struct/class to enable the (de)serialization of this
8263 data. The `int __type` field is set to a `SOAP_TYPE_X` value, where `X` is the name of a type. gSOAP generates the `SOAP_TYPE_X` definitions in `soapH.h` and uses them internally to uniquely identify the type of each object.
8264 The type naming conventions outlined in
8265 Section \ref serialize are used to determine the type name for *X*.
8267 Here is an example to illustrate the (de)serialization of a `void*` field in a struct:
8272 int __type; // the SOAP_TYPE pointed to by p
8277 The `__type` integer can be set to 0 at run time to omit the serialization
8278 of the void pointer field.
8280 The following example illustrates the initialization of `myStruct` with a
8281 void pointer to an int:
8287 S.__type = SOAP_TYPE_int;
8290 The serialized output of `S` contains the integer.
8292 The deserializer for `myStruct` will automatically set the `__type`
8293 field and void pointer to the deserialized data, provided that the XML content
8294 for `p` carries the *`xsi:type`* attribute from which gSOAP can determine
8297 @note when (de)serializing strings via a `void*` field, the `void*` pointer MUST directly point to the string value rather than indirectly as with all other types. For example:
8301 S.p = (void*)"Hello";
8302 S.__type = SOAP_TYPE_string;
8305 This is the case for all string-based types, including types defined with `typedef char*`.
8307 You may use an arbitrary suffix with the `__type` fields to handle
8308 multiple void pointers in structs/classes. For example
8313 int __typeOfp; // the SOAP_TYPE pointed to by p
8315 int __typeOfq; // the SOAP_TYPE pointed to by q
8320 Because service method parameters are stored within structs, you can use
8321 `__type` and `void*` parameters to pass polymorphic arguments without
8322 having to define a C++ class hierarchy (Section \ref polymorph ). For
8326 typedef char *xsd__string;
8327 typedef int xsd__int;
8328 typedef float xsd__float;
8329 enum ns__status { on, off };
8330 struct ns__widget { xsd__string name; xsd__int part; };
8331 int ns__myMethod(int __type, void *data, struct ns__myMethodResponse { int __type; void *return_; } *out);
8334 This method has a polymorphic input parameter `data` and a polymorphic
8335 output parameter `return_`. The `__type` parameters can be one of
8336 `SOAP_TYPE_xsd__string`, `SOAP_TYPE_xsd__int`,
8337 `SOAP_TYPE_xsd__float`, `SOAP_TYPE_ns__status`, or
8338 `SOAP_TYPE_ns__widget`. The WSDL produced by the gSOAP `soapcpp2` compiler
8339 declares the polymorphic parameters of type *`xsd:anyType`* which is "too
8340 loose" and doesn't allow the gSOAP importer to handle the WSDL accurately.
8341 Future gSOAP releases might replace *`xsd:anyType`* with a *`choice`*
8342 schema type that limits the choice of types to the types declared in the
8345 ## Fixed-Size Arrays
8347 Fixed size arrays are encoded as per SOAP 1.1 one-dimensional array types.
8348 Multi-dimensional fixed size arrays are encoded by gSOAP as nested
8349 one-dimensional arrays in SOAP. Encoding of fixed size arrays supports
8350 partially transmitted and sparse array SOAP formats.
8352 The decoding of (multi-dimensional) fixed-size arrays supports the SOAP multi-dimensional array format as well as partially transmitted and sparse array formats.
8357 // Contents of header file "fixed.h":
8364 This specifies a fixed-size array part of the `struct Example`. The encoding of array `a` is:
8368 <a xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="float[][2]">
8369 <SOAP-ENC:Array xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="float[3]"
8370 <float xsi:type="float">...</float>
8371 <float xsi:type="float">...</float>
8372 <float xsi:type="float">...</float>
8374 <SOAP-ENC:Array xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="float[3]"
8375 <float xsi:type="float">...</float>
8376 <float xsi:type="float">...</float>
8377 <float xsi:type="float">...</float>
8383 @warning Any decoded parts of a (multi-dimensional) array that do not "fit" in the fixed size array are ignored by the deserializer.
8385 ## Dynamic Arrays {#dynarray}
8387 As the name suggests, dynamic arrays are much more flexible than fixed-size
8388 arrays and dynamic arrays are better adaptable to the SOAP encoding and decoding
8389 rules for arrays. In addition, a typical C application allocates a dynamic
8390 array using `malloc`, assigns the location to a pointer variable, and
8391 deallocates the array later with `free`. A typical C++ application
8392 allocates a dynamic array using `new`, assigns the location to a pointer
8393 variable, and deallocates the array later with `delete`. Such dynamic
8394 allocations are flexible, but pose a problem for the serialization of data: how
8395 does the array serializer know the length of the array to be serialized given
8396 only a pointer to the sequence of elements? The application stores the size
8397 information somewhere. This information is crucial for the array serializer and
8398 has to be made explicitly known to the array serializer by packaging the
8399 pointer and array size information within a `struct` or `class`.
8401 ### SOAP Array Bounds Limits
8403 SOAP encoded arrays use the *`SOAP-ENC:Array`* type and the *`SOAP-ENC:arrayType`* attribute to define the array dimensionality and size. As a security measure to avoid denial of service attacks based on sending a huge array size value requiring the allocation of large chunks of memory, the total number of array elements set by the *`SOAP-ENC:arrayType`* attribute cannot exceed `SOAP_MAXARRAYSIZE`, which is set to 100,000 by default. This constant is defined in `stdsoap2.h`. This constant **only** affects multi-dimensional arrays and the dimensionality of the receiving array will be lost when the number of elements exceeds 100,000. One-dimensional arrays will be populated in sequential order as expected.
8405 ### One-Dimensional Dynamic SOAP Arrays
8407 A special form of `struct` or `class` is used to define one-dimensional
8408 dynamic SOAP-encoded arrays. Each array has a pointer variable and a field that records the
8409 number of elements the pointer points to in memory.
8411 The general form of the `struct` declaration that contains a one-dimensional dynamic SOAP-encoded array is:
8416 Type *__ptr; // pointer to array of elements in memory
8417 int __size; // number of elements pointed to
8418 [optional: [optional: static const] int __offset [optional: = ...];] // optional SOAP 1.1 array offset
8419 ... // anything that follows here will be ignored
8423 where `Type` MUST be a type associated with an XML Schema or MUST be a primitive type.
8424 If these conditions are not met, a vector-like XML (de)serialization is used (see Section \ref list ).
8425 A primitive type can be used with or without a `typedef`.
8426 If the array elements are structs or classes, then the `struct`/`class` type names should have a namespace prefix for schema
8427 association, or they should be other (nested) dynamic arrays.
8429 An alternative to a `struct` is to use a `class` with optional methods that MUST appear after the `__ptr` and
8438 [optional: [optional: static const] int __offset [optional: = ...];]
8441 ... // any fields that follow will be ignored
8445 To encode the data type as an array, the name of the `struct` or
8446 `class` SHOULD NOT have a namespace prefix, otherwise the data type will
8447 be encoded and decoded as a generic vector, see Section \ref list .
8449 The deserializer of a dynamic array can decode partially transmitted and/or
8450 SOAP sparse arrays, and even multi-dimensional arrays which will be collapsed
8451 into a one-dimensional array with row-major ordering.
8453 @warning SOAP 1.2 does not support partially transmitted arrays. So the `__offset` field of a dynamic array is ignored.
8457 The following example header file specifies the XMethods Service Listing service `getAllSOAPServices` service operation and an array of `SOAPService` data structures:
8460 // Contents of file "listing.h":
8461 class ns3__SOAPService
8471 char *methodNamespaceURI;
8472 char *serviceStatus;
8479 char *serverImplementation;
8484 ns3__SOAPService *__ptr; // points to array elements
8485 int __size; // number of elements pointed to
8490 int ns__getAllSOAPServices(ServiceArray &return_);
8493 An example client application:
8498 // ServiceArray class method implementations:
8499 ServiceArray::ServiceArray()
8504 ServiceArray::~ServiceArray()
8505 { // destruction handled by gSOAP
8507 void ServiceArray::print()
8509 for (int i = 0; i < __size; i++)
8510 cout << __ptr[i].name << ": " << __ptr[i].homepage << endl;
8513 // Request a service listing and display results:
8516 ServiceArray result;
8517 const char *endpoint = "www.xmethods.net:80/soap/servlet/rpcrouter";
8518 const char *action = "urn:xmethodsServicesManager#getAllSOAPServices";
8521 soap_call_ns__getAllSOAPServices(&soap, endpoint, action, result);
8524 soap_destroy(&soap); // dealloc class instances
8525 soap_end(&soap); // dealloc deserialized data
8526 soap_done(&soap); // cleanup and detach soap struct
8530 ### One-Dimensional Dynamic SOAP Arrays With Non-Zero Offset
8532 The declaration of a dynamic array as described in \ref dynarray MAY
8533 include an `int __offset` field. When set to an integer value, the
8534 serializer of the dynamic array will use this field as the start index of the
8535 array and the SOAP array offset attribute will be used in the SOAP payload.
8536 Note that array offsets is a SOAP 1.1 specific feature which is not supported
8539 For example, the following header file declares a mathematical `Vector`
8540 class, which is a dynamic array of floating point values with an index that
8544 // Contents of file "vector.h":
8545 typedef float xsd__float;
8553 float& \operator[](int i);
8557 The implementations of the `Vector` methods are:
8566 Vector::Vector(int n)
8568 __ptr = (float*)malloc(n*sizeof(float));
8577 float& Vector::\operator[](int i)
8579 return __ptr[i-__offset];
8583 An example program fragment that serializes a vector of 3 elements:
8598 The output is a partially transmitted array:
8602 <vec xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="xsd:float[4]" SOAP-ENC:offset="[1]">
8603 <item xsi:type="xsd:float">1.0</item>
8604 <item xsi:type="xsd:float">2.0</item>
8605 <item xsi:type="xsd:float">3.0</item>
8610 Note that the size of the encoded array is necessarily set to 4 and that the encoding omits the non-existent element at index 0.
8612 The decoding of a dynamic array with an `__offset` field is more efficient than decoding a dynamic array without an `__offset` field, because the `__offset` field will be assigned the value of the *`SOAP-ENC:offset`* attribute instead of padding the initial part of the array with default values.
8614 ### Nested One-Dimensional Dynamic SOAP Arrays {#nested}
8616 One-dimensional dynamic arrays MAY be nested.
8617 For example, using `class Vector` declared in the previous section, `class Matrix` is declared:
8620 // Contents of file "matrix.h":
8628 Matrix(int n, int m);
8630 Vector& \operator[](int i);
8634 The Matrix type is essentially an array of pointers to arrays which make up the rows of a matrix.
8635 The encoding of the two-dimensional dynamic array in SOAP will be in nested form.
8637 ### Multi-Dimensional Dynamic SOAP Arrays
8639 The general form of the `struct` declaration for K-dimensional (K>1) dynamic arrays is:
8647 ... // anything that follows here will be ignored
8651 where `Type` MUST be a type associated with an XML Schema, which means that it must be a `typedef`ed type
8652 in case of a primitive type, or a `struct`/`class` name with a namespace prefix for schema association, or another dynamic array. If these conditions are not met, a generic vector XML (de)serialization is used (see Section \ref list ).
8654 An alternative is to use a `class` with optional methods:
8665 ... // any fields that follow will be ignored
8669 In the above, K is a constant denoting the number of dimensions of the multi-dimensional array.
8671 To encode the data type as an array, the name of the `struct` or `class` SHOULD NOT have a namespace prefix, otherwise
8672 the data type will be encoded and decoded as a generic vector, see Section \ref list .
8674 The deserializer of a dynamic array can decode partially transmitted multi-dimensional arrays.
8676 For example, the following declaration specifies a matrix class:
8679 typedef double xsd__double;
8689 In contrast to the matrix class of Section \ref nested that defined a matrix as an array of pointers to matrix rows, this
8690 class has one pointer to a matrix stored in row-major order. The size of the matrix is determined by the `__size` field:
8691 `__size[0]` holds the number of rows and `__size[1]` holds the number of columns of the matrix. Likewise, `__offset[0]` is the row offset and `__offset[1]` is the columns offset.
8693 ### Encoding XML Generics Containing Dynamic Arrays {#list}
8695 The XML "generics" concept discussed in the SOAP encoding protocols extends the concept of a SOAP struct by allowing repetitions of elements within the struct. This is just a form of a repetition of XML elements without the SOAP-encoded array requirements. While SOAP-encoded arrays are more expressive (offset information to encode sparse arrays for example), simple repetitions of values are used more frequently.
8697 A simple generic reperition is an array-like data structure with a repetition of an element.
8698 To achieve this, declare a dynamic array as a `struct` or `class` with a name that is qualified with
8699 a namespace prefix. SOAP arrays are declared without prefix.
8701 For example, we define a Map structure that contains a sequence of pairs of key-val:
8706 int __size; // number of pairs
8707 struct ns__Binding {char *key; char *val;} *pair;
8711 Since 2.7.16 it is also possible to use a '`$`' as a special marker to annotate a
8712 size field that must be of type `int` or `size_t` and the field
8713 name is no longer relevant:
8718 $int length; // number of pairs
8719 struct ns__Binding {char *key; char *val;} *pair;
8722 This declares a dynamic array pointed to by `pair` and size `__size`. The array will be serialized and deserialized as a sequence of pairs:
8726 <ns:Map xsi:type="ns:Map">
8727 <pair xsi:type="ns:Binding">
8729 <val>555 77 1234</val>
8731 <pair xsi:type="ns:Binding">
8733 <val>555 12 6725</val>
8735 <pair xsi:type="ns:Binding">
8737 <val>555 99 4321</val>
8743 Deserialization is less efficient compared to a SOAP-encoded array, because the size of the
8744 sequence is not part of the SOAP encoding. Internal buffering is used by the
8745 deserializer to collect the elements. When the end of the list is reached, the
8746 buffered elements are copied to a newly allocated space on the heap for the
8749 Multiple arrays can be used in a struct/class to support the concept of
8750 "generics". Each array results in a repetition of elements in the struct/class.
8751 This is achieved with a `int __size` (or `$int`) field in
8752 the struct/class where the next field (i.e. below the `__size` field) is a
8753 pointer type. The pointer
8754 type is assumed to point to an array of values at run time. The `__size`
8755 field holds the number of values at run time. Multiple arrays can be embedded
8756 in a struct/class with `__size` fields that have a distinct names. To
8757 make the `__size` fields distinct, you can end them with a unique name
8758 suffix such as `__sizeOfstrings`, for example.
8760 The general convention for embedding arrays is:
8763 struct ns__SomeStruct
8766 int __sizename1; // number of elements pointed to
8767 Type1 *field1; // by this field
8769 int __sizename2; // number of elements pointed to
8770 Type2 *field2; // by this field
8775 where `name1` and `name2` are identifiers used as a suffix to distinguish the `__size` field. These names can be arbitrary and are not visible in XML.
8777 In 2.7.16 and higher this is simplified with a '`$`' marker:
8780 struct ns__SomeStruct
8783 $int name1; // number of elements pointed to
8784 Type1 *field1; // by this field
8786 $int name2; // number of elements pointed to
8787 Type2 *field2; // by this field
8792 For example, the following struct has two embedded arrays:
8799 $int nPhones; // number of Phones
8800 ULONG64 *phoneNumber; // array of phone numbers
8801 $int nEmails; // number of emails
8802 char **emailAddress; // array of email addresses
8807 The XML serialization of an example `ns__Contact` is:
8811 <mycontact xsi:type="ns:Contact">
8812 <firstName>Joe</firstName>
8813 <lastName>Smith</lastName>
8814 <phoneNumber>5551112222</phoneNumber>
8815 <phoneNumber>5551234567</phoneNumber>
8816 <phoneNumber>5552348901</phoneNumber>
8817 <emailAddress>Joe.Smith@mail.com</emailAddress>
8818 <emailAddress>Joe@Smith.com</emailAddress>
8819 <socSecNumber>999999999</socSecNumber>
8824 ### STL Containers {#templates}
8826 gSOAP supports the STL containers `std::deque`, `std::list`,
8827 `std::set`, and `std::vector`.
8829 STL containers can only be used within classes to declare members that contain
8830 multiple values. This is somewhat similar to the embedding of arrays in
8831 structs in C as explained in Section \ref list , but the STL container
8832 approach is more flexible.
8834 You need to import `stldeque.h`, `stllist.h`, `stlset.h`, or
8835 `stlvector.h` to enable `std::deque`, `std::list`, `std::set`,
8836 and `std::vector` (de)serialization.
8840 #import "stlvector.h"
8843 std::vector<int> *number;
8844 std::vector<xsd__string> *name;
8849 The use of pointer members is not required but advised. The reason is that
8850 interoperability with other SOAP toolkits may lead to copying of `ns__myClass` instances at run time when (de)serializing multi-referenced data.
8851 When a copy is made, certain parts of the containers will be shared between the
8852 copies which could lead to disaster when the classes with their containers are
8853 deallocated. Another way to avoid this is to declare class `ns__myClass`
8854 within other data types via a pointer. (Interoperability between gSOAP clients
8855 and services does not lead to copying.)
8857 The XML Schema that corresponds to the `ns__myClass` type is
8861 <complexType name="myClass">
8863 <element name="number" type="xsd:int" minOccurs="1" maxOccurs="unbounded"/>
8864 <element name="name" type="xsd:string" minOccurs="1" maxOccurs="unbounded"/>
8871 You can specify the minOccurs and maxOccurs values as explained in Section \ref directives .
8873 You can also implement your own
8874 containers similar to STL containers. The containers must be class templates and should define a forward iterator type, and provide the following methods:
8877 * `void clear()` empty the container;
8879 * `iterator begin()` return iterator to beginning;
8881 * `const_iterator begin() const` return const iterator to beginning;
8883 * `iterator end()` return iterator to end;
8885 * `const_iterator end() const` return const iterator to end;
8887 * `size_t size()` return size;
8889 * `iterator insert(iterator pos, const_reference val)` insert element.
8891 The `iterator` should be a forward iterator with a dereference operator to
8892 access the container's elements, it must be comparable (equal/unequal), and be pre-incrementable (`++it`). The const iterator is used by gSOAP to
8893 send a sequence of XML element values. The `insert` method is used to populate a container with `Container::iterator i = container.insert(container.end(), val)`.
8895 Here is in example user-defined container template class:
8903 typedef T value_type;
8904 typedef value_type * pointer;
8905 typedef const value_type * const_pointer;
8906 typedef value_type & reference;
8907 typedef const value_type & const_reference;
8908 typedef pointer iterator;
8909 typedef const_pointer const_iterator;
8915 simple_vector() { head = tail = NULL; }
8916 simple_vector(const simple_vector& v)
8918 ~simple_vector() { if (head) delete[] head; }
8919 void clear() { tail = head; }
8920 /* the member functions below are required for (de)serialization of templates */
8921 iterator begin() { return head; }
8922 const_iterator begin() const { return head; }
8923 iterator end() { return tail; }
8924 const_iterator end() const { return tail; }
8925 size_t size() const { return tail - head; }
8926 iterator insert(iterator pos, const_reference val)
8929 head = tail = new value_type[capacity = 1];
8930 else if (tail >= head + capacity)
8933 iterator j = new value_type[capacity *= 2];
8938 pos = j + (pos - head);
8939 tail = j + (tail - head);
8943 if (pos && pos >= head && pos < tail)
8958 simple_vector& \operator=(const simple_vector& v)
8961 capacity = v.capacity;
8964 head = tail = new value_type[capacity];
8965 iterator i = v.head;
8974 To enable the container, we add the following two lines to our gSOAP header file:
8977 #include "simpleVector.h"
8978 template <class T> class simpleVector;
8982 should not be defined in the gSOAP header file. It must be defined in
8983 a separate header file (e.g. "simpleVector.h"). The `template <class T> class simpleVector` declaration ensures that gSOAP will recognize `simpleVector` as a container class.
8985 @warning when parsing XML content the container elements may not be stored in the same order given in
8986 the XML content. When gSOAP parses XML it uses the `insert` container methods to
8987 store elements one by one. However, element content that is "forwarded" with
8988 *`href`* attributes will be appended to the container. Forwarding can take
8989 place with multi-referenced data that is referred to from the main part of the
8990 SOAP 1.1 XML message to the independent elements that carry *`id`*s.
8991 Therefore, your application should not rely on the preservation of the order of
8992 elements in a container.
8994 ### Polymorphic Dynamic Arrays and Lists
8996 Polymorphic arrays (arrays of polymorphic element types) can be encoded when
8997 declared as an array of pointers to class instances. For example:
9005 class ns__Data: public ns__Object
9013 ns__Object **__ptr; // pointer to array of pointers to Objects
9014 int __size; // number of Objects pointed to
9015 int __offset; // optional SOAP 1.1 array offset
9020 std::vector<ns__Object*> objects; // vector of pointers to objects
9024 The pointers in the array can point to the `ns__Object` base class or
9025 `ns__Data` derived class instances which will be serialized and
9026 deserialized accordingly in SOAP. That is, the array elements are polymorphic.
9028 Since we can't use dynamic binding to support polymorphism in C, another
9029 mechanism is available based on the serialization of void pointers, that is, dynamic serialization of data referenced by void pointers, see Section \ref void .
9034 int __type; // type T represented by SOAP_TYPE_T
9035 void *__item; // pointer to data of type T
9037 struct ArrayOfObject
9039 struct __wrapper __ptr; // pointer to array of pointers to Objects
9040 int __size; // number of Objects pointed to
9041 int __offset; // optional SOAP 1.1 array offset
9046 struct __wrapper *objects; // array of pointers to wrapped types
9050 ### How to Change the Tag Names of the Elements of a SOAP Array or List
9052 The `__ptr` field in a `struct` or `class` declaration of a dynamic array may have an optional suffix part that
9053 describes the name of the tags of the SOAP array XML elements.
9054 The suffix is part of the field name:
9057 Type *__ptrarray_elt_name
9060 The suffix describes the tag name to be used for all array elements. The usual identifier to XML translations apply, see
9061 Section \ref idtrans .
9062 The default XML element tag name for array elements is *`item`* (which corresponds to the use of field name `__ptritem`).
9064 Consider for example:
9067 struct ArrayOfstring
9069 xsd__string *__ptrstring;
9074 The array is serialized as:
9078 <array xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="xsd:string[2]">
9079 <string xsi:type="xsd:string">Hello</string>
9080 <string xsi:type="xsd:string">World</string>
9085 SOAP 1.1 and 1.2 do not require the use of a specific tag name for array elements. gSOAP will deserialize a SOAP array while
9086 ignoring the tag names. Certain XML Schemas used in doc/literal encoding may require the declaration of array element tag names.
9088 ## Base64Binary XML Schema Type Encoding {#base64binary}
9090 The *`base64Binary`* XML Schema type is a special form of dynamic array declared with a pointer (`__ptr`) to an
9091 `unsigned char` array.
9093 For example using a `struct`:
9096 struct xsd__base64Binary
9098 unsigned char *__ptr;
9106 class xsd__base64Binary
9109 unsigned char *__ptr;
9114 When compiled by the gSOAP `soapcpp2` tool, this header file specification will generate *`base64Binary`* serializers and deserializers.
9116 The *`SOAP_ENC:base64`* encoding is another type for base 64 binary encoding
9117 specified by the SOAP data type schema and some SOAP applications may use this form
9118 (as indicated by their WSDL descriptions). It is declared by:
9121 struct SOAP_ENC__base64
9123 unsigned char *__ptr;
9131 class SOAP_ENC__base64
9133 unsigned char *__ptr;
9138 When compiled by the gSOAP `soapcpp2` tool, this header file specification will generate *`SOAP-ENC:base64`* serializers and deserializers.
9140 The advantage of using a `class` is that methods can be used to initialize and manipulate the `__ptr` and `__size` fields. The user can add methods to this class to do this. For example:
9143 class xsd__base64Binary
9146 unsigned char *__ptr;
9148 xsd__base64Binary(); // Constructor
9149 xsd__base64Binary(struct soap *soap, int n); // Constructor
9150 ~xsd__base64Binary(); // Destructor
9151 unsigned char *location(); // returns the memory location
9152 int size(); // returns the number of bytes
9156 Here are example method implementations:
9159 xsd__base64Binary::xsd__base64Binary()
9164 xsd__base64Binary::xsd__base64Binary(struct soap *soap, int n)
9166 __ptr = (unsigned char*)soap_malloc(soap, n);
9169 xsd__base64Binary::~xsd__base64Binary()
9171 unsigned char *xsd__base64Binary::location()
9175 int xsd__base64Binary::size()
9181 The following example in C/C++ reads from a raw image file and encodes the image in SOAP using the *`base64Binary`* type:
9185 FILE *fd = fopen("image.jpg", "rb");
9186 xsd__base64Binary image(&soap, filesize(fd));
9187 fread(image.location(), image.size(), 1, fd);
9189 soap_begin_send(&soap);
9190 image.soap_serialize(&soap);
9191 image.soap_put(&soap, "jpegimage", NULL);
9192 soap_end_send(&soap);
9196 where `filesize` is a function that returns the size of a file given a file descriptor.
9198 Reading the *`xsd:base64Binary`* encoded image.
9202 xsd__base64Binary image;
9203 soap_begin_recv(&soap);
9204 image.get(&soap, "jpegimage");
9205 soap_end_recv(&soap);
9209 The `struct` or `class` name `soap_enc__base64` should be used for *`SOAP-ENC:base64`* schema type instead of
9210 `xsd__base64Binary`.
9212 ## hexBinary XML Schema Type Encoding {#hexbinary}
9214 The *`hexBinary`* XML Schema type is a special form of dynamic array declared with the name `xsd__hexBinary` and a pointer (`__ptr`) to an `unsigned char` array, similar to the base64Binary type described in the previous section. The only difference with the base64Binary type is the hexadecimal content instead of base64 content. Both types are declared identically, with the exception that the word "`hex`" occurs in the struct/class name.
9216 For example, using a `struct`:
9219 struct xsd__hexBinary
9221 unsigned char *__ptr;
9229 class xsd__hexBinary
9232 unsigned char *__ptr;
9237 or if a binary type such as `xsd__base64Binary` is defined, then we can simply use a `typedef` to introduce the hex variant:
9240 class xsd__base64Binary // serializes into base64 content
9243 unsigned char *__ptr;
9246 typedef xsd__base64Binary xsd__hexBinary; // serializes into hex content
9249 When compiled by the gSOAP `soapcpp2` tool, this header file specification will generate *`hexBinary`* serializers and deserializers.
9251 ## Literal XML Encoding Style {#literal}
9253 gSOAP supports document/literal encoding by default.
9254 Just as with SOAP RPC encoding, literal encoding requires the XML Schema of the message data to be provided
9255 e.g. in WSDL in order for the
9256 gSOAP `soapcpp2` compiler to generate the (de)serialization routines.
9258 The `//gsoap service encoding`, `//gsoap service method-encoding`, and `//gsoap service method-response-encoding` directives explicitly enable SOAP encoded or literal encoded messages. For example, to enable RPC encoding style for the entire service, use:
9261 //gsoap ns service encoding: encoded
9264 To enable encoding for particular service methods, use:
9267 //gsoap ns service method-encoding: myMethod encoded
9268 int ns__myMethod(...)
9271 To enable encoding for particular service methods responses when the method request is literal, use:
9274 //gsoap ns service method-response-encoding: myMethod encoded
9275 int ns__myMethod(...)
9278 Instead of the `encoded` value, you can use `literal`, or a specific encoding style value.
9280 Consider the following example that uses the directive to make the literal encoding explicit.
9281 The `LocalTimeByZipCode` service operation of the LocalTime service provides
9282 the local time given a zip code and uses literal encoding (with MS
9283 .NET). The following header file declares the method:
9286 int LocalTimeByZipCode(char *ZipCode, char **LocalTimeByZipCodeResult);
9289 Note that none of the data types need to be namespace qualified using
9293 //gsoap ns service name: localtime
9294 //gsoap ns service encoding: literal
9295 //gsoap ns service namespace: http://alethea.net/webservices/
9296 int ns__LocalTimeByZipCode(char *ZipCode, char **LocalTimeByZipCodeResult);
9299 In this case, the method name requires to be associated with a schema through a namespace prefix, e.g. `ns` is used in this example.
9300 See Section \ref directives for more details on gSOAP directives.
9301 With these directives, the gSOAP `soapcpp2` compiler generates client and server sources with the specified settings.
9303 The example client program is:
9307 #include "localtime.nsmap" // include generated map file
9313 if (soap_call_ns__LocalTimeByZipCode(&soap, "http://alethea.net/webservices/LocalTime.asmx", "http://alethea.net/webservices/LocalTimeByZipCode", "32306", &t))
9314 soap_print_fault(&soap, stderr);
9316 printf("Time = %s\n", t);
9321 To illustrate the manual doc/literal setting, the following client program sets
9322 the required properties before the call:
9326 #include "localtime.nsmap" // include generated map file
9332 soap.encodingStyle = NULL; // don't use SOAP encoding
9333 soap_set_omode(&soap, SOAP_XML_TREE);" // don't produce multi-ref data (but can accept)
9334 if (soap_call_ns__LocalTimeByZipCode(&soap, "http://alethea.net/webservices/LocalTime.asmx", "http://alethea.net/webservices/LocalTimeByZipCode", "32306", &t))
9335 soap_print_fault(&soap, stderr);
9337 printf("Time = %s\n", t);
9342 The SOAP request is:
9346 POST /webservices/LocalTime.asmx HTTP/1.0
9348 Content-Type: text/xml; charset=utf-8
9350 SOAPAction: "http://alethea.net/webservices/LocalTimeByZipCode"
9352 <?xml version="1.0" encoding="UTF-8"?>
9354 xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
9355 xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
9356 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
9357 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
9359 <LocalTimeByZipCode xmlns="http://alethea.net/webservices/">
9360 <ZipCode>32306</ZipCode></LocalTimeByZipCode>
9362 </SOAP-ENV:Envelope>
9366 ### Serializing and Deserializing Mixed Content XML With Strings {#literal2}
9368 To declare a literal XML "type" to hold XML documents in regular strings, use:
9374 To declare a literal XML "type" to hold XML documents in wide character strings, use:
9377 typedef wchar_t *XML;
9380 Note: only one of the two storage formats can be used.
9381 The differences between the use of regular strings versus wide character strings for XML documents are:
9384 * Regular strings for XML documents MUST hold UTF-8 encoded XML documents. That is, the string MUST contain the proper UTF-8
9385 encoding to exchange the XML document in SOAP messages.
9387 * Wide character strings for XML documents SHOULD NOT hold UTF-8 encoded XML documents. Instead, the UTF-8 translation is done automatically by
9388 the gSOAP runtime marshalling routines.
9390 Here is a C++ example of a service operation specification in which the parameters of the service operation uses literal XML encoding to pass
9391 an XML document to a service and back:
9395 ns__GetDocument(XML m__XMLDoc, XML &m__XMLDoc_);
9402 ns__GetDocument(XML m__XMLDoc, XML *m__XMLDoc_);
9405 The `ns__Document` is essentially a `struct` that forms the root of the XML document.
9406 The use of the underscore in the `ns__Document` response part of the message avoids the name clash between the
9408 Assuming that the namespace mapping table contains the binding of `ns` to *`http://my.org/`*
9409 and the binding of `m` to *`http://my.org/mydoc.xsd`*, the XML message is:
9413 <?xml version="1.0" encoding="UTF-8"?>
9415 xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
9416 xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
9417 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
9418 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
9419 xmlns:ns="http://my.org/"
9420 xmlns:m="http://my.org/mydoc.xsd"
9421 SOAP-ENV:encodingStyle="">
9424 <XMLDoc xmlns="http://my.org/mydoc.xsd">
9429 </SOAP-ENV:Envelope>
9433 When using literal encoding of method parameters and response as shown in the example above, the literal XML encoding style MUST be specified by setting `soap.encodingStyle`.
9434 For example, to specify no constraints on the encoding style (which is typical) use NULL:
9439 soap.encodingStyle = NULL;
9442 As a result, the *`SOAP-ENV:encodingStyle`* attribute will not appear in the SOAP payload.
9444 For interoperability with Apache SOAP, use
9449 soap.encodingStyle = "http://xml.apache.org/xml-soap/literalxml";
9452 When the response parameter is an XML type, it will store the entire XML response content but without the enveloping response element.
9454 The XML type can be used as part of any data structure to enable the rendering and parsing of custom XML documents. For example:
9458 struct ns__Data /* data in namespace 'ns' */
9462 XML m__document; /* XML document in default namespace 'm' */
9464 ns__Example(struct ns__Data data, struct ns__ExampleResponse { struct ns__Data data; } *out);
9467 # SOAP Fault Processing {#fault}
9469 A predeclared standard SOAP Fault data structure is generated by the gSOAP `soapcpp2` tool for exchanging exception messages.
9470 The built-in `struct SOAP_ENV__Fault` data structure is defined as:
9473 struct SOAP_ENV__Fault
9475 _QName faultcode; // _QName is builtin
9478 struct SOAP_ENV__Detail *detail;
9479 struct SOAP_ENV__Code *SOAP_ENV__Code; // MUST be a SOAP_ENV__Code struct defined below
9480 char *SOAP_ENV__Reason;
9481 char *SOAP_ENV__Node;
9482 char *SOAP_ENV__Role;
9483 struct SOAP_ENV__Detail *SOAP_ENV__Detail; // SOAP 1.2 detail field
9485 struct SOAP_ENV__Code
9487 _QName SOAP_ENV__Value;
9488 struct SOAP_ENV__Code *SOAP_ENV__Subcode;
9490 struct SOAP_ENV__Detail
9492 int __type; // The SOAP_TYPE_ of the object serialized as Fault detail
9493 void *fault; // pointer to the fault object, or NULL
9494 char *__any; // any other detail element content (stored in XML format)
9498 The first four fields in `SOAP_ENV__Fault` are SOAP 1.1 specific. The last five fields are SOAP 1.2 specific.
9499 You can redefine these structures in the header file. For example, you can use a `class` for the `SOAP_ENV__Fault` and add methods for convenience.
9501 The data structure content can be changed to the need of an application, but this is generally not necessary because the application-specific SOAP Fault details can be serialized via the `__type` and `fault` fields in the `SOAP_ENV__Detail` field, see Section \ref void on the serialization of data refered to by `__type` and `fault`.
9503 The `__type` field allows application data to be serialized as part of the SOAP Fault. The application data SHOULD be defined as XML elements, which requires you to declare the type names with a leading underscore to ensure that the types are compatible with XML elements and not just simpleTypes and complexTypes.
9505 When the skeleton of a service operation returns an error (see Section \ref errcodes ), then `soap.fault` contains the SOAP
9506 Fault data at the receiving side (client).
9508 Server-side faults are raised with `soap_sender_fault` or `soap_receiver_fault`. The `soap_sender_fault` call should be used to inform that the sender is at fault and the sender (client) should not resend the request. The `soap_receiver_fault` call should be used to indicate a temporary server-side problem, so a sender (client) can resend the request later. For example:
9511 int ns1__myMethod(struct soap *soap, ...)
9514 return soap_receiver_fault(soap, "Resource temporarily unavailable", NULL); // return fault to sender
9518 In the example, the SOAP Fault details were empty (NULL). You may pass an XML fragment, which will be literally included in the SOAP Fault message. For WS-I Basic Profile compliance, you must pass an XML string with one or more namespace qualified elements, such as:
9521 return soap_receiver_fault(soap, "Resource temporarily unavailable", "<errorcode xmlns='http://tempuri.org'>123</errorcode><errorinfo xmlns='http://tempuri.org'>abc</errorinfo>");
9525 When a service operation must raise an exception with application SOAP Fault details, it does so by assigning the `soap.fault` field of the current reference to the
9526 runtime context with
9527 appropriate data associated with the exception and by returning the error `SOAP_FAULT`.
9531 soap_receiver_fault(soap, "Stack dump", NULL);
9532 if (soap->version == 2) // SOAP 1.2 is used
9534 soap->fault->SOAP_ENV__Detail = (struct SOAP_ENV__Detail*)soap_malloc(soap, sizeof(struct SOAP_ENV__Detail);
9535 soap->fault->SOAP_ENV__Detail->__type = SOAP_TYPE_ns1__myStackDataType; // stack type
9536 soap->fault->SOAP_ENV__Detail->fault = sp; // point to stack
9537 soap->fault->SOAP_ENV__Detail->__any = NULL; // no other XML data
9541 soap->fault->detail = (struct SOAP_ENV__Detail*)soap_malloc(soap, sizeof(struct SOAP_ENV__Detail);
9542 soap->fault->detail->__type = SOAP_TYPE_ns1__myStackDataType; // stack type
9543 soap->fault->detail->fault = sp; // point to stack
9544 soap->fault->detail->__any = NULL; // no other XML data
9546 return SOAP_FAULT; // return from service operation call
9549 When `soap_receiver_fault` allocates a fault struct, this data is removed with the `soap_end` call (or `soap_dealloc`).
9550 Note that the `soap_receiver_fault` function is called to allocate the fault struct and set the fault string and detail
9551 fields, i.e. `soap_receiver_fault(soap, "Stack dump", NULL)`. The advantage is that this is independent of SOAP 1.1 and
9552 SOAP 1.2. However, setting the custom detail fields requires inspecting the SOAP version used, using the `soap->version`
9553 attribute which is 1 for SOAP 1.1 and 2 for SOAP 1.2.
9555 Each service operation implementation in a service application can return a SOAP Fault upon an exception by returning an error code,
9556 see Section \ref example7 for details and an example.
9557 In addition, a SOAP Fault can be returned by a service application through calling the `soap_send_fault` function.
9558 This is useful in case the initialization of the application fails, as illustrated in the example below:
9565 some initialization code
9566 if (initialization failed)
9568 soap.error = soap_receiver_fault(&soap, "Init failed", NULL); // set the error condition (SOAP_FAULT)
9569 soap_send_fault(&soap); // Send SOAP Fault to client
9570 return 0; // Terminate
9575 # SOAP Header Processing {#header}
9577 A predeclared standard SOAP Header data structure is generated by the gSOAP `soapcpp2` tool for exchanging SOAP
9578 messages with SOAP Headers.
9579 This predeclared data structure is:
9582 struct SOAP_ENV__Header { };
9585 which declares and empty header (some C and C++ compilers don't accept empty structs, use compile flag `-DWITH_NOEMPTYSTRUCT` to avoid these errors).
9587 To adapt the data structure to a specific need for SOAP Header processing, a
9588 new `struct SOAP_ENV__Header` can be added to the header file input to the gSOAP
9589 compiler. A `class` for the SOAP Header data structure can be used instead of a `struct`.
9591 For example, the following header can be used for transaction control:
9594 struct SOAP_ENV__Header
9595 { char *t__transaction;
9599 with client-side code:
9605 soap.header = NULL; // do not use a SOAP Header for the request (as set with soap_init)
9606 soap.actor = NULL; // do not use an actor (receiver is actor)
9607 soap_call_method(&soap, ...);
9608 if (soap.header) // a SOAP Header was received
9609 cout << soap.header->t__transaction;
9610 // Can reset, modify, or set soap.header here before next call
9611 soap_call_method(&soap, ...); // reuse the SOAP Header of the service response for the request
9615 The SOAP Web service response can include a SOAP Header with a transaction number that the client is supposed to use for the next service operation invocation to the service. Therefore, the next request includes a transaction number:
9620 <SOAP-ENV:Envelope ...>
9622 <transaction xmlns="..." xsi:type="int">12345</transaction>
9627 </SOAP-ENV:Envelope>
9631 This is just an example and the transaction control is not a feature of SOAP but can be added on by the application layer
9632 to implement stateful transactions between clients and services.
9633 At the client side, the `soap.actor` attribute can be set to
9634 indicate the recipient of the header (the SOAP *`SOAP-ENV:actor`* attribute).
9636 A Web service can read and set the SOAP Header as follows:
9642 soap.actor = NULL; // use this to accept all headers (default)
9643 soap.actor = "http://some/actor"; // accept headers destined for "http://some/actor" only
9647 int method(struct soap *soap, ...)
9649 if (soap->header) // a Header was received
9650 ... = soap->header->t__transaction;
9652 soap->header = soap_malloc(sizeof(struct SOAP_ENV__Header)); // alloc new header
9654 soap->header->t__transaction = ...;
9659 See Section \ref directives on how to generate WSDL with the proper method-to-header-part bindings.
9661 The *`SOAP-ENV:mustUnderstand`* attribute indicates the requirement that the recipient of the SOAP Header (who must
9662 correspond to the *`SOAP-ENV:actor`* attribute when present or when the attribute has the value
9663 *`SOAP-ENV:actor="http://schemas.xmlsoap.org/soap/actor/next"`*) MUST handle the Header part that carries the attribute.
9664 gSOAP handles this automatically on the background. However, an application still needs to inspect the header part's value
9665 and handle it appropriately. If a service operation in a Web service is not able to do this, it should return
9666 `SOAP_MUSTUNDERSTAND` to indicate this failure.
9668 The syntax for the header file input to the gSOAP `soapcpp2` compiler is extended with a special storage qualifier `mustUnderstand`.
9669 This qualifier can be used in the SOAP Header declaration to indicate which parts should carry a `SOAP-ENV:mustUnderstand="1"`
9670 attribute. For example:
9673 struct SOAP_ENV__Header
9675 char *t__transaction;
9676 mustUnderstand char *t__authentication;
9680 When both fields are set and `soap.actor="http://some/actor"` then the message contains:
9684 <SOAP-ENV:Envelope ...>
9686 <transaction xmlns="...">5</transaction>
9687 <authentication xmlns="..."
9688 SOAP-ENV:actor="http://some/actor" SOAP-ENV:mustUnderstand="1">XX
9694 </SOAP-ENV:Envelope>
9698 # MIME Attachments {#MIME}
9700 The gSOAP toolkit supports MIME attachments as per SOAP with Attachments (SwA)
9701 specification (http://www.w3.org/TR/SOAP-attachments). In the following
9702 discussion, MIME attachment data is assumed to be resident in memory for
9703 sending operations and MIME attachments received will be stored in memory. MTOM
9704 and DIME attachments on the other hand can be streamed and therefore MTOM/DIME
9705 attachment data does not need to be stored in memory, see
9706 Section \ref DIME and \ref MTOM .
9708 Transmitting multipart/related MIME attachments with a SOAP/XML message is
9709 accomplished with two functions, `soap_set_mime` and
9710 `soap_set_mime_attachment`. The first function is for initialization
9711 purposes and the latter function is used to specify meta data and content data
9712 for each attachment.
9714 ## Sending a Collection of MIME Attachments (SwA)
9716 The following functions should be used to set up a collection of
9717 multipart/related MIME attachments for transmission with a SOAP/XML message.
9719 * `void soap_set_mime(struct soap *soap, const char *boundary, const char *start)`
9720 This function must be called first to initialize MIME attachment send
9721 operations (receives are automatic). The function specifies a MIME boundary and
9722 start content ID used for the SOAP message body. When `boundary` is NULL, an
9723 appropriate MIME boundary will be choosen (important: boundaries cannot occur
9724 in the SOAP/XML message and cannot occur in any of the MIME attachments
9725 content). When a specific boundary value is provided, gSOAP will NOT verify
9726 that the boundary is valid. When `start` is NULL, the start ID of the SOAP
9727 message is <*`SOAP-ENV:Envelope`*>.
9729 * `int soap_set_mime_attachment(struct soap *soap, char *ptr, size_t size, enum soap_mime_encoding encoding, const char *type, const char *id, const char *location, const char *description)`
9730 This function adds a new attachment to the list of attachments, where `ptr`
9731 and `size` refer to the block of memory that holds the attachment data. The
9732 `encoding` parameter specifies the content encoding of this block, where the
9733 value of `encoding` is one of `SOAP_MIME_7BIT`, `SOAP_MIME_8BIT`,
9734 `SOAP_MIME_BINARY`, `SOAP_MIME_QUOTED_PRINTABLE`, `SOAP_MIME_BASE64`,
9735 `SOAP_MIME_IETF_TOKEN`, or `SOAP_MIME_X_TOKEN`. These constants reflect the
9736 content encoding defined in RFC2045 and you MUST adhere to the content
9737 encoding rules defined by RFC2045. When in doubt, use `SOAP_MIME_BINARY`,
9738 since this encoding type covers any content. The mandatory `type` string
9739 parameter is the MIME type of the data. The `id` string parameter is the
9740 content ID of the MIME attachment. The optional `location` string parameter
9741 is the content location of the attachment. The optional `description` string
9742 parameter holds a textual description of the attachment (it may not contain
9743 any control characters). All parameter values are copied, except `ptr`
9744 which must point to a valid location of the attachment data during the
9745 transfer. The value `SOAP_OK` is returned when the attachment was added.
9746 Otherwise a gSOAP error code is returned.
9748 * `void soap_clr_mime(struct soap *soap)`
9749 Disables MIME attachments, e.g. to avoid MIME attachments to be part of a SOAP Fault response message.
9751 When providing a MIME boundary with `soap_set_mime`, you have to make
9752 sure the boundary cannot match any SOAP/XML message content.
9753 Or you can simply pass NULL and let gSOAP select a safe boundary for you.
9755 The internal list of attachments is destroyed with `soap_end`, you should
9756 call this function sometime after the message exchange was completed (the
9757 content of the block of memory referred to by the `ptr` parameter is
9760 The following example shows how a multipart/related HTTP message with three
9761 MIME attachments is set up and transmitted to a server. The first attachment
9762 contains the SOAP message. The second and third attachments contain image data.
9763 In this example we let the SOAP message body refer to the attachments using
9764 *`href`* attributes. The `struct claim__form` data type includes a
9765 definition of a `href` attribute for this purpose.
9768 struct claim__form form1, form2;
9769 form1.href = "cid:claim061400a.tiff@claiming-it.com";
9770 form2.href = "cid:claim061400a.jpeg@claiming-it.com";
9771 /* initialize and enable MIME */
9772 soap_set_mime(soap, "MIME_boundary", "<claim061400a.xml@claiming-it.com>");
9773 /* add a base64 encoded tiff image (tiffImage points to base64 data) */
9774 soap_set_mime_attachment(soap, tiffImage, tiffLen, SOAP_MIME_BASE64, "image/tiff",
9775 "<claim061400a.tiff@claiming-it.com>", NULL, NULL);
9776 /* add a raw binary jpeg image (jpegImage points to raw data) */
9777 soap_set_mime_attachment(soap, jpegImage, jpegLen, SOAP_MIME_BINARY, "image/jpeg",
9778 "<claim061400a.jpeg@claiming-it.com>", NULL, NULL);
9779 /* send the forms as MIME attachments with this invocation */
9780 if (soap_call_claim__insurance_claim_auto(soap, form1, form2, ...))
9781 // an error occurred
9786 Note: the above example assumes that the boundary `MIME_boundary` does not match any part of the SOAP/XML message.
9788 The `claim__form` struct is declared in the gSOAP header file as:
9797 This data type defines the parameter data of the operation. The claim forms in
9798 the SOAP/XML message consist of *`href`*s to the claim forms attached. The
9799 produced message is similar to the last example shown in the SOAP with
9800 Attachments specification (http://www.w3.org/TR/SOAP-attachments). Note that
9801 the use of *`href`* or other attributes for referring to the MIME attachments
9802 is optional according to the SwA standard.
9804 To associate MIME attachments with the request and response of a service operation in the generated WSDL, please see Section \ref MIMEWSDL .
9806 The server-side code to transmit MIME attachments back to a client is similar:
9809 int claim__insurance_claim_auto(struct soap *soap, ...)
9811 soap_set_mime(soap, NULL, NULL); // enable MIME
9812 // add a HTML document (htmlDoc points to data, where the HTML doc is stored in compliance with 7bit encoding RFC2045)
9813 if (soap_set_mime_attachment(soap, htmlDoc, strlen(htmlDoc), SOAP_MIME_7BIT, "text/html",
9814 "<claim061400a.html@claiming-it.com>", NULL, NULL))
9816 soap_clr_mime(soap); // don't want fault with attachments
9823 It is also possible to attach data to a SOAP fault message.
9825 @warning DIME in MIME is supported. However, gSOAP will not verify whether
9826 the MIME boundary is present in the DIME attachments and therefore will not
9827 select a boundary that is guaranteed to be unique. Therefore, you must provide
9828 a MIME boundary with `soap_set_mime` that is unique when using DIME in
9831 ## Retrieving a Collection of MIME Attachments (SwA)
9833 MIME attachments are automatically parsed and stored in memory.
9834 After receiving a set of MIME attachments, either at the client-side or
9835 the server-side, the list of MIME attachments can be traversed to extract
9836 meta data and the attachment content. The first attachment in the collection of
9837 MIME attachments always contains meta data about the SOAP message
9838 itself (because the SOAP message was processed the attachment does not contain
9841 To traverse the list of MIME attachments in C, you use a loop similar to:
9844 struct soap_multipart *attachment;
9845 for (attachment = soap.mime.list; attachment; attachment = attachment->next)
9847 printf("MIME attachment:\n");
9848 printf("Memory=%p\n", (*attachment).ptr);
9849 printf("Size=%ul\n", (*attachment).size);
9850 printf("Encoding=%d\n", (int)(*attachment).encoding);
9851 printf("Type=%s\n", (*attachment).type?(*attachment).type:"null");
9852 printf("ID=%s\n", (*attachment).id?(*attachment).id:"null");
9853 printf("Location=%s\n", (*attachment).location?(*attachment).location:"null");
9854 printf("Description=%s\n", (*attachment).description?(*attachment).description:"null");
9858 C++ programmers can use an iterator instead, as in:
9861 for (soap_multipart::iterator attachment = soap.mime.begin(); attachment != soap.mime.end(); ++attachment)
9863 cout << "MIME attachment:" << endl;
9864 cout << "Memory=" << (void*)(*attachment).ptr << endl;
9865 cout << "Size=" << (*attachment).size << endl;
9866 cout << "Encoding=" << (*attachment).encoding << endl;
9867 cout << "Type=" << ((*attachment).type?(*attachment).type:"null") << endl;
9868 cout << "ID=" << ((*attachment).id?(*attachment).id:"null") << endl;
9869 cout << "Location=" << ((*attachment).location?(*attachment).location:"null") << endl;
9870 cout << "Description=" << ((*attachment).description?(*attachment).description:"null") << endl;
9874 Note: keep in mind that the first attachment is associated with the SOAP
9875 message and you may want to ignore it if the message has the attachment data
9876 already embedded through its hrefs.
9878 A call to `soap_end` removes all of the received MIME data. To preserve an
9879 attachment in memory, use `soap_unlink` on the `ptr` field of the
9880 `soap_multipart` struct. Recall that the `soap_unlink` function is
9881 commonly used to prevent deallocation of deserialized data.
9883 # DIME Attachments {#DIME}
9885 The gSOAP toolkit supports DIME attachments as per DIME specification, see
9886 http://msdn.microsoft.com/library/en-us/dnglobspec/html/draft-nielsen-dime-02.txt
9888 Applications developed with gSOAP can transmit binary DIME attachments with or
9889 without streaming messages. Without streaming, all data is stored and retrieved in
9890 memory, which can be prohibitive when transmitting large files on small
9891 devices. The maximum DIME attachment size is limited to 8 MB by default as set with `SOAP_MAXDIMESIZE` in `stdsoap2.h`. This limit can be changed as needed by recompiling `stdsoap2.c` and `stdsoap2.cpp` with `-DSOAP_MAXDIMESIZE=100000000` for example. In contrast, with DIME streaming, data handlers are used to pass the
9892 data to and from a resource, such as a file or device. With DIME output
9893 streaming, raw binary data is send from a data source in chunks on the fly
9894 without buffering the entire content to save memory. With DIME input streaming,
9895 raw binary data will be passed to data handlers (callbacks).
9897 ## Sending a Collection of DIME Attachments
9899 The following functions can be used to explicitly set up a collection of
9900 DIME attachments for transmission with a SOAP/XML message body.
9901 The attachments can be streamed, as described in
9902 Section \ref DIMEstreaming . Without streaming, each attachment must refer
9903 to a block of data in memory.
9905 * `void soap_set_dime(struct soap *soap)`
9906 This function must be called first to initialize DIME attachment send operations (receives are automatic).
9908 * `int soap_set_dime_attachment(struct soap *soap, char *ptr, size_t size, const char *type, const char *id, unsigned short optype, const char *option)`
9909 This function adds a new attachment to the list of attachments, where `ptr` and `size` refer to the block of memory that holds the attachment data (except when DIME streaming callback handlers are used as described in Section \ref DIMEstreaming . The `type` string parameter is the MIME type of the data. The `id` string parameter is the content ID of the DIME attachment. The `option` string parameter holds optional text (gSOAP supports DIME options, but it can send only one) and `optype` is a user-defined option type (as per DIME option specification format). All parameter values are copied, except `ptr`.
9910 The value `SOAP_OK` is returned when the attachment was added. Otherwise a gSOAP error code is returned.
9912 * `void soap_clr_dime(struct soap *soap)`
9913 Disables DIME attachments, unless the serialized SOAP message contains attachments for transmission.
9915 These functions allow DIME attachments to be added without requiring message
9916 body references. This is also referred to as the open DIME attachment style.
9917 The closed attachment style requires all DIME attachments to be referenced from
9918 the SOAP message body with *`href`* (or similar) references. For the closed
9919 style, gSOAP supports an automatic binary data serialization method, see
9920 Section \ref DIMEbinary .
9922 ## Retrieving a Collection of DIME Attachments
9924 DIME attachments are automatically parsed and stored in memory (or passed to
9925 the streaming handlers, when applicable). After receiving a set of DIME
9926 attachments, either at the client-side or the server-side, the list of DIME
9927 attachments can be traversed to extract meta data and the attachment content.
9929 To traverse the list of DIME attachments in C, you use a loop similar to:
9932 struct soap_multipart *attachment;
9933 for (attachment = soap.dime.list; attachment; attachment = attachment->next)
9935 printf("DIME attachment:\n");
9936 printf("Memory=%p\n", (*attachment).ptr);
9937 printf("Size=%ul\n", (*attachment).size);
9938 printf("Type=%s\n", (*attachment).type?(*attachment).type:"null");
9939 printf("ID=%s\n", (*attachment).id?(*attachment).id:"null");
9943 C++ programmers can use an iterator instead, as in:
9946 for (soap_multipart::iterator attachment = soap.dime.begin(); attachment != soap.dime.end(); ++attachment)
9948 cout << "DIME attachment:" << endl;
9949 cout << "Memory=" << (void*)(*attachment).ptr << endl;
9950 cout << "Size=" << (*attachment).size << endl;
9951 cout << "Type=" << ((*attachment).type?(*attachment).type:"null") << endl;
9952 cout << "ID=" << ((*attachment).id?(*attachment).id:"null") << endl;
9956 The `options` field is available as well. The `options` content is
9957 formatted according to the DIME specification: the first two bytes are reserved
9958 for the option type, the next two bytes store the size of the option data,
9959 followed by the (binary) option data.
9961 A call to `soap_end` removes all of the received DIME data. To preserve an
9962 attachment in memory, use `soap_unlink` on the `ptr` field of the
9963 `soap_multipart` struct. Recall that the `soap_unlink` function is
9964 commonly used to prevent deallocation of deserialized data.
9966 ## Serializing Binary Data in DIME {#DIMEbinary}
9968 Binary data stored in extended *`xsd:base64Binary`* and *`xsd:hexBinary`*
9969 types can be serialized and deserialized as DIME attachments. These attachments
9970 will be transmitted prior to the sequence of secondary DIME attachments defined
9971 by the user with `soap_set_dime_attachment` as explained in the
9972 previous section. The serialization process is automated for SOAP encoded
9973 messages and DIME attachments will be send even when `soap_set_dime` or
9974 `soap_set_dime_attachment` are not used. For non-SOAP-encoded messages
9975 such as document/literal messages you must still call `soap_set_dime` to
9976 enable sending messages with attachments.
9978 The *`xsd:base64Binary`* XSD type is defined in gSOAP as a struct or class by
9981 struct xsd__base64Binary
9983 unsigned char *__ptr; // pointer to raw binary data
9984 int __size; // size of the block of data
9988 To enable serialization of the data in DIME, we extend this type with three
9992 struct xsd__base64Binary
9994 unsigned char *__ptr;
10002 The three additional fields consist of an `id` field for attachment
10003 referencing (typically a content id (CID) or UUID), a `type` field to
10004 specify the MIME type of the binary data, and an `options` field to
10005 piggy-back additional information with a DIME attachment. The order of the
10006 declaration of the fields is significant. In addition, no other fields or
10007 methods may be declared before any of these fields in the struct/class, but
10008 additional fields and methods may appear after the field declarations. An
10009 extended `xsd__hexBinary` declaration is similar.
10011 The `id` and `type` fields contain text. The set the DIME-specific
10012 options field, you can use the `soap_dime_option` function:
10015 char *soap_dime_option(struct soap *soap, unsigned short type, const char *option)
10018 returns a string with this encoding. For example
10021 struct xsd__base64Binary image;
10023 image.__size = ...;
10024 image.id = "uuid:09233523-345b-4351-b623-5dsf35sgs5d6";
10025 image.type = "image/jpeg";
10026 image.options = soap_dime_option(soap, 0, "My wedding picture");
10029 When either the `id` or `type` field values are non-NULL at run time,
10030 the data will be serialized as a DIME attachment. The SOAP/XML message refers
10031 to the attachments using *`href`* attributes. This generally works will with
10032 SOAP RPC, because *`href`* attributes are permitted. However, with document/literal style the referencing mechanism must be explicitly defined
10033 in the schema of the binary type. The gSOAP
10034 declaration of an extended binary type is
10037 struct ns__myBinaryDataType
10039 unsigned char *__ptr;
10047 C++ programmers can use inheritance instead of textual extension required in C, as in
10050 class xsd__base64Binary
10052 unsigned char *__ptr;
10055 class ns__myBinaryDataType : xsd__base64Binary
10063 This defines an extension of *`xsd:base64Binary`*, such that the data can be
10064 serialized as DIME attachments using *`href`* attributes for referencing.
10065 When a different attribute name is in fact used, it must be explicitly defined:
10068 //gsoap WSref schema import: http://schemas.xmlsoap.org/ws/2002/04/reference/
10069 struct ns__myBinaryDataType
10071 unsigned char *__ptr;
10076 @ char *WSref__location;
10080 The example above uses the *`location`* attribute defined in the content reference schema, as defined in one of the vendor's specific WSDL extensions for DIME (http://www.gotdotnet.com/team/xml_wsspecs/dime/WSDL-Extension-for-DIME.htm).
10082 When receiving DIME attachments, the DIME meta data and binary data content is
10083 stored in binary data types only when the XML parts of the message uses
10084 *`href`* attributes to refer to these attachments. The gSOAP toolkit may
10085 support automatic (de)serialization with other user-defined (or WSDL-defined)
10086 attributes in future releases.
10088 Messages may contain binary data that references external resources not
10089 provided as attachments. In that case, the `__ptr` field is NULL and the
10090 `id` field refers to the external data source.
10092 The `dime_id_format` attribute of the current gSOAP run-time context
10093 can be set to the default format of DIME id fields. The format string MUST
10094 contain a `%d` format specifier (or any other `int`-based format
10095 specifier). The value of this specifier is a non-negative integer, with zero
10096 being the value of the DIME attachment id for the SOAP message. For example,
10101 soap.dime_id_format = "uuid:09233523-345b-4351-b623-5dsf35sgs5d6-%x";
10104 As a result, all attachments with a NULL `id` field will use a
10105 gSOAP-generated id value based on the format string.
10107 @warning Care must be taken not to introduce duplicate content id values,
10108 when assigning content id values to the id fields of DIME extended binary data
10109 types. Content ids must be unique.
10111 ## Streaming DIME {#DIMEstreaming}
10113 Streaming DIME is achieved with callback functions to fetch and store data
10114 during transmission. Three function callbacks for streaming DIME output and
10115 three callbacks for streaming DIME input are available.
10117 * `void *(*soap.fdimereadopen)(struct soap *soap, void *handle, const char *id, const char *type, const char *options)`
10118 Called by the gSOAP run-time DIME attachment sender to start reading from a
10119 (binary) data source for outbound transmission. The content will be read from
10120 the application's data source in chunks using the `fdimeread` callback and
10121 streamed into the SOAP/XML/DIME output stream. The `handle` contains the
10122 value of the `__ptr` field of an attachment struct/class, which could be a
10123 pointer to specific information such as a file descriptor or a pointer to a
10124 string to be passed to this callback. Both `__ptr` and `__size` fields
10125 should have been set by the application prior to the serialization of the
10126 content. The `id`, `type`, and `options` arguments are the DIME id, type, and
10127 options, respectively. The callback should return `handle`, or another
10128 pointer value which will be passed as a handle to `fdimeread` and
10129 `fdimereadclose`. The callback should return NULL and set `soap->error`
10130 when an error occurred. The callback should return NULL (and not set
10131 `soap->error`) when this particular DIME attachment is not to be streamed.
10133 * `size_t (*soap.fdimeread)(struct soap *soap, void *handle, char *buf, size_t len)`
10134 Called by the gSOAP run-time DIME attachment sender to read more data from a
10135 (binary) data source for streaming into the output stream. The `handle`
10136 contains the value returned by the `fdimereadopen` callback. The `buf`
10137 argument is the buffer of length `len` into which a chunk of data should be
10138 stored. The actual amount of data stored in the buffer may be less than
10139 `len` and this amount should be returned by the application. A return value
10140 of 0 indicates an error (the callback may set `soap->errnum` to errno).
10141 The `__size` field of the attachment struct/class should have been set by the
10142 application prior to the serialization of the content. The value of `__size`
10143 indicates the total size of the content to be transmitted. When the `__size`
10144 is zero then DIME chunked transfers can be used under certain circumstances
10145 to stream content without prior determination of attachment size, see Section
10146 \ref dimechunking below.
10148 * `void (*soap.fdimereadclose)(struct soap *soap, void *handle)`
10149 Called by the gSOAP run-time DIME attachment sender at the end of the
10150 streaming process to close the data source. The `handle` contains the value
10151 returned by the `fdimereadopen` callback. The `fdimewriteclose` callback is
10152 called after successfully transmitting the data or when an error occurred.
10154 * `void *(*soap.fdimewriteopen)(struct soap *soap, const char *id, const char *type, const char *options)`
10155 Called by the gSOAP run-time DIME attachment receiver to start writing an
10156 inbound DIME attachment to an application's data store. The content is
10157 streamed into an application data store through multiple `fdimewrite` calls
10158 from the gSOAP attachment receiver. The `id`, `type`, and `options`
10159 arguments are the DIME id, type, and options respectively. The callback
10160 should return a handle which is passed to the `fdimewrite` and
10161 `fdimewriteclose` callbacks. The `__ptr` field of the attachment struct/class
10162 is set to the value of this handle. The `__size` field is set to the total
10163 size of the attachment after receiving the entire content. The size is
10164 unknown in advance because DIME attachments may be chunked.
10166 * `int (*soap.fdimewrite)(struct soap *soap, void *handle, const char *buf, size_t len)`
10167 Called by the gSOAP run-time DIME attachment receiver to write part of an
10168 inbound DIME attachment to an application's data store. The `handle`
10169 contains the value returned by the `fdimewriteopen` callback. The `buf`
10170 argument contains the data of length `len`. The callback should return a
10171 gSOAP error code (e.g. `SOAP_OK` when no error occurred).
10173 * `void (*soap.fdimewriteclose)(struct soap *soap, void *handle)`
10174 Called by the gSOAP run-time DIME attachment receiver at the end of the
10175 streaming process to close the data store. The `fdimewriteclose` callback is
10176 called after successfully receiving the data or when an error occurred. The
10177 `handle` contains the value returned by the `fdimewriteopen` callback.
10179 In addition, a `void*user` field in the `struct soap` data structure
10180 is available to pass user-defined data to the callbacks. This way, you can set
10181 `soap.user` to point to application data that the callbacks need such as a
10182 file name for example.
10184 The following example illustrates the client-side initialization of an image
10185 attachment struct to stream a file into a DIME attachment:
10191 struct xsd__base64Binary image;
10195 if (!fstat(fileno(fd), &sb) && sb.st_size > 0)
10196 { // because we can get the length of the file, we can stream it
10197 soap.fdimereadopen = dime_read_open;
10198 soap.fdimereadclose = dime_read_close;
10199 soap.fdimeread = dime_read;
10200 image.__ptr = (unsigned char*)fd; // must set to non-NULL (this is our fd handle which we need in the callbacks)
10201 image.__size = sb.st_size; // must set size
10204 { // don't know the size, so buffer it
10207 image.__ptr = (unsigned char*)soap_malloc(&soap, MAX_FILE_SIZE);
10208 for (i = 0; i < MAX_FILE_SIZE; i++)
10210 if ((c = fgetc(fd)) == EOF)
10212 image.__ptr[i] = c;
10217 image.type = "image/jpeg";
10218 image.options = soap_dime_option(&soap, 0, "My picture");
10219 soap_call_ns__method(&soap, ...);
10222 void *dime_read_open(struct soap *soap, void *handle, const char *id, const char *type, const char *options)
10226 void dime_read_close(struct soap *soap, void *handle)
10227 { fclose((FILE*)handle);
10229 size_t dime_read(struct soap *soap, void *handle, char *buf, size_t len)
10230 { return fread(buf, 1, len, (FILE*)handle);
10234 The following example illustrates the streaming of a DIME attachment into a file by a client:
10238 { struct soap soap;
10240 soap.fdimewriteopen = dime_write_open;
10241 soap.fdimewriteclose = dime_write_close;
10242 soap.fdimewrite = dime_write;
10243 soap_call_ns__method(&soap, ...);
10246 void *dime_write_open(struct soap *soap, const char *id, const char *type, const char *options)
10248 FILE *handle = fopen("somefile", "wb");
10251 soap->error = SOAP_EOF;
10252 soap->errnum = errno; // get reason
10254 return (void*)handle;
10256 void dime_write_close(struct soap *soap, void *handle)
10257 { fclose((FILE*)handle);
10259 int dime_write(struct soap *soap, void *handle, const char *buf, size_t len)
10264 nwritten = fwrite(buf, 1, len, (FILE*)handle);
10267 soap->errnum = errno; // get reason
10277 Note that compression can be used with DIME to compress the entire message.
10278 However, compression requires buffering to determine the HTTP content length
10279 header, which cancels the benefits of streaming DIME. To avoid this, you should
10280 use chunked HTTP (with the output-mode `SOAP_IO_CHUNK` flag) with
10281 compression and streaming DIME. At the server side, when you set
10282 `SOAP_IO_CHUNK` before calling `soap_serve`, gSOAP will
10283 automatically revert to buffering (`SOAP_IO_STORE` flag is set). You can
10284 check this flag with `(soap->omode & SOAP_IO) == SOAP_IO_CHUNK` to see
10285 if the client accepts chunking. More information about streaming chunked DIME
10286 can be found in Section \ref dimechunking .
10288 @warning The `options` field is a DIME-specific data structure,
10289 consisting of a 4 byte header containing the option type info (hi byte, lo
10290 byte), option string length (hi byte, lo byte), followed by a non-'\0'
10291 terminated string. The gSOAP DIME handler recognizes one option at most.
10293 ## Streaming Chunked DIME {#dimechunking}
10295 gSOAP automatically handles inbound chunked DIME attachments (streaming or
10296 non-streaming). To transmit outbound DIME attachments, the attachment sizes
10297 MUST be determined in advance to calculate HTTP message length required to
10298 stream DIME over HTTP. However, gSOAP also supports the transmission of
10299 outbound chunked DIME attachments without prior determination of DIME
10300 attachment sizes when certain conditions are met. These conditions require
10301 either non-HTTP transport (use the output-mode `SOAP_ENC_PLAIN` flag), or
10302 chunked HTTP transport (use the output-mode `SOAP_IO_CHUNK` flag). You
10303 can also use the `SOAP_IO_STORE` flag (which is also used automatically
10304 with compression to determine the HTTP content length header) but that cancels
10305 the benefits of streaming DIME.
10307 To stream chunked DIME, set the `__size` field of an attachment to zero
10308 and enable HTTP chunking. The DIME `fdimeread` callback then fetches data
10309 in chunks and it is important to fill the entire buffer unless the end of the
10310 data has been reached and the last chunk is to be send. That is,
10311 `fdimeread` should return the value of the last `len` parameter and
10312 fill the entire buffer `buf` for all chunks except the last.
10314 ## WSDL Bindings for DIME Attachments
10316 The `wsdl2h` WSDL parser recognizes DIME attachments and produces an
10317 annotated header file. Both open and closed layouts are supported for
10318 transmitting DIME attachments. For closed formats, all DIME attachments must be
10319 referenced from the SOAP message, e.g. using hrefs with SOAP encoding and using
10320 the application-specific reference attribute included in the `base64Binary`
10321 struct/class for doc/lit.
10323 The gSOAP compiler `soapcpp2` does not produce a WSDL with DIME extensions.
10324 DIME is an older binary format that has no WSDL protocol support, unlike MIME
10327 # MTOM Attachments {#MTOM}
10329 MTOM (Message Transmission Optimization Mechanism) is a relatively new format
10330 for transmitting attachments with SOAP messages (see
10331 <http://www.w3.org/TR/soap12-mtom>). MTOM is a W3C working draft as of this
10332 writing. MTOM attachments are essentially MIME attachments with standardized
10333 mechanisms for cross referencing attachments from the SOAP body, which is
10334 absent in (plain) MIME attachments and optional with DIME attachments.
10336 Unlike the name suggests, the speed by which attached data is transmitted is
10337 not increased compared to MIME, DIME, or even XML encoded base64 data (at least
10338 the performance differences in gSOAP will be small). The advantage of the
10339 format is the standardized attachment reference mechanism, which should improve
10342 The MTOM specification mandates SOAP 1.2 and the use of the XOP namespace. The
10343 XOP Include element *`xop:Include`* is used to reference attachment(s) from the SOAP message body.
10345 Because references from within the SOAP message body to attachments are
10346 mandatory with MTOM, the implementation of the serialization and deserialization of MTOM
10347 MIME attachments in gSOAP uses the extended binary type comparable to DIME support in gSOAP. This binary type is predefined in the `import/xop.h` file:
10350 //gsoap xop schema import: http://www.w3.org/2004/08/xop/include
10351 struct _xop__Include
10353 unsigned char *__ptr;
10359 typedef struct _xop__Include _xop__Include;
10362 The additional `id`, `type`, and `option` fields
10363 enable MTOM attachments for the data pointed to by `__ptr` of size `__size`. The process for sending and receiving MTOM XOP
10364 attachments is fully automated.
10365 The `id` field references the attachment (typically a content id CID or UUID). When set to NULL, gSOAP assigns a unique CID. The `type`
10366 field specifies the required MIME type of the binary data, and the optional
10367 `options` field can be used to piggy-back descriptive text with an attachment. The order of the
10368 declaration of the fields is significant.
10370 You can explicitly import the `xop.h` in your header file to use the MTOM attachments in your service, for example:
10373 #import "import/soap12.h"
10374 /* alternatively, without the import above, use:
10375 //gsoap SOAP-ENV schema namespace: http://www.w3.org/2003/05/soap-envelope
10376 //gsoap SOAP-ENC schema namespace: http://www.w3.org/2003/05/soap-encoding
10378 #import "import/xop.h"
10379 #import "import/xmime5.h"
10381 //gsoap x schema namespace: http://my.first.mtom.net
10384 _xop__Include xop__Include; // attachment
10385 @ char *xmime5__contentType; // and its contentType
10387 int x__myMTOMtest(struct x__myData *in, struct x__myData *out);
10390 As you can see, there is really no difference between the specification of MTOM
10391 and DIME attachments in a gSOAP header file. Except that you MUST use SOAP 1.2
10392 and the `xop__Include` element.
10394 When an instance of `x__myDataType` is serialized and either or both the
10395 `id` and `type` fields are non-NULL, the data is transmitted as MTOM
10396 MIME attachment if the `SOAP_ENC_MTOM` flag is set in the gSOAP's soap
10400 struct soap *soap = soap_new1(SOAP_ENC_MTOM);
10403 Without this flag, the attachments will be transmitted in DIME format
10404 (Section \ref DIME ). If your current clients and services are based on
10405 non-streaming DIME attachments using the SOAP body reference mechanism (thus,
10406 without using the `soap_set_dime_attachment` function) or plain base64
10407 binary XML data elements, it is very easy to adopt MTOM by renaming the binary types to `xop__Include` and using the
10408 `SOAP_ENC_MTOM` flag with the SOAP 1.2 namespace.
10410 ## Generating MultipartRelated MIME Attachment Bindings in WSDL {#MIMEWSDL}
10412 To generate multipartRelated bindings in the WSDL file, use the
10415 //gsoap ... service method-mime-type
10418 directive (see also Section \ref directives . The
10419 directive can be repeated for each attachment you want to associate with a
10420 method's request and response messages.
10425 #import "import/soap12.h"
10426 #import "import/xop.h"
10427 #import "import/xmime5.h"
10429 //gsoap x schema namespace: http://my.first.mtom.net
10432 _xop__Include xop__Include; // attachment
10433 @ char *xmime5__contentType; // and its contentType
10435 //gsoap x service method-mime-type: myMTOMtest text/xml
10436 int x__myMTOMtest(struct x__myData *in, struct x__myData *out);
10439 The `//gsoap x service method-mime-type` directive indicates that this
10440 operation accepts *`text/xml`* MIME attachments. See the SOAP-with-Attachment
10441 specification for the MIME types to use (for example, *`*/*`* is a wildcard).
10442 If the operation has more than one attachment, just repeat this directive for
10443 each attachment you want to bind to the operation.
10445 To bind attachments only to the request message of an operation, use
10446 `//gsoap x service method-input-mime-type`. Similarly, to bind attachments
10447 only to the response message of an operation, use
10450 //gsoap x service method-ouput-mime-type
10453 The `wsdl2h` WSDL parser recognizes MIME attachments and produces an
10454 annotated header file. However, the ordering of MIME parts in the
10455 multipartRelated elements is not reflected in the header file. Application
10456 developers should adhere the standards and ensure that multipart/related
10457 attachments are transmitted in compliance with the WSDL operation declarations.
10459 ## Sending and Receiving MTOM Attachments
10461 A receiver must be informed to recognize MTOM attachments by setting the
10462 `SOAP_ENC_MTOM` flag of the gSOAP context. Otherwise, the regular MIME
10463 attachment mechanism (SwA) will be used to store attachments.
10465 When using `wsdl2h` to build clients and/or services, you should use the
10466 `typemap.dat` file included in the distribution package. The
10467 `typemap.dat` file defines the XOP namespace and XML MIME namespaces as
10468 imported namespaces:
10471 xop = <http://www.w3.org/2004/08/xop/include>
10472 xmime5 = <http://www.w3.org/2005/05/xmlmime>
10473 xmime4 = <http://www.w3.org/2004/11/xmlmime>
10476 The `wsdl2h` tool uses the `typemap.dat` file (see also option -t) to
10477 convert WSDL into a gSOAP header file. In this case we don't want the
10478 `wsdl2h` tool to read the XOP schema and translate it, since we have a
10479 pre-defined `_xop__Include` element to handle XOP for MTOM. This
10480 `_xop__Include` element is defined in `xop.h`. Therefore, the
10481 bindings shown above will not translate the XOP and XML MIME schemas to code,
10482 but generates `#import` statements instead:
10489 The `#import` statements are only added for those namespaces that are
10490 actually used by the service.
10492 Let's take a look at an example.
10493 The `wsdl2h` importer generates a header file with `#import "xop.h"` from a WSDL that references XOP, for example:
10500 _xop__Include xop__Include;
10501 @ char *xmime5__contentType;
10505 Suppose the WSDL defines an operation:
10508 int ns__echoData(struct ns__Data *in, struct ns__Data *out);
10511 After generating the stubs/proxies with the `soapcpp2` compiler, we can invoke the stub at the client side with:
10514 struct soap *soap = soap_new1(SOAP_ENC_MTOM);
10515 struct ns__Data data;
10516 data.xop__Include.__ptr = (unsigned char*)"<b>Hello world!</b>";
10517 data.xop__Include.__size = 20;
10518 data.xop__Include.id = NULL; // CID automatically generated by gSOAP engine
10519 data.xop__Include.type = "text/html"; // MIME type
10520 data.xop__Include.options = NULL; // no descriptive info added
10521 data.xmime5__contentType = "text/html"; // MIME type
10522 if (soap_call_ns__echoData(soap, endpoint, action, &data, &data))
10523 soap_print_fault(soap, stderr);
10525 printf("Got data\n");
10526 soap_destroy(soap); // remove deserialized class instances
10527 soap_end(soap); // remove temporary and deserialized data
10528 soap_free(soap); // detach and free context
10531 Note that the `xop__Include.type` field must be set to transmit MTOM attachments, otherwise plain base64 XML will be used.
10533 At the server side, we show an example of an operation handler that just copies the input data to output:
10536 int ns__echoData(struct soap *soap, struct ns__Data *in, struct ns__data *out)
10543 The server must use the `SOAP_ENC_MTOM` flag to initialize the soap struct to receive and send MTOM attachments.
10545 ## Streaming MTOM/MIME {#MTOMstreaming}
10547 Streaming MTOM/MIME is achieved with callback functions to fetch and store data
10548 during transmission. Three function callbacks for streaming MTOM/MIME output and
10549 three callbacks for streaming MTOM/MIME input are available.
10551 * `void *(*soap.fmimereadopen)(struct soap *soap, void *handle, const char *id, const char *type, const char *description)`
10552 Called by the gSOAP run-time MTOM/MIME attachment sender to start reading
10553 from a (binary) data source for outbound transmission. The content will be
10554 read from the application's data source in chunks using the `fmimeread`
10555 callback and streamed into the SOAP/XML/MTOM/MIME output stream. The `handle`
10556 contains the value of the `__ptr` field of an attachment struct/class, which
10557 could be a pointer to specific information such as a file descriptor or a
10558 pointer to a string to be passed to this callback. Both `__ptr` and `__size`
10559 fields should have been set by the application prior to the serialization of
10560 the content. The `id`, `type`, and `description` arguments are the MTOM/MIME
10561 id, type, and description, respectively. The callback should return `handle`,
10562 or another pointer value which will be passed as a handle to `fmimeread` and
10563 `fmimereadclose`. The callback should return NULL and set `soap->error`
10564 when an error occurred. The callback should return NULL (and not set
10565 `soap->error`) when this particular MTOM/MIME attachment is not to be
10568 * `size_t (*soap.fmimeread)(struct soap *soap, void *handle, char *buf, size_t len)`
10569 Called by the gSOAP run-time MTOM/MIME attachment sender to read more data
10570 from a (binary) data source for streaming into the output stream. The
10571 `handle` contains the value returned by the `fmimereadopen` callback. The
10572 `buf` argument is the buffer of length `len` into which a chunk of data
10573 should be stored. The actual amount of data stored in the buffer may be less
10574 than `len` and this amount should be returned by the application. A return
10575 value of 0 indicates an error (the callback may set `soap->errnum` to errno).
10576 The `__size` field of the attachment struct/class should have been set by the
10577 application prior to the serialization of the content. The value of `__size`
10578 indicates the total size of the content to be transmitted. When the `__size`
10579 is zero then MTOM/MIME chunked transfers can be used under certain
10580 circumstances to stream content without prior determination of attachment
10581 size, see Section \ref mimechunking below.
10583 * `void (*soap.fmimereadclose)(struct soap *soap, void *handle)`
10584 Called by the gSOAP run-time MTOM/MIME attachment sender at the end of the
10585 streaming process to close the data source. The `handle` contains the value
10586 returned by the `fmimereadopen` callback. The `fmimewriteclose` callback is
10587 called after successfully transmitting the data or when an error occurred.
10589 * `void *(*soap.fmimewriteopen)(struct soap *soap, void *handle, const char *id, const char *type, const char *description, enum soap_mime_encoding encoding)`
10590 Called by the gSOAP run-time MTOM/MIME attachment receiver to start writing
10591 an inbound MTOM/MIME attachment to an application's data store. The content
10592 is streamed into an application data store through multiple `fmimewrite`
10593 calls from the gSOAP attachment receiver. The `handle` argument is normally
10594 NULL, unless `soap_get_mime_attachment` is used that passes the handle to the
10595 callback, see Section \ref MTOMpoststreaming . The `id`, `type`, and
10596 `description` arguments are the MTOM/MIME id, type, and description
10597 respectively. The `encoding` enumeration value indicates the MIME content
10598 transfer encoding, which is one of `SOAP_MIME_NONE`, `SOAP_MIME_7BIT`,
10599 `SOAP_MIME_8BIT`, `SOAP_MIME_BINARY`, `SOAP_MIME_QUOTED_PRINTABLE`,
10600 `SOAP_MIME_BASE64`, `SOAP_MIME_IETF_TOKEN`, `SOAP_MIME_X_TOKEN`. Content
10601 decoding may have to be considered by the application based on this value.
10602 The callback should return a non-NULL handle which is passed to the
10603 `fmimewrite` and `fmimewriteclose` callbacks. The `__ptr` field of the
10604 attachment struct/class is set to the value of this handle. The `__size`
10605 field is set to the total size of the attachment after receiving the entire
10606 content. The size is unknown in advance because MTOM/MIME attachments may be
10609 * `int (*soap.fmimewrite)(struct soap *soap, void *handle, const char *buf, size_t len)`
10610 Called by the gSOAP run-time MTOM/MIME attachment receiver to write part of
10611 an inbound MTOM/MIME attachment to an application's data store. The `handle`
10612 contains the value returned by the `fmimewriteopen` callback. The `buf`
10613 argument contains the data of length `len`. The callback should return a
10614 gSOAP error code (e.g. `SOAP_OK` when no error occurred).
10616 * `void (*soap.fmimewriteclose)(struct soap *soap, void *handle)`
10617 Called by the gSOAP run-time MTOM/MIME attachment receiver at the end of the
10618 streaming process to close the data store. The `fmimewriteclose` callback is
10619 called after successfully receiving the data or when an error occurred. The
10620 `handle` contains the value returned by the `fmimewriteopen` callback.
10622 In addition, a `void *user` field in the `struct soap` data structure
10623 is available to pass user-defined data to the callbacks. This way, you can set
10624 `soap.user` to point to application data that the callbacks need such as a
10625 file name for example.
10627 The following example illustrates the client-side initialization of an image
10628 attachment struct to stream a file into a MTOM attachment without HTTP chunking (HTTP streaming chunked MTOM transfer is presented in Section \ref mimechunking ):
10634 struct xsd__base64Binary image;
10637 soap_init1(&soap, SOAP_ENC_MTOM); // mandatory to enable MTOM
10638 if (!fstat(fileno(fd), &sb) && sb.st_size > 0)
10640 // because we can get the length of the file, we can stream it without chunking
10641 soap.fmimereadopen = mime_read_open;
10642 soap.fmimereadclose = mime_read_close;
10643 soap.fmimeread = mime_read;
10644 image.__ptr = (unsigned char*)fd; // must set to non-NULL (this is our fd handle which we need in the callbacks)
10645 image.__size = sb.st_size; // must set size
10649 // don't know the size, so buffer it
10652 image.__ptr = (unsigned char*)soap_malloc(&soap, MAX_FILE_SIZE);
10653 for (i = 0; i < MAX_FILE_SIZE; i++)
10655 if ((c = fgetc(fd)) == EOF)
10657 image.__ptr[i] = c;
10662 image.type = "image/jpeg"; // MIME type
10663 image.options = "This is my picture"; // description of object
10664 soap_call_ns__method(&soap, ...);
10667 void *mime_read_open(struct soap *soap, void *handle, const char *id, const char *type, const char *description)
10671 void mime_read_close(struct soap *soap, void *handle)
10673 fclose((FILE*)handle);
10675 size_t mime_read(struct soap *soap, void *handle, char *buf, size_t len)
10677 return fread(buf, 1, len, (FILE*)handle);
10681 The following example illustrates the streaming of a MTOM/MIME attachment into a file by a client:
10688 soap.fmimewriteopen = mime_write_open;
10689 soap.fmimewriteclose = mime_write_close;
10690 soap.fmimewrite = mime_write;
10691 soap_call_ns__method(&soap, ...);
10694 void *mime_write_open(struct soap *soap, const char *id, const char *type, const char *description, enum soap_mime_encoding encoding)
10696 FILE *handle = fopen("somefile", "wb");
10697 // We ignore the MIME content transfer encoding here, but should check
10700 soap->error = SOAP_EOF;
10701 soap->errnum = errno; // get reason
10703 return (void*)handle;
10705 void mime_write_close(struct soap *soap, void *handle)
10707 fclose((FILE*)handle);
10709 int mime_write(struct soap *soap, void *handle, const char *buf, size_t len)
10714 nwritten = fwrite(buf, 1, len, (FILE*)handle);
10717 soap->errnum = errno; // get reason
10727 Note that compression can be used with MTOM/MIME to compress the entire message.
10728 However, compression requires buffering to determine the HTTP content length
10729 header, which cancels the benefits of streaming MTOM/MIME. To avoid this, you should
10730 use chunked HTTP (with the output-mode `SOAP_IO_CHUNK` flag) with
10731 compression and streaming MTOM/MIME. At the server side, when you set
10732 `SOAP_IO_CHUNK` before calling `soap_serve`, gSOAP will
10733 automatically revert to buffering (`SOAP_IO_STORE` flag is set). You can
10734 check this flag with `(soap->omode & SOAP_IO) == SOAP_IO_CHUNK` to see
10735 if the client accepts chunking. More information about streaming chunked MTOM/MIME
10736 can be found in Section \ref mimechunking .
10738 Note that the example above for `mime_read` uses a handle that points to the open file
10740 The simple example above is not recommended when the
10741 platform imposes a limit on the number of open file descriptors.
10742 You can use the handle to pass along more information than just
10743 the file descriptor. So for example, when the number of open file descriptors
10744 is limited on your platform, you should let the handle point to a structure
10745 with file-related information. The C++ example below illustrates this:
10748 file.xop__Include = soap_new__xop__Include(soap);
10749 file.xop__Include->id = NULL;
10750 file.xop__Include->type = type;
10751 file.xop__Include->options = NULL;
10753 file.xmime5__contentType = type;
10754 file.filename = filename;
10756 // The object holding all information to read data
10757 FileStreamIn *ins = new FileStreamIn(errorhandler);
10758 ins->setFilePath(path);
10759 ins->setFileName(filename);
10761 file.xop__Include->__size = size;
10762 file.xop__Include->__ptr = (unsigned char*)ins;
10765 To read the MTOM data for transmission:
10768 void *mime_read_open(struct soap *soap, void *handle, const char *id, const char *type, const char *description)
10772 FileStreamIn *ins = (FileStreamIn*)handle;
10775 soap->error = SOAP_ERR;
10780 void mime_read_close(struct soap *soap, void *handle)
10784 FileStreamIn *ins = (FileStreamIn*)handle;
10787 size_t mime_read(struct soap *soap, void *handle, char *buf, size_t len)
10791 FileStreamIn *ins = (FileStreamIn*)handle;
10792 size_t nread = ins->read(buf, len);
10793 if (ins->streamError())
10795 soap->error = ins->streamError();
10802 ## Redirecting Inbound MTOM/MIME Streams Based on SOAP Body Content {#MTOMpoststreaming}
10804 When it is preferable or required to redirect inbound MTOM/MIME attachment
10805 streams based on SOAP message body content, where for example the names of the
10806 resources are listed in the SOAP message body, an alternative mechanism must be
10807 used. This mechanism can be used both at the client and server side.
10809 Because the routing of the streams is accomplished with explicit function
10810 calls, this method should only be used when required and should not be
10811 considered optional. That is, when you enable this method, you MUST check for
10812 pending MTOM/MIME attachments and handle them appropriately. This is true even
10813 when you don't expect MTOM/MIME attachments in the payload, because the peer
10814 may trick you by sending attachments anyway and you should be prepared to
10815 accept or reject them.
10817 The explicit MTOM/MIME streaming mechanism consists of three API functions:
10819 * `void soap_post_check_mime_attachments(struct soap *soap)`
10820 Enables post-message body inbound streaming MTOM/MIME attachments. The
10821 presence of attachments must be explicitly checked using the function below.
10823 * `int soap_check_mime_attachments(struct soap *soap)`
10824 Should be called after a client-side call (e.g. `soap_call_ns__method`) to
10825 check the presence of attachments. Returns 1 (true) when attachments are
10826 present. If present, each attachment MUST be processed with the function
10829 * `struct soap_multipart *soap_get_mime_attachment(struct soap *soap, void *handle)`
10830 Parses an attachment and invokes the MIME callbacks (when set). The `handle`
10831 parameter is passed to `fmimewriteopen`. The handle may contain any data that
10832 is extracted from the SOAP message body to guide the redirection of the
10833 stream in the callbacks. The return value is a struct with a `char *ptr`
10834 field that contains the handle value returned by the `fmimewriteopen`
10835 callback, and `char *id`, `char *type`, and `char *description` fields with
10836 the optional MIME id, type, and description info.
10838 Example client-side code in C:
10841 struct soap *soap = soap_new1(SOAP_ENC_MTOM);
10842 soap_post_check_mime_attachments(soap);
10844 if (soap_call_ns__myMethod(soap, ...))
10845 soap_print_fault(soap, stderr); // an error occurred
10848 if (soap_check_mime_attachments(soap))
10849 { // attachments are present, channel is still open
10853 ... // get data 'handle' from SOAP response and pass to callbacks
10854 ... // set the fmime callbacks, if needed
10855 struct soap_multipart *content = soap_get_mime_attachment(soap, (void*)handle);
10856 printf("Received attachment with id=%s and type=%s\n", content->id?content->id:"", content->type?content->type:"");
10859 soap_print_fault(soap, stderr);
10864 soap_destroy(soap);
10866 soap_free(soap); // detach and free context
10869 The server-side service operations are implemented as usual, but with additional checks for MTOM/MIME attachments:
10872 struct soap *soap = soap_new1(SOAP_ENC_MTOM);
10873 soap_post_check_mime_attachments(soap);
10877 int ns__myMethod(struct soap *soap, ...)
10879 ... // server-side processing logic
10880 if (soap_check_mime_attachments(soap))
10881 { // attachments are present, channel is still open
10885 ... // get data 'handle' from SOAP request and pass to callbacks
10886 ... // set the fmime callbacks, if needed
10887 struct soap_multipart *content = soap_get_mime_attachment(soap, (void*)handle);
10888 printf("Received attachment with id=%s and type=%s\n", content->id?content->id:"", content->type?content->type:"");
10891 return soap->error;
10894 ... // server-side processing logic
10899 ## Streaming Chunked MTOM/MIME {#mimechunking}
10901 gSOAP automatically handles inbound chunked MTOM/MIME attachments (streaming or
10902 non-streaming). To transmit outbound MTOM/MIME attachments, the attachment sizes
10903 MUST be determined in advance to calculate HTTP message length required to
10904 stream MTOM/MIME over HTTP. However, gSOAP also supports the transmission of
10905 outbound chunked MTOM/MIME attachments without prior determination of MTOM/MIME
10906 attachment sizes when certain conditions are met. These conditions require
10907 either non-HTTP transport (use the output-mode `SOAP_ENC_PLAIN` flag), or
10908 chunked HTTP transport (use the output-mode `SOAP_IO_CHUNK` flag). You
10909 can also use the `SOAP_IO_STORE` flag (which is also used automatically
10910 with compression to determine the HTTP content length header) but that cancels
10911 the benefits of streaming MTOM/MIME.
10913 To stream chunked MTOM/MIME, set the `__size` field of an attachment to
10914 zero and enable HTTP chunking. The MTOM/MIME `fmimeread` callback then
10915 fetches data in chunks of any size between 1 and the value of the `len`
10916 argument. The `fmimeread` callback should return 0 upon reaching the end of
10919 # XML Validation {#validation}
10921 The gSOAP XML parser applies basic rules to validate content. Constraints are not automatically verified unless explicitly
10922 set using flags. This helps to avoid interoperability problems with toolkits that do
10923 not strictly enforce validation rules. In addition, we cannot always use strict
10924 validation for SOAP RPC encoded messages, since SOAP RPC encoding adopts a very
10925 loose serialization format.
10927 Validation constraints are enabled with the `SOAP_XML_STRICT` input mode
10928 flag set, e.g. with `soap_set_imode(soap, SOAP_XML_STRICT)` or
10929 `soap_new(SOAP_XML_STRICT)`, see Section \ref flags for the complete list
10932 ## Occurrence Constraints
10936 Default values can be defined for optional elements and attributes, which means
10937 that the default value will be used when the element or attribute value is not
10938 present in the parsed XML. See also Section \ref default and examples in
10939 subsequent subsections below.
10941 Default values must be primitive types, integer, float, string, etc.
10942 Default values can be specified for struct and class members, as shown in the example below:
10945 struct ns__MyRecord
10947 int n = 5; // optional element with default value 5
10948 char *name = "none"; // optional element with default value "none"
10949 @ enum ns__color { RED, WHITE, BLUE } color = RED; // optional attribute with default value RED
10953 Upon deserialization of absent data, these members will be set accordingly.
10954 When classes are instantiated with `soap_new_ClassName` the instance will
10955 be initialized with default values.
10957 ### Elements with minOccurs and maxOccurs Restrictions
10959 To force the validation of minOccurs and maxOccurs contraints the `SOAP_XML_STRICT` input mode flag must be set.
10960 The minOccurs and maxOccurs constraints are specified for fields of a struct and members of a class in a header file using the following syntax:
10963 Type fieldname [optional: nullptr] [optional: minOccurs[optional: :maxOccurs]] [optional: = value]
10966 The minOccurs and maxOccurs values must be integer literals. Also a default initialization value can be provided. When minOccurs is not specified it is assumed to be one (1) for non-pointer `fieldname` members that are elements and zero (0) for `fieldname` members that are pointers or are attributes (i.e. have a `@` qualifier).
10968 The nillable property can by specified by adding a nullptr before the minOccurs (version 2.8.24 or greater).
10970 A fixed initialization value can be specified with `==` (version 2.8.48 or greater).
10975 struct ns__MyRecord
10977 int n 0 = 5; // element with default value 5, minOccurs=0, maxOccurs=1
10978 int m; // element with minOccurs=1
10979 int *k nullptr 1; // element with minOccurs=1 and nillable=true
10980 int v == 2; // element with minOccurs=1 and fixed value 2
10981 int __size 0:10; // sequence <item> with minOccurs=0, maxOccurs=10
10983 std::vector<double> nums 2; // sequence <nums> with minOccurs=2, maxOccurs=unbounded
10987 int *__ptr 1:100; // minOccurs=1, maxOccurs=100
10994 ### Required and Prohibited Attributes
10996 Similar to the minOccurs and maxOccurs annotations defined in the previous
10997 section, attributes in a struct or class can be annotated with occurrence
10998 constraints to make them optional (0), required (1), or prohibited (0:0).
10999 Default values can be assigned to optional attributes.
11004 struct ns__MyRecord
11006 @ int m 1; // required attribute (occurs at least once)
11007 @ int n = 5; // optional attribute with default value 5
11008 @ int o 0; // optional attribute (may or may not occur)
11009 @ int p 0:0; // prohibited attribute
11013 Remember to set the `SOAP_XML_STRICT` input mode flag to
11014 enable the validation of attribute occurrence constraints.
11016 ## Value Constraints
11018 ### Data Length Restrictions
11020 A schema simpleType is defined with a `typedef` by taking a base primitive to defined a derived simpleType. For example:
11023 typedef int time__seconds;
11026 This defines the following schema type in `time.xsd`:
11030 <simpleType name="seconds">
11031 <restriction base="xsd:int"/>
11036 A complexType with simpleContent is defined with a wrapper struct/class:
11041 char *__item; // some custom format date (restriction of string)
11042 @ enum time__zone { EST, GMT, ... } zone;
11046 This defines the following schema type in `time.xsd`:
11050 <complexType name="date">
11052 <extension base="xsd:string"/>
11054 <attribute name="zone" type="time:zone" use="optional"/>
11056 <simpleType name="zone">
11057 <restriction base="xsd:string">
11058 <enumeration value="EST"/>
11059 <enumeration value="GMT"/>
11066 Data value length constraints of simpleTypes and complexTypes with simpleContent are defined as follows.
11069 typedef char *ns__string256 0:256; // simpleType restriction of string with max length 256 characters
11070 typedef char *ns__string10 10:10; // simpleType restriction of string with length of 10 characters
11071 typedef std::string *ns__string8 8; // simpleType restriction of string with at least 8 characters
11072 struct ns__data // simpleContent wrapper
11074 char *__item :256; // simpleContent with at most 256 characters
11075 @ char *name 1; // required name attribute
11077 struct time__date // simpleContent wrapper
11080 @ enum time__zone { EST, GMT, ... } zone = GMT;
11084 Remember to set the `SOAP_XML_STRICT` input mode flag to
11085 enable the validation of value length constraints.
11087 Use compiler flag `WITH_REPLACE_ILLEGAL_UTF8` to force strict UTF-8 text
11088 conversions, which replaces invalid UTF-8 with U+FFFD. Compile
11089 `stdsoap2.c` and `stdsoap2.cpp` with this flag.
11091 ### Value Range Restrictions
11093 Similar to data length constraints for string-based data, integer and floatig point value range
11094 constraints on numeric simpleTypes and complexTypes with simpleContent are
11095 declared with `low : high`, where `low` and `high` are optional.
11097 As of gSOAP 2.8.26, floating point value ranges and integer ranges can be
11098 exclusive by adding < on either side of the '`:`' range operator:
11100 Range | Validitation check
11101 -------------- | ------------------
11105 `1 : 10 ` | 1 <= x <= 10
11106 `1 < : < 10 ` | 1 < x < 10
11107 `1 < 10 ` | 1 < x < 10
11108 `1 : < 10` | 1 <= x < 10
11113 `1 < : 10 ` | 1 < x <= 10
11118 typedef int ns__int10 0:10; // simpleType restriction of int 0..10
11119 typedef LONG64 ns__long -1000000:1000000; // simpleType restriction of long64 -1000000..1000000
11120 typedef float ns__float -1.0 <:< 10.5; // simpleType restriction of float in (-1,10.5)
11121 struct ns__data // simpleContent wrapper
11123 int __item 0:10; // simpleContent range 0..10
11124 @ char *name 1; // required name attribute
11128 Remember to set the `SOAP_XML_STRICT` input mode flag to
11129 enable the validation of value range constraints.
11131 Use compiler flag `WITH_REPLACE_ILLEGAL_UTF8` to force strict UTF-8 text
11132 conversions, which replaces invalid UTF-8 with U+FFFD. Compile
11133 `stdsoap2.c` and `stdsoap2.cpp` with this flag.
11135 ### Pattern Restrictions
11137 Patterns can be defined for simpleType content. However, patterns are currently not enforced in the validation process though possibly in future releases.
11139 To associate a pattern with a simpleType, you can define a simpleType with a `typedef` and a pattern string:
11142 typedef int time__second "[1-5]?[0-9]|60";
11145 This defines the following schema type in `time.xsd`:
11149 <simpleType name="second">
11150 <restriction base="xsd:int">
11151 <pattern value="[1-5]?[0-9]|60"/>
11157 The pattern string MUST contain a valid regular expression.
11159 A special case for C format string patterns is introduced in gSOAP 2.8.18.
11160 When *`xs:totalDigits`* and *`xs:fractionDigits`* are given in a XSD file,
11161 then a C format string is produced to output floating point values with the
11162 proper precision and scale. For example:
11166 <simpleType name="ratio">
11167 <restriction base="xsd:float">
11168 <totalDigits value="5"/>
11169 <fractionDigits value="2"/>
11178 typedef float time__ratio "%5.2f";
11181 The format string is used to format the output the floating point value in XML.
11183 ## Element and Attribute Qualified/Unqualified Forms
11185 Struct, class, and union members represent elements and attributes that are
11186 automatically qualified or unqualified depending on the schema element and
11187 attribute default forms specified. The gSOAP engine always validates the prefixes of
11188 elements and attributes. When a namespace mismatch occurs, the element or
11189 attribute is not consumed which can lead to a validation error (unless the
11190 complexType is extensible or when `SOAP_XML_STRICT` is turned off).
11192 See Section \ref idtrans for details on the
11193 the struct/class/union member identifier translation rules.
11194 Consider for example:
11197 //gsoap ns schema elementForm: qualified
11198 //gsoap ns schema attributeForm: unqualified
11206 Here, the `ns__record` struct is serialized with qualified element `name` and unqualified attribute `type`:
11210 <ns:record type="...">
11211 <ns:name>...</ns:name>
11216 The "colon notation" for struct/class/union member field names is used to
11217 override element and attribute qualified or unqualified forms.
11218 To override the form for individual members that represent elements and attributes, use a namespace prefix and colon with the member name:
11221 //gsoap ns schema elementForm: qualified
11222 //gsoap ns schema attributeForm: unqualified
11230 where `name` is unqualified and `type` is qualified:
11234 <ns:record ns:type="...">
11240 The colon notation is a syntactic notation used only in the gSOAP header file
11241 syntax, it is not translated to the C/C++ output.
11243 The colon notation does not avoid name clashes between members. For example:
11253 results in a redefinition error, since both members have the same name. To avoid name clashes, use a underscore suffix:
11263 Not that the namespace prefix convention can be used instead:
11273 which avoids the name clash. However, the resulting schema is different
11274 since the last example generates a global `name` element definition that is
11275 referenced by the local element.
11277 More specifically, the difference between the namespace prefix convention with double underscores
11278 and colon notation is that the namespace prefix convention generates schema
11279 element/attribute references to elements/attributes at the top level,
11280 while the colon notation only affects the local element/attribute namespace
11281 qualification by form overriding. This is best illustrated by an example:
11293 which generates the following `x.xsd`schema:
11297 <complexType name="record">
11299 <element name="name" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true" form="unqualified"/>
11300 <element name="phone" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true" form="qualified"/>
11301 <element ref="x:fax" minOccurs="0" maxOccurs="1"/>
11302 <element ref="y:zip" minOccurs="0" maxOccurs="1"/>
11305 <element name="fax" type="xsd:string"/>
11309 and the `y.xsd` schema defines contains:
11313 <element name="zip" type="xsd:string"/>
11317 # SOAP/XML Over UDP {#udp}
11319 UDP is a simple, unreliable datagram protocol: UDP sockets are connectionless.
11320 UDP address formats are identical to those used by TCP. In particular UDP
11321 provides a port identifier in addition to the normal Internet address format.
11322 The UDP port space is separate from the TCP port space (i.e. a UDP port may not
11323 be "connected" to a TCP port). In addition broadcast packets may be sent
11324 (assuming the underlying network supports this) by using a reserved "broadcast
11325 address"; this address is network interface dependent.
11327 Client-side messages with SOAP-over-UDP endpoint URLs
11328 (`soap.udp://...`) will be automatically transmitted as datagrams.
11329 Server-side applications should set the `SOAP_IO_UDP` mode flag to
11330 accept UDP requests, e.g. using `soap_init1` or `soap_set_mode`.
11332 The maximum message length for datagram packets is restricted by the buffer
11333 size `SOAP_BUFLEN`, which is 65536 by default, unless
11334 compiled with `WITH_LEAN` to support small-scale embedded systems.
11335 For UDP transport `SOAP_BUFLEN` must not exceed the maximum UDP packet size
11336 65536 (the size of datagram messages is constrained by the
11337 UDP packet size 2^16=65536 as per UDP standard). You can use gzip compression
11338 to reduce the message size, but note that compressed SOAP-over-UDP is a
11339 gSOAP-specific feature because it is not part of the SOAP-over-UDP
11342 The SOAP-over-UDP specification relies on WS-Addressing. The `wsa.h`
11343 file in the `import` directory defines the WS-Addressing elements for
11344 client and server applications.
11346 The gSOAP implementation conforms to the SOAP-over-UDP requirements:
11349 * SOAP-over-UDP server endpoint URL format: *soap.udp://host:port/path*
11351 * Support one-way message-exchange pattern (MEP) where a SOAP envelope is
11352 carried in a user datagram.
11354 * Support request-response message-exchange pattern (MEP) where SOAP envelopes
11355 are carried in user datagrams.
11357 * Support multicast transmission of SOAP envelopes carried in user datagrams.
11359 * Support both SOAP 1.1 and SOAP 1.2 envelopes.
11361 The following additional features are also available, but are not supported by the SOAP-over-UDP specification:
11364 * Zlib/gzip message compression (compile `-DWITH_GZIP`).
11366 * SOAP with DIME attachments over UDP.
11368 * SOAP with MIME attachments (SwA) over UDP.
11370 * Support for IPv6 (compile `-DWITH_IPV6`)
11373 ## Using WS-Addressing with SOAP-over-UDP {#udp.h}
11375 A SOAP-over-UDP application MUST use WS-Addressing to control message delivery
11376 as per SOAP-over-UDP specification.
11378 The `wsa.h` file in the `import` directory defines the
11379 WS-Addressing elements. To include the WS-Addressing elements in the SOAP
11380 Header for messaging, a `struct SOAP_ENV__Header` structure must be
11381 defined in your header file with the appropriate WS-Addressing elements.
11386 struct SOAP_ENV__Header
11388 mustUnderstand _wsa__MessageID wsa__MessageID 0;
11389 mustUnderstand _wsa__RelatesTo *wsa__RelatesTo 0;
11390 mustUnderstand _wsa__From *wsa__From 0;
11391 mustUnderstand _wsa__ReplyTo *wsa__ReplyTo 0;
11392 mustUnderstand _wsa__FaultTo *wsa__FaultTo 0;
11393 mustUnderstand _wsa__To wsa__To 0;
11394 mustUnderstand _wsa__Action wsa__Action 0;
11398 We also included a `//gsoap wsa schema import` directive in the `wsa.h` file to enable the generation of WSDL
11399 specifications that import (instead of includes) the WS-Addressing elements.
11400 Note that the `//gsoapopt w` directive must not be present in your header file to enable WSDL generation.
11402 One-way SOAP-over-UDP messages (see Section \ref oneway1 ) should be
11403 declared to include the `wsa:MessageID`, `wsa:To`, and `wsa:Action`
11404 elements in the SOAP Header of the request message as follows:
11407 //gsoap ns service method-header-part: sendString wsa__MessageID
11408 //gsoap ns service method-header-part: sendString wsa__To
11409 //gsoap ns service method-header-part: sendString wsa__Action
11410 int ns__sendString(char *str, void);
11413 Request-response SOAP-over-UDP messages should be declared to include the
11414 `wsa:MessageID`, `wsa:To`, `wsa:Action`, and `wsa:ReplyTo`
11415 elements in the SOAP Header of the request message, and the the
11416 `wsa:MessageID`, `wsa:To`, `wsa:Action`, and `wsa:RelatesTo`
11417 elements in the SOAP Header of the response message:
11420 //gsoap ns service method-header-part: echoString wsa__MessageID
11421 //gsoap ns service method-header-part: echoString wsa__To
11422 //gsoap ns service method-header-part: echoString wsa__Action
11423 //gsoap ns service method-input-header-part: sendString wsa__ReplyTo
11424 //gsoap ns service method-output-header-part: echoString wsa__RelatesTo
11425 int ns__echoString(char *str, char **res);
11428 For the content requirements of these elements, please consult the
11429 SOAP-over-UDP specification and/or read the next sections explaining
11430 SOAP-over-UDP unicast, multicast, one-way, and request-response client and
11431 server applications.
11433 ## Client-side One-way Unicast
11435 This example assumes that the gSOAP header file includes the SOAP Header with
11436 WS-Addressing elements and the `ns__sendString` function discussed in
11441 struct SOAP_ENV__Header header; // the SOAP Header
11443 soap.send_timeout = 5; // 5 seconds max socket delay
11444 soap_default_SOAP_ENV__Header(&soap, &header); // init SOAP Header
11445 header.wsa__MessageID = "*message ID*";
11446 header.wsa__To = "*server URL*";
11447 header.wsa__Action = "*server action*";
11448 soap.header = &header; // bind the SOAP Header for transport
11449 // Send the message over UDP:
11450 if (soap_send_ns__echoString(&soap, "soap.udp://...", NULL, "hello world!"))
11451 soap_print_fault(&soap, stderr); // report error
11452 soap_end(&soap); // cleanup
11453 soap_destroy(&soap); // cleanup
11454 soap_done(&soap); // close connection (should not use soap struct after this)
11457 ## Client-side One-way Multicast
11459 This example is similar to the one-way unicast example discussed above, but
11460 uses a broadcast address and the `SO_BROADCAST` socket option:
11464 struct SOAP_ENV__Header header; // the SOAP Header
11465 in_addr_t addr = inet_addr("1.2.3.4"); // optional
11467 soap.send_timeout = 5; // 5 seconds max socket delay \
11468 soap.connect_flags = SO_BROADCAST; // required for broadcast
11469 soap.ipv4_multicast_if = &addr; // optional for IPv4: see setsockopt IPPROTO_IP IP_MULTICAST_IF
11470 soap.ipv6_multicast_if = addr; // optional for IPv6: multicast sin6_scope_id
11471 soap.ipv4_multicast_ttl = 1; // optional, see setsockopt IPPROTO_IP, IP_MULTICAST_TTL
11472 soap_default_SOAP_ENV__Header(&soap, &header); // init SOAP Header
11473 header.wsa__MessageID = "*message ID*";
11474 header.wsa__To = "*server URL*";
11475 header.wsa__Action = "*server action*";
11476 soap.header = &header; // bind the SOAP Header for transport
11477 // Send the message over UDP to a broadcast address:
11478 if (soap_send_ns__echoString(&soap, "soap.udp://...", NULL, "hello world!"))
11479 soap_print_fault(&soap, stderr); // report error
11480 soap_destroy(&soap); // cleanup
11481 soap_end(&soap); // cleanup
11482 soap_done(&soap); // close connection (should not use soap struct after this)
11485 Please refer to the socket options for `IPPROTO_IP IP_MULTICAST_IF`
11487 the default interface for multicast datagrams to be sent from. This
11488 is a `struct in_addr` (`in_addr_t` for `sin6_scope_id`)
11489 interface value. Otherwise, the default interface set by the system
11490 administrator will be used (if any).
11492 Please refer to the socket options for `IPPROTO_IP IP_MULTICAST_TTL` to limit
11493 the lifetime of the packet. Multicast datagrams are sent with a default value
11494 of 1, to prevent them to be forwarded beyond the local network. This parameter
11495 can be set between 1 to 255.
11497 ## Client-side Request-Response Unicast
11499 This example assumes that the gSOAP header file includes the SOAP Header with
11500 WS-Addressing elements and the `ns__echoString` function discussed in
11505 struct SOAP_ENV__Header header; // the SOAP Header
11506 struct wsa__EndpointReferenceType replyTo; // (anonymous) reply address
11507 char *res; // server response
11509 soap.send_timeout = 5; // 5 seconds max socket delay
11510 soap.recv_timeout = 5; // 5 seconds max socket delay
11511 soap_default_SOAP_ENV__Header(&soap, &header); // init SOAP Header
11512 soap_default_wsa__EndpointReferenceType(&soap, &replyTo); // init reply address
11513 replyTo.Address = "http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous";
11514 header.wsa__MessageID = "*message ID*";
11515 header.wsa__To = "*server URL*";
11516 header.wsa__Action = "*server action*";
11517 header.wsa__ReplyTo = &replyTo;
11518 soap.header = &header; // bind the SOAP Header for transport
11519 // Send and receive messages over UDP:
11520 if (soap_call_ns__echoString(&soap, "soap.udp://...", NULL, "hello world!", &res))
11522 if (soap.error == SOAP_EOF && soap.errnum == 0)
11523 // Timeout: no response from server (message already delivered?)
11525 soap_print_fault(&soap, stderr);
11528 // UDP server response is stored in 'res'
11529 // check SOAP header received, if applicable
11530 check_header(&soap.header);
11531 soap_destroy(&soap); // cleanup
11532 soap_end(&soap); // cleanup
11533 soap_done(&soap); // close connection (should not use soap struct after this)
11536 ## Client-side Request-Response Multicast
11538 This example is similar to the request-response unicast example discussed
11539 above, but uses a broadcast address and the `SO_BROADCAST` socket option.
11540 Because we expect to receive multiple responses, we also need to use separate
11541 request-response messages to send one request and consume multiple responses.
11542 In this example we defined a `bcastString` request and a
11543 `bcastStringResponse` response message, which are essentially declared as
11544 one-way messages in the header file:
11547 //gsoap ns service method-header-part: bcastString wsa__MessageID
11548 //gsoap ns service method-header-part: bcastString wsa__To
11549 //gsoap ns service method-header-part: bcastString wsa__Action
11550 //gsoap ns service method-header-part: bcastString wsa__ReplyTo
11551 int ns__bcastString(char *str, void);
11552 //gsoap ns service method-header-part: bcastStringResponse wsa__MessageID
11553 //gsoap ns service method-header-part: bcastStringResponse wsa__To
11554 //gsoap ns service method-header-part: bcastStringResponse wsa__Action
11555 //gsoap ns service method-header-part: bcastStringResponse wsa__RelatesTo
11556 int ns__bcastStringResponse(char *res, void);
11559 To obtain response one-way operations, use the wsdl2h `-b` option.
11561 The client code includes a loop to receive response messages until a timeout occurs:
11565 struct SOAP_ENV__Header header;
11566 struct wsa__EndpointReferenceType replyTo;
11569 soap.connect_flags = SO_BROADCAST;
11570 soap.send_timeout = 5; // 5 seconds max socket delay
11571 soap.recv_timeout = 5; // 5 seconds max socket delay
11572 soap_default_SOAP_ENV__Header(&soap, &header);
11573 soap.header = &header;
11574 soap_default_wsa__EndpointReferenceType(&soap, &replyTo);
11575 replyTo.Address = "http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous";
11576 header.wsa__MessageID = "*message ID*";
11577 header.wsa__To = "*server URL*";
11578 header.wsa__Action = "*server action*";
11579 header.wsa__ReplyTo = &replyTo;
11580 if (soap_send_ns__bcastString(&soap, "soap.udp://...", NULL, "hello world!"))
11581 soap_print_fault(&soap, stderr);
11586 if (soap_recv_ns__bcastStringResponse(&soap, &res))
11588 // Got response 'res' from a server
11590 if (soap.error == SOAP_EOF && soap.errnum == 0)
11591 // Timeout: no more messages received
11593 soap_print_fault(&soap, stderr);
11595 soap_destroy(&soap); // cleanup
11596 soap_end(&soap); // cleanup
11597 soap_done(&soap); // close connection (should not use soap struct after this)
11600 Note that a server for the `bcastString` does not need to use two-one way
11601 messages. Thus, multicast request-response message pattern can be declared and
11602 implemented as request-response operations at the server side.
11604 ## SOAP-over-UDP Server {#soapoverudp}
11606 The following example code illustrates a SOAP-over-UDP server for one-way `sendString` and request-response `echoString` messages.
11607 This example assumes that the gSOAP header file includes the SOAP Header with
11608 WS-Addressing elements and the `ns__echoString` function discussed in
11609 Section \ref udp.h .
11615 soap_init1(&soap, SOAP_IO_UDP); // must set UDP flag
11616 // bind to host (NULL=current host) and port:
11617 if (!soap_valid_socket(soap_bind(&soap, host, port, 100)))
11619 soap_print_fault(&soap, stderr);
11624 if (soap_serve(&soap))
11625 soap_print_fault(&soap, stderr); // report the problem
11626 soap_destroy(&soap);
11629 soap_done(&soap); // close connection
11631 int ns__echoString(struct soap *soap, char *str, char **res)
11634 return soap_sender_fault(soap, "No SOAP header", NULL);
11635 if (!soap->header->wsa__MessageID)
11636 return soap_sender_fault(soap, "No WS-Addressing MessageID", NULL);
11637 soap->header->wsa__RelatesTo = (struct wsa__Relationship*)soap_malloc(soap, sizeof(struct wsa__Relationship));
11638 soap_default_wsa__Relationship(soap, soap->header->wsa__RelatesTo);
11639 soap->header->wsa__RelatesTo->__item = soap->header->wsa__MessageID;
11640 // must check for duplicate messages
11641 if (check_received(soap->header->wsa__MessageID))
11643 // Request message already received
11644 return SOAP_STOP; // don't return response
11646 if (!soap->header->wsa__ReplyTo || !soap->header->wsa__ReplyTo->Address)
11647 return soap_sender_fault(soap, "No WS-Addressing ReplyTo address", NULL);
11648 soap->header->wsa__To = soap->header->wsa__ReplyTo->Address;
11649 soap->header->wsa__MessageID = soap_strdup(soap, soap_int2s(soap, id_count++)) ;
11650 soap->header->wsa__Action = "http://genivia.com/udp/echoStringResponse";
11654 int ns__sendString(struct soap *soap, char *str)
11658 if (!soap->header->wsa__MessageID)
11660 // must check for duplicate messages
11661 if (check_received(soap->header->wsa__MessageID))
11665 int ns__sendStringResponse(struct soap *soap, char *res)
11666 { return SOAP_NO_METHOD; } // we don't expect to serve this message
11669 The server binds to a host and port and accepts messages in a tight sequential
11670 loop. Because UDP does not have the equivalent of an accept the messages
11671 cannot be dispatched to threads, the `soap_serve` waits for a message and
11672 immediately accepts it. You can use a receive timeout to make `soap_serve`
11675 To obtain response one-way operations from a WSDL, use the wsdl2h `-b` option. This produces additional one-way operations to support asynchronous handling of response messages in the same way requests are handled.
11677 ## SOAP-over-UDP Multicast Receiving Server
11679 For UDP multicast support, follow the suggestions in
11680 Section \ref soapoverudp and change the initialization parts of the code
11681 to enable UDP multicast port binding by to telliing the kernel which multicast
11682 groups you are interested in:
11688 struct ip_mreq mcast;
11689 soap_init1(&soap, SOAP_IO_UDP);
11690 if (!soap_valid_socket(soap_bind(&soap, host, port, 100)))
11692 soap_print_fault(&soap, stderr);
11695 mcast.imr_multiaddr.s_addr = inet_addr("{\tt put IP multicast address of group here}");
11696 mcast.imr_interface.s_addr = htonl(INADDR_ANY);
11697 if (setsockopt(soap.master, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mcast, sizeof(mcast))<0)
11701 # Advanced Features {#advanced}
11703 ## Internationalization
11705 gSOAP uses regular strings by default. Regular strings cannot be used to hold
11706 UCS characters outside of the character range [1,255]. gSOAP can handle
11707 wide-character content in two ways. First, applications can utilize
11708 wide-character strings (`wchar_t*`) instead of regular strings to store
11709 wide-character content. For example, the *`xsd:string`* string schema type
11710 can be declared as a wide-character string and used subsequently:
11713 typedef wchar_t *xsd__string;
11715 int ns__myMethod(xsd__string input, xsd__string *output);
11718 Second, regular strings can be used to hold wide-character content in UTF-8
11719 format. This is accomplished with the `SOAP_C_UTFSTRING` flag (for both input/output mode), see Section \ref flags .
11720 With this flag set, gSOAP will deserialize XML into
11721 regular strings in UTF-8 format. An application is responsible for filling
11722 regular strings with UTF-8 content to ensure that strings can be correctly serialized XML.
11723 Third, the `SOAP_C_MBSTRING` flag (for both input/output mode) can be used to activate multibyte character support. Multibyte support depends on the locale settings for dealing with extended natural language encodings.
11725 Both regular strings and wide-character strings can be used together within an application.
11726 For example, the following header file declaration introduces two string schema types:
11729 typedef wchar_t *xsd__string;
11730 typedef char *xsd__string_; // trailing '_' avoids name clash
11732 int ns__myMethod(xsd__string input, xsd__string_ *output);
11735 The `input` string parameter is a wide-character string and the `output` string
11736 parameter is a regular string. The regular string has UCS character content
11737 in the range [1,255] unless the
11738 `SOAP_C_UTFSTRING` flag is set. With this flag, the string has UTF-8
11741 Please consult the UTF-8 specification for details on the UTF-8 format.
11742 Note that the ASCII character set [1-127] is a subset of UTF-8. Therefore, with the `SOAP_C_UTFSTRING` flag set, strings may hold ASCII character data and UTF-8 extensions.
11744 ## Customizing the WSDL and Namespace Mapping Table File Contents With gSOAP Directives {#directives}
11746 A header file can be augmented with directives for the gSOAP `soapcpp2` tool to automatically generate customized WSDL and namespace mapping tables contents. The WSDL and namespace mapping table files do not need to be modified by hand (Sections \ref wsdl and \ref nstable ).
11747 In addition, the sample SOAP/XML request and response files generated by the compiler are valid provided that XML Schema namespace
11748 information is added to the header file with directives so that the gSOAP `soapcpp2` compiler can produce example SOAP/XML messages that are correctly namespace qualified.
11749 These compiler directive are specified as `//`-comments.
11750 (Note: blanks can be used anywhere in the directive, except between `//` and `gsoap`.)
11752 Three directives are currently supported that can be used to specify details associated with namespace prefixes used by the service operation
11753 names in the header file.
11754 To specify the name of a Web Service in the header file, use:
11757 //gsoap *namespace-prefix* service name: *service-name*
11760 where *namespace-prefix* is a namespace prefix used by identifiers in the header file and *service-name* is the name
11761 of a Web Service (only required to create new Web Services).
11762 The name may be followed by text up to the end of the line which is incorporated into the WSDL service documentation. Alternatively, the service documentation can be provided with the directive below.
11764 To specify the name of the WSDL definitions in the header file, use:
11767 //gsoap *namespace-prefix* service definitions: *definitions-name*
11770 where *namespace-prefix* is a namespace prefix used by identifiers in the header file and *definitions-name* is the name of the WSDL definitions. By default, the WSDL definitions name is the same as the service name.
11772 To specify the documentation of a Web Service in the header file, use:
11775 //gsoap *namespace-prefix* service documentation: *text*
11781 //gsoap *namespace-prefix* service doc: *text*
11784 where *namespace-prefix* is a namespace prefix used by identifiers in the header file and *text* is the documentation text up to the end of the line.
11785 The text is incorporated into the WSDL service documentation.
11787 To specify the portType of a Web Service in the header file, use:
11790 //gsoap *namespace-prefix* service portType: *portType-name*
11796 //gsoap *namespace-prefix* service type: *portType-name*
11799 or using WSDL 2.0 terms
11802 //gsoap *namespace-prefix* service interface: *portType-name*
11805 where *namespace-prefix* is a namespace prefix used by identifiers in the header file and *portType-name* is the portType name of the WSDL service portType.
11807 To specify the port name of a Web Service in the header file, use:
11810 //gsoap *namespace-prefix* service portName: *port-name*
11813 where *namespace-prefix* is a namespace prefix used by identifiers in the header file and *port-name* is the name of the WSDL service port element. By default, the port name is the same as the service name.
11815 To specify the binding name of a Web Service in the header file, use:
11818 //gsoap *namespace-prefix* service binding: *binding-name*
11821 where *namespace-prefix* is a namespace prefix used by identifiers in the header file and *binding-name* is the binding name of the WSDL service binding element. By default, the binding name is the same as the service name.
11823 To specify the binding's transport protocol of a Web Service in the header file, use:
11826 //gsoap *namespace-prefix* service transport: *transport-URL*
11829 where *namespace-prefix* is a namespace prefix used by identifiers in the header file and *transport-URL* is the URL of the transport protocol such as `http://schemas.xmlsoap.org/soap/http` for HTTP. HTTP transport is assumed by default.
11831 To specify the location (or port endpoint) of a Web Service in the header file, use:
11834 //gsoap *namespace-prefix* service location: *URL*
11840 //gsoap *namespace-prefix* service endpoint: *URL*
11846 //gsoap *namespace-prefix* service port: *URL*
11849 where *URL* is the location of the Web Service (only required to create new Web Services).
11850 The *URL* specifies the path to the service executable (so URL/service-executable
11851 is the actual location of the executable when declared).
11853 To specify the name of the executable of a Web Service in the header file, use:
11856 //gsoap *namespace-prefix* service executable: *executable-name*
11859 where *executable-name* is the name of the executable of the Web Service.
11861 When doc/literal encoding is required for the entire service, the service encoding can be specified in the header file as follows:
11864 //gsoap *namespace-prefix* service encoding: literal
11867 or when the *`SOAP-ENV:encodingStyle`* attribute is different from the SOAP 1.1/1.2 encoding style:
11870 //gsoap *namespace-prefix* service encoding: *encoding-style*
11873 To specify the namespace URI of a Web Service in the header file, use:
11876 //gsoap *namespace-prefix* service namespace: *namespace-URI*
11879 where *namespace-URI* is the URI associated with the namespace prefix.
11881 In addition, the schema namespace URI can be specified in the header file:
11884 //gsoap *namespace-prefix* schema namespace: *namespace-URI*
11887 where *namespace-URI* is the schema URI associated with the namespace prefix.
11888 If present, it defines the schema-part of the generated WSDL file and the URI in the namespace mapping table.
11889 This declaration is useful when the service declares its own data types that need to be associated with a namespace.
11890 Furthermore, the header file for client applications do not need the full service details and the specification of the schema
11891 namespaces for namespace prefixes suffices.
11892 In addition, a second namespace can be defined that is only used to match the namespaces of inbound XML:
11895 //gsoap *namespace-prefix* schema namespace2: *namespace-URI-pattern*
11898 If the first namespace does not match the inbound parsed XML, then the second
11899 will be tried. This pattern may contain `*` multichar wildcards and `-` single
11900 chard wildcards. This allows two or more namespace versions to be handled by
11901 the same namespace prefix.
11903 The directive above specifies a new schema and the gSOAP `soapcpp2` compiler generates a schema files (.xsd) file for the schema.
11904 An existing schema namespace URI can be imported with:
11907 //gsoap *namespace-prefix* schema import: *namespace-URI*
11910 where *namespace-URI* is the schema URI associated with the namespace prefix.
11911 gSOAP does not produce XML Schema files for imported schemas and imports the schema namespaces in the generated WSDL file.
11913 A schema namespace URI can be imported from a location with:
11916 //gsoap *namespace-prefix* schema namespace: *namespace-URI*
11917 //gsoap *namespace-prefix* schema import: *schema-location*
11920 The elementFormDefault and attributeFormDefault qualification of a schema can be defined with:
11923 //gsoap *namespace-prefix* schema elementForm: qualified
11924 //gsoap *namespace-prefix* schema attributeForm: qualified
11930 //gsoap *namespace-prefix* schema elementForm: unqualified
11931 //gsoap *namespace-prefix* schema attributeForm: unqualified
11934 A shortcut to define the default qualification of elements and attributes of a schema:
11937 //gsoap *namespace-prefix* schema form: qualified
11943 //gsoap *namespace-prefix* schema form: unqualified
11946 To include *`xsi:type`* attributes in the runtime XML element output for specific schemas, use:
11949 //gsoap *namespace-prefix* schema typed: yes
11952 Note that `soapcpp2 -t` enables *`xsi:type`* for all elements in the runtime XML output.
11954 To document a data type, use:
11957 //gsoap *namespace-prefix* schema type-documentation: *type-name* //*text*
11963 //gsoap *namespace-prefix* schema type: *type-name* //*text*
11966 where *type-name* is the unqualified name of the data type and *text*
11967 is a line of text terminated by a newline. Do not use any XML reserved
11968 characters in *text* such as `<` and `>`. Use well-formed XML and XHTML markup instead.
11972 //gsoap ns schema type: tdata stores <a href="transaction.html">transaction</a> data
11977 To document a data type's fields and members, use:
11980 //gsoap *namespace-prefix* schema type-documentation: *type-name::field* //*text*
11986 //gsoap *namespace-prefix* schema type: *type-name::field* //*text*
11989 where *type-name* is the unqualified name of the data type, *field* is a field, member, or enum name, and *text*
11990 is a line of text terminated by a newline. Do not use any XML reserved
11991 characters in *text* such as `<` and `>`. Use well-formed XML and XHTML markup instead.
11995 //gsoap ns schema type: tdata::id the transaction number
11996 //gsoap ns schema type: tdata::state transaction state
11997 //gsoap ns schema type: tstate::INIT initial state
11998 //gsoap ns schema type: tstate::DONE final state
12002 enum ns__tstate { INIT, DONE } state;
12007 The documentation form above can also be used to document SOAP/XML message
12008 parts in the generated WSDL. For the type-name use the function name. For the field names, you can use the function name and/or the function argument names.
12010 To document a method, use:
12013 //gsoap *namespace-prefix* service method-documentation: *method-name* *text*
12019 //gsoap *namespace-prefix* service method: *method-name* *text*
12022 where *method-name* is the unqualified name of the method and *text*
12023 is a line of text terminated by a newline. Do not use any XML reserved
12024 characters in *text* such as < and >. Use well-formed XML and XHTML markup instead.
12028 //gsoap ns service method: getQuote returns a <i>stock quote</i>
12029 int ns__getQuote(char *symbol, float &_result);
12032 To specify the SOAP Action for a SOAP method, use:
12035 //gsoap *namespace-prefix* service method-action: *method-name* *action*
12038 where *method-name* is the unqualified name of the method and *action*
12039 is a string without spaces and blanks (the string can be quoted when preferred).
12043 //gsoap ns service method-action: getQuote ""
12044 int ns__getQuote(char *symbol, float &_result);
12047 Or, alternatively for the input action (part of the request):
12050 //gsoap ns service method-input-action: getQuote ""
12051 int ns__getQuote(char *symbol, float &_result);
12054 To specify the HTTP "location" of REST methods to a perform POST/GET/PUT action, use:
12057 //gsoap *namespace-prefix* service method-action: *method-name* *action*
12060 where *method-name* is the unqualified name of the method and *action*
12061 is a string without spaces and blanks (the string can be quoted when preferred).
12062 This directive requires that the `protocol:` directive for this method is set to HTTP, POST, GET, or PUT.
12064 A response action and fault action are defined by:
12067 //gsoap *namespace-prefix* service method-output-action: *method-name* *action*
12068 //gsoap *namespace-prefix* service method-fault-action: *method-name* *action*
12071 To override the SOAP or REST protocol of an operation (SOAP by default), use:
12074 //gsoap *namespace-prefix* service method-protocol: *method-name* *protocol*
12077 where *protocol* is one of
12079 *protocol* | result
12080 ------------- | ------
12081 `SOAP` | default SOAP transport (supports 1.1 and 1.2)
12082 `SOAP1.1` | SOAP 1.1 only
12083 `SOAP1.2` | SOAP 1.2 only
12084 `SOAP-GET` | one-way SOAP with HTTP GET
12085 `SOAP1.1-GET` | one-way SOAP 1.1 with HTTP GET
12086 `SOAP1.2-GET` | one-way SOAP 1.2 with HTTP GET
12087 `HTTP` | REST HTTP (POST or one-way PUT)
12088 `POST` | REST HTTP POST
12089 `GET` | one-way REST HTTP GET
12090 `PUT` | one-way REST HTTP PUT
12091 `DELETE` | REST HTTP DELETE
12093 When document style is preferred for a particular service method, use:
12096 //gsoap *namespace-prefix* service method-style: *method-name* document
12099 When SOAP RPC encoding is required for a particular service method, use:
12102 //gsoap *namespace-prefix* service method-encoding: *method-name* encoded
12105 When literal encoding is required for a particular service method, use:
12108 //gsoap *namespace-prefix* service method-encoding: *method-name* literal
12111 or when the *`SOAP-ENV:encodingStyle`* attribute is different from the SOAP 1.1/1.2 encoding style, use:
12114 //gsoap *namespace-prefix* service method-encoding: *method-name* *encoding-style*
12117 When SOAP RPC encoding is required for a particular service method response when the request message is literal, use:
12120 //gsoap *namespace-prefix* service method-response-encoding: *method-name* encoded
12123 When literal encoding is required for a particular service method response when the request message is encoded, use:
12126 //gsoap *namespace-prefix* service method-response-encoding: *method-name* literal
12129 or when the *`SOAP-ENV:encodingStyle`* attribute is different from the SOAP 1.1/1.2 encoding style, use:
12132 //gsoap *namespace-prefix* service method-response-encoding: *method-name* *encoding-style*
12135 Note that the `method-response-encoding` is set to the value of `method-encoding` by default.
12137 When header processing is required, each method declared in the WSDL should provide a binding to the parts of the header that may
12138 appear as part of a method request message. Such a binding is given by:
12141 //gsoap *namespace-prefix* service method-header-part: *method-name* *header-part*
12147 struct SOAP_ENV__Header
12149 char *h__transaction;
12150 struct UserAuth *h__authentication;
12154 Suppose method `ns__login` uses both header parts (at most), then this is declared as:
12157 //gsoap ns service method-header-part: login h__transaction
12158 //gsoap ns service method-header-part: login h__authentication
12159 int ns__login(...);
12162 Suppose method `ns__search` uses only the first header part, then this is declared as:
12165 //gsoap ns service method-header-part: search h__transaction
12166 int ns__search(...);
12169 Note that the method name and header part names MUST be namespace qualified.
12170 The headers MUST be present in all operations that declared the header parts.
12172 To specify the header parts for the method input (method request message), use:
12175 //gsoap *namespace-prefix* service method-input-header-part: *method-name* *header-part*
12178 Similarly, to specify the header parts for the method output (method response message), use:
12181 //gsoap *namespace-prefix* service method-output-header-part: *method-name* *header-part*
12184 The declarations only affect the WSDL.
12188 struct SOAP_ENV__Header
12190 char *h__transaction;
12191 struct UserAuth *h__authentication;
12193 //gsoap ns service method-input-header-part: login h__authentication
12194 //gsoap ns service method-input-header-part: login h__transaction
12195 //gsoap ns service method-output-header-part: login h__transaction
12196 int ns__login(...);
12199 The headers MUST be present in all operations that declared the header parts.
12201 When SOAP Faults include custom fault information, the SOAP Fault detail element contains one or more elements with this information. Assuming that the SOAP Fault detail structure contains one or more members that correspond to the optional detail elements, a method may be associated with one or more of these members by using:
12204 //gsoap *namespace-prefix* service method-fault: *method-name* *fault-detail*
12207 The declarations only affect the WSDL.
12211 struct SOAP_ENV__Header
12213 char *h__transaction;
12214 struct UserAuth *h__authentication;
12216 //gsoap ns service method-fault: login f__invalid
12217 //gsoap ns service method-fault: login f__unavailable
12218 int ns__login(...);
12221 The fault members MUST be present in the `SOAP_ENV__Detail` structure, for example, `f__invalid` must be a pointer-based member of the `SOAP_ENV__Detail` struct, see Section \ref fault . Alternatively to adding members to the structure, use the `__type` field that can be set to point to an object that is serialized as the SOAP Fault detail element.
12223 To specify MIME attachments for the method input and output (method request and response messages), use:
12226 //gsoap *namespace-prefix* service method-mime-type: *method-name* *mime-type*
12229 You can repeat this directive for all multipartRelated MIME attachments you want to associate with the method.
12231 To specify MIME attachments for the method input (method request message), use:
12234 //gsoap *namespace-prefix* service method-input-mime-type: *method-name* *mime-type*
12237 Similarly, to specify MIME attachments for the method output (method response message), use:
12240 //gsoap *namespace-prefix* service method-output-mime-type: *method-name* *mime-type*
12243 You can repeat these directives for all multipartRelated MIME attachments you want to associate with the method.
12247 The use of directives is best illustrated with an example. The example uses a
12248 hypothetical stock quote service and exchange rate service, actual services
12249 such as these are available for free on the web.
12252 //gsoap ns1 service namespace: urn:GetQuote
12253 int ns1__getQuote(char *symbol, float &result);
12255 //gsoap ns2 service namespace: urn:CurrencyExchange
12256 int ns2__getRate(char *country1, char *country2, float &result);
12258 //gsoap ns3 service name: quotex
12259 //gsoap ns3 service style: rpc
12260 //gsoap ns3 service encoding: encoded
12261 //gsoap ns3 service port: http://www.mydomain.com/quotex.cgi
12262 //gsoap ns3 service namespace: urn:quotex
12263 int ns3__getQuote(char *symbol, char *country, float &result);
12266 The `quotex.h` example is a new Web Service created by combining two existing Web Services:
12267 a Stock Quote service and a Currency Exchange service.
12269 Namespace prefix `ns3` is used for the new `quotex` Web Service with namespace URI `urn:quotex`,
12270 service name `quotex`, and endpoint port `http://www.mydomain.com/quotex.cgi`.
12272 Since the new Web Service invokes the `ns1__getQuote` and `ns2__getRate` service operations,
12273 the service namespaces and other details such as style and encoding of these methods are given by directives.
12274 After invoking the gSOAP `soapcpp2` tool on the `quotex.h` header file:
12276 > soapcpp2 quotex.h
12278 the WSDL of the new `quotex` Web Service is saved as `quotex.wsdl`.
12279 Since the service name, endpoint port, and namespace URI
12280 were provided in the header file, the generated WSDL file can be published
12281 together with the compiled Web Service installed as a CGI application.
12283 The namespace mapping table for the `quotex.cpp` Web Service implementation
12284 is saved as `quotex.nsmap`. This file can be directly included in
12285 `quotex.cpp` instead of specified by hand in the source of
12289 #include "quotex.nsmap"
12292 The automatic generation and inclusion of the namespace mapping table requires
12293 compiler directives for **all** namespace prefixes to associate each
12294 namespace prefix with a namespace URI. Otherwise, namespace URIs have to be
12295 manually added to the table (they appear as `http://tempuri.org`).
12297 ## Transient Data Types {#transient}
12299 There are situations when certain data types have to be ignored by gSOAP for
12300 the compilation of (de)marshalling routines. For example, in certain cases
12301 only a few members of a class or struct need not be (de)serialized, or the base
12302 class of a derived class should not be (de)serialized. Certain built-in classes
12303 such as `ostream` cannot be (de)serialized. Data parts that should be kept
12304 invisible to gSOAP are called "transient". Transient data types and
12305 transient struct/class members are declared with the `\extern` keyword or
12306 are declared within `[` and `]` blocks in the header file. The
12307 `\extern` keyword has a special meaning to the gSOAP `soapcpp2` compiler and won't
12308 affect the generated codes. The special `[` and `]` block construct
12309 can be used with data type declarations and within `struct` and
12310 `class` declarations. The use of `\extern` or `[ ]` achieve the
12311 same effect, but `[ ]` may be more convenient to encapsulate transient
12312 types in a larger part of the header file. The use of `\extern` with
12313 `typedef` is reserved for the declaration of user-defined external
12314 (de)serializers for data types, see Section \ref extern .
12319 extern class ostream; // ostream can't be (de)serialized, but need to be declared to make it visible to gSOAP
12322 virtual void print(ostream &s) const; // need ostream here
12331 class myBase // base class need not be (de)serialized
12334 class ns__myDerived : myBase
12341 [ typedef int transientInt; ]
12344 int a; // will be (de)serialized
12346 int b; // transient field
12347 char s[256]; // transient field
12349 extern float d; // transient field
12350 char *t; // will be (de)serialized
12351 transientInt *n; // transient field
12353 virtual void method(char buf[1024]); // does not create a char[1024] (de)serializer
12358 In this example, `class ns__myClass` has three transient fields:
12359 `b`, `s`, and `n` which will not be (de)serialized in SOAP. Field
12360 `n` is transient because the type is declared within a transient block.
12361 Pointers, references, and arrays of transient types are transient. The single
12362 class method is encapsulated within `[` and `]` to prevent gSOAP from
12363 creating (de)serializers for the `char[1024]` type. gSOAP will generate
12364 (de)serializers for all types that are not declared within a `[` and
12365 `]` transient block.
12367 ## Serialization "{as is" with Volatile Data Types} {#volatile}
12369 Volatile-declared data types in gSOAP are assumed to be part of an
12370 existing non-modifiable software package, such as a built-in library. It would
12371 not make sense to redefine the data types in a gSOAP header file. In certain
12372 cases it could also be problematic to have classes augmented with serializer
12373 methods. When you need to (de)serialize such data types "as is", you must
12374 declare them in a gSOAP header file and use the `volatile` qualifier.
12376 Consider for example `struct tm`, declared in `time.h`. The structure may actually vary between platforms, but the tm structure includes at least the following fields:
12381 int tm_sec; /* seconds (0 - 60) */
12382 int tm_min; /* minutes (0 - 59) */
12383 int tm_hour; /* hours (0 - 23) */
12384 int tm_mday; /* day of month (1 - 31) */
12385 int tm_mon; /* month of year (0 - 11) */
12386 int tm_year; /* year - 1900 */
12387 int tm_wday; /* day of week (Sunday = 0) */
12388 int tm_yday; /* day of year (0 - 365) */
12389 int tm_isdst; /* is summer time in effect? */
12390 char *tm_zone; /* abbreviation of timezone name */
12391 long tm_gmtoff; /* offset from UTC in seconds */
12395 Note that we qualified the structure `volatile` in the gSOAP header file to inform the gSOAP `soapcpp2` compiler that it should not attempt to redeclare it.
12396 We can now readily serialize and deserialize the tm structure. The following program fragment serializes the local time stored in a tm structure to stdout:
12399 struct soap *soap = soap_new();
12401 time_t T = time(NULL);
12402 struct tm *t = localtime(&T);
12403 struct soap *soap = soap_new();
12404 soap_write_tm(soap, t);
12405 soap_destroy(soap);
12407 soap_free(soap); // detach and free context
12410 It is also possible to serialize the tm fields as XML attributes using the
12411 `@` qualifier, see Section \ref attributes .
12413 If you must produce a schema file, say `time.xsd`, that defines an XML
12414 schema and namespace for the tm struct, you can add a `typedef`
12415 declaration to the header file:
12418 typedef struct tm time__struct_tm;
12421 We used the `typedef` name `time__struct_tm` rather than `time__tm`, because a schema name clash will occur with the latter since taking off
12422 the `time` prefix will result in the same name being used.
12424 Classes should be declared volatile to prevent modification of these classes by ithe gSOAP `soapcpp2` source code output.
12425 Note that gSOAP adds serialization methods to classes to support polymorphism. However,
12426 this is a problem when you can't modify class declarations because they are
12427 part of a non-modifiable software package. The solution is to declare these
12428 classes `volatile`, similar to the tm structure example illustrated above.
12429 You can also use a `typedef` to associate a schema with a class.
12431 ## How to Declare User-Defined Serializers and Deserializers {#extern}
12433 Users can declare their own (de)serializers for specific data types instead of relying on the gSOAP-generated (de)serializers.
12434 To declare a external (de)serializer, declare a type with `extern typedef`. gSOAP will not generate the (de)serializers
12435 for the type name that is declared. For example:
12438 extern typedef char *MyData;
12441 MyData s; // use user-defined (de)serializer for this field
12442 char *t; // use gSOAP (de)serializer for this field
12446 The user is required to supply the following routines for each `extern typedef`'ed name T:
12449 int soap_serialize_T(struct soap *soap, const T *a)
12450 void soap_default_T(struct soap *soap, T *a)
12451 int soap_out_T(struct soap *soap, const char *tag, int id, const T *a, const char *type)
12452 T *soap_in_T(struct soap *soap, const char *tag, T *a, const char *type)
12455 The function prototypes can be found in `soapH.h`.
12457 For example, the (de)serialization of `MyData` can be done with the following code:
12460 int soap_serialize_MyData(struct soap *soap, MyData const*a)
12461 { return SOAP_OK; } // no need to mark this node (for multi-ref and cycle detection)
12462 void soap_default_MyData(struct soap *soap, MyData *a)
12464 int soap_out_MyData(struct soap *soap, const char *tag, int id, MyData const*a, const char *type)
12466 if (soap_element_begin_out(soap, tag, id, type) // print XML beginning tag
12467 || soap_send(soap, *a) // just print the string (no XML conversion)
12468 || soap_element_end_out(soap, tag)) // print XML ending tag
12469 return soap->error;
12472 MyData **soap_in_MyData(struct soap *soap, const char *tag, MyData *a, const char *type)
12474 if (soap_element_begin_in(soap, tag))
12477 a = (MyData*)soap_malloc(soap, sizeof(MyData));
12479 *a = NULL; // xsi:nil element
12480 if (*soap->type && soap_match_tag(soap, soap->type, type))
12482 soap->error = SOAP_TYPE;
12483 return NULL; // type mismatch
12486 a = (MyData**)soap_id_forward(soap, soap->href, a, 0, SOAP_TYPE_MyData, 0, sizeof(MyData), 0, NULL, NULL)
12487 else if (soap->body)
12489 char *s = soap_value(soap); // fill buffer
12490 *a = (char*)soap_malloc(soap, strlen(s)+1);
12493 if (soap->body && soap_element_end_in(soap, tag))
12499 More information on custom (de)serialization is available in the package in the gsoap/custom directory where you can also find several examples of custom serializers.
12500 Note that (de)serializer code requires the use of the low-level gSOAP API that may differ in older gSOAP releases. If in doubt, we recommend to follow the material and examples in gsoap/custom.
12502 ## How to Serialize Data Without Generating xsi:type Attributes
12504 gSOAP serializes data in XML with *`xsi:type`* attributes when the types are
12505 declared with namespace prefixes to indicate the schema type of the data
12506 contained in the elements. SOAP 1.1 and 1.2 requires *`xsi:type`* attributes
12507 in the presence of polymorphic data or when the type of the data cannot be
12508 deduced from the SOAP payload. The namespace prefixes are associated with the
12509 type names of `typedef`s (Section \ref primitive ) for primitive data
12510 types, `struct`/`class` names, and `enum` names.
12512 To prevent the output of these *`xsi:type`* attributes in the XML
12513 serialization, you can simply use type declarations that do not include these
12514 namespace prefixes. That is, don't use the `typedef`s for primitive types
12515 and use unqualified type names with `struct`s, `class`es, and
12518 However, there are two issues. Firstly, if you want to use a primitive schema
12519 type that has no C/C++ counterpart, you must declare it as a `typedef`
12520 name with a leading underscore, as in:
12523 typedef char *_xsd__date;
12526 This will produce the necessary *`xsd:date`* information in the WSDL output
12527 by the gSOAP `soapcpp2` compiler. But the XML serialization of this type at run time
12528 won't include the *`xsi:type`* attribute. Secondly, to include the proper
12529 schema definitions in the WSDL produced by the gSOAP `soapcpp2` compiler, you should
12530 use qualified `struct`, `class`, and `enum` names with a leading
12534 struct _ns__myStruct
12538 This ensures that `myStruct` is associated with a schema, and therefore
12539 included in the appropriate schema in the generated WSDL. The leading
12540 underscore prevents the XML serialization of *`xsi:type`* attributes for this
12541 type in the SOAP/XML payload.
12543 ## Function Callbacks for Customized I/O and HTTP Handling {#callback}
12545 gSOAP provides five callback functions for customized I/O and HTTP handling:
12547 * `SOAP_SOCKET (*soap.fopen)(struct soap *soap, const char *endpoint, const char *host, int port)`
12548 Called from a client proxy to open a connection to a Web Service located at
12549 `endpoint`. Input parameters `host` and `port` are micro-parsed from
12550 `endpoint`. Should return a valid file descriptor, or `SOAP_INVALID_SOCKET`
12551 and `soap->error` set to an error code. Built-in gSOAP function:
12554 * `int (*soap.fclose)(struct soap *soap)`
12555 Called by client proxy **multiple times**, to close a socket connection
12556 before a new socket connection is established and at the end of
12557 communications when the `SOAP_IO_KEEPALIVE` flag is not set and
12558 `soap.keep_alive != 0` (indicating that the other party supports keep
12559 alive). Should return `SOAP_OK`, or a gSOAP error code. Built-in gSOAP
12560 function: `tcp_disconnect`
12562 * `int (*soap.fget)(struct soap *soap)`
12563 Called by the main server loop upon an HTTP GET request. The
12564 `SOAP_GET_METHOD` error is returned by default. This callback can be used to
12565 respond to HTTP GET methods with content, see Section \ref get . Should
12566 return `SOAP_OK`, or a gSOAP error code. Built-in gSOAP function: `http_get`
12568 * `int (*soap.fput)(struct soap *soap)`
12569 Called by the main server loop upon an HTTP PUT request. The
12570 `SOAP_PUT_METHOD` error is returned by default. This callback can be used to
12571 respond to HTTP PUT. Should return `SOAP_OK`, or a gSOAP error code.
12572 Built-in gSOAP function: `http_put`
12574 * `int (*soap.fdel)(struct soap *soap)`
12575 Called by the main server loop upon an HTTP DELETE request. The
12576 `SOAP_DELETE_METHOD` error is returned by default. This callback can be used
12577 to respond to HTTP DELETE methods. Should return `SOAP_OK`, or a gSOAP error
12578 code. Built-in gSOAP function: `http_del`
12580 * `int (*soap.fhead)(struct soap *soap)`
12581 Called by the main server loop upon an HTTP HEAD request. The
12582 `SOAP_HEAD_METHOD` error is returned by default. This callback can be used to
12583 respond to HTTP HEAD methods. Should return `SOAP_OK`, or a gSOAP error
12584 code. Built-in gSOAP function: `http_get`
12586 * `int (*soap.fform)(struct soap *soap)`
12587 Called by the main server loop when a user-defined `fparsehdr` callback
12588 returned `SOAP_FORM` to signal that the HTTP body must be processed by this
12589 form handler callback. The HTTP POST form data MUST be read, otherwise
12590 keep-alive messages will end up out of sync. Should return `SOAP_OK` or a
12591 gSOAP error code. Built-in gSOAP function: none.
12593 * `int (*soap.fpost)(struct soap *soap, const char *endpoint, const char *host, int port, const char *path, const char *action, size_t count)`
12594 Called from a client proxy to generate the HTTP header to connect to
12595 `endpoint`. Input parameters `host`, `port`, and `path` are micro-parsed
12596 from `endpoint`, `action` is the SOAP action, and `count` is the length of
12597 the SOAP message or 0 when `SOAP_ENC_PLAIN` is set or when `SOAP_IO_LENGTH`
12598 is reset. Use function `soap_send(struct soap *soap, char *s)` to write the
12599 header contents. Should return `SOAP_OK`, or a gSOAP error code. Built-in
12600 gSOAP function: `http_post`.
12602 * `int (*soap.fposthdr)(struct soap *soap, const char *key, const char *val)`
12603 Called by `http_post` and `http_response` (through the callbacks). Emits
12604 HTTP `key`: `val` header entries. Should return `SOAP_OK`, or a gSOAP error
12605 code. Built-in gSOAP function: `http_post_header`.
12607 * `int (*soap.fresponse)(struct soap *soap, int soap_error_code, size_t count)`
12608 Called from a service to generate the response HTTP header. Input parameter
12609 `soap_error_code` is a gSOAP error code (see Section \ref errcodes and
12610 `count` is the length of the SOAP message or 0 when `SOAP_ENC_PLAIN` is
12611 set or when `SOAP_IO_LENGTH` is reset. Use function `soap_send(struct soap
12612 *soap, char *s)` to write the header contents. Should return `SOAP_OK`, or a
12613 gSOAP error code Built-in gSOAP function: `http_response`
12615 * `int (*soap.fparse)(struct soap *soap)`
12616 Called by client proxy and service to parse an HTTP header (if present).
12617 When user-defined, this routine must at least skip the header. Use function
12618 `int soap_getline(struct soap *soap, char *buf, int len)` to read HTTP header
12619 lines into a buffer `buf` of length `len` (returns empty line at end of HTTP
12620 header). Should return `SOAP_OK`, or a gSOAP error code. Built-in gSOAP
12621 function: `http_parse`
12623 * `int (*soap.fparsehdr)(struct soap *soap, const char *key, const char *val)`
12624 Called by `http_parse` (through the `fparse` callback). Handles HTTP `key`:
12625 `val` header entries to set gSOAP's internals. Should return `SOAP_OK`,
12626 `SOAP_STOP` (see `fstop`) or a gSOAP error code. Built-in gSOAP function:
12627 `http_parse_header`
12629 * `int (*soap.fsend)(struct soap *soap, const char *s, size_t n)`
12630 Called for all send operations to emit contents of `s` of length `n`. Should
12631 return `SOAP_OK`, or a gSOAP error code. Built-in gSOAP function: `fsend`
12633 * `size_t (*soap.frecv)(struct soap *soap, char *s, size_t n)`
12634 Called for all receive operations to fill buffer `s` of maximum length `n`.
12635 Should return the number of bytes read or 0 in case of an error, e.g. EOF.
12636 Built-in gSOAP function: `frecv`
12638 * `int (*soap.fignore)(struct soap *soap, const char *tag)`
12639 Called when an unknown XML element was encountered on the input. The `tag`
12640 parameter is the offending XML element tag name. Should return `SOAP_OK`, or
12641 a gSOAP error code such as `SOAP_TAG_MISMATCH` to stop processing. Can be
12642 used to override *`mustUnderstand="true"`* attributes on unrecognized SOAP
12643 Header elements that raise faults. Check `soap->mustUnderstand != 0` in
12644 `fignore` function for presence of mustUnderstand attribute. Built-in gSOAP
12647 * `int (*soap.fconnect)(struct soap *soap, const char *endpoint, const char *host, int port)`
12648 When non-NULL, this callback is called for all client-to-server connect
12649 operations instead of the built-in socket connect code. Therefore, it can be
12650 used to override the built-in connection establishment. Parameter `endpoint`
12651 contains the server endpoint URL, `host` the domain name or IP, and `port`
12652 the port number. Should return `SOAP_OK`, or a gSOAP error code. Built-in
12653 gSOAP function: none
12655 * `SOAP_SOCKET (*soap.faccept)(struct soap *soap, SOAP_SOCKERT s, struct sockaddr *a, int *n)`
12656 Called by `soap_accept`. This is a wrapper routine for `accept`. Given
12657 master socket `s` should return a valid socket descriptor or
12658 `SOAP_INVALID_SOCKET` and set `soap->error` to an error code. Built-in gSOAP
12659 function: `tcp_accept`
12661 * `int (*soap.fresolve)(struct soap *soap, const char *addr, struct in_addr *inaddr)`
12662 Called by `soap_bind` if a host name is given and `soap_connect` to resolve a
12663 domain name `addr`. Should set `in_addr *a` and return `SOAP_OK` or return
12664 `SOAP_ERR` upon failure. Built-in gSOAP function: `tcp_gethost`
12666 * `int (*soap.fpoll)(struct soap *soap)`
12667 Used by clients to check if the server is still responsive.
12668 Built-in gSOAP function: `soap_poll`
12670 * `int (*soap.fserveloop)(struct soap *soap)`
12671 Called after successful invocation of a server operation in the server loop,
12672 immediately after sending the response to a client. Can be used to clean up
12673 resources (e.g. using `soap_end()`) while serving a long sequence of
12674 keep-alive connections. Should return `SOAP_OK`, or set `soap->error` to a
12675 gSOAP error code and return `soap->error`. Built-in gSOAP function: none.
12677 * `void (*soap.fmalloc)(struct soap *soap, size_t n)`
12678 Use to override memory allocation for deserialized C data. Memory allocated
12679 via this callback will *not* be automatically released by the gSOAP engine.
12680 The application must release this data by keeping track of the allocations.
12681 Note: it is not safe to traverse deserialized data structures and free each
12682 node, since data might be shared (SOAP multiref) and some allocated data such
12683 as the HTTP SOAPAction might no be part of the structure.
12684 Built-in gSOAP function: none.
12686 * `int (*soap.fheader)(struct soap *soap)`
12687 Called immediately after parsing a SOAP Header. The SOAP Header struct
12688 referenced by `soap->header` can be inspected and verified. The function
12689 should return `SOAP_OK` or a fault. Built-in gSOAP function: none.
12691 * `int (*soap.fsvalidate)(struct soap *soap, const char *pattern, const char *string)`
12692 Called to validate a non-NULL string against a non-NULL pattern. Patterns use
12693 XML schema regex syntax. Allows user-defined pattern validation. Should
12694 return `SOAP_OK` when the string matches the pattern or `SOAP_TYPE` when the
12695 string does not match. Built-in gSOAP function: none.
12697 * `int (*soap.fwvalidate)(struct soap *soap, const char *pattern, const wchar_t *string)`
12698 Called to validate a non-NULL wide string against a non-NULL pattern.
12699 Patterns use XML schema regex syntax. Allows user-defined pattern validation.
12700 Should return `SOAP_OK` when the string matches the pattern or `SOAP_TYPE`
12701 when the string does not match. Built-in gSOAP function: none.
12703 * `void (*soap.fseterror)(struct soap *soap, const char **code, const char **string)`
12704 Called to set the SOAP Fault `code` and `string` values based on the value of
12705 `soap->error`. Allows user-defined messages to be associated with gSOAP error
12706 codes to override gSOAP's built-in error messages. Built-in gSOAP function:
12709 In addition, a `void *user` field in the `struct soap` data structure is available to pass user-defined data to the callbacks.
12711 The following example uses I/O function callbacks for customized serialization of data into a fixed-size buffer and deserialization back into a
12715 char buf[10000]; // XML buffer
12716 int len1 = 0; // #chars written
12717 int len2 = 0; // #chars read
12718 // mysend: put XML in buf[]
12719 int mysend(struct soap *soap, const char *s, size_t n)
12721 if (len1 + n > sizeof(buf))
12723 strcpy(buf + len1, s);
12727 // myrecv: get XML from buf[]
12728 size_t myrecv(struct soap *soap, char *s, size_t n)
12730 if (len2 + n > len1)
12732 strncpy(s, buf + len2, n);
12739 struct ns__person p;
12741 len1 = len2 = 0; // reset buffer pointers
12742 p.name = "John Doe";
12744 soap.fsend = mysend; // assign callback
12745 soap.frecv = myrecv; // assign callback
12746 soap_begin_send(&soap);
12747 soap_set_omode(&soap, SOAP_XML_TREE);
12748 soap_serialize_ns__person(&soap, &p);
12749 soap_put_ns__person(&soap, &p, "ns:person", NULL);
12750 soap_end_send(&soap);
12753 soap_print_fault(&soap, stdout);
12756 soap_begin_recv(&soap);
12757 soap_get_ns__person(&soap, &p, "ns:person", NULL);
12758 soap_end_recv(&soap);
12761 soap_print_fault(&soap, stdout);
12764 soap_destroy(&soap);
12766 soap_done(&soap); // disable callbacks
12770 A fixed-size buffer to store the outbound message sent is not flexible to handle large content. To store the message in an expanding buffer, use for example:
12781 struct buffer *h = malloc(sizeof(struct buffer));
12785 soap.user = (void *)h; // pass buffer as a handle to the callback
12786 soap.fsend = mysend; // assign callback
12790 ... // use h->buf[0..h->len-1] content
12799 int mysend(struct soap *soap, const char *s, size_t n)
12801 struct buffer *h = (struct buffer*)soap->user; // get buffer through handle
12802 int m = h->max, k = h->len + n;
12803 // need to increase space?
12811 char *buf = malloc(m);
12812 memcpy(buf, h->buf, h->len);
12818 memcpy(h->buf + h->len, s, n);
12824 The `soap_done` function can be called to reset the callback to the default internal gSOAP I/O and HTTP handlers.
12826 The following example illustrates customized I/O and (HTTP) header handling. The SOAP request is saved to a file. The client proxy
12827 then reads the file contents as the service response. To perform this trick, the service response has exactly the same structure as the
12828 request. This is declared by the `struct ns__test` output parameter part of the service operation declaration.
12829 This struct resembles the service request (see the generated `soapStub.h` file created from the header file).
12831 The header file is:
12834 //gsoap ns service name: callback
12835 //gsoap ns service namespace: urn:callback
12841 int ns__test(struct ns__person in, struct ns__test &out);
12844 The client program is:
12849 SOAP_SOCKET myopen(struct soap *soap, const char *endpoint, const char *host, int port)
12851 if (strncmp(endpoint, "file:", 5))
12853 printf("File name expected\n");
12854 return SOAP_INVALID_SOCKET;
12856 if ((soap->sendfd = soap->recvfd = open(host, O_RDWR|O_CREAT, S_IWUSR|S_IRUSR)) < 0)
12857 return SOAP_INVALID_SOCKET;
12858 return soap->sendfd;
12860 void myclose(struct soap *soap)
12862 if (soap->sendfd > 2) // still open?
12863 close(soap->sendfd); // then close it
12864 soap->recvfd = 0; // set back to stdin
12865 soap->sendfd = 1; // set back to stdout
12867 int mypost(struct soap *soap, const char *endpoint, const char *host, const char *path, const char *action, size_t count)
12869 return soap_send(soap, "Custom-generated file\n"); // writes to soap->sendfd
12871 int myparse(struct soap *soap)
12874 if (lseek(soap->recvfd, 0, SEEK_SET) < 0 || soap_getline(soap, buf, 256)) // go to begin and skip custom header
12882 struct ns__person p;
12883 soap_init(&soap); // reset
12884 p.name = "John Doe";
12886 soap.fopen = myopen; // use custom open
12887 soap.fpost = mypost; // use custom post
12888 soap.fparse = myparse; // use custom response parser
12889 soap.fclose = myclose; // use custom close
12890 soap_call_ns__test(&soap, "file://test.xml", "", p, r);
12893 soap_print_fault(&soap, stdout);
12897 soap_init(&soap); // reset to default callbacks
12901 SOAP 1.1 and 1.2 specify that XML elements may be ignored when present in a SOAP payload on the receiving side.
12902 gSOAP ignores XML elements that are unknown, unless the XML attribute *`mustUnderstand="true"`* is present in the XML element.
12903 It may be undesirable for elements to be ignored when the outcome of the omission is uncertain.
12904 The `soap.fignore` callback can be set to a function that returns `SOAP_OK` in case the element can be safely ignored, or
12905 `SOAP_MUSTUNDERSTAND` to throw an exception, or to perform some application-specific action.
12906 For example, to throw an exception as soon as an unknown element is encountered on the input, use:
12909 int myignore(struct soap *soap, const char *tag)
12911 return SOAP_MUSTUNDERSTAND; // never skip elements (secure)
12914 soap.fignore = myignore;
12915 soap_call_ns__method(&soap, ...); // or soap_serve(&soap);
12918 To selectively throw an exception when *`mustUnderstand="true"`* SOAP Header element is encountered or when an unknown element is encountered except for element *`ns:xyz`*, use:
12921 int myignore(struct soap *soap, const char *tag)
12923 if (soap->mustUnderstand)
12924 return SOAP_MUSTUNDERSTAND; // do not ignore mustUnderstand="true"
12925 if (soap_match_tag(soap, tag, "ns:xyz") != SOAP_OK)
12926 return SOAP_MUSTUNDERSTAND;
12930 soap.fignore = myignore;
12931 soap_call_ns__method(&soap, ...); // or soap_serve(&soap)
12933 struct Namespace namespaces[] =
12935 {"SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/"},
12936 {"SOAP-ENC","http://schemas.xmlsoap.org/soap/encoding/"},
12937 {"xsi", "http://www.w3.org/2001/XMLSchema-instance"},
12938 {"xsd", "http://www.w3.org/2001/XMLSchema"},
12939 {"ns", "some-URI"}, // the namespace of element ns:xyz
12943 Function `soap_match_tag` compares two tags. The third parameter may be a pattern where `*` is a wildcard
12944 and `-` is a single character wildcard. So for example
12945 `soap_match_tag(tag, "ns:*")` will match any element in namespace `ns` or when no namespace prefix is present in the XML
12948 The callback can also be used to keep track of unknown elements in an internal data structure such as a list:
12954 struct Unknown *next;
12956 int myignore(struct soap *soap, const char *tag)
12958 char *s = (char*)soap_malloc(soap, strlen(tag)+1);
12959 struct Unknown *u = (struct Unknown*)soap_malloc(soap, sizeof(struct Unknown));
12970 struct Unknown *ulist = NULL;
12972 soap.fignore = myignore;
12973 soap_call_ns__method(&soap, ...); // or soap_serve(&soap)
12974 // print the list of unknown elements
12975 soap_end(&soap); // clean up
12978 ## HTTP 1.0 and 1.1
12980 gSOAP uses HTTP 1.1 by default. You can revert to HTTP 1.0 as follows:
12986 soap.http_version = "1.0";
12989 This sets the HTTP version and reconfigures the engine to revert to HTTP 1.0.
12990 Note that you cannot use HTTP chunking with HTTP 1.0.
12992 ## HTTP 307 Temporary Redirect Support
12994 The client-side handling of HTTP 307 code "Temporary Redirect" and any of the redirect codes 301, 302, and 303 are not automated in gSOAP. Client application developers may want to consider adding a few lines of code to support redirects. It was decided not to automatically support redirects for the following reasons:
12997 * Redirecting a secure HTTPS address to a non-secure HTTP address via 307 creates a security vulnerability.
12999 * Cyclic redirects must be detected (e.g. allowing only a limited number of redirect levels).
13001 * Redirecting HTTP POST will result in re-serialization and re-post of the entire SOAP request. The SOAP request message must be re-posted in its entirity when re-issuing the SOAP operation to a new address.
13003 To implement client-side 307 redirect, add the following lines of code:
13006 char *endpoint = NULL; // use default endpoint given in WSDL (or add another one here)
13007 int n = 10; // max redirect count
13010 if (soap_call_ns1__myMethod(soap, endpoint, ...))
13012 if ((soap->error >= 301 && soap->error <= 303) || soap->error == 307)
13013 endpoint = soap_strdup(soap, soap->endpoint); // endpoint from HTTP 301, 302, 303, 307 Location header
13015 { ... report and handle error
13024 ## HTTP GET Support {#get}
13026 To implement your own HTTP (HTTPS) GET request responses, you need to set the `soap.fget` callback. The callback is required to produce a response to the request in textual form, such as a Web page or a SOAP/XML response. This method does not work with CGI.
13028 The following example produces a Web page upon a HTTP GET request (e.g. from a browser):
13031 struct soap *soap = soap_new();
13032 soap->fget = http_get;
13036 int http_get(struct soap *soap)
13038 soap_response(soap, SOAP_HTML); // HTTP response header with text/html
13039 soap_send(soap, "<HTML>My Web server is operational.</HTML>");
13040 soap_end_send(soap);
13045 The example below produces a WSDL file upon a HTTP GET with path `?wsdl`:
13048 int http_get(struct soap *soap)
13051 char *s = strchr(soap->path, '?');
13052 if (!s || strcmp(s, "?wsdl"))
13053 return SOAP_GET_METHOD;
13054 fd = fopen("myservice.wsdl", "rb"); // open WSDL file to copy
13056 return 404; // return HTTP not found error
13057 soap->http_content = "text/xml"; // HTTP header with text/xml content
13058 soap_response(soap, SOAP_FILE);
13061 size_t r = fread(soap->tmpbuf, 1, sizeof(soap->tmpbuf), fd);
13064 if (soap_send_raw(soap, soap->tmpbuf, r))
13065 break; // can't send, but little we can do about that
13068 soap_end_send(soap);
13073 Using one-way SOAP/XML message, you can also return a SOAP/XML response:
13076 int http_get(struct soap *soap)
13078 if ((soap->omode & SOAP_IO) != SOAP_IO_CHUNK)
13079 soap_set_omode(soap, SOAP_IO_STORE); // if not chunking we MUST buffer entire content to determine content length
13080 soap_response(soap, SOAP_OK);
13081 return soap_send_ns1__mySendMethodResponse(soap, "", NULL, ... params ...);
13085 where `ns1__mySendMethodResponse` is a one-way message declared in a gSOAP header file as:
13088 int ns1__mySendMethodResponse(... params ..., void);
13091 The generated `soapClient.cpp` includes the sending-side stub function.
13093 ## TCP and HTTP Keep-Alive {#keepalive}
13095 gSOAP supports keep-alive socket connections. To activate keep-alive support,
13096 set the `SOAP_IO_KEEPALIVE` flag for both input and output modes, see Section \ref flags .
13101 soap_init2(&soap, SOAP_IO_KEEPALIVE, SOAP_IO_KEEPALIVE);
13104 When a client or a service communicates with another client or service that supports keep alive, the
13105 attribute `soap.keep_alive` will be set to 1, otherwise it is reset to 0 (indicating that the other party
13106 will close the connection).
13107 The connection maybe terminated on either end before the communication completed, for example when the server keep-alive
13108 connection has timed out.
13109 This generates a "Broken Pipe" signal on Unix/Linux platforms. This signal can be caught with a signal handler:
13112 signal(SIGPIPE, sigpipe_handle);
13115 where, for example:
13118 void sigpipe_handle(int x) { }
13121 Alternatively, broken pipes can be kept silent by setting:
13124 soap.socket_flags = MSG_NOSIGNAL;
13127 This setting will not generate a sigpipe but read/write operations return `SOAP_EOF` instead.
13128 Note that Win32 systems do not support signals and lack the `MSG_NOSIGNAL` flag.
13129 The sigpipe handling and flags are not very portable.
13131 A connection will be kept open only if the request contains an HTTP 1.0 header
13132 with "*`Connection: Keep-Alive`*" or an HTTP 1.1 header that does not contain
13133 "*`Connection: close`*". This means that a gSOAP client method call should
13134 use "*`http://`*" in the endpoint URL of the request to the stand-alone
13135 service to ensure HTTP headers are used.
13137 If the client does not close the connection, the server will wait forever when
13138 no `recv_timeout` is specified. In addition, other clients will be denied
13139 service as long as a client keeps the connection to the server open. To
13140 prevent this from happening, the service should be multi-threaded such that
13141 each thread handles the client connection:
13144 int main(int argc, char **argv)
13146 struct soap soap, *tsoap;
13149 soap_init2(&soap, SOAP_IO_KEEPALIVE, SOAP_IO_KEEPALIVE);
13150 soap.max_keep_alive = 100; // at most 100 calls per keep-alive session
13151 soap.accept_timeout = 600; // optional: let server time out after ten minutes of inactivity
13152 m = soap_bind(&soap, NULL, 18000, BACKLOG); // use port 18000 on the current machine
13155 soap_print_fault(&soap, stderr);
13158 fprintf(stderr, "Socket connection successful %d\n", m);
13159 for (count = 0; count >= 0; count++)
13161 soap.socket_flags = MSG_NOSIGNAL; // use this
13162 soap.accept_flags = SO_NOSIGPIPE; // or this to prevent sigpipe
13163 s = soap_accept(&soap);
13167 soap_print_fault(&soap, stderr);
13169 fprintf(stderr, "Server timed out\n"); // Assume timeout is long enough for threads to complete serving requests
13172 fprintf(stderr, "Accepts socket %d connection from IP %d.%d.%d.%d\n", s, (int)(soap.ip>>24)&0xFF, (int)(soap.ip>>16)&0xFF, (int)(soap.ip>>8)&0xFF, (int)soap.ip&0xFF);
13173 tsoap = soap_copy(&soap);
13174 pthread_create(&tid, NULL, (void*(*)(void*))process_request, (void*)tsoap);
13178 void *process_request(void *soap)
13180 pthread_detach(pthread_self());
13181 ((struct soap*)soap)->recv_timeout = 60; // Timeout after 1 minute stall on recv
13182 ((struct soap*)soap)->send_timeout = 10; // Timeout after 10 second stall on send
13183 soap_serve((struct soap*)soap);
13184 soap_destroy((struct soap*)soap);
13185 soap_end((struct soap*)soap);
13186 soap_free((struct soap*)soap);
13191 To prevent a malicious client from keeping a thread waiting forever by keeping
13192 the connection open, timeouts are set in the `process_request` routine as
13193 shown. See Section \ref timeout for more details on timeout settings.
13195 A gSOAP client call will automatically attempt to re-establish a connection to
13196 a server when the server has terminated the connection for any reason. This
13197 way, a sequence of calls can be made to the server while keeping the connection
13198 open. Client stubs will poll the server to check if the connection is still
13199 open. When the connection was terminated by the server, the client will
13200 automatically reconnect.
13202 A client should reset `SOAP_IO_KEEPALIVE` just before the last call to a
13203 server to close the connection after this last call. This will close the socket
13204 after the call and also informs the server to gracefully close the connection.
13206 The client-side can also set the TCP keep-alive socket properties, using the `soap.tcp_keep_alive` flag (set to 1 to enable), `soap.tcp_keep_idle` to set the TCP_KEEPIDLE value, `soap.tcp_keep_intvl` to set the TCP_KEEPINTVL value, and `soap.tcp_keep_cnt` to set the TCP_KEEPCNT value.
13208 If a client is in the middle of soap call that might take a long time and the
13209 server goes away/down the caller does not get any feedback until the
13210 `soap.recv_timeout` is reached. Enabling TCP keep alive on systems that
13211 support it allows for a faster connection teardown detection for applications
13214 ## HTTP Chunked Transfer Encoding {#chunked}
13216 gSOAP supports HTTP chunked transfer encoding. Un-chunking of inbound messages
13217 takes place automatically. Outbound messages are never chunked, except when the
13218 `SOAP_IO_CHUNK` flag is set for the output mode. Most Web services,
13219 however, will not accept chunked inbound messages.
13221 ## HTTP Buffered Sends
13223 The entire outbound message can be stored to determine the HTTP content length
13224 rather than the two-phase encoding used by gSOAP which requires a separate pass
13225 over the data to determine the length of the outbound message. Setting the
13226 flag `SOAP_IO_STORE` for the output mode will buffer the entire message.
13227 This can speed up the transmission of messages, depending on the content, but
13228 may require significant storage space to hold the verbose XML message.
13230 Zlib compressed transfers require buffering. The `SOAP_IO_STORE` flag is
13231 set when the `SOAP_ENC_ZLIB` flag is set to send compressed messages. The use of chunking
13232 significantly reduces memory usage and may speed up the transmission of compressed SOAP/XML messages.
13233 This is accomplished by setting the `SOAP_IO_CHUNK` flag with
13234 `SOAP_ENC_ZLIB` for the output mode.
13236 ## HTTP Authentication
13238 HTTP authentication (basic) is enabled at the client-side by setting the
13239 `soap.userid` and `soap.passwd` strings to a username and password,
13240 respectively. A server may request user authentication
13241 and denies access (HTTP 401 error) when the client tries to connect without HTTP authentication (or with the wrong authentication information).
13243 Here is an example client code fragment to set the HTTP authentication username and password:
13248 soap.userid = "guest";
13249 soap.passwd = "visit";
13253 A client SOAP request will have the following HTTP header:
13259 User-Agent: gSOAP/2.2
13260 Content-Type: text/xml; charset=utf-8
13261 Content-Length: nnn
13262 Authorization: Basic Z3Vlc3Q6Z3Vlc3Q=
13267 A client MUST set the `soap.userid` and `soap.passwd` strings for each call that requires client authentication. The strings are reset after each successful or unsuccessful call.
13269 When present, the value of the `WWW-Authenticate` HTTP header with the authentication realm can be obtained from the `soap.authrealm` string. This is useful for clients to respond intelligently to authentication requests.
13271 A stand-alone gSOAP Web Service can enforce HTTP authentication upon clients, by checking the `soap.userid` and `soap.passwd` strings. These strings are set when a client request contains HTTP authentication headers. The strings SHOULD be checked in each service method (that requires authentication to execute).
13273 Here is an example service method implementation that enforced client authentication:
13276 int ns__method(struct soap *soap, ...)
13278 if (!soap->.userid || !soap->.passwd ||
13279 strcmp(soap->.userid, "guest") ||
13280 strcmp(soap->.passwd, "visit"))
13286 When the authentication fails, the service response with a SOAP Fault message and a HTTP error code "401 Unauthorized".
13287 The HTTP error codes are described in Section \ref errcodes .
13289 ## HTTP NTLM Authentication
13291 HTTP NTLM authentication is enabled at the client-side by installing
13292 `libntlm` from <http://www.nongnu.org/libntlm> and compiling all
13293 project source codes with `-DWITH_NTLM`.
13295 In your application code set the `soap.userid`, `soap.passwd`, and
13296 `soap.authrealm` strings to a username, password,
13297 and the authentication domain respectively. A server may request NTLM
13298 authentication and denies access (HTTP 401 authentication required or HTTP 407 HTTP proxy authentication required) when the client tries to
13299 connect without HTTP authentication (or with the wrong authentication
13302 Here is an example client code fragment to set the NTLM authentication username and password:
13306 soap_init1(&soap, SOAP_IO_KEEPALIVE);
13307 if (soap_call_ns__method(&soap, ...))
13308 { if (soap.error == 401)
13309 { soap.userid = "Zaphod";
13310 soap.passwd = "Beeblebrox";
13311 soap.authrealm = "Ursa-Minor";
13312 if (soap_call_ns__method(&soap, ...))
13316 The following NTLM handshake between the client C and server S is performed:
13320 1: C --> S & POST ...
13321 & Content-Type: text/xml; charset=utf-8
13323 2: C <-- S & 401 Unauthorized
13324 & WWW-Authenticate: NTLM
13326 3: C --> S & GET ...
13327 & Authorization: NTLM <base64-encoded type-1-message>
13329 4: C <-- S & 401 Unauthorized
13330 & WWW-Authenticate: NTLM <base64-encoded type-2-message>
13332 5: C --> S & POST ...
13333 & Content-Type: text/xml; charset=utf-8
13334 & Authorization: NTLM <base64-encoded type-3-message>
13336 6: C <-- S & 200 OK
13340 where stages 1 and 2 indicates a client attempting to connect without
13341 authorization information, which is the first method call in the code above. Stage 3 to 6 happen with the proper client
13342 authentication set with `soap.userid`, `soap.passwd`, and
13343 `soap.authrealm` provided. NTLM authenticates connections, not requests. When the connection is kept alive, subsequent messages can be exchanged without re-authentication.
13345 To avoid the overhead of the first rejected call, use:
13349 soap_init1(&soap, SOAP_IO_KEEPALIVE);
13350 soap.userid = "Zaphod";
13351 soap.passwd = "Beeblebrox";
13352 soap.authrealm = "Ursa-Minor";
13353 soap.ntlm_challenge = "";
13354 if (soap_call_ns__method(&soap, ...))
13358 When the authentication fails (stage 1 and 2), the service response with a SOAP
13359 Fault message and a HTTP error code "401 Unauthorized". The HTTP error codes
13360 are described in Section \ref errcodes .
13362 On windows, an alternative is to use the WinInet module, which has built-in
13363 NTLM support. The WinInet for gSOAP module is available in the `mod_gsoap`
13364 directory of the gSOAP package. Instructions for WinInet use are included there.
13366 ## HTTP Proxy NTLM Authentication
13368 For HTTP 407 Proxy Authentication Required, set the proxy userid and passwd:
13372 soap_init1(&soap, SOAP_IO_KEEPALIVE);
13373 soap.proxy_host = "...";
13374 soap.proxy_port = ...;
13375 if (soap_call_ns__method(&soap, ...))
13376 { if (soap.error == 407)
13377 { soap.proxy_userid = "Zaphod";
13378 soap.proxy_passwd = "Beeblebrox";
13379 soap.authrealm = "Ursa-Minor";
13380 if (soap_call_ns__method(&soap, ...))
13384 To avoid the overhead of the first rejected call, use:
13388 soap_init1(&soap, SOAP_IO_KEEPALIVE);
13389 soap.proxy_host = "...";
13390 soap.proxy_port = ...;
13391 soap.proxy_userid = "Zaphod";
13392 soap.proxy_passwd = "Beeblebrox";
13393 soap.authrealm = "Ursa-Minor";
13394 soap.ntlm_challenge = "";
13395 if (soap_call_ns__method(&soap, ...))
13399 ## HTTP Proxy Basic Authentication
13401 HTTP proxy authentication (basic) is enabled at the client-side by setting the
13402 `soap.proxy_userid` and `soap.proxy_passwd` strings to a username and
13403 password, respectively. For example, a proxy server may request user
13404 authentication. Otherwise, access is denied by the proxy (HTTP 407 error).
13405 Example client code fragment to set proxy server, username, and password:
13410 soap.proxy_host = "xx.xx.xx.xx"; // IP or domain
13411 soap.proxy_port = 8080;
13412 soap.proxy_userid = "guest";
13413 soap.proxy_passwd = "guest";
13417 A client SOAP request will have the following HTTP header:
13423 User-Agent: gSOAP/2.2
13424 Content-Type: text/xml; charset=utf-8
13425 Content-Length: nnn
13426 Proxy-Authorization: Basic Z3Vlc3Q6Z3Vlc3Q=
13431 When X-Forwarded-For headers are returned by the proxy, the header can be accessed in the `soap.proxy_from` string.
13433 The CONNECT method is used for HTTP proxy authentication:
13437 CONNECT server.example.com:80 HTTP/1.1
13441 In some cases, it may be necessary to use the Host HTTP header with the CONNECT
13446 CONNECT server.example.com:80 HTTP/1.1
13447 Host: server.example.com:80
13451 If so, compile the gSOAP code with `-DWITH_CONNECT_HOST` to include the
13452 Host HTTP header with the CONNECT protocol.
13454 ## Messaging Speed and Performance Improvement Tips
13456 Here are some tips you can use to speed up gSOAP. gSOAP's default settings are choosen to maximize portability and compatibility. The settings can be tweaked to optimize the performance as follows:
13459 * Increase the buffer size `SOAP_BUFLEN` by changing the `SOAP_BUFLEN` macro in `stdsoap2.h`. Use buffer size 2^18=262144 for example.
13461 * Use HTTP keep-alive at the client-side, see \ref keepalive , when the client needs to make a series of calls to the same server. Server-side keep-alive support can greatly improve performance of both client and server. But be aware that clients and services under Unix/Linux require signal handlers to catch dropped connections.
13463 * Use HTTP chunked transfers, see \ref chunked .
13465 * Do NOT use gzip compression, since the overhead of compression is typically higher than the bandwidth gains.
13467 * Set the `SOAP_XML_TREE` flag to disable id-ref multi-ref object (de)serialization. This boosts performance significantly and works with SOAP document/literal style (i.e. no id-ref graph serialization as required with SOAP encoding style).
13469 * Compile `stdsoap2.c` and `stdsoap2.cpp` and all other source codes with `-DWITH_NOIDREF` to improve performance even better by permanently disabling id-ref multi-ref object (de)serialization.
13471 * Do NOT use DEBUG mode, since the overhead of logging is significant.
13474 ## XML Parsing Options to set Safety Guards {#safety}
13476 The XML parser is configured to restrict the XML nesting depth level to `SOAP_MAXLEVEL` and restricts the repeated occurrence of elements that are deserialized into arrays and containers by `SOAP_MAXOCCURS`. These macros can be changed, but you can also change the following context attributes at runtime, e.g. to enhance the safety for specific service and/or client operations:
13480 * `soap.maxlevel` is an `unsigned int` to restrict the XML nesting depth level, where the default value is `SOAP_MAXLEVEL=10000`.
13482 * `soap.maxoccurs` is a `size_t` to restrict the number of repeated occurrences of elements that are deserialized into arrays and structs, where the default value is `SOAP_MAXOCCURS=100000`.
13484 * `soap.maxlength` is a positive `long` length that restricts the length of strings deserialized from XML. A zero or negative value is unrestricted length. When restricted, the XML schema validation maxLength takes precedence over this length restriction. So setting a smaller value will not interfere with the XML validation rules. The default value is `SOAP_MAXLENGTH=0`. Note that string length is expressed in number of characters, not bytes. So UTF-8 encodings are not truncated.
13486 XML schema validation constraints are enforced with the `SOAP_XML_STRICT` context flag. The schema maxLength validation constraint overrules the `soap.maxlength` guard. The schema maxOccurs validation constraint DOES NOT overrule the `soap.maxoccurs` guard, so arrays and containers are always restricted in length by this guard.
13488 ## Timeout Management for Non-Blocking Operations {#timeout}
13490 Socket connect, accept, send, and receive timeout values can be set to manage
13491 socket communication timeouts. The `soap.connect_timeout`,
13492 `soap.accept_timeout`, `soap.send_timeout`,
13493 `soap.recv_timeout` and `soap.transfer_timeout` context attributes of
13494 the current gSOAP runtime context `soap` can be set to the appropriate
13495 user-defined socket send, receive, and accept timeout values. A positive value
13496 measures the timeout in seconds. A negative timeout value measures the timeout
13497 in microseconds (10^-6 sec).
13499 The `soap.connect_timeout` specifies the timeout for
13500 `soap_call_ns__method` calls.
13502 The `soap.accept_timeout` specifies the timeout for
13503 `soap_accept(&soap)` calls.
13505 The `soap.send_timeout` and `soap.recv_timeout` specify the timeout
13506 for non-blocking socket I/O operations. This is the maximum delay on the socket operation permitted.
13508 The `soap.transfer_timeout` is new since 2.8.48 and limits the time a message send and a message receive operation can take. This value should be used in combination with `soap.send_timeout` and `soap.recv_timeout` for accurate timeout control.
13515 soap.send_timeout = 10;
13516 soap.recv_timeout = 10;
13517 soap.recv_timeout = 60;
13520 This will result in a timeout if no data can be send in 10 seconds and no data is received within 10 seconds after initiating
13521 a send or receive operation over the socket. A value of zero disables timeout, for example:
13524 soap.send_timeout = 0;
13525 soap.recv_timeout = 0;
13526 soap.recv_timeout = 0;
13529 When a timeout occurs in the send or receive operations, a `SOAP_EOF` exception will be raised ("end of file or no input").
13530 Negative timeout values measure timeouts in microseconds, for example:
13534 #define mSec *-1000
13535 soap.accept_timeout = 10 uSec;
13536 soap.send_timeout = 20 mSec;
13537 soap.recv_timeout = 20 mSec;
13538 soap.recv_timeout = 10;
13541 The macros improve readability.
13543 @warning many Linux versions do not support non-blocking `connect()`.
13544 Therefore, setting `soap.connect_timeout` for non-blocking
13545 `soap_call_ns__method` calls may not work under Linux.
13547 @warning interrupts (EINTR) can affect the blocking time in I/O operations.
13548 The maximum number of EINTR that will not trigger an error is set by
13549 `SOAP_MAXEINTR` in `stdsoap2.h`, which is 10 by default. Each EINTR
13550 may increase the blocking time by up to one second, up to `SOAP_MAXEINTR`
13553 ## Socket Options and Flags
13555 gSOAP's socket communications can be controlled with socket options and flags.
13556 The gSOAP run-time context `struct soap` flags are:
13557 `int soap.socket_flags` to control socket send() and recv() calls,
13558 `int soap.connect_flags` to set client connection socket options,
13559 `int soap.bind_flags` to set server-side port bind socket options,
13560 `int soap.accept_flags` to set server-side request message accept
13561 socket options. See the manual pages of `send` and `recv` for
13562 `soap.socket_flags` values and see the manual pages of
13564 `soap.connect_flags`, `soap.bind_flags`, and
13565 `soap.accept_flags` (SOL_SOCKET) values.
13566 These `SO_` socket option flags (see `setsockopt` manual pages)
13567 can be bit-wise or-ed to set multiple
13568 socket options at once.
13569 The client-side flag `soap.connect_flags=SO_LINGER` is supported with values `l_onoff=1` and `l_linger=soap.linger_time`. The `soap.linger_time` determines the wait time (the time resolution is system dependent, though according to some experts only zero and nonzero values matter). The linger option can be used to manage the number of connections that remain in TIME_WAIT state at the server side.
13571 For example, to disable sigpipe signals on Unix/Linux platforms use:
13572 `soap.socket_flags = MSG_NOSIGNAL` and/or
13573 `soap.connect_flags = SO_NOSIGPIPE` (i.e. client-side connect) depending
13576 Use `soap.bind_flags=SO_REUSEADDR` to enable server-side port reuse and local port
13577 sharing (but be aware of the possible security implications such as port hijacking).
13579 Note that multiple socket options can be explicitly set with `setsockopt` as follows:
13582 int sock = soap_bind(soap, host, port, backlog);
13583 if (soap_valid_socket(sock))
13585 setsockopt(sock, ..., ..., ..., ...);
13586 setsockopt(sock, ..., ..., ..., ...);
13589 ## Overriding the Host and Port to Connect
13591 To override the host and port of the client connecting to a server, set `soap.override_host` and `soap.override_port`:
13594 soap.override_host = "example.com"; // host name or IP address
13595 soap.override_port = 80; // port number to use when overriding the address
13598 ## Secure Web Services with HTTPS/SSL~ {#serveropenssl}
13600 When a Web Service is installed as CGI, it uses standard I/O that is encrypted/decrypted by the Web server that runs the CGI
13602 HTTPS/SSL support must be configured for the Web server (not CGI-based Web Service application itself).
13604 To enable SSL for stand-alone gSOAP servers, first install OpenSSL and use option `-DWITH_OPENSSL` to compile the sources with your C or C++ compiler (or use `-DWITH_GNUTLS` if you prefer GNUTLS), for example:
13606 > c++ -DWITH_OPENSSL -o myprog myprog.cpp stdsoap2.cpp soapC.cpp soapServer.cpp -lssl -lcrypto
13610 > c++ -DWITH_GNUTLS -o myprog myprog.cpp stdsoap2.cpp soapC.cpp soapServer.cpp -lgnutls -lgcrypt -lgpg-error
13612 SSL support for stand-alone gSOAP Web services is enabled by calling `soap_ssl_accept` to perform the SSL/TLS handshake after `soap_accept`.
13613 In addition, a key file, a CA file (or path to certificates), DH file (if RSA is not used), and password need to be supplied. Instructions on how to do this can be found in the
13614 OpenSSL documentation `http://www.openssl.org`. See also Section \ref ssl .
13616 Let's take a look at an example SSL secure
13617 multi-threaded stand-alone SOAP Web Service:
13624 struct soap soap, *tsoap;
13625 soap_ssl_init(); /* init OpenSSL (skipping this or calling multiple times is OK, since the engine will init SSL automatically) */
13626 // soap_ssl_noinit(); /* do not init OpenSSL (if SSL is already initialized elsewhere) */
13627 if (CRYPTO_thread_setup()) // OpenSSL
13629 fprintf(stderr, "Cannot setup thread mutex\n");
13633 if (soap_ssl_server_context(&soap,
13635 "server.pem", /* keyfile: required when server must authenticate to clients (see SSL docs on how to obtain this file) */
13636 "password", /* password to read the key file (not used with GNUTLS) */
13637 "cacert.pem", /* optional cacert file to store trusted certificates */
13638 NULL, /* optional capath to directory with trusted certificates */
13639 "dh512.pem", /* DH file name or DH key len bits (minimum is 512, e.g. "512") to generate DH param, if NULL use RSA */
13640 NULL, /* if randfile!=NULL: use a file with random data to seed randomness */
13641 NULL /* optional server identification to enable SSL session cache (must be a unique name) */
13644 soap_print_fault(&soap, stderr);
13647 m = soap_bind(&soap, NULL, 18000, 100); // use port 18000
13650 soap_print_fault(&soap, stderr);
13653 fprintf(stderr, "Socket connection successful: master socket = %d\n", m);
13656 s = soap_accept(&soap);
13657 fprintf(stderr, "Socket connection successful: slave socket = %d\n", s);
13660 soap_print_fault(&soap, stderr);
13663 tsoap = soap_copy(&soap); /* should call soap_ssl_accept on a copy */
13666 pthread_create(&tid, NULL, &process_request, (void*)tsoap);
13668 soap_done(&soap); /* deallocates SSL context */
13669 CRYPTO_thread_cleanup(); // OpenSSL
13672 void *process_request(void *soap)
13674 pthread_detach(pthread_self());
13675 if (soap_ssl_accept((struct soap*)soap))
13676 soap_print_fault(tsoap, stderr);
13678 soap_serve((struct soap*)soap);
13679 soap_destroy((struct soap*)soap);
13680 soap_end((struct soap*)soap);
13681 soap_free((struct soap*)soap); // done and free context
13686 The `soap_ssl_server_context` function initializes the server-side SSL context. The `server.pem` key file is the server's private key concatenated with its certificate. The `cacert.pem` is used to authenticate clients and contains the client certificates. Alternatively a directory name can be specified. This directory is assumed to contain the certificates. The `dh512.pem` file specifies that DH will be used for key agreement instead of RSA. A numeric value greater than 512 can be provided instead as a string constant (e.g. `"512"`) to allow the engine to generate the DH parameters on the fly (this can take a while) rather than retrieving them from a file. The randfile entry can be used to seed the PRNG. The last entry enable server-side session caching. A unique server name is required.
13688 The GNUTLS mutex lock setup is automatically peformed in the gSOAP engine, but only when POSIX threads are detected and available.
13690 OpenSSL requires mutex locks to be explicitly setup in your code for multithreaded applications, for which we need to call `CRYPTO_thread_setup()` and `CRYPTO_thread_cleanup()`. These routines can be found in `openssl/crypto/threads/th-lock.c` and are also used in the SSL example codes `samples/ssl`. These routines are required to setup locks for multi-threaded applications that use SSL.
13692 We give a Windows and POSIX threads implementation of these here:
13695 #include <unistd.h> /* defines _POSIX_THREADS if pthreads are available */
13696 #ifdef _POSIX_THREADS
13697 # include <pthread.h>
13700 # define MUTEX_TYPE HANDLE
13701 # define MUTEX_SETUP(x) (x) = CreateMutex(NULL, FALSE, NULL)
13702 # define MUTEX_CLEANUP(x) CloseHandle(x)
13703 # define MUTEX_LOCK(x) WaitForSingleObject((x), INFINITE)
13704 # define MUTEX_UNLOCK(x) ReleaseMutex(x)
13705 # define THREAD_ID GetCurrentThreadID()
13706 #elif defined(_POSIX_THREADS)
13707 # define MUTEX_TYPE pthread_mutex_t
13708 # define MUTEX_SETUP(x) pthread_mutex_init(&(x), NULL)
13709 # define MUTEX_CLEANUP(x) pthread_mutex_destroy(&(x))
13710 # define MUTEX_LOCK(x) pthread_mutex_lock(&(x))
13711 # define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x))
13712 # define THREAD_ID pthread_self()
13714 # error "You must define mutex operations appropriate for your platform"
13715 # error "See OpenSSL /threads/th-lock.c on how to implement mutex on your platform"
13717 struct CRYPTO_dynlock_value { MUTEX_TYPE mutex; };
13718 static MUTEX_TYPE *mutex_buf;
13719 static struct CRYPTO_dynlock_value *dyn_create_function(const char *file, int line)
13721 struct CRYPTO_dynlock_value *value;
13722 value = (struct CRYPTO_dynlock_value*)malloc(sizeof(struct CRYPTO_dynlock_value));
13724 MUTEX_SETUP(value->mutex);
13727 static void dyn_lock_function(int mode, struct CRYPTO_dynlock_value *l, const char *file, int line)
13729 if (mode & CRYPTO_LOCK)
13730 MUTEX_LOCK(l->mutex);
13732 MUTEX_UNLOCK(l->mutex);
13734 static void dyn_destroy_function(struct CRYPTO_dynlock_value *l, const char *file, int line)
13736 MUTEX_CLEANUP(l->mutex);
13739 void locking_function(int mode, int n, const char *file, int line)
13741 if (mode & CRYPTO_LOCK)
13742 MUTEX_LOCK(mutex_buf[n]);
13744 MUTEX_UNLOCK(mutex_buf[n]);
13746 unsigned long id_function()
13748 return (unsigned long)THREAD_ID;
13750 int CRYPTO_thread_setup()
13753 mutex_buf = (MUTEX_TYPE*)malloc(CRYPTO_num_locks() * sizeof(MUTEX_TYPE));
13756 for (i = 0; i < CRYPTO_num_locks(); i++)
13757 MUTEX_SETUP(mutex_buf[i]);
13758 CRYPTO_set_id_callback(id_function);
13759 CRYPTO_set_locking_callback(locking_function);
13760 CRYPTO_set_dynlock_create_callback(dyn_create_function);
13761 CRYPTO_set_dynlock_lock_callback(dyn_lock_function);
13762 CRYPTO_set_dynlock_destroy_callback(dyn_destroy_function);
13765 void CRYPTO_thread_cleanup()
13770 CRYPTO_set_id_callback(NULL);
13771 CRYPTO_set_locking_callback(NULL);
13772 CRYPTO_set_dynlock_create_callback(NULL);
13773 CRYPTO_set_dynlock_lock_callback(NULL);
13774 CRYPTO_set_dynlock_destroy_callback(NULL);
13775 for (i = 0; i < CRYPTO_num_locks(); i++)
13776 MUTEX_CLEANUP(mutex_buf[i]);
13782 For Unix and Linux, make sure you have signal handlers set in your service and/or client applications to catch broken connections (`SIGPIPE`):
13785 signal(SIGPIPE, sigpipe_handle);
13788 where, for example:
13791 void sigpipe_handle(int x) { }
13794 By default, clients are not required to authenticate. To support client authentication use the following:
13797 if (soap_ssl_server_context(&soap,
13798 SOAP_SSL_REQUIRE_CLIENT_AUTHENTICATION,
13807 soap_print_fault(&soap, stderr);
13812 This requires each client to authenticate with its certificate.
13814 Since release version 2.8.20 SSL v3 is disabled. To enable SSL v3 together with TLS v1.0, v1.1, and v1.2 use `SOAP_SSLv3_TLSv1` in `soap_ssl_server_context`. To use TLS v1.1 only use `SOAP_TLSv1_1`. To use TLS v1.2 only use `SOAP_TLSv1_2`. To use SSL v3 only use `SOAP_SSLv3`.
13816 The `cacert` file and `capath` are optional. Either one can be
13817 specified when clients must run on non-trusted systems (`capath` is not used with GNUTLS). We want to avoid
13818 storing trusted certificates in the default location on the file system when
13819 that is not secure. Therefore, a flat `cacert.pem` file or directory can be
13820 specified to store trusted certificates.
13822 The gSOAP distribution includes a `cacerts.pem` file with the certificates
13823 of all certificate authorities such as Verisign. You can use this file to
13824 verify the authentication of servers that provide certificates issued by these
13827 The `cacert.pem`, `client.pem`, and `server.pem` files in the gSOAP
13828 distribution are examples of self-signed certificates.
13829 The `client.pem` and `server.pem` contain the client/server private key
13830 concatenated with the certificate. The keyfiles (`client.pem` and
13831 `server.pem`) are created by concatenating the private key PEM with the
13832 certificate PEM. The keyfile SHOULD NEVER be shared with any party. With
13833 OpenSSL, you can encrypt the keyfiles with a password to offer some protection
13834 and the password is used in the client/server code to read the keyfile. GNUTLS
13835 does not support this feature and cannot encrypt or decrypt a keyfile.
13837 @warning it is important that the `WITH_OPENSSL` macro MUST be consistently defined to
13838 compile the sources, such as `stdsoap2.cpp`, `soapC.cpp`,
13839 `soapClient.cpp`, `soapServer.cpp`, and all application sources that
13840 include `stdsoap2.h` or `soapH.h`. If the macros are not consistently
13841 used, the application will crash due to a mismatches in the declaration and
13842 access of the gSOAP context.
13844 ## Secure Clients with HTTPS/SSL {#clientopenssl}
13846 To utilize HTTPS/SSL, you need to install the OpenSSL library on your platform or GNUTLS for a light-weight SSL/TLS library.
13847 After installation, compile all the sources of your application with option `-DWITH_OPENSSL` (or `-DWITH_GNUTLS` when using GNUTLS). For example on Linux:
13849 > c++ -DWITH_OPENSSL myclient.cpp stdsoap.cpp soapC.cpp soapClient.cpp -lssl -lcrypto
13853 > c++ -DWITH_OPENSSL myclient.cpp stdsoap.cpp soapC.cpp soapClient.cpp -lxnet -lsocket -lnsl -lssl -lcrypto
13855 or you can add the following line to `soapdefs.h`:
13858 #define WITH_OPENSSL
13861 and compile with option `-DWITH_SOAPDEFS_H` to include `soapdefs.h` in your project.
13862 Alternatively, compile with GNUTLS:
13864 > c++ -DWITH_GNUTLS myclient.cpp stdsoap.cpp soapC.cpp soapClient.cpp -lgnutls -lgcrypt -lgpg-error
13867 A client program simply uses the prefix `https:` instead of `http:` in the endpoint URL of a service operation call to a
13868 Web Service to use encrypted transfers (if the service supports HTTPS). You need to specify the client-side key file and password of the keyfile:
13871 soap_ssl_init(); /* init OpenSSL (skipping this or calling multiple times is OK, since the engine will init SSL automatically) */
13872 // soap_ssl_noinit(); /* do not init OpenSSL (if SSL is already initialized elsewhere) */
13873 if (soap_ssl_client_context(&soap,
13875 "client.pem", /* keyfile: required only when client must authenticate to server (see SSL docs on how to obtain this file) */
13876 "password", /* password to read the key file (not used with GNUTLS) */
13877 "cacerts.pem", /* cacert file to store trusted certificates (needed to verify server) */
13878 NULL, /* capath to directory with trusted certificates */
13879 NULL /* if randfile!=NULL: use a file with random data to seed randomness */
13882 soap_print_fault(&soap, stderr);
13885 soap_call_ns__mymethod(&soap, "https://domain/path/secure.cgi", "", ...);
13888 By default, server authentication is enabled and the `cacerts.pem` or
13889 `capath` (not used with GNUTLS) must be set so that the CA certificates of the server(s) are
13890 accessible at run time. The `cacerts.pem` file included in the package
13891 contains the certificates of common CAs. This file must be supplied with the
13892 client, if server authentication is required. Althernatively, you can use the
13893 `plugin/cacerts.h` and `plugin/cacerts.c` code to embed CA certificates
13894 in your client code.
13896 Other client-side SSL options are `SOAP_SSL_SKIP_HOST_CHECK` to skip the host name verification check and `SOAP_SSL_ALLOW_EXPIRED_CERTIFICATE` to allow connecting to a host with an expired certificate. For example,
13899 soap_ssl_init(); /* init OpenSSL (skipping this or calling multiple times is OK, since the engine will init SSL automatically) */
13900 // soap_ssl_noinit(); /* do not init OpenSSL (if SSL is already initialized elsewhere) */
13901 if (soap_ssl_client_context(&soap,
13902 SOAP_SSL_REQUIRE_SERVER_AUTHENTICATION
13903 | SOAP_SSL_SKIP_HOST_CHECK,
13904 | SOAP_SSL_ALLOW_EXPIRED_CERTIFICATE,
13905 "client.pem", /* keyfile: required only when client must authenticate to server (see SSL docs on how to obtain this file) */
13906 "password", /* password to read the key file (not used with GNUTLS) */
13907 "cacerts.pem", /* cacert file to store trusted certificates (needed to verify server) */
13908 NULL, /* capath to directory with trusted certificates */
13909 NULL /* if randfile!=NULL: use a file with random data to seed randomness */
13912 soap_print_fault(&soap, stderr);
13915 soap_call_ns__mymethod(&soap, "https://domain/path/secure.cgi", "", ...);
13918 For systems based on Microsoft windows, the WinInet module can be used instead, see `mod_gsoap/gsoap_win/wininet`.
13920 Since release version 2.8.20 SSL v3 is disabled. To enable SSL v3 together with TLS v1.0, v1.1, and v1.2 use `SOAP_SSLv3_TLSv1` in `soap_ssl_server_context`. To use TLS v1.1 only use `SOAP_TLSv1_1`. To use TLS v1.2 only use `SOAP_TLSv1_2`. To use SSL v3 only use `SOAP_SSLv3`.
13922 To disable server authentication for testing purposes, use the following:
13925 if (soap_ssl_client_context(&soap,
13926 SOAP_SSL_NO_AUTHENTICATION,
13934 soap_print_fault(&soap, stderr);
13939 This also assumes that the server does not require clients to authenticate (the keyfile is absent).
13941 Make sure you have signal handlers set in your application to catch broken connections (`SIGPIPE`):
13944 signal(SIGPIPE, sigpipe_handle);
13947 where, for example:
13950 void sigpipe_handle(int x) { }
13953 @warning it is important that the `WITH_OPENSSL` macro MUST be consistently defined to
13954 compile the sources, such as `stdsoap2.cpp`, `soapC.cpp`,
13955 `soapClient.cpp`, `soapServer.cpp`, and all application sources that
13956 include `stdsoap2.h` or `soapH.h`. If the macros are not consistently
13957 used, the application will crash due to a mismatches in the declaration and
13958 access of the gSOAP context.
13959 @warning concurrent client calls MUST be made using separate soap structs copied with `soap_copy` from an originating struct initialized with `soap_ssl_client_context`. In addition, the thread initialization code discussed in Section \ref serveropenssl MUST be used to properly setup OpenSSL in a multi-threaded client application.
13961 ## SSL Authentication Callbacks
13963 The `fsslauth` callback function controls OpenSSL/GNUTLS authentication initialization:
13965 * `int (*soap.fsslauth)(struct soap *soap)`
13966 Initialize the authentication information for clients and services, such as
13967 the certificate chain, password, read the key and/or DH file, generate an RSA
13968 key, and initialization of the RNG. Should return a gSOAP error code or
13969 `SOAP_OK`. Built-in gSOAP function: `ssl_auth_init`
13971 The `fsslverify` callback function controls OpenSSL peer certificate
13972 verification, via internally invoking `SSL_CTX_set_verify`:
13974 * `int (*soap.fssverify)(int ok, X509_STORE_CTX *store`
13975 Used to control the certificate verification behaviour when the
13976 `SOAP_SSL_REQUIRE_CLIENT_AUTHENTICATION` or
13977 `SOAP_SSL_REQUIRE_SERVER_AUTHENTICATION` flags are specified with
13978 `soap_ssl_client_context` and `soap_ssl_server_context`. It receives two
13979 arguments: `ok` indicates, whether the verification of the certificate in
13980 question was passed (`ok=1`) or not (]blk{ok=0}). If the callback returns 0,
13981 the verification process is immediately stopped with "verification failed"
13982 state. A verification failure alert is sent to the peer and the TLS/SSL
13983 handshake is terminated. If the callback returns 1, the verification process
13984 is continued. Built-in gSOAP function: `ssl_verify_callback` and
13985 `ssl_verify_callback_allow_expired_certificate`. These functions are used
13986 when `fsslverify` is initially set to `NULL` and were not reassigned before
13987 `soap_ssl_client_context` or `soap_ssl_server_context` are called.
13989 ## SSL Certificates and Key Files {#ssl}
13991 The gSOAP distribution includes a `cacerts.pem` file with the certificates
13992 of all certificate authorities (such as Verisign). You can use this file to
13993 verify the authentication of servers that provide certificates issued by these
13994 CAs. Just set the `cafile` parameter to the location of this file on your
13995 file system. Therefore, when you obtain a certifice signed by a trusted CA
13996 such as Verisign, you can simply use the `cacerts.pem` file to develop
13997 client applications that can verify the authenticity of your server.
13999 Althernatively, you can use the `plugin/cacerts.h` and
14000 `plugin/cacerts.c` code to embed CA certificates in your client code.
14002 For systems based on Microsoft windows, the WinInet module can be used instead,
14003 see the `README.txt` located in the package under
14004 `mod_gsoap/gsoap_win/wininet`.
14006 The other `.pem` files in the gSOAP distribution are examples
14007 of self-signed certificates for testing purposes (`cacert.pem`, `client.pem`, `server.pem`). The `client.pem` and `server.pem` contain the private key and certificate of the client or server, respectively. The keyfiles (`client.pem` and `server.pem`) are created by concatenating the private key PEM with the certificate PEM. The keyfile SHOULD NEVER be shared with any party. With OpenSSL, you can encrypt the keyfiles with a password to offer some protection and the password is used in the client/server code to read the keyfile. GNUTLS does not support this feature and cannot encrypt or decrypt a keyfile.
14009 You can also create your own self-signed certificates. There is more than one
14010 way to generate the necessary files for clients and servers.
14011 See `http://www.openssl.org` for information on OpenSSL and
14012 `http://sial.org/howto/openssl/ca/` on how to setup and manage a local CA
14013 and `http://sial.org/howto/openssl/self-signed/` on how to setup self-signed
14016 It is possible to convert IIS-generated certificates to PEM format with the openssl library and openssl command-line tool:
14019 openssl x509 -in mycert.cer -inform DER -out mycert.pem -outform PEM
14022 This converts the CRT-formatted mycert.cer to PEM-formatted mycert.pem.
14024 Here is the simplest way to setup self-signed certificates. First you need to create a private Certificate Authority (CA). The CA is used in SSL to verify the authenticity of a given
14025 certificate. The CA acts as a trusted third party who has authenticated the
14026 user of the signed certificate as being who they say. The certificate is
14027 signed by the CA, and if the client trusts the CA, it will trust your
14028 certificate. For use within your organization, a private CA will probably
14029 serve your needs. However, if you intend use your certificates for a public
14030 service, you should probably obtain a certificate from a known CA (e.g. VeriSign).
14031 In addition to identification, your certificate is also used for encryption.
14033 Creating certificates should be done through a CA to obtain signed certificates. But you can create your own certificates for testing purposes as follows.
14036 * Go to the OpenSSL bin directory (`/usr/local/ssl` by default and
14037 `/System/Library/OpenSSL` on Mac OS X)
14039 * There should be a file called openssl.cnf
14041 * Create a new directory in your home account, e.g. $HOME/CA, and copy the openssl.cnf file to this directory
14043 * Modify openssl.cnf by changing the 'dir' value to HOME/CA
14045 * Copy the README.txt, root.sh, and cert.sh scripts from the gSOAP distribution package located in the samples/ssl directory to HOME/CA
14047 * Follow the README.txt instructions
14049 You now have a self-signed CA root certificate cacert.pem and a server.pem (or client.pem) certificate in PEM format.
14050 The cacert.pem certificate is used in the `cafile` parameter of the `soap_ssl_client_context` (or `soap_ssl_server_context`) at the client (or server) side to verify the authenticity of the peer. You can also provide a capath parameter to these trusted certificates. The server.pem (or client.pem) must be provided with the `soap_ssl_server_context` at the server side (or `soap_ssl_client_context` at the client side) together with the password you entered when generating the certificate using cert.sh to access the file. These certificates must be present to grant authentication requests by peers. In addition, the server.pem (and client.pem) include the host name of the machine on which the application runs (e.g. localhost), so you need to generate new certificates when migrating a server (or client).
14052 Finally, you need to generate Diffie-Helmann (DH) parameters for the server if
14053 you wish to use DH instead of RSA. There are two options:
14056 * Set the `dhfile` parameter to the numeric DH prime length in bits
14057 required (for example "1024") to let the engine generate DH parameters at
14058 initialization. This can be time consuming.
14060 * Provide a file name for the `dhfile` parameter of
14061 `soap_ssl_server_context`. The file should be generated beforehand. To
14062 do so with the OpenSSL command line tool, use:
14064 > openssl dhparam -outform PEM -out dh.pem 512
14066 File `dh512.pem` is the output file and 512 is the number of bits used.
14069 ## SSL Hardware Acceleration
14071 You can specify a hardware engine to enable hardware support for cryptographic acceleration. This can be done once in a server or client with the following statements:
14074 static const char *engine = "cswift"; /* engine name */
14079 if (!(e = ENGINE_by_id(engine)))
14080 fprintf(stderr, "Error finding engine %s\n", engine);
14081 else if (!ENGINE_set_default(e, ENGINE_METHOD_ALL))
14082 fprintf(stderr, "Error using engine %s\n", engine);
14086 The following table lists the names of the hardware and software engines:
14089 -------------------- | ------
14090 `openssl` | The default software engine for cryptographic operations
14091 `openbsd_dev_crypto` | OpenBSD supports kernel level cryptography
14092 `cswift` | CryptoSwift acceleration hardware
14093 `chil` | nCipher CHIL acceleration hardware
14094 `atalla` | Compaq Atalla acceleration hardware
14095 `nuron` | Nuron acceleration hardware
14096 `ubsec` | Broadcom uBSec acceleration hardware
14097 `aep` | Aep acceleration hardware
14098 `sureware` | SureWare acceleration hardware
14102 Set the full path to libssl.lib and libcrypto.lib
14103 under the MSVC++ "Projects" menu, then choose "Link": "Object/Modules".
14104 Please make sure `libssl32.dll` and `libeay32.dll` can be loaded by
14105 gSOAP applications, thus they must be installed properly on the target
14108 If you're using compilation settings such as `/MTd` then link to the correct `libeay32MTd.lib` and `ssleay32MTd.lib` libraries.
14110 Alternatively, you can use the WinInet interface available in the `mod_gsoap` directory of the gSOAP package. API instructions are included in the source.
14112 ## Zlib Compression {#compression}
14114 To enable deflate and gzip compression with Zlib, install Zlib from
14115 http://www.zlib.org if not already installed on your system. Compile
14116 `stdsoap2.cpp` (or `stdsoap2.c`) and **all** your sources that include
14117 `stdsoap2.h` or `soapH.h` with compiler option `-DWITH_GZIP` and
14118 link your code with the Zlib library, e.g. `-lz` on Unix/Linux platforms.
14120 The gzip compression is orthogonal to all transport encodings such as HTTP,
14121 SSL, DIME, and can be used with other transport layers. You can even save and
14122 load compressed XML data to/from files.
14124 gSOAP supports two compression formats: deflate and gzip. The gzip format is
14125 used by default. The gzip format has several benefits over deflate. Firstly,
14126 gSOAP can automatically detect gzip compressed inbound messages, even without
14127 HTTP headers, by checking for the presence of a gzip header in the message
14128 content. Secondly, gzip includes a CRC32 checksum to ensure messages have been
14129 correctly received. Thirdly, gzip compressed content can be decompressed with
14130 other compression software, so you can decompress XML data saved by gSOAP in
14133 Gzip compression is enabled by compiling the sources with `-DWITH_GZIP`.
14134 To transmit gzip compressed SOAP/XML data, set the output mode flags to
14135 `SOAP_ENC_ZLIB`. For example:
14140 soap_set_omode(&soap, SOAP_ENC_ZLIB); // enable Zlib's gzip
14141 if (soap_call_ns__myMethod(&soap, ...))
14143 soap_clr_omode(&soap, SOAP_ENC_ZLIB); // disable Zlib's gzip
14147 This will send a compressed SOAP/XML request to a service, provided that Zlib is
14148 installed and linked with the application and the `-DWITH_GZIP` option was used to compile the sources.
14149 Receiving compressed SOAP/XML over HTTP either in gzip or deflate formats is automatic. The `SOAP_ENC_ZLIB` flag does not have
14150 to be set at the server side to accept compressed messages. Reading and receiving gzip compressed SOAP/XML without HTTP headers (e.g. with other transport protocols) is also automatic.
14152 To control the level of compression for outbound messages, you can set the `soap.z_level` to a value between 1 and 9, where 1 is the best speed and 9 is the best compression (default is 6). For example
14157 soap_set_omode(&soap, SOAP_ENC_ZLIB);
14158 soap.z_level = 9; // best compression
14162 To verify and monitor compression rates, you can use the values `soap.z_ratio_in` and `soap.z_ratio_out`. These two float values lie between 0.0 and 1.0 and express the ratio of the compressed message length over uncompressed message length.
14165 soap_call_ns__myMethod(&soap, ...);
14167 printf("Compression ratio: %f%% (in) %f%% (out)\n", 100*soap.z_ratio_out, 100*soap.z_ratio_in);
14171 Note: lower ratios mean higher compression rates.
14173 Compressed transfers require buffering the entire output message to determine HTTP message length.
14174 This means that the `SOAP_IO_STORE` flag is
14175 automatically set when the `SOAP_ENC_ZLIB` flag is set to send compressed messages. The use of HTTP chunking
14176 significantly reduces memory usage and may speed up the transmission of compressed SOAP/XML messages.
14177 This is accomplished by setting the `SOAP_IO_CHUNK` flag with
14178 `SOAP_ENC_ZLIB` for the output mode.
14179 However, some Web servers do not accept HTTP chunked request messages (even when they return HTTP chunked messages!). Stand-alone gSOAP services always accept chunked request messages.
14181 To restrict the compression to the deflate format only, compile the sources with `-DWITH_ZLIB`. This limits compression and decompression to the deflate format. Only plain and deflated messages can be exchanged, gzip is not supported with this option.
14182 Receiving gzip compressed content is automatic, even in the absence of HTTP headers.
14183 Receiving deflate compressed content is not automatic in the absence of HTTP headers and requires the flag
14184 `SOAP_ENC_ZLIB` to be set for the input mode to decompress deflated data.
14186 @warning it is important that the `WITH_GZIP` and `WITH_ZLIB` macros MUST be consistently defined to
14187 compile the sources, such as `stdsoap2.cpp`, `soapC.cpp`,
14188 `soapClient.cpp`, `soapServer.cpp`, and all application sources that
14189 include `stdsoap2.h` or `soapH.h`. If the macros are not consistently
14190 used, the application will crash due to a mismatches in the declaration and
14191 access of the gSOAP context.
14193 ## Client-Side Cookie Support {#clientcookie}
14195 Client-side cookie support is optional. To enable cookie support, compile all sources with option `-DWITH_COOKIES`, for example:
14197 > c++ -DWITH_COOKIES -o myclient stdsoap2.cpp soapC.cpp soapClient.cpp
14199 or add the following line to `stdsoap.h`:
14202 #define WITH_COOKIES
14205 Client-side cookie support is fully automatic. So just (re)compile `stdsoap2.cpp` with `-DWITH_COOKIES` to enable
14206 cookie-based session control in your client.
14208 A database of cookies is kept and returned to the appropriate servers.
14209 Cookies are not automatically saved to a file by a client. An example cookie
14210 file manager is included as an extras in the distribution. You should
14211 explicitly remove all cookies before terminating a gSOAP context by
14212 calling `soap_free_cookies(soap)` or by calling `soap_done(soap)`.
14214 To avoid "cookie storms" caused by malicious servers that return an
14215 unreasonable amount of cookies, gSOAP clients/servers are restricted to
14216 a database size that the user can limit (32 cookies by default), for example:
14221 soap.cookie_max = 10;
14224 The cookie database is a linked list pointed to by `soap.cookies` where each node is declared as:
14233 long expire; /* client-side: local time to expire; server-side: seconds to expire */
14234 unsigned int version;
14236 short session; /* server-side */
14237 short env; /* server-side: 1 = got cookie from client */
14238 short modified; /* server-side: 1 = client cookie was modified */
14239 struct soap_cookie *next;
14243 Since the cookie database is linked to a `soap` struct, each thread has a local cookie database in a multi-threaded
14246 ## Server-Side Cookie Support {#servercookie}
14248 Server-side cookie support is optional. To enable cookie support, compile all sources with option `-DWITH_COOKIES`, for example:
14250 > c++ -DWITH_COOKIES -o myserver ...
14252 gSOAP provides the following cookie API for server-side cookie session control:
14254 * `struct soap_cookie *soap_set_cookie(struct soap *soap, const char *name, const char *value, const char *domain, const char *path);`
14255 Add a cookie to the database with name `name` and value `value`. `domain`
14256 and `path` may be NULL to use the current domain and path given by
14257 `soap_cookie_domain` and `soap_cookie_path`. If successful, returns pointer
14258 to a cookie node in the linked list, or NULL otherwise.
14260 * `struct soap_cookie *soap_cookie(struct soap *soap, const char *name, const char *domain, const char *path);`
14261 Find a cookie in the database with name `name` and value `value`. `domain`
14262 and `path` may be NULL to use the current domain and path given by
14263 `soap_cookie_domain` and `soap_cookie_path`. If successful, returns pointer
14264 to a cookie node in the linked list, or NULL otherwise.
14266 * `char *soap_cookie_value(struct soap *soap, const char *name, const char *domain, const char *path);`
14267 Get value of a cookie in the database with name `name`. `domain` and `path`
14268 may be NULL to use the current domain and path given by `soap_cookie_domain`
14269 and `soap_cookie_path`. If successful, returns the string pointer to the
14270 value, or NULL otherwise.
14272 * `long soap_cookie_expire(struct soap *soap, const char *name, const char *domain, const char *path);`
14273 Get expiration value of the cookie in the database with name `name` (in
14274 seconds). `domain` and `path` may be NULL to use the current domain and
14275 path given by `soap_cookie_domain` and `soap_cookie_path`. Returns the
14276 expiration value, or -1 if cookie does not exist.
14278 * `int soap_set_cookie_expire(struct soap *soap, const char *name, long expire, const char *domain, const char *path);`
14279 Set expiration value `expire` of the cookie in the database with name `name`
14280 (in seconds). `domain` and `path` may be NULL to use the current domain and
14281 path given by `soap_cookie_domain` and `soap_cookie_path`. If successful,
14282 returns `SOAP_OK`, or `SOAP_EOF` otherwise.
14284 * `int soap_set_cookie_session(struct soap *soap, const char *name, const char *domain, const char *path);`
14285 Set cookie in the database with name `name` to be a session cookie. This
14286 means that the cookie will be returned to the client. (Only cookies that are
14287 modified are returned to the client). `domain` and `path` may be NULL to
14288 use the current domain and path given by `soap_cookie_domain` and
14289 `soap_cookie_path`. If successful, returns `SOAP_OK`, or `SOAP_EOF`
14292 * `int soap_clr_cookie_session(struct soap *soap, const char *name, const char *domain, const char *path);`
14293 Clear cookie in the database with name `name` to be a session cookie.
14294 `domain` and `path` may be NULL to use the current domain and path given by
14295 `soap_cookie_domain` and `soap_cookie_path`. If successful, returns
14296 `SOAP_OK`, or `SOAP_EOF` otherwise.
14298 * `void soap_clr_cookie(struct soap *soap, const char *name, const char *domain, const char *path);`
14299 Remove cookie from the database with name `name`. `domain` and `path` may be
14300 NULL to use the current domain and path given by `soap_cookie_domain` and
14301 `soap_cookie_path`.
14303 * `int soap_getenv_cookies(struct soap *soap);`
14304 Initializes cookie database by reading the `HTTP_COOKIE` environment
14305 variable. This provides a means for a CGI application to read cookies send
14306 by a client. If successful, returns `SOAP_OK`, or `SOAP_EOF` otherwise.
14308 * `void soap_free_cookies(struct soap *soap);`
14309 Release cookie database.
14311 The following global variables are used to define the current domain and path:
14313 * `const char *cookie_domain` MUST be set to the domain (host) of the service
14315 * `const char *cookie_path` MAY be set to the default path to the service
14317 * `int cookie_max` maximum cookie database size (default=32)
14319 The `cookie_path` value is used to filter cookies intended for this service according to the path prefix rules outlined in
14322 The following example server adopts cookies for session control:
14330 soap.cookie_domain = "...";
14331 soap.cookie_path = "/"; // the path which is used to filter/set cookies with this destination
14334 soap_getenv_cookies(&soap); // CGI app: grab cookies from 'HTTP_COOKIE' env var
14339 m = soap_bind(&soap, NULL, atoi(argv[1]), 100);
14342 for (int i = 1; ; i++)
14344 s = soap_accept(&soap);
14348 soap_end(&soap); // clean up
14349 soap_free_cookies(&soap); // remove all old cookies from database so no interference occurs with the arrival of new cookies
14354 int ck__demo(struct soap *soap, ...)
14358 s = soap_cookie_value(soap, "demo", NULL, NULL); // cookie returned by client?
14360 s = "init-value"; // no: set initial cookie value
14362 ... // modify 's' to reflect session control
14363 soap_set_cookie(soap, "demo", s, NULL, NULL);
14364 soap_set_cookie_expire(soap, "demo", 5, NULL, NULL); // cookie may expire at client-side in 5 seconds
14369 ## Connecting Clients Through Proxy Servers
14371 When a client needs to connect to a Web Service through a proxy server, set the `soap.proxy_host` string and
14372 `soap.proxy_port` integer attributes of the current `soap` runtime context to the proxy's host name and port, respectively. For example:
14377 soap.proxy_host = "proxyhostname";
14378 soap.proxy_port = 8080;
14379 if (soap_call_ns__method(&soap, "http://host:port/path", "action", ...))
14380 soap_print_fault(&soap, stderr);
14385 The context attributes `soap.proxy_host` and `soap.proxy_port` keep their values through a sequence of service operation calls,
14386 so they only need to be set once.
14388 When X-Forwarded-For headers are returned by the proxy, the header can be accessed in the `soap.proxy_from` string.
14390 ## Bind Before Connect and Setting the Client Interface Address
14392 To bind the client to a port before connect, set the `soap.client_port` to a non-negative port number:
14397 soap.client_port = ...; // non-negative port number
14398 if (soap_call_ns__method(&soap, "http://host:port/path", "action", ...))
14399 soap_print_fault(&soap, stderr);
14404 This port number is used only once and reset to -1 (disabled). Set it again for the next call.
14406 To set a client interface address for the connection that is an IP address of the client:
14411 soap.client_interface = "..."; // IP address
14412 if (soap_call_ns__method(&soap, "http://host:port/path", "action", ...))
14413 soap_print_fault(&soap, stderr);
14418 This client interface address string is used only once and reset to NULL (disabled). Set it again for the next call. This feature is not available when compiling the code on windows.
14420 ## FastCGI Support {#fastcgi}
14422 To enable FastCGI support, install FastCGI and compile *all* sources (do
14423 not use `libgsoap` but compile `stdsoap2.c`) and your application
14424 sources with option `-DWITH_FASTCGI` or add
14427 #define WITH_FASTCGI
14430 to `stdsoap2.h` and recompile the project code.
14432 @warning Do not link against the `libgsoap` libraries as these are not
14433 suitable for FastCGI. Compile `stdsoap2.c` (or `stdsoap2.cpp`) instead.
14435 ## How to Create gSOAP Applications With a Small Memory Footprint {#lean}
14437 To compile gSOAP applications intended for small memory devices, you may want
14438 to remove all non-essential features that consume precious code and data space.
14439 To do this, compile the gSOAP sources with `-DWITH_LEAN` (i.e. `#define WITH_LEAN`) to remove many
14440 non-essential features. The features that will be disabled are:
14443 * No I/O timeouts. Note that many socket operations already obey some form of timeout handling, such as a connect timeout for example.
14447 * No HTTP keep alive
14451 * No HTTP authentication
14453 * No HTTP chunked output (but input is OK)
14455 * No HTTP compressed output (but input is OK when compiled with `WITH_GZIP`)
14457 * No send/recv timeouts
14459 * No socket flags (no `soap.socket_flag, soap.connect_flag, soap.bind_flag, soap.accept_flag`)
14461 * No canonical XML output
14465 * Limited TCP/IP and HTTP error diagnostic messages
14467 * No support for `time_t` serialization
14469 * No support for `hexBinary` XML attribute serialization (remap `hexBinary` to strings by adding a remap entry to typemap.dat)
14471 Use `-DWITH_LEANER` to make the executable even smaller by removing DIME
14472 and MIME attachment handling, `LONG64` (64 bit) serialization, `wchar_t*` serialization, and support for XML DOM operations.
14473 Note that DIME/MIME attachments are not essential to achieve
14474 SOAP/XML interoperability. DIME attachments are a convenient way to exchange
14475 non-text-based (i.e. binary) content, but are not required for basic SOAP/XML
14476 interoperability. Attachment requirements are predictable. That is,
14477 applications won't suddenly decide to use DIME or MIME instead of XML to exchange
14480 It is safe to try to compile your application with `-DWITH_LEAN`, provided
14481 that your application does not rely on I/O timeouts. When no linkage error
14482 occurs in the compilation process, it is safe to assume that your application
14483 will run just fine.
14485 ## How to Eliminate BSD Socket Library Linkage {#noio}
14487 The `stdsoap2.c` and `stdsoap2.cpp` gSOAP runtime libraries should be linked with a BSD socket library in the project build, e.g. winsock2 for Win32. To eliminate the need to link a socket library, you can compile `stdsoap2.c` (for C) and `stdsoap2.cpp` (for C++) with the `-DWITH_NOIO` macro set (i.e. `#define WITH_NOIO`). This eliminates the dependency on the BSD socket API, IO streams, `FILE` type, and `errno`.
14489 As a consequence, you MUST define callbacks to replace the missing socket stack. To do so, add to your code the following definitions:
14494 /* fsend is used to transmit data in blocks */
14495 soap.fsend = my_send;
14496 /* frecv is used to receive data in blocks */
14497 soap.frecv = my_recv;
14498 /* fopen is used to connect */
14499 soap.fopen = my_tcp_connect;
14500 /* fclose is used to disconnect */
14501 soap.fclose = my_tcp_disconnect;
14502 /* fclosesocket is used only to close the master socket in a server upon soap_done() */
14503 soap.fclosesocket = my_tcp_closesocket;
14504 /* fshutdownsocket is used after completing a send operation to send TCP FIN */
14505 soap.fshutdownsocket = my_tcp_shutdownsocket;
14506 /* setting fpoll is optional, leave it NULL to omit polling the server */
14507 soap.fpoll = my_poll;
14508 /* faccept is used only by a server application */
14509 soap.faccept = my_accept;
14512 These functions are supposed to provide a (minimal) transport stack.
14513 See Section \ref callback for more details on the use of these callbacks.
14514 All callback function pointers should be non-NULL, except `fpoll`.
14516 You cannot use `soap_print_fault` and `soap_print_fault_location` to print error diagnostics. Instead, the value of `soap.error`, which contains the gSOAP error code, can be used to determine the cause of a fault.
14518 ## How to Combine Multiple Client and Server Implementations into one Executable
14520 The `wsdl2h` tool can be used to import multiple WSDLs and schemas at once.
14521 The service definitions are combined in one header file to be parsed by
14522 `soapcpp2`. It is important to assign namespace prefixes to namespace URIs
14523 using the `typemap.dat` file. Otherwise, `wsdl2h` will assign namespace
14524 prefixes `ns1`, `ns2`, and so on to the service operations and schema
14525 types. Thus, any change to a WSDL or schema may result in a new prefix
14526 assignment. For more details, please see Section \ref typemap .
14528 Another approach to combine multiple client and service applications into one
14529 executable is by using C++ namespaces to structurally separate the definitions
14530 or by creating C libraries for the client/server objects as explained in
14531 subsequent sections. This is automated with `wsdl2h` option `-q`.
14533 Both approaches are demonstrated by example in the gSOAP distribution, the `samples/link` (C only) and `samples/link++` (C++ with C++ namespaces) examples.
14535 ## How to Build a Client or Server in a C++ Code Namespace {#codenamespace}
14537 You can use a C++ code namespace of your choice in your header file to build
14538 a client or server in that code namespace. In this way, you can create multiple
14539 clients and servers that can be combined and linked together without conflicts,
14540 which is explained in more detail in the next section (which also shows an
14541 example combining two client libraries defined in two C++ code namespaces).
14543 Use `wsdl2h` option `-q`*name* to generate definitions in the C++ *name* namespace. This option can also be used in combination with C++ proxy and server object generation, using `soapcpp2` options `-i` (or `-j`) and `-p`.
14545 At most one namespace can be defined for the entire gSOAP header file. The code
14546 namespace MUST completely encapsulate the entire contents of the header file:
14549 namespace myNamespaceName {
14550 ... gSOAP header file contents ...
14554 When compiling this header file with the gSOAP `soapcpp2` compiler, all type definitions,
14555 the (de)serializers for these types, and the stub/skeleton codes will be placed
14556 in this namespace. The XML namespace mapping table (saved in a `.nsmap`
14557 file) will not be placed in the code namespace to allow it to be linked as a
14558 global object. You can use option `-n` to create local XML namespace
14559 tables, see Section \ref options (but remember that you explicitly need to
14560 initialize the `soap.namespaces` to point to a table at run time). The
14561 generated files are prefixed with the code namespace name instead of the usual
14562 `soap` file name prefix to enable multiple client/server codes to be build
14563 in the same project directory (a code namespace automatically sets the `-p`
14564 compiler option, see Section \ref options for options).
14566 Because the SOAP Header and Fault serialization codes will also be placed in
14567 the namespace, they cannot be called from the `stdsoap2.cpp` run time
14568 library code and are therefore rendered unusable. Therefore, these serializers
14569 are not compiled at all (enforced with `#define WITH_NOGLOBAL`). To add SOAP
14570 Header and Fault serializers, you MUST compile them separately as follows.
14571 First, create a new header file `env.h` with the SOAP Header and Fault
14572 definitions. You can leave this header file empty if you want to use the
14573 default SOAP Header and Fault. Then compile this header file with:
14575 > soapcpp2 -penv env.h
14577 The generated `envC.cpp` file holds the SOAP Header and Fault serializers and you can
14578 link this file with your client or server application.
14580 ## How to Create Client/Server Libraries {#dylibs}
14582 The gSOAP `soapcpp2` compiler produces `soapClientLib.cpp` and `soapServerLib.cpp`
14583 codes that are specifically intended for building static or dynamic
14584 client/server libraries. These codes export the stubs and skeletons, but keep
14585 all marshaling code (i.e. parameter serializers and deserializers) local (i.e.
14586 as static functions) to avoid link symbol conflicts when combining multiple
14587 clients and/or servers into one executable. Note that it is far simpler to use
14588 the `wsdl2h` tool on multiple WSDL files to generate a header file that
14589 combines all service definitions. However, the approach presented in this
14590 section is useful when creating (dynamic) libraries for client and server
14591 objects, such as DLLs as described in Section \ref dll .
14593 Do not link `soapClientLib.cpp` or `soapServerLib.cpp` together with `soapC.cpp`, `soapClient.cpp`, and `soapServer.cpp`. The library versions already include all of the necessary definitions.
14595 To build multiple libraries in the same project directory, you can define a C++
14596 code namespace in your header file (see Section \ref codenamespace ) or you
14597 can use `soapcpp2` with option `-p` to rename the generated
14598 `soapClientLib.cpp` and `soapServerLib.cpp` (and associated) files. The
14599 `-p` option specifies the file name prefix to replace the `soap`
14600 prefix. The libraries don't have to be C++ codes. You can use option `-c`
14601 to generate C code. A clean separation of libraries can also be achieved with
14602 C++ code namespaces, see Section \ref codenamespace .
14604 The library codes do not define SOAP Header and Fault serializers. You MUST
14605 add SOAP Header and Fault serializers to your application, which are compiled
14606 separately as follows. First, create a new header file `env.h` with the
14607 SOAP Header and Fault definitions. You can leave this header file empty if you
14608 want to use the default SOAP Header and Fault. Then compile this header file
14611 > soapcpp2 -penv env.h
14613 The generated `envC.cpp` file holds the SOAP Header and Fault serializers and you can
14614 create a (dynamic) library for it to link this code with your client or server application.
14616 You MUST compile the `stdsoap2.cpp` library using `-DWITH_NONAMESPACES`:
14618 > c++ -DWITH_NONAMESPACES -c stdsoap2.cpp
14620 This omits the reference to the global namespaces table, which is nowhere
14621 to be defined since we will use XML namespaces for each client/service separately. Therefore, you MUST explicitly set the
14622 namespaces value of the gSOAP context in your code every time after initialization of the soap struct with the `soap_set_namespaces(struct soap*, const struct Namespace*)` function.
14624 For example, suppose we have two clients defined in header files `client1.h` and `client2.h`. We first generate the `envH.h` file for the SOAP Header and Fault definitions:
14626 > soapcpp2 -c -penv env.h
14628 Then we generate the code for client1 and client2:
14630 > soapcpp2 -c -n -pmyClient1 client1.h
14631 > soapcpp2 -c -n -pmyClient2 client2.h
14633 This generates `myClient1ClientLib.c` and `myClient2ClientLib.c` (among many other files).
14634 These two files should be compiled and linked with your application.
14635 The source code of your application should include the generated `envH.h`, `myClient1H.h`, `myClient2.h` files and `myClient1.nsmap`, `myClient2.nsmap` files:
14638 #include "myClient1H.h" // include client 1 stubs
14639 #include "myClient2H.h" // include client 2 stubs
14642 #include "myClient1H.nsmap" // include client 1 nsmap
14643 #include "myClient2H.nsmap" // include client 2 nsmap
14646 soap_set_namespaces(&soap, myClient1_namespaces);
14647 ... make Client 1 invocations ...
14649 soap_set_namespaces(&soap, myClient2_namespaces);
14650 ... make Client 2 invocations ...
14653 It is important to use `soapcpp2` option `-n`, see Section \ref options , to rename the namespace tables so we can include them all without running into redefinitions.
14655 Note: Link conflicts may still occur in the unlikely situation that identical service operation names are defined in
14656 two or more client stubs or server skeletons when these methods share the same XML namespace prefix. You may have to use C++ code
14657 namespaces to avoid these link conflicts or rename the namespace prefixes used by the service operation defined in the header files.
14659 ### C++ Clients Example
14661 As an example we will build a Delayed Stock Quote client library and a Currency Exchange Rate client library.
14663 First, we create an empty header file `env.h` (which may contain optional SOAP Header and Fault definitions), and compile it as follows:
14665 > soapcpp2 -penv env.h
14668 We also compile `stdsoap2.cpp` without namespaces:
14670 > c++ -c -DWITH_NONAMESPACES stdsoap2.cpp
14672 Note: when you forget to use `-DWITH_NONAMESPACES` you will get an unresolved link error for the global `namespaces` table. You can define a dummy table to avoid having to recompile `stdsoap2.cpp`.
14674 Second, we create the Delayed Stock Quote header file specification, which may be obtained using the WSDL importer. If you want to use C++ namespaces then you need to manually add the `namespace` declaration to the generated header file:
14678 //gsoap ns service name: Service
14679 //gsoap ns service style: rpc
14680 //gsoap ns service encoding: encoded
14681 //gsoap ns service location: http://services.xmethods.net/soap
14682 //gsoap ns schema namespace: urn:xmethods-delayed-quotes
14683 //gsoap ns service method-action: getQuote ""
14684 int ns__getQuote(char *symbol, float &Result);
14688 We then compile it as a library and we use option `-n` to rename the namespace table to avoid link conflicts later:
14690 > soapcpp2 -n quote.h
14691 > c++ -c quoteClientLib.cpp
14693 If you don't want to use a C++ code namespace, you should compile `quote.h` "as is" with soapcpp2 option `-pquote`:
14695 > soapcpp2 -n -pquote quote.h
14696 > c++ -c quoteClientLib.cpp
14698 Third, we create the Currency Exchange Rate header file specification:
14702 //gsoap ns service name: Service
14703 //gsoap ns service style: rpc
14704 //gsoap ns service encoding: encoded
14705 //gsoap ns service location: http://services.xmethods.net/soap
14706 //gsoap ns schema namespace: urn:xmethods-CurrencyExchange
14707 //gsoap ns service method-action: getRate ""
14708 int ns__getRate(char *country1, char *country2, float &Result);
14712 Similar to the Quote example above, we compile it as a library and we use option `-n` to rename the namespace table to avoid link conflicts:
14714 > soapcpp2 -n rate.h
14716 Fourth, we consider linking the libraries to the main program.
14717 The main program can import the `quoteServiceProxy.h` and `rateServiceProxy.h` files to obtain client proxies to invoke the services. The proxy implementations are defined in `quoteClient.cpp`.
14718 The `-n` option also affects the generation of the C++ proxy codes to ensure that the gSOAP context is properly initialized with the appropriate namespace table (so you don't have to initialize explicitly -- this feature is only available with C++ proxy and server object classes).
14721 #include "quoteServiceProxy.h" // get quote Service proxy
14722 #include "rateServiceProxy.h" // get rate Service proxy
14723 #include "quote.nsmap" // get quote namespace bindings
14724 #include "rate.nsmap" // get rate namespace bindings
14725 int main(int argc, char *argv[])
14729 std::cerr << "Usage: main ticker [currency]" << std::endl
14732 quote::Service quote;
14734 if (quote.getQuote(argv[1], q)) // get quote
14735 soap_print_fault(quote.soap, stderr);
14740 rate::Service rate;
14742 if (rate.getRate("us", argv[2], r)) // get rate in US dollars
14743 soap_print_fault(rate.soap, stderr);
14745 q *= r; // convert the quote
14747 std::cout << argv[1] << ": " << q << std::endl;
14753 Compile and link this application with `stdsoap2.o`, `envC.o`, `quoteServerProxy.o`, and `rateServerProxy.o`.
14755 To compile and link a server object is very similar. For example, assume that we need to implement a calculator service and we want to create a library for it.
14759 //gsoap ns service name: Service
14760 //gsoap ns service style: rpc
14761 //gsoap ns service encoding: encoded
14762 //gsoap ns service location: http://www.cs.fsu.edu/~engelen/calc.cgi
14763 //gsoap ns schema namespace: urn:calc
14764 int ns__add(double a, double b, double &result);
14765 int ns__sub(double a, double b, double &result);
14766 int ns__mul(double a, double b, double &result);
14767 int ns__div(double a, double b, double &result);
14771 We compile this with:
14773 > soapcpp2 -n calc.h
14775 The effect of the `-n` option is that it creates local namespace tables, and a modified `calcServiceObject.h` server class definitions that properly initialize the gSOAP run time with the table.
14778 #include "calcServiceObject.h" // get Service object
14779 #include "calc.nsmap" // get calc namespace bindings
14781 calc::Service calc;
14782 calc.serve(); // calls request dispatcher to invoke one of the functions below
14784 int calc::Service::add(double a, double b, double &result);
14785 { result = a + b; return SOAP_OK; }
14786 int calc::Service::sub(double a, double b, double &result);
14787 { result = a - b; return SOAP_OK; }
14788 int calc::Service::mul(double a, double b, double &result);
14789 { result = a * b; return SOAP_OK; }
14790 int calc::Service::div(double a, double b, double &result);
14791 { result = a / b; return SOAP_OK; }
14794 In fact, the `calc::Service` class is derived from the `struct soap`. So the context
14795 is available as `this`, which can be passed to all gSOAP functions that require a soap struct
14798 The example above serves requests over stdin/out. Use the bind and accept calls to create a stand-alone server to service inbound requests over sockets, see \ref stand-alone .
14800 ### C Clients Example
14802 This is the same example as above, but the clients are build with pure C.
14804 We create a `env.h` that contains the joint SOAP Header and SOAP Fault
14805 definitions. You may have to copy-paste these from the other header files.
14806 Then, compile it as follows:
14808 > soapcpp2 -c -penv env.h
14811 We also compile `stdsoap2.c` without namespaces:
14813 > cc -c -DWITH_NONAMESPACES stdsoap2.c
14815 Second, we create the Delayed Stock Quote header file specification, which may be obtained using the WSDL importer.
14818 //gsoap ns service name: Service
14819 //gsoap ns service style: rpc
14820 //gsoap ns service encoding: encoded
14821 //gsoap ns service location: http://services.xmethods.net/soap
14822 //gsoap ns schema namespace: urn:xmethods-delayed-quotes
14823 //gsoap ns service method-action: getQuote ""
14824 int ns__getQuote(char *symbol, float *Result);
14827 We compile it as a library and we use options `-n` and `-p` to rename the namespace table to avoid link conflicts:
14829 > soapcpp2 -c -n -pquote quote.h
14830 > cc -c quoteClientLib.c
14832 Third, we create the Currency Exchange Rate header file specification:
14835 //gsoap ns service name: Service
14836 //gsoap ns service style: rpc
14837 //gsoap ns service encoding: encoded
14838 //gsoap ns service location: http://services.xmethods.net/soap
14839 //gsoap ns schema namespace: urn:xmethods-CurrencyExchange
14840 //gsoap ns service method-action: getRate ""
14841 int ns__getRate(char *country1, char *country2, float *Result);
14844 We compile it as a library and we use options `-n` and `-p` to rename the namespace table to avoid link conflicts:
14846 > soapcpp2 -c -n -prate rate.h
14847 > cc -c rateClientLib.c
14849 The main program is:
14852 #include "quoteStub.h" // get quote Service stub
14853 #include "rateStub.h" // get rate Service stub
14854 #include "quote.nsmap" // get quote namespace bindings
14855 #include "rate.nsmap" // get rate namespace bindings
14856 int main(int argc, char *argv[])
14860 fprintf(stderr, "Usage: main ticker [currency]\n");
14866 soap_set_namespaces(&soap, quote_namespaces);
14867 if (soap_call_ns__getQuote(&soap, "http://services.xmethods.net/soap", "", argv[1], &q)) // get quote
14868 soap_print_fault(&soap, stderr);
14873 soap_set_namespaces(&soap, rate_namespaces);
14875 if (soap_call_ns__getRate(&soap, "http://services.xmethods.net/soap", "", "us", argv[2], &r)) // get rate in US dollars
14876 soap_print_fault(&soap, stderr);
14878 q *= r; // convert the quote
14880 printf("%s: %f \n", argv[1], q);
14886 Compile and link this application with `stdsoap2.o`, `envC.o`, `quoteClientLib.o`, and `rateClientLib.o`.
14888 To compile and link a server library is very similar. Assuming that the server is named "`calc`" (as specified with options `-n` and `-p`), the application needs to include the `calcStub.h` file, link the `calcServerLib.o` file, and call `calc_serve(&soap)` function at run time.
14890 ### C Services Chaining Example
14892 We build a C application for multiple services served on one port.
14894 We create a `env.h` that contains the joint SOAP Header and SOAP Fault
14895 definitions. You may have to copy-paste these from the other header files.
14896 Then, compile it as follows:
14898 > soapcpp2 -c -penv env.h
14901 We also compile `stdsoap2.c` without namespaces:
14903 > cc -c -DWITH_NONAMESPACES stdsoap2.c
14905 Say we have a service definition in `quote.h`. We compile it as a library and we use options `-n` and `-p` to rename the namespace table to avoid link conflicts:
14907 > soapcpp2 -c -n -pquote quote.h
14908 > cc -c quoteClientLib.c
14910 We do the same for a service definition in `rate.h`:
14912 > soapcpp2 -c -n -prate rate.h
14913 > cc -c rateClientLib.c
14915 To serve both the quote and rate services on the same port, we chain the service dispatchers as follows:
14918 struct soap *soap = soap_new();
14919 soap_bind(soap, NULL, 8080, 100);
14921 if (soap_begin_serve(soap))
14922 soap_send_fault(&abc); // send fault to client
14923 else if (quote_serve_request(soap) == SOAP_NO_METHOD)
14925 if (rate_serve_request(soap))
14926 soap_send_fault(soap); // send fault to client
14928 else if (soap.error)
14929 soap_send_fault(soap); // send fault to client
14930 soap_destroy(soap);
14935 This chaining can be arbitrarily deep. When the previous request fails with a `SOAP_NO_METHOD` then next request dispatcher can be tried.
14937 The server should also define the service operations:
14940 int ns__getQuote(struct soap *soap, char *symbol, float *Result);
14944 int ns__getRate(struct soap *soap, char *country1, char *country2, float *Result);
14950 ## How to Create DLLs {#dll}
14952 ### Create the Base stdsoap2.dll
14954 First, create a new header file `env.h` with the SOAP Header and Fault
14955 definitions. You can leave this header file empty if you want to use the
14956 default SOAP Header and Fault. Then compile this header file with:
14958 > soapcpp2 -penv env.h
14960 The generated `envC.cpp` file holds the SOAP Header and Fault serializers, which need to be part of the base library functions. The SOAP Header and Fault structures are generated by wsdl2h and are also located in the `.h` files for plugins such as `wsse.h`. You should copy these Header and Fault structures into `env.h` to ensure processing by these plugins succeeds.
14962 The next step is to create `stdsoap2.dll` which consists of the file
14963 `stdsoap2.cpp` and `envC.cpp` and optionally the plugins you want to use such as `wsseapi.c` (rename to .cpp to avoid warnings). This DLL contains all common functions
14964 needed for all other clients and servers based on gSOAP. Compile
14965 `envC.cpp` and `stdsoap2.cpp` into `stdsoap2.dll` using the
14966 compiler option `-DWITH_NONAMESPACES` and the MSVC Pre-Processor
14967 definitions `SOAP_FMAC1=__declspec(dllexport)`, `SOAP_FMAC3=__declspec(dllexport)`, and the `SOAP_STD_EXPORTS` macro set as shown below from the MSVC command prompt:
14969 C: cl /c /I. /EHsc /DWITH_NONAMESPACES /DSOAP_FMAC1=__declspec(dllexport) /DSOAP_FMAC3=__declspec(dllexport) /DSOAP_STD_EXPORTS envC.cpp stdsoap2.cpp
14970 C: link /LIBPATH ws2_32.lib /OUT:mygsoap.dll /DLL envC.obj stdsoap2.obj
14972 Note: as of gSOAP 2.8.30 and later, the DLL export macros shown here are all set with one pre-processor definition `SOAP_STD_EXPORTS`.
14974 Alternatively, you can compile with
14975 `-DWITH_SOAPDEFS_H` and put the macro definitions in `soapdefs.h`.
14976 This exports all functions which are preceded by the macro `SOAP_FMAC1` in
14977 the `soapcpp2.cpp` source file and macro `SOAP_FMAC3` in the `envC.cpp` source file.
14979 Finally, note that the gSOAP distribution package contains a number of .c
14980 files. Mixing .c with .cpp files is not recommended with Visual Studio and
14981 will lead to runtime errors when building DLLs. Therefore, always rename .c
14982 files to .cpp files when creating DLLs.
14984 ### Creating Client and Server DLLs
14986 Compile the `soapClientLib.cpp` and `soapServerLib.cpp` sources as DLLs
14987 by using the MSVC Pre-Processor definitions `SOAP_FMAC5=__declspec(dllexport)` and `SOAP_CMAC=__declspec(dllexport)`, and by using the C++ compiler option `-DWITH_NONAMESPACES`. All of these macros are set as a shorthand with one pre-processor definition `SOAP_STD_EXPORTS` (requires gSOAP 2.8.30 or later).
14989 This DLL links to `stdsoap2.dll`.
14991 To create multiple DLLs in the same project directory, you SHOULD use option
14992 `-p` to rename the generated `soapClientLib.cpp` and
14993 `soapServerLib.cpp` (and associated) files. The `-p` option specifies
14994 the file name prefix to replace the `soap` prefix.
14995 A clean separation of libraries can also be achieved with C++ namespaces, see Section \ref codenamespace .
14997 Unless you use the client proxy and server object classes (`soapXProxy.h` and `soapXObject.h` where `X` is the name of the service), all client and server applications MUST explicitly set the namespaces value of the gSOAP context:
15001 soap_set_namespaces(&soap, namespaces);
15004 where the `namespaces[]` table should be defined in the client/server source. These tables are generated in the `.nsmap` files. You can rename the tables using option `-n`, see Section \ref options .
15006 ## gSOAP Plug-ins {#plugins}
15008 The gSOAP plug-in feature enables a convenient extension mechanism of gSOAP
15009 capabilities. When the plug-in registers with gSOAP, it has full access
15010 to the run-time settings and the gSOAP function callbacks.
15011 Upon registry, the plug-in's local data is associated with the gSOAP run-time.
15012 By overriding gSOAP's function callbacks with the plug-in's function callbacks,
15013 the plug-in can extend gSOAP's capabilities. The local plug-in data can be
15014 accessed through a lookup function, usually invoked within a callback function
15015 to access the plug-in data.
15016 The registry and lookup functions are:
15019 int soap_register_plugin_arg(struct soap *soap, int (*fcreate)(struct soap *soap, struct soap_plugin *p, void *arg), void *arg)
15020 void* soap_lookup_plugin(struct soap*, const char*);
15023 Other functions that deal with plug-ins are:
15026 int soap_copy(struct soap *soap);
15027 void soap_done(struct soap *soap);
15030 The `soap_copy` function returns a new dynamically allocated gSOAP
15031 context that is a copy of another, such that no data is shared between the
15032 copy and the original context. The `soap_copy` function invokes the
15033 plug-in copy callbacks to copy the plug-ins' local data.
15034 The `soap_copy` function returns a gSOAP error code or `SOAP_OK`.
15035 The `soap_done` function de-registers all plugin-ins, so this function
15036 should be called to cleanly terminate a gSOAP run-time context.
15038 An example will be used to illustrate these functions.
15039 This example overrides the send and receive callbacks to copy all messages
15040 that are sent and received to the terminal (stderr).
15042 First, we write a header file `plugin.h` to define the local plug-in data
15043 structure(s) and we define a global name to identify the plug-in:
15046 #include "stdsoap2.h"
15047 #define PLUGIN_ID "PLUGIN-1.0" // some name to identify plugin
15048 struct plugin_data // local plugin data
15050 int (*fsend)(struct soap*, const char*, size_t); // to save and use send callback
15051 size_t (*frecv)(struct soap*, char*, size_t); // to save and use recv callback
15053 int plugin(struct soap *soap, struct soap_plugin *plugin, void *arg);
15056 Then, we write the plugin registry function and the callbacks:
15059 #include "plugin.h"
15060 static const char plugin_id[] = PLUGIN_ID; // the plugin id
15061 static int plugin_init(struct soap *soap, struct plugin_data *data);
15062 static int plugin_copy(struct soap *soap, struct soap_plugin *dst, struct soap_plugin *src);
15063 static void plugin_delete(struct soap *soap, struct soap_plugin *p);
15064 static int plugin_send(struct soap *soap, const char *buf, size_t len);
15065 static size_t plugin_recv(struct soap *soap, char *buf, size_t len);
15066 // the registry function:
15067 int plugin(struct soap *soap, struct soap_plugin *p, void *arg)
15070 p->data = (void*)malloc(sizeof(struct plugin_data));
15071 p->fcopy = plugin_copy; /* optional: when set the plugin must copy its local data */
15072 p->fdelete = plugin_delete;
15074 if (plugin_init(soap, (struct plugin_data*)p->data))
15076 free(p->data); // error: could not init
15077 return SOAP_EOM; // return error
15081 static int plugin_init(struct soap *soap, struct plugin_data *data)
15083 data->fsend = soap->fsend; // save old recv callback
15084 data->frecv = soap->frecv; // save old send callback
15085 soap->fsend = plugin_send; // replace send callback with new
15086 soap->frecv = plugin_recv; // replace recv callback with new
15089 // copy plugin data, called by soap_copy()
15090 // This is important: we need a deep copy to avoid data sharing by two run-time contexts
15091 static int plugin_copy(struct soap *soap, struct soap_plugin *dst, struct soap_plugin *src)
15093 if (!(dst->data = (struct plugin_data*)malloc(sizeof(struct plugin_data))))
15095 *dst->data = *src->data;
15098 // plugin deletion, called by soap_done()
15099 static void plugin_delete(struct soap *soap, struct soap_plugin *p)
15100 { free(p->data); // free allocated plugin data
15102 // the new send callback
15103 static int plugin_send(struct soap *soap, const char *buf, size_t len)
15105 struct plugin_data *data = (struct plugin_data*)soap_lookup_plugin(soap, plugin_id); // fetch plugin's local data
15106 fwrite(buf, len, 1, stderr); // write message to stderr
15107 return data->fsend(soap, buf, len); // pass data on to old send callback
15109 // the new receive callback
15110 static size_t plugin_recv(struct soap *soap, char *buf, size_t len)
15112 struct plugin_data *data = (struct plugin_data*)soap_lookup_plugin(soap, plugin_id); // fetch plugin's local data
15113 size_t res = data->frecv(soap, buf, len); // get data from old recv callback
15114 fwrite(buf, res, 1, stderr);
15119 The `fdelete` callback of `struct soap_plugin`
15120 MUST be set to register the plugin. It is the responsibility of the plug-in to
15121 handle registry (init), copy, and deletion of the plug-in data and callbacks.
15123 A plugin is copied with the `soap_copy()` call. This function copies a soap struct
15124 and the chain of plugins. It is up to the plugin implementation to share the plugin data
15128 * if the `fcopy()` callback is set by the plugin initialization, this callback will be called to allow
15129 the plugin to copy its local data upon a `soap_copy()` call. When `soap_done()` is called on
15130 the soap struct copy, the `fdelete()` callback is called for deallocation and cleanup of the local data.
15133 if the `fcopy()` callback is not set, then the plugin data
15134 will be shared (i.e. the data pointer points to the same address).
15135 The `fdelete()` callback will not be called upon a `soap_done()` on a
15136 copy of the soap struct. The `fdelete()` callback will be called for
15137 the original soap struct with which the plugin was registered.
15139 The example plug-in should be used as follows:
15144 soap_register_plugin(&soap, plugin);
15149 Note: `soap_register_plugin(...)` is an alias for
15150 `soap_register_plugin_arg(..., NULL)`. That is, it passes NULL as an
15151 argument to plug-in's registry callback.
15153 A number of example plug-ins are included in the gSOAP package's `plugin` directory. Some of these plug-ins are discussed.
15155 ### The Message Logging and Statistics Plug-in
15157 The message logging and access statistics plug-in can be used to selectively log inbound and outbound messages to a file or stream. It also keeps access statistics to log the total number of bytes sent and received.
15159 To use the plug-in, compile and link your application with `logging.c` located in the `plugin` directory of the package.
15160 To enable the plug-in in your code, register the plug-in and set the streams as follows:
15163 #include "logging.h"
15167 if (soap_register_plugin(&soap, logging))
15168 soap_print_fault(&soap, stderr); // failed to register
15170 soap_set_logging_inbound(&soap, stdout);
15171 soap_set_logging_outbound(&soap, stdout);
15172 ... process messages ...
15173 soap_set_logging_inbound(&soap, NULL); // disable logging
15174 soap_set_logging_outbound(&soap, NULL); // disable logging
15175 soap_get_logging_stats(&soap, &bytes_out, &bytes_in);
15178 If you use `soap_copy` to copy the soap struct with the plug-in, the plug-in's data will be shared by the copy.
15179 Therefore, the statistics are not 100% guaranteed to be accurate for multi-threaded services since race conditions on the counters may occur. Mutex is not used to update the counters to avoid introducing expensive synchronization points. If 100% server-side accuracy is required, add mutex at the points indicated in the `logging.c` code.
15181 ### RESTful Client-Side API
15183 The soapcpp2 tool generates the following functions for client-side REST operations:
15185 `soap_PUT_`*Name*`(struct soap *soap, const char *URL, `*Type*`* data)`
15186 REST PUT XML of type *Type* to the endoint at the specified URL.
15188 `soap_POST_send_`*Name*`(struct soap *soap, const char *URL, `*Type*`* data)`
15189 REST POST send XML of type *Type* to the endoint at the specified URL, which MUST be followed by a REST POST receive (see below) to receive response data.
15191 `soap_GET_`*Name*`(struct soap *soap, const char *URL, `*Type*`* data)`
15192 REST GET XML of type *Type* from the endoint at the specified URL.
15194 `soap_POST_recv_`*Name*`(struct soap *soap, `*Type*`* data)`
15195 REST POST receive XML of type *Type* after REST POST send.
15197 The REST POST operation is a two-step process, first a POST send of the data
15198 followed by a POST receive of the response data.
15200 ### RESTful Server-Side API: The HTTP GET Plug-in
15202 Server-side use of RESTful HTTP GET operations is supported with the HTTP GET
15203 plug-in `plugin/httpget.c`.
15205 The HTTP GET plug-in allows your server to handle RESTful HTTP GET requests and
15206 at the same time still serve SOAP-based POST requests. The plug-in provides
15207 support to client applications to issue HTTP GET operations to a server.
15209 Note that HTTP GET requests can also be handled at the server side with the
15210 `fget` callback, see Section \ref callback . However, the HTTP GET
15211 plug-in also keeps statistics on the number of successful POST and GET
15212 exchanges and failed operations (HTTP faults, SOAP Faults, etc.). It also keeps
15213 hit histograms accumulated for up to a year of runtime.
15215 To use the plug-in, compile and link your application with `httpget.c` located in the `plugin` directory of the package.
15216 To enable the plug-in in your code, register the plug-in with your HTTP GET handler function as follows:
15219 #include "httpget.h"
15221 if (soap_register_plugin_arg(&soap, httpget, (void*)my_http_get_handler))
15222 soap_print_fault(&soap, stderr); // failed to register
15224 struct http_get_data *httpgetdata;
15225 httpgetdata = (struct http_get_data*)soap_lookup_plugin(&soap, http_get_id);
15227 ... // if the plug-in registered OK, there is certainly data but can't hurt to check
15228 ... process messages ...
15229 size_t get_ok = httpgetdata->stat_get;
15230 size_t post_ok = httpgetdata->stat_post;
15231 size_t errors = httpgetdata->stat_fail;
15233 time_t now = time(NULL);
15235 T = localtime(&now);
15236 size_t hitsthisminute = httpgetdata->min[T->tm_min];
15237 size_t hitsthishour = httpgetdata->hour[T->tm_hour];
15238 size_t hitstoday = httpgetdata->day[T->tm_yday];
15241 An HTTP GET handler can simply produce some HTML content, or any other type of content by sending data:
15244 int my_http_get_handler(struct *soap)
15246 soap->http_content = "text/html";
15247 soap_response(soap, SOAP_FILE);
15248 soap_send(soap, "<html>Hello</html>");
15249 soap_end_send(soap);
15250 return SOAP_OK; // return SOAP_OK or HTTP error code, e.g. 404
15254 If you use `soap_copy` to copy the soap struct with the plug-in, the plug-in's data will be shared by the copy.
15255 Therefore, the statistics are not 100% guaranteed to be accurate for multi-threaded services since race conditions on the counters may occur. Mutex is not used to update the counters to avoid introducing expensive synchronization points. If 100% server-side accuracy is required, add mutex at the points indicated in the `httpget.c` code.
15257 The client-side use of HTTP GET is provided by the `soap_get_connect` operation. To receive a SOAP/XML (response) message *`ns:methodResponse`*, use:
15260 #include "httpget.h"
15262 soap_register_plugin(&soap, http_get);
15264 if (soap_get_connect(&soap, endpoint, action))
15265 ... connect error ...
15266 else if (soap_recv_ns__methodResponse(&soap, ... params ...))
15270 soap_destroy(&soap);
15275 To receive any HTTP Body data into a buffer, use:
15278 #include "httpget.h"
15280 char *response = NULL;
15281 soap_register_plugin(&soap, http_get);
15283 if (soap_get_connect(&soap, endpoint, NULL))
15284 ... connect error ...
15285 else if (soap_begin_recv(&soap))
15288 response = soap_get_http_body(&soap);
15289 soap_end_recv(&soap);
15290 ... use the 'response' string (NULL indicates no body or error)
15291 soap_destroy(&soap);
15296 ### RESTful Server-Side API: The HTTP POST Plug-in
15298 Server-side use of RESTful HTTP POST, PUT, and DELETE operations are supported
15299 with the HTTP POST plug-in `plugin/httppost.c`.
15301 The HTTP POST plug-in allows your server to handle RESTful HTTP POST requests
15302 and at the same time still serve SOAP-based POST requests. The plug-in also
15303 provides support for client applications to issue HTTP POST operations to a
15306 To simplify the server-side handling of POST requests, handlers can be associated with media types:
15309 struct http_post_handlers my_handlers[] =
15310 { { "image/jpg", jpeg_handler },
15311 { "image/ *", image_handler },
15312 { "text/html", html_handler },
15313 { "text/ *", text_handler },
15314 { "text/ *;*", text_handler },
15315 { "POST", generic_POST_handler },
15316 { "PUT", generic_PUT_handler },
15317 { "DELETE", generic_DELETE_handler },
15322 Note that `*` can be used as a wildcard and some media types may have
15323 optional parameters (after `;`). The handlers are functions that will be
15324 invoked when a POSTed request message matching media type is send to the
15327 An example image handler that checks the specific image type:
15330 int image_handler(struct soap *soap)
15333 // if necessary, check type in soap->http_content
15334 if (soap->http_content && !soap_tag_cmp(soap->http_content, "image/gif")
15335 return 404; // HTTP error 404
15336 if (soap_http_body(soap, &buf, &len) != SOAP_OK)
15337 return soap->error;
15338 // ... now process image in buf
15339 // reply with empty HTTP OK response:
15340 soap_response(soap, SOAP_OK);
15341 soap_end_send(soap);
15346 The HTTP POST plug-in provides a `soap_http_body` operation as illustrated above to copy the HTTP Body content into a buffer.
15348 The above example returns HTTP OK. If content is supposed to be returned, then use:
15351 soap->http_content = "image/jpeg"; // a jpeg image to return back
15352 soap_response(soap, SOAP_FILE); // SOAP_FILE sets custom http content
15353 soap_send_raw(soap, buf, len); // send image
15354 soap_end_send(soap);
15357 For client applications to use HTTP POST, use the `soap_post_connect` operation:
15360 char *buf; // holds the HTTP request/response body data
15361 size_t len; // length of data
15363 if (soap_post_connect(soap, "URL", "SOAP action or NULL", "media type")
15364 || soap_send_raw(soap, buf, len);
15365 || soap_end_send(soap))
15367 if (soap_begin_recv(&soap)
15368 || soap_http_body(&soap, &buf, &len)
15369 || soap_end_recv(&soap))
15371 // ... use buf[0..len-1]
15375 Similarly, `soap_put_connect` and `soap_delete_connect` commands are provided for PUT and DELETE handling.
15377 ### The HTTP MD5 Checksum Plug-in
15379 The HTTP MD5 plug-in works in the background to automatically verify the
15380 content of messages using MD5 checksums. With the plug-in, messages can be
15381 transferred over (trusted but) unreliable connections. The plug-in can be used
15382 on the client side and server side.
15384 To use the plug-in, compile and link your application with `httpmd5.c` and `md5evp.c` located in the `plugin` directory of the package. The `md5evp.c` implementation uses the EVP interface to compute MD5 checksums with OpenSSL (compiled with `-DWITH_OPENSSL`).
15386 To enable the plug-in in your code, register the plug-in as follows:
15389 #include "httpmd5.h"
15391 if (soap_register_plugin(&soap, http_md5))
15392 soap_print_fault(&soap, stderr); // failed to register
15395 Once registered, MD5 checksums are produced for all outbound messages. Inbound messages with MD5 checksums in the HTTP header are automatically verified.
15397 The plug-in requires you to set the `SOAP_IO_STORE` flag when sending SOAP with attachments:
15400 #include "httpmd5.h"
15403 soap_init1(&soap, SOAP_IO_STORE);
15404 if (soap_register_plugin(&soap, http_md5)
15405 soap_print_fault(&soap, stderr); // failed to register
15406 ... now safe to send SOAP with attachments ...
15409 Unfortunately, this eliminates streaming.
15411 ### The HTTP Digest Authentication Plug-in
15413 The HTTP digest authentication plug-in enables a more secure authentication
15414 scheme compared to basic authentication. HTTP basic authentication sends
15415 unencrypted userids and passwords over the net, while digest authentication
15416 does not exchange passwords but exchanges checksums of passwords (and other
15417 data such as nonces to avoid replay attacks). For more details, please see
15420 The HTTP digest authentication can be used next to the built-in basic
15421 authentication, or basic authentication can be rejected to tighten security.
15422 The server must have a database with userid's and passwords (in plain text
15423 form). The client, when challenged by the server, checks the authentication
15424 realm provided by the server and sets the userid and passwords for digest
15425 authentication. The client application can temporarily store the userid and
15426 password for a sequence of message exchanges with the server, which is faster
15427 than repeated authorization challenges and authentication responses.
15429 At the client side, the plug-in is registered and service invocations are
15430 checked for authorization challenges (HTTP error code 401). When the server
15431 challenges the client, the client should set the userid and password and retry
15432 the invocation. The client can determine the userid and password based on the
15433 authentication realm part of the server's challenge. The authentication information can be temporarily saved for multiple invocations.
15435 Client-side example:
15438 #include "httpda.h"
15440 if soap_register_plugin(&soap, http_da))
15441 soap_print_fault(&soap, stderr); // failed to register
15443 if (soap_call_ns__method(&soap, ...) != SOAP_OK)
15445 if (soap.error == 401) // challenge: HTTP authentication required
15447 if (!strcmp(soap.authrealm, authrealm)) // determine authentication realm
15449 struct http_da_info info; // to store userid and passwd
15450 http_da_save(&soap, &info, authrealm, userid, passwd); // set userid and passwd for this realm
15451 if (soap_call_ns__method(&soap, ...) == SOAP_OK) // retry
15453 soap_end(&soap); // userid and passwd were deallocated
15454 http_da_restore(&soap, &info); // restore userid and passwd
15455 if (!soap_call_ns__method(&soap, ...) == SOAP_OK) // another call
15457 http_da_release(&soap, &info); // remove userid and passwd
15460 This code supports both basic and digest authentication.
15462 The server can challenge a client using HTTP code 401. With the plug-in, HTTP digest authentication challenges are send. Without the plug-in, basic authentication challenges are send.
15464 Each server method can implement authentication as desired and may enforce
15465 digest authentication or may also accept basic authentication responses. To
15466 verify digest authentication responses, the server should compute and compare
15467 the checksums using the plug-in's `http_da_verify_post` function for
15468 HTTP POST requests (and `http_da_verify_get` for HTTP GET requests with
15469 the HTTP GET plugin) as follows:
15472 #include "httpda.h"
15474 if (soap_register_plugin(&soap, http_da))
15475 soap_print_fault(&soap, stderr); // failed to register
15479 int ns__method(struct soap *soap, ...)
15481 if (soap->userid && soap->passwd) // client used basic authentication
15482 { // may decide not to handle, but if ok then go ahead and compare info:
15483 if (!strcmp(soap->userid, userid) && !strcmp(soap->passwd, passwd))
15484 { ... handle request ...
15488 else if (soap->authrealm && soap->userid) // Digest authentication
15490 passwd = ... // database lookup on userid and authrealm to find passwd
15491 if (!strcmp(soap->authrealm, authrealm) && !strcmp(soap->userid, userid))
15493 if (!http_da_verify_post(soap, passwd))
15494 { ... handle request ...
15499 soap->authrealm = authrealm; // set realm for challenge
15500 return 401; // Not authorized, challenge digest authentication
15504 For more details, including how to configure HTTP Digest authentication for
15505 proxies, please see the `doc/httpda/html/index.html` documentation in the gSOAP package.
15507 ### The WS-Addressing Plug-in
15509 The WSA WS-Addressing plug-in and the source code are extensively documented in
15510 the `doc/wsa` directory of the gSOAP package. Please refer to the documentation
15511 included in the package.
15513 The plug-in code is located in the `plugin` directory containing
15514 `wsaapi.h` and `wsaapi.c` (C and C++).
15516 To enable WS-Addressing 2005 (and support for 8/2004), the service definitions header file for `soapcpp2` should include the following imports:
15519 #import "import/wsa5.h"
15522 This imports the SOAP header elements required by WS-Addressing.
15524 For more details, please see the `doc/wsa/html/index.html` documentation in the gSOAP package.
15526 ### The WS-ReliableMessaging Plug-in
15528 The WSRM WS-ReliableMessaging plug-in and the source code are extensively documented in
15529 the `doc/wsrm` directory of the gSOAP package. Please refer to the documentation
15530 included in the package.
15532 The plug-in code is located in the `plugin` directory containing `wsrmapi.h` and `wsrmapi.c` (C and C++).
15534 Also needed are: `threads.h` and `threads.c` for multithreading and locking support.
15536 To enable WS-ReliableMessaging, the service definitions header file for `soapcpp2` should include the following imports:
15539 #import "import/wsrm.h"
15540 #import "import/wsa5.h"
15543 This imports the SOAP header elements required by WS-ReliableMessaging.
15545 For more details, please see the `doc/wsrm/html/index.html` documentation in the gSOAP package.
15547 ### The WS-Security Plug-in
15549 The WSSE WS-Security plug-in and the source code are extensively documented in
15550 the `doc/wsse` directory of the gSOAP package. Please refer to the
15551 documentation included in the package for details.
15553 The plug-in code is located in the `plugin` directory containing `wsseapi.h` and `wsseapi.c` (C and C++).
15555 Also needed are: `smdevp.h` and `smdevp.c` for streaming XML signature and message digest engine,
15556 `mecevp.h` and `mecevp.c` for streaming XML encryption engine, `threads.h` and `threads.c` for multithreading and locking support.
15558 To enable WS-Secrutiy, the service definitions header file for `soapcpp2` should include the following imports:
15561 #import "import/wsse.h"
15564 This imports the SOAP header elements required by WS-Security.
15566 For more details, please see the `doc/wsse/html/index.html` documentation in the gSOAP package.
15570 The WS-Discovery implementation is documented in the `doc/wsdd` directory
15571 of the gSOAP package. Please refer to the documentation included in the package
15574 Basically, to add WS-Discovery support the following event handlers must be
15575 defined and linked:
15578 void wsdd_event_Hello(struct soap *soap,
15579 unsigned int InstanceId,
15580 const char *SequenceId,
15581 unsigned int MessageNumber,
15582 const char *MessageID,
15583 const char *RelatesTo,
15584 const char *EndpointReference,
15586 const char *Scopes,
15587 const char *MatchBy,
15588 const char *XAddrs,
15589 unsigned int MetadataVersion)
15593 void wsdd_event_Bye(struct soap *soap,
15594 unsigned int InstanceId,
15595 const char *SequenceId,
15596 unsigned int MessageNumber,
15597 const char *MessageID,
15598 const char *RelatesTo,
15599 const char *EndpointReference,
15601 const char *Scopes,
15602 const char *MatchBy,
15603 const char *XAddrs,
15604 unsigned int MetadataVersion)
15608 soap_wsdd_mode wsdd_event_Probe(struct soap *soap,
15609 const char *MessageID,
15610 const char *ReplyTo,
15612 const char *Scopes,
15613 const char *MatchBy,
15614 struct wsdd__ProbeMatchesType *ProbeMatches)
15618 void wsdd_event_ProbeMatches(struct soap *soap,
15619 unsigned int InstanceId,
15620 const char *SequenceId,
15621 unsigned int MessageNumber,
15622 const char *MessageID,
15623 const char *RelatesTo,
15624 struct wsdd__ProbeMatchesType *ProbeMatches)
15628 soap_wsdd_mode wsdd_event_Resolve(struct soap *soap,
15629 const char *MessageID,
15630 const char *ReplyTo,
15631 const char *EndpointReference,
15632 struct wsdd__ResolveMatchesType *ResolveMatches)
15636 void wsdd_event_ResolveMatches(struct soap *soap,
15637 unsigned int InstanceId,
15638 const char *SequenceId,
15639 unsigned int MessageNumber,
15640 const char *MessageID,
15641 const char *RelatesTo,
15642 const char *EndpointReference,
15644 const char *Scopes,
15645 const char *MatchBy,
15646 const char *XAddrs,
15647 unsigned int MetadataVersion)
15650 These event handlers will be invoked when inbound WS-Discovery messages arrive using:
15653 if (!soap_valid_socket(soap_bind(soap, NULL, port, 100)))
15655 if (soap_wsdd_listen(soap, timeout))
15659 which will listen for `timeout` seconds to inbound WS-Discovery messages
15660 on a port and dispatches them to the event handlers. A negative `timeout` is measured
15663 Copyright (c) 2017, Robert van Engelen, Genivia Inc. All rights reserved.