|  | Home | Documentation | guide.md Source File updated Tue Jul 4 2017 by Robert van Engelen |

- Main Page

guide.md
Go to the documentation of this file.
1 gSOAP user guide {#mainpage}
2 ================
3
4 [TOC]
5
6 # Introduction {#intro}
7
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.
26
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
32 firewalls.
33
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.
39
40 🔝 [Back to table of contents](#)
41
42 # Getting Started {#start}
43
44 To start building Web services applications or automate XML data bindings with
45 gSOAP, you will need:
46
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>.
50
51 * A C or C++ compiler.
52
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.
56
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
59 compression.
60
61 The gSOAP distribution package includes:
62
63 * The `wsdl2h` WSDL/schema converter and data binding tool.
64
65 * The `soapcpp2` stub/skeleton compiler and code generator.
66
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
69 more details.
70
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.
74
75 If you don't have the binaries or if you want to rebuild them, you need
76
77 * Bison (or Yacc) to build `soapcpp2`.
78
79 * Flex (or Lex) to build `soapcpp2`.
80
81 * A C++ compiler to build `wsdl2h`.
82
83 Bison and Flex are preferred. Both are released under open source licenses that
84 are compatible with gSOAP's licenses:
85
86 * Bison is available from <http://www.gnu.org/software/bison>
87
88 * Flex is available from <http://flex.sourceforge.net>
89
90 You can also build `soapcpp2` without Bison and Flex installed, see
91 installation instructions on the gSOAP web site.
92
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.
99
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.
107
108 ## Creating a client app {#start-client}
109
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
118 (`soapServer.cpp`).
119
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.
125
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
131 output file:
132
133 > wsdl2h -o calc.h http://www.genivia.com/calc.wsdl
134
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.
141
142 The `wsdl2h`-generated service definitions header file also contains information on the use of the service, such as WS-Policy assertions when applicable.
143
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
146 `-s`:
147
148 > wsdl2h -s -o calc.h http://www.genivia.com/calc.wsdl
149
150 To build a pure C application, use option `-c`:
151
152 > wsdl2h -c -o calc.h http://www.genivia.com/calc.wsdl
153
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.
157
158 We have not yet generated the stubs for the C/C++ API. To do so, run the `soapcpp2` compiler:
159
160 > soapcpp2 -i -C -Iimport calc.h
161
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.
166
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`.
168
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
172 service:
173
174 ```cpp
175 #include "soapcalcProxy.h"
176 #include "calc.nsmap"
177 int main()
178 {
179 calcProxy service;
180 double result;
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;
183 else
184 service.soap_stream_fault(std::cerr);
185 service.destroy(); // delete data and release memory
186 }
187 ```
188
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.
191
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`:
193
194 ```cpp
195 #include "soapH.h"
196 #include "calc.nsmap"
197 int main()
198 {
199 struct soap *soap = soap_new();
200 double result;
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);
203 else
204 soap_print_fault(soap, stderr);
205 soap_end(soap);
206 soap_free(soap);
207 }
208 ```
209
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.
214
215 ## Creating a service app {#start-service}
216
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).
223
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
226 your Web site.
227
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.
229
230 Our `currentTime` service only has an output parameter, which is the
231 current time defined in our `currentTime.h` gSOAP service specification:
232
233 ```cpp
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);
239 ```
240
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.
249
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`:
251
252 ```cpp
253 // File: currentTime.cpp
254 #include "soapH.h" // include the generated declarations
255 #include "currentTime.nsmap" // include the XML namespace mappings
256 int main()
257 {
258 // create soap context and serve one CGI-based request:
259 return soap_serve(soap_new());
260 }
261
262 int ns__currentTime(struct soap *soap, time_t& response)
263 {
264 response = time(0);
265 return SOAP_OK;
266 }
267 ```
268
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.
273
274 We run the `soapcpp2` compiler on the header file to generate the
275 server-side code:
276
277 > soapcpp2 -S currentTime.h
278
279 and then compile the CGI binary:
280
281 > c++ -o currentTime.cgi currentTime.cpp soapC.cpp soapServer.cpp stdsoap2.cpp
282
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`
285 source:
286
287 > c++ -o currentTime.cgi currentTime.cpp soapC.cpp soapServer.cpp -lgsoap++
288
289 To activate the service, copy the `currentTime.cgi` binary to your
290 `bin-cgi` directory using the proper file permissions.
291
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
296 client-side code.
297
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:
301
302 > ./currentTime.cgi < currentTime.currentTime.req.xml
303
304 and this displays the server response in SOAP XML.
305
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.
310
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:
317
318 > soapcpp2 -i -S currentTime.h
319
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`.
323
324 Using the `currentTimeService` object we rewrite the CGI server as:
325
326 ```cpp
327 // File: currentTime.cpp
328 #include "soapcurrentTimeService.h" // include the proxy declarations
329 #include "currentTime.nsmap" // include the XML namespace mappings
330 int main()
331 {
332 // create server and serve one CGI-based request:
333 currentTimeService server;
334 server.serve();
335 server.destroy();
336 }
337
338 int currentTimeService::currentTime(time_t& response)
339 {
340 response = time(0);
341 return SOAP_OK;
342 }
343 ```
344
345 Compile with
346
347 > c++ -o currentTime.cgi currentTime.cpp soapC.cpp soapcurrentTimeService.cpp -lgsoap++
348
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.
351
352 To run the server as a stand-alone iterative (non-multithreaded) server on port 8080:
353 ```cpp
354 while (server.run(8080) != SOAP_TCP_ERROR)
355 server.soap_stream_fault(std::cerr);
356 ```
357
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.
362
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 .
366
367 # XML data bindings {#databindings}
368
369 Or in other words, how to map schemas (XSD files) to C/C++ bindings for
370 automatically reading and writing XML data.
371
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:
380
381 <div class="alt">
382 ```xml
383 <complexType name="Address"> class ns__Address {
384 <sequence> public:
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;
389 </sequence>
390 <attribute name="ID" type="int" use="required"/> @ int ID;
391 </complexType> }
392 ```
393 </div>
394
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.
401
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.
403
404 We will illustrate this further with an example. Suppose we have an XML document with a book record:
405
406 <div class="alt">
407 ```xml
408 <book isbn="1234567890">
409 <title>Farewell John Doe</title>
410 <publisher>ABC's is our Name</publisher>
411 </book>
412 ```
413 </div>
414
415 An example XML schema that defines the book element and type could be
416
417 <div class="alt">
418 ```xml
419 <schema ...>
420 <element name="book">
421 <complexType>
422 <sequence>
423 <element name="title" type="string" minOccurs="1"/>
424 <element name="publisher" type="string" minOccurs="1"/>
425 </sequence>
426 <attribute name="isbn" type="unsignedLong" use="required"/>
427 </complexType>
428 </element>
429 </schema>
430 ```
431 </div>
432
433 Using `wsdl2h` we translate the XML schema that defines the book type and root element to a class definition:
434
435 ```cpp
436 class book
437 {
438 public:
439 @ ULONG64 isbn;
440 std::string title;
441 std::string publisher;
442 }
443 ```
444
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.
447
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.
452
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:
454
455 ```cpp
456 soap *ctx = soap_new1(SOAP_XML_INDENT); // new context with option
457 book bk;
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)
462 ... error ...
463
464
465
466 soap_destroy(ctx); // clean up allocated class instances
467 soap_end(ctx); // clean up allocated temporaries
468 soap_free(ctx); // delete context
469 ```
470
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.
476
477 To read the XML representation from standard input into a book object, use:
478
479 ```cpp
480 soap *ctx = soap_new1(SOAP_XML_STRICT); // new context with option
481 book bk;
482 if (soap_read_book(ctx, &bk) != SOAP_OK)
483
484
485
486 ... error ...
487 else
488 cout << bk.isbn << ", " << bk.title << ", " << bk.publisher << endl;
489 ... further use of bk ...
490
491 soap_destroy(ctx); // delete deserialized objects
492 soap_end(ctx); // delete temporaries
493 soap_free(ctx); // delete context
494 ```
495
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
500 instead of stdin.
501
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
504 to avoid leaks.
505
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.
509
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.
518
519 The following options are available to control serialization:
520
521 ```cpp
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
526 ```
527
528 Other flags can be used to format XML, see Section \ref flags .
529
530 For more details on XML databinding support for C and C++, see
531 Section \ref bindings .
532
533 ## Feature Overview
534
535 The highlights of gSOAP are:
536
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.
539
540
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.
550
551
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.
556
557
558 * gSOAP supports XML-RPC and RSS protocols. Examples are provided.
559
560
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.
563
564
565 * The `wsdl2h` tool supports WS-Policy. Policy assertions are included in
566 the generated service description header file with recommendations and usage
567 hints.
568
569
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.
576
577
578 * gSOAP supports SOAP-over-UDP.
579
580
581 * gSOAP supports IPv4 and IPv6.
582
583
584 * gSOAP supports Zlib deflate and gzip compression (for HTTP, TCP/IP, and XML file storage).
585
586
587 * gSOAP supports SSL (HTTPS) using OpenSSL and optionally using GNUTLS.
588
589
590 * gSOAP supports HTTP/1.0, HTTP/1.1 keep-alive, chunking, basic authentication, and digest authentication using a plugin.
591
592
593 * gSOAP supports SOAP one-way messaging.
594
595
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.
598
599
600 * The `soapcpp2` compiler includes a WSDL and schema generator for convenient
601 Web Service publishing.
602
603
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.
607
608
609 * The `wsdl2h` tool converts WSDL and XSD files to gSOAP header files for automated client and server development.
610
611
612 * Generates source code for stand-alone Web Services and client applications.
613
614
615 * Ideal for small devices such as Palm OS, Symbian, Pocket PC, because the memory footprint is small.
616
617
618 * Ideal for building web services that are compute-intensive and are therefore best written in C and C++.
619
620
621 * Platform independent: Windows, Unix, Linux, Mac OS X, Pocket PC, Palm OS, Symbian, VXWorks, etc.
622
623
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.
625
626
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.
630
631
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.
635
636
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.
640
641
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.
644
645
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).
648
649
650 * Full and customizable SOAP Fault processing (client receive and service send).
651
652
653 * Customizable SOAP Header processing (send and receive), which for example enables easy transaction processing for the service to
654 keep state information.
655
656 # Notational Conventions
657
658 The typographical conventions used by this document are:
659
660 * `Courier` denotes C and C++ source code, XML data, JSON data, file names, and shell/batch commands.
661
662 * `[optional: ...]` denotes an optional construct.
663
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.
666
667 # Differences Between gSOAP Versions 2.4 (and Earlier) and 2.5
668
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.
672
673 # Differences Between gSOAP Versions 2.1 (and Earlier) and 2.2
674
675 You should read this section only if you are upgrading from gSOAP 2.1 to 2.2 and later.
676
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.
683
684 Before a client can invoke service operations or before a service can accept requests, a runtime context needs to be allocated and
685 initialized.
686
687 * `soap_init(struct soap *soap)` & Initializes a context (required only once)
688
689 * `struct soap *soap_new()` & Allocates, initializes, and returns a pointer to a runtime context
690
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
693 original context
694
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)`.
698
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:
702
703 ```cpp
704 int main()
705 {
706 struct soap soap;
707 ...
708 soap_init(&soap); // initialize runtime context
709 ...
710 soap_call_ns__method1(&soap, ...); // make a remote call
711 ...
712 soap_call_ns__method2(&soap, ...); // make another remote call
713 ...
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)
717 ...
718 }
719 ```
720
721 The runtime context can also be heap allocated:
722
723 ```cpp
724 int main()
725 {
726 struct soap *soap;
727 ...
728 soap = soap_new(); // allocate and initialize runtime context
729 if (!soap) // couldn't allocate: stop
730 ...
731 soap_call_ns__method1(soap, ...); // make a remote call
732 ...
733 soap_call_ns__method2(soap, ...); // make another remote call
734 ...
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
738 }
739 ```
740
741 A service needs to allocate and initialize an context before calling `soap_serve`:
742
743 ```cpp
744 int main()
745 {
746 struct soap soap;
747 soap_init(&soap);
748 soap_serve(&soap);
749 }
750 ```
751
752 Or alternatively:
753
754 ```cpp
755 int main()
756 {
757 soap_serve(soap_new());
758 }
759 ```
760
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 ).
762
763 A service can use multi-threading to handle requests while running some other code that invokes service operations:
764
765 ```cpp
766 int main()
767 {
768 struct soap soap1, soap2;
769 pthread_t tid;
770 ...
771 soap_init(&soap1);
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);
775 ...
776 soap_init(&soap2);
777 soap_call_ns__method(&soap2, ...); // make a remote call
778 ...
779 soap_end(&soap2);
780 ...
781 pthread_join(tid, NULL); // wait for thread to terminate
782 soap_end(&soap1); // release its data
783 }
784 ```
785
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).
789
790 Section \ref mt presents a multi-threaded stand-alone Web Service that handles multiple SOAP requests by spawning a thread for each request.
791
792 # Interoperability
793
794 gSOAP interoperability has been verified with the following SOAP implementations and toolkits:
795
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
797
798 # Quick User Guide
799
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.
811
812 ## How to Build SOAP/XML Clients {#client}
813
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.
825
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.
830
831 Consider the following command (entered at the Linux/Unix/Windows command line prompt):
832
833 > wsdl2h -o calc.h http://www.genivia.com/calc.wsdl
834
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.
839
840 To generate a service definition header file to develop a pure C client application, use the `-c` option:
841
842 > wsdl2h -c -o calc.h http://www.genivia.com/calc.wsdl
843
844 For more details on the WSDL parser and its options, see \ref wsdlin .
845
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.
849
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:
852
853 ```cpp
854 int ns2__add(double a, double b, double& result);
855 ```
856
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.
866
867 These function prototypes are translated by the gSOAP `soapcpp2` tool to stubs and proxies for remote calls:
868
869 * `soapStub.h` annotated copy of the input definitions
870
871 * `soapH.h` serializers
872
873 * `soapC.cpp` serializers
874
875 * `soapClient.cpp` client calling stubs
876
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.
879
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
885 in SOAP/XML.
886
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
889 skeleton routines
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).
894
895 ### Example {#example1}
896
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:
900
901 * Endpoint URL: *`http://websrv.cs.fsu.edu/~engelen/calcserver.cgi`*
902
903 * XML namespace: *`urn:calc`*
904
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:
910
911 * SOAP style: RPC
912
913 * SOAP encoding: encoded
914
915 * SOAP action: *`""`* (empty string)
916
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):
920
921 ```cpp
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
926
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);
932 ```
933
934 The other calculator operations are similar and elided here for clarity.
935
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 .
938
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
942 this case).
943
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.
951
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.
956
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.
962
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`:
967
968 <div class="alt">
969 ```xml
970 c = "urn:calc"
971 ```
972 </div>
973
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`.
976
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 .
981
982 Next, the gSOAP `soapcpp2` tool is invoked from the command line to process the `calc.h` service definitions:
983
984 > soapcpp2 calc.h
985
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):
990
991 ```cpp
992 int soap_call_c__add(struct soap *soap, char *URL, char *action, double a, double b, double& result);
993 ```
994
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.
999
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.
1003
1004 The following example C/C++ client program uses the stub:
1005
1006 ```cpp
1007 #include "soapH.h" // include all interfaces (library and generated)
1008 #include "calc.nsmap" // import the generated namespace mapping table
1009 int main()
1010 {
1011 double sum;
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
1021 return 0;
1022 }
1023 ```
1024
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).
1028
1029 The following functions can be used to explicitly setup a gSOAP runtime context (`struct soap`):
1030
1031 * `soap_init(struct soap *soap)` Initializes a runtime context
1032
1033 * `soap_init1(struct soap *soap, soap_mode iomode)` Initializes a runtime context and set in/out mode flags
1034
1035 * `soap_init2(struct soap *soap, soap_mode imode, soap_mode omode)` Initializes a runtime context and set in/out mode flags
1036
1037 * `struct soap *soap_new()` Allocates, initializes, and returns a pointer to a runtime context
1038
1039 * `struct soap *soap_new1(soap_mode iomode)` Allocates, initializes, and returns a pointer to a runtime context and set in/out mode flags
1040
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
1042
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)
1044
1045 * `soap_done(struct soap *soap)` Reset, close communications, and remove callbacks
1046
1047 * `soap_free(struct soap *soap)` Reset and deallocate the context created with `soap_new` or `soap_copy`
1048
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.
1052
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:
1054
1055 > soapcpp2 -i calc.h
1056
1057 The proxy is defined in:
1058
1059 * `soapcalcProxy.h` client proxy class
1060
1061 * `soapcalcProxy.cpp` client proxy class
1062
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 .
1069
1070 The generated C++ proxy class initializes the gSOAP runtime context and offers the service interface as a collection of methods:
1071
1072 ```cpp
1073 #include "soapcalcProxy.h" // get proxy
1074 #include "calc.nsmap" // import the generated namespace mapping table
1075 int main()
1076 {
1077 calcProxy calc(SOAP_XML_INDENT);
1078 double sum;
1079 if (calc.add(1.0, 2.0, sum) == SOAP_OK)
1080 std::cout << "Sum = " << sum << std::endl;
1081 else
1082 calc.soap_stream_fault(std::cerr);
1083 return calc.error; // nonzero when error
1084 }
1085 ```
1086
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.
1090
1091 The code is compiled and linked with `soapcalcProxy.cpp`, `soapC.cpp`,
1092 and `stdsoap2.cpp` (or use `libgsoap++.a`).
1093
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
1095
1096 ```cpp
1097 //gsoap ns2 service name: calc
1098 ```
1099
1100 and rerun `soapcpp2` to generate code that uses the new name.
1101
1102 When the example client application is invoked, a SOAP request is performed:
1103
1104 <div class="alt">
1105 ```xml
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
1110 Content-Length: 464
1111 Connection: close
1112 SOAPAction: ""
1113
1114 <?xml version="1.0" encoding="UTF-8"?>
1115 <SOAP-ENV:Envelope
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"
1120 xmlns:c="urn:calc">
1121 <SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
1122 <c:add>
1123 <a>1</a>
1124 <b>2</b>
1125 </c:add>
1126 </SOAP-ENV:Body>
1127 </SOAP-ENV:Envelope>
1128 ```
1129 </div>
1130
1131 The SOAP response message:
1132
1133 <div class="alt">
1134 ```xml
1135 HTTP/1.1 200 OK
1136 Date: Wed, 05 May 2010 16:02:21 GMT
1137 Server: Apache/2.0.52 (Scientific Linux)
1138 Content-Length: 463
1139 Connection: close
1140 Content-Type: text/xml; charset=utf-8
1141
1142 <?xml version="1.0" encoding="UTF-8"?>
1143 <SOAP-ENV:Envelope
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/">
1150 <ns:addResponse>
1151 <result>3</result>
1152 </ns:addResponse>
1153 </SOAP-ENV:Body>
1154 </SOAP-ENV:Envelope>
1155 ```
1156 </div>
1157
1158 A client can invoke a sequence of service operations:
1159
1160 ```cpp
1161 #include "soapcalcProxy.h" // get proxy
1162 #include "calc.nsmap" // import the generated namespace mapping table
1163 int main()
1164 {
1165 calcProxy calc(SOAP_IO_KEEPALIVE); // keep-alive improves connection performance
1166 double sum = 0.0;
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))
1170 return calc.error;
1171 std::cout << "Sum = " << sum << std::endl;
1172 return 0;
1173 }
1174 ```
1175
1176 In the above, no data is deallocated until the proxy is deleted. To deallocate deserialized data between the calls, use:
1177
1178 ```cpp
1179 for (int i = 0; i < 4; i++)
1180 {
1181 if (calc.add(sum, val[i], sum))
1182 return calc.error;
1183 calc.destroy();
1184 }
1185 ```
1186
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:
1190
1191 ```cpp
1192 soap_unlink(struct soap *soap, const void *data)
1193 ```
1194
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:
1196
1197 ```cpp
1198 soap_delegate_deletion(struct soap *soap_from, struct soap *soap_to)
1199 ```
1200
1201 For example
1202
1203 ```cpp
1204 struct soap soap;
1205 soap_init(&soap);
1206 { // create proxy
1207 calcProxy calc;
1208 ... data generated ...
1209 soap_delegate_deletion(&calc, &soap);
1210 } // proxy deleted
1211 ... data used ...
1212 soap_destroy(&soap);
1213 soap_end(&soap);
1214 soap_done(&soap);
1215 ```
1216
1217 In C (use `wsdl2h -c`) the example program would be written as:
1218
1219 ```cpp
1220 #include "soapH.h"
1221 #include "calc.nsmap"
1222 int main()
1223 {
1224 struct soap soap;
1225 double sum = 0.0;
1226 double val[] = { 5.0, 3.5, 7.1, 1.2 };
1227 int i;
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))
1231 return soap.error;
1232 printf("Sum = %lg\n", sum);
1233 soap_end(&soap);
1234 soap_done(&soap);
1235 return 0;
1236 }
1237 ```
1238
1239 The code above is compiled and linked with `soapClient.c`, `soapC.c`,
1240 and `stdsoap2.c` (or use `libgsoap.a`).
1241
1242 ### XML Namespace Considerations {#namespace}
1243
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.
1249
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 .
1257
1258 The namespace mapping table is:
1259
1260 ```cpp
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
1269 };
1270 ```
1271
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
1280 mapping table.
1281
1282 The namespace mapping table will be output as part of the SOAP Envelope by the stub routine. For example:
1283
1284 <div class="alt">
1285 ```xml
1286 ...
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/">
1293 ...
1294 ```
1295 </div>
1296
1297 The namespace bindings will be used by a SOAP service to validate the SOAP request.
1298
1299 ### Example {#example2}
1300
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
1306
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:
1308
1309 ```cpp
1310 class e__Address // an electronic address from schema 'e'
1311 {
1312 char *email;
1313 char *url;
1314 };
1315 class s__Address // a street address from schema 's'
1316 {
1317 char *street;
1318 int number;
1319 char *city;
1320 };
1321 ```
1322
1323 The namespace prefix is separated from the name of a data type by a pair of underscores (`__`).
1324
1325 An instance of `e__Address` is encoded by the generated serializer for this type as an Address element with namespace prefix `e`:
1326
1327 <div class="alt">
1328 ```xml
1329 <e:Address xsi:type="e:Address">
1330 <email xsi:type="string">me@home</email>
1331 <url xsi:type="string">www.me.com</url>
1332 </e:Address>
1333 ```
1334 </div>
1335
1336 While an instance of `s__Address` is encoded by the generated serializer for this type as an Address element with namespace prefix `s`:
1337
1338 <div class="alt">
1339 ```xml
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>
1344 </s:Address>
1345 ```
1346 </div>
1347
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:
1349
1350 ```cpp
1351 struct Namespace namespaces[] =
1352 { ...
1353 {"e", "http://www.me.com/schemas/electronic-address"},
1354 {"s", "http://www.me.com/schemas/street-address"},
1355 ...
1356 ```
1357
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.
1359
1360 ### How to Generate C++ Client Proxy Classes {#proxy}
1361
1362 Proxy classes for C++ client applications are automatically generated by the gSOAP `soapcpp2` tool, as was shown in Section \ref example1 .
1363
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
1367 capabilites.
1368
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
1375 amount of code.
1376
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:
1381
1382 ```cpp
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
1390
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);
1396
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);
1402
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);
1408
1409 ...
1410 ```
1411
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 .
1417
1418 The `soapcpp2` tool takes this header file and generates a proxy `soapcalcProxy.h` with the
1419 following contents (not using option `-i`):
1420
1421 ```cpp
1422 #include "soapH.h"
1423 class calc
1424 { public:
1425 struct soap *soap;
1426 const char *endpoint;
1427 calc() { ... };
1428 ~calc() { ... };
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; };
1432 ...
1433 };
1434 ```
1435
1436 The gSOAP context and endpoint are declared public to enable access.
1437
1438 This generated proxy class can be included into a client application together with the generated namespace table as shown in this example:
1439
1440 ```cpp
1441 #include "soapcalcProxy.h" // get proxy
1442 #include "calc.nsmap" // get namespace bindings
1443 int main()
1444 {
1445 calc s;
1446 double r;
1447 if (s.ns2__add(1.0, 2.0, r) == SOAP_OK)
1448 std::cout << r << std::endl;
1449 else
1450 soap_print_fault(s.soap, stderr);
1451 return 0;
1452 }
1453 ```
1454
1455 The constructor allocates and initializes a gSOAP context for the instance.
1456
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 .
1463
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 .
1467
1468 ### XSD Type Encoding Considerations {#encoding}
1469
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:
1477
1478 ```cpp
1479 // Contents of header file:
1480 ...
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
1487 ...
1488 ```
1489
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).
1496
1497 ### Example {#example3}
1498
1499 Reconsider the calculator example, now rewritten with explicit XSD types to illustrate the effect:
1500
1501 ```cpp
1502 // Contents of file "calc.h":
1503 typedef double xsd__double;
1504 int ns2__add(xsd__string a, xsd__double b, xsd__double &Result);
1505 ```
1506
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:
1509
1510 ```cpp
1511 int soap_call_ns2__add(struct soap *soap, char *URL, char *action, double a, double b, double& result);
1512 ```
1513
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.
1517
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):
1519
1520 <div class="alt">
1521 ```xml
1522 ...
1523 <SOAP-ENV:Body>
1524 <ns2:add>
1525 <a xsi:type="xsd:string">1.0</a>
1526 <b xsi:type="xsd:string">2.0</b>
1527 </ns2:add>
1528 </SOAP-ENV:Body>
1529 ...
1530 ```
1531 </div>
1532
1533 The service response is:
1534
1535 <div class="alt">
1536 ```xml
1537 ...
1538 <soap:Body>
1539 <n:addResponse xmlns:n="urn:calc">
1540 <result xsi:type="xsd:double">3.0</result>
1541 </n:addResponse>
1542 </soap:Body>
1543 ...
1544 ```
1545 </div>
1546
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.
1553
1554 ### How to Change the Response Element Name {#response}
1555
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
1558 *`addResponse`*.
1559
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.
1568
1569 ### Example {#example4}
1570
1571 Reconsider the calculator service operation specification which can be rewritten with an explicit declaration of a SOAP response
1572 element as follows:
1573
1574 ```cpp
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);
1579 ```
1580
1581 The SOAP request and response messages are the same as before:
1582
1583 <div class="alt">
1584 ```xml
1585 ...
1586 <SOAP-ENV:Body>
1587 <ns2:add>
1588 <a xsi:type="xsd:string">1.0</a>
1589 <b xsi:type="xsd:string">2.0</b>
1590 </ns2:add>
1591 </SOAP-ENV:Body>
1592 ...
1593 ```
1594 </div>
1595
1596 The difference is that the service response is required to match the specified `addResponse` name and its namespace URI:
1597
1598 <div class="alt">
1599 ```xml
1600 ...
1601 <soap:Body>
1602 <n:addResponse xmlns:n='urn:calc'>
1603 <result xsi:type="xsd:double">3.0</result>
1604 </n:addResponse>
1605 </soap:Body>
1606 ...
1607 ```
1608 </div>
1609
1610 This use of a `struct` or `class` enables the adaptation of the default SOAP response element name and/or namespace URI when required.
1611
1612 ### How to Specify Multiple Output Parameters {#multiple}
1613
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 .
1623
1624 ### Example {#example5}
1625
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:
1628
1629 ```cpp
1630 // Contents of file "getNames.h":
1631 int ns3__getNames(char *SSN, struct ns3__getNamesResponse {char *first; char *last;} &r);
1632 ```
1633
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:
1635
1636 <div class="alt">
1637 ```xml
1638 ...
1639 <SOAP-ENV:Envelope ... xmlns:ns3="urn:names" ...>
1640 ...
1641 <ns3:getNames>
1642 <SSN>999 99 9999</SSN>
1643 </ns3:getNames>
1644 ...
1645 ```
1646 </div>
1647
1648 The response by a SOAP service:
1649
1650 <div class="alt">
1651 ```xml
1652 ...
1653 <m:getNamesResponse xmlns:m="urn:names">
1654 <first>John</first>
1655 <last>Doe</last>
1656 </m:getNamesResponse>
1657 ...
1658 ```
1659 </div>
1660
1661 where *`first`* and *`last`* are the output parameters of the `getNames` service operation of the service.
1662
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`:
1665
1666 ```cpp
1667 // Content of file "copy.h":
1668 int X_rox__copy_name(char *name, struct X_rox__copy_nameResponse {char *name;} &r);
1669 ```
1670
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.
1673
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:
1675
1676 <div class="alt">
1677 ```xml
1678 ...
1679 <SOAP-ENV:Envelope ... xmlns:X-rox="urn:copy" ...>
1680 ...
1681 <X-rox:copy-name>
1682 <name>SOAP</name>
1683 </X-rox:copy-name>
1684 ...
1685 ```
1686 </div>
1687
1688 The response by a SOAP copy service could be something like:
1689
1690 <div class="alt">
1691 ```xml
1692 ...
1693 <m:copy-nameResponse xmlns:m="urn:copy">
1694 <name>SOAP</name>
1695 </m:copy-nameResponse>
1696 ...
1697 ```
1698 </div>
1699
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.
1701
1702 ### How to Specify Output Parameters With struct/class Compound Data Types {#compound}
1703
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 .
1709
1710 ### Example {#example6}
1711
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:
1719
1720 ```cpp
1721 // Contents of file "flight.h":
1722 typedef char *xsd__string;
1723 class ns2__FlightInfo
1724 {
1725 public:
1726 xsd__string airline;
1727 xsd__string flightNumber;
1728 xsd__string altitude;
1729 xsd__string currentLocation;
1730 xsd__string equipment;
1731 xsd__string speed;
1732 };
1733 struct ns1__getFlightInfoResponse {ns2__FlightInfo return_;};
1734 int ns1__getFlightInfo(xsd__string param1, xsd__string param2, struct ns1__getFlightInfoResponse &r);
1735 ```
1736
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.
1740
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:
1742
1743 ```cpp
1744 struct soap soap;
1745 ...
1746 soap_init(&soap);
1747 ...
1748 soap_call_ns1__getFlightInfo(&soap, "testvger.objectspace.com/soap/servlet/rpcrouter",
1749 "urn:galdemo:flighttracker", "UAL", "184", r);
1750 ...
1751 struct Namespace namespaces[] =
1752 {
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"},
1759 {NULL, NULL}
1760 };
1761 ```
1762
1763 When invoked by a client application, the proxy produces the SOAP request:
1764
1765 <div class="alt">
1766 ```xml
1767 POST /soap/servlet/rpcrouter HTTP/1.1
1768 Host: testvger.objectspace.com
1769 Content-Type: text/xml
1770 Content-Length: 634
1771 SOAPAction: "urn:galdemo:flighttracker"
1772
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/">
1781 <SOAP-ENV:Body>
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>
1786 </SOAP-ENV:Body>
1787 </SOAP-ENV:Envelope>
1788 ```
1789 </div>
1790
1791 The Flighttracker service responds with:
1792
1793 <div class="alt">
1794 ```xml
1795 HTTP/1.1 200 ok
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
1801 Content-Length: 861
1802 Content-Type: text/xml; charset=utf-8
1803 Content-Language: en
1804
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">
1809 <SOAP-ENV:Body>
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>
1819 </return>
1820 </ns1:getFlightInfoResponse>
1821 </SOAP-ENV:Body>
1822 </SOAP-ENV:Envelope>
1823 ```
1824 </div>
1825
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:
1827
1828 ```cpp
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;
1832 ```
1833
1834 This code displays the service response as:
1835
1836 A320 flight UAL184 traveling 497 mph at 37000 ft, is located 188 mi W of Lincoln, NE
1837
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.
1839
1840 ### How to Specify Anonymous Parameter Names {#anonymous}
1841
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:
1849
1850 ```cpp
1851 // Contents of "calc.h":
1852 typedef double xsd__double;
1853 int ns2__add(xsd__string, xsd__double, xsd__double &);
1854 ```
1855
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.
1858
1859 For example:
1860
1861 ```cpp
1862 // Contents of "calc.h":
1863 typedef double xsd__double;
1864 int ns2__add(xsd__string _a, xsd__double _b, xsd__double & _return);
1865 ```
1866
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.
1872
1873 @warning when anonymous parameter names are used, the order of the parameters in the function prototype of a service operation is
1874 significant.
1875
1876 ### How to Specify a Method with No Input Parameters
1877
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:
1882
1883 ```cpp
1884 struct ns3__SOAPService
1885 {
1886 public:
1887 int ID;
1888 char *name;
1889 char *owner;
1890 char *description;
1891 char *homepageURL;
1892 char *endpoint;
1893 char *SOAPAction;
1894 char *methodNamespaceURI;
1895 char *serviceStatus;
1896 char *methodName;
1897 char *dateCreated;
1898 char *downloadURL;
1899 char *wsdlURL;
1900 char *instructions;
1901 char *contactEmail;
1902 char *serverImplementation;
1903 };
1904 struct ArrayOfSOAPService {struct ns3__SOAPService *__ptr; int __size;};
1905 int ns__getAllSOAPServices(void *_, struct ArrayOfSOAPService &_return);
1906 ```
1907
1908 The `ns__getAllSOAPServices` method has one `void*` input parameter which is ignored by the serializer to produce the
1909 request message.
1910
1911 Most C/C++ compilers allow empty `struct`s and therefore the `void*` parameter is not required.
1912
1913 ### How to Specify a Method with No Output Parameters
1914
1915 To specify a service operation that has no output parameters, just define a function prototype with a response struct that is
1916 empty. For example:
1917
1918 ```cpp
1919 enum ns__event { off, on, stand_by };
1920 int ns__signal(enum ns__event in, struct ns__signalResponse { } *out);
1921 ```
1922
1923 Since the response struct is empty, no output parameters are specified.
1924
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.
1927
1928 ## How to Build SOAP/XML Web Services
1929
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.
1938
1939 ### Example {#example7}
1940
1941 The following example specifies three service operations to be implemented by a new SOAP Web service:
1942
1943 ```cpp
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);
1949 ```
1950
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.
1956
1957 To generate the skeleton routines, the gSOAP `soapcpp2` compiler is invoked from the command line with:
1958
1959 > soapcpp2 calc.h
1960
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.
1968
1969 Here is an example Calculator service application that uses the generated `soap_serve` routine to handle client requests:
1970
1971 ```cpp
1972 // Contents of file "calc.cpp":
1973 #include "soapH.h"
1974 #include <math.h> // for sqrt()
1975 int main()
1976 {
1977 return soap_serve(soap_new()); // use the service operation request dispatcher
1978 }
1979 // Implementation of the "add" service operation:
1980 int ns__add(struct soap *soap, double a, double b, double &result)
1981 {
1982 result = a + b;
1983 return SOAP_OK;
1984 }
1985 // Implementation of the "sub" service operation:
1986 int ns__sub(struct soap *soap, double a, double b, double &result)
1987 {
1988 result = a - b;
1989 return SOAP_OK;
1990 }
1991 // Implementation of the "sqrt" service operation:
1992 int ns__sqrt(struct soap *soap, double a, double &result)
1993 {
1994 if (a >= 0)
1995 {
1996 result = sqrt(a);
1997 return SOAP_OK;
1998 }
1999 else
2000 return soap_receiver_fault(soap, "Square root of negative number", "I can only take the square root of a non-negative number");
2001 }
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
2010 {NULL, NULL}
2011 };
2012 ```
2013
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.
2025
2026 This service application can be readily installed as a CGI application. The service description would be:
2027
2028 * Endpoint URL: the URL of the CGI application
2029
2030 * SOAP action: "" (2 quotes)
2031
2032 * Remote method namespace: *`urn:simple-calc`*
2033
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`*
2037
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`*
2041
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
2045
2046 The `soapcpp2` compile generates a WSDL file for this service, see Section \ref wsdl .
2047
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.)
2052
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.
2058
2059 ### MSVC++ Builds
2060
2061
2062
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.
2067
2068
2069 * Use files with extension .cpp only (don't mix .c with .cpp).
2070
2071
2072 * Turn pre-compiled headers off.
2073
2074
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.
2076
2077
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.
2079
2080
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*`*.
2082
2083
2084
2085 ### How to Create a Stand-Alone Server {#stand-alone}
2086
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.
2093
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:
2096
2097 ```cpp
2098 int main()
2099 {
2100 struct soap soap;
2101 int m, s; // master and slave sockets
2102 soap_init(&soap);
2103 m = soap_bind(&soap, "machine.genivia.com", 18083, 100);
2104 if (m < 0)
2105 soap_print_fault(&soap, stderr);
2106 else
2107 {
2108 fprintf(stderr, "Socket connection successful: master socket = %d\n", m);
2109 for (int i = 1; ; i++)
2110 {
2111 s = soap_accept(&soap);
2112 if (s < 0)
2113 {
2114 soap_print_fault(&soap, stderr);
2115 break;
2116 }
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
2124 }
2125 }
2126 soap_done(&soap); // close master socket and detach context
2127 }
2128 ```
2129
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 ).
2131
2132 The gSOAP functions that are frequently used for server-side coding are:
2133
2134 * `soap_new()` Allocates and Initializes gSOAP context
2135
2136 * `soap_init(struct soap *soap)` Initializes a stack-allocated gSOAP context (required once)
2137
2138 * `soap_bind(struct soap *soap, char *host, int port, int backlog)` Returns master socket (backlog = max. queue
2139
2140 * size for requests). When `host==NULL`: host is the machine on which the service runs
2141
2142 * `soap_accept(struct soap *soap)` Returns slave socket
2143
2144 * `soap_end(struct soap *soap)` Clean up deserialized data (except class instances) and temporary data
2145
2146 * `soap_free_temp(struct soap *soap)` Clean up temporary data only
2147
2148 * `soap_destroy(struct soap *soap)` Clean up deserialized class instances (note: this function will be renamed with option `-n`
2149
2150 * `soap_done(struct soap *soap)` Reset and detach context: close master/slave sockets and remove callbacks
2151
2152 * `soap_free(struct soap *soap)` Detach and deallocate context (`soap_new`())
2153
2154 The *host* name in `soap_bind` may be NULL to indicate that the current host should be used.
2155
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.
2158
2159 See Section \ref memory for more details on memory management.
2160
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.
2165
2166 ### How to Create a Multi-Threaded Stand-Alone Service {#mt}
2167
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.
2173
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.
2177
2178 The following example illustrates the use of threads to improve the quality of service by handling new requests in separate threads:
2179
2180 ```cpp
2181 #include "soapH.h"
2182 #include <pthread.h>
2183 #define BACKLOG (100) // Max. request backlog
2184 int main(int argc, char **argv)
2185 {
2186 struct soap soap;
2187 soap_init(&soap);
2188 if (argc < 2) // no args: assume this is a CGI application
2189 {
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
2193 }
2194 else
2195 {
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*);
2201 struct soap *tsoap;
2202 pthread_t tid;
2203 int port = atoi(argv[1]); // first command-line arg is port
2204 SOAP_SOCKET m, s;
2205 m = soap_bind(&soap, NULL, port, BACKLOG);
2206 if (!soap_valid_socket(m))
2207 exit(1);
2208 fprintf(stderr, "Socket connection successful %d\n", m);
2209 for (;;)
2210 {
2211 s = soap_accept(&soap);
2212 if (!soap_valid_socket(s))
2213 {
2214 if (soap.errnum)
2215 {
2216 soap_print_fault(&soap, stderr);
2217 exit(1);
2218 }
2219 fprintf(stderr, "server timed out\n");
2220 break;
2221 }
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
2225 if (!tsoap)
2226 break;
2227 pthread_create(&tid, NULL, (void*(*)(void*))process_request, (void*)tsoap);
2228 }
2229 }
2230 soap_done(&soap); // detach soap struct
2231 return 0;
2232 }
2233 void *process_request(void *soap)
2234 {
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
2240 free(soap);
2241 return NULL;
2242 }
2243 ```
2244
2245 Note: the code does not wait for threads to join the main thread upon program termination.
2246
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.
2254
2255 The following example uses a pool of servers to limit the machine's resource utilization:
2256
2257 ```cpp
2258 #include "soapH.h"
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)
2263 {
2264 struct soap soap;
2265 soap_init(&soap);
2266 if (argc < 2) // no args: assume this is a CGI application
2267 {
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
2271 }
2272 else
2273 {
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
2277 SOAP_SOCKET m, s;
2278 int i;
2279 m = soap_bind(&soap, NULL, port, BACKLOG);
2280 if (!soap_valid_socket(m))
2281 exit(1);
2282 fprintf(stderr, "Socket connection successful %d\n", m);
2283 for (i = 0; i < MAX_THR; i++)
2284 soap_thr[i] = NULL;
2285 for (;;)
2286 {
2287 for (i = 0; i < MAX_THR; i++)
2288 {
2289 s = soap_accept(&soap);
2290 if (!soap_valid_socket(s))
2291 {
2292 if (soap.errnum)
2293 {
2294 soap_print_fault(&soap, stderr);
2295 \continue; // retry
2296 }
2297 else
2298 {
2299 fprintf(stderr, "Server timed out\n");
2300 break;
2301 }
2302 }
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
2306 {
2307 soap_thr[i] = soap_copy(&soap);
2308 if (!soap_thr[i])
2309 exit(1); // could not allocate
2310 }
2311 else // recycle soap context
2312 {
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
2317 }
2318 soap_thr[i]->socket = s; // new socket fd
2319 pthread_create(&tid[i], NULL, (void*(*)(void*))soap_serve, (void*)soap_thr[i]);
2320 }
2321 }
2322 for (i = 0; i < MAX_THR; i++)
2323 if (soap_thr[i])
2324 {
2325 soap_done(soap_thr[i]); // detach context
2326 free(soap_thr[i]); // free up
2327 }
2328 }
2329 return 0;
2330 }
2331 ```
2332
2333 The following functions can be used to setup a gSOAP runtime context (`struct soap`):
2334
2335 * `soap_init(struct soap *soap)` Initializes a runtime context (required only once)
2336
2337 * `struct soap *soap_new()` Allocates, initializes, and returns a pointer to a runtime context
2338
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)
2340
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
2343
2344 A new context is initiated for each thread to guarantee exclusive access
2345 to runtime contexts.
2346
2347 For clean termination of the server, the master socket can be closed and callbacks removed with `soap_done(struct soap *soap)`.
2348
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.
2350
2351 ```cpp
2352 #include "soapH.h"
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)
2365 {
2366 struct soap soap;
2367 soap_init(&soap);
2368 if (argc < 2) // no args: assume this is a CGI application
2369 {
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
2373 }
2374 else
2375 {
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
2379 SOAP_SOCKET m, s;
2380 int i;
2381 m = soap_bind(&soap, NULL, port, BACKLOG);
2382 if (!soap_valid_socket(m))
2383 exit(1);
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++)
2388 {
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]);
2392 }
2393 for (;;)
2394 {
2395 s = soap_accept(&soap);
2396 if (!soap_valid_socket(s))
2397 {
2398 if (soap.errnum)
2399 {
2400 soap_print_fault(&soap, stderr);
2401 \continue; // retry
2402 }
2403 else
2404 {
2405 fprintf(stderr, "Server timed out\n");
2406 break;
2407 }
2408 }
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)
2411 sleep(1);
2412 }
2413 for (i = 0; i < MAX_THR; i++)
2414 {
2415 while (enqueue(SOAP_INVALID_SOCKET) == SOAP_EOM)
2416 sleep(1);
2417 }
2418 for (i = 0; i < MAX_THR; i++)
2419 {
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]);
2424 free(soap_thr[i]);
2425 }
2426 pthread_mutex_destroy(&queue_cs);
2427 pthread_cond_destroy(&queue_cv);
2428 }
2429 soap_done(&soap);
2430 return 0;
2431 }
2432 void *process_queue(void *soap)
2433 {
2434 struct soap *tsoap = (struct soap*)soap;
2435 for (;;)
2436 {
2437 tsoap->socket = dequeue();
2438 if (!soap_valid_socket(tsoap->socket))
2439 break;
2440 soap_serve(tsoap);
2441 soap_destroy(tsoap);
2442 soap_end(tsoap);
2443 fprintf(stderr, "served\n");
2444 }
2445 return NULL;
2446 }
2447 int enqueue(SOAP_SOCKET sock)
2448 {
2449 int status = SOAP_OK;
2450 int next;
2451 pthread_mutex_lock(&queue_cs);
2452 next = tail + 1;
2453 if (next >= MAX_QUEUE)
2454 next = 0;
2455 if (next == head)
2456 status = SOAP_EOM;
2457 else
2458 {
2459 queue[tail] = sock;
2460 tail = next;
2461 pthread_cond_signal(&queue_cv);
2462 }
2463 pthread_mutex_unlock(&queue_cs);
2464 return status;
2465 }
2466 SOAP_SOCKET dequeue()
2467 {
2468 SOAP_SOCKET sock;
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)
2474 head = 0;
2475 pthread_mutex_unlock(&queue_cs);
2476 return sock;
2477 }
2478 ```
2479
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
2483 or POSIX calls.
2484
2485 ### How to Pass Application Data to Service Methods
2486
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:
2492
2493 ```cpp
2494 { ...
2495 struct soap soap;
2496 database_handle_type database_handle;
2497 soap_init(&soap);
2498 soap.user = (void*)database_handle;
2499 ...
2500 soap_serve(&soap); // call the service operation dispatcher to handle request
2501 ...
2502 }
2503 int ns__myMethod(struct soap *soap, ...)
2504 { ...
2505 fetch((database_handle_type*)soap->user); // get data
2506 ...
2507 return SOAP_OK;
2508 }
2509 ```
2510
2511 Another way to pass application data around in a more organized way is accomplished with plugins, see Section \ref plugins .
2512
2513 ### Web Service Implementation Aspects
2514
2515 The same client header file specification issues apply to the specification and implementation of a SOAP Web service. Refer to
2516
2517
2518 * \ref namespace for namespace considerations.
2519
2520 * \ref encoding for an explanation on how to change the encoding of the primitive types.
2521
2522 * \ref response for a discussion on how the response element format can be controlled.
2523
2524 * \ref multiple for details on how to pass multiple output parameters from a service operation.
2525
2526 * \ref compound for passing complex data types as output parameters.
2527
2528 * \ref anonymous for anonymizing the input and output parameter names.
2529
2530
2531 ### How to Generate C++ Server Object Classes {#object}
2532
2533 Server object classes for C++ server applications are automatically generated
2534 by the gSOAP `soapcpp2` compiler.
2535
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.
2539
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:
2543
2544 ```cpp
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);
2557 ```
2558
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
2562 following contents:
2563
2564 ```cpp
2565 #include "soapH.h"
2566 class CalculatorObject : public soap
2567 { public:
2568 Calculator() { ... };
2569 ~Calculator() { ... };
2570 int serve() { return soap_serve(\this); };
2571 };
2572 ```
2573
2574 This generated server object class can be included into a server application together with the generated namespace table as shown in this example:
2575
2576 ```cpp
2577 #include "soapCalculatorObject.h" // get server object
2578 #include "Calculator.nsmap" // get namespace bindings
2579 int main()
2580 {
2581 CalculatorObject c;
2582 return c.serve(); // calls `soap_serve` to serve as CGI application (using stdin/out)
2583 }
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)
2586 {
2587 result = a + b;
2588 return SOAP_OK;
2589 }
2590 ... sub(), mul(), and div() implementations ...
2591 ```
2592
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 .
2598
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 .
2602
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.
2606
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`).
2608
2609 This generated server object class can be included into a server application together with the generated namespace table as shown in this example:
2610
2611 ```cpp
2612 #include "soapCalculatorService.h" // get server object
2613 #include "Calculator.nsmap" // get namespace bindings
2614 int main()
2615 {
2616 soapCalculatorService c;
2617 return c.serve(); // calls `soap_serve` to serve as CGI application (using stdin/out)
2618 }
2619 // The 'add' service method (soapcpp2 w/ option -i)
2620 int soapCalculatorService::add(double a, double b, double &result)
2621 {
2622 result = a + b;
2623 return SOAP_OK;
2624 }
2625 ... sub(), mul(), and div() implementations ...
2626 ```
2627
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).
2631
2632 ### How to Chain C++ Server Classes to Accept Messages on the Same Port {#chaining}
2633
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 .
2638
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
2644 same port.
2645
2646 The approach is to chain the service dispatchers, as shown below:
2647
2648 ```cpp
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
2653
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
2657 ...
2658 abc.bind(NULL, 8080, 100);
2659 ...
2660 abc.accept();
2661 // when using SSL: ssl_accept(&abc);
2662 ...
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)
2666 {
2667 soap_copy_stream(&uvw, &abc);
2668 soap_free_stream(&abc); // abc no longer uses this stream
2669 if (uvw.dispatch() == SOAP_NO_METHOD)
2670 {
2671 soap_copy_stream(&xyz, &uvw);
2672 soap_free_stream(&uvw); // uvw no longer uses this stream
2673 if (xyz.dispatch())
2674 {
2675 soap_send_fault(&xyz); // send fault to client
2676 xyz.soap_stream_fault(std::cerr);
2677 }
2678 xyz.destroy();
2679 }
2680 else
2681 {
2682 soap_send_fault(&uvw); // send fault to client
2683 uvw.soap_stream_fault(std::cerr);
2684 }
2685 uvw.destroy();
2686 }
2687 else
2688 abc.soap_stream_fault(std::cerr);
2689 abc.destroy();
2690 ...
2691 ```
2692
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.
2701
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.
2703
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
2707 to the complexity.
2708
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.
2713
2714 With option `-j` and `-q` the code to chain the services is as follows, based on a single `struct soap` engine context:
2715
2716 ```cpp
2717 #include "AbcABCService.h"
2718 #include "UvwUVWService.h"
2719 #include "XyzXYZService.h"
2720 #include "envH.h" // include this file last, if it is needed
2721
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
2726
2727 soap_bind(soap, NULL, 8080, 100);
2728 soap_accept(soap);
2729 if (soap_begin_serve(soap))
2730 ... error
2731 else if (abc.dispatch() == SOAP_NO_METHOD)
2732 {
2733 if (uvw.dispatch() == SOAP_NO_METHOD)
2734 {
2735 if (xyz.dispatch() == SOAP_NO_METHOD)
2736 ... error
2737 }
2738 }
2739 soap_destroy(soap);
2740 soap_end(soap);
2741 soap_free(soap); // safe to delete when abc, uvw, xyz are also deleted
2742 ```
2743
2744
2745 ### How to Generate WSDL Service Descriptions {#wsdl}
2746
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.
2752
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:
2755
2756 ```cpp
2757 struct Namespace namespaces[] =
2758 {
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"},
2764 {NULL, NULL}
2765 };
2766 ```
2767
2768 This file can be incorporated in the
2769 client/service application, see Section \ref nstable for details on namespace mapping tables.
2770
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.
2774
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.
2779
2780 To customize the WSDL output, it is essential to use `//gsoap` directives to declare the service name, the endpoint port, and namespace:
2781
2782 ```cpp
2783 //gsoap ns service name: example
2784 //gsoap ns servire port: http://www.mydomain.com/example
2785 //gsoap ns service namespace: urn:example
2786 ```
2787
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.
2789
2790 ### Example {#example8}
2791
2792 For example, suppose the following methods are defined in the header file:
2793
2794 ```cpp
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);
2799 ```
2800
2801 Then, one WSDL file will be created with the file name *`ns.wsdl`* that describes all three service operations:
2802
2803 <div class="alt">
2804 ```xml
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">
2816 <types>
2817 <schema
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">
2823 <all>
2824 <element name="result" type="double" minOccurs="0" maxOccurs="1"/>
2825 </all>
2826 <anyAttribute namespace="##other"/>
2827 </complexType>
2828 <complexType name="subResponse">
2829 <all>
2830 <element name="result" type="double" minOccurs="0" maxOccurs="1"/>
2831 </all>
2832 <anyAttribute namespace="##other"/>
2833 </complexType>
2834 <complexType name="sqrtResponse">
2835 <all>
2836 <element name="result" type="double" minOccurs="0" maxOccurs="1"/>
2837 </all>
2838 <anyAttribute namespace="##other"/>
2839 </complexType>
2840 </schema>
2841 </types>
2842 <message name="addRequest">
2843 <part name="a" type="xsd:double"/>
2844 <part name="b" type="xsd:double"/>
2845 </message>
2846 <message name="addResponse">
2847 <part name="result" type="xsd:double"/>
2848 </message>
2849 <message name="subRequest">
2850 <part name="a" type="xsd:double"/>
2851 <part name="b" type="xsd:double"/>
2852 </message>
2853 <message name="subResponse">
2854 <part name="result" type="xsd:double"/>
2855 </message>
2856 <message name="sqrtRequest">
2857 <part name="a" type="xsd:double"/>
2858 </message>
2859 <message name="sqrtResponse">
2860 <part name="result" type="xsd:double"/>
2861 </message>
2862 <portType name="ServicePortType">
2863 <operation name="add">
2864 <input message="tns:addRequest"/>
2865 <output message="tns:addResponse"/>
2866 </operation>
2867 <operation name="sub">
2868 <input message="tns:subRequest"/>
2869 <output message="tns:subResponse"/>
2870 </operation>
2871 <operation name="sqrt">
2872 <input message="tns:sqrtRequest"/>
2873 <output message="tns:sqrtResponse"/>
2874 </operation>
2875 </portType>
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"/>
2880 <input>
2881 <SOAP:body use="encoded" namespace="http://tempuri.org"
2882 encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
2883 </input>
2884 <output>
2885 <SOAP:body use="encoded" namespace="http://tempuri.org"
2886 encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
2887 </output>
2888 </operation>
2889 <operation name="sub">
2890 <SOAP:operation soapAction="http://tempuri.org#sub"/>
2891 <input>
2892 <SOAP:body use="encoded" namespace="http://tempuri.org"
2893 encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
2894 </input>
2895 <output>
2896 <SOAP:body use="encoded" namespace="http://tempuri.org"
2897 encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
2898 </output>
2899 </operation>
2900 <operation name="sqrt">
2901 <SOAP:operation soapAction="http://tempuri.org#sqrt"/>
2902 <input>
2903 <SOAP:body use="encoded" namespace="http://tempuri.org"
2904 encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
2905 </input>
2906 <output>
2907 <SOAP:body use="encoded" namespace="http://tempuri.org"
2908 encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
2909 </output>
2910 </operation>
2911 </binding>
2912 <service name="Service">
2913 <port name="ServicePort" binding="tns:ServiceBinding">
2914 <SOAP:address location="http://location/Service.cgi"/>
2915 </port>
2916 </service>
2917 </definitions>
2918 ```
2919 </div>
2920
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 ).
2922
2923 ### How to Use Client Functionalities Within a Service
2924
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.
2926
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).
2932
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
2938 terminal.
2939
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):
2941
2942 ```cpp
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
2947 ```
2948
2949 The `quotex.cpp` client/service application source is:
2950
2951 ```cpp
2952 // Contents of file "quotex.cpp":
2953 #include "soapH.h" // include generated proxy and SOAP support
2954 int main(int argc, char **argv)
2955 {
2956 struct soap soap;
2957 float q;
2958 soap_init(&soap);
2959 if (argc <= 2)
2960 soap_serve(&soap);
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);
2963 else
2964 printf("\nCompany %s: %f (%s)\n", argv[1], q, argv[2]);
2965 return 0;
2966 }
2967 int ns3__getQuote(struct soap *soap, char *symbol, char *country, float &result)
2968 {
2969 float q, r;
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)
2973 {
2974 result = q*r;
2975 soap->socket = socket;
2976 return SOAP_OK;
2977 }
2978 soap->socket = socket;
2979 return SOAP_FAULT; // pass soap fault messages on to the client of this app
2980 }
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.
2985 */
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
2990
2991 struct Namespace namespaces[] =
2992 {
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"},
3000 {NULL, NULL}
3001 };
3002 ```
3003
3004 To compile:
3005
3006 > soapcpp2 quotex.h
3007 > c++ -o quotex.cgi quotex.cpp soapC.cpp soapClient.cpp soapServer.cpp stdsoap2.cpp -lsocket -lxnet -lnsl
3008
3009 Note: under Linux and Mac OS X you can often omit the *`-l`* libraries.
3010
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
3014
3015 > quotex.cgi IBM uk
3016
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
3020 abbreviations.
3021
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
3027 never called.
3028
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
3033 services).
3034
3035 ## Asynchronous One-Way Message Passing {#oneway1}
3036
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.
3039
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.
3042
3043 For example, the following header file specifies an event message for SOAP messaging:
3044
3045 ```cpp
3046 int ns__event(int eventNo, void);
3047 ```
3048
3049 The gSOAP `soapcpp2` tool generates the following functions in `soapClient.cpp`:
3050
3051 ```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);
3054 ```
3055
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.
3060
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:
3064
3065 ```cpp
3066 struct ns__event
3067 { int eventNo;
3068 }
3069 ```
3070
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.)
3073
3074 ```cpp
3075 int soap_serve_ns__event(struct soap *soap);
3076 ```
3077
3078 The skeleton routine calls the user-implemented `ns__event(struct soap *soap, int eventNo)` routine (note the absence of the void
3079 parameter!).
3080
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:
3083
3084 ```cpp
3085 int main()
3086 { soap_serve(soap_new());
3087 }
3088 int ns__event(struct soap *soap, int eventNo)
3089 {
3090 ... // handle event
3091 return SOAP_OK;
3092 }
3093 ```
3094
3095 ## Implementing Synchronous One-Way Message Passing over HTTP {#oneway2}
3096
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.
3103
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:
3110
3111 ```cpp
3112 int ns__event(struct soap *soap, int eventNo)
3113 {
3114 ... // handle event
3115 return soap_send_empty_response(soap, SOAP_OK); // SOAP_OK: return HTTP 202 ACCEPTED
3116 }
3117 ```
3118
3119 At the client side, the empty response header must be parsed as follows:
3120
3121 ```cpp
3122 if (soap_send_ns__event(soap, eventNo) != SOAP_OK
3123 || soap_recv_empty_response(soap) != SOAP_OK)
3124 soap_print_fault(soap, stderr);
3125 ...
3126 ```
3127
3128 The synchronous (and asynchronous) one-way messaging supports HTTP keep-alive and chunking.
3129
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.
3134
3135 ## How to Use the SOAP Serializers and Deserializers to Save and Load Application Data using XML Data Bindings {#bindings}
3136
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.
3142
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>.
3147
3148 ### Mapping XML Schema to C/C++ with wsdl2h
3149
3150 Command:
3151
3152 > wsdl2h [options] XSD and WSDL files ...
3153
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:
3158
3159 <div class="alt">
3160 ```xml
3161 <xs:any [minOccurs, maxOccurs] >
3162 <xs:anyAttribute>
3163 <xs:all>
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] >
3172 ```
3173 </div>
3174
3175 The supported facets are:
3176
3177 <div class="alt">
3178 ```xml
3179 <xs:enumeration>
3180 <xs:simpleContent>
3181 <xs:complexContent>
3182 <xs:list>
3183 <xs:extension>
3184 <xs:restriction>
3185 <xs:length>
3186 <xs:minLength>
3187 <xs:maxLength>
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
3198 ```
3199 </div>
3200
3201 Other:
3202
3203 <div class="alt">
3204 ```xml
3205 <xs:import>
3206 <xs:include>
3207 <xs:redefine>
3208 <xs:override>
3209 <xs:annotation>
3210 ```
3211 </div>
3212
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.
3216
3217 <div class="alt">
3218 ```xml
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)
3239 ```
3240 </div>
3241
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 .
3243
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.
3248
3249 All non-primitive XSD types are supported (with the default mapping shown):
3250
3251 <div class="alt">
3252 ```xml
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
3269 xsd:int maps to int
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
3281 ```
3282 </div>
3283
3284 There are several initialization flags to control XML serialization at runtime:
3285
3286 * XML validation is more stricly enforced with `SOAP_XML_STRICT`.
3287
3288 * XML namespaces are supported, unless disabled with `SOAP_XML_IGNORENS`.
3289
3290 * XML exclusive canonicalization is enabled with `SOAP_XML_CANONICAL`.
3291
3292 * XML default `xmlns="..."` namespace bindings are enforced with `SOAP_XML_DEFAULTNS`.
3293
3294 * XML is indented for enhanced readability with `SOAP_XML_INDENT`.
3295
3296 * XML `xsi:nil` for NULL elements is serialized with `SOAP_XML_NIL`.
3297
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.
3306
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.
3312
3313 ### Mapping C/C++ to XML Schema with soapcpp2
3314
3315 To generate serialization code, execute:
3316
3317 > soapcpp2 [options] header_file.h
3318
3319 The following C/C++ types are supported in the header file:
3320
3321 ```cpp
3322 bool
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)
3332 typedef
3333 time_t
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
3342 ```
3343
3344 Additional features and C/C++ syntax requirements:
3345
3346 * A header file should not include any code statements, only data type declarations.
3347
3348 * Nested classes and nested types are unnested.
3349
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
3352 code.
3353
3354 * C++ namespaces are supported (must cover entire header file content)
3355
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>.
3360
3361 * Types are denoted transient using the 'extern' qualifier, which prevents
3362 serialization as desired:
3363
3364 ```cpp
3365 extern class name; // class 'name' is not serialized
3366 struct name { extern char *name; int num; }; // 'name' is not serialized
3367 ```
3368
3369 * Only public members of a class can be serialized:
3370
3371 ```cpp
3372 class name { private: char *secret; }; // 'secret' is not serialized
3373 ```
3374
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:
3377
3378 ```cpp
3379 volatile class name { ... }; // defined here just to generate the serializers
3380 ```
3381
3382 * Classes and structs declared "mutable" means that they can be augmented with additional members, rather than leading to a redefinition error:
3383
3384 ```cpp
3385 mutable class name { int n; }; // class has a member 'n'
3386 mutable class name { float x; }; // and also a member 'x'
3387 ```
3388
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.
3390
3391 * struct/class members are serialized as attributes when qualified with '@':
3392
3393 ```cpp
3394 struct record { @ char *name; int num; }; // attribute name, element num
3395 ```
3396
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.
3399
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.
3407
3408 ### Serializing C/C++ Data to XML {#serialize}
3409
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.
3411
3412 The following context attributes can be set to control the destination and source for serialization and deserialization:
3413
3414 * `int soap.socket` socket file descriptor for input and output (or set to `SOAP_INVALID_SOCKET`)
3415
3416 * `ostream *soap.os` C++ only: output stream used for send operations
3417
3418 * `const char **soap.os` C only: points to a string pointer to be set with the managed string content
3419
3420 * `istream *soap.is` C++ only: input stream used for receive operations
3421
3422 * `const char *soap.is` C only: string with input to parse (this pointer advances)
3423
3424 * `int soap.sendfd` when `soap.socket`=`SOAP_INVALID_SOCKET`, this fd is used for send operations
3425
3426 * `int soap.recvfd` when `soap.socket`=`SOAP_INVALID_SOCKET`, this fd is used for receive operations
3427
3428 The following initializing and finalizing functions can be used:
3429
3430 * `void soap_begin_send(struct soap*)` start a send/write phase
3431
3432 * `int soap_end_send(struct soap*)` flush the buffer
3433
3434 * `int soap_begin_recv(struct soap*)` start a rec/read phase (if an HTTP header is present, parse it first)
3435
3436 * `int soap_end_recv(struct soap*)` perform a id/href consistency check on deserialized data
3437
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.
3440
3441 The following options are available to control serialization:
3442
3443 ```cpp
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
3448 ```
3449
3450 See also Section \ref flags to control the I/O buffering and content encoding such as compression and DIME encoding.
3451
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.
3453
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.
3459
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.
3464
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
3471 first parameter.
3472
3473 The following table lists the type naming conventions used by gSOAP:
3474
3475 Type | Name
3476 ---- | ----------
3477 `char*` | `string`
3478 `wchar_t*` | `wstring`
3479 `std::string` | `std__string`
3480 `std::wstring` | `std__wstring`
3481 `char` | `byte`
3482 `bool` | `bool`
3483 `double` | `double`
3484 `int` | `int`
3485 `float` | `float`
3486 `long` | `long`
3487 `long long` | `LONG64`
3488 `short` | `short`
3489 `time_t` | `time`
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`
3501
3502 Consider for example the following C code with a declaration of `p` as a
3503 pointer to a `struct ns__Person`:
3504
3505 ```cpp
3506 struct ns__Person { char *name; } *p;
3507 ```
3508
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:
3512
3513 ```cpp
3514 soap_serialize_PointerTons__Person(&soap, &p);
3515 ```
3516
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`):
3522
3523 ```cpp
3524 soap_begin_send(&soap);
3525 soap_put_PointerTons__Person(&soap, &p, "ns:element-name", "ns:type-name");
3526 soap_end_send(&soap);
3527 ```
3528
3529 or the shorthand for the above (without the xsi type):
3530
3531 ```cpp
3532 soap_write_PointerTons__Person(&soap, &p);
3533 ```
3534
3535 This produces:
3536
3537 <div class="alt">
3538 ```xml
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>
3542 </ns:element-name>
3543 ```
3544 </div>
3545
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).
3550
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`.
3552
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.
3557
3558 You can assign an
3559 output stream in C++ to `soap.os` and in C an output string `soap.os`, or a file descriptor to `soap.sendfd`.
3560
3561 For example, to assign a file descriptor:
3562
3563 ```cpp
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);
3569 ```
3570
3571 The above can be abbreviated to
3572
3573 ```cpp
3574 soap.sendfd = open(file, O_RDWR|O_CREAT, S_IWUSR|S_IRUSR);
3575 soap_write_PointerTons__Person(&soap, &p);
3576 ```
3577
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.
3589
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.
3592
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
3598
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:
3602
3603 ```cpp
3604 T1 var1;
3605 T2 var2;
3606 struct soap soap;
3607 ...
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);
3614 ...
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");
3621 ...
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
3626 ...
3627 ```
3628
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.
3634
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.
3638
3639 You can serialize a class instance to a stream as follows:
3640
3641 ```cpp
3642 struct soap soap;
3643 myClass obj;
3644 ... populate obj
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
3653 ...
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
3657 ```
3658
3659 For gSOAP 2.8.28 and later, in C we use `soap.os` to obtain a string with the XML serialized data:
3660
3661 ```cpp
3662 struct soap soap;
3663 struct myClass obj;
3664 const char *out;
3665 ... populate obj
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
3676 ...
3677 soap_end(&soap); // remove deserialized data
3678 soap_done(&soap); // finalize last use of this context
3679 ```
3680
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:
3682
3683 ```cpp
3684 ostream &operator<<(ostream &o, const myClass &e)
3685 {
3686 if (!e.soap)
3687 ... error: need a soap struct to serialize (could use global struct) ...
3688 else
3689 {
3690 ostream *os = e.soap->os;
3691 e.soap->os = &o;
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);
3697 e.soap->os = os;
3698 soap_clr_omode(e.soap, SOAP_XML_GRAPH);
3699 }
3700 return o;
3701 }
3702 ```
3703
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 .
3705
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.
3711
3712 Consider the following `struct`:
3713
3714 ```cpp
3715 // Contents of file "tricky.h":
3716 struct Tricky
3717 {
3718 int *p;
3719 int n;
3720 int *q;
3721 };
3722 ```
3723
3724 The following fragment initializes the pointer fields `p` and `q` to the value of field `n`:
3725
3726 ```cpp
3727 struct soap soap;
3728 struct Tricky X;
3729 X.n = 1;
3730 X.p = &X.n;
3731 X.q = &X.n;
3732 soap_init(&soap);
3733 soap_begin(&soap);
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
3737 ```
3738
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.
3740
3741 The resulting output is:
3742
3743 <div class="alt">
3744 ```xml
3745 <Tricky xsi:type="Tricky">
3746 <p href="#2"/>
3747 <n xsi:type="int">1</n>
3748 <q href="#2"/>
3749 <r xsi:type="int">2</r>
3750 </Tricky>
3751 <id id="2" xsi:type="int">1</id>
3752 ```
3753 </div>
3754
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.
3756
3757 With the `SOAP_XML_GRAPH` flag the output is:
3758
3759 <div class="alt">
3760 ```xml
3761 <Tricky xsi:type="Tricky">
3762 <p href="#2"/>
3763 <n id="2" xsi:type="int">1</n>
3764 <q href="#2"/>
3765 </Tricky>
3766 ```
3767 </div>
3768
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).
3771
3772 ### Deserializing C/C++ Data from XML {#deserialize}
3773
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.
3775
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:
3777
3778 ```cpp
3779 T1 var1;
3780 T2 var2;
3781 struct soap soap;
3782 ...
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"))
3790 ... error ...
3791 if (!soap_get_Type2(&soap, &var2, "[optional: namespace-prefix:]element-name2", "[optional: namespace-prefix:]type-name1"))
3792 ... error ...
3793 ...
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
3798 ```
3799
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, "...", "...")`.
3806
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.
3810
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
3813 `soap_end`.
3814
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`.
3818 Also storing
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.
3823
3824 You can deserialize class instances from a stream as follows:
3825
3826 ```cpp
3827 myClass obj;
3828 struct soap soap;
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)
3833 ... error ...
3834 soap_end_recv(&soap); // check consistency of id/hrefs
3835 ...
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
3839 ```
3840
3841 This can be abbreviated to:
3842
3843 ```cpp
3844 myClass obj;
3845 struct soap soap;
3846 soap_init(&soap); // initialize
3847 soap.is = &cin; // read from cin
3848 if (soap_read_myClass(&soap, &obj, NULL) != SOAP_OK)
3849 ... error ...
3850 ...
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
3854 ```
3855
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:
3857
3858 ```cpp
3859 istream &operator>>(istream &i, myClass &e)
3860 {
3861 if (!e.soap)
3862 ... error: need soap struct to deserialize (could use global struct)...
3863 istream *is = e.soap->is;
3864 e.soap->is = &i;
3865 if (soap_read_myClass(e.soap, &e) != SOAP_OK)
3866 ... error ...
3867 e.soap->is = is;
3868 return i;
3869 }
3870 ```
3871
3872 For gSOAP 2.8.28 and later, you can parse XML from strings as follows:
3873
3874 ```cpp
3875 struct myClass obj;
3876 struct soap soap;
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)
3880 ... error ...
3881 soap.is = NULL; // stop parsing from strings
3882 ...
3883 soap_end(&soap); // remove deserialized data
3884 soap_done(&soap); // finalize last use of the context
3885 ```
3886
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:
3888
3889 ```cpp
3890 istream &operator>>(istream &i, myClass &e)
3891 {
3892 if (!e.soap)
3893 ... error: need soap struct to deserialize (could use global struct)...
3894 istream *is = e.soap->is;
3895 e.soap->is = &i;
3896 if (soap_read_myClass(e.soap, &e) != SOAP_OK)
3897 ... error ...
3898 e.soap->is = is;
3899 return i;
3900 }
3901 ```
3902
3903 ### Example {#example9}
3904
3905 As an example, consider the following data type declarations:
3906
3907 ```cpp
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};
3913 class ns__Address
3914 {
3915 public:
3916 xsd__string street;
3917 xsd__unsignedInt number;
3918 xsd__string city;
3919 };
3920 class ns__Person
3921 {
3922 public:
3923 xsd__Name name;
3924 enum ns__Gender gender;
3925 ns__Address address;
3926 ns__Person *mother;
3927 ns__Person *father;
3928 };
3929 ```
3930
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):
3934
3935 ```cpp
3936 // Contents of file "person.cpp":
3937 #include "soapH.h"
3938 int main()
3939 {
3940 struct soap soap;
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;
3956 john.name = "John";
3957 john.gender = male;
3958 john.address = mother.address;
3959 john.mother = &mother;
3960 john.father = &father;
3961 soap_init(&soap);
3962 soap_omode(&soap, SOAP_ENC_ZLIB|SOAP_XML_GRAPH); // see \ref flags
3963 soap_begin(&soap);
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);
3969 soap_end(&soap);
3970 soap_done(&soap);
3971 }
3972 struct Namespace namespaces[] =
3973 {
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
3979 {NULL, NULL}
3980 };
3981 ```
3982
3983 The header file is processed and the application compiled on Linux/Unix with:
3984
3985 > soapcpp2 person.h
3986 > c++ -DWITH_GZIP -o person person.cpp soapC.cpp stdsoap2.cpp -lsocket -lxnet -lnsl -lz
3987
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
3991 libraries.)
3992 See \ref compression for details on compression with gSOAP.
3993
3994 Running the `person` application results in the compressed XML output:
3995
3996 <div class="alt">
3997 ```xml
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>
4010 </address>
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">
4015 <street href="#3"/>
4016 <number xsi:type="unsignedInt">5</number>
4017 <city href="#4"/>
4018 </address>
4019 </mother>
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>
4026 <city href="#4"/>
4027 </address>
4028 </father>
4029 </johnnie>
4030 ```
4031 </div>
4032
4033 The following program fragment decodes this content from standard input and reconstructs the original data structure on the heap:
4034
4035 ```cpp
4036 #include "soapH.h"
4037 int main()
4038 {
4039 struct soap soap;
4040 ns__Person *mother, *father, *john = NULL;
4041 soap_init(&soap);
4042 soap_imode(&soap, SOAP_ENC_ZLIB); // optional: gzip is detected automatically
4043 soap_begin(&soap);
4044 if ((john = soap_get_ns__Person(&soap, NULL, NULL, NULL)) == NULL)
4045 ... error ...
4046 mother = john->mother;
4047 father = john->father;
4048 ...
4049 soap_end_recv(&soap);
4050 soap_free_temp(&soap); // Clean up temporary data but keep deserialized data
4051 }
4052 struct Namespace namespaces[] =
4053 {
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
4059 {NULL, NULL}
4060 };
4061 ```
4062
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:
4066
4067 ```cpp
4068 #include "soapH.h"
4069 int main()
4070 {
4071 struct soap soap;
4072 ns__Person *mother, *father, john;
4073 soap_init(&soap);
4074 soap_default_ns__Person(&soap, &john);
4075 soap_imode(&soap, SOAP_ENC_ZLIB); // optional
4076 soap_begin(&soap);
4077 soap_begin_recv(&soap);
4078 if (soap_get_ns__Person(&soap, &john, "johnnie", NULL) == NULL)
4079 ... error ...
4080 ...
4081 }
4082 struct Namespace namespaces[] =
4083 ...
4084 ```
4085
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`.
4088
4089 ### Serializing and Deserializing Class Instances to Streams
4090
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.
4093 Consider the class
4094
4095 ```cpp
4096 class ns__person
4097 { public:
4098 char *name;
4099 struct soap *soap; // we need this, see below
4100 ns__person();
4101 ~ns__person();
4102 };
4103 ```
4104
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):
4109
4110 > soapcpp2 person.h
4111
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`.
4116
4117 ```cpp
4118 #include "soapH.h"
4119 #include "ns.nsmap"
4120 ...
4121 struct soap *soap = soap_new();
4122 ns__person *p = soap_new_ns__person(soap);
4123 ...
4124 cout << p; // serialize p in XML
4125 ...
4126 in >> p; // parse XML and deserialize p
4127 ...
4128 soap_destroy(soap); // deletes p too
4129 soap_end(soap);
4130 soap_done(soap);
4131 ```
4132
4133 The stream operations are implemented as follows
4134
4135 ```cpp
4136 ostream &\operator<<(ostream &o, const ns__person &p)
4137 {
4138 if (!p.soap)
4139 return o; // need a gSOAP context to serialize
4140 p.soap->os = &o;
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
4147 return o;
4148 }
4149 istream &\operator>>(istream &i, ns__person &p)
4150 {
4151 if (!p.soap)
4152 return o; // need a gSOAP context to parse XML and deserialize
4153 p.soap->is = &i;
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
4158 return i;
4159 }
4160 ```
4161
4162 ### How to Specify Default Values for Omitted Data {#default}
4163
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:
4166
4167 ```cpp
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
4184 ```
4185
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
4189 deserialization.
4190
4191 Default values can also be assigned to individual `struct` and `class` fields of primitive type. For example,
4192
4193 ```cpp
4194 struct MyRecord
4195 {
4196 char *name = "Unknown";
4197 int value = 9999;
4198 enum Status { active, passive } status = passive;
4199 }
4200 ```
4201
4202 Default values are assigned to the fields on receiving a SOAP/XML message in which the data values are absent.
4203
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
4208 SOAP/XML request:
4209
4210 ```cpp
4211 int ns__login(char *uid = "anonymous", char *pwd = "guest", bool granted);
4212 ```
4213
4214 When the request message lacks uid and pwd parameters, e.g.:
4215
4216 <div class="alt">
4217 ```xml
4218 <?xml version="1.0" encoding="UTF-8"?>
4219 <SOAP-ENV:Envelope
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/">
4226 <ns:login>
4227 </ns:login>
4228 </SOAP-ENV:Body>
4229 </SOAP-ENV:Envelope>
4230 ```
4231 </div>
4232
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
4235 compiler.
4236
4237 # The wsdl2h WSDL and Schema Importer {#wsdlin}
4238
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++.
4242
4243 The creation of C and C++ applications from one of more WSDL service
4244 descriptions is a two-step process.
4245
4246 To convert a WSDL to C++, use:
4247
4248 > wsdl2h file.wsdl
4249
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.
4256
4257 To generate ANSI C, use option `-c`:
4258
4259 > wsdl2h -c file.wsdl
4260
4261 Multiple WSDL specifications can be processed at once and saved to one file with the `-o` option:
4262
4263 > wsdl2h -o file.h file1.wsdl file2.wsdl file3.wsdl
4264
4265 You can retrieve WSDLs from one of more URLs:
4266
4267 > wsdl2h -o file.h http://www.example.com/example.wsdl
4268
4269 To convert XML schemas to C or C++ XML data binding code, use:
4270
4271 > wsdl2h -o file.h file1.xsd file2.xsd file3.xsd
4272
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
4276 application.
4277
4278 To process a gSOAP header file `file.h` (generated by `wsdl2h`) to generate advanced XML data bindings for C++, use:
4279
4280 > soapcpp2 -i -Iimport file.h
4281
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.
4289
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.
4293
4294 Consider for example the following commands to implement a c++ client of a service:
4295
4296 > wsdl2h -o calc.h http://www.genivia.com/calc.wsdl
4297 > soapcpp2 -i -Iimport calc.h
4298
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.
4302
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.
4307
4308 ## wsdl2h Options
4309
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.
4318
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.
4326
4327 The `wsdl2h` command-line options are:
4328
4329 option | result
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)
4371
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.
4374
4375 ## Customizing Data Bindings With The typemap.dat File {#typemap}
4376
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
4380 convenience.
4381
4382 Here is an example typemap file's content:
4383
4384 <div class="alt">
4385 ```xml
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.
4389
4390 [
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
4394 ]
4395 # XML namespace prefix definitions can be provided to override the
4396 # default choice of ns1, ns2, ... prefixes. For example:
4397
4398 i = "http://www.soapinterop.org/"
4399 s = "http://www.soapinterop.org/xsd"
4400 ```
4401 </div>
4402
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:
4406
4407 <div class="alt">
4408 ```xml
4409 prefix__type = declaration | use | ptr-use
4410 ```
4411 </div>
4412
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.
4417
4418 <div class="alt">
4419 ```xml
4420 # Example XML Schema and C/C++ type bindings:
4421
4422 xsd__int = | int
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;
4431 ```
4432 </div>
4433
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.
4436
4437 When a type binding requires only the usage to be changed, the
4438 declaration part can be given by an elipsis ..., as in:
4439
4440 <div class="alt">
4441 ```xml
4442 prefix__type = ... | use | ptr-use
4443 ```
4444 </div>
4445
4446 This ensures that the wsdl2h-generated type definition is preserved,
4447 while the use and ptr-use are remapped.
4448
4449 This method is useful to serialize dynamic types in C, where elements types int
4450 XML carry the *`xsi:type`* attribute.
4451
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`*:
4455
4456 <div class="alt">
4457 ```xml
4458 [
4459 struct __any
4460 {
4461 int __type;
4462 void *__item;
4463 }
4464 ]
4465 xsd__anyType = ... | struct __any | struct __any
4466 ```
4467 </div>
4468
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.
4471
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.
4477
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:
4480
4481 <div class="alt">
4482 ```xml
4483 [
4484 struct __ns__base
4485 {
4486 int __type;
4487 void *__item;
4488 struct ns__base *__self;
4489 }
4490 ]
4491 ns__base = ... | struct __ns__base | struct __ns__base
4492 ```
4493 </div>
4494
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:
4497
4498 ```cpp
4499 struct ns__data
4500 {
4501 ...
4502 struct __ns__base name;
4503 ...
4504 };
4505 ```
4506
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.
4511
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:
4515
4516 <div class="alt">
4517 ```xml
4518 prefix__type = $ member-declaration
4519 ```
4520 </div>
4521
4522 For example, to add a constructor and destructor to class myns__record:
4523
4524 <div class="alt">
4525 ```xml
4526 myns__record = $ myns__record();
4527 myns__record = $ ~myns__record();
4528 ```
4529 </div>
4530
4531 Type remappings can be given to map a type to another type:
4532
4533 <div class="alt">
4534 ```xml
4535 prefix__type1 == prefix__type2
4536 ```
4537 </div>
4538
4539 which replaces *`prefix__type1`* by *`prefix__type2`* in the wsdl2h output.
4540 For example:
4541
4542 <div class="alt">
4543 ```xml
4544 SOAP_ENC__boolean == xsd__boolean
4545 ```
4546 </div>
4547
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.
4549
4550 # Using the soapcpp2 Compiler and Code Generator {#soapcpp2}
4551
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:
4555
4556 > soapcpp2 headerfile.h
4557
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.
4561
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.
4565
4566 The type of files generated by `soapcpp2` are:
4567
4568 * `soapStub.h` A modified and annotated header file produced from the input header file
4569
4570 * `soapH.h` Main header file to be included by all client and service sources
4571
4572 * `soapC.cpp` Serializers and deserializers for the specified data structures
4573
4574 * `soapClient.cpp` Client stub routines for remote operations
4575
4576 * `soapServer.cpp` Service skeleton routines
4577
4578 * `soapClientLib.cpp` Client stubs combined with local static (de)serializers
4579
4580 * `soapServerLib.cpp` Service skeletons combined with local static (de)serializers
4581
4582 * `soapXYZProxy.h` A C++ proxy object (link with soapC.cpp soapClient.cpp)
4583
4584 * `soapXYZProxy.h` With option -i: proxy object (link with soapC.cpp and soapXYZProxy.cpp)
4585
4586 * `soapXYZProxy.cpp` With option -i: proxy code
4587
4588 * `soapXYZObject.h` A C++ server object (link with soapC.cpp and soapServer.cpp)
4589
4590 * `soapXYZService.h` With option -i: server object (link with soapC.cpp and soapXYZService.cpp)
4591
4592 * `soapXYZService.cpp` With option -i: server code
4593
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
4595
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
4597
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
4600
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
4602
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
4610 service.
4611
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 .
4613
4614 The following files are part of the gSOAP package and are required to build client and service applications:
4615
4616 * `stdsoap2.h` Header file of `stdsoap2.cpp` runtime library
4617
4618 * `stdsoap2.c` Runtime C library with XML parser and run-time support routines
4619
4620 * `stdsoap2.cpp` Runtime C++ library identical to `stdsoap2.c`
4621
4622 ## soapcpp2 Options {#options}
4623
4624 The `soapcpp2` source-to-source compiler supports the following command-line options:
4625
4626 option | result
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
4667
4668 For example
4669
4670 > soapcpp2 -c -d 'projects' -pmy file.h
4671
4672 Saves the sources:
4673
4674 * `projects/myH.h`
4675
4676 * `projects/myC.c`
4677
4678 * `projects/myClient.c`
4679
4680 * `projects/myServer.c`
4681
4682 * `projects/myStub.h`
4683
4684 MS Windows users can use the usual "`/`" for options, for example:
4685
4686 soapcpp2 /cd '..\projects' /pmy file.h
4687
4688 Compiler options `c, i, n, l, w` can be set in the gSOAP header file using the `//gsoapopt` directive. For example,
4689
4690 ```cpp
4691 // Generate pure C and do not produce WSDL output:
4692 //gsoapopt cw
4693 int ns__myMethod(char*, char**); // takes a string and returns a string (as pointed to)
4694 ```
4695
4696 ## SOAP 1.1 Versus SOAP 1.2 and Dynamic Switching
4697
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:
4700
4701 ```cpp
4702 struct Namespace namespaces[] =
4703 {
4704 {"SOAP-ENV", "http://www.w3.org/2003/05/soap-envelope", ... },
4705 {"SOAP-ENC", "http://www.w3.org/2003/05/soap-encoding, ... "},
4706 ...
4707 }
4708 ```
4709
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:
4712
4713 ```cpp
4714 struct Namespace namespaces[] =
4715 {
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"},
4718 ...
4719 }
4720 ```
4721
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.
4723
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.
4725
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.
4729
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`:
4731
4732 ```cpp
4733 #import "import/soap12.h"
4734 ```
4735
4736 @warning SOAP 1.2 does not support partially transmitted arrays. So the `__offset` field of a dynamic array is meaningless.
4737
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).
4744
4745 ## The soapdefs.h Header File {#soapdefs}
4746
4747 The `soapdefs.h` header file is included in `stdsoap2.h` when compiling with option `-DWITH_SOAPDEFS_H`:
4748
4749 > c++ -DWITH_SOAPDEFS_H -c stdsoap2.cpp
4750
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`:
4752
4753 > c++ -DSOAPDEFS_H=mydefs.h -c stdsoap2.cpp
4754
4755 For example,
4756
4757 ```cpp
4758 // Contents of soapdefs.h
4759 #include <ostream>
4760 #define SOAP_BUFLEN 65536 // use large send/recv buffer
4761 ```
4762
4763 The following header file can now refer to `ostream`:
4764
4765 ```cpp
4766 extern class ostream; // ostream can't be (de)serialized, but need to be declared to make it visible to gSOAP
4767 class ns__myClass
4768 { ...
4769 virtual void print(ostream &s) const; // need ostream here
4770 ...
4771 };
4772 ```
4773
4774 See also Section \ref transient .
4775
4776 ## How to Build Modules and Libraries with the #module Directive {#module}
4777
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:
4779
4780 ```cpp
4781 #module "name"
4782 ```
4783
4784 and
4785
4786 ```cpp
4787 #module "name" "fullname"
4788 ```
4789
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.
4791
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.
4793
4794 For example:
4795
4796 ```cpp
4797 /* Contents of module.h */
4798 #module "test"
4799 long;
4800 char*;
4801 struct ns__S
4802 { ... }
4803 ```
4804
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.
4806
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 ).
4808
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.
4810
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.
4812
4813 ## How to use the #import Directive {#import}
4814
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 .
4819
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 .
4821
4822 An example of the `#import` directive:
4823
4824 ```cpp
4825 #import "mydefs.gsoap"
4826 int ns__mymethod(xsd__string in, xsd__int *out);
4827 ```
4828
4829 where `"mydefs.gsoap"` is a gSOAP header file that defines `xsd__string` and `xsd__int`:
4830
4831 ```cpp
4832 typedef char *xsd__string;
4833 typedef int xsd__int;
4834 ```
4835
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).
4837
4838 ## How to Use #include and #define Directives {#pragmas}
4839
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`.
4845
4846 The following example header file refers to `ostream` by including `<ostream>`:
4847
4848 ```cpp
4849 #include <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
4855 class ns__myClass
4856 { ...
4857 virtual void print(ostream &s) const; // need ostream here
4858 ...
4859 };
4860 ```
4861
4862 This example also uses `#define` directives for various settings in the target source code.
4863
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.
4867
4868 ## Compiling a SOAP/XML Client Application with soapcpp2
4869
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:
4871
4872 > c++ -o myclient myclient.cpp stdsoap2.cpp soapC.cpp soapClient.cpp
4873
4874 Or on a Unix machine:
4875
4876 > c++ -o myclient myclient.cpp stdsoap2.cpp soapC.cpp soapClient.cpp -lsocket -lxnet -lnsl
4877
4878 (Depending on your system configuration, the libraries `libsocket.a`,
4879 `libxnet.a`, `libnsl.a` or dynamic `*.so` versions of those libraries are required.)
4880
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:
4882
4883 ```cpp
4884 // Contents of file "myclient.cpp"
4885 #include "soapH.h";
4886 ...
4887 // A service operation invocation:
4888 soap_call_some_remote_method(...);
4889 ...
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"},
4897 {NULL, NULL}
4898 };
4899 ...
4900 ```
4901
4902 A mapping table is generated by the gSOAP `soapcpp2` compiler that can be used in the source, see Section \ref wsdl .
4903
4904 ## Compiling a SOAP/XML Web Service with soapcpp2
4905
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:
4907
4908 > c++ -o myserver myserver.cpp stdsoap2.cpp soapC.cpp soapServer.cpp
4909
4910 Or on a Unix machine:
4911
4912 > c++ -o myserver myserver.cpp stdsoap2.cpp soapC.cpp soapServer.cpp -lsocket -lxnet -lnsl
4913
4914 (Depending on your system configuration, the libraries `libsocket.a`,
4915 `libxnet.a`, `libnsl.a` or dynamic `*.so` versions of those libraries are required.)
4916
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:
4918
4919 ```cpp
4920 // Contents of file "myserver.cpp"
4921 #include "soapH.h";
4922 int main()
4923 {
4924 soap_serve(soap_new());
4925 }
4926 ...
4927 // Implementations of the service operations as C++ functions
4928 ...
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"},
4936 {NULL, NULL}
4937 };
4938 ...
4939 ```
4940
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.
4946
4947 ## Compiling Web Services and Clients in ANSI C
4948
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:
4953
4954 > soapcpp2 -c quote.h
4955 > cc -o quote quote.c stdsoap2.c soapC.c soapClient.c
4956
4957 Warnings will be issued by the compiler when C++ class declarations occur in the header file.
4958
4959 ## Limitations of gSOAP {#limitations}
4960
4961 gSOAP is SOAP 1.1 and SOAP 1.2 compliant and supports SOAP RPC and document/literal operations.
4962
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.
4964
4965 There are certain limitations for the following C++ language constructs:
4966
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 ).
4968
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.
4970
4971 * Multiple inheritance: Single class inheritance is supported. Multiple inheritance cannot be supported due to limitations of the SOAP protocol.
4972
4973 * Abstract methods: A class must be instantiatable to allow decoding of instances of the class.
4974
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 .
4980
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.
4982
4983 The following data types require some attention to ensure they are serialized:
4984
4985
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.
4987
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 .
4989
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 .
4995
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.
4998
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,
5003 see \ref dynarray .
5004
5005 ## Library Build Flags {#compilerflags}
5006
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:
5008
5009 define | result
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)`
5040
5041 Compile-time flags to change the default engine settings:
5042
5043 define | result
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)
5049
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.
5056
5057 ## Run Time Flags {#flags}
5058
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).
5062
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
5068 messages.
5069
5070 To set and clear flags for inbound message processing use:
5071
5072 ```cpp
5073 soap_set_imode(soap, inflag);
5074 soap_clr_imode(soap, inflag);
5075 ```
5076
5077 To set and clear the flags for outbound message processing use:
5078
5079 ```cpp
5080 soap_set_omode(soap, outflag);
5081 soap_clr_imode(soap, outflag);
5082 ```
5083
5084 To allocate and initialize a gSOAP context with inbound and outbound flags use:
5085
5086 ```cpp
5087 soap_new2(soap, inflag, outflag);
5088 ```
5089
5090 To initialize an unitialized gSOAP context with inbound and outbound flags use:
5091
5092 ```cpp
5093 soap_init2(soap, inflag, outflag);
5094 ```
5095
5096 The input-mode and output-mode flags for inbound and outbound message processing are:
5097
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)
5127
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.
5130
5131 All flags are orthogonal, except
5132 `SOAP_IO_FLUSH`,
5133 `SOAP_IO_BUFFER`,
5134 `SOAP_IO_STORE`, and
5135 `SOAP_IO_CHUNK`
5136 which are enumerations and only one of these I/O flags can be used. Also the
5137 XML serialization flags
5138 `SOAP_XML_TREE` and
5139 `SOAP_XML_GRAPH` should not be mixed.
5140
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:
5144
5145 * `soap_init2(struct soap *soap, int imode, int omode)` Initialize the runtime and set flags
5146
5147 * `soap_imode(struct soap *soap, int imode)` Set all input mode flags
5148
5149 * `soap_omode(struct soap *soap, int omode)` Set all output mode flags
5150
5151 * `soap_set_imode(struct soap *soap, int imode)` Enable input mode flags
5152
5153 * `soap_set_omode(struct soap *soap, int omode)` Enable output mode flags
5154
5155 * `soap_clr_imode(struct soap *soap, int omode)` Disable input mode flags
5156
5157 * `soap_clr_omode(struct soap *soap, int omode)` Disable output mode flags
5158
5159 The default setting is `SOAP_IO_DEFAULT` for both input and output modes.
5160
5161 For example
5162
5163 ```cpp
5164 struct soap soap;
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, ...))
5168 ...
5169 ```
5170
5171 sends a compressed client request with keep-alive enabled and all data serialized as canonical XML trees.
5172
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`.
5179
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.
5184
5185 Additional run-time flags to control sockets.
5186
5187 Use the following selection of flags that are OS dependent to control sockets for send/sendto/recv/recvfrom operations:
5188
5189 * `MSG_NOSIGNAL` disables sigpipe (check your OS, this is not portable)
5190
5191 * `MSG_DONTROUTE` bypass routing, use direct interface
5192
5193 Use the following selection of flags to set client-side socket connection flags (setsockopt):
5194
5195 * `SO_NOSIGPIPE` disables sigpipe (check your OS, this is not portable)
5196
5197 * `SO_DEBUG` turns on recording of debugging information in the underlying protocol modules
5198
5199 * `SO_BROADCAST` permits sending of broadcast messages (e.g. with UDP) when permitted
5200
5201 * `SO_LINGER` set `soap.linger_time` (set this value as needed)
5202
5203 Use the following selection of flags to set server-side socket connection accept flags (setsockopt):
5204
5205 * `SO_NOSIGPIPE` disables sigpipe (check your OS, this is not portable)
5206
5207 * `SO_DEBUG` turns on recording of debugging information in the underlying protocol modules
5208
5209 * `SO_REUSEADDR` reuse bind address immediately (prevents bind reject)
5210
5211 * `SO_LINGER` set `soap.linger_time` (set this value as needed)
5212
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).
5214
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.
5216
5217 ## Memory Management {#memory}
5218
5219 Understanding gSOAP's run-time memory management is important to optimize
5220 client and service applications by eliminating memory leaks and/or dangling
5221 references.
5222
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.
5235
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.
5237
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.
5243
5244 The deallocation functions are:
5245
5246 * `soap_destroy(struct soap *soap)` Remove all dynamically allocated C++ objects. must be called before `soap_end()`
5247
5248 * `soap_end(struct soap *soap)` Remove temporary data and deserialized data except class instances
5249
5250 * `soap_free_temp(struct soap *soap)` Instead of `soap_destroy` and `soap_end`: remove temporary data only
5251
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
5253
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))
5255
5256 * `soap_unlink(struct soap *soap, void *p)` Unlink data/object at `p` from gSOAP's deallocation chain so gSOAP won't deallocate it
5257
5258 * `soap_done(struct soap *soap)` Detach context (reset runtime context)
5259
5260 * `soap_free(struct soap *soap)` Detach and free context (allocated with `soap_new`)
5261
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.
5275
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.
5279
5280 ### Memory Allocation and Management Policies
5281
5282 There are three situations to consider for memory deallocation policies for class instances:
5283
5284
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,
5288
5289 * or the class
5290 destructors SHOULD NOT deallocate any data and the `soap_end` and `soap_destroy` functions can be called to remove
5291 the data.
5292
5293 * or the class
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.
5297
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).
5306
5307 To summarize, it is advised to pass class data types by pointer to a service operation. For example:
5308
5309 ```cpp
5310 class X { ... };
5311 ns__remoteMethod(X *in, ...);
5312 ```
5313
5314 Response elements that are class data types can be passed by reference, as in:
5315
5316 ```cpp
5317 class X { ... };
5318 class ns__remoteMethodResponse { ... };
5319 ns__remoteMethod(X *in, ns__remoteMethodResponse &out);
5320 ```
5321
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:
5324
5325 ```cpp
5326 typedef int xsd__int;
5327 class X { ... };
5328 class ArrayOfint { xsd__int *__ptr; int __size; };
5329 ns__remoteMethod(X *in, ArrayOfint *out);
5330 ```
5331
5332 Or a reference to a valid or `NULL` pointer, as in:
5333
5334 ```cpp
5335 typedef int xsd__int;
5336 class X { ... };
5337 class ArrayOfint { xsd__int *__ptr; int __size; };
5338 ns__remoteMethod(X *in, ArrayOfint *&out);
5339 ```
5340
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:
5344
5345 * `void *soap_malloc(struct soap *soap, size_t n)` return pointer to `n` bytes
5346
5347 * `Type *soap_new_Type(struct soap *soap)` allocate and instantiate
5348
5349 * `Type *soap_new_Type(struct soap *soap, int n)` instantiate array of `n` objects
5350
5351 * `Type *soap_new_set_Type(struct soap *soap, m1, ..., mn)` instantiate and set members
5352
5353 * `Type *soap_new_req_Type(struct soap *soap, m1, ..., mn)` instantiate and set required-only members
5354
5355 The `soap_new_X` functions are generated by the gSOAP `soapcpp2` compiler for every type in the header file.
5356
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*)`.
5359
5360 For example, the following service uses temporary data in the service operation implementation:
5361
5362 ```cpp
5363 int main()
5364 {
5365 ...
5366 struct soap soap;
5367 soap_init(&soap);
5368 soap_serve(&soap);
5369 soap_end(&soap);
5370 ...
5371 }
5372 ```
5373
5374 An example service operation that allocates a temporary string is:
5375
5376 ```cpp
5377 int ns__itoa(struct soap *soap, int i, char **a)
5378 {
5379 *a = (char*)soap_malloc(soap, 11);
5380 sprintf(*a, "%d", i);
5381 return SOAP_OK;
5382 }
5383 ```
5384
5385 This temporary allocation can also be used to allocate strings for the SOAP Fault data structure. For example:
5386
5387 ```cpp
5388 int ns__mymethod(...)
5389 { ...
5390 if (exception)
5391 {
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
5395 }
5396 ...
5397 }
5398 ```
5399
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.
5404
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.
5407
5408 gSOAP provides a function to duplicate a string into gSOAP's memory space:
5409
5410 ```cpp
5411 char *soap_strdup(struct soap *soap, const char *s)
5412 ```
5413
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.
5417
5418 ### Intra-Class Memory Management {#classmemory}
5419
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`.
5425 For example:
5426
5427 ```cpp
5428 class Sample
5429 { public:
5430 struct soap *soap; // reference to gSOAP's run-time
5431 ...
5432 Sample();
5433 ~Sample();
5434 };
5435 ```
5436
5437 The constructor and destructor for class `Sample` are:
5438
5439 ```cpp
5440 Sample::Sample()
5441 { this->soap = NULL;
5442 }
5443 Sample::~Sample()
5444 { soap_unlink(this->soap, this);
5445 }
5446 ```
5447
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:
5451
5452 ```cpp
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
5455 ...
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
5459 ```
5460
5461 Here is another example:
5462
5463 ```cpp
5464 class ns__myClass
5465 { ...
5466 struct soap *soap; // set by soap_new_ns__myClass()
5467 char *name;
5468 void setName(const char *s);
5469 ...
5470 };
5471 ```
5472
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.
5477 For example
5478
5479 ```cpp
5480 int ns__myMethod(struct soap *soap, ...)
5481 {
5482 ns__myClass *p = soap_new_ns__myClass(soap);
5483 p->setName("SOAP");
5484 return SOAP_OK;
5485 }
5486 void ns__myClass::ns__setName(const char *s)
5487 {
5488 if (soap)
5489 name = (char*)soap_malloc(soap, strlen(s)+1);
5490 else
5491 name = (char*)malloc(strlen(s)+1);
5492 strcpy(name, s);
5493 }
5494 ns__myClass::ns__myClass()
5495 {
5496 soap = NULL;
5497 name = NULL;
5498 }
5499 ns__myClass::~ns__myClass()
5500 {
5501 if (!soap && name) free(name);
5502 soap_unlink(soap, this);
5503 }
5504 ```
5505
5506 Calling `soap_destroy` right after `soap_serve` in the Web Service will destroy all dynamically allocated
5507 class instances.
5508
5509 ## Debugging
5510
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`.
5517
5518 When your client and server applications run, they will log their activity in three
5519 separate files:
5520
5521 * `SENT.log` the SOAP content transmitted by the application
5522
5523 * `RECV.log` the SOAP content received by the application
5524
5525 * `TEST.log` a log containing various activities performed by the application
5526
5527 @warning The client and server applications may run slow due to the logging activity.
5528
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.
5532
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.
5536
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,
5542
5543 > ./myservice.cgi < SENT.tst
5544
5545 This should display the service response on the terminal.
5546
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:
5550
5551 ```cpp
5552 struct soap soap;
5553 soap_init(&soap);
5554 ...
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
5558 ...
5559 soap_serve(&soap);
5560 ...
5561 ```
5562
5563 Likewise, messages can be logged for individual client-side service operation calls.
5564
5565 ## Generating an Auto Test Server for Client Testing
5566
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.
5568
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`:
5573
5574 > ./tester < example.req.xml
5575
5576 which then returns the response with default XML values displayed on the terminal.
5577
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:
5579
5580 > ./tester 16 8080
5581
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.
5586
5587 ## Generating Deep Copy and Deletion Code
5588
5589 The `soapcpp2 -Ec` option generates deep copy code for each type `T`:
5590
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
5598 `dst` is NULL).
5599
5600 For classes `T`, also a deep copy method is generated with option `-Ec`:
5601
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.
5608
5609 The `soapcpp2 -Ed` option generates deep deletion code for each type
5610 `T`:
5611
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
5618 itself.
5619
5620 For classes `T`, also a deep deletion method is generated with option
5621 `-Ed`:
5622
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
5629 itself.
5630
5631 ## Required Libraries
5632
5633
5634
5635 * The socket library is essential and requires the inclusion of the appropriate libraries with the compile command for Sun
5636 Solaris systems:
5637
5638 > c++ -o myclient myclient.cpp stdsoap2.cpp soapC.cpp soapClient.cpp -lsocket -lxnet -lnsl
5639
5640 These library loading options are not required with Linux.
5641
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:
5645
5646 > c++ -o myclient myclient.cpp stdsoap2.cpp soapC.cpp soapClient.cpp -lsocket -lxnet -lnsl
5647
5648 # The gSOAP Service Operation Specification Format
5649
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.
5654
5655 The general format of a service operation specification is:
5656
5657 ```cpp
5658 [optional: int] [optional: namespace_prefix__]method_name([optional: inparam1, inparam2, ...,] outparam);
5659 ```
5660
5661 where
5662
5663 * `namespace_prefix__` is the optional namespace prefix of the method (see identifier translation rules \ref idtrans )
5664
5665 * `method_name` it the service operation name (see identifier translation rules \ref idtrans )
5666
5667 * `inparam` is the declaration of an input parameter of the service operation
5668
5669 * `outparam` is the declaration of the output parameter of the service operation
5670
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.
5675
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:
5677
5678 <div class="alt">
5679 ```xml
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>
5683 ...
5684 </[optional: namespace-prefix:]method_name>
5685 ```
5686 </div>
5687
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: ].)
5690
5691 The XML response by the Web service is of the form:
5692
5693 <div class="alt">
5694 ```xml
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>
5698 ```
5699 </div>
5700
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.
5704
5705 The gSOAP `soapcpp2` tool generates a stub routine for the service
5706 operation. This stub is of the form:
5707
5708 ```cpp
5709 int soap_call_[optional: namespace_prefix__]method_name(struct soap *soap, char *URL, char *action, [optional: inparam1, inparam2, ...,] outparam);
5710 ```
5711
5712 This proxy can be called by a client application to perform the service operation
5713 call.
5714
5715 The gSOAP `soapcpp2` tool generates a skeleton routine for the
5716 service operation. The skeleton function is:
5717
5718 ```cpp
5719 int soap_serve_[optional: namespace_prefix__]method_name(struct soap *soap);
5720 ```
5721
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.
5727
5728 ## Service Operation Parameter Passing {#param}
5729
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
5741 the caller.
5742
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 `&`.
5746
5747 The input and output parameter types have certain limitations, see
5748 Section \ref limitations
5749
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`*".
5760
5761 The general form of a response element declaration is:
5762
5763 ```cpp
5764 struct [optional: namespace_prefix__]response_element_name
5765 {
5766 outparam1;
5767 outparam2;
5768 ...
5769 };
5770 ```
5771
5772 where
5773
5774 * `namespace_prefix__` is the optional namespace prefix of the response element (see identifier translation rules \ref idtrans )
5775
5776 * `response_element_name` it the name of the response element (see identifier translation rules \ref idtrans )
5777
5778 * `outparam` is the declaration of an output parameter of the service operation
5779
5780 The general form of a service operation specification with a response element declaration for (multiple) output parameters is:
5781
5782 ```cpp
5783 [optional: int] [optional: namespace_prefix__]method_name([optional: inparam1, inparam2, ...,] struct [optional: namespace_prefix__]response_element_name {outparam1[optional: , outparam2, ...]} &anyparam);
5784 ```
5785
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
5787 response.
5788
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
5791 format:
5792
5793 <div class="alt">
5794 ```xml
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>
5798 ...
5799 </[optional: namespace-prefix:]method-name>
5800 ```
5801 </div>
5802
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
5806 [optional: ].)
5807
5808 The method response is expected to be of the form:
5809
5810 <div class="alt">
5811 ```xml
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>
5815 ...
5816 </[optional: namespace-prefix:]response-element-name>
5817 ```
5818 </div>
5819
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
5823 [optional: ].)
5824
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 .
5828
5829 ## Error Codes {#errcodes}
5830
5831 The error codes returned by the stub and skeleton routines are listed below.
5832
5833 code | description
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)
5885
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.
5901
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)`.
5914
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:
5919
5920 code | description
5921 ---- | -----------
5922 201 | Created
5923 202 | Accepted
5924 203 | Non-Authoritative Information
5925 204 | No Content
5926 205 | Reset Content
5927 206 | Partial Content
5928 300 | Multiple Choices
5929 301 | Moved Permanently
5930 302 | Found
5931 303 | See Other
5932 304 | Not Modified
5933 305 | Use Proxy
5934 307 | Temporary Redirect
5935 400 | Bad Request
5936 401 | Unauthorized
5937 402 | Payment Required
5938 403 | Forbidden
5939 404 | Not Found
5940 405 | Method Not Allowed
5941 406 | Not Acceptable
5942 407 | Proxy Authentication Required
5943 408 | Request Time-out
5944 409 | Conflict
5945 410 | Gone
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
5955 502 | Bad Gateway
5956 503 | Service Unavailable
5957 504 | Gateway Time-out
5958 505 | HTTP Version not supported
5959
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.
5961
5962 ## C/C++ Identifier Name to XML Tag Name Mapping {#idtrans}
5963
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
5968 name of the form
5969
5970 ```cpp
5971 [optional: namespace_prefix__]element_name
5972 ```
5973
5974 where the prefix and the element name are separated by double underscores will be encoded in XML as
5975
5976 <div class="alt">
5977 ```xml
5978 <[optional: namespace-prefix:]element-name ...>
5979 ```
5980 </div>
5981
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.
5989
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:
5999
6000 ```cpp
6001 class n_s__biz_DOTcom
6002 {
6003 char *n_s__biz_USCOREname;
6004 };
6005 ```
6006
6007 is encoded in XML as:
6008
6009 <div class="alt">
6010 ```xml
6011 <n-s:biz.com xsi:type="n-s:biz.com">
6012 <n-s:biz_name xsi:type="string">Bizybiz</n-s:biz_name>
6013 </n-s:biz.com>
6014 ```
6015 </div>
6016
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.
6026
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`*.
6033
6034 By default, `soapcpp2` generates data bindings in which all XML elements are and attributes are unqualified:
6035
6036 ```cpp
6037 //gsoap x schema namespace: urn:x
6038 struct x__record
6039 {
6040 @ char * type;
6041 char * name;
6042 };
6043 ```
6044
6045 where the `name` element and the `type` attribute are unqualified in the XML content (for example to facilitate SOAP RPC encoding).
6046
6047 To force qualification of elements and attributes, use the "form" directive:
6048
6049 ```cpp
6050 //gsoap x schema namespace: urn:x
6051 //gsoap x schema form: qualified
6052 struct x__record
6053 {
6054 @ char * type;
6055 char * name;
6056 };
6057 ```
6058
6059 You can also use "elementForm" and "attributeForm" directives to (un)qualify local element and attributes, respectively.
6060
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
6064 be used.
6065
6066 If explicit qualification is needed, this can be done using the prefix convention:
6067
6068 ```cpp
6069 //gsoap x schema namespace: urn:x
6070 //gsoap y schema namespace: urn:y
6071 struct x__record
6072 {
6073 @ char * xsi__type;
6074 char * y__name;
6075 };
6076 ```
6077
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.
6079
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.
6086
6087 The colon notation for type names, struct/class names and members overrides the prefix qualification rules explicitly:
6088
6089 ```cpp
6090 //gsoap x schema namespace: urn:x
6091 //gsoap y schema namespace: urn:y
6092 struct x:record
6093 {
6094 @ char * xsi:type;
6095 char * y:name;
6096 };
6097 ```
6098
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:
6101
6102 ```cpp
6103 // This code is generated from the above by soapcpp2 in soapStub.h:
6104 struct record
6105 {
6106 char *type; /* optional attribute of type xsd:string */
6107 char *name; /* optional element of type xsd:string */
6108 };
6109 ```
6110
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.
6114
6115 The colon notation also allows you to override the element/attribute form to unqualified for qualified schemas:
6116
6117 ```cpp
6118 //gsoap x schema namespace: urn:x
6119 //gsoap x schema form: qualified
6120 struct x:record
6121 {
6122 @ char * :type;
6123 char * :name;
6124 };
6125 ```
6126
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
6129 the `x` schema.
6130
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:
6134
6135 ```cpp
6136 enum x:color { RED, WHITE, BLUE };
6137 enum y:color { YELLOW, ORANGE }; // illegal enum name: name clash with x:color
6138 ```
6139
6140 while prefixing with double underscores never lead to clashes:
6141
6142 ```cpp
6143 enum x__color { RED, WHITE, BLUE };
6144 enum y__color { YELLOW, ORANGE }; // no name clash
6145 ```
6146
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.
6150
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:
6154
6155 ```cpp
6156 //gsoap x schema namespace: urn:x
6157 //gsoap x schema form: qualified
6158 struct x:record
6159 {
6160 @ char * t `type{}`;
6161 char * s `full-name{}`;
6162 };
6163 ```
6164
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.
6168
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.
6170
6171 ## Namespace Mapping Table {#nstable}
6172
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:
6177
6178 ```cpp
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
6187 };
6188 ```
6189
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.
6196
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:
6204
6205 ```cpp
6206 struct Namespace namespaces[] =
6207 { // {"ns-prefix", "ns-name", "ns-name validation pattern"}
6208 ...
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"},
6211 ...
6212 ```
6213
6214 Or alternatively, asterisks can be used as wildcards for multiple characters:
6215
6216 ```cpp
6217 struct Namespace namespaces[] =
6218 { // {"ns-prefix", "ns-name", "ns-name validation pattern"}
6219 ...
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"},
6222 ...
6223 ```
6224
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.
6231
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:
6236
6237
6238 * the string in the second column matches the namespace URI (case insensitive)
6239
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
6242
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.
6246
6247 For example, let's say we have the following structs:
6248
6249 ```cpp
6250 struct a__elt { ... };
6251 struct b__elt { ... };
6252 struct k__elt { ... };
6253 ```
6254
6255 and a namespace mapping table in the program:
6256
6257 ```cpp
6258 struct Namespace namespaces[] =
6259 { // {"ns-prefix", "ns-name", "ns-name validation pattern"}
6260 ...
6261 {"a", "some uri"},
6262 {"b", "other uri"},
6263 {"c", "his uri", "* uri"},
6264 ...
6265 ```
6266
6267 Then, the following XML elements will match the structs:
6268
6269 <div class="alt">
6270 ```xml
6271 <n:elt xmlns:n="some URI"> \qquad\mbox{matches the struct name `a__elt`}
6272 ...
6273 <m:elt xmlns:m="other URI"> \qquad\mbox{matches the struct name `b__elt`}
6274 ...
6275 <k:elt xmlns:k="my URI"> \qquad\mbox{matches the struct name `c__elt`}
6276 ...
6277 ```
6278 </div>
6279
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`*.
6282
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:
6289
6290 ```cpp
6291 struct Namespace namespacesTable1[] = { ... };
6292 struct Namespace namespacesTable2[] = { ... };
6293 struct Namespace namespacesTable3[] = { ... };
6294 struct Namespace *namespaces;
6295 ...
6296 struct soap soap;
6297 ...
6298 soap_init(&soap);
6299 soap_set_namespaces(&soap, namespaceTable1);
6300 soap_call_remote_method(&soap, URL, Action, ...);
6301 ...
6302 ```
6303
6304 # gSOAP Serialization and Deserialization Rules
6305
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.
6307
6308 ## SOAP RPC Encoding Versus Document/Literal and xsi:type Info
6309
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.
6314
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.
6321
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.
6327
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.
6332
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.
6338
6339 ## Primitive Type Encoding
6340
6341 The default encoding rules for the primitive C and C++ data types are given in the table below:
6342
6343 C/C++ type | XML schema type
6344 -------------------- | ---------------
6345 `bool` | *`boolean`*
6346 `char*` | *`string`*
6347 `char` | *`byte`*
6348 `long double` | *`decimal`* with `#import "custom/long_double.h"`
6349 `double` | *`double`*
6350 `float` | *`float`*
6351 `int` | *`int`*
6352 `long` | *`long`*
6353 `LONG64` | *`long`*
6354 `long long` | *`long`*
6355 `short` | *`short`*
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`*
6368
6369 Objects of type `void` and `void *` cannot be encoded.
6370 Enumerations and bit masks are supported as well, see \ref enum .
6371
6372 ## How to Represent Primitive C/C++ Types as XSD Types {#primitive}
6373
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.
6382
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.
6387
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
6393 SOAP payload.
6394
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.
6401
6402 For example, the declaration
6403
6404 ```cpp
6405 typedef unsigned int xsd__positiveInteger;
6406 ```
6407
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
6410
6411 <div class="alt">
6412 ```xml
6413 <positiveInteger xsi:type="xsd:positiveInteger">3</positiveInteger>
6414 ```
6415 </div>
6416
6417 <img src="https://www.w3.org/TR/xmlschema-2/type-hierarchy.gif"/>
6418
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__`.
6422
6423 * *`xsd:anyURI`*
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:
6428
6429 ```cpp
6430 typedef char *xsd__anyURI;
6431 ```
6432
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:
6438
6439 ```cpp
6440 typedef char *xsd__base64Binary;
6441 ```
6442
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.
6444
6445
6446 * *`xsd:boolean`*
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:
6450
6451 ```cpp
6452 typedef bool xsd__boolean;
6453 ```
6454
6455 Type `xsd__boolean` declares a Boolean (0 or 1), which is encoded as
6456
6457 <div class="alt">
6458 ```xml
6459 <xsd:boolean xsi:type="xsd:boolean">...</xsd:boolean>
6460 ```
6461 </div>
6462
6463
6464 * *`xsd:byte`*
6465 Represents a byte (-128...127). The corresponding type declaration is:
6466 ```cpp
6467 typedef char xsd__byte;
6468 ```
6469
6470 Type `xsd__byte` declares a byte which is encoded as
6471
6472 <div class="alt">
6473 ```xml
6474 <xsd:byte xsi:type="xsd:byte">...</xsd:byte>
6475 ```
6476 </div>
6477
6478
6479 * *`xsd:dateTime`*
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:
6485
6486 ```cpp
6487 typedef time_t xsd__dateTime;
6488 ```
6489
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.
6493
6494 Strings (`char*`) can be used to store *`xsd:dateTime`* XSD Schema types. The type declaration is:
6495
6496 ```cpp
6497 typedef char *xsd__dateTime;
6498 ```
6499 In this case, it is up to the application to read and set the dateTime representation.
6500
6501
6502 * *`xsd:date`*
6503 Represents a date.
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:
6506
6507 ```cpp
6508 typedef char *xsd__date;
6509 ```
6510
6511
6512 * *`xsd:decimal`*
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:
6515
6516 ```cpp
6517 typedef double xsd__decimal;
6518 ```
6519
6520 Type `xsd__decimal` declares a double floating point number which is encoded as
6521
6522 <div class="alt">
6523 ```xml
6524 <xsd:double xsi:type="xsd:decimal">...</xsd:double>
6525 ```
6526 </div>
6527
6528
6529 * *`xsd:double`*
6530 Corresponds to the IEEE double-precision 64-bit floating point type. The type declaration is:
6531
6532 ```cpp
6533 typedef double xsd__double;
6534 ```
6535
6536 Type `xsd__double` declares a double floating point number which is encoded as
6537
6538 <div class="alt">
6539 ```xml
6540 <xsd:double xsi:type="xsd:double">...</xsd:double>
6541 ```
6542 </div>
6543
6544
6545 * *`xsd:duration`*
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:
6552
6553 ```cpp
6554 typedef char *xsd__duration;
6555 ```
6556
6557
6558 * *`xsd:float`*
6559 Corresponds to the IEEE single-precision 32-bit floating point type. The type declaration is:
6560
6561 ```cpp
6562 typedef float xsd__float;
6563 ```
6564
6565 Type `xsd__float` declares a floating point number which is encoded as
6566
6567 <div class="alt">
6568 ```xml
6569 <xsd:float xsi:type="xsd:float">...</xsd:float>
6570 ```
6571 </div>
6572
6573
6574 * *`xsd:hexBinary`*
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:
6581
6582 ```cpp
6583 typedef char *xsd__hexBinary;
6584 ```
6585
6586 With this approach, it is solely the responsibility of the application to make sure the string content consists of a sequence of octets.
6587
6588
6589 * *`xsd:int`*
6590 Corresponds to a 32-bit integer in the range -2147483648 to 2147483647.
6591
6592 ```cpp
6593 typedef int xsd__int;
6594 ```
6595
6596 Type `xsd__int` declares a 32-bit integer which is encoded as
6597
6598 <div class="alt">
6599 ```xml
6600 <xsd:int xsi:type="xsd:int">...</xsd:int>
6601 ```
6602 </div>
6603
6604
6605 * *`xsd:integer`*
6606 Corresponds to an unbounded integer.
6607 Since C++ does not support unbounded integers as a standard feature, the recommended type declaration is:
6608
6609 ```cpp
6610 typedef long long xsd__integer;
6611 ```
6612
6613 Type `xsd__integer` declares a 64-bit integer which is encoded as an unbounded *`xsd:integer`*:
6614
6615 <div class="alt">
6616 ```xml
6617 <xsd:integer xsi:type="xsd:integer">...</xsd:integer>
6618 ```
6619 </div>
6620
6621 Another possibility is to use strings to represent unbounded integers and do the translation in code.
6622
6623
6624 * *`xsd:long`*
6625 Corresponds to a 64-bit integer in the range -9223372036854775808 to 9223372036854775807.
6626 The type declaration is:
6627
6628 ```cpp
6629 typedef long long xsd__long;
6630 ```
6631
6632 Or
6633
6634 ```cpp
6635 typedef LONG64 xsd__long;
6636 ```
6637
6638 Or
6639
6640 ```cpp
6641 typedef int64_t xsd__long;
6642 ```
6643
6644 Type `xsd__long` declares a 64-bit integer which is encoded as
6645
6646 <div class="alt">
6647 ```xml
6648 <xsd:long xsi:type="xsd:long">...</xsd:long>
6649 ```
6650 </div>
6651
6652
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:
6656
6657 ```cpp
6658 typedef long long xsd__negativeInteger;
6659 ```
6660
6661 Type `xsd__negativeInteger` declares a 64-bit integer which is encoded as a *`xsd:negativeInteger`*:
6662
6663 <div class="alt">
6664 ```xml
6665 <xsd:negativeInteger xsi:type="xsd:negativeInteger">...</xsd:negativeInteger>
6666 ```
6667 </div>
6668
6669 Another possibility is to use strings to represent unbounded integers and do the translation in code.
6670
6671
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:
6675
6676 ```cpp
6677 typedef unsigned long long xsd__nonNegativeInteger;
6678 ```
6679
6680 Type `xsd__nonNegativeInteger` declares a 64-bit unsigned integer which is encoded as a non-negative unbounded *`xsd:nonNegativeInteger`*:
6681
6682 <div class="alt">
6683 ```xml
6684 <xsd:nonNegativeInteger xsi:type="xsd:nonNegativeInteger">...</xsd:nonNegativeInteger>
6685 ```
6686 </div>
6687
6688 Another possibility is to use strings to represent unbounded integers and do the translation in code.
6689
6690
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:
6694
6695 ```cpp
6696 typedef long long xsd__nonPositiveInteger;
6697 ```
6698
6699 Type `xsd__nonPositiveInteger` declares a 64-bit integer which is encoded as a *`xsd:nonPositiveInteger`*:
6700
6701 <div class="alt">
6702 ```xml
6703 <xsd:nonPositiveInteger xsi:type="xsd:nonPositiveInteger">...</xsd:nonPositiveInteger>
6704 ```
6705 </div>
6706
6707 Another possibility is to use strings to represent unbounded integers and do the translation in code.
6708
6709
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:
6715
6716 ```cpp
6717 typedef char *xsd__normalizedString;
6718 ```
6719
6720 Type `xsd__normalizedString` declares a string type which is encoded as
6721
6722 <div class="alt">
6723 ```xml
6724 <xsd:normalizedString xsi:type="xsd:normalizedString">...</xsd:normalizedString>
6725 ```
6726 </div>
6727
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.
6730
6731
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:
6735
6736 ```cpp
6737 typedef unsigned long long xsd__positiveInteger;
6738 ```
6739
6740 Type `xsd__positiveInteger` declares a 64-bit unsigned integer which is encoded as a *`xsd:positiveInteger`*:
6741
6742 <div class="alt">
6743 ```xml
6744 <xsd:positiveInteger xsi:type="xsd:positiveInteger">...</xsd:positiveInteger>
6745 ```
6746 </div>
6747
6748 Another possibility is to use strings to represent unbounded integers and do the translation in code.
6749
6750
6751 * *`xsd:short`*
6752 Corresponds to a 16-bit integer in the range -32768 to 32767.
6753 The type declaration is:
6754
6755 ```cpp
6756 typedef short xsd__short;
6757 ```
6758
6759 Type `xsd__short` declares a short 16-bit integer which is encoded as
6760
6761 <div class="alt">
6762 ```xml
6763 <xsd:short xsi:type="xsd:short">...</xsd:short>
6764 ```
6765 </div>
6766
6767
6768 * *`xsd:string`*
6769 Represents character strings. The type declaration is:
6770
6771 ```cpp
6772 typedef char *xsd__string;
6773 ```
6774
6775 Type `xsd__string` declares a string type which is encoded as
6776
6777 <div class="alt">
6778 ```xml
6779 <xsd:string xsi:type="xsd:string">...</xsd:string>
6780 ```
6781 </div>
6782
6783 The type declaration for wide character strings is:
6784
6785 ```cpp
6786 typedef wchar_t *xsd__string;
6787 ```
6788
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:
6791
6792 ```cpp
6793 typedef wchar_t *xsd__string_;
6794 ```
6795
6796
6797 * *`xsd:time`*
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:
6801
6802 ```cpp
6803 typedef char *xsd__time;
6804 ```
6805
6806 * *`xsd:token`*
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:
6813
6814 ```cpp
6815 typedef char *xsd__token;
6816 ```
6817
6818 Type `xsd__token` declares a string type which is encoded as
6819
6820 <div class="alt">
6821 ```xml
6822 <xsd:token xsi:type="xsd:token">...</xsd:token>
6823 ```
6824 </div>
6825
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.
6828
6829
6830 * *`xsd:unsignedByte`*
6831 Corresponds to an 8-bit unsigned integer in the range 0 to 255.
6832 The type declaration is:
6833
6834 ```cpp
6835 typedef unsigned char xsd__unsignedByte;
6836 ```
6837
6838 Type `xsd__unsignedByte` declares a unsigned 8-bit integer which is encoded as
6839
6840 <div class="alt">
6841 ```xml
6842 <xsd:unsignedByte xsi:type="xsd:unsignedByte">...</xsd:unsignedByte>
6843 ```
6844 </div>
6845
6846
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:
6850
6851 ```cpp
6852 typedef unsigned int xsd__unsignedInt;
6853 ```
6854
6855 Otherwise, the C++ compiler supports 16-bit `int` types and the type declaration should use the `long` type:
6856
6857 ```cpp
6858 typedef unsigned long xsd__unsignedInt;
6859 ```
6860
6861 Type `xsd__unsignedInt` declares an unsigned 32-bit integer which is encoded as
6862
6863 <div class="alt">
6864 ```xml
6865 <xsd:unsignedInt xsi:type="xsd:unsignedInt">...</xsd:unsignedInt>
6866 ```
6867 </div>
6868
6869
6870 * *`xsd:unsignedLong`*
6871 Corresponds to a 64-bit unsigned integer in the range 0 to 18446744073709551615.
6872 The type declaration is:
6873
6874 ```cpp
6875 typedef unsigned long long xsd__unsignedLong;
6876 ```
6877
6878 Or in Visual C++:
6879
6880 ```cpp
6881 typedef ULONG64 xsd__unsignedLong;
6882 ```
6883
6884 Type `xsd__unsignedLong` declares an unsigned 64-bit integer which is encoded as
6885
6886 <div class="alt">
6887 ```xml
6888 <xsd:unsignedLong xsi:type="xsd:unsignedLong">...</xsd:unsignedLong>
6889 ```
6890 </div>
6891
6892
6893 * *`xsd:unsignedShort`*
6894 Corresponds to a 16-bit unsigned integer in the range 0 to 65535.
6895 The type declaration is:
6896
6897 ```cpp
6898 typedef unsigned short xsd__unsignedShort;
6899 ```
6900
6901 Type `xsd__unsginedShort` declares an unsigned short 16-bit integer which is encoded as
6902
6903 <div class="alt">
6904 ```xml
6905 <xsd:unsignedShort xsi:type="xsd:unsignedShort">...</xsd:unsignedShort>
6906 ```
6907 </div>
6908
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.
6911
6912 ### How to Use Multiple C/C++ Types for a Single Primitive XSD Type
6913
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:
6919
6920 ```cpp
6921 typedef char *xsd__string;
6922 typedef wchar_t *xsd__string_;
6923 ```
6924
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.
6928
6929 ### How to use C++ Wrapper Classes to Specify Polymorphic Primitive Types {#primclass}
6930
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
6937 particular case.
6938
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`
6946 declarations.
6947
6948 The general form of a primitive type declaration that is derived from a super type is:
6949
6950 ```cpp
6951 class xsd__type_name: [optional: public xsd__super_type_name]
6952 { public: Type __item;
6953 [optional: public:] [optional: private] [optional: protected:]
6954 method1;
6955 method2;
6956 ...
6957 };
6958 ```
6959
6960 where Type is a primitive C type. The `__item` field MUST be the first
6961 field in this wrapper class.
6962
6963 For example, the XML Schema type hierarchy can be copied to C++ with the following declarations:
6964
6965 ```cpp
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; };
7018 ```
7019
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:
7023
7024 ```cpp
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; };
7027 ```
7028
7029 See Sections \ref base64binary and \ref hexbinary .
7030
7031 Methods are allowed to be added to the classes above, such as constructors and getter/setter methods, see Section \ref gettersetter .
7032
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 .
7036
7037 ### Multi-Reference Strings
7038
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
7041
7042 ```cpp
7043 char *s = "hello", *t = s;
7044 ```
7045
7046 The `s` and `t` variables are assigned the same string, and when serialized, `t` refers to the content of `s`:
7047
7048 <div class="alt">
7049 ```xml
7050 <string id="123" xsi:type="string">hello</string>
7051 ...
7052 <string href="#123"/>
7053 ```
7054 </div>
7055
7056 The example assumed that `s` and `t` are encoded as independent elements.
7057
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
7061
7062 ```cpp
7063 typedef char *xsd__string;
7064 typedef char *xsd__anyURI;
7065 xsd__anyURI *s = "http://www.myservice.com";
7066 xsd__string *t = s;
7067 ```
7068
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.
7071
7072 ### "Smart String" Mixed-Content Decoding {#smart}
7073
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.
7076
7077 For example, suppose the `getInfo` service operation returns some detailed information. The service operation is declared as:
7078
7079 ```cpp
7080 // Contents of header file "getInfo.h":
7081 getInfo(char *detail);
7082 ```
7083
7084 The proxy of the service is used by a client to request a piece of information and the service responds with:
7085
7086 <div class="alt">
7087 ```xml
7088 HTTP/1.1 200 OK
7089 Content-Type: text/xml
7090 Content-Length: nnn
7091
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"
7096 <SOAP-ENV:Body>
7097 <getInfoResponse>
7098 <detail>
7099 <picture>Mona Lisa by <i>Leonardo da Vinci</i></picture>
7100 </detail>
7101 </getInfoResponse>
7102 </SOAP-ENV:Body>
7103 </SOAP-ENV:Envelope>
7104 ```
7105 </div>
7106
7107 As a result of the mixed content decoding, the `detail` string contains "*`<picture>Mona Lisa by <i>Leonardo da Vinci</i></picture>`*".
7108
7109 ### C++ Strings {#strings}
7110
7111 gSOAP supports C++ strings `std::string` and `std::wstring` wide character strings.
7112 For example:
7113
7114 ```cpp
7115 typedef std::string xsd__string;
7116 class ns__myClass
7117 { public:
7118 xsd__string s; // serialized with xsi:type="xsd:string"
7119 std::string t; // serialized without xsi:type
7120 ...
7121 };
7122 ```
7123
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.
7125
7126 ### Changing the Encoding Precision of float and double Types
7127
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.
7131
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:
7135
7136 ```cpp
7137 struct soap soap;
7138 soap_init(&soap); // sets double_format = "%.18G"
7139 soap.double_format = "%e"; // redefine
7140 ```
7141
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:
7144
7145 ```cpp
7146 struct soap soap;
7147 soap_init(&soap); // sets float_format = "%.9G"
7148 soap.float_format = "%.4f"; // redefine
7149 ```
7150
7151 which causes all floats to be encoded with four digits precision.
7152
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.
7156
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
7160 XML. For example:
7161
7162 ```cpp
7163 typedef float time__ratio "%5.2f";
7164 ```
7165
7166 This will output the float with 5 digits total and 2 digits after the decimal
7167 point.
7168
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:
7172
7173 <div class="alt">
7174 ```xml
7175 <simpleType name="ratio">
7176 <restriction base="xsd:float">
7177 <totalDigits value="5"/>
7178 <fractionDigits value="2"/>
7179 </restriction>
7180 </simpleType>
7181 ```
7182 </div>
7183
7184 ### INF, -INF, and NaN Values of float and double Types
7185
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
7188 representations.
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:
7191
7192 ```cpp
7193 #define FLT_NAN
7194 #define FLT_PINFTY
7195 #define FLT_NINFTY
7196 #define DBL_NAN
7197 #define DBL_PINFTY
7198 #define DBL_NINFTY
7199 ```
7200
7201 ## Enumeration Serialization {#enum}
7202
7203 Enumerations are generally useful for the declaration of named integer-valued constants, also called enumeration constants.
7204
7205 ### Serialization of Symbolic Enumeration Constants
7206
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:
7208
7209 ```cpp
7210 enum weekday {Mon, Tue, Wed, Thu, Fri, Sat, Sun};
7211 ```
7212
7213 The enumeration-constant `Mon`, for example, is encoded as
7214
7215 <div class="alt">
7216 ```xml
7217 <weekday xsi:type="weekday">Mon</weekday>
7218 ```
7219 </div>
7220
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.
7222
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:
7224
7225 ```cpp
7226 enum ns1__weekday {Mon, Tue, Wed, Thu, Fri, Sat, Sun};
7227 ```
7228
7229 The enumeration-constant `Sat`, for example, is encoded as:
7230
7231 <div class="alt">
7232 ```xml
7233 <ns1:weekday xsi:type="ns1:weekday">Sat</ns1:weekday>
7234 ```
7235 </div>
7236
7237 The corresponding XML Schema for this enumeration data type would be:
7238
7239 <div class="alt">
7240 ```xml
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"/>
7251 </xsd:restriction>
7252 </xsd:simpleType>
7253 ```
7254 </div>
7255
7256 ### Encoding of Enumeration Constants
7257
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:
7259
7260 ```cpp
7261 enum ns1__workday {Mon, Tue, Wed, Thu, Fri};
7262 ```
7263
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:
7265
7266 <div class="alt">
7267 ```xml
7268 <ns1:workday xsi:type="ns1:workday">5</ns1:workday>
7269 ```
7270 </div>
7271
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).
7275
7276 Both symbolic and literal enumeration constants can be decoded.
7277
7278 To enforce the literal enumeration constant encoding and to get the literal constants in the WSDL file, use the following trick:
7279
7280 ```cpp
7281 enum ns1__nums { _1 = 1, _2 = 2, _3 = 3 };
7282 ```
7283
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.
7286
7287 ### Initialized Enumeration Constants
7288
7289 The gSOAP `soapcpp2` compiler supports the initialization of enumeration constants, as in:
7290 ```cpp
7291 enum ns1__relation {LESS = -1, EQUAL = 0, GREATER = 1};
7292 ```
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.
7294
7295 ### How to "Reuse" Symbolic Enumeration Constants
7296
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.
7298
7299 Consider for example:
7300
7301 ```cpp
7302 enum ns1__workday {Mon, Tue, Wed, Thu, Fri};
7303 enum ns1__weekday {Mon_, Tue_, Wed_, Thu_, Fri_, Sat_, Sun_};
7304 ```
7305
7306 which will result in the encoding of the constants of `enum ns1__weekday` without the underscore, for example as *`Mon`*.
7307
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:
7309
7310 ```cpp
7311 enum prefixedname { prefixedname__enumconst1, prefixedname__enumconst2, ... };
7312 ```
7313
7314 where the type name of the enumeration `prefixedname` is a prefixed name,
7315 such as:
7316
7317 ```cpp
7318 enum ns1__workday {
7319 ns1__workday__Mon,
7320 ns1__workday__Tue,
7321 ns1__workday__Wed,
7322 ns1__workday__Thu,
7323 ns1__workday__Fri };
7324 enum ns1__weekday {
7325 ns1__workday__Mon,
7326 ns1__workday__Tue,
7327 ns1__workday__Wed,
7328 ns1__workday__Thu,
7329 ns1__workday__Fri,
7330 ns1__workday__Sat,
7331 ns1__workday__Sun
7332 };
7333 ```
7334
7335 This ensures that the XML schema enumeration values are still simply *`Mon`*, *`Tue`*, *`Wed`*, *`Thu`*, *`Fri`*, *`Sat`*, and *`Sun`*.
7336
7337 @warning The following declaration:
7338
7339 ```cpp
7340 enum ns1__workday {Mon, Tue, Wed, Thu, Fri};
7341 enum ns1__weekday {Sat = 5, Sun = 6};
7342 ```
7343
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.
7345
7346 ### Boolean Enumeration Serialization for C {#boolean}
7347
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:
7351
7352 ```cpp
7353 enum xsd__boolean {false_, true_};
7354 ```
7355
7356 The value `false_`, for example, is encoded as:
7357
7358 <div class="alt">
7359 ```xml
7360 <xsd:boolean xsi:type="xsd:boolean">false</xsd:boolean>
7361 ```
7362 </div>
7363
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:
7365
7366 ```cpp
7367 enum SOAP_ENC__boolean {};
7368 ```
7369
7370 The value `0`, for example, is encoded with an integer literal:
7371
7372 <div class="alt">
7373 ```xml
7374 <SOAP-ENC:boolean xsi:type="SOAP-ENC:boolean">0<SOAP-ENC:boolean>
7375 ```
7376 </div>
7377
7378 ### Bitmask Enumeration Serialization
7379
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.
7382
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
7384 asterisk:
7385
7386 ```cpp
7387 enum * *name* { *enum-constant*, *enum-constant*, ... };
7388 ```
7389
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
7392 in SOAP.
7393 For example:
7394
7395 ```cpp
7396 enum * ns__machineStatus { ON, BELT, VALVE, HATCH};
7397 int ns__getMachineStatus(char *name, char *enum ns__machineStatus result);
7398 ```
7399
7400 Note that the use of the `enum` does not require the asterisk, only the definition.
7401 The gSOAP `soapcpp2` compiler generates the enumeration:
7402
7403 ```cpp
7404 enum ns__machineStatus { ON=1, BELT=2, VALVE=4, HATCH=8};
7405 ```
7406
7407 A service operation implementation in a Web service can return:
7408
7409 ```cpp
7410 int ns__getMachineStatus(struct soap *soap, char *name, enum ns__machineStatus result)
7411 { ...
7412 *result = BELT | HATCH;
7413 return SOAP_OK;
7414 }
7415 ```
7416
7417 ## Struct Serialization {#struct}
7418
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.
7427
7428 Certain type of fields of a `struct` can be (de)serialized as XML
7429 attributes using the `@` type qualifier. See Section \ref attributes
7430 for more details.
7431
7432 See Section \ref idtrans for more details on the struct/class member field
7433 serialization and the resulting element and attribute qualified forms.
7434
7435 ## Class Instance Serialization {#class}
7436
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.
7441
7442 The general form of a `class` declaration is:
7443
7444 ```cpp
7445 class [optional: namespace_prefix__]class_name1 [optional: :[optional: public:] [optional: private:] [optional: protected:] [optional: namespace_prefix__]class_name2]
7446 {
7447 [optional: public:] [optional: private:] [optional: protected:]
7448 field1;
7449 field2;
7450 ...
7451 [optional: public:] [optional: private:] [optional: protected:]
7452 method1;
7453 method2;
7454 ...
7455 };
7456 ```
7457
7458 where
7459
7460 * `namespace_prefix__` is the optional namespace prefix of the compound data type (see identifier translation rules \ref idtrans )
7461
7462 * `class_name1` is the element name of the compound data type (see identifier translation rules \ref idtrans ).
7463
7464 * `class_name2` is an optional base class.
7465
7466 * `field` is a field declaration (data member). A field MAY be declared `static` and `const` and MAY be initialized.
7467
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.
7469
7470 * [optional: public:] [optional: private:] [optional: protected:] are OPTIONAL. Only members with `public` acces permission can be serialized.
7471
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
7477 `class`).
7478
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.
7481
7482 If a constructor method is present, there MUST also be a constructor
7483 declaration with empty parameter list.
7484
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.
7486
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.
7490
7491 Certain type of fields of a `struct` can be (de)serialized as XML
7492 attributes using the `@` type qualifier. See Section \ref attributes
7493 for more details.
7494
7495 See Section \ref idtrans for more details on the struct/class member field
7496 serialization and the resulting element and attribute qualified forms.
7497
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".
7501
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
7504 Section \ref void .
7505
7506 A `class` instance is encoded as:
7507
7508 <div class="alt">
7509 ```xml
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>
7513 ...
7514 <field-name1 xsi:type="...">...</field-name1>
7515 <field-name2 xsi:type="...">...</field-name2>
7516 ...
7517 </[optional: namespace-prefix:]class-name>
7518 ```
7519 </div>
7520
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: ].)
7525
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.
7532
7533 ### Example
7534
7535 The following example declares a base class `ns__Object` and a derived class `ns__Shape`:
7536
7537 ```cpp
7538 // Contents of file "shape.h":
7539 class ns__Object
7540 {
7541 public:
7542 char *name;
7543 };
7544 class ns__Shape : public ns__Object
7545 {
7546 public:
7547 int sides;
7548 enum ns__Color {Red, Green, Blue} color;
7549 ns__Shape();
7550 ns__Shape(int sides, enum ns__Green color);
7551 ~ns__Shape();
7552 };
7553 ```
7554
7555 The implementation of the methods of `class ns__Shape` must not be part of the header file and need to be defined elsewhere.
7556
7557 An instance of `class ns__Shape` with name Triangle, 3 sides, and color Green is encoded as:
7558 <div class="alt">
7559
7560 ```xml
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>
7565 </ns:shape>
7566 ```
7567 </div>
7568
7569 The namespace URI of the namespace prefix *`ns`* must be defined by a namespace mapping table, see Section \ref nstable .
7570
7571 ### Initialized static const Fields
7572
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
7576 example:
7577
7578 ```cpp
7579 // Contents of file "triangle.h":
7580 class ns__Triangle : public ns__Object
7581 {
7582 public:
7583 int size;
7584 static const int sides = 3;
7585 };
7586 ```
7587
7588 An instance of `class ns__Triangle` is encoded in SOAP as:
7589
7590 <div class="alt">
7591 ```xml
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>
7596 </ns:Triangle>
7597 ```
7598 </div>
7599
7600 Decoding will ignore the `sides` field's value.
7601
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.
7605
7606 ### Class Methods
7607
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`.
7613
7614 Dynamic binding is supported, so a method MAY be declared `virtual`.
7615
7616 ### Getter and Setter Methods {#gettersetter}
7617
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.
7620
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.
7629
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
7634 the fly.
7635
7636 Getter and setter methods have the following signature:
7637
7638 ```cpp
7639 [optional: virtual] int get(struct soap *soap) [optional: const];
7640 [optional: virtual] int set(struct soap *soap);
7641 ```
7642
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.
7644
7645 Here is an example of a base64 binary class:
7646
7647 ```cpp
7648 class xsd__base64Binary
7649 { public:
7650 unsigned char *__ptr;
7651 int __size;
7652 int get(struct soap *soap);
7653 int set(struct soap *soap);
7654 };
7655 ```
7656
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).
7662
7663 The `get` method is invoked after the base64 data has been processed. You
7664 can use it for post-processing purposes.
7665
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.
7667
7668 ```cpp
7669 class update
7670 { public:
7671 time_t __item;
7672 int set(struct soap *soap);
7673 };
7674 ```
7675
7676 The setter method assigns the current time:
7677
7678 ```cpp
7679 int update::set(struct soap *soap)
7680 {
7681 this->__item = time(NULL);
7682 return SOAP_OK;
7683 }
7684 ```
7685
7686 Therefore, serialization results in the inclusion of a time stamp in XML.
7687
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
7690 *`href`* attribute.
7691
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.
7697
7698 ### Streaming XML with Getter and Setter Methods {#streaming}
7699
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:
7705
7706 ```cpp
7707 class h__Authentication
7708 { public:
7709 char *id;
7710 int get(struct soap *soap);
7711 };
7712 class SOAP_ENV__Header
7713 { public:
7714 h__Authentication *h__authentication;
7715 };
7716 ```
7717
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.
7721
7722 ### Polymorphism, Derived Classes, and Dynamic Binding {#polymorph}
7723
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.
7736
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
7739 instance:
7740
7741 ```cpp
7742 // Contents of file "derived.h"
7743 class Base
7744 {
7745 public:
7746 char *name;
7747 Base();
7748 virtual void print();
7749 };
7750 class Derived : public Base
7751 {
7752 public:
7753 int num;
7754 Derived();
7755 virtual void print();
7756 };
7757 int method(Base *in, struct methodResponse { Base *out; } &result);
7758 ```
7759
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.
7762
7763 The Base and Derived class method implementations are:
7764
7765 ```cpp
7766 // Method implementations of the Base and Derived classes:
7767 #include "soapH.h"
7768 ...
7769 Base::Base()
7770 {
7771 cout << "created a Base class instance" << endl;
7772 }
7773 Derived::Derived()
7774 {
7775 cout << "created a Derived class instance" << endl;
7776 }
7777 Base::print()
7778 {
7779 cout << "print(): Base class instance " << name << endl;
7780 }
7781 Derived::print()
7782 {
7783 cout << "print(): Derived class instance " << name << " " << num << endl;
7784 }
7785 ```
7786
7787 Below is an example `CLIENT` application that creates a Derived class instance that is passed as the input parameter of the service operation:
7788
7789 ```cpp
7790 // CLIENT
7791 #include "soapH.h"
7792 int main()
7793 {
7794 struct soap soap;
7795 soap_init(&soap);
7796 Derived obj1;
7797 Base *obj2;
7798 struct methodResponse r;
7799 obj1.name = "X";
7800 obj1.num = 3;
7801 soap_call_method(&soap, url, action, &obj1, r);
7802 r.obj2->print();
7803 }
7804 ...
7805 ```
7806
7807 The following example `SERVER1` application copies a class instance (Base or Derived class) from the input to the output parameter:
7808
7809 ```cpp
7810 // SERVER1
7811 #include "soapH.h"
7812 int main()
7813 {
7814 soap_serve(soap_new());
7815 }
7816 int method(struct soap *soap, Base *obj1, struct methodResponse &result)
7817 {
7818 obj1->print();
7819 result.obj2 = obj1;
7820 return SOAP_OK;
7821 }
7822 ...
7823 ```
7824
7825 The following messages are produced by the `CLIENT` and `SERVER1` applications:
7826
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
7832
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.
7834
7835 Now suppose a service application is developed that only accepts Base class instances. The header file is:
7836
7837 ```cpp
7838 // Contents of file "base.h":
7839 class Base
7840 {
7841 public:
7842 char *name;
7843 Base();
7844 virtual void print();
7845 };
7846 int method(Base *in, Base *out);
7847 ```
7848
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).
7850
7851 The method implementation of the Base class are:
7852
7853 ```cpp
7854 // Method implementations of the Base class:
7855 #include "soapH.h"
7856 ...
7857 Base::Base()
7858 {
7859 cout << "created a Base class instance" << endl;
7860 }
7861 Base::print()
7862 {
7863 cout << "print(): Base class instance " << name << endl;
7864 }
7865 ```
7866
7867 And the `SERVER2` application is that uses the Base class is:
7868
7869 ```cpp
7870 // SERVER2
7871 #include "soapH.h"
7872 int main()
7873 {
7874 soap_serve(soap_new());
7875 }
7876 int method(struct soap *soap, Base *obj1, struct methodResponse &result)
7877 {
7878 obj1->print();
7879 result.obj2 = obj1;
7880 return SOAP_OK;
7881 }
7882 ...
7883 ```
7884
7885 Here are the messages produced by the `CLIENT` and `SERVER2` applications:
7886
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
7892
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`.
7894
7895 ### XML Attributes {#attributes}
7896
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.
7907
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
7914
7915 ```cpp
7916 typedef char *xsd__string;
7917 typedef bool *xsd__boolean;
7918 enum ns__state { _0, _1, _2 };
7919 struct ns__myStruct
7920 {
7921 @ xsd__string ns__type;
7922 @ xsd__boolean ns__flag = false;
7923 @ enum ns__state ns__state = _2;
7924 struct ns__myStruct *next;
7925 };
7926 ```
7927
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
7932 with *`xsi:type`*).
7933
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.
7938
7939 String attributes are optional. Other type of attributes should be declared as pointers to make them optional:
7940
7941 ```cpp
7942 struct ns__myStruct
7943 {
7944 @ int *a; // omitted when NULL
7945 };
7946 ```
7947
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
7950 example
7951
7952 ```cpp
7953 int ns__myMethod(@ char *ns__name, ...);
7954 ```
7955
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
7958 example
7959
7960 ```cpp
7961 struct xsd__string
7962 {
7963 char *__item;
7964 @ xsd__boolean flag;
7965 };
7966 ```
7967
7968 and
7969
7970 ```cpp
7971 struct xsd__base64Binary
7972 {
7973 unsigned char *__ptr;
7974 int __size;
7975 @ xsd__boolean flag;
7976 };
7977 ```
7978
7979 The attribute declarations MUST follow the `__item`, `__ptr`, and `__size` fields
7980 which define the characteristics of wrapper structs/classes and dynamic arrays.
7981
7982 @warning Do not use XML attributes with SOAP RPC encoding. You can only use attributes with RPC literal encoding.
7983
7984 ### QName Attributes and Elements
7985
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.
7991 For example
7992
7993 ```cpp
7994 typedef char *xsd__QName;
7995 struct ns__myStruct
7996 {
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"
7999 };
8000 ```
8001
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
8014 table or not.
8015
8016 Note: `QName` is a pre-defined typedef type and used by gSOAP to
8017 (de)serialize SOAP Fault codes which are QName elements.
8018
8019 ## Union Serialization {#union}
8020
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
8027 serialize.
8028
8029 A `union` within a `struct` or `class` with a selector field
8030 represents *`xs:choice`* within a Schema complexType component. For example:
8031
8032 ```cpp
8033 struct ns__PO
8034 { ... };
8035 struct ns__Invoice
8036 { ... };
8037 union ns__PO_or_Invoice
8038 {
8039 struct ns__PO po;
8040 struct ns__Invoice invoice;
8041 };
8042 struct ns__composite
8043 {
8044 char *name;
8045 int __union;
8046 union ns__PO_or_Invoice value;
8047 };
8048 ```
8049
8050 The `union ns__PO_or_Invoice` is expanded as a *`xs:choice`*:
8051
8052 <div class="alt">
8053 ```xml
8054 <complexType name="composite">
8055 <sequence>
8056 <element name="name" type="xsd:string"/>
8057 <choice>
8058 <element name="po" type="ns:PO"/>
8059 <element name="invoice" type="ns:Invoice"/>
8060 </choice>
8061 </sequence>
8062 </complexType>
8063 ```
8064 </div>
8065
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).
8070
8071 The `int __union` field selector's values are determined by the
8072 `soapcpp2` compiler. Each `union` field name has a selector value
8073 formed by:
8074
8075 ```cpp
8076 SOAP_UNION_*union-name*_*field-name*
8077 ```
8078
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:
8083
8084 ```cpp
8085 struct ns__composite
8086 {
8087 char *name;
8088 int __union 0; // *`<choice minOccurs="0"{`*>}
8089 union ns__PO_or_Invoice value;
8090 };
8091 ```
8092
8093 This way we can treat the `union` as an optional data item by setting `__union=0`.
8094
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
8097 relevant:
8098
8099 ```cpp
8100 struct ns__composite
8101 {
8102 char *name;
8103 $int select 0; // *`<choice minOccurs="0"{`*>}
8104 union ns__PO_or_Invoice value;
8105 };
8106 ```
8107
8108 The following example shows how the `struct ns__composite` instance is
8109 initialized for serialization using the above declaration:
8110
8111 ```cpp
8112 struct ns__composite data;
8113 data.name = "...";
8114 data.select = SOAP_UNION_ns__PO_or_Invoice_po; // select PO
8115 data.value.po.number = ...; // populate the PO
8116 ```
8117
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
8120 `union` field.
8121
8122 For deserialization of `union` types, the selector will be
8123 set to one of the
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.
8128
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
8131 suffixes as in:
8132
8133 ```cpp
8134 struct ns__composite
8135 {
8136 char *name;
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;
8141 };
8142 ```
8143
8144 ## Serializing Pointer Types {#pointer}
8145
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
8149 type pointed to.
8150
8151 ### Multi-Referenced Data
8152
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:
8161
8162 ```cpp
8163 typedef char *xsd__string;
8164 struct ns__list
8165 {
8166 xsd__string value;
8167 struct ns__list *next;
8168 };
8169 ```
8170
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:
8173
8174 <div class="alt">
8175 ```xml
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>
8180 <next href="#1"/>
8181 </next>
8182 </ns:list>
8183 ```
8184 </div>
8185
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:
8189
8190 ```cpp
8191 typedef long xsd__int;
8192 struct ns__record
8193 {
8194 xsd__int *a;
8195 xsd__int *b;
8196 } P;
8197 struct ns__record
8198 {
8199 xsd__int a;
8200 xsd__int b;
8201 } R;
8202 ...
8203 P.a = &n;
8204 P.b = &n;
8205 ...
8206 ```
8207
8208 Since both `a` and `b` fields of `P` point to the same integer, the encoding of `P` is multi-reference:
8209
8210 <div class="alt">
8211 ```xml
8212 <ns:record xsi:type="ns:record">
8213 <a href="#1"/>
8214 <b href="#1"/>
8215 </ns:record>
8216 <id id="1" xsi:type="xsd:int">123</id>
8217 ```
8218 </div>
8219
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.
8223
8224 ### NULL Pointers and Nil Elements
8225
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).
8228 For example:
8229
8230 ```cpp
8231 struct X
8232 {
8233 int *p;
8234 int **q;
8235 }
8236 ```
8237
8238 Suppose pointer `q` points to pointer `p` and suppose `p=NULL`.
8239 In that case the `p` pointer is serialized as
8240
8241 <div class="alt">
8242 ```xml
8243 <... id="123" xsi:nil="true"/>
8244 ```
8245 </div>
8246
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.
8251
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.
8255
8256 ## Void Pointers {#void}
8257
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*.
8266
8267 Here is an example to illustrate the (de)serialization of a `void*` field in a struct:
8268
8269 ```cpp
8270 struct myStruct
8271 {
8272 int __type; // the SOAP_TYPE pointed to by p
8273 void *p;
8274 };
8275 ```
8276
8277 The `__type` integer can be set to 0 at run time to omit the serialization
8278 of the void pointer field.
8279
8280 The following example illustrates the initialization of `myStruct` with a
8281 void pointer to an int:
8282
8283 ```cpp
8284 struct myStruct S;
8285 int n;
8286 S.p = &n;
8287 S.__type = SOAP_TYPE_int;
8288 ```
8289
8290 The serialized output of `S` contains the integer.
8291
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
8295 the type.
8296
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:
8298
8299 ```cpp
8300 struct myStruct S;
8301 S.p = (void*)"Hello";
8302 S.__type = SOAP_TYPE_string;
8303 ```
8304
8305 This is the case for all string-based types, including types defined with `typedef char*`.
8306
8307 You may use an arbitrary suffix with the `__type` fields to handle
8308 multiple void pointers in structs/classes. For example
8309
8310 ```cpp
8311 struct myStruct
8312 {
8313 int __typeOfp; // the SOAP_TYPE pointed to by p
8314 void *p;
8315 int __typeOfq; // the SOAP_TYPE pointed to by q
8316 void *q;
8317 };
8318 ```
8319
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
8323 example:
8324
8325 ```cpp
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);
8332 ```
8333
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
8343 header file.
8344
8345 ## Fixed-Size Arrays
8346
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.
8351
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.
8353
8354 An example:
8355
8356 ```cpp
8357 // Contents of header file "fixed.h":
8358 struct Example
8359 {
8360 float a[2][3];
8361 };
8362 ```
8363
8364 This specifies a fixed-size array part of the `struct Example`. The encoding of array `a` is:
8365
8366 <div class="alt">
8367 ```xml
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>
8373 </SOAP-ENC:Array>
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>
8378 </SOAP-ENC:Array>
8379 </a>
8380 ```
8381 </div>
8382
8383 @warning Any decoded parts of a (multi-dimensional) array that do not "fit" in the fixed size array are ignored by the deserializer.
8384
8385 ## Dynamic Arrays {#dynarray}
8386
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`.
8400
8401 ### SOAP Array Bounds Limits
8402
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.
8404
8405 ### One-Dimensional Dynamic SOAP Arrays
8406
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.
8410
8411 The general form of the `struct` declaration that contains a one-dimensional dynamic SOAP-encoded array is:
8412
8413 ```cpp
8414 struct some_name
8415 {
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
8420 };
8421 ```
8422
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.
8428
8429 An alternative to a `struct` is to use a `class` with optional methods that MUST appear after the `__ptr` and
8430 `__size` fields:
8431
8432 ```cpp
8433 class some_name
8434 {
8435 public:
8436 Type *__ptr;
8437 int __size;
8438 [optional: [optional: static const] int __offset [optional: = ...];]
8439 method1;
8440 method2;
8441 ... // any fields that follow will be ignored
8442 };
8443 ```
8444
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 .
8448
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.
8452
8453 @warning SOAP 1.2 does not support partially transmitted arrays. So the `__offset` field of a dynamic array is ignored.
8454
8455 ### Example
8456
8457 The following example header file specifies the XMethods Service Listing service `getAllSOAPServices` service operation and an array of `SOAPService` data structures:
8458
8459 ```cpp
8460 // Contents of file "listing.h":
8461 class ns3__SOAPService
8462 {
8463 public:
8464 int ID;
8465 char *name;
8466 char *owner;
8467 char *description;
8468 char *homepageURL;
8469 char *endpoint;
8470 char *SOAPAction;
8471 char *methodNamespaceURI;
8472 char *serviceStatus;
8473 char *methodName;
8474 char *dateCreated;
8475 char *downloadURL;
8476 char *wsdlURL;
8477 char *instructions;
8478 char *contactEmail;
8479 char *serverImplementation;
8480 };
8481 class ServiceArray
8482 {
8483 public:
8484 ns3__SOAPService *__ptr; // points to array elements
8485 int __size; // number of elements pointed to
8486 ServiceArray();
8487 ~ServiceArray();
8488 void print();
8489 };
8490 int ns__getAllSOAPServices(ServiceArray &return_);
8491 ```
8492
8493 An example client application:
8494
8495 ```cpp
8496 #include "soapH.h"
8497 ...
8498 // ServiceArray class method implementations:
8499 ServiceArray::ServiceArray()
8500 {
8501 __ptr = NULL;
8502 __size = 0;
8503 }
8504 ServiceArray::~ServiceArray()
8505 { // destruction handled by gSOAP
8506 }
8507 void ServiceArray::print()
8508 {
8509 for (int i = 0; i < __size; i++)
8510 cout << __ptr[i].name << ": " << __ptr[i].homepage << endl;
8511 }
8512 ...
8513 // Request a service listing and display results:
8514 {
8515 struct soap soap;
8516 ServiceArray result;
8517 const char *endpoint = "www.xmethods.net:80/soap/servlet/rpcrouter";
8518 const char *action = "urn:xmethodsServicesManager#getAllSOAPServices";
8519 ...
8520 soap_init(&soap);
8521 soap_call_ns__getAllSOAPServices(&soap, endpoint, action, result);
8522 result.print();
8523 ...
8524 soap_destroy(&soap); // dealloc class instances
8525 soap_end(&soap); // dealloc deserialized data
8526 soap_done(&soap); // cleanup and detach soap struct
8527 }
8528 ```
8529
8530 ### One-Dimensional Dynamic SOAP Arrays With Non-Zero Offset
8531
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
8537 in SOAP 1.2.
8538
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
8541 starts at 1:
8542
8543 ```cpp
8544 // Contents of file "vector.h":
8545 typedef float xsd__float;
8546 class Vector
8547 {
8548 xsd__float *__ptr;
8549 int __size;
8550 int __offset;
8551 Vector();
8552 Vector(int n);
8553 float& \operator[](int i);
8554 }
8555 ```
8556
8557 The implementations of the `Vector` methods are:
8558
8559 ```cpp
8560 Vector::Vector()
8561 {
8562 __ptr = NULL;
8563 __size = 0;
8564 __offset = 1;
8565 }
8566 Vector::Vector(int n)
8567 {
8568 __ptr = (float*)malloc(n*sizeof(float));
8569 __size = n;
8570 __offset = 1;
8571 }
8572 Vector::~Vector()
8573 {
8574 if (__ptr)
8575 free(__ptr);
8576 }
8577 float& Vector::\operator[](int i)
8578 {
8579 return __ptr[i-__offset];
8580 }
8581 ```
8582
8583 An example program fragment that serializes a vector of 3 elements:
8584
8585 ```cpp
8586 struct soap soap;
8587 soap_init(&soap);
8588 Vector v(3);
8589 v[1] = 1.0;
8590 v[2] = 2.0;
8591 v[3] = 3.0;
8592 soap_begin(&soap);
8593 v.serialize(&soap);
8594 v.put("vec");
8595 soap_end(&soap);
8596 ```
8597
8598 The output is a partially transmitted array:
8599
8600 <div class="alt">
8601 ```xml
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>
8606 </vec>
8607 ```
8608 </div>
8609
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.
8611
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.
8613
8614 ### Nested One-Dimensional Dynamic SOAP Arrays {#nested}
8615
8616 One-dimensional dynamic arrays MAY be nested.
8617 For example, using `class Vector` declared in the previous section, `class Matrix` is declared:
8618
8619 ```cpp
8620 // Contents of file "matrix.h":
8621 class Matrix
8622 {
8623 public:
8624 Vector *__ptr;
8625 int __size;
8626 int __offset;
8627 Matrix();
8628 Matrix(int n, int m);
8629 ~Matrix();
8630 Vector& \operator[](int i);
8631 };
8632 ```
8633
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.
8636
8637 ### Multi-Dimensional Dynamic SOAP Arrays
8638
8639 The general form of the `struct` declaration for K-dimensional (K>1) dynamic arrays is:
8640
8641 ```cpp
8642 struct some_name
8643 {
8644 Type *__ptr;
8645 int __size[K];
8646 int __offset[K];
8647 ... // anything that follows here will be ignored
8648 };
8649 ```
8650
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 ).
8653
8654 An alternative is to use a `class` with optional methods:
8655
8656 ```cpp
8657 class some_name
8658 {
8659 public:
8660 Type *__ptr;
8661 int __size[K];
8662 int __offset[K];
8663 method1;
8664 method2;
8665 ... // any fields that follow will be ignored
8666 };
8667 ```
8668
8669 In the above, K is a constant denoting the number of dimensions of the multi-dimensional array.
8670
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 .
8673
8674 The deserializer of a dynamic array can decode partially transmitted multi-dimensional arrays.
8675
8676 For example, the following declaration specifies a matrix class:
8677
8678 ```cpp
8679 typedef double xsd__double;
8680 class Matrix
8681 {
8682 public:
8683 xsd__double *__ptr;
8684 int __size[2];
8685 int __offset[2];
8686 };
8687 ```
8688
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.
8692
8693 ### Encoding XML Generics Containing Dynamic Arrays {#list}
8694
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.
8696
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.
8700
8701 For example, we define a Map structure that contains a sequence of pairs of key-val:
8702
8703 ```cpp
8704 struct ns__Map
8705 {
8706 int __size; // number of pairs
8707 struct ns__Binding {char *key; char *val;} *pair;
8708 };
8709 ```
8710
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:
8714
8715 ```cpp
8716 struct ns__Map
8717 {
8718 $int length; // number of pairs
8719 struct ns__Binding {char *key; char *val;} *pair;
8720 };
8721 ```
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:
8723
8724 <div class="alt">
8725 ```xml
8726 <ns:Map xsi:type="ns:Map">
8727 <pair xsi:type="ns:Binding">
8728 <key>Joe</key>
8729 <val>555 77 1234</val>
8730 </pair>
8731 <pair xsi:type="ns:Binding">
8732 <key>Susan</key>
8733 <val>555 12 6725</val>
8734 </pair>
8735 <pair xsi:type="ns:Binding">
8736 <key>Pete</key>
8737 <val>555 99 4321</val>
8738 </pair>
8739 </ns:Map>
8740 ```
8741 </div>
8742
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
8747 dynamic array.
8748
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.
8759
8760 The general convention for embedding arrays is:
8761
8762 ```cpp
8763 struct ns__SomeStruct
8764 {
8765 ...
8766 int __sizename1; // number of elements pointed to
8767 Type1 *field1; // by this field
8768 ...
8769 int __sizename2; // number of elements pointed to
8770 Type2 *field2; // by this field
8771 ...
8772 };
8773 ```
8774
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.
8776
8777 In 2.7.16 and higher this is simplified with a '`$`' marker:
8778
8779 ```cpp
8780 struct ns__SomeStruct
8781 {
8782 ...
8783 $int name1; // number of elements pointed to
8784 Type1 *field1; // by this field
8785 ...
8786 $int name2; // number of elements pointed to
8787 Type2 *field2; // by this field
8788 ...
8789 };
8790 ```
8791
8792 For example, the following struct has two embedded arrays:
8793
8794 ```cpp
8795 struct ns__Contact
8796 {
8797 char *firstName;
8798 char *lastName;
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
8803 char *socSecNumber;
8804 };
8805 ```
8806
8807 The XML serialization of an example `ns__Contact` is:
8808
8809 <div class="alt">
8810 ```xml
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>
8820 </mycontact>
8821 ```
8822 </div>
8823
8824 ### STL Containers {#templates}
8825
8826 gSOAP supports the STL containers `std::deque`, `std::list`,
8827 `std::set`, and `std::vector`.
8828
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.
8833
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.
8837 Here is an example:
8838
8839 ```cpp
8840 #import "stlvector.h"
8841 class ns__myClass
8842 { public:
8843 std::vector<int> *number;
8844 std::vector<xsd__string> *name;
8845 ...
8846 };
8847 ```
8848
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.)
8856
8857 The XML Schema that corresponds to the `ns__myClass` type is
8858
8859 <div class="alt">
8860 ```xml
8861 <complexType name="myClass">
8862 <sequence>
8863 <element name="number" type="xsd:int" minOccurs="1" maxOccurs="unbounded"/>
8864 <element name="name" type="xsd:string" minOccurs="1" maxOccurs="unbounded"/>
8865 ...
8866 </sequence>
8867 </complexType>
8868 ```
8869 </div>
8870
8871 You can specify the minOccurs and maxOccurs values as explained in Section \ref directives .
8872
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:
8875
8876
8877 * `void clear()` empty the container;
8878
8879 * `iterator begin()` return iterator to beginning;
8880
8881 * `const_iterator begin() const` return const iterator to beginning;
8882
8883 * `iterator end()` return iterator to end;
8884
8885 * `const_iterator end() const` return const iterator to end;
8886
8887 * `size_t size()` return size;
8888
8889 * `iterator insert(iterator pos, const_reference val)` insert element.
8890
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)`.
8894
8895 Here is in example user-defined container template class:
8896
8897 ```cpp
8898 // simple_vector.h
8899 template <class T>
8900 class simple_vector
8901 {
8902 public:
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;
8910 protected:
8911 iterator head;
8912 iterator tail;
8913 size_t capacity;
8914 public:
8915 simple_vector() { head = tail = NULL; }
8916 simple_vector(const simple_vector& v)
8917 { operator=(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)
8927 {
8928 if (!head)
8929 head = tail = new value_type[capacity = 1];
8930 else if (tail >= head + capacity)
8931 {
8932 iterator i = head;
8933 iterator j = new value_type[capacity *= 2];
8934 iterator k = j;
8935 while (i < tail)
8936 *k++ = *i++;
8937 if (pos)
8938 pos = j + (pos - head);
8939 tail = j + (tail - head);
8940 delete[] head;
8941 head = j;
8942 }
8943 if (pos && pos >= head && pos < tail)
8944 {
8945 iterator i = tail;
8946 iterator j = i - 1;
8947 while (j != pos)
8948 *i-- = *j--;
8949 *pos = val;
8950 }
8951 else
8952 {
8953 pos = tail;
8954 *tail++ = val;
8955 }
8956 return pos;
8957 }
8958 simple_vector& \operator=(const simple_vector& v)
8959 {
8960 head = tail = NULL;
8961 capacity = v.capacity;
8962 if (v.head)
8963 {
8964 head = tail = new value_type[capacity];
8965 iterator i = v.head;
8966 while (i != v.tail)
8967 *tail++ = *i++;
8968 }
8969 return *\this;
8970 }
8971 };
8972 ```
8973
8974 To enable the container, we add the following two lines to our gSOAP header file:
8975
8976 ```cpp
8977 #include "simpleVector.h"
8978 template <class T> class simpleVector;
8979 ```
8980
8981 The container class
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.
8984
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.
8993
8994 ### Polymorphic Dynamic Arrays and Lists
8995
8996 Polymorphic arrays (arrays of polymorphic element types) can be encoded when
8997 declared as an array of pointers to class instances. For example:
8998
8999 ```cpp
9000 class ns__Object
9001 {
9002 public:
9003 ...
9004 };
9005 class ns__Data: public ns__Object
9006 {
9007 public:
9008 ...
9009 };
9010 class ArrayOfObject
9011 {
9012 public:
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
9016 };
9017 class ns__Objects
9018 {
9019 public:
9020 std::vector<ns__Object*> objects; // vector of pointers to objects
9021 };
9022 ```
9023
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.
9027
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 .
9030
9031 ```cpp
9032 struct __wrapper
9033 {
9034 int __type; // type T represented by SOAP_TYPE_T
9035 void *__item; // pointer to data of type T
9036 };
9037 struct ArrayOfObject
9038 {
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
9042 };
9043 struct ns__Objects
9044 {
9045 int __size;
9046 struct __wrapper *objects; // array of pointers to wrapped types
9047 };
9048 ```
9049
9050 ### How to Change the Tag Names of the Elements of a SOAP Array or List
9051
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:
9055
9056 ```cpp
9057 Type *__ptrarray_elt_name
9058 ```
9059
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`).
9063
9064 Consider for example:
9065
9066 ```cpp
9067 struct ArrayOfstring
9068 {
9069 xsd__string *__ptrstring;
9070 int __size;
9071 };
9072 ```
9073
9074 The array is serialized as:
9075
9076 <div class="alt">
9077 ```xml
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>
9081 </array>
9082 ```
9083 </div>
9084
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.
9087
9088 ## Base64Binary XML Schema Type Encoding {#base64binary}
9089
9090 The *`base64Binary`* XML Schema type is a special form of dynamic array declared with a pointer (`__ptr`) to an
9091 `unsigned char` array.
9092
9093 For example using a `struct`:
9094
9095 ```cpp
9096 struct xsd__base64Binary
9097 {
9098 unsigned char *__ptr;
9099 int __size;
9100 };
9101 ```
9102
9103 Or with a `class`:
9104
9105 ```cpp
9106 class xsd__base64Binary
9107 {
9108 public:
9109 unsigned char *__ptr;
9110 int __size;
9111 };
9112 ```
9113
9114 When compiled by the gSOAP `soapcpp2` tool, this header file specification will generate *`base64Binary`* serializers and deserializers.
9115
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:
9119
9120 ```cpp
9121 struct SOAP_ENC__base64
9122 {
9123 unsigned char *__ptr;
9124 int __size;
9125 };
9126 ```
9127
9128 Or with a `class`:
9129
9130 ```cpp
9131 class SOAP_ENC__base64
9132 {
9133 unsigned char *__ptr;
9134 int __size;
9135 };
9136 ```
9137
9138 When compiled by the gSOAP `soapcpp2` tool, this header file specification will generate *`SOAP-ENC:base64`* serializers and deserializers.
9139
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:
9141
9142 ```cpp
9143 class xsd__base64Binary
9144 {
9145 public:
9146 unsigned char *__ptr;
9147 int __size;
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
9153 };
9154 ```
9155
9156 Here are example method implementations:
9157
9158 ```cpp
9159 xsd__base64Binary::xsd__base64Binary()
9160 {
9161 __ptr = NULL;
9162 __size = 0;
9163 }
9164 xsd__base64Binary::xsd__base64Binary(struct soap *soap, int n)
9165 {
9166 __ptr = (unsigned char*)soap_malloc(soap, n);
9167 __size = n;
9168 }
9169 xsd__base64Binary::~xsd__base64Binary()
9170 { }
9171 unsigned char *xsd__base64Binary::location()
9172 {
9173 return __ptr;
9174 }
9175 int xsd__base64Binary::size()
9176 {
9177 return __size;
9178 }
9179 ```
9180
9181 The following example in C/C++ reads from a raw image file and encodes the image in SOAP using the *`base64Binary`* type:
9182
9183 ```cpp
9184 ...
9185 FILE *fd = fopen("image.jpg", "rb");
9186 xsd__base64Binary image(&soap, filesize(fd));
9187 fread(image.location(), image.size(), 1, fd);
9188 fclose(fd);
9189 soap_begin_send(&soap);
9190 image.soap_serialize(&soap);
9191 image.soap_put(&soap, "jpegimage", NULL);
9192 soap_end_send(&soap);
9193 ...
9194 ```
9195
9196 where `filesize` is a function that returns the size of a file given a file descriptor.
9197
9198 Reading the *`xsd:base64Binary`* encoded image.
9199
9200 ```cpp
9201 ...
9202 xsd__base64Binary image;
9203 soap_begin_recv(&soap);
9204 image.get(&soap, "jpegimage");
9205 soap_end_recv(&soap);
9206 ...
9207 ```
9208
9209 The `struct` or `class` name `soap_enc__base64` should be used for *`SOAP-ENC:base64`* schema type instead of
9210 `xsd__base64Binary`.
9211
9212 ## hexBinary XML Schema Type Encoding {#hexbinary}
9213
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.
9215
9216 For example, using a `struct`:
9217
9218 ```cpp
9219 struct xsd__hexBinary
9220 {
9221 unsigned char *__ptr;
9222 int __size;
9223 };
9224 ```
9225
9226 Or using a `class`:
9227
9228 ```cpp
9229 class xsd__hexBinary
9230 {
9231 public:
9232 unsigned char *__ptr;
9233 int __size;
9234 };
9235 ```
9236
9237 or if a binary type such as `xsd__base64Binary` is defined, then we can simply use a `typedef` to introduce the hex variant:
9238
9239 ```cpp
9240 class xsd__base64Binary // serializes into base64 content
9241 {
9242 public:
9243 unsigned char *__ptr;
9244 int __size;
9245 };
9246 typedef xsd__base64Binary xsd__hexBinary; // serializes into hex content
9247 ```
9248
9249 When compiled by the gSOAP `soapcpp2` tool, this header file specification will generate *`hexBinary`* serializers and deserializers.
9250
9251 ## Literal XML Encoding Style {#literal}
9252
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.
9257
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:
9259
9260 ```cpp
9261 //gsoap ns service encoding: encoded
9262 ```
9263
9264 To enable encoding for particular service methods, use:
9265
9266 ```cpp
9267 //gsoap ns service method-encoding: myMethod encoded
9268 int ns__myMethod(...)
9269 ```
9270
9271 To enable encoding for particular service methods responses when the method request is literal, use:
9272
9273 ```cpp
9274 //gsoap ns service method-response-encoding: myMethod encoded
9275 int ns__myMethod(...)
9276 ```
9277
9278 Instead of the `encoded` value, you can use `literal`, or a specific encoding style value.
9279
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:
9284
9285 ```cpp
9286 int LocalTimeByZipCode(char *ZipCode, char **LocalTimeByZipCodeResult);
9287 ```
9288
9289 Note that none of the data types need to be namespace qualified using
9290 namespace prefixes.
9291
9292 ```cpp
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);
9297 ```
9298
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.
9302
9303 The example client program is:
9304
9305 ```cpp
9306 #include "soapH.h"
9307 #include "localtime.nsmap" // include generated map file
9308 int main()
9309 {
9310 struct soap soap;
9311 char *t;
9312 soap_init(&soap);
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);
9315 else
9316 printf("Time = %s\n", t);
9317 return 0;
9318 }
9319 ```
9320
9321 To illustrate the manual doc/literal setting, the following client program sets
9322 the required properties before the call:
9323
9324 ```cpp
9325 #include "soapH.h"
9326 #include "localtime.nsmap" // include generated map file
9327 int main()
9328 {
9329 struct soap soap;
9330 char *t;
9331 soap_init(&soap);
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);
9336 else
9337 printf("Time = %s\n", t);
9338 return 0;
9339 }
9340 ```
9341
9342 The SOAP request is:
9343
9344 <div class="alt">
9345 ```xml
9346 POST /webservices/LocalTime.asmx HTTP/1.0
9347 Host: alethea.net
9348 Content-Type: text/xml; charset=utf-8
9349 Content-Length: 479
9350 SOAPAction: "http://alethea.net/webservices/LocalTimeByZipCode"
9351
9352 <?xml version="1.0" encoding="UTF-8"?>
9353 <SOAP-ENV:Envelope
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"
9358 <SOAP-ENV:Body>
9359 <LocalTimeByZipCode xmlns="http://alethea.net/webservices/">
9360 <ZipCode>32306</ZipCode></LocalTimeByZipCode>
9361 </SOAP-ENV:Body>
9362 </SOAP-ENV:Envelope>
9363 ```
9364 </div>
9365
9366 ### Serializing and Deserializing Mixed Content XML With Strings {#literal2}
9367
9368 To declare a literal XML "type" to hold XML documents in regular strings, use:
9369
9370 ```cpp
9371 typedef char *XML;
9372 ```
9373
9374 To declare a literal XML "type" to hold XML documents in wide character strings, use:
9375
9376 ```cpp
9377 typedef wchar_t *XML;
9378 ```
9379
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:
9382
9383
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.
9386
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.
9389
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:
9392
9393 ```cpp
9394 typedef char *XML;
9395 ns__GetDocument(XML m__XMLDoc, XML &m__XMLDoc_);
9396 ```
9397
9398 and in C:
9399
9400 ```cpp
9401 typedef char *XML;
9402 ns__GetDocument(XML m__XMLDoc, XML *m__XMLDoc_);
9403 ```
9404
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
9407 `struct`s.
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:
9410
9411 <div class="alt">
9412 ```xml
9413 <?xml version="1.0" encoding="UTF-8"?>
9414 <SOAP-ENV:Envelope
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="">
9422 <SOAP-ENV:Body>
9423 <ns:GetDocument>
9424 <XMLDoc xmlns="http://my.org/mydoc.xsd">
9425 ...
9426 </XMLDoc>
9427 </ns:Document>
9428 </SOAP-ENV:Body>
9429 </SOAP-ENV:Envelope>
9430 ```
9431 </div>
9432
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:
9435
9436 ```cpp
9437 struct soap soap;
9438 soap_init(&soap);
9439 soap.encodingStyle = NULL;
9440 ```
9441
9442 As a result, the *`SOAP-ENV:encodingStyle`* attribute will not appear in the SOAP payload.
9443
9444 For interoperability with Apache SOAP, use
9445
9446 ```cpp
9447 struct soap soap;
9448 soap_init(&soap);
9449 soap.encodingStyle = "http://xml.apache.org/xml-soap/literalxml";
9450 ```
9451
9452 When the response parameter is an XML type, it will store the entire XML response content but without the enveloping response element.
9453
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:
9455
9456 ```cpp
9457 typedef char *XML;
9458 struct ns__Data /* data in namespace 'ns' */
9459 {
9460 int number;
9461 char *name;
9462 XML m__document; /* XML document in default namespace 'm' */
9463 };
9464 ns__Example(struct ns__Data data, struct ns__ExampleResponse { struct ns__Data data; } *out);
9465 ```
9466
9467 # SOAP Fault Processing {#fault}
9468
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:
9471
9472 ```cpp
9473 struct SOAP_ENV__Fault
9474 {
9475 _QName faultcode; // _QName is builtin
9476 char *faultstring;
9477 char *faultactor;
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
9484 };
9485 struct SOAP_ENV__Code
9486 {
9487 _QName SOAP_ENV__Value;
9488 struct SOAP_ENV__Code *SOAP_ENV__Subcode;
9489 };
9490 struct SOAP_ENV__Detail
9491 {
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)
9495 };
9496 ```
9497
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.
9500
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`.
9502
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.
9504
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).
9507
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:
9509
9510 ```cpp
9511 int ns1__myMethod(struct soap *soap, ...)
9512 {
9513 ...
9514 return soap_receiver_fault(soap, "Resource temporarily unavailable", NULL); // return fault to sender
9515 }
9516 ```
9517
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:
9519
9520 ```cpp
9521 return soap_receiver_fault(soap, "Resource temporarily unavailable", "<errorcode xmlns='http://tempuri.org'>123</errorcode><errorinfo xmlns='http://tempuri.org'>abc</errorinfo>");
9522 ```
9523
9524
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`.
9528 For example:
9529
9530 ```cpp
9531 soap_receiver_fault(soap, "Stack dump", NULL);
9532 if (soap->version == 2) // SOAP 1.2 is used
9533 {
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
9538 }
9539 else
9540 {
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
9545 }
9546 return SOAP_FAULT; // return from service operation call
9547 ```
9548
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.
9554
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:
9559
9560 ```cpp
9561 int main()
9562 {
9563 struct soap soap;
9564 soap_init(&soap);
9565 some initialization code
9566 if (initialization failed)
9567 {
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
9571 }
9572 }
9573 ```
9574
9575 # SOAP Header Processing {#header}
9576
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:
9580
9581 ```cpp
9582 struct SOAP_ENV__Header { };
9583 ```
9584
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).
9586
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`.
9590
9591 For example, the following header can be used for transaction control:
9592
9593 ```cpp
9594 struct SOAP_ENV__Header
9595 { char *t__transaction;
9596 };
9597 ```
9598
9599 with client-side code:
9600
9601 ```cpp
9602 struct soap soap;
9603 soap_init(&soap);
9604 ...
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
9612 ...
9613 ```
9614
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:
9616
9617 <div class="alt">
9618 ```xml
9619 ...
9620 <SOAP-ENV:Envelope ...>
9621 <SOAP-ENV:Header>
9622 <transaction xmlns="..." xsi:type="int">12345</transaction>
9623 </SOAP-ENV:Header>
9624 <SOAP-ENV:Body>
9625 ...
9626 </SOAP-ENV:Body>
9627 </SOAP-ENV:Envelope>
9628 ```
9629 </div>
9630
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).
9635
9636 A Web service can read and set the SOAP Header as follows:
9637
9638 ```cpp
9639 int main()
9640 {
9641 struct soap soap;
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
9644 soap_serve(&soap);
9645 }
9646 ...
9647 int method(struct soap *soap, ...)
9648 {
9649 if (soap->header) // a Header was received
9650 ... = soap->header->t__transaction;
9651 else
9652 soap->header = soap_malloc(sizeof(struct SOAP_ENV__Header)); // alloc new header
9653 ...
9654 soap->header->t__transaction = ...;
9655 return SOAP_OK;
9656 }
9657 ```
9658
9659 See Section \ref directives on how to generate WSDL with the proper method-to-header-part bindings.
9660
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.
9667
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:
9671
9672 ```cpp
9673 struct SOAP_ENV__Header
9674 {
9675 char *t__transaction;
9676 mustUnderstand char *t__authentication;
9677 };
9678 ```
9679
9680 When both fields are set and `soap.actor="http://some/actor"` then the message contains:
9681
9682 <div class="alt">
9683 ```xml
9684 <SOAP-ENV:Envelope ...>
9685 <SOAP-ENV:Header>
9686 <transaction xmlns="...">5</transaction>
9687 <authentication xmlns="..."
9688 SOAP-ENV:actor="http://some/actor" SOAP-ENV:mustUnderstand="1">XX
9689 </authentication>
9690 </SOAP-ENV:Header>
9691 <SOAP-ENV:Body>
9692 ...
9693 </SOAP-ENV:Body>
9694 </SOAP-ENV:Envelope>
9695 ```
9696 </div>
9697
9698 # MIME Attachments {#MIME}
9699
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 .
9707
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.
9713
9714 ## Sending a Collection of MIME Attachments (SwA)
9715
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.
9718
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`*>.
9728
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.
9747
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.
9750
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.
9754
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
9758 unaffected).
9759
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.
9766
9767 ```cpp
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
9782 else
9783 // process response
9784 ```
9785
9786 Note: the above example assumes that the boundary `MIME_boundary` does not match any part of the SOAP/XML message.
9787
9788 The `claim__form` struct is declared in the gSOAP header file as:
9789
9790 ```cpp
9791 struct claim__form
9792 {
9793 @ char *href;
9794 };
9795 ```
9796
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.
9803
9804 To associate MIME attachments with the request and response of a service operation in the generated WSDL, please see Section \ref MIMEWSDL .
9805
9806 The server-side code to transmit MIME attachments back to a client is similar:
9807
9808 ```cpp
9809 int claim__insurance_claim_auto(struct soap *soap, ...)
9810 {
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))
9815 {
9816 soap_clr_mime(soap); // don't want fault with attachments
9817 return soap->error;
9818 }
9819 return SOAP_OK;
9820 }
9821 ```
9822
9823 It is also possible to attach data to a SOAP fault message.
9824
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
9829 MIME.
9830
9831 ## Retrieving a Collection of MIME Attachments (SwA)
9832
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
9839 any useful data).
9840
9841 To traverse the list of MIME attachments in C, you use a loop similar to:
9842
9843 ```cpp
9844 struct soap_multipart *attachment;
9845 for (attachment = soap.mime.list; attachment; attachment = attachment->next)
9846 {
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");
9855 }
9856 ```
9857
9858 C++ programmers can use an iterator instead, as in:
9859
9860 ```cpp
9861 for (soap_multipart::iterator attachment = soap.mime.begin(); attachment != soap.mime.end(); ++attachment)
9862 {
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;
9871 }
9872 ```
9873
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.
9877
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.
9882
9883 # DIME Attachments {#DIME}
9884
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
9887
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).
9896
9897 ## Sending a Collection of DIME Attachments
9898
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.
9904
9905 * `void soap_set_dime(struct soap *soap)`
9906 This function must be called first to initialize DIME attachment send operations (receives are automatic).
9907
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.
9911
9912 * `void soap_clr_dime(struct soap *soap)`
9913 Disables DIME attachments, unless the serialized SOAP message contains attachments for transmission.
9914
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 .
9921
9922 ## Retrieving a Collection of DIME Attachments
9923
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.
9928
9929 To traverse the list of DIME attachments in C, you use a loop similar to:
9930
9931 ```cpp
9932 struct soap_multipart *attachment;
9933 for (attachment = soap.dime.list; attachment; attachment = attachment->next)
9934 {
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");
9940 }
9941 ```
9942
9943 C++ programmers can use an iterator instead, as in:
9944
9945 ```cpp
9946 for (soap_multipart::iterator attachment = soap.dime.begin(); attachment != soap.dime.end(); ++attachment)
9947 {
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;
9953 }
9954 ```
9955
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.
9960
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.
9965
9966 ## Serializing Binary Data in DIME {#DIMEbinary}
9967
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.
9977
9978 The *`xsd:base64Binary`* XSD type is defined in gSOAP as a struct or class by
9979
9980 ```cpp
9981 struct xsd__base64Binary
9982 {
9983 unsigned char *__ptr; // pointer to raw binary data
9984 int __size; // size of the block of data
9985 };
9986 ```
9987
9988 To enable serialization of the data in DIME, we extend this type with three
9989 additional fields:
9990
9991 ```cpp
9992 struct xsd__base64Binary
9993 {
9994 unsigned char *__ptr;
9995 int __size;
9996 char *id;
9997 char *type;
9998 char *options;
9999 };
10000 ```
10001
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.
10010
10011 The `id` and `type` fields contain text. The set the DIME-specific
10012 options field, you can use the `soap_dime_option` function:
10013
10014 ```cpp
10015 char *soap_dime_option(struct soap *soap, unsigned short type, const char *option)
10016 ```
10017
10018 returns a string with this encoding. For example
10019
10020 ```cpp
10021 struct xsd__base64Binary image;
10022 image.__ptr = ...;
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");
10027 ```
10028
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
10035
10036 ```cpp
10037 struct ns__myBinaryDataType
10038 {
10039 unsigned char *__ptr;
10040 int __size;
10041 char *id;
10042 char *type;
10043 char *options;
10044 };
10045 ```
10046
10047 C++ programmers can use inheritance instead of textual extension required in C, as in
10048
10049 ```cpp
10050 class xsd__base64Binary
10051 {
10052 unsigned char *__ptr;
10053 int __size;
10054 };
10055 class ns__myBinaryDataType : xsd__base64Binary
10056 {
10057 char *id;
10058 char *type;
10059 char *options;
10060 };
10061 ```
10062
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:
10066
10067 ```cpp
10068 //gsoap WSref schema import: http://schemas.xmlsoap.org/ws/2002/04/reference/
10069 struct ns__myBinaryDataType
10070 {
10071 unsigned char *__ptr;
10072 int __size;
10073 char *id;
10074 char *type;
10075 char *options;
10076 @ char *WSref__location;
10077 };
10078 ```
10079
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).
10081
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.
10087
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.
10091
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,
10097
10098 ```cpp
10099 struct soap soap;
10100 soap_init(&soap);
10101 soap.dime_id_format = "uuid:09233523-345b-4351-b623-5dsf35sgs5d6-%x";
10102 ```
10103
10104 As a result, all attachments with a NULL `id` field will use a
10105 gSOAP-generated id value based on the format string.
10106
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.
10110
10111 ## Streaming DIME {#DIMEstreaming}
10112
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.
10116
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.
10132
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.
10147
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.
10153
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.
10165
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).
10172
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.
10178
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.
10183
10184 The following example illustrates the client-side initialization of an image
10185 attachment struct to stream a file into a DIME attachment:
10186
10187 ```cpp
10188 int main()
10189 {
10190 struct soap soap;
10191 struct xsd__base64Binary image;
10192 FILE *fd;
10193 struct stat sb;
10194 soap_init(&soap);
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
10202 }
10203 else
10204 { // don't know the size, so buffer it
10205 size_t i;
10206 int c;
10207 image.__ptr = (unsigned char*)soap_malloc(&soap, MAX_FILE_SIZE);
10208 for (i = 0; i < MAX_FILE_SIZE; i++)
10209 {
10210 if ((c = fgetc(fd)) == EOF)
10211 break;
10212 image.__ptr[i] = c;
10213 }
10214 fclose(fd);
10215 image.__size = i;
10216 }
10217 image.type = "image/jpeg";
10218 image.options = soap_dime_option(&soap, 0, "My picture");
10219 soap_call_ns__method(&soap, ...);
10220 ...
10221 }
10222 void *dime_read_open(struct soap *soap, void *handle, const char *id, const char *type, const char *options)
10223 {
10224 return handle;
10225 }
10226 void dime_read_close(struct soap *soap, void *handle)
10227 { fclose((FILE*)handle);
10228 }
10229 size_t dime_read(struct soap *soap, void *handle, char *buf, size_t len)
10230 { return fread(buf, 1, len, (FILE*)handle);
10231 }
10232 ```
10233
10234 The following example illustrates the streaming of a DIME attachment into a file by a client:
10235
10236 ```cpp
10237 int main()
10238 { struct soap soap;
10239 soap_init(&soap);
10240 soap.fdimewriteopen = dime_write_open;
10241 soap.fdimewriteclose = dime_write_close;
10242 soap.fdimewrite = dime_write;
10243 soap_call_ns__method(&soap, ...);
10244 ...
10245 }
10246 void *dime_write_open(struct soap *soap, const char *id, const char *type, const char *options)
10247 {
10248 FILE *handle = fopen("somefile", "wb");
10249 if (!handle)
10250 {
10251 soap->error = SOAP_EOF;
10252 soap->errnum = errno; // get reason
10253 }
10254 return (void*)handle;
10255 }
10256 void dime_write_close(struct soap *soap, void *handle)
10257 { fclose((FILE*)handle);
10258 }
10259 int dime_write(struct soap *soap, void *handle, const char *buf, size_t len)
10260 {
10261 size_t nwritten;
10262 while (len)
10263 {
10264 nwritten = fwrite(buf, 1, len, (FILE*)handle);
10265 if (!nwritten)
10266 {
10267 soap->errnum = errno; // get reason
10268 return SOAP_EOF;
10269 }
10270 len -= nwritten;
10271 buf += nwritten;
10272 }
10273 return SOAP_OK;
10274 }
10275 ```
10276
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 .
10287
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.
10292
10293 ## Streaming Chunked DIME {#dimechunking}
10294
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.
10306
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.
10313
10314 ## WSDL Bindings for DIME Attachments
10315
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.
10322
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
10325 and MTOM.
10326
10327 # MTOM Attachments {#MTOM}
10328
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.
10335
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
10340 interoperability.
10341
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.
10344
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:
10348
10349 ```cpp
10350 //gsoap xop schema import: http://www.w3.org/2004/08/xop/include
10351 struct _xop__Include
10352 {
10353 unsigned char *__ptr;
10354 int __size;
10355 char *id;
10356 char *type;
10357 char *options;
10358 };
10359 typedef struct _xop__Include _xop__Include;
10360 ```
10361
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.
10369
10370 You can explicitly import the `xop.h` in your header file to use the MTOM attachments in your service, for example:
10371
10372 ```cpp
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
10377 */
10378 #import "import/xop.h"
10379 #import "import/xmime5.h"
10380
10381 //gsoap x schema namespace: http://my.first.mtom.net
10382 struct x__myData
10383 {
10384 _xop__Include xop__Include; // attachment
10385 @ char *xmime5__contentType; // and its contentType
10386 };
10387 int x__myMTOMtest(struct x__myData *in, struct x__myData *out);
10388 ```
10389
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.
10393
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
10397 struct context:
10398
10399 ```cpp
10400 struct soap *soap = soap_new1(SOAP_ENC_MTOM);
10401 ```
10402
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.
10409
10410 ## Generating MultipartRelated MIME Attachment Bindings in WSDL {#MIMEWSDL}
10411
10412 To generate multipartRelated bindings in the WSDL file, use the
10413
10414 ```cpp
10415 //gsoap ... service method-mime-type
10416 ```
10417
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.
10421
10422 For example:
10423
10424 ```cpp
10425 #import "import/soap12.h"
10426 #import "import/xop.h"
10427 #import "import/xmime5.h"
10428
10429 //gsoap x schema namespace: http://my.first.mtom.net
10430 struct x__myData
10431 {
10432 _xop__Include xop__Include; // attachment
10433 @ char *xmime5__contentType; // and its contentType
10434 };
10435 //gsoap x service method-mime-type: myMTOMtest text/xml
10436 int x__myMTOMtest(struct x__myData *in, struct x__myData *out);
10437 ```
10438
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.
10444
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
10448
10449 ```cpp
10450 //gsoap x service method-ouput-mime-type
10451 ```
10452
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.
10458
10459 ## Sending and Receiving MTOM Attachments
10460
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.
10464
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:
10469
10470 ```cpp
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>
10474 ```
10475
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:
10483
10484 ```cpp
10485 #import "xop.h"
10486 #import "xmime5.h"
10487 ```
10488
10489 The `#import` statements are only added for those namespaces that are
10490 actually used by the service.
10491
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:
10494
10495 ```cpp
10496 #import "xop.h"
10497 #import "xmime5.h"
10498 struct ns__Data
10499 {
10500 _xop__Include xop__Include;
10501 @ char *xmime5__contentType;
10502 };
10503 ```
10504
10505 Suppose the WSDL defines an operation:
10506
10507 ```cpp
10508 int ns__echoData(struct ns__Data *in, struct ns__Data *out);
10509 ```
10510
10511 After generating the stubs/proxies with the `soapcpp2` compiler, we can invoke the stub at the client side with:
10512
10513 ```cpp
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);
10524 else
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
10529 ```
10530
10531 Note that the `xop__Include.type` field must be set to transmit MTOM attachments, otherwise plain base64 XML will be used.
10532
10533 At the server side, we show an example of an operation handler that just copies the input data to output:
10534
10535 ```cpp
10536 int ns__echoData(struct soap *soap, struct ns__Data *in, struct ns__data *out)
10537 {
10538 *out = *in;
10539 return SOAP_OK;
10540 }
10541 ```
10542
10543 The server must use the `SOAP_ENC_MTOM` flag to initialize the soap struct to receive and send MTOM attachments.
10544
10545 ## Streaming MTOM/MIME {#MTOMstreaming}
10546
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.
10550
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
10566 streamed.
10567
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.
10582
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.
10588
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
10607 chunked.
10608
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).
10615
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.
10621
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.
10626
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 ):
10629
10630 ```cpp
10631 int main()
10632 {
10633 struct soap soap;
10634 struct xsd__base64Binary image;
10635 FILE *fd;
10636 struct stat sb;
10637 soap_init1(&soap, SOAP_ENC_MTOM); // mandatory to enable MTOM
10638 if (!fstat(fileno(fd), &sb) && sb.st_size > 0)
10639 {
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
10646 }
10647 else
10648 {
10649 // don't know the size, so buffer it
10650 size_t i;
10651 int c;
10652 image.__ptr = (unsigned char*)soap_malloc(&soap, MAX_FILE_SIZE);
10653 for (i = 0; i < MAX_FILE_SIZE; i++)
10654 {
10655 if ((c = fgetc(fd)) == EOF)
10656 break;
10657 image.__ptr[i] = c;
10658 }
10659 fclose(fd);
10660 image.__size = i;
10661 }
10662 image.type = "image/jpeg"; // MIME type
10663 image.options = "This is my picture"; // description of object
10664 soap_call_ns__method(&soap, ...);
10665 ...
10666 }
10667 void *mime_read_open(struct soap *soap, void *handle, const char *id, const char *type, const char *description)
10668 {
10669 return handle;
10670 }
10671 void mime_read_close(struct soap *soap, void *handle)
10672 {
10673 fclose((FILE*)handle);
10674 }
10675 size_t mime_read(struct soap *soap, void *handle, char *buf, size_t len)
10676 {
10677 return fread(buf, 1, len, (FILE*)handle);
10678 }
10679 ```
10680
10681 The following example illustrates the streaming of a MTOM/MIME attachment into a file by a client:
10682
10683 ```cpp
10684 int main()
10685 {
10686 struct soap soap;
10687 soap_init(&soap);
10688 soap.fmimewriteopen = mime_write_open;
10689 soap.fmimewriteclose = mime_write_close;
10690 soap.fmimewrite = mime_write;
10691 soap_call_ns__method(&soap, ...);
10692 ...
10693 }
10694 void *mime_write_open(struct soap *soap, const char *id, const char *type, const char *description, enum soap_mime_encoding encoding)
10695 {
10696 FILE *handle = fopen("somefile", "wb");
10697 // We ignore the MIME content transfer encoding here, but should check
10698 if (!handle)
10699 {
10700 soap->error = SOAP_EOF;
10701 soap->errnum = errno; // get reason
10702 }
10703 return (void*)handle;
10704 }
10705 void mime_write_close(struct soap *soap, void *handle)
10706 {
10707 fclose((FILE*)handle);
10708 }
10709 int mime_write(struct soap *soap, void *handle, const char *buf, size_t len)
10710 {
10711 size_t nwritten;
10712 while (len)
10713 {
10714 nwritten = fwrite(buf, 1, len, (FILE*)handle);
10715 if (!nwritten)
10716 {
10717 soap->errnum = errno; // get reason
10718 return SOAP_EOF;
10719 }
10720 len -= nwritten;
10721 buf += nwritten;
10722 }
10723 return SOAP_OK;
10724 }
10725 ```
10726
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 .
10737
10738 Note that the example above for `mime_read` uses a handle that points to the open file
10739 `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:
10746
10747 ```cpp
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;
10752
10753 file.xmime5__contentType = type;
10754 file.filename = filename;
10755
10756 // The object holding all information to read data
10757 FileStreamIn *ins = new FileStreamIn(errorhandler);
10758 ins->setFilePath(path);
10759 ins->setFileName(filename);
10760
10761 file.xop__Include->__size = size;
10762 file.xop__Include->__ptr = (unsigned char*)ins;
10763 ```
10764
10765 To read the MTOM data for transmission:
10766
10767 ```cpp
10768 void *mime_read_open(struct soap *soap, void *handle, const char *id, const char *type, const char *description)
10769 {
10770 if (!handle)
10771 return NULL;
10772 FileStreamIn *ins = (FileStreamIn*)handle;
10773 if (!ins->open())
10774 {
10775 soap->error = SOAP_ERR;
10776 return NULL;
10777 }
10778 return handle;
10779 }
10780 void mime_read_close(struct soap *soap, void *handle)
10781 {
10782 if (!handle)
10783 \return;
10784 FileStreamIn *ins = (FileStreamIn*)handle;
10785 delete ins;
10786 }
10787 size_t mime_read(struct soap *soap, void *handle, char *buf, size_t len)
10788 {
10789 if (!handle)
10790 return 0;
10791 FileStreamIn *ins = (FileStreamIn*)handle;
10792 size_t nread = ins->read(buf, len);
10793 if (ins->streamError())
10794 {
10795 soap->error = ins->streamError();
10796 return 0;
10797 }
10798 return nread;
10799 }
10800 ```
10801
10802 ## Redirecting Inbound MTOM/MIME Streams Based on SOAP Body Content {#MTOMpoststreaming}
10803
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.
10808
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.
10816
10817 The explicit MTOM/MIME streaming mechanism consists of three API functions:
10818
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.
10822
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
10827 below.
10828
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.
10837
10838 Example client-side code in C:
10839
10840 ```cpp
10841 struct soap *soap = soap_new1(SOAP_ENC_MTOM);
10842 soap_post_check_mime_attachments(soap);
10843 ...
10844 if (soap_call_ns__myMethod(soap, ...))
10845 soap_print_fault(soap, stderr); // an error occurred
10846 else
10847 {
10848 if (soap_check_mime_attachments(soap))
10849 { // attachments are present, channel is still open
10850 {
10851 \Do
10852 {
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:"");
10857 } while (content);
10858 if (soap->error)
10859 soap_print_fault(soap, stderr);
10860 }
10861 }
10862 }
10863 ...
10864 soap_destroy(soap);
10865 soap_end(soap);
10866 soap_free(soap); // detach and free context
10867 ```
10868
10869 The server-side service operations are implemented as usual, but with additional checks for MTOM/MIME attachments:
10870
10871 ```cpp
10872 struct soap *soap = soap_new1(SOAP_ENC_MTOM);
10873 soap_post_check_mime_attachments(soap);
10874 ...
10875 soap_serve(soap);
10876 ...
10877 int ns__myMethod(struct soap *soap, ...)
10878 {
10879 ... // server-side processing logic
10880 if (soap_check_mime_attachments(soap))
10881 { // attachments are present, channel is still open
10882 {
10883 \Do
10884 {
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:"");
10889 } while (content);
10890 if (soap->error)
10891 return soap->error;
10892 }
10893 }
10894 ... // server-side processing logic
10895 return SOAP_OK;
10896 }
10897 ```
10898
10899 ## Streaming Chunked MTOM/MIME {#mimechunking}
10900
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.
10912
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
10917 the data stream.
10918
10919 # XML Validation {#validation}
10920
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.
10926
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
10930 of flags.
10931
10932 ## Occurrence Constraints
10933
10934 ### Default Values
10935
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.
10940
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:
10943
10944 ```cpp
10945 struct ns__MyRecord
10946 {
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
10950 };
10951 ```
10952
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.
10956
10957 ### Elements with minOccurs and maxOccurs Restrictions
10958
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:
10961
10962 ```cpp
10963 Type fieldname [optional: nullptr] [optional: minOccurs[optional: :maxOccurs]] [optional: = value]
10964 ```
10965
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).
10967
10968 The nillable property can by specified by adding a nullptr before the minOccurs (version 2.8.24 or greater).
10969
10970 A fixed initialization value can be specified with `==` (version 2.8.48 or greater).
10971
10972 For example
10973
10974 ```cpp
10975 struct ns__MyRecord
10976 {
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
10982 int *item;
10983 std::vector<double> nums 2; // sequence <nums> with minOccurs=2, maxOccurs=unbounded
10984 };
10985 struct arrayOfint
10986 {
10987 int *__ptr 1:100; // minOccurs=1, maxOccurs=100
10988 int size;
10989 };
10990 ```
10991
10992
10993
10994 ### Required and Prohibited Attributes
10995
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.
11000
11001 For example
11002
11003 ```cpp
11004 struct ns__MyRecord
11005 {
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
11010 };
11011 ```
11012
11013 Remember to set the `SOAP_XML_STRICT` input mode flag to
11014 enable the validation of attribute occurrence constraints.
11015
11016 ## Value Constraints
11017
11018 ### Data Length Restrictions
11019
11020 A schema simpleType is defined with a `typedef` by taking a base primitive to defined a derived simpleType. For example:
11021
11022 ```cpp
11023 typedef int time__seconds;
11024 ```
11025
11026 This defines the following schema type in `time.xsd`:
11027
11028 <div class="alt">
11029 ```xml
11030 <simpleType name="seconds">
11031 <restriction base="xsd:int"/>
11032 </simpleType>
11033 ```
11034 </div>
11035
11036 A complexType with simpleContent is defined with a wrapper struct/class:
11037
11038 ```cpp
11039 struct time__date
11040 {
11041 char *__item; // some custom format date (restriction of string)
11042 @ enum time__zone { EST, GMT, ... } zone;
11043 }
11044 ```
11045
11046 This defines the following schema type in `time.xsd`:
11047
11048 <div class="alt">
11049 ```xml
11050 <complexType name="date">
11051 <simpleContent>
11052 <extension base="xsd:string"/>
11053 </simpleContent>
11054 <attribute name="zone" type="time:zone" use="optional"/>
11055 </complexType>
11056 <simpleType name="zone">
11057 <restriction base="xsd:string">
11058 <enumeration value="EST"/>
11059 <enumeration value="GMT"/>
11060 ...
11061 </restriction>
11062 </simpleType>
11063 ```
11064 </div>
11065
11066 Data value length constraints of simpleTypes and complexTypes with simpleContent are defined as follows.
11067
11068 ```cpp
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
11073 {
11074 char *__item :256; // simpleContent with at most 256 characters
11075 @ char *name 1; // required name attribute
11076 };
11077 struct time__date // simpleContent wrapper
11078 {
11079 char *__item :100;
11080 @ enum time__zone { EST, GMT, ... } zone = GMT;
11081 }
11082 ```
11083
11084 Remember to set the `SOAP_XML_STRICT` input mode flag to
11085 enable the validation of value length constraints.
11086
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.
11090
11091 ### Value Range Restrictions
11092
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.
11096
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:
11099
11100 Range | Validitation check
11101 -------------- | ------------------
11102 `1 ` | 1 <= x
11103 `1 : ` | 1 <= x
11104 ` : 10 ` | x <= 10
11105 `1 : 10 ` | 1 <= x <= 10
11106 `1 < : < 10 ` | 1 < x < 10
11107 `1 < 10 ` | 1 < x < 10
11108 `1 : < 10` | 1 <= x < 10
11109 ` : < 10` | x < 10
11110 ` < 10` | x < 10
11111 `1 < : ` | 1 < x
11112 `1 < ` | 1 < x
11113 `1 < : 10 ` | 1 < x <= 10
11114
11115 Example:
11116
11117 ```cpp
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
11122 {
11123 int __item 0:10; // simpleContent range 0..10
11124 @ char *name 1; // required name attribute
11125 };
11126 ```
11127
11128 Remember to set the `SOAP_XML_STRICT` input mode flag to
11129 enable the validation of value range constraints.
11130
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.
11134
11135 ### Pattern Restrictions
11136
11137 Patterns can be defined for simpleType content. However, patterns are currently not enforced in the validation process though possibly in future releases.
11138
11139 To associate a pattern with a simpleType, you can define a simpleType with a `typedef` and a pattern string:
11140
11141 ```cpp
11142 typedef int time__second "[1-5]?[0-9]|60";
11143 ```
11144
11145 This defines the following schema type in `time.xsd`:
11146
11147 <div class="alt">
11148 ```xml
11149 <simpleType name="second">
11150 <restriction base="xsd:int">
11151 <pattern value="[1-5]?[0-9]|60"/>
11152 </restriction>
11153 </simpleType>
11154 ```
11155
11156 </div>
11157 The pattern string MUST contain a valid regular expression.
11158
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:
11163
11164 <div class="alt">
11165 ```xml
11166 <simpleType name="ratio">
11167 <restriction base="xsd:float">
11168 <totalDigits value="5"/>
11169 <fractionDigits value="2"/>
11170 </restriction>
11171 </simpleType>
11172 ```
11173 </div>
11174
11175 produces:
11176
11177 ```cpp
11178 typedef float time__ratio "%5.2f";
11179 ```
11180
11181 The format string is used to format the output the floating point value in XML.
11182
11183 ## Element and Attribute Qualified/Unqualified Forms
11184
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).
11191
11192 See Section \ref idtrans for details on the
11193 the struct/class/union member identifier translation rules.
11194 Consider for example:
11195
11196 ```cpp
11197 //gsoap ns schema elementForm: qualified
11198 //gsoap ns schema attributeForm: unqualified
11199 struct ns__record
11200 {
11201 @ char * type;
11202 char * name;
11203 };
11204 ```
11205
11206 Here, the `ns__record` struct is serialized with qualified element `name` and unqualified attribute `type`:
11207
11208 <div class="alt">
11209 ```xml
11210 <ns:record type="...">
11211 <ns:name>...</ns:name>
11212 </ns:record>
11213 ```
11214 </div>
11215
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:
11219
11220 ```cpp
11221 //gsoap ns schema elementForm: qualified
11222 //gsoap ns schema attributeForm: unqualified
11223 struct ns__record
11224 {
11225 @ char * ns:type;
11226 char * :name;
11227 };
11228 ```
11229
11230 where `name` is unqualified and `type` is qualified:
11231
11232 <div class="alt">
11233 ```xml
11234 <ns:record ns:type="...">
11235 <name>...</name>
11236 </ns:record>
11237 ```
11238 </div>
11239
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.
11242
11243 The colon notation does not avoid name clashes between members. For example:
11244
11245 ```cpp
11246 struct x__record
11247 {
11248 @ char * name;
11249 char * x:name;
11250 };
11251 ```
11252
11253 results in a redefinition error, since both members have the same name. To avoid name clashes, use a underscore suffix:
11254
11255 ```cpp
11256 struct x__record
11257 {
11258 @ char * name;
11259 char * x:name_;
11260 };
11261 ```
11262
11263 Not that the namespace prefix convention can be used instead:
11264
11265 ```cpp
11266 struct x__record
11267 {
11268 @ char * name;
11269 char * x__name;
11270 };
11271 ```
11272
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.
11276
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:
11282
11283 ```cpp
11284 struct x__record
11285 {
11286 char * :name;
11287 char * x:phone;
11288 char * x__fax;
11289 char * y__zip;
11290 };
11291 ```
11292
11293 which generates the following `x.xsd`schema:
11294
11295 <div class="alt">
11296 ```xml
11297 <complexType name="record">
11298 <sequence>
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"/>
11303 </sequence>
11304 </complexType>
11305 <element name="fax" type="xsd:string"/>
11306 ```
11307 </div>
11308
11309 and the `y.xsd` schema defines contains:
11310
11311 <div class="alt">
11312 ```xml
11313 <element name="zip" type="xsd:string"/>
11314 ```
11315 </div>
11316
11317 # SOAP/XML Over UDP {#udp}
11318
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.
11326
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`.
11331
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
11340 specification.
11341
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.
11345
11346 The gSOAP implementation conforms to the SOAP-over-UDP requirements:
11347
11348
11349 * SOAP-over-UDP server endpoint URL format: *soap.udp://host:port/path*
11350
11351 * Support one-way message-exchange pattern (MEP) where a SOAP envelope is
11352 carried in a user datagram.
11353
11354 * Support request-response message-exchange pattern (MEP) where SOAP envelopes
11355 are carried in user datagrams.
11356
11357 * Support multicast transmission of SOAP envelopes carried in user datagrams.
11358
11359 * Support both SOAP 1.1 and SOAP 1.2 envelopes.
11360
11361 The following additional features are also available, but are not supported by the SOAP-over-UDP specification:
11362
11363
11364 * Zlib/gzip message compression (compile `-DWITH_GZIP`).
11365
11366 * SOAP with DIME attachments over UDP.
11367
11368 * SOAP with MIME attachments (SwA) over UDP.
11369
11370 * Support for IPv6 (compile `-DWITH_IPV6`)
11371
11372
11373 ## Using WS-Addressing with SOAP-over-UDP {#udp.h}
11374
11375 A SOAP-over-UDP application MUST use WS-Addressing to control message delivery
11376 as per SOAP-over-UDP specification.
11377
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.
11382 For example:
11383
11384 ```cpp
11385 #import "wsa.h"
11386 struct SOAP_ENV__Header
11387 {
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;
11395 };
11396 ```
11397
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.
11401
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:
11405
11406 ```cpp
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);
11411 ```
11412
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:
11418
11419 ```cpp
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);
11426 ```
11427
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.
11432
11433 ## Client-side One-way Unicast
11434
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
11437 Section \ref udp.h
11438
11439 ```cpp
11440 struct soap soap;
11441 struct SOAP_ENV__Header header; // the SOAP Header
11442 soap_init(&soap);
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)
11455 ```
11456
11457 ## Client-side One-way Multicast
11458
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:
11461
11462 ```cpp
11463 struct soap soap;
11464 struct SOAP_ENV__Header header; // the SOAP Header
11465 in_addr_t addr = inet_addr("1.2.3.4"); // optional
11466 soap_init(&soap);
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)
11483 ```
11484
11485 Please refer to the socket options for `IPPROTO_IP IP_MULTICAST_IF`
11486 to specify
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).
11491
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.
11496
11497 ## Client-side Request-Response Unicast
11498
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
11501 Section \ref udp.h
11502
11503 ```cpp
11504 struct soap soap;
11505 struct SOAP_ENV__Header header; // the SOAP Header
11506 struct wsa__EndpointReferenceType replyTo; // (anonymous) reply address
11507 char *res; // server response
11508 soap_init(&soap);
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))
11521 {
11522 if (soap.error == SOAP_EOF && soap.errnum == 0)
11523 // Timeout: no response from server (message already delivered?)
11524 else
11525 soap_print_fault(&soap, stderr);
11526 }
11527 else
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)
11534 ```
11535
11536 ## Client-side Request-Response Multicast
11537
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:
11545
11546 ```cpp
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);
11557 ```
11558
11559 To obtain response one-way operations, use the wsdl2h `-b` option.
11560
11561 The client code includes a loop to receive response messages until a timeout occurs:
11562
11563 ```cpp
11564 struct soap soap;
11565 struct SOAP_ENV__Header header;
11566 struct wsa__EndpointReferenceType replyTo;
11567 char *res;
11568 soap_init(&soap);
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);
11582 else
11583 {
11584 for (;;)
11585 {
11586 if (soap_recv_ns__bcastStringResponse(&soap, &res))
11587 break;
11588 // Got response 'res' from a server
11589 }
11590 if (soap.error == SOAP_EOF && soap.errnum == 0)
11591 // Timeout: no more messages received
11592 else
11593 soap_print_fault(&soap, stderr);
11594 }
11595 soap_destroy(&soap); // cleanup
11596 soap_end(&soap); // cleanup
11597 soap_done(&soap); // close connection (should not use soap struct after this)
11598 ```
11599
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.
11603
11604 ## SOAP-over-UDP Server {#soapoverudp}
11605
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 .
11610
11611 ```cpp
11612 int main()
11613 {
11614 struct soap soap;
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)))
11618 {
11619 soap_print_fault(&soap, stderr);
11620 exit(1);
11621 }
11622 for (;;)
11623 {
11624 if (soap_serve(&soap))
11625 soap_print_fault(&soap, stderr); // report the problem
11626 soap_destroy(&soap);
11627 soap_end(&soap);
11628 }
11629 soap_done(&soap); // close connection
11630 }
11631 int ns__echoString(struct soap *soap, char *str, char **res)
11632 {
11633 if (!soap->header)
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))
11642 {
11643 // Request message already received
11644 return SOAP_STOP; // don't return response
11645 }
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";
11651 *res = str;
11652 return SOAP_OK;
11653 }
11654 int ns__sendString(struct soap *soap, char *str)
11655 {
11656 if (!soap->header)
11657 return SOAP_STOP;
11658 if (!soap->header->wsa__MessageID)
11659 return SOAP_STOP;
11660 // must check for duplicate messages
11661 if (check_received(soap->header->wsa__MessageID))
11662 return SOAP_STOP;
11663 return SOAP_OK;
11664 }
11665 int ns__sendStringResponse(struct soap *soap, char *res)
11666 { return SOAP_NO_METHOD; } // we don't expect to serve this message
11667 ```
11668
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`
11673 non-blocking.
11674
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.
11676
11677 ## SOAP-over-UDP Multicast Receiving Server
11678
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:
11683
11684 ```cpp
11685 int main()
11686 {
11687 struct soap soap;
11688 struct ip_mreq mcast;
11689 soap_init1(&soap, SOAP_IO_UDP);
11690 if (!soap_valid_socket(soap_bind(&soap, host, port, 100)))
11691 {
11692 soap_print_fault(&soap, stderr);
11693 exit(1);
11694 }
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)
11698 ... error ...
11699 ```
11700
11701 # Advanced Features {#advanced}
11702
11703 ## Internationalization
11704
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:
11711
11712 ```cpp
11713 typedef wchar_t *xsd__string;
11714 ...
11715 int ns__myMethod(xsd__string input, xsd__string *output);
11716 ```
11717
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.
11724
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:
11727
11728 ```cpp
11729 typedef wchar_t *xsd__string;
11730 typedef char *xsd__string_; // trailing '_' avoids name clash
11731 ...
11732 int ns__myMethod(xsd__string input, xsd__string_ *output);
11733 ```
11734
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
11739 encoded content.
11740
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.
11743
11744 ## Customizing the WSDL and Namespace Mapping Table File Contents With gSOAP Directives {#directives}
11745
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`.)
11751
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:
11755
11756 ```cpp
11757 //gsoap *namespace-prefix* service name: *service-name*
11758 ```
11759
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.
11763
11764 To specify the name of the WSDL definitions in the header file, use:
11765
11766 ```cpp
11767 //gsoap *namespace-prefix* service definitions: *definitions-name*
11768 ```
11769
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.
11771
11772 To specify the documentation of a Web Service in the header file, use:
11773
11774 ```cpp
11775 //gsoap *namespace-prefix* service documentation: *text*
11776 ```
11777
11778 or shorthand:
11779
11780 ```cpp
11781 //gsoap *namespace-prefix* service doc: *text*
11782 ```
11783
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.
11786
11787 To specify the portType of a Web Service in the header file, use:
11788
11789 ```cpp
11790 //gsoap *namespace-prefix* service portType: *portType-name*
11791 ```
11792
11793 or just
11794
11795 ```cpp
11796 //gsoap *namespace-prefix* service type: *portType-name*
11797 ```
11798
11799 or using WSDL 2.0 terms
11800
11801 ```cpp
11802 //gsoap *namespace-prefix* service interface: *portType-name*
11803 ```
11804
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.
11806
11807 To specify the port name of a Web Service in the header file, use:
11808
11809 ```cpp
11810 //gsoap *namespace-prefix* service portName: *port-name*
11811 ```
11812
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.
11814
11815 To specify the binding name of a Web Service in the header file, use:
11816
11817 ```cpp
11818 //gsoap *namespace-prefix* service binding: *binding-name*
11819 ```
11820
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.
11822
11823 To specify the binding's transport protocol of a Web Service in the header file, use:
11824
11825 ```cpp
11826 //gsoap *namespace-prefix* service transport: *transport-URL*
11827 ```
11828
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.
11830
11831 To specify the location (or port endpoint) of a Web Service in the header file, use:
11832
11833 ```cpp
11834 //gsoap *namespace-prefix* service location: *URL*
11835 ```
11836
11837 or alternatively
11838
11839 ```cpp
11840 //gsoap *namespace-prefix* service endpoint: *URL*
11841 ```
11842
11843 or
11844
11845 ```cpp
11846 //gsoap *namespace-prefix* service port: *URL*
11847 ```
11848
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).
11852
11853 To specify the name of the executable of a Web Service in the header file, use:
11854
11855 ```cpp
11856 //gsoap *namespace-prefix* service executable: *executable-name*
11857 ```
11858
11859 where *executable-name* is the name of the executable of the Web Service.
11860
11861 When doc/literal encoding is required for the entire service, the service encoding can be specified in the header file as follows:
11862
11863 ```cpp
11864 //gsoap *namespace-prefix* service encoding: literal
11865 ```
11866
11867 or when the *`SOAP-ENV:encodingStyle`* attribute is different from the SOAP 1.1/1.2 encoding style:
11868
11869 ```cpp
11870 //gsoap *namespace-prefix* service encoding: *encoding-style*
11871 ```
11872
11873 To specify the namespace URI of a Web Service in the header file, use:
11874
11875 ```cpp
11876 //gsoap *namespace-prefix* service namespace: *namespace-URI*
11877 ```
11878
11879 where *namespace-URI* is the URI associated with the namespace prefix.
11880
11881 In addition, the schema namespace URI can be specified in the header file:
11882
11883 ```cpp
11884 //gsoap *namespace-prefix* schema namespace: *namespace-URI*
11885 ```
11886
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:
11893
11894 ```cpp
11895 //gsoap *namespace-prefix* schema namespace2: *namespace-URI-pattern*
11896 ```
11897
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.
11902
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:
11905
11906 ```cpp
11907 //gsoap *namespace-prefix* schema import: *namespace-URI*
11908 ```
11909
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.
11912
11913 A schema namespace URI can be imported from a location with:
11914
11915 ```cpp
11916 //gsoap *namespace-prefix* schema namespace: *namespace-URI*
11917 //gsoap *namespace-prefix* schema import: *schema-location*
11918 ```
11919
11920 The elementFormDefault and attributeFormDefault qualification of a schema can be defined with:
11921
11922 ```cpp
11923 //gsoap *namespace-prefix* schema elementForm: qualified
11924 //gsoap *namespace-prefix* schema attributeForm: qualified
11925 ```
11926
11927 or:
11928
11929 ```cpp
11930 //gsoap *namespace-prefix* schema elementForm: unqualified
11931 //gsoap *namespace-prefix* schema attributeForm: unqualified
11932 ```
11933
11934 A shortcut to define the default qualification of elements and attributes of a schema:
11935
11936 ```cpp
11937 //gsoap *namespace-prefix* schema form: qualified
11938 ```
11939
11940 or:
11941
11942 ```cpp
11943 //gsoap *namespace-prefix* schema form: unqualified
11944 ```
11945
11946 To include *`xsi:type`* attributes in the runtime XML element output for specific schemas, use:
11947
11948 ```cpp
11949 //gsoap *namespace-prefix* schema typed: yes
11950 ```
11951
11952 Note that `soapcpp2 -t` enables *`xsi:type`* for all elements in the runtime XML output.
11953
11954 To document a data type, use:
11955
11956 ```cpp
11957 //gsoap *namespace-prefix* schema type-documentation: *type-name* //*text*
11958 ```
11959
11960 or shorthand:
11961
11962 ```cpp
11963 //gsoap *namespace-prefix* schema type: *type-name* //*text*
11964 ```
11965
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.
11969 For example:
11970
11971 ```cpp
11972 //gsoap ns schema type: tdata stores <a href="transaction.html">transaction</a> data
11973 class ns__tdata
11974 { ... }
11975 ```
11976
11977 To document a data type's fields and members, use:
11978
11979 ```cpp
11980 //gsoap *namespace-prefix* schema type-documentation: *type-name::field* //*text*
11981 ```
11982
11983 or shorthand
11984
11985 ```cpp
11986 //gsoap *namespace-prefix* schema type: *type-name::field* //*text*
11987 ```
11988
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.
11992 For example:
11993
11994 ```cpp
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
11999 class ns__tdata
12000 {
12001 @ int id;
12002 enum ns__tstate { INIT, DONE } state;
12003 ...
12004 }
12005 ```
12006
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.
12009
12010 To document a method, use:
12011
12012 ```cpp
12013 //gsoap *namespace-prefix* service method-documentation: *method-name* *text*
12014 ```
12015
12016 or shorthand:
12017
12018 ```cpp
12019 //gsoap *namespace-prefix* service method: *method-name* *text*
12020 ```
12021
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.
12025 For example:
12026
12027 ```cpp
12028 //gsoap ns service method: getQuote returns a <i>stock quote</i>
12029 int ns__getQuote(char *symbol, float &_result);
12030 ```
12031
12032 To specify the SOAP Action for a SOAP method, use:
12033
12034 ```cpp
12035 //gsoap *namespace-prefix* service method-action: *method-name* *action*
12036 ```
12037
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).
12040 For example:
12041
12042 ```cpp
12043 //gsoap ns service method-action: getQuote ""
12044 int ns__getQuote(char *symbol, float &_result);
12045 ```
12046
12047 Or, alternatively for the input action (part of the request):
12048
12049 ```cpp
12050 //gsoap ns service method-input-action: getQuote ""
12051 int ns__getQuote(char *symbol, float &_result);
12052 ```
12053
12054 To specify the HTTP "location" of REST methods to a perform POST/GET/PUT action, use:
12055
12056 ```cpp
12057 //gsoap *namespace-prefix* service method-action: *method-name* *action*
12058 ```
12059
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.
12063
12064 A response action and fault action are defined by:
12065
12066 ```cpp
12067 //gsoap *namespace-prefix* service method-output-action: *method-name* *action*
12068 //gsoap *namespace-prefix* service method-fault-action: *method-name* *action*
12069 ```
12070
12071 To override the SOAP or REST protocol of an operation (SOAP by default), use:
12072
12073 ```cpp
12074 //gsoap *namespace-prefix* service method-protocol: *method-name* *protocol*
12075 ```
12076
12077 where *protocol* is one of
12078
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
12092
12093 When document style is preferred for a particular service method, use:
12094
12095 ```cpp
12096 //gsoap *namespace-prefix* service method-style: *method-name* document
12097 ```
12098
12099 When SOAP RPC encoding is required for a particular service method, use:
12100
12101 ```cpp
12102 //gsoap *namespace-prefix* service method-encoding: *method-name* encoded
12103 ```
12104
12105 When literal encoding is required for a particular service method, use:
12106
12107 ```cpp
12108 //gsoap *namespace-prefix* service method-encoding: *method-name* literal
12109 ```
12110
12111 or when the *`SOAP-ENV:encodingStyle`* attribute is different from the SOAP 1.1/1.2 encoding style, use:
12112
12113 ```cpp
12114 //gsoap *namespace-prefix* service method-encoding: *method-name* *encoding-style*
12115 ```
12116
12117 When SOAP RPC encoding is required for a particular service method response when the request message is literal, use:
12118
12119 ```cpp
12120 //gsoap *namespace-prefix* service method-response-encoding: *method-name* encoded
12121 ```
12122
12123 When literal encoding is required for a particular service method response when the request message is encoded, use:
12124
12125 ```cpp
12126 //gsoap *namespace-prefix* service method-response-encoding: *method-name* literal
12127 ```
12128
12129 or when the *`SOAP-ENV:encodingStyle`* attribute is different from the SOAP 1.1/1.2 encoding style, use:
12130
12131 ```cpp
12132 //gsoap *namespace-prefix* service method-response-encoding: *method-name* *encoding-style*
12133 ```
12134
12135 Note that the `method-response-encoding` is set to the value of `method-encoding` by default.
12136
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:
12139
12140 ```cpp
12141 //gsoap *namespace-prefix* service method-header-part: *method-name* *header-part*
12142 ```
12143
12144 For example:
12145
12146 ```cpp
12147 struct SOAP_ENV__Header
12148 {
12149 char *h__transaction;
12150 struct UserAuth *h__authentication;
12151 };
12152 ```
12153
12154 Suppose method `ns__login` uses both header parts (at most), then this is declared as:
12155
12156 ```cpp
12157 //gsoap ns service method-header-part: login h__transaction
12158 //gsoap ns service method-header-part: login h__authentication
12159 int ns__login(...);
12160 ```
12161
12162 Suppose method `ns__search` uses only the first header part, then this is declared as:
12163
12164 ```cpp
12165 //gsoap ns service method-header-part: search h__transaction
12166 int ns__search(...);
12167 ```
12168
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.
12171
12172 To specify the header parts for the method input (method request message), use:
12173
12174 ```cpp
12175 //gsoap *namespace-prefix* service method-input-header-part: *method-name* *header-part*
12176 ```
12177
12178 Similarly, to specify the header parts for the method output (method response message), use:
12179
12180 ```cpp
12181 //gsoap *namespace-prefix* service method-output-header-part: *method-name* *header-part*
12182 ```
12183
12184 The declarations only affect the WSDL.
12185 For example:
12186
12187 ```cpp
12188 struct SOAP_ENV__Header
12189 {
12190 char *h__transaction;
12191 struct UserAuth *h__authentication;
12192 };
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(...);
12197 ```
12198
12199 The headers MUST be present in all operations that declared the header parts.
12200
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:
12202
12203 ```cpp
12204 //gsoap *namespace-prefix* service method-fault: *method-name* *fault-detail*
12205 ```
12206
12207 The declarations only affect the WSDL.
12208 For example:
12209
12210 ```cpp
12211 struct SOAP_ENV__Header
12212 {
12213 char *h__transaction;
12214 struct UserAuth *h__authentication;
12215 };
12216 //gsoap ns service method-fault: login f__invalid
12217 //gsoap ns service method-fault: login f__unavailable
12218 int ns__login(...);
12219 ```
12220
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.
12222
12223 To specify MIME attachments for the method input and output (method request and response messages), use:
12224
12225 ```cpp
12226 //gsoap *namespace-prefix* service method-mime-type: *method-name* *mime-type*
12227 ```
12228
12229 You can repeat this directive for all multipartRelated MIME attachments you want to associate with the method.
12230
12231 To specify MIME attachments for the method input (method request message), use:
12232
12233 ```cpp
12234 //gsoap *namespace-prefix* service method-input-mime-type: *method-name* *mime-type*
12235 ```
12236
12237 Similarly, to specify MIME attachments for the method output (method response message), use:
12238
12239 ```cpp
12240 //gsoap *namespace-prefix* service method-output-mime-type: *method-name* *mime-type*
12241 ```
12242
12243 You can repeat these directives for all multipartRelated MIME attachments you want to associate with the method.
12244
12245 ### Example
12246
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.
12250
12251 ```cpp
12252 //gsoap ns1 service namespace: urn:GetQuote
12253 int ns1__getQuote(char *symbol, float &result);
12254
12255 //gsoap ns2 service namespace: urn:CurrencyExchange
12256 int ns2__getRate(char *country1, char *country2, float &result);
12257
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);
12264 ```
12265
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.
12268
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`.
12271
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:
12275
12276 > soapcpp2 quotex.h
12277
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.
12282
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
12286 `quotex.cpp`:
12287
12288 ```cpp
12289 #include "quotex.nsmap"
12290 ```
12291
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`).
12296
12297 ## Transient Data Types {#transient}
12298
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 .
12315
12316 First example:
12317
12318 ```cpp
12319 extern class ostream; // ostream can't be (de)serialized, but need to be declared to make it visible to gSOAP
12320 class ns__myClass
12321 { ...
12322 virtual void print(ostream &s) const; // need ostream here
12323 ...
12324 };
12325 ```
12326
12327 Second example:
12328
12329 ```cpp
12330 [
12331 class myBase // base class need not be (de)serialized
12332 { ... };
12333 ]
12334 class ns__myDerived : myBase
12335 { ... };
12336 ```
12337
12338 Third example:
12339
12340 ```cpp
12341 [ typedef int transientInt; ]
12342 class ns__myClass
12343 {
12344 int a; // will be (de)serialized
12345 [
12346 int b; // transient field
12347 char s[256]; // transient field
12348 ]
12349 extern float d; // transient field
12350 char *t; // will be (de)serialized
12351 transientInt *n; // transient field
12352 [
12353 virtual void method(char buf[1024]); // does not create a char[1024] (de)serializer
12354 ]
12355 };
12356 ```
12357
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.
12366
12367 ## Serialization "{as is" with Volatile Data Types} {#volatile}
12368
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.
12375
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:
12377
12378 ```cpp
12379 volatile struct tm
12380 {
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 */
12392 };
12393 ```
12394
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:
12397
12398 ```cpp
12399 struct soap *soap = soap_new();
12400 ...
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);
12406 soap_end(soap);
12407 soap_free(soap); // detach and free context
12408 ```
12409
12410 It is also possible to serialize the tm fields as XML attributes using the
12411 `@` qualifier, see Section \ref attributes .
12412
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:
12416
12417 ```cpp
12418 typedef struct tm time__struct_tm;
12419 ```
12420
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.
12423
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.
12430
12431 ## How to Declare User-Defined Serializers and Deserializers {#extern}
12432
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:
12436
12437 ```cpp
12438 extern typedef char *MyData;
12439 struct Sample
12440 {
12441 MyData s; // use user-defined (de)serializer for this field
12442 char *t; // use gSOAP (de)serializer for this field
12443 };
12444 ```
12445
12446 The user is required to supply the following routines for each `extern typedef`'ed name T:
12447
12448 ```cpp
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)
12453 ```
12454
12455 The function prototypes can be found in `soapH.h`.
12456
12457 For example, the (de)serialization of `MyData` can be done with the following code:
12458
12459 ```cpp
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)
12463 { *a = NULL }
12464 int soap_out_MyData(struct soap *soap, const char *tag, int id, MyData const*a, const char *type)
12465 {
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;
12470 return SOAP_OK;
12471 }
12472 MyData **soap_in_MyData(struct soap *soap, const char *tag, MyData *a, const char *type)
12473 {
12474 if (soap_element_begin_in(soap, tag))
12475 return NULL;
12476 if (!a)
12477 a = (MyData*)soap_malloc(soap, sizeof(MyData));
12478 if (soap->null)
12479 *a = NULL; // xsi:nil element
12480 if (*soap->type && soap_match_tag(soap, soap->type, type))
12481 {
12482 soap->error = SOAP_TYPE;
12483 return NULL; // type mismatch
12484 }
12485 if (*soap->href)
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)
12488 {
12489 char *s = soap_value(soap); // fill buffer
12490 *a = (char*)soap_malloc(soap, strlen(s)+1);
12491 strcpy(*a, s);
12492 }
12493 if (soap->body && soap_element_end_in(soap, tag))
12494 return NULL;
12495 return a;
12496 }
12497 ```
12498
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.
12501
12502 ## How to Serialize Data Without Generating xsi:type Attributes
12503
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.
12511
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
12516 `enum`s.
12517
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:
12521
12522 ```cpp
12523 typedef char *_xsd__date;
12524 ```
12525
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
12531 underscore, as in:
12532
12533 ```cpp
12534 struct _ns__myStruct
12535 { ... };
12536 ```
12537
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.
12542
12543 ## Function Callbacks for Customized I/O and HTTP Handling {#callback}
12544
12545 gSOAP provides five callback functions for customized I/O and HTTP handling:
12546
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:
12552 `tcp_connect`
12553
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`
12561
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`
12567
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`
12573
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`
12579
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`
12585
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.
12592
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`.
12601
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`.
12606
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`
12614
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`
12622
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`
12628
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`
12632
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`
12637
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
12645 function: none.
12646
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
12654
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`
12660
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`
12665
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`
12669
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.
12676
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.
12685
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.
12690
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.
12696
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.
12702
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:
12707 none.
12708
12709 In addition, a `void *user` field in the `struct soap` data structure is available to pass user-defined data to the callbacks.
12710
12711 The following example uses I/O function callbacks for customized serialization of data into a fixed-size buffer and deserialization back into a
12712 datastructure:
12713
12714 ```cpp
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)
12720 {
12721 if (len1 + n > sizeof(buf))
12722 return SOAP_EOF;
12723 strcpy(buf + len1, s);
12724 len1 += n;
12725 return SOAP_OK;
12726 }
12727 // myrecv: get XML from buf[]
12728 size_t myrecv(struct soap *soap, char *s, size_t n)
12729 {
12730 if (len2 + n > len1)
12731 n = len1 - len2;
12732 strncpy(s, buf + len2, n);
12733 len2 += n;
12734 return n;
12735 }
12736 int main()
12737 {
12738 struct soap soap;
12739 struct ns__person p;
12740 soap_init(&soap);
12741 len1 = len2 = 0; // reset buffer pointers
12742 p.name = "John Doe";
12743 p.age = 25;
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);
12751 if (soap.error)
12752 {
12753 soap_print_fault(&soap, stdout);
12754 exit(1);
12755 }
12756 soap_begin_recv(&soap);
12757 soap_get_ns__person(&soap, &p, "ns:person", NULL);
12758 soap_end_recv(&soap);
12759 if (soap.error)
12760 {
12761 soap_print_fault(&soap, stdout);
12762 exit(1);
12763 }
12764 soap_destroy(&soap);
12765 soap_end(&soap);
12766 soap_done(&soap); // disable callbacks
12767 }
12768 ```
12769
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:
12771
12772 ```cpp
12773 struct buffer
12774 {
12775 size_t len;
12776 size_t max;
12777 char *buf;
12778 };
12779 int main()
12780 {
12781 struct buffer *h = malloc(sizeof(struct buffer));
12782 h->len = 0;
12783 h->max = 0;
12784 h->buf = NULL;
12785 soap.user = (void *)h; // pass buffer as a handle to the callback
12786 soap.fsend = mysend; // assign callback
12787 ...
12788 if (h->len)
12789 {
12790 ... // use h->buf[0..h->len-1] content
12791 // then cleanup:
12792 h->len = 0;
12793 h->max = 0;
12794 free(h->buf);
12795 h->buf = NULL;
12796 }
12797 ...
12798 }
12799 int mysend(struct soap *soap, const char *s, size_t n)
12800 {
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?
12804 if (m == 0)
12805 m = 1024;
12806 else
12807 while (k >= m)
12808 m *= 2;
12809 if (m != h->max)
12810 {
12811 char *buf = malloc(m);
12812 memcpy(buf, h->buf, h->len);
12813 h->max = m;
12814 if (h->buf)
12815 free(h->buf);
12816 h->buf = buf;
12817 }
12818 memcpy(h->buf + h->len, s, n);
12819 h->len += n;
12820 return SOAP_OK;
12821 }
12822 ```
12823
12824 The `soap_done` function can be called to reset the callback to the default internal gSOAP I/O and HTTP handlers.
12825
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).
12830
12831 The header file is:
12832
12833 ```cpp
12834 //gsoap ns service name: callback
12835 //gsoap ns service namespace: urn:callback
12836 struct ns__person
12837 {
12838 char *name;
12839 int age;
12840 };
12841 int ns__test(struct ns__person in, struct ns__test &out);
12842 ```
12843
12844 The client program is:
12845
12846 ```cpp
12847 #include "soapH.h"
12848 ...
12849 SOAP_SOCKET myopen(struct soap *soap, const char *endpoint, const char *host, int port)
12850 {
12851 if (strncmp(endpoint, "file:", 5))
12852 {
12853 printf("File name expected\n");
12854 return SOAP_INVALID_SOCKET;
12855 }
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;
12859 }
12860 void myclose(struct soap *soap)
12861 {
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
12866 }
12867 int mypost(struct soap *soap, const char *endpoint, const char *host, const char *path, const char *action, size_t count)
12868 {
12869 return soap_send(soap, "Custom-generated file\n"); // writes to soap->sendfd
12870 }
12871 int myparse(struct soap *soap)
12872 {
12873 char buf[256];
12874 if (lseek(soap->recvfd, 0, SEEK_SET) < 0 || soap_getline(soap, buf, 256)) // go to begin and skip custom header
12875 return SOAP_EOF;
12876 return SOAP_OK;
12877 }
12878 int main()
12879 {
12880 struct soap soap;
12881 struct ns__test r;
12882 struct ns__person p;
12883 soap_init(&soap); // reset
12884 p.name = "John Doe";
12885 p.age = 99;
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);
12891 if (soap.error)
12892 {
12893 soap_print_fault(&soap, stdout);
12894 exit(1);
12895 }
12896 soap_end(&soap);
12897 soap_init(&soap); // reset to default callbacks
12898 }
12899 ```
12900
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:
12907
12908 ```cpp
12909 int myignore(struct soap *soap, const char *tag)
12910 {
12911 return SOAP_MUSTUNDERSTAND; // never skip elements (secure)
12912 }
12913 ...
12914 soap.fignore = myignore;
12915 soap_call_ns__method(&soap, ...); // or soap_serve(&soap);
12916 ```
12917
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:
12919
12920 ```cpp
12921 int myignore(struct soap *soap, const char *tag)
12922 {
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;
12927 return SOAP_OK;
12928 }
12929 ...
12930 soap.fignore = myignore;
12931 soap_call_ns__method(&soap, ...); // or soap_serve(&soap)
12932 ...
12933 struct Namespace namespaces[] =
12934 {
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
12940 {NULL, NULL}
12941 ```
12942
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
12946 message.
12947
12948 The callback can also be used to keep track of unknown elements in an internal data structure such as a list:
12949
12950 ```cpp
12951 struct Unknown
12952 {
12953 char *tag;
12954 struct Unknown *next;
12955 };
12956 int myignore(struct soap *soap, const char *tag)
12957 {
12958 char *s = (char*)soap_malloc(soap, strlen(tag)+1);
12959 struct Unknown *u = (struct Unknown*)soap_malloc(soap, sizeof(struct Unknown));
12960 if (s && u)
12961 {
12962 strcpy(s, tag);
12963 u->tag = s;
12964 u->next = ulist;
12965 ulist = u;
12966 }
12967 }
12968 ...
12969 struct soap *soap;
12970 struct Unknown *ulist = NULL;
12971 soap_init(&soap);
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
12976 ```
12977
12978 ## HTTP 1.0 and 1.1
12979
12980 gSOAP uses HTTP 1.1 by default. You can revert to HTTP 1.0 as follows:
12981
12982 ```cpp
12983 struct soap soap;
12984 soap_init(&soap);
12985 ...
12986 soap.http_version = "1.0";
12987 ```
12988
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.
12991
12992 ## HTTP 307 Temporary Redirect Support
12993
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:
12995
12996
12997 * Redirecting a secure HTTPS address to a non-secure HTTP address via 307 creates a security vulnerability.
12998
12999 * Cyclic redirects must be detected (e.g. allowing only a limited number of redirect levels).
13000
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.
13002
13003 To implement client-side 307 redirect, add the following lines of code:
13004
13005 ```cpp
13006 char *endpoint = NULL; // use default endpoint given in WSDL (or add another one here)
13007 int n = 10; // max redirect count
13008 while (n--)
13009 {
13010 if (soap_call_ns1__myMethod(soap, endpoint, ...))
13011 {
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
13014 else
13015 { ... report and handle error
13016 break;
13017 }
13018 }
13019 else
13020 break;
13021 }
13022 ```
13023
13024 ## HTTP GET Support {#get}
13025
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.
13027
13028 The following example produces a Web page upon a HTTP GET request (e.g. from a browser):
13029
13030 ```cpp
13031 struct soap *soap = soap_new();
13032 soap->fget = http_get;
13033 ...
13034 soap_serve(soap);
13035 ...
13036 int http_get(struct soap *soap)
13037 {
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);
13041 return SOAP_OK;
13042 }
13043 ```
13044
13045 The example below produces a WSDL file upon a HTTP GET with path `?wsdl`:
13046
13047 ```cpp
13048 int http_get(struct soap *soap)
13049 {
13050 FILE *fd = NULL;
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
13055 if (!fd)
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);
13059 for (;;)
13060 {
13061 size_t r = fread(soap->tmpbuf, 1, sizeof(soap->tmpbuf), fd);
13062 if (!r)
13063 break;
13064 if (soap_send_raw(soap, soap->tmpbuf, r))
13065 break; // can't send, but little we can do about that
13066 }
13067 fclose(fd);
13068 soap_end_send(soap);
13069 return SOAP_OK;
13070 }
13071 ```
13072
13073 Using one-way SOAP/XML message, you can also return a SOAP/XML response:
13074
13075 ```cpp
13076 int http_get(struct soap *soap)
13077 {
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 ...);
13082 }
13083 ```
13084
13085 where `ns1__mySendMethodResponse` is a one-way message declared in a gSOAP header file as:
13086
13087 ```cpp
13088 int ns1__mySendMethodResponse(... params ..., void);
13089 ```
13090
13091 The generated `soapClient.cpp` includes the sending-side stub function.
13092
13093 ## TCP and HTTP Keep-Alive {#keepalive}
13094
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 .
13097 For example
13098
13099 ```cpp
13100 struct soap soap;
13101 soap_init2(&soap, SOAP_IO_KEEPALIVE, SOAP_IO_KEEPALIVE);
13102 ```
13103
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:
13110
13111 ```cpp
13112 signal(SIGPIPE, sigpipe_handle);
13113 ```
13114
13115 where, for example:
13116
13117 ```cpp
13118 void sigpipe_handle(int x) { }
13119 ```
13120
13121 Alternatively, broken pipes can be kept silent by setting:
13122
13123 ```cpp
13124 soap.socket_flags = MSG_NOSIGNAL;
13125 ```
13126
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.
13130
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.
13136
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:
13142
13143 ```cpp
13144 int main(int argc, char **argv)
13145 {
13146 struct soap soap, *tsoap;
13147 pthread_t tid;
13148 int m, s;
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
13153 if (m < 0)
13154 {
13155 soap_print_fault(&soap, stderr);
13156 exit(1);
13157 }
13158 fprintf(stderr, "Socket connection successful %d\n", m);
13159 for (count = 0; count >= 0; count++)
13160 {
13161 soap.socket_flags = MSG_NOSIGNAL; // use this
13162 soap.accept_flags = SO_NOSIGPIPE; // or this to prevent sigpipe
13163 s = soap_accept(&soap);
13164 if (s < 0)
13165 {
13166 if (soap.errnum)
13167 soap_print_fault(&soap, stderr);
13168 else
13169 fprintf(stderr, "Server timed out\n"); // Assume timeout is long enough for threads to complete serving requests
13170 break;
13171 }
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);
13175 }
13176 return 0;
13177 }
13178 void *process_request(void *soap)
13179 {
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);
13187 return NULL;
13188 }
13189 ```
13190
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.
13194
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.
13201
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.
13205
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.
13207
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
13212 that need it.
13213
13214 ## HTTP Chunked Transfer Encoding {#chunked}
13215
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.
13220
13221 ## HTTP Buffered Sends
13222
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.
13229
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.
13235
13236 ## HTTP Authentication
13237
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).
13242
13243 Here is an example client code fragment to set the HTTP authentication username and password:
13244
13245 ```cpp
13246 struct soap soap;
13247 soap_init(&soap);
13248 soap.userid = "guest";
13249 soap.passwd = "visit";
13250 ...
13251 ```
13252
13253 A client SOAP request will have the following HTTP header:
13254
13255 <div class="alt">
13256 ```xml
13257 POST /XXX HTTP/1.0
13258 Host: YYY
13259 User-Agent: gSOAP/2.2
13260 Content-Type: text/xml; charset=utf-8
13261 Content-Length: nnn
13262 Authorization: Basic Z3Vlc3Q6Z3Vlc3Q=
13263 ...
13264 ```
13265 </div>
13266
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.
13268
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.
13270
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).
13272
13273 Here is an example service method implementation that enforced client authentication:
13274
13275 ```cpp
13276 int ns__method(struct soap *soap, ...)
13277 {
13278 if (!soap->.userid || !soap->.passwd ||
13279 strcmp(soap->.userid, "guest") ||
13280 strcmp(soap->.passwd, "visit"))
13281 return 401;
13282 ...
13283 }
13284 ```
13285
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 .
13288
13289 ## HTTP NTLM Authentication
13290
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`.
13294
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
13300 information).
13301
13302 Here is an example client code fragment to set the NTLM authentication username and password:
13303
13304 ```cpp
13305 struct soap soap;
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, ...))
13313 ...
13314 ```
13315
13316 The following NTLM handshake between the client C and server S is performed:
13317
13318 <div class="alt">
13319 ```xml
13320 1: C --> S & POST ...
13321 & Content-Type: text/xml; charset=utf-8
13322
13323 2: C <-- S & 401 Unauthorized
13324 & WWW-Authenticate: NTLM
13325
13326 3: C --> S & GET ...
13327 & Authorization: NTLM <base64-encoded type-1-message>
13328
13329 4: C <-- S & 401 Unauthorized
13330 & WWW-Authenticate: NTLM <base64-encoded type-2-message>
13331
13332 5: C --> S & POST ...
13333 & Content-Type: text/xml; charset=utf-8
13334 & Authorization: NTLM <base64-encoded type-3-message>
13335
13336 6: C <-- S & 200 OK
13337 ```
13338 </div>
13339
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.
13344
13345 To avoid the overhead of the first rejected call, use:
13346
13347 ```cpp
13348 struct soap soap;
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, ...))
13355 ...
13356 ```
13357
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 .
13361
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.
13365
13366 ## HTTP Proxy NTLM Authentication
13367
13368 For HTTP 407 Proxy Authentication Required, set the proxy userid and passwd:
13369
13370 ```cpp
13371 struct soap soap;
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, ...))
13381 ...
13382 ```
13383
13384 To avoid the overhead of the first rejected call, use:
13385
13386 ```cpp
13387 struct soap soap;
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, ...))
13396 ...
13397 ```
13398
13399 ## HTTP Proxy Basic Authentication
13400
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:
13406
13407 ```cpp
13408 struct soap soap;
13409 soap_init(&soap);
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";
13414 ...
13415 ```
13416
13417 A client SOAP request will have the following HTTP header:
13418
13419 <div class="alt">
13420 ```xml
13421 POST /XXX HTTP/1.0
13422 Host: YYY
13423 User-Agent: gSOAP/2.2
13424 Content-Type: text/xml; charset=utf-8
13425 Content-Length: nnn
13426 Proxy-Authorization: Basic Z3Vlc3Q6Z3Vlc3Q=
13427 ...
13428 ```
13429 </div>
13430
13431 When X-Forwarded-For headers are returned by the proxy, the header can be accessed in the `soap.proxy_from` string.
13432
13433 The CONNECT method is used for HTTP proxy authentication:
13434
13435 <div class="alt">
13436 ```xml
13437 CONNECT server.example.com:80 HTTP/1.1
13438 ```
13439 </div>
13440
13441 In some cases, it may be necessary to use the Host HTTP header with the CONNECT
13442 protocol:
13443
13444 <div class="alt">
13445 ```xml
13446 CONNECT server.example.com:80 HTTP/1.1
13447 Host: server.example.com:80
13448 ```
13449 </div>
13450
13451 If so, compile the gSOAP code with `-DWITH_CONNECT_HOST` to include the
13452 Host HTTP header with the CONNECT protocol.
13453
13454 ## Messaging Speed and Performance Improvement Tips
13455
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:
13457
13458
13459 * Increase the buffer size `SOAP_BUFLEN` by changing the `SOAP_BUFLEN` macro in `stdsoap2.h`. Use buffer size 2^18=262144 for example.
13460
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.
13462
13463 * Use HTTP chunked transfers, see \ref chunked .
13464
13465 * Do NOT use gzip compression, since the overhead of compression is typically higher than the bandwidth gains.
13466
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).
13468
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.
13470
13471 * Do NOT use DEBUG mode, since the overhead of logging is significant.
13472
13473
13474 ## XML Parsing Options to set Safety Guards {#safety}
13475
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:
13477
13478
13479
13480 * `soap.maxlevel` is an `unsigned int` to restrict the XML nesting depth level, where the default value is `SOAP_MAXLEVEL=10000`.
13481
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`.
13483
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.
13485
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.
13487
13488 ## Timeout Management for Non-Blocking Operations {#timeout}
13489
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).
13498
13499 The `soap.connect_timeout` specifies the timeout for
13500 `soap_call_ns__method` calls.
13501
13502 The `soap.accept_timeout` specifies the timeout for
13503 `soap_accept(&soap)` calls.
13504
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.
13507
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.
13509
13510 Example:
13511
13512 ```cpp
13513 struct soap soap;
13514 soap_init(&soap);
13515 soap.send_timeout = 10;
13516 soap.recv_timeout = 10;
13517 soap.recv_timeout = 60;
13518 ```
13519
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:
13522
13523 ```cpp
13524 soap.send_timeout = 0;
13525 soap.recv_timeout = 0;
13526 soap.recv_timeout = 0;
13527 ```
13528
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:
13531
13532 ```cpp
13533 #define uSec *-1
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;
13539 ```
13540
13541 The macros improve readability.
13542
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.
13546
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`
13551 seconds total.
13552
13553 ## Socket Options and Flags
13554
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
13563 `setsockopt` for
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.
13570
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
13574 on your platform.
13575
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).
13578
13579 Note that multiple socket options can be explicitly set with `setsockopt` as follows:
13580
13581 ```cpp
13582 int sock = soap_bind(soap, host, port, backlog);
13583 if (soap_valid_socket(sock))
13584 {
13585 setsockopt(sock, ..., ..., ..., ...);
13586 setsockopt(sock, ..., ..., ..., ...);
13587 ```
13588
13589 ## Overriding the Host and Port to Connect
13590
13591 To override the host and port of the client connecting to a server, set `soap.override_host` and `soap.override_port`:
13592
13593 ```cpp
13594 soap.override_host = "example.com"; // host name or IP address
13595 soap.override_port = 80; // port number to use when overriding the address
13596 ```
13597
13598 ## Secure Web Services with HTTPS/SSL~ {#serveropenssl}
13599
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
13601 application.
13602 HTTPS/SSL support must be configured for the Web server (not CGI-based Web Service application itself).
13603
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:
13605
13606 > c++ -DWITH_OPENSSL -o myprog myprog.cpp stdsoap2.cpp soapC.cpp soapServer.cpp -lssl -lcrypto
13607
13608 With GNUTLS:
13609
13610 > c++ -DWITH_GNUTLS -o myprog myprog.cpp stdsoap2.cpp soapC.cpp soapServer.cpp -lgnutls -lgcrypt -lgpg-error
13611
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 .
13615
13616 Let's take a look at an example SSL secure
13617 multi-threaded stand-alone SOAP Web Service:
13618
13619 ```cpp
13620 int main()
13621 {
13622 int m, s;
13623 pthread_t tid;
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
13628 {
13629 fprintf(stderr, "Cannot setup thread mutex\n");
13630 exit(1);
13631 }
13632 soap_init(&soap);
13633 if (soap_ssl_server_context(&soap,
13634 SOAP_SSL_DEFAULT,
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) */
13642 ))
13643 {
13644 soap_print_fault(&soap, stderr);
13645 exit(1);
13646 }
13647 m = soap_bind(&soap, NULL, 18000, 100); // use port 18000
13648 if (m < 0)
13649 {
13650 soap_print_fault(&soap, stderr);
13651 exit(1);
13652 }
13653 fprintf(stderr, "Socket connection successful: master socket = %d\n", m);
13654 for (;;)
13655 {
13656 s = soap_accept(&soap);
13657 fprintf(stderr, "Socket connection successful: slave socket = %d\n", s);
13658 if (s < 0)
13659 {
13660 soap_print_fault(&soap, stderr);
13661 break;
13662 }
13663 tsoap = soap_copy(&soap); /* should call soap_ssl_accept on a copy */
13664 if (!tsoap)
13665 break;
13666 pthread_create(&tid, NULL, &process_request, (void*)tsoap);
13667 }
13668 soap_done(&soap); /* deallocates SSL context */
13669 CRYPTO_thread_cleanup(); // OpenSSL
13670 return 0;
13671 }
13672 void *process_request(void *soap)
13673 {
13674 pthread_detach(pthread_self());
13675 if (soap_ssl_accept((struct soap*)soap))
13676 soap_print_fault(tsoap, stderr);
13677 else
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
13682 return NULL;
13683 }
13684 ```
13685
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.
13687
13688 The GNUTLS mutex lock setup is automatically peformed in the gSOAP engine, but only when POSIX threads are detected and available.
13689
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.
13691
13692 We give a Windows and POSIX threads implementation of these here:
13693
13694 ```cpp
13695 #include <unistd.h> /* defines _POSIX_THREADS if pthreads are available */
13696 #ifdef _POSIX_THREADS
13697 # include <pthread.h>
13698 #endif
13699 #if defined(WIN32)
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()
13713 #else
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"
13716 #endif
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)
13720 {
13721 struct CRYPTO_dynlock_value *value;
13722 value = (struct CRYPTO_dynlock_value*)malloc(sizeof(struct CRYPTO_dynlock_value));
13723 if (value)
13724 MUTEX_SETUP(value->mutex);
13725 return value;
13726 }
13727 static void dyn_lock_function(int mode, struct CRYPTO_dynlock_value *l, const char *file, int line)
13728 {
13729 if (mode & CRYPTO_LOCK)
13730 MUTEX_LOCK(l->mutex);
13731 else
13732 MUTEX_UNLOCK(l->mutex);
13733 }
13734 static void dyn_destroy_function(struct CRYPTO_dynlock_value *l, const char *file, int line)
13735 {
13736 MUTEX_CLEANUP(l->mutex);
13737 free(l);
13738 }
13739 void locking_function(int mode, int n, const char *file, int line)
13740 {
13741 if (mode & CRYPTO_LOCK)
13742 MUTEX_LOCK(mutex_buf[n]);
13743 else
13744 MUTEX_UNLOCK(mutex_buf[n]);
13745 }
13746 unsigned long id_function()
13747 {
13748 return (unsigned long)THREAD_ID;
13749 }
13750 int CRYPTO_thread_setup()
13751 {
13752 int i;
13753 mutex_buf = (MUTEX_TYPE*)malloc(CRYPTO_num_locks() * sizeof(MUTEX_TYPE));
13754 if (!mutex_buf)
13755 return SOAP_EOM;
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);
13763 return SOAP_OK;
13764 }
13765 void CRYPTO_thread_cleanup()
13766 {
13767 int i;
13768 if (!mutex_buf)
13769 \return;
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]);
13777 free(mutex_buf);
13778 mutex_buf = NULL;
13779 }
13780 ```
13781
13782 For Unix and Linux, make sure you have signal handlers set in your service and/or client applications to catch broken connections (`SIGPIPE`):
13783
13784 ```cpp
13785 signal(SIGPIPE, sigpipe_handle);
13786 ```
13787
13788 where, for example:
13789
13790 ```cpp
13791 void sigpipe_handle(int x) { }
13792 ```
13793
13794 By default, clients are not required to authenticate. To support client authentication use the following:
13795
13796 ```cpp
13797 if (soap_ssl_server_context(&soap,
13798 SOAP_SSL_REQUIRE_CLIENT_AUTHENTICATION,
13799 "server.pem",
13800 "password",
13801 "cacert.pem",
13802 NULL,
13803 "dh512.pem",
13804 NULL,
13805 NULL))
13806 {
13807 soap_print_fault(&soap, stderr);
13808 exit(1);
13809 }
13810 ```
13811
13812 This requires each client to authenticate with its certificate.
13813
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`.
13815
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.
13821
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
13825 CAs.
13826
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.
13836
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.
13843
13844 ## Secure Clients with HTTPS/SSL {#clientopenssl}
13845
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:
13848
13849 > c++ -DWITH_OPENSSL myclient.cpp stdsoap.cpp soapC.cpp soapClient.cpp -lssl -lcrypto
13850
13851 or Unix:
13852
13853 > c++ -DWITH_OPENSSL myclient.cpp stdsoap.cpp soapC.cpp soapClient.cpp -lxnet -lsocket -lnsl -lssl -lcrypto
13854
13855 or you can add the following line to `soapdefs.h`:
13856
13857 ```cpp
13858 #define WITH_OPENSSL
13859 ```
13860
13861 and compile with option `-DWITH_SOAPDEFS_H` to include `soapdefs.h` in your project.
13862 Alternatively, compile with GNUTLS:
13863
13864 > c++ -DWITH_GNUTLS myclient.cpp stdsoap.cpp soapC.cpp soapClient.cpp -lgnutls -lgcrypt -lgpg-error
13865
13866
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:
13869
13870 ```cpp
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,
13874 SOAP_SSL_DEFAULT,
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 */
13880 ))
13881 {
13882 soap_print_fault(&soap, stderr);
13883 exit(1);
13884 }
13885 soap_call_ns__mymethod(&soap, "https://domain/path/secure.cgi", "", ...);
13886 ```
13887
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.
13895
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,
13897
13898 ```cpp
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 */
13910 ))
13911 {
13912 soap_print_fault(&soap, stderr);
13913 exit(1);
13914 }
13915 soap_call_ns__mymethod(&soap, "https://domain/path/secure.cgi", "", ...);
13916 ```
13917
13918 For systems based on Microsoft windows, the WinInet module can be used instead, see `mod_gsoap/gsoap_win/wininet`.
13919
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`.
13921
13922 To disable server authentication for testing purposes, use the following:
13923
13924 ```cpp
13925 if (soap_ssl_client_context(&soap,
13926 SOAP_SSL_NO_AUTHENTICATION,
13927 NULL,
13928 NULL,
13929 NULL,
13930 NULL,
13931 NULL
13932 ))
13933 {
13934 soap_print_fault(&soap, stderr);
13935 exit(1);
13936 }
13937 ```
13938
13939 This also assumes that the server does not require clients to authenticate (the keyfile is absent).
13940
13941 Make sure you have signal handlers set in your application to catch broken connections (`SIGPIPE`):
13942
13943 ```cpp
13944 signal(SIGPIPE, sigpipe_handle);
13945 ```
13946
13947 where, for example:
13948
13949 ```cpp
13950 void sigpipe_handle(int x) { }
13951 ```
13952
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.
13960
13961 ## SSL Authentication Callbacks
13962
13963 The `fsslauth` callback function controls OpenSSL/GNUTLS authentication initialization:
13964
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`
13970
13971 The `fsslverify` callback function controls OpenSSL peer certificate
13972 verification, via internally invoking `SSL_CTX_set_verify`:
13973
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.
13988
13989 ## SSL Certificates and Key Files {#ssl}
13990
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.
13998
13999 Althernatively, you can use the `plugin/cacerts.h` and
14000 `plugin/cacerts.c` code to embed CA certificates in your client code.
14001
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`.
14005
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.
14008
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
14014 test certificates.
14015
14016 It is possible to convert IIS-generated certificates to PEM format with the openssl library and openssl command-line tool:
14017
14018 ```cpp
14019 openssl x509 -in mycert.cer -inform DER -out mycert.pem -outform PEM
14020 ```
14021
14022 This converts the CRT-formatted mycert.cer to PEM-formatted mycert.pem.
14023
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.
14032
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.
14034
14035
14036 * Go to the OpenSSL bin directory (`/usr/local/ssl` by default and
14037 `/System/Library/OpenSSL` on Mac OS X)
14038
14039 * There should be a file called openssl.cnf
14040
14041 * Create a new directory in your home account, e.g. $HOME/CA, and copy the openssl.cnf file to this directory
14042
14043 * Modify openssl.cnf by changing the 'dir' value to HOME/CA
14044
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
14046
14047 * Follow the README.txt instructions
14048
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).
14051
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:
14054
14055
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.
14059
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:
14063
14064 > openssl dhparam -outform PEM -out dh.pem 512
14065
14066 File `dh512.pem` is the output file and 512 is the number of bits used.
14067
14068
14069 ## SSL Hardware Acceleration
14070
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:
14072
14073 ```cpp
14074 static const char *engine = "cswift"; /* engine name */
14075 int main()
14076 {
14077 ...
14078 ENGINE *e;
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);
14083 ...
14084 ```
14085
14086 The following table lists the names of the hardware and software engines:
14087
14088 engine | result
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
14099
14100 ## SSL on Windows
14101
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
14106 machine.
14107
14108 If you're using compilation settings such as `/MTd` then link to the correct `libeay32MTd.lib` and `ssleay32MTd.lib` libraries.
14109
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.
14111
14112 ## Zlib Compression {#compression}
14113
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.
14119
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.
14123
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
14131 gzip format.
14132
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:
14136
14137 ```cpp
14138 soap_init(&soap);
14139 ...
14140 soap_set_omode(&soap, SOAP_ENC_ZLIB); // enable Zlib's gzip
14141 if (soap_call_ns__myMethod(&soap, ...))
14142 ...
14143 soap_clr_omode(&soap, SOAP_ENC_ZLIB); // disable Zlib's gzip
14144 ...
14145 ```
14146
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.
14151
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
14153
14154 ```cpp
14155 soap_init(&soap);
14156 ...
14157 soap_set_omode(&soap, SOAP_ENC_ZLIB);
14158 soap.z_level = 9; // best compression
14159 ...
14160 ```
14161
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.
14163
14164 ```cpp
14165 soap_call_ns__myMethod(&soap, ...);
14166 ...
14167 printf("Compression ratio: %f%% (in) %f%% (out)\n", 100*soap.z_ratio_out, 100*soap.z_ratio_in);
14168 ...
14169 ```
14170
14171 Note: lower ratios mean higher compression rates.
14172
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.
14180
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.
14185
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.
14192
14193 ## Client-Side Cookie Support {#clientcookie}
14194
14195 Client-side cookie support is optional. To enable cookie support, compile all sources with option `-DWITH_COOKIES`, for example:
14196
14197 > c++ -DWITH_COOKIES -o myclient stdsoap2.cpp soapC.cpp soapClient.cpp
14198
14199 or add the following line to `stdsoap.h`:
14200
14201 ```cpp
14202 #define WITH_COOKIES
14203 ```
14204
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.
14207
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)`.
14213
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:
14217
14218 ```cpp
14219 struct soap soap;
14220 soap_init(&soap);
14221 soap.cookie_max = 10;
14222 ```
14223
14224 The cookie database is a linked list pointed to by `soap.cookies` where each node is declared as:
14225
14226 ```cpp
14227 struct soap_cookie
14228 {
14229 char *name;
14230 char *value;
14231 char *domain;
14232 char *path;
14233 long expire; /* client-side: local time to expire; server-side: seconds to expire */
14234 unsigned int version;
14235 short secure;
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;
14240 };
14241 ```
14242
14243 Since the cookie database is linked to a `soap` struct, each thread has a local cookie database in a multi-threaded
14244 implementation.
14245
14246 ## Server-Side Cookie Support {#servercookie}
14247
14248 Server-side cookie support is optional. To enable cookie support, compile all sources with option `-DWITH_COOKIES`, for example:
14249
14250 > c++ -DWITH_COOKIES -o myserver ...
14251
14252 gSOAP provides the following cookie API for server-side cookie session control:
14253
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.
14259
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.
14265
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.
14271
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.
14277
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.
14283
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`
14290 otherwise.
14291
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.
14297
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`.
14302
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.
14307
14308 * `void soap_free_cookies(struct soap *soap);`
14309 Release cookie database.
14310
14311 The following global variables are used to define the current domain and path:
14312
14313 * `const char *cookie_domain` MUST be set to the domain (host) of the service
14314
14315 * `const char *cookie_path` MAY be set to the default path to the service
14316
14317 * `int cookie_max` maximum cookie database size (default=32)
14318
14319 The `cookie_path` value is used to filter cookies intended for this service according to the path prefix rules outlined in
14320 RFC2109.
14321
14322 The following example server adopts cookies for session control:
14323
14324 ```cpp
14325 int main()
14326 {
14327 struct soap soap;
14328 int m, s;
14329 soap_init(&soap);
14330 soap.cookie_domain = "...";
14331 soap.cookie_path = "/"; // the path which is used to filter/set cookies with this destination
14332 if (argc < 2)
14333 {
14334 soap_getenv_cookies(&soap); // CGI app: grab cookies from 'HTTP_COOKIE' env var
14335 soap_serve(&soap);
14336 }
14337 else
14338 {
14339 m = soap_bind(&soap, NULL, atoi(argv[1]), 100);
14340 if (m < 0)
14341 exit(1);
14342 for (int i = 1; ; i++)
14343 {
14344 s = soap_accept(&soap);
14345 if (s < 0)
14346 exit(1);
14347 soap_serve(&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
14350 }
14351 }
14352 return 0;
14353 }
14354 int ck__demo(struct soap *soap, ...)
14355 {
14356 int n;
14357 const char *s;
14358 s = soap_cookie_value(soap, "demo", NULL, NULL); // cookie returned by client?
14359 if (!s)
14360 s = "init-value"; // no: set initial cookie value
14361 else
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
14365 return SOAP_OK;
14366 }
14367 ```
14368
14369 ## Connecting Clients Through Proxy Servers
14370
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:
14373
14374 ```cpp
14375 struct soap soap;
14376 soap_init(&soap);
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);
14381 else
14382 ...
14383 ```
14384
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.
14387
14388 When X-Forwarded-For headers are returned by the proxy, the header can be accessed in the `soap.proxy_from` string.
14389
14390 ## Bind Before Connect and Setting the Client Interface Address
14391
14392 To bind the client to a port before connect, set the `soap.client_port` to a non-negative port number:
14393
14394 ```cpp
14395 struct soap soap;
14396 soap_init(&soap);
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);
14400 else
14401 ...
14402 ```
14403
14404 This port number is used only once and reset to -1 (disabled). Set it again for the next call.
14405
14406 To set a client interface address for the connection that is an IP address of the client:
14407
14408 ```cpp
14409 struct soap soap;
14410 soap_init(&soap);
14411 soap.client_interface = "..."; // IP address
14412 if (soap_call_ns__method(&soap, "http://host:port/path", "action", ...))
14413 soap_print_fault(&soap, stderr);
14414 else
14415 ...
14416 ```
14417
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.
14419
14420 ## FastCGI Support {#fastcgi}
14421
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
14425
14426 ```cpp
14427 #define WITH_FASTCGI
14428 ```
14429
14430 to `stdsoap2.h` and recompile the project code.
14431
14432 @warning Do not link against the `libgsoap` libraries as these are not
14433 suitable for FastCGI. Compile `stdsoap2.c` (or `stdsoap2.cpp`) instead.
14434
14435 ## How to Create gSOAP Applications With a Small Memory Footprint {#lean}
14436
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:
14441
14442
14443 * No I/O timeouts. Note that many socket operations already obey some form of timeout handling, such as a connect timeout for example.
14444
14445 * No UDP support
14446
14447 * No HTTP keep alive
14448
14449 * No HTTP cookies
14450
14451 * No HTTP authentication
14452
14453 * No HTTP chunked output (but input is OK)
14454
14455 * No HTTP compressed output (but input is OK when compiled with `WITH_GZIP`)
14456
14457 * No send/recv timeouts
14458
14459 * No socket flags (no `soap.socket_flag, soap.connect_flag, soap.bind_flag, soap.accept_flag`)
14460
14461 * No canonical XML output
14462
14463 * No logging
14464
14465 * Limited TCP/IP and HTTP error diagnostic messages
14466
14467 * No support for `time_t` serialization
14468
14469 * No support for `hexBinary` XML attribute serialization (remap `hexBinary` to strings by adding a remap entry to typemap.dat)
14470
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
14478 content.
14479
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.
14484
14485 ## How to Eliminate BSD Socket Library Linkage {#noio}
14486
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`.
14488
14489 As a consequence, you MUST define callbacks to replace the missing socket stack. To do so, add to your code the following definitions:
14490
14491 ```cpp
14492 struct soap soap;
14493 soap_init(&soap);
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;
14510 ```
14511
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`.
14515
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.
14517
14518 ## How to Combine Multiple Client and Server Implementations into one Executable
14519
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 .
14527
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`.
14532
14533 Both approaches are demonstrated by example in the gSOAP distribution, the `samples/link` (C only) and `samples/link++` (C++ with C++ namespaces) examples.
14534
14535 ## How to Build a Client or Server in a C++ Code Namespace {#codenamespace}
14536
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).
14542
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`.
14544
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:
14547
14548 ```cpp
14549 namespace myNamespaceName {
14550 ... gSOAP header file contents ...
14551 }
14552 ```
14553
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).
14565
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:
14574
14575 > soapcpp2 -penv env.h
14576
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.
14579
14580 ## How to Create Client/Server Libraries {#dylibs}
14581
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 .
14592
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.
14594
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 .
14603
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
14609 with:
14610
14611 > soapcpp2 -penv env.h
14612
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.
14615
14616 You MUST compile the `stdsoap2.cpp` library using `-DWITH_NONAMESPACES`:
14617
14618 > c++ -DWITH_NONAMESPACES -c stdsoap2.cpp
14619
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.
14623
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:
14625
14626 > soapcpp2 -c -penv env.h
14627
14628 Then we generate the code for client1 and client2:
14629
14630 > soapcpp2 -c -n -pmyClient1 client1.h
14631 > soapcpp2 -c -n -pmyClient2 client2.h
14632
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:
14636
14637 ```cpp
14638 #include "myClient1H.h" // include client 1 stubs
14639 #include "myClient2H.h" // include client 2 stubs
14640 #include "envH.h"
14641 ...
14642 #include "myClient1H.nsmap" // include client 1 nsmap
14643 #include "myClient2H.nsmap" // include client 2 nsmap
14644 ...
14645 soap_init(&soap);
14646 soap_set_namespaces(&soap, myClient1_namespaces);
14647 ... make Client 1 invocations ...
14648 ...
14649 soap_set_namespaces(&soap, myClient2_namespaces);
14650 ... make Client 2 invocations ...
14651 ```
14652
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.
14654
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.
14658
14659 ### C++ Clients Example
14660
14661 As an example we will build a Delayed Stock Quote client library and a Currency Exchange Rate client library.
14662
14663 First, we create an empty header file `env.h` (which may contain optional SOAP Header and Fault definitions), and compile it as follows:
14664
14665 > soapcpp2 -penv env.h
14666 > c++ -c envC.cpp
14667
14668 We also compile `stdsoap2.cpp` without namespaces:
14669
14670 > c++ -c -DWITH_NONAMESPACES stdsoap2.cpp
14671
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`.
14673
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:
14675
14676 ```cpp
14677 namespace quote {
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);
14685 }
14686 ```
14687
14688 We then compile it as a library and we use option `-n` to rename the namespace table to avoid link conflicts later:
14689
14690 > soapcpp2 -n quote.h
14691 > c++ -c quoteClientLib.cpp
14692
14693 If you don't want to use a C++ code namespace, you should compile `quote.h` "as is" with soapcpp2 option `-pquote`:
14694
14695 > soapcpp2 -n -pquote quote.h
14696 > c++ -c quoteClientLib.cpp
14697
14698 Third, we create the Currency Exchange Rate header file specification:
14699
14700 ```cpp
14701 namespace rate {
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);
14709 }
14710 ```
14711
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:
14713
14714 > soapcpp2 -n rate.h
14715
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).
14719
14720 ```cpp
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[])
14726 {
14727 if (argc <= 1)
14728 {
14729 std::cerr << "Usage: main ticker [currency]" << std::endl
14730 exit(0);
14731 }
14732 quote::Service quote;
14733 float q;
14734 if (quote.getQuote(argv[1], q)) // get quote
14735 soap_print_fault(quote.soap, stderr);
14736 else
14737 {
14738 if (argc > 2)
14739 {
14740 rate::Service rate;
14741 float r;
14742 if (rate.getRate("us", argv[2], r)) // get rate in US dollars
14743 soap_print_fault(rate.soap, stderr);
14744 else
14745 q *= r; // convert the quote
14746 }
14747 std::cout << argv[1] << ": " << q << std::endl;
14748 }
14749 return 0;
14750 }
14751 ```
14752
14753 Compile and link this application with `stdsoap2.o`, `envC.o`, `quoteServerProxy.o`, and `rateServerProxy.o`.
14754
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.
14756
14757 ```cpp
14758 namespace calc {
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);
14768 }
14769 ```
14770
14771 We compile this with:
14772
14773 > soapcpp2 -n calc.h
14774
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.
14776
14777 ```cpp
14778 #include "calcServiceObject.h" // get Service object
14779 #include "calc.nsmap" // get calc namespace bindings
14780 ...
14781 calc::Service calc;
14782 calc.serve(); // calls request dispatcher to invoke one of the functions below
14783 ...
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; }
14792 ```
14793
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
14796 context.
14797
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 .
14799
14800 ### C Clients Example
14801
14802 This is the same example as above, but the clients are build with pure C.
14803
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:
14807
14808 > soapcpp2 -c -penv env.h
14809 > cc -c envC.c
14810
14811 We also compile `stdsoap2.c` without namespaces:
14812
14813 > cc -c -DWITH_NONAMESPACES stdsoap2.c
14814
14815 Second, we create the Delayed Stock Quote header file specification, which may be obtained using the WSDL importer.
14816
14817 ```cpp
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);
14825 ```
14826
14827 We compile it as a library and we use options `-n` and `-p` to rename the namespace table to avoid link conflicts:
14828
14829 > soapcpp2 -c -n -pquote quote.h
14830 > cc -c quoteClientLib.c
14831
14832 Third, we create the Currency Exchange Rate header file specification:
14833
14834 ```cpp
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);
14842 ```
14843
14844 We compile it as a library and we use options `-n` and `-p` to rename the namespace table to avoid link conflicts:
14845
14846 > soapcpp2 -c -n -prate rate.h
14847 > cc -c rateClientLib.c
14848
14849 The main program is:
14850
14851 ```cpp
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[])
14857 {
14858 if (argc <= 1)
14859 {
14860 fprintf(stderr, "Usage: main ticker [currency]\n");
14861 exit(0);
14862 }
14863 struct soap soap;
14864 float q;
14865 soap_init(&soap);
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);
14869 else
14870 {
14871 if (argc > 2)
14872 {
14873 soap_set_namespaces(&soap, rate_namespaces);
14874 float r;
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);
14877 else
14878 q *= r; // convert the quote
14879 }
14880 printf("%s: %f \n", argv[1], q);
14881 }
14882 return 0;
14883 }
14884 ```
14885
14886 Compile and link this application with `stdsoap2.o`, `envC.o`, `quoteClientLib.o`, and `rateClientLib.o`.
14887
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.
14889
14890 ### C Services Chaining Example
14891
14892 We build a C application for multiple services served on one port.
14893
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:
14897
14898 > soapcpp2 -c -penv env.h
14899 > cc -c envC.c
14900
14901 We also compile `stdsoap2.c` without namespaces:
14902
14903 > cc -c -DWITH_NONAMESPACES stdsoap2.c
14904
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:
14906
14907 > soapcpp2 -c -n -pquote quote.h
14908 > cc -c quoteClientLib.c
14909
14910 We do the same for a service definition in `rate.h`:
14911
14912 > soapcpp2 -c -n -prate rate.h
14913 > cc -c rateClientLib.c
14914
14915 To serve both the quote and rate services on the same port, we chain the service dispatchers as follows:
14916
14917 ```cpp
14918 struct soap *soap = soap_new();
14919 soap_bind(soap, NULL, 8080, 100);
14920 soap_accept(soap);
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)
14924 {
14925 if (rate_serve_request(soap))
14926 soap_send_fault(soap); // send fault to client
14927 }
14928 else if (soap.error)
14929 soap_send_fault(soap); // send fault to client
14930 soap_destroy(soap);
14931 soap_end(soap);
14932 soap_free(soap);
14933 ```
14934
14935 This chaining can be arbitrarily deep. When the previous request fails with a `SOAP_NO_METHOD` then next request dispatcher can be tried.
14936
14937 The server should also define the service operations:
14938
14939 ```cpp
14940 int ns__getQuote(struct soap *soap, char *symbol, float *Result);
14941 { *Result = ... ;
14942 return SOAP_OK;
14943 }
14944 int ns__getRate(struct soap *soap, char *country1, char *country2, float *Result);
14945 { *Result = ... ;
14946 return SOAP_OK;
14947 }
14948 ```
14949
14950 ## How to Create DLLs {#dll}
14951
14952 ### Create the Base stdsoap2.dll
14953
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:
14957
14958 > soapcpp2 -penv env.h
14959
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.
14961
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:
14968
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
14971
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`.
14973
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.
14978
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.
14983
14984 ### Creating Client and Server DLLs
14985
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).
14988
14989 This DLL links to `stdsoap2.dll`.
14990
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 .
14996
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:
14998
14999 ```cpp
15000 soap_init(&soap);
15001 soap_set_namespaces(&soap, namespaces);
15002 ```
15003
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 .
15005
15006 ## gSOAP Plug-ins {#plugins}
15007
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:
15017
15018 ```cpp
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*);
15021 ```
15022
15023 Other functions that deal with plug-ins are:
15024
15025 ```cpp
15026 int soap_copy(struct soap *soap);
15027 void soap_done(struct soap *soap);
15028 ```
15029
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.
15037
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).
15041
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:
15044
15045 ```cpp
15046 #include "stdsoap2.h"
15047 #define PLUGIN_ID "PLUGIN-1.0" // some name to identify plugin
15048 struct plugin_data // local plugin data
15049 {
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
15052 };
15053 int plugin(struct soap *soap, struct soap_plugin *plugin, void *arg);
15054 ```
15055
15056 Then, we write the plugin registry function and the callbacks:
15057
15058 ```cpp
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)
15068 {
15069 p->id = plugin_id;
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;
15073 if (p->data)
15074 if (plugin_init(soap, (struct plugin_data*)p->data))
15075 {
15076 free(p->data); // error: could not init
15077 return SOAP_EOM; // return error
15078 }
15079 return SOAP_OK;
15080 }
15081 static int plugin_init(struct soap *soap, struct plugin_data *data)
15082 {
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
15087 return SOAP_OK;
15088 }
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)
15092 {
15093 if (!(dst->data = (struct plugin_data*)malloc(sizeof(struct plugin_data))))
15094 return SOAP_EOM;
15095 *dst->data = *src->data;
15096 return SOAP_OK;
15097 }
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
15101 }
15102 // the new send callback
15103 static int plugin_send(struct soap *soap, const char *buf, size_t len)
15104 {
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
15108 }
15109 // the new receive callback
15110 static size_t plugin_recv(struct soap *soap, char *buf, size_t len)
15111 {
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);
15115 return res;
15116 }
15117 ```
15118
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.
15122
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
15125 or not:
15126
15127
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.
15131
15132 *
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.
15138
15139 The example plug-in should be used as follows:
15140
15141 ```cpp
15142 struct soap soap;
15143 soap_init(&soap);
15144 soap_register_plugin(&soap, plugin);
15145 ...
15146 soap_done(&soap);
15147 ```
15148
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.
15152
15153 A number of example plug-ins are included in the gSOAP package's `plugin` directory. Some of these plug-ins are discussed.
15154
15155 ### The Message Logging and Statistics Plug-in
15156
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.
15158
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:
15161
15162 ```cpp
15163 #include "logging.h"
15164 size_t bytes_in;
15165 size_t bytes_out;
15166 ...
15167 if (soap_register_plugin(&soap, logging))
15168 soap_print_fault(&soap, stderr); // failed to register
15169 ...
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);
15176 ```
15177
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.
15180
15181 ### RESTful Client-Side API
15182
15183 The soapcpp2 tool generates the following functions for client-side REST operations:
15184
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.
15187
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.
15190
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.
15193
15194 `soap_POST_recv_`*Name*`(struct soap *soap, `*Type*`* data)`
15195 REST POST receive XML of type *Type* after REST POST send.
15196
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.
15199
15200 ### RESTful Server-Side API: The HTTP GET Plug-in
15201
15202 Server-side use of RESTful HTTP GET operations is supported with the HTTP GET
15203 plug-in `plugin/httpget.c`.
15204
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.
15208
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.
15214
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:
15217
15218 ```cpp
15219 #include "httpget.h"
15220 ...
15221 if (soap_register_plugin_arg(&soap, httpget, (void*)my_http_get_handler))
15222 soap_print_fault(&soap, stderr); // failed to register
15223 ...
15224 struct http_get_data *httpgetdata;
15225 httpgetdata = (struct http_get_data*)soap_lookup_plugin(&soap, http_get_id);
15226 if (!httpgetdata)
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;
15232 ...
15233 time_t now = time(NULL);
15234 struct tm *T;
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];
15239 ```
15240
15241 An HTTP GET handler can simply produce some HTML content, or any other type of content by sending data:
15242
15243 ```cpp
15244 int my_http_get_handler(struct *soap)
15245 {
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
15251 }
15252 ```
15253
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.
15256
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:
15258
15259 ```cpp
15260 #include "httpget.h"
15261 ...
15262 soap_register_plugin(&soap, http_get);
15263 ...
15264 if (soap_get_connect(&soap, endpoint, action))
15265 ... connect error ...
15266 else if (soap_recv_ns__methodResponse(&soap, ... params ...))
15267 ... error ...
15268 else
15269 ... ok ...
15270 soap_destroy(&soap);
15271 soap_end(&soap);
15272 soap_done(&soap);
15273 ```
15274
15275 To receive any HTTP Body data into a buffer, use:
15276
15277 ```cpp
15278 #include "httpget.h"
15279 ...
15280 char *response = NULL;
15281 soap_register_plugin(&soap, http_get);
15282 ...
15283 if (soap_get_connect(&soap, endpoint, NULL))
15284 ... connect error ...
15285 else if (soap_begin_recv(&soap))
15286 ... error ...
15287 else
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);
15292 soap_end(&soap);
15293 soap_done(&soap);
15294 ```
15295
15296 ### RESTful Server-Side API: The HTTP POST Plug-in
15297
15298 Server-side use of RESTful HTTP POST, PUT, and DELETE operations are supported
15299 with the HTTP POST plug-in `plugin/httppost.c`.
15300
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
15304 server.
15305
15306 To simplify the server-side handling of POST requests, handlers can be associated with media types:
15307
15308 ```cpp
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 },
15318 { NULL }
15319 };
15320 ```
15321
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
15325 server.
15326
15327 An example image handler that checks the specific image type:
15328
15329 ```cpp
15330 int image_handler(struct soap *soap)
15331 { const char *buf;
15332 size_t len;
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);
15342 return SOAP_OK;
15343 }
15344 ```
15345
15346 The HTTP POST plug-in provides a `soap_http_body` operation as illustrated above to copy the HTTP Body content into a buffer.
15347
15348 The above example returns HTTP OK. If content is supposed to be returned, then use:
15349
15350 ```cpp
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);
15355 ```
15356
15357 For client applications to use HTTP POST, use the `soap_post_connect` operation:
15358
15359 ```cpp
15360 char *buf; // holds the HTTP request/response body data
15361 size_t len; // length of data
15362 ...
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))
15366 ... error ...
15367 if (soap_begin_recv(&soap)
15368 || soap_http_body(&soap, &buf, &len)
15369 || soap_end_recv(&soap))
15370 ... error ...
15371 // ... use buf[0..len-1]
15372 soap_end(soap);
15373 ```
15374
15375 Similarly, `soap_put_connect` and `soap_delete_connect` commands are provided for PUT and DELETE handling.
15376
15377 ### The HTTP MD5 Checksum Plug-in
15378
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.
15383
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`).
15385
15386 To enable the plug-in in your code, register the plug-in as follows:
15387
15388 ```cpp
15389 #include "httpmd5.h"
15390 ...
15391 if (soap_register_plugin(&soap, http_md5))
15392 soap_print_fault(&soap, stderr); // failed to register
15393 ```
15394
15395 Once registered, MD5 checksums are produced for all outbound messages. Inbound messages with MD5 checksums in the HTTP header are automatically verified.
15396
15397 The plug-in requires you to set the `SOAP_IO_STORE` flag when sending SOAP with attachments:
15398
15399 ```cpp
15400 #include "httpmd5.h"
15401 ...
15402 struct soap soap;
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 ...
15407 ```
15408
15409 Unfortunately, this eliminates streaming.
15410
15411 ### The HTTP Digest Authentication Plug-in
15412
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
15418 RFC 2617.
15419
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.
15428
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.
15434
15435 Client-side example:
15436
15437 ```cpp
15438 #include "httpda.h"
15439 ...
15440 if soap_register_plugin(&soap, http_da))
15441 soap_print_fault(&soap, stderr); // failed to register
15442 ...
15443 if (soap_call_ns__method(&soap, ...) != SOAP_OK)
15444 {
15445 if (soap.error == 401) // challenge: HTTP authentication required
15446 {
15447 if (!strcmp(soap.authrealm, authrealm)) // determine authentication realm
15448 {
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
15452 { ...
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
15456 ...
15457 http_da_release(&soap, &info); // remove userid and passwd
15458 ```
15459
15460 This code supports both basic and digest authentication.
15461
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.
15463
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:
15470
15471 ```cpp
15472 #include "httpda.h"
15473 ...
15474 if (soap_register_plugin(&soap, http_da))
15475 soap_print_fault(&soap, stderr); // failed to register
15476 ...
15477 soap_serve(&soap);
15478 ...
15479 int ns__method(struct soap *soap, ...)
15480 {
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 ...
15485 return SOAP_OK;
15486 }
15487 }
15488 else if (soap->authrealm && soap->userid) // Digest authentication
15489 {
15490 passwd = ... // database lookup on userid and authrealm to find passwd
15491 if (!strcmp(soap->authrealm, authrealm) && !strcmp(soap->userid, userid))
15492 {
15493 if (!http_da_verify_post(soap, passwd))
15494 { ... handle request ...
15495 return SOAP_OK;
15496 }
15497 }
15498 }
15499 soap->authrealm = authrealm; // set realm for challenge
15500 return 401; // Not authorized, challenge digest authentication
15501 }
15502 ```
15503
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.
15506
15507 ### The WS-Addressing Plug-in
15508
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.
15512
15513 The plug-in code is located in the `plugin` directory containing
15514 `wsaapi.h` and `wsaapi.c` (C and C++).
15515
15516 To enable WS-Addressing 2005 (and support for 8/2004), the service definitions header file for `soapcpp2` should include the following imports:
15517
15518 ```cpp
15519 #import "import/wsa5.h"
15520 ```
15521
15522 This imports the SOAP header elements required by WS-Addressing.
15523
15524 For more details, please see the `doc/wsa/html/index.html` documentation in the gSOAP package.
15525
15526 ### The WS-ReliableMessaging Plug-in
15527
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.
15531
15532 The plug-in code is located in the `plugin` directory containing `wsrmapi.h` and `wsrmapi.c` (C and C++).
15533
15534 Also needed are: `threads.h` and `threads.c` for multithreading and locking support.
15535
15536 To enable WS-ReliableMessaging, the service definitions header file for `soapcpp2` should include the following imports:
15537
15538 ```cpp
15539 #import "import/wsrm.h"
15540 #import "import/wsa5.h"
15541 ```
15542
15543 This imports the SOAP header elements required by WS-ReliableMessaging.
15544
15545 For more details, please see the `doc/wsrm/html/index.html` documentation in the gSOAP package.
15546
15547 ### The WS-Security Plug-in
15548
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.
15552
15553 The plug-in code is located in the `plugin` directory containing `wsseapi.h` and `wsseapi.c` (C and C++).
15554
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.
15557
15558 To enable WS-Secrutiy, the service definitions header file for `soapcpp2` should include the following imports:
15559
15560 ```cpp
15561 #import "import/wsse.h"
15562 ```
15563
15564 This imports the SOAP header elements required by WS-Security.
15565
15566 For more details, please see the `doc/wsse/html/index.html` documentation in the gSOAP package.
15567
15568 ### WS-Discovery
15569
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
15572 for details.
15573
15574 Basically, to add WS-Discovery support the following event handlers must be
15575 defined and linked:
15576
15577 ```cpp
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,
15585 const char *Types,
15586 const char *Scopes,
15587 const char *MatchBy,
15588 const char *XAddrs,
15589 unsigned int MetadataVersion)
15590 ```
15591
15592 ```cpp
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,
15600 const char *Types,
15601 const char *Scopes,
15602 const char *MatchBy,
15603 const char *XAddrs,
15604 unsigned int MetadataVersion)
15605 ```
15606
15607 ```cpp
15608 soap_wsdd_mode wsdd_event_Probe(struct soap *soap,
15609 const char *MessageID,
15610 const char *ReplyTo,
15611 const char *Types,
15612 const char *Scopes,
15613 const char *MatchBy,
15614 struct wsdd__ProbeMatchesType *ProbeMatches)
15615 ```
15616
15617 ```cpp
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)
15625 ```
15626
15627 ```cpp
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)
15633 ```
15634
15635 ```cpp
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,
15643 const char *Types,
15644 const char *Scopes,
15645 const char *MatchBy,
15646 const char *XAddrs,
15647 unsigned int MetadataVersion)
15648 ```
15649
15650 These event handlers will be invoked when inbound WS-Discovery messages arrive using:
15651
15652 ```cpp
15653 if (!soap_valid_socket(soap_bind(soap, NULL, port, 100)))
15654 .. error
15655 if (soap_wsdd_listen(soap, timeout))
15656 ... error
15657 ```
15658
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
15661 in ns.
15662
15663 Copyright (c) 2017, Robert van Engelen, Genivia Inc. All rights reserved.