How to report bugs and patches and get help
---
### Commercial edition users
You are entitled to our timely expert professional support. Please [submit a ticket](inquire/support.php) or [contact us](contact.html) for more details about technical support services offered by Genivia.
### Open source users
Report bugs or ask for support by visiting the [SourceForge gSOAP bug tracker](https://sourceforge.net/p/gsoap2/bugs/) and [SourceForge gSOAP support tracker.](https://sourceforge.net/p/gsoap2/support-requests/) We monitor these trackers and you can receive status updates as the issues are addressed over time.
Where can I find commercial licensing and technical support for gSOAP?
---
Please [contact us](contact.html) for licensing and technical support inquiries.
Where can I find the fact sheet and gSOAP documentation?
---
The gSOAP [toolkit fact sheet.](factsheet.pdf)
Read the gSOAP [documentation.](docs.html)
Where can I find mailing lists and public discussion forums about gSOAP?
---
[Subscribe](https://eepurl.com/cW6GT1) to receive email notifications with important updates about Genivia software and related developments.
Visit [StackOverflow gSOAP tagged questions and answers.](https://stackoverflow.com/questions/tagged/gsoap)
Visit and join the new [gsoap@groups.io](https://groups.io/g/gsoap) for technical discussions and help.
Visit the old gSOAP [mailing list at Yahoo! groups.](https://groups.yahoo.com/neo/groups/gsoap/info) This list is inactive as Yahoo! no longer hosts user created content.
Which software license is applicable when I use gSOAP?
---
Genivia is pleased to offer the gSOAP software with the GNU GPLv2 license. A commercial end-user license agreement is available from Genivia upon request. The commercial end-user license agreement is a royalty-free software development license for the gSOAP toolkit with limited warranties and optional professional technical support and maintenance.
Please note that the terms and conditions required by the GNU GPLv2 license of the **open source version of gSOAP** (available from SourceForge etc.) may not be compatible with your commercial end product's licensing and use. The GPLv2 open source license permits selling copies of your end product commercially developed with gSOAP **but only under the terms of the GNU GPLv2**. This means that you must make the source code of your end product available and you permit users to redistribute and modify the end product source code as described in the GPLv2. These requirements are the condition for including the GPL-covered code you received in a program of your own. The GPL v2 requirements may hamper certain proprietary software development scenarios. If you do not wish for your program to be released under the GPL (or under a GPL-compatible open source license), then contact Genivia to inquire about commercial licensing.
Genivia offers a **commercial version of gSOAP with a commercial end-user license agreement (EULA)** that removes the GNU GPLv2 requirements, so that your end products will always remain closed. Please [contact Genivia](contact.html) for more details.
Notes:
1. Genivia owns the copyright of its software and does not accept or include any third-party GPL code that is incompatible with its proprietary (closed source) licensing terms.
2. The gSOAP public license (derived from the MPL1.1 license) only covers the gSOAP runtime engine, the engine plug-ins, and the Apache and IIS modules.
3. The GNU Bison and Flex tools are used to generate source code for the soapcpp2 tool. The Bison/Flex-generated source code is not restricted by the GPL or LGPL terms.
4. Non-GPL third-party contributions are included in the `gsoap/extras` directory in the package and you are always free to use these contributions.
Why should I use gSOAP?
---
### Comprehensive XML data binding
The gSOAP toolkit offers [XML data binding tools](doc/databinding/html/index.html) for C and C++. The tools allow developers to write clean and type-safe code to manipulate large and complex XML-sourced data sets. You can serialize your C/C++ data in XML trees and **(cyclic) C/C++ structure-preserving** XML id-ref graphs. To understand what makes gSOAP tick, please see our [introduction to XML data bindings.](#bindings)
### Portable
The toolkit generates portable C and C++ source code for C90 and up (C++11 etc.). The software runs on a wide range of OS platforms, including Windows Win32/Win64 (XP, Vista, Windows 7/8/10), MS-DOS, Cygwin, MinGW, Linux (RedHat, SuSE, etc.), Mac OS X, Solaris, HP-UX, BSD, FreeBSD, Irix, QNX, AIX, TRU64, OpenVMS, NonStop Tandem, VxWorks, WinCE, Palm OS, Symbian, iOS, Raspberry Pi, and embedded systems/RTOS. See also our [gSOAP fact sheet.](factsheet.pdf)
### Fast
The toolkit generates efficient code to implement low-overhead Web services and fast client proxies. The serializers push and retrieve XML directly to and from sockets without the overhead of HTTP and XML stacks.
### Standardized
The toolkit meets W3C and OASIS standards requirements for WSDL, XSD, SOAP, RESTful XML, WS-I Basic and Security Profiles, WS-Policy, WS-SecurityPolicy, WS-Security, WS-Addressing, WS-ReliableMessaging, WS-Discovery, and passes W3C Databinding interoperability tests. The toolkit also includes libraries for [XML-RPC and JSON.](doc/xml-rpc-json/html/index.html)
### Interoperable
Applications developed with gSOAP interoperate with other SOAP and RESTful XML stacks such as .NET WCF, Axis, PHP5, SOAP::Lite, SOAP4R, Weblogic, ZSI and many others. Further, XML data binding enables interoperable XML data processing in non-SOAP/REST environments.
### Widely deployable
Services developed with gSOAP can be deployed with CGI/FastCGI and with the built-in fast HTTP/S stack. We recommend to use our [Apache](doc/apache/html/index.html) and [IIS](doc/isapi/html/index.html) modules for production-quality service deployment.
### Legacy reusable
The toolkit can be leveraged for SaaS deployment of legacy C and C++ systems. All of the necessary gluing code and WSDL service descriptions are auto-generated.
### Stable
The software is stable and mature, and is used for several years by companies world-wide to develop software products and services. Companies include the top 15 technology companies and most of the Fortune 500.
### Licensing
[Contact Genivia](contact.html) to obtain commercial-use licenses. Otherwise, open source GPLv2 licensing is applicable to your project. For details, [please read this.](products.html#gsoap)
What is the history of gSOAP?
---
The gSOAP toolkit was first introduced in 1999 as a research project at the Florida State University for generic XML communications by establishing a type-safe data binding between XML schema types and C/C++ data types through automatic programming. A domain-specific C compiler tool was developed to generate source code that efficiently converts native C data structures to XML and back. The toolkit was further developed to support the SOAP web services messaging protocol, introduced at around the same time, hence the name "gSOAP" (generic XML and SOAP). Further development took place under ownership of Genivia Incorporated, which included the addition of new WSDL and XML schema processing capabilities in 2003 as well as the addition of WS-* Web services protocol capabilities, XML-RPC messaging, JSON, a stand-alone web server, and much more.
See also [gSOAP on Wikipedia.](https://en.wikipedia.org/wiki/GSOAP)
Where can I find examples of gSOAP?
---
See [getting started](dev.html) to begin using gSOAP and see the [examples.](examples/calc/index.html)
See our [tutorials.](tutorials.html)
Many examples are included in the gSOAP package in `gsoap/samples`.
Where can I find and cite technical articles about gSOAP?
---
**We recommend citing the following paper(s) when referencing technical papers on gSOAP:**
*[The gSOAP Toolkit for Web Services and Peer-To-Peer Computing Networks](https://www.cs.fsu.edu/~engelen/ccgrid.pdf)* by Robert A. van Engelen and Kyle Gallivan, in the proceedings of the 2nd IEEE International Symposium on Cluster Computing and the Grid (CCGrid 2002), pages 128-135, May 21-24, 2002, Berlin, Germany.
*[A Framework for Service-Oriented Computing with C and C++ Web Service Components](https://portal.acm.org/citation.cfm?id=1361188)* by Robert van Engelen, ACM Transactions on Internet Technologies, Volume 8, Issue 3, Article 12, May 2008.
*[Developing Web Services for C and C++](https://doi.ieeecomputersociety.org/10.1109/MIC.2003.1189189)* by Robert van Engelen, Gunjan Gupta, and Saurabh Pant, in IEEE Internet Computing Journal, March, 2003, pages 53-61.
*[Pushing the SOAP Envelope with Web Services for Scientific Computing](https://www.cs.fsu.edu/~engelen/icws03.pdf)* by Robert van Engelen, in the proceedings of the International Conference on Web Services (ICWS), 2003, pages 346-354.
**Other related technical papers:**
*An Overview and Evaluation of Web Services Security Performance Optimizations* by Robert van Engelen and Wei Zhang, in the proceedings of the IEEE International Conference on Web Services (ICWS), 2008, pages 137-144.
*High-Performance XML Parsing and Validation with Permutation Phrase Grammar Parsers* by Wei Zhang and Robert van Engelen, in the proceedings of the IEEE International Conference on Web Services (ICWS), 2008, pages 286-294.
*Identifying Opportunities for Web Services Security Performance Optimizations* by Robert A. van Engelen and Wei Zhang, in the proceedings of the IEEE Congress on Services (SERVICES), 2008.
*[The GSI plug-in for gSOAP: building cross-grid interoperable secure grid services](https://www.springerlink.com/content/2598221j5k353h62/)* by M. Cafaro, D. Lezzi, S. Fiore, G. Aloisio, and R. van Engelen, in the proceedings of the International Conference on Parallel Processing and Applied Mathematics (PPAM) 2007, workshop on Models, Algorithms and Methodologies for Grid-enabled Computing Environment (MAMGCE), Springer Verlag LNCS Volume 4967, pages 894-901, 2008.
*[Toward Remote Object Coherence with Compiled Object Serialization for Distributed Computing with XML Web Services](https://www.cs.fsu.edu/~engelen/cpcpaper06.pdf)* by Robert van Engelen, Wei Zhang, and Madhusudhan Govindaraju, in the proceedings of Compilers for Parallel Computing (CPC), 2006, pages 441-455.
*Benchmarking XML Processors for Applications in Grid Web Services* by M. Head, M. Govindaraju , R. van Engelen, and W. Zhang, in the proceedings of Supercomputing 2006.
*[A Table-Driven XML Streaming Methodology for High-Performance Web Services](https://www.cs.fsu.edu/~engelen/icws2006tdx.pdf)*
by Wei Zhang and Robert van Engelen, in the proceedings of IEEE International Conference on Web Services (ICWS), 2006, pages 197-206.
*TDX: a High-Performance Table-Driven XML Parser* by Wei Zhang and Robert van Engelen, in the proceedings of the ACM SouthEast conference, 2006, pages 726-731.
*[Exploring Remote Object Coherence in XML Web Services](https://www.cs.fsu.edu/~engelen/icws2006coh.pdf)* by Robert van Engelen, Madhusudhan Govindaraju, and Wei Zhang, in proceedings of IEEE International Conference on Web Services (ICWS), 2006, pages 249-256.
*The GSI plug-in for gSOAP: Enhanced Security, Performance, and Reliability* by Giovanni Aloisio, Massimo Cafaro, Italo Epicoco, Daniele Lezzi, and Robert van Engelen, in the ITCC conference 2005, IEEE Press, Volume I, pages 304-309.
*[Benchmark Suite for SOAP-based Communication in Grid Web Services](https://www.extreme.indiana.edu/xgws/papers/soapBench2.pdf)* by Michael R. Head, Madhusudhan Govindaraju, Aleksander Slominski, Pu Liu, Nayef Abu-Ghazaleh, Robert van Engelen, Kenneth Chiu, Michael J. Lewis, in the proceedings of ACM/IEEE Supercomputing (SC), 2005.
*[Constructing Finite State Automata for High Performance XML Web Services](https://www.cs.fsu.edu/~engelen/ISWSpaper.pdf)* by Robert van Engelen, in the proceedings of the International Symposium on Web Services (ISWS), 2004, pages 975-981.
*[Code Generation Techniques for Developing Web Services for Embedded Devices](https://www.cs.fsu.edu/~engelen/SACpaper.pdf)* by Robert van Engelen, in the proceedings of the 9th ACM Symposium on Applied Computing SAC, Nicosia, Cyprus, 2004, pages 854-861.
*Toward Characterizing the Performance of SOAP Toolkits* by M. Govindaraju, A. Slominski, K. Chiu, P. Liu, R. van Engelen, and M. Lewis, in the proceedings of the 5th IEEE/ACM International Workshop on Grid Computing, pages 365-372, Pittsburgh, USA, 2004.
*Secure Web Services with Globus GSI and gSOAP* by Giovanni Aloisio, Massimo Cafaro, Daniele Lezzi, and Robert van Engelen, in the proceedings of EUROPAR 2003.
Where can I find an introduction to SOAP, WSDL and XML?
---
The gSOAP toolkit automates most of the WSDL and SOAP/XML processing, but it is strongly recommended that users should have a basic understanding of these protocols to get started.
A fairly basic [tutorial on WSDL](https://www.w3schools.com/webservices/ws_wsdl_intro.asp) (Web Services Description Language).
A fairly basic [tutorial on SOAP](https://www.w3schools.com/webservices/ws_soap_intro.asp) (Simple Object Access Protocol or Services Oriented Access Protocol).
Both WSDL and SOAP require an understanding of the XML syntax of elements and attributes, XML namespaces, XML schemas (XSD) and their role in XML validation. Also, WSDL and SOAP define and require XML schemas and XML namespaces.
See the [XML tutorial.](https://www.w3schools.com/xml)
Here are the links to the latest W3C recommended standards:
[WSDL 1.1](https://www.w3.org/TR/wsdl)
[WSDL 2.0](https://www.w3.org/TR/wsdl20/)
[SOAP 1.1/1.2](https://www.w3.org/TR/soap/)
I have been told that SOAP is too big and too complex, so should I use REST instead?
---
First of all, SOAP is basically an envelope with an XML header and an XML body which does not add a lot of complexity. The envelope adds about 100 to 300 bytes to a message. This overhead is insignificant in practice with gSOAP, which does not store any of this in memory.
Second, a SOAP message is essentially XML. You have the benefit of strict validation of messages that use SOAP document/literal style. The other style, SOAP encoding instead of literal, supports accurate serialization of data in XML, including cyclic graphs using id-ref attributes that tag "XML objects as pointers".
Third, SOAP does not require connection- or transport-level information embedded in HTTP URLs (as with REST) to invoke services because it is self contained.
Fourth, SOAP has become a native communication protocol to many development platforms. Most SOAP toolkits have stablized along with the protocol.
The claim that SOAP is for "big web services" misses the point that size is not a key factor in deciding on communication protocols, but how interoperable the protocol is and whether the protocol adheres to common standards for message exchange. These are key factors that gives us the assurance that the implementation is reliable and largely maintenance free due to the availability of stable libraries that only require a few lines of code to exchange data with "big" SOAP/XML web services.
Also, the rate of development cost tends to rise faster as the size of the code base grows; longer development cycles have shown to correlate with a higher, non-linear growth in bug rates. Working with schema-based data structures such as XML offers a huge advantage in this context. Schemas provide type safety by content validation rules. XML data binding tools translate this safety to strongly typed code to manipulate XML-sourced data. In contrast, exchanging non-validated XML and JSON over open networks is vulnerable to security exploits. Non-validating SAX, DOM, or JSON libraries also require substantially more application logic, resulting in prolonged development and testing cycles.
Most implementations communicate SOAP over HTTP with POST and GET anyway, similar to RESTful XML but with self-contained messages. The important difference to REST is that the SOAP protocol is stable, adheres to industry standards, and has many useful extensions such as MIME attachments, WS-Addressing, WS-Security, and WS-ReliableMessaging.
The gSOAP toolkit supports both SOAP and RESTful XML messaging with its built-in XML data binding to process XML generally.
How do I use gSOAP to develop a client for a WCF service?
--
First, there are no assumptions on how the WCF service was developed. The general steps to develop a WCF service in C# are as follows. In addition, the gSOAP distribution package includes WCF examples in `gsoap/samples/wcf`.
We will first discuss how a WCF service is created and then explain the steps to develop a gSOAP client for the service. It is also possible to create a gSOAP service and develop a WCF client for this service.
### Creating a WCF Service
To create a new WCF service, open VS in administrator mode and create a WCF Service Application project. VS will automatically generate an interface file `IService1.cs`, a service class file `Service1.svc.cs`, a configuration file `Web.config` and some other related files.
Add the *System.ServiceModel* reference by right clicking *Reference* of the project. Then add *using System.ServiceModel;* in the code file.
The interface `IService1.cs` defines the interfaces of the functions provided by the service. For example:
namespace WCF_sample_dataquery
{
[ServiceContract(Namespace = "https://WCF_sample_dataquery")] // Makes the interface become public in WCF service
public interface IDataQueryService
{
[OperationContract] // Makes the function SearchByAmount the public member of the public interface in WCF service
List SearchByAmount(int amount);
[OperationContract]
List SearchByOrigin(string origin);
//...
}
}
The service class `Service1.svc.cs` implements the interfaces defined in `IService1.cs`. For example:
namespace WCF_sample_dataquery
{
public class DataQueryService : IDataQueryService // Implement IDataQueryService interface
{
public List SearchByAmount(int amount)
{
//...
}
public List SearchByOrigin(string origin)
{
//...
}
//...
}
}
In the `Web.config` file set the basic http binding by adding the following content inside `` labels.
[xml]
Right-click the project name in *Solution Explorer*. Select *Properties* and modify the *Output* type to *Class Library*. Then build the WCF Service Application project.
### WCF Client for the WCF Service
Before we dig into developing a gSOAP client for a WCF service, we will go through the process of creating a WCF client application for the WCF service (the steps are similar when developing a WCF client for a gSOAP service).
The following assumes that Visual Studio 2010 or later is used.
First, right click on the solution name in *Solution Explorer*. Create a Console Application by selecting *Add* / *Visual C#* / *Console Application*.
Then add the service reference: right click *Service References* / *Add Service Reference*. Click the *Discover* button in the *Add Service Reference* window and VS will automatically find the address of the service file.
Select *Go* to test the availability of the service file. If this succeeds it will show a message such as *"1 service(s) found at address 'https://localhost:NNNN/Service1.svc'"*.
Click *OK* to add the reference.
You must rebuild the service after modifying the code and settings it and also update the service reference in the client project.
Edit the `Program.cs` file to implement your client-side logic.
To start the service and run the client, right-click on the solution name in *Solution Explorer* then click *Properties* and select *Startup Project* in the left side of the pop-up window. Check *Multiple* startup projects. Select both the service and client project action with *Start* and move the service project at the top of the project table. This ensures that the service will be hosted first.
Press *F5* or click *Start* to start the WCF service and client.
### gSOAP Client for the WCF Service
When the WCF service runs, you can access its WSDL through its endpoint URL using the URL query `?wsdl`. For example, `https://localhost:NNNN/DataQueryService.svc?wsdl`.
This WSDL is needed to implement a gSOAP client for the WCF service. We run wsdl2h on this WSDL to generate the C or C++ interface:
[command]
wsdl2h -o myclient.h https://localhost:NNNN/DataQueryService.svc?wsdl
It is highly recommended to change the `ns1`, `ns2`, etc prefixes to something more maintainable for your code.
To do so, open the generated `myclient.h` file and look for the *NOTE*. There is a list of prefixes and URIs, for example:
ns1 = "https://schemas.microsoft.com/exchange/services/2006/messages"
ns2 = "https://schemas.microsoft.com/exchange/services/2006/types"
Copy these definitions with your own prefixes to typemap.dat, so that the prefixes are more meaningful and unique for each URI, such as:
[command]
ewsmsg = "https://schemas.microsoft.com/exchange/services/2006/messages"
ewstyp = "https://schemas.microsoft.com/exchange/services/2006/types"
Then rerun wsdl2h with the modified typemap.dat located in your local directory. If the modified typemap.dat is not in your local directory then use wsdl2h option `-t/path/to/gsoap/typemap.dat`.
Run soapcpp2 to generate the data binding implementation and the C++ proxy class to access the WCF service:
[command]
soapcpp2 -j -CL -I/path/to/gsoap/import service.h
See the list of source code files generated when running soapcpp2, which includes a .h and .cpp file with the proxy class. Use the generated proxy class in your main program. The proxy class .h file has more details.
Also, you can use soapcpp2 option `-R` to generate a report with more information.
If the WCF service returns an error
[command]
HTTP/1.1 415 Cannot process the message because the content type 'application/soap+xml; charset=utf-8;
then please see the recommendations below to correct this problem.
There is a problem with my gSOAP client connecting to a WCF service, which returns an HTTP error
---
If the service returns the following error to your client:
[command]
HTTP/1.1 415 Cannot process the message because the content type 'application/soap+xml; charset=utf-8;
then the gSOAP client uses SOAP 1.2 messaging when the service expects SOAP 1.1 which uses HTTP content type `text/xml`. SOAP 1.2 uses HTTP content type `application/soap+xml`.
You can display these errors after making a failed call with `soap_print_fault(soap, stderr)` or `soap_stream_fault(soap, std::cerr)`.
To resolve this problem, remove the line `#import "soap12.h"` from the interface header file generated by wsdl2h. You can also use soapcpp2 option `-1` to force SOAP 1.1 messaging:
[command]
soapcpp2 -1 -j -CL -I/path/to/gsoap/import service.h
This generates a .nsmap file with updated SOAP protocol namespaces:
{"SOAP-ENV", "https://schemas.xmlsoap.org/soap/envelope/", "https://www.w3.org/*/soap-envelope", NULL},
{"SOAP-ENC", "https://schemas.xmlsoap.org/soap/encoding/", "https://www.w3.org/*/soap-encoding", NULL},
So make sure to `#include` this nsmap file in your code in order to use the
SOAP 1.1 namespace by default.
The gSOAP engine accepts both SOAP 1.1 and SOAP 1.2 messages, which is the
reason for the second namespace URI pattern in the nsmap that corresponds to SOAP 1.2 (or other versions).
If the service returns a different HTTP error then you may want to check the endpoint URL of the service that you are connecting to and the SOAP action string (if any). These string can be provided with the client-side call:
if (soap_call_ns__method(soap, "endpoint URL", "SOAP Action", ...) != SOAP_OK)
soap_print_fault(soap, stderr); // error
The endpoint URL string is an optional string to construct a proxy object and can also be passed to proxy methods:
Proxy proxy("endpoint URL");
...
if (proxy.method("endpoint URL", "SOAP Action", ...) != SOAP_OK)
proxy.soap_stream_fault(std::cerr); // error
If the service returns an "HTTP 401 Unauthorized" error or "HTTP 407 Proxy Authentication Required" error, then use Basic or Digest authentication.
For example, to enable HTTP Basic authentication (this MUST only be used over HTTPS to be safe!):
soap.userid = "Zaphod";
soap.passwd = "Beeblebrox";
if (soap_call_ns__method(&soap, ...)) // call with basic auth credentials
soap_print_fault(&soap, stderr); // error
For proxy authentication you should set these:
soap.proxy_userid = "Zaphod";
soap.proxy_passwd = "Beeblebrox";
HTTP Digest authentication requires setting up a credentials store, please see the [HTTP DA plugin](doc/httpda/html/httpda.html) for details.
You can use NTLM authentication with Microsoft services by compiling your code and stdsoap2.cpp with `-DWITH_NTLM` to enable NTLM. Also link with the [libntlm](https://www.nongnu.org/libntlm) library.
To use NTLM authentication:
soap_call_ns__method(&soap, ...) != SOAP_OK) // try calling without credentials
{
if (soap.error == 401) // must authenticate
{
soap.userid = "Zaphod";
soap.passwd = "Beeblebrox";
soap.authrealm = "Ursa-Minor";
if (soap_call_ns__method(&soap, ...) != SOAP_OK) // call with credentials
soap_print_fault(&soap, stderr); // error
}
}
The first step of this two-step authentication process can be eliminated as follows:
soap.userid = "Zaphod";
soap.passwd = "Beeblebrox";
soap.authrealm = "Ursa-Minor";
soap.ntlm_challenge = ""; // enable NTLM authentication
if (soap_call_ns__method(&soap, ...) != SOAP_OK) // call with credentials
soap_print_fault(&soap, stderr); // error
Where can I find a good description of the Apache module, ISAPI extension, and WinInet plugin for gSOAP?
---
See [Apache Module](doc/apache/html/index.html) for gSOAP in our Development Center.
See [ISAPI Extension](doc/isapi/html/index.html) for gSOAP in our Development Center.
See [WinInet Plugin](doc/wininet/html/index.html) for gSOAP in our Development Center.
How do I decrease the code size of my gSOAP application?
---
With gSOAP version 2.8.60 or greater, use wsdl2h option `-O2` to omit unused schema components from the generated code. This removes the C/C++ definitions of all unused schema types from the generated source code. Unused schema types are unreachable from WSDL and XSD roots, i.e. not reachable from root elements, root attributes, and from WSDL message parts via other schema types. This novel form of "schema slicing" yields a smaller code footprint of your application.
For small-scale devices we recommend compiling the source code with compiler option `-DWITH_LEAN` to reduce the size of the library by removing some features that are rarely used. If that works for you then you may want to try to further reduce the size of the library with compiler option `-DWITH_LEANER`.
For very larger projects the generated code can still be large and some compilers may complain about source code file sizes. To split up `soapC.cpp` (or `soapC.c` for C) in multiple files for your size-challenged C or C++ compiler, you can use soapcpp2 option `-fN` with `N` larger than 10 to generate `N` serializers per file.
How do I further increase the speed of XML processing and serialization?
---
The default settings of the gSOAP runtime engine maximize portability and compatibility. The settings can be tweaked to optimize the performance as follows:
Tweak the buffer size `SOAP_BUFLEN` by changing the `SOAP_BUFLEN` macro in `stdsoap2.h` (and compile your project with `stdsoap2.c` and `stdsoap2.cpp`, **DO NOT USE** `libgsoapXX.a` with the old buffer size). Test with buffer sizes 32768, 65536, 131072 for example.
Use HTTP keep-alive `SOAP_IO_KEEPALIVE` at the client-side 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.
Use HTTP chunked transfer `SOAP_IO_CHUNKED`.
Do NOT use gzip compression, since the overhead of compression is typically higher than the bandwidth gains.
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). This flag is **not compatible with SOAP encoded style** that requires id-ref object serialization.
Compile `stdsoap2.c` and `stdsoap2.cpp` with `-DWITH_NOIDREF` to improve performance by permanently disabling id-ref multi-ref object (de)serialization. Again, **this is not compatible with SOAP encoded style** that requires id-ref object serialization.
Do NOT use DEBUG mode, since the overhead of logging is significant.
I cannot build gSOAP version 2.7.13 and earlier
---
Because the OpenSSL API has slightly changed over time, build errors may occur. To fix this, edit `gsoap/stdsoap2.c` and `gsoap/stdsoap2.cpp` line 4162 to add `const` before `X509V3_EXT_METHOD *meth`:
{ const X509V3_EXT_METHOD *meth = X509V3_EXT_get(ext);
When using gSOAP version 2.7.13 and earlier I get the undefined SOAP_TYPE_wchar error
---
Edit `gsoap/src/symbo2.c` function `is_transient` and add the two lines as shown below:
int
is_transient(Tnode *typ)
{
if (!typ)
return 1;
if (typ->type == Tstruct && typ->id == lookup("soap"))
return 1;
if (is_external(typ) || is_volatile(typ))
return 0;
if (typ->transient > 0)
return 1;
if (is_wstring(typ)) /* wchar_t* is serializable but wchar_t is transient */
return 0;
When using an older gSOAP version I get the undifined M_ASN1_STRING_data error
---
The following patch works for all gSOAP versions.
In `gsoap/stdsoap2.c` and `gsoap/stdsoap2.cpp` replace:
{ if (!soap_tag_cmp(host, (const char*)M_ASN1_STRING_data(name)))
{
with:
{
#if OPENSSL_VERSION_NUMBER < 0x10100000L
const char *tmp = (const char*)ASN1_STRING_data(name);
#else
const char *tmp = (const char*)ASN1_STRING_get0_data(name);
#endif
if (!soap_tag_cmp(host, tmp))
{
I cannot deserialize polymorphic objects in my C-based service, but in C++ it works fine?
---
Services developed in C++ with gSOAP support full polymorphism, including xsd:anyType. However, the C language limitations make it more difficult to map schema complexType extensions to the limited C types. In order to support polymorphism in C, we suggest to use soapcpp2 with option `-F`.
See gSOAP documentation Section "soapcpp2 option -F".
See gSOAP documentation Section "Customizing Data Bindings With The typemap.dat File".
Use the typemap.dat file for wsdl2h to automatically replace all occurences of a polymorphic type.
When building the gSOAP library I get a syntax error before "locale_t"
---
This happens when the installation of locale.h is somehow incomplete and `locale_t` is undefined. To build the gSOAP library without locale switching to C:
[command]
./configure --disable-c-locale
make
sudo make install
Using these options means that other locale settings on the machine or in the application may affect floating point conversions, e.g. when `LC_NUMERIC` is set to the European-style decimal comma instead of a decimal point. This obviously affects text processing in XML.
I get a No deserializer found to deserialize error from an Axis server. What is the problem?
---
Some toolkits, including Axis, require `xsi:type` attributes for each accessor for messages using the SOAP RPC encoding style. Use soapcpp2 option `-t` to automatically re-generate serialization code to produce typed messages.
I suspect that gSOAP has a memory leak, because no memory is released?
---
The gSOAP engine uses a memory management method to allocate and deallocate memory. The deallocation is performed with `soap_destroy()` followed by `soap_end()`. However, when you compile with `-DDEBUG` or `-DSOAP_MEM_DEBUG` then no memory is released until `soap_done()` is invoked.
This ensures that the gSOAP engine can track all malloced data to verify leaks and double frees in debug mode. Use `-DSOAP_DEBUG` to use the normal debugging facilities without memory debugging. Note that some compilers have DEBUG enabled in the debug configuration, so this behavior should be expected unless you compile in release config.
Memory management requires `soap_destroy()` followed by `soap_end()` (or C++ `soap` context method `destroy()`) to be invoked before the `soap` context is released. When `soap_new()` or `soap_copy()` is used to create/copy a new context on the heap, use `soap_free()` to release it. In addition, when `soap_init()` is used to initialize a stack-allocated `soap` context, use `soap_done()`. Never invoke `soap_init()` after `soap_new()` or after the first `soap_init()`. See also our [user guide on memory](https://www.genivia.com/doc/guide/html/index.html#memory) and [memory management](https://www.genivia.com/doc/databinding/html/index.html#memory) in the C/C++ XML data bindings guide.
Important note on OpenSSL 1.1.0 and greater: when an application is statically linked to OpenSSL, all threads must call `OPENSSL_thread_stop()` before terminating to prevent leaks. See also : *"Resources local to a thread are deallocated automatically when the thread exits (e.g. in a pthreads environment, when pthread_exit() is called). On Windows platforms this is done in response to a DLL_THREAD_DETACH message being sent to the libcrypto32.dll entry point. Some windows functions may cause threads to exit without sending this message (for example ExitProcess()). If the application uses such functions, then the application must free up OpenSSL resources directly via a call to OPENSSL_thread_stop() on each thread. Similarly this message will also not be sent if OpenSSL is linked statically, and therefore applications using static linking should also call OPENSSL_thread_stop() on each thread. Additionally if OpenSSL is loaded dynamically via LoadLibrary() and the threads are not destroyed until after FreeLibrary() is called then each thread should call OPENSSL_thread_stop() prior to the FreeLibrary() call."*
What is the data corruption in dynamic allocation error?
---
When your application uses `soap_malloc()` to allocate a (temporary) chunk of data and the allocated size is exceeded, the gSOAP engine will detect this buffer overrun in `-DDEBUG` compiled mode. Check your code and/or enlarge the allocated buffer.
The compiler produces an error for empty structs and classes that are present in the generated code. What should I do?
---
Use `-DWITH_NOEMPTYSTRUCT` as a C/C++ compiler option to add dummy
members automatically to the generated code (gSOAP version 2.7.9g or higher).
I downloaded a new release, but now I get GSOAP VERSION MISMATCH IN LIBRARY: PLEASE REINSTALL PACKAGE?
---
This error is caused by mixing old with new gSOAP versions of the generated code and gSOAP libraries. Make sure to include the latest `stdsoap2.h` and link with the latest `libgsoapXX.a` libraries (or use the `stdsoap2.c` or `stdsoap2.cpp` source code).
I downloaded a new release, but now I get a link error for XXX_REQUIRE_lib_vYYY?
---
See the item above.
I get macro redefinition errors on my Windows platform, what should I do?
---
When you get macro redefinitions, such as
[command]
warning C4005: 'AF_IPX' : macro redefinition
then try arrange your include list such that `windows.h` is included after `stdsoap2.h`. Or define `_WINSOCKAPI_` first:
#define _WINSOCKAPI_ // stops windows.h including winsock.h
#include
...
#include "soapH.h" // also includes "stdsoap2.h"
The `stdsoap2.h` code includes `winsock2.h`, which clashes with `winsock.h` included by `windows.h`. Similar problems may occur when `stdafx.h` is included.
If all else fails, revert back to older `winsock.h` by changing `stdsoap2.h`:
#include // was:
How do I install gSOAP on HP-UX?
---
If the configuration with `./configure` and installation with `make` fails, then please follow these recommendations.
Install GNU m4 from [www.gnu.org/software/m4](https://www.gnu.org/software/m4)
Install Bison from [www.gnu.org/software/bison](https://www.gnu.org/software/bison).
Install Flex from [GitHub](https://github.com/westes/flex).
If you are not able to install Flex or Bison, see the [installation instructions](downloads.html) on how to build the gSOAP tools without Flex and Bison.
If HTTP compression is needed for your project, then install zlib from [www.zlib.net](https://www.zlib.net) and make sure that `libz` is installed on a library path accessible to the compiler.
If HTTPS and SSL for WS-Security are required, then install OpenSSL.
When OpenSSL is NOT installed in the above steps, execute in the root dir of the gsoap package:
[command]
./configure --disable-openssl
With OpenSSL installed on your system, execute:
[command]
./configure
Edit `config.h`:
set HAVE_REALLOC 1
/* #define realloc rpl_realloc commented out */
Also make sure that in `config.h` we have:
#define HAVE_STRTOLL 0
#define HAVE_STRTOULL 0
Then execute:
[command]
make
If there are errors when building the tests, then ignore these for now.
Edit the Makefile to make sure that:
LEXLIB = /usr/local/lib/libfl.a
Then rebuild with:
[command]
make
If there is a problem building wsdl2h, do this:
[command]
cd ../wsdl
And edit the `Makefile` there:
wsdl2h_DEPENDENCIES = wsdlC.cpp $(top_builddir)/gsoap/stdsoap2.cpp
AM_LDFLAGS = $(INCLUDES) -DWITH_OPENSSL -L$(srcdir)
SOAP_CCP_LIB_SSL = $(top_builddir)/gsoap/stdsoap2.cpp
Then execute:
[command]
make
cd ../..
make install-exec
Now we have soapcpp2 and wsdl2h built and installed.
Execute:
[command]
make install
If all else fails, you can build the soapcpp2 and wsdl2h tools using the supplied `MakefileManual` files in the source directories. Before doing so, remove the old package and unpack again to start fresh. Then execute:
[command]
cd gsoap/src
make -f MakefileManual soapcpp2
cd gsoap/wsdl
make -f MakefileManual
In your projects use `gsoap/stdsoap2.h` and `gsoap/stdsoap2.c` (or `gsoap/stdsoap2.cpp` for C++) directly instead of the `libgsoapXX.a` libraries (which are built from `stdsoap2.c` and `stdsoap2.cpp`).
If `stdsoap2.c` or `stdsoap2.cpp` do not compile, modify `stdsoap2.h` for portability. For example, if `socklen_t` is not defined, change it to an `int` as in:
#elif defined(__socklen_t_defined) || defined(_SOCKLEN_T) || defined(CYGWIN) \
|| defined(FREEBSD) || defined(__FreeBSD__) || defined(OPENBSD) \
|| defined(__QNX__) || defined(QNX) || defined(OS390) || defined(HP_UX)
# define SOAP_SOCKLEN_T socklen_t
To:
#elif defined(__socklen_t_defined) || defined(_SOCKLEN_T) || defined(CYGWIN) \
|| defined(FREEBSD) || defined(__FreeBSD__) || defined(OPENBSD) \
|| defined(__QNX__) || defined(QNX) || defined(OS390) || defined(HP_UX)
# define SOAP_SOCKLEN_T int
Similar changes may be needed depending on HP-UX system versions.
How do I build a universal PPC/Intel binary for MAC OS?
---
To build a Mac OS X Universal Binary you have to run:
[command]
automake --ignore-deps
./configure CFLAGS="-arch ppc -arch i386" LDFLAGS="-arch ppc -arch i386"
make clean
make
make install
How do I build the libraries with libtool?
---
In `configure.in` change `AC_PROG_RANLIB` to `AC_PROG_LIBTOOL`.
In `gsoap/Makefile.am` replace the `.a` and the `_a` respectively by `.la` and `_la` in this file, so that you get:
lib_LTLIBRARIES = libgsoap.la libgsoap++.la libgsoapck.la libgsoapck++.la libgsoapssl.la libgsoapssl++.la
libgsoap_la_SOURCES = stdsoap2.c
libgsoap_la_CFLAGS = $(SOAPCPP2_DEBUG) $(SOAPCPP2_NONAMESPACES) -D$(platform)
libgsoap___la_SOURCES = stdsoap2_cpp.cpp
libgsoap___la_CXXFLAGS = $(SOAPCPP2_DEBUG) $(SOAPCPP2_NONAMESPACES) -D$(platform)
libgsoapck_la_SOURCES = stdsoap2_ck.c
libgsoapck_la_CFLAGS = $(SOAPCPP2_DEBUG) $(SOAPCPP2_NONAMESPACES) -D$(platform) -DWITH_COOKIES
libgsoapck___la_SOURCES = stdsoap2_ck_cpp.cpp
libgsoapck___la_CXXFLAGS = $(SOAPCPP2_DEBUG) $(SOAPCPP2_NONAMESPACES) -D$(platform) -DWITH_COOKIES
libgsoapssl_la_SOURCES = stdsoap2_ssl.c
libgsoapssl_la_CFLAGS = $(SOAPCPP2_DEBUG) $(SOAPCPP2_NONAMESPACES) -D$(platform) -DWITH_OPENSSL -DWITH_DOM -DWITH_GZIP
libgsoapssl___la_SOURCES = stdsoap2_ssl_cpp.cpp
libgsoapssl___la_CXXFLAGS = $(SOAPCPP2_DEBUG) $(SOAPCPP2_NONAMESPACES) -D$(platform) -DWITH_OPENSSL -DWITH_DOM -DWITH_GZIP
After the modifications run
[command]
autoconf -f -i -v configure
make
make install
Is gSOAP portable to NonStop Tandem?
---
Yes. A software bridge for the engine to work on NonStop Tandem is included in the package. All generated code is platform-independent, so the soapcpp2/wsdl2h tools can be used on any platform to produce the client/server interface.
Why do I get a Compliance Warning from soapcpp2?
---
WS-I Basic Profile compliance warnings are meant to inform you about potential interoperability problems with other SOAP/XML Web services. The [WS-I Basic Profile publication](https://www.ws-i.org/Profiles/BasicProfile-1.0-2004-04-16.html) consists of a set of non-proprietary Web services specifications, along with clarifications and amendments to those specifications which promote interoperability. Compliance warnings for existing services should be ignored, because compliance requires changes to the service WSDL that would break other applications that depend on the service. You may consider these compliance issues for new services however, see the [Basic Compliance Report](https://www.cs.fsu.edu/~engelen/soapBP.html) for gSOAP.
What is the difference between qualified element/attribute forms and unqualified forms?
---
When a schema defines element forms to be qualified by default (`elementFormDefault="qualified"`), the header file includes a directive
//gsoap ns schema elementForm: qualified
Likewise, when the default is unqualified, you will find
//gsoap ns schema elementForm: unqualified
When an element form is qualified by default, elements in XML instances of the schema are required to be namespace qualified. Without going into too much detail, the XML basically looks like:
[xml]
bar is qualified
or:
[xml]
bar is qualified
When the element form is unqualified (as in SOAP RPC encoding), we would have:
[xml]
bar is unqualified
Note that sometimes we can have multiple namespaces as in:
[xml]
or:
[xml]
In the last example the bar element belongs to the `urn:bar` namespace, because the default namespace is `urn:bar`.
With Visual Studio .NET 2003 WSDL import, we could not successfully deserialize data from a multi-namespace situation when a response element contains an element of struct type in a second namespace. The individual members of the struct were ignored on the .NET side until the element form default 'qualified' was defined.
How do I tune TCP/IP TIME_WAIT for systems with high connection rates?
---
When a large number of connections in the `TIME_WAIT` state are observed, e.g. using the "netstat" command to monitor open TCP/IP connections, the system exhibits poor throughput possibly coupled with high CPU use or refusal to accept new connections by `soap_accept()`.
The `TIME_WAIT` state is used to deal with possible problems related to unreliable or delayed packet delivery. TCP holds connections for a temporary waiting period (`TIME_WAIT`) to ensure that any delayed packets are caught and not treated as new connection requests. The size of `TIME_WAIT` is supposed to be twice the maximum segment lifetime or twice the time a packet can remain alive on a particular IP network. For some operating systems, this can be as high as 4 minutes. On busy systems, this can lead to a depletion of TCP port resources. Low throughput may occur due to many connections sitting in TIME_WAIT state.
Set the `soap.accept_flags |= SO_LINGER` and `soap.linger_time = n` with integer `n` before calling `soap_accept()`. This works on most systems, but zapping the `TIME_WAIT` state is not always encouraged!
If that does not work, then reduce the operating system setting for `TIME_WAIT` substantially to the operating system minimum of 15 or 30 seconds (depending on OS).
For Windows: use regedit and create a `REG_DWORD` named `TcpTimedWaitDelay` under
[command]
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TcpIp\Parameters
Set it to a decimal value of 30 which is for 30 seconds - the minimum.
For AIX: to see the current `TCP_TIMEWAIT` value, run the following command:
[command]
/usr/sbin/no a | grep tcp_timewait
To set the `TCP_TIMEWAIT` values to 15 seconds, run the following command:
[command]
/usr/sbin/no o tcp_timewait =1
The `tcp_timewait` option is used to configure how long connections are kept in the timewait state. It is given in 15-second intervals, and the default is 1.
- For Linux: set the `timeout_timewait` paramater using the following command:
[command]
/sbin/sysctl -w net.ipv4.vs.timeout_timewait=30
This will set `TME_WAIT` for 30 seconds.
- For Solaris: set the `tcp_time_wait_interval` to 30000 milliseconds as follows:
[command]
/usr/sbin/ndd -set /dev/tcp tcp_time_wait_interval 30000
My gSOAP client receives an ECONNRESET from a server
---
Set `soap.accept_flags |= SO_LINGER` and set `soap.linger = n` in the server code before calling `soap_accept()`. This forces the server to block on the close attempt until it is able to transmit the data or until it decides it is unable to deliver the information after a timeout period. The `soap.linger = n` value controls the timout period (the linger time resolution is system-dependent, consult the `setsockopt` manual page. However, according to some experts only zero and nonzero values matter).
Why do I get a warning on a parameter with a type that does not correspond to the required unique type?
---
SOAP RPC literal encoding requires the operation parameters to be described as top-level Schema elements in WSDL. Therefore, a service operation with parameter `x` of type `X` has an `` definition in the Schema of the service. A parameter `x` of type `Y` cannot be defined, since `x` is already bound to type `X`. If you must use SOAP RPC literal encoding, rename the parameter, e.g. `y` of type `Y`, or define new schema namespaces by qualifying the parameter names, e.g. `arg__x`, `arg__y`, etc. You can use document literal encoding to avoid this problem, or SOAP RPC encoding (not WS Basic Profile compliant).
I get a link error in Visual Studio C++. What should I do?
---
Visual Studio C++ differs from compilers such as GCC with respect to the C or C++ compilation mode based on file extensions, which means that:
For C++ builds: change `.c` into `.cpp` extensions.
For C++ builds: do not use soapcpp2 option `-c`.
For C++ builds: link your application with `soapC.cpp`, `soapClient.cpp` (or `soapServer.cpp` for services), and `stdsoap2.cpp`.
Check the actual-formal parameter passing (`soapStub.h` contains the prototypes of the generated stub functions).
You need `winsock.dll` (`wsock32.lib`). To do this in Visual C++ for example, go to "Project", "settings", select the "Link" tab (the project file needs to be selected in the file view) and add "wsock32.lib" to the "Object/library modules" entry.
I get a link error when compiling. What should I do?
---
For C use soapcpp2 option `-c` to generate C code. Use only the gSOAP package's `.c` files. Link with `libgsoap.a` (`-lgsoap`) or use the lib's source `stdsoap2.c` (and `dom.c` when applicable).
For C++ there is no need to change the gSOAP package's `.c` source files to files with `.cpp` extensions, but compilers may warn about deprecated behavior.
For example, suppose we have a `myprog.cpp` C++ client that uses the WS-Addressing and WS-ReliableMessaging plugins and the `duration` custom serializer which are all C files:
soapcpp2 -a -L -S -I $GSOAPHOME -I $GSOAPHOME/import myprog.h
c++ -I $GSOAPHOME -o myprog myprog.cpp plugin/wsaapi.c plugin/wsrmapi.c custom/duration.c soapC.cpp soapClient.cpp -lgsoap++
All plugin sources are located in the `plugin` directory and should be compiled and linked with your C or C++ code. Custom types and serializers are located in the `custom` directory. When a serializer of a custom type is used the source file with the serializer implementation must be compiled and linked as well.
The build fails when the Bison tool is invoked and produces a signal 13. What should I do?
---
You need to install a newer version of m4 from [GNU m4](https://www.gnu.org/software/m4) and then check again. If the build then fails due to missing `libsigsegv`, install `libsigsegv`.
My code segfaults. What should I do?
---
First determine if the application crashes in the gSOAP code. Then verify the following:
Make sure that the gSOAP run-time environment (struct soap) is initialized by calling `soap_init(&soap)`. A soap struct dynamically allocated with `soap_new()` is already initialized.
When working with C++ applications, make sure that you don't include the wsdl2h-generated .h header file directly in your C++ sources. You must use the gSOAP-generated `soapH.h` file instead, which includes the proper class extensions with virtual serialization methods. The soapcpp2 tool adds serializers to classes, so it is important to use the classes redefined in `soapH.h` (via `soapStub.h`). If your project does not allow class redefinitions, use the `volatile` qualifier with your class definition in the `.h` file for soapcpp2.
Make sure you don't pass the gSOAP run-time environment (struct soap) by value to your application functions. Always pass struct soap by reference or pointer, just like the internal gSOAP functions do. In case you need to make a copy of it, use `$soap_copy()`.
Make sure all pointers that occur in the data structures that are passed as parameters to remote methods are initialized, i.e. pointers should be NULL or point to a valid object. If your application crashes in the serialization code while sending data, it is very likely that the serializer encountered an undefined pointer member in a struct or class to serialize to XML. Make sure the data to be serialized is properly set and contains valid data for all struct/class members (transient members are not serialized and can be undefined). Set struct/class pointer members to NULL when not in use. To ease this burden, use the `soap_default_T()` generated functions for structs `T` and `T::soap_default()` function members of classes.
Make sure all class instances that are passed as parameters to remote methods are initialized, i.e. the virtual method tables
(VMTs) must be set.
Make sure that no two (or more) threads access the same gSOAP run-time environment (struct soap) concurrently, i.e. use separate soap struct run-time environments in threads.
Remove all calls to `soap_destroy()` and `soap_end()` and rerun to check if the segfault results from gSOAP's garbage collect cleanup.
If the segfault occurs in the `soap_destroy()` cleanup, remove all deallocation calls in the destructors to avoid duplicate deallocations (one by the destructor and one by gSOAP's cleanup). Compensate the elimination of deallocation calls by allocating data solely with `soap_malloc()` and `soap_new_Class()` routines in your code. Alternatively, you can use `soap_unlink(p)` in the class destructors to unlink the data pointed to by `p` from gSOAP's deallocation chain before deallocating it in the class destructor (see the gSOAP documentation on `soap_malloc()`, `soap_new_Class()`, and `soap_unlink()` in class methods).
If the segfault occurs in the `soap_end()` cleanup, then it is likely that data is already deallocated with `free()` in your code and deallocated again in `soap_end()`. Use `soap_unlink(p)` to unlink the data pointed to by `p` from gSOAP's deallocation chain before freeing it up.
When you use OpenSSL and/or Zlib, please compile **all source files** with `-DWITH_OPENSSL` and/or `-DWITH_GZIP` to ensure that the `struct soap` layout is identical in all places where it is used.
If the crash occurs in the deserialzer while reading data, and you declared in the gSOAP specificication header file a SOAP array (or `__ptr` and `__size` pair) of an array of class instances, then it is strongly advised to use pointers to class instances instead using `T **__ptr` to point to an array of pointers to class `T` instances. Otherwise class instances might be copied in memory to collect them into arrays which on some platforms may fail.
If your server application crashes after invoking a service operation while returning data to the client, then see the next FAQ item below.
How can I allocate temporary data in service operations?
---
Avoid returning stack-allocated objects from service operations, which is definitely not safe.
To allocate temporary data in service operations, use the functions:
void *soap_malloc(struct soap *soap, size_t n); // allocate n bytes
ClassX *soap_new_classX(struct soap *soap); // one instance of ClassX
ClassX *soap_new_classX(struct soap *soap, size_t n); // an array of n instances of ClassX
This allocates memory on the heap that will be released upon calling `soap_destroy()` followed by `soap_end()`, such as after `soap_serve()`:
soap_serve(&soap);
soap_destroy(&soap);
soap_end(&soap);
An example service operation that allocates a temporary string:
int ns__itoa(struct soap *soap, int i, char **a)
{
*a = (char*)soap_malloc(soap, 11);
sprintf(*a, "%d", i);
return SOAP_OK;
}
Note that you don't want to use local function variables to store values such as strings, because the values are allocated on the stack and deallocated when the function returns while serialization of the values takes place after return.
This allocation with `soap_malloc()` can also be used to allocate strings for the SOAP Fault data structure, for example:
int ns__mymethod(struct soap *soap, ...)
{ ...
if (exception)
{
char *message = (char*)soap_malloc(soap, 1024);
char *details = (char*)soap_malloc(soap, 1024);
sprintf(message, ...);
sprintf(details, ...);
return soap_receiver_fault(soap, message, details);
}
...
}
The time_t deserialization appears to be incorrect, because the time_t value is off by one or more hours. How can I fix this?
---
Some systems do not support `timegm()` to convert time expressed in UCT to `time_t` values. Therefore, the gSOAP kernel uses `gettimeofday()` or `ftime()` with `mktime()` to deserialize `xsd:dateTime` values into `time_t`. As a result, when the timezone on the machine on which gSOAP runs is set incorrectly, this will cause the `time_t` value to be off by one or more hours. Unfortunately, the problem is more difficult with Solaris 8 and earlier Solaris versions, because Solaris does not implement the DST settings of `gettimeofday()` and `ftime()` correctly.
My application recieves a Broken Pipe signal. What should I do?
---
A "broken pipe" signal SIGPIPE is OS dependent. It is triggered when a peer closes a connection unexpectedly on Linux and Unix variants. When the signal is not caught, the application exits. To prevent this, use one of the following three methods:
soap.accept_flags = SO_NOSIGPIPE; /* some systems accept this */
soap.socket_flags = MSG_NOSIGNAL; /* others need this */
signal(SIGPIPE, sigpipe_handler); /* and when the above are not supported, we use a sigpipe handler */
where the `sigpipe_handler` is defined as a no-op function:
void sigpipe_handler(int x) { }
I get a tag mismatch error and/or data appears to be missing when receiving SOAP/XML messages?
---
Check that your gSOAP header file includes `//gsoap` directives to define XML namespaces. These namespace bindings will be added to a `.nsmap` file generated by the gSOAP compiler (or you can write your own `.nsmap` file). The gSOAP header file requires a one-to-one correspondence between namespace prefix and the namespace name. Therefore, a namespace name may not occur more than once in a `//gsoap ... service namespace` directive.
My code appears to ignore data when receiving SOAP/XML messages. How can my code detect unrecognized elements at run time?
---
The SOAP RPC encoding style allows optional elements to be ignored, even through the XML validator would flag this. As a side effect, a namespace mismatch and/or tag name mismatch will result in dropping the element. If the namespace and/or tag name are defined correctly, data will never be dropped at run time. To assist debugging and to catch dropped elements, set the `soap_set_imode(&soap, SOAP_XML_STRICT)` flag. This will enforce strict validation of messages.
Another way to control the dropping of unrecognized elements is to define the `fignore` callback. For example:
struct soap soap;
soap_init(&soap);
soap.fignore = mustmatch; // overwrite default callback
...
soap_done(&soap); // reset callbacks
...
int mustmatch(struct soap *soap, const char *tag)
{
return SOAP_TAG_MISMATCH; // every tag must be handled
}
The tag parameter contains the offending tag name. You can also selectively return a fault:
int mustmatch(struct soap *soap, const char *tag)
{
if (soap_match_tag(soap, tag, "ns:login*")) // all tags in namespace "ns" that start with "login" are optional
return SOAP_OK;
return SOAP_TAG_MISMATCH; // every other tag must be understood (handled)
}
SOAP 1.1 allows the return parameter elements of a SOAP response to be anonymous. How can I tell gSOAP to use anonymous return parameter names?
---
For gSOAP 2.1.11 and higher, specify the function prototype without parameter names. For earlier gSOAP releases, you can prefix the return parameter names with an underscore (`_`). For example:
int ns__mymethod(..., int *_return); // single anonymous output parameter
and
int ns__mymethod(..., struct ns__mymethodResponse{int _return1; char *_return2; ...} *result); // multiple output paramers
How can I tell gSOAP to ignore certain declarations of types in a header file so I can write class methods that use parameters of these types?
---
You can provide the type declarations in the header file and use the `extern` qualifier or enclose the type declarations between `[` and `]` to make them "transient", i.e. non-serializable. For example:
extern class ostream; // can't be (de)serialized so must be declared a transient type
class ns__foo
{
public:
char *s;
struct soap *soap; // special field: already transient
ns__foo();
[ ns__foo(const char *t); // transient constructor
print(ostream &s); // transient method
]
};
with e.g. the following implementation of `ns__foo`:
ns__foo::ns__foo(const char *t)
{
s = (char*)soap_malloc(soap, strlen(t)+1);
strcpy(s, t);
}
The `struct soap* soap` field in this class is a special field set by gSOAP's deserializers and the gSOAP-generated `soap_new_ns__foo()` function.
How can I tell gSOAP to use primitive XSD schema types or SOAP-ENC schema types?
---
Use `typedef` declarations for primitive types in the header file input to the compiler.
This is important for SOAP RPC encoding style. For example, to declare a XSD schema string type, declare `typedef char *xsd__string;` and use the `xsd__string` type in remote method parameters and other compound data structures. See the documentation for more details on primitive XSD schema types and the section on doc/literal encoding. The declaration of SOAP-ENC schema types is similar. For example, `typedef char *SOAP_ENC__string` declares a SOAP-ENC:string schema type.
How do I debug a gSOAP client?
---
Compile `stdsoap2.cpp` (or `stdsoap2.c` for C) with compiler option `-DDEBUG` (`/DSOAP_DEBUG` in MSVC++) to enable logging.
When you run your application, three files are created in the current directory: `SENT.log`, `RECV.log`, and `TEST.log`. All output messages are appended to `SENT.log`, all input messages are appended to `RECV.log`, and `TEST.log` contains various logging messages generated by the gSOAP runtime environment.
Alternatively, you can use the example plugin code provided in the distribution package in `extras/plugin.h` to develop an application that can selectively log input and output messages.
In addition, you can use a simple trick to inspect a client request message by leaving the endpoint URL empty ("" string). This will send the request message to stdout. The client application expect the response to be available from `stdin`. So, unless you provide a response message using redirect e.g. from a file or a service application using Unix pipes, you will have to terminate the client application.
How do I debug a Web Service installed as a CGI application?
---
First, see the answer above and then install the executable as a CGI application on your Web server. Create three empty files in the same directory: `SENT.log`, `RECV.log`, and `TEST.log`. They should have read and write permissions for "other" (i.e. for everyone). These files will log all accesses to the CGI application. Do not forget to remove them later and turn off debugging.
Alternatively, to test the CGI server, create a file with the SOAP request message (for example by using the soapcpp2 auto-generated `.req.xml` messages) and use file redirect to input this message as standard input to the executable, which should display the response message.
Does gSOAP support multi-threading and is it MT-safe?
---
Yes, gSOAP 2.x is MT-safe and implements multi-threaded clients and servers. There are differences in the API's used in gSOAP 2.x compared to the very old gSOAP 1.X to support multi-threading. Section 3 of the gSOAP 2.x documentation details these differences.
I wrote a client and service that exchange strings, but I get garbage or I get only one character communicated and not the entire string?
---
Your function prototype is probably similar to `mymethod(char *in, char *out)`. The output parameter "out" is a pointer to a byte instead of a pointer to a string (output parameters must be pointers or references to a type). The correct way to do this is: `mymethod(char *in, char **out)` or `mymethod(char *in, char *&out)`.
I wrote a client and service that exchange strings declared as char[N], but I get an array of N bytes in the payload?
---
If you use a fixed-size array of chars, the array is (de)marshalled as an array of bytes and not a string. Always use `char*` for strings. Use soapcpp2 option `-b` to support fixed-size string arrays `char[N]`.
I wrote a remote method declaration and the compiler gives a syntax error for parameter names that are keywords
---
Use one or more trailing underscores in parameter names, type names, struct fields, class members, etc. to avoid name clashes with keywords. The trailing underscores in identifier names are invisible in the SOAP/XML payload. For example `mymethod(int &return_);` declares a remote method with output parameter `return_` which will be (de)serialized in XML as `return`.
How do I write a remote method that has no input parameters?
---
Just specify one (output) parameter.
I have a remote method with a response struct that is also used as a type elsewhere in my header file, but now my WSDL is incomplete because the type is not defined in the WSDL (an element definition appears instead)
---
A response struct/class is not a type but a placeholder or wrapper for the result parameters. So you cannot use this struct/class anywhere else in your type definitions, since it will be defined as a schema element rather than a schema type. For example:
struct ns__data { ... };
int ns__example(..., struct ns__data *out);
where the `ns__data` struct contains the result parameters of the method. The struct is translated into an element definition in the generated WSDL to support doc/lit style messaging. As you can see, this means that `ns__data` cannot be used as a type anywhere else in your header file. To work around this problem, use:
struct ns__data { ... };
int ns__example(..., struct ns__exampleResponse { struct ns__data out; } *out);
Now we have a type `ns__data` and a response struct for the method results.
How do I write a remote method that has no output parameters?
---
Specify an empty struct output parameter. For example: `ns__myMethod(..., struct ns__myMethodResponse { } &response)`.
How can I use (wide character) strings for doc/literal encoding to (de)serialize any form of XML?
---
Use the built-in `_XML` char-based string type or declare your own:
typedef char *XML; // in C
typedef std::string XML; // or in C++
or as wide strings:
typedef wchar_t *XML; // in C
typedef std::wstring XML; // or in C++
and use this `XML` type for mixed-content strings (strings that contain XML).
How do I add SOAP Headers to my messages?
---
Set the `soap.header` field of the runtime environment variable (soap struct) to point to a `struct SOAP_ENV__Header`
structure:
if (soap.header == NULL)
{
soap.header = soap_malloc(&soap, sizeof(struct SOAP_ENV__Header));
soap_default_SOAP_ENV__Header(&soap, soap.header)
}
The exact same can be accomplished with:
soap_header(&soap);
How do I use gSOAP with the ONVIF specifications?
---
Use gSOAP 2.8.10 or greater. In the typemap.dat file that is used by wsdl2h, add the following if not already there:
[command]
# ONVIF recommended prefixes
tds = "https://www.onvif.org/ver10/device/wsdl"
tev = "https://www.onvif.org/ver10/events/wsdl"
tls = "https://www.onvif.org/ver10/display/wsdl"
tmd = "https://www.onvif.org/ver10/deviceIO/wsdl"
timg = "https://www.onvif.org/ver20/imaging/wsdl"
trt = "https://www.onvif.org/ver10/media/wsdl"
tptz = "https://www.onvif.org/ver20/ptz/wsdl"
trv = "https://www.onvif.org/ver10/receiver/wsdl"
trc = "https://www.onvif.org/ver10/recording/wsdl"
tse = "https://www.onvif.org/ver10/search/wsdl"
trp = "https://www.onvif.org/ver10/replay/wsdl"
tan = "https://www.onvif.org/ver20/analytics/wsdl"
tad = "https://www.onvif.org/ver10/analyticsdevice/wsdl"
tdn = "https://www.onvif.org/ver10/network/wsdl"
tt = "https://www.onvif.org/ver10/schema"
# OASIS recommended prefixes
wsnt = "https://docs.oasis-open.org/wsn/b-2"
wsntw = "https://docs.oasis-open.org/wsn/bw-2"
wsrfbf = "https://docs.oasis-open.org/wsrf/bf-2"
wsrfr = "https://docs.oasis-open.org/wsrf/r-2"
wsrfrw = "https://docs.oasis-open.org/wsrf/rw-2"
wstop = "https://docs.oasis-open.org/wsn/t-1"
# WS-Discovery 1.0 remapping
wsdd10__HelloType = | wsdd__HelloType
wsdd10__ByeType = | wsdd__ByeType
wsdd10__ProbeType = | wsdd__ProbeType
wsdd10__ProbeMatchesType = | wsdd__ProbeMatchesType
wsdd10__ProbeMatchType = | wsdd__ProbeMatchType
wsdd10__ResolveType = | wsdd__ResolveType
wsdd10__ResolveMatchesType = | wsdd__ResolveMatchesType
wsdd10__ResolveMatchType = | wsdd__ResolveMatchType
# SOAP-ENV mapping
SOAP_ENV__Envelope = struct SOAP_ENV__Envelope { struct SOAP_ENV__Header *SOAP_ENV__Header; _XML SOAP_ENV__Body; }; | struct SOAP_ENV__Envelope
SOAP_ENV__Header = | struct SOAP_ENV__Header
SOAP_ENV__Fault = | struct SOAP_ENV__Fault
SOAP_ENV__Detail = | struct SOAP_ENV__Detail
SOAP_ENV__Code = | struct SOAP_ENV__Code
SOAP_ENV__Subcode = | struct SOAP_ENV__Subcode
SOAP_ENV__Reason = | struct SOAP_ENV__Reason
At the command line prompt, run wsdl2h on the ONVIF WSDLs. For example, the device management and event specifications:
[command]
wsdl2h -O4 -P -x -o onvif.h https://www.onvif.org/onvif/ver10/device/wsdl/devicemgmt.wsdl https://www.onvif.org/onvif/ver10/event/wsdl/event.wsdl
soapcpp2 -2 -I path/gsoap/import onvif.h
where `-I path/gsoap/import` is a path to the `gsoap/import` directory in the gSOAP source code tree. To generate C code instead of C++, use wsdl2h option `-c`.
Option `soapcpp2 -2` forces SOAP 1.2, which is required by ONVIF. In some cases the wsdl2h conversion may not detect SOAP 1.2 and therefore we recommend this option.
Note that the specifications are substantial in size. Option `wsdl2h -P` removes unnecessary class hierarchy dependences on the root type `xsd__anyType`. This option will reduce the code size. Option `wsdl2h -x` removes extensibility elements (`xsd:anyAttribute` attributes and `xsd:any` elements). If attribute and element extensions to a complexType are needed, then use the typemap.dat file to add these as additional optional members. For example, to extend `tt__AudioDecoderConfigurationOptionsExtension` complexType class with an element `Address` of type `tt:IPAddress`, then add to typemap.dat:
[command]
tt__AudioDecoderConfigurationOptionsExtension = $ tt__IPAddress *Address;
After running wsdl2h we see that `tt__IPAddress *Address` is now part of the `tt__AudioDecoderConfigurationOptionsExtension` class or struct. A pointer is used to make this element optional when serialized.
Compile the soapcpp2-generated code together with `custom/duration.c`. For C++ builds, you should rename this file to `custom/duration.cpp`.
If WS-Discovery is used (e.g. with ONVIF remotediscovery), also include `plugin/wsddapi.h` in your code and compile `plugin/wsddapi.c` (see [WS-Discovery](doc/wsdd/html/wsdd_0.html) documentation).
If it appears that multiple service operations are generated with the same name, such as `GetServices` and `GetServices_` then remove `https://www.onvif.org/onvif/ver10/device/wsdl/devicemgmt.wsdl` from the command line list of URLs because this WSDL is already imported by another WSDL.
Please note that wsdl2h 2.8.10 and earlier versions generate ns1, ns2, ns3, etc prefixes when multiple service bindings are given for service operations. This will be changed in gSOAP 2.8.11 and up. The change can be made in 2.8.10 and earlier versions by modifying `gsoap/wsdl/service.cpp` at line 70:
void Definitions::analyze(const wsdl__definitions &definitions)
{ // Analyze WSDL and build Service information
int binding_count = 0;
// Determine number of relevant SOAP service bindings
if (service_prefix)
{ for (vector::const_iterator i =
definitions.binding.begin(); i != definitions.binding.end(); ++i)
{ for (vector::const_iterator j =
(*i).operation.begin(); j != (*i).operation.end(); ++j)
{ if ((*j).operationPtr() && (*j).input && (*j).input->soap__body_)
{ binding_count++;
break;
}
}
}
}
else
binding_count = 1; // Put all operations under a single binding
...
then rebuild wsdl2h. With this change, option `wsdl2h -Nns` reverts back to the old behavior.
How do I use gSOAP with the HL7 FHIR XML specifications?
---
In the typemap.dat file that is used by wsdl2h, add the following if not already there:
[command]
# FHIR recommended prefix
fhir = "https://hl7.org/fhir"
Create an `xhtml.h` file with the following:
#import "dom.h"
typedef xsd__anyType _xhtml__div;
This is essentially our XHTML data bindings file. Since we will use a DOM to store XHTML content, we declare `_xhtml__div` as a DOM `xsd__anyType` object. Only the `_xhtml__div` element (xhtml:div) is needed by FHIR, so this suffices.
At the command line prompt, run wsdl2h on the FHIR XSD. For example, the `fhir-single.xsd` that contains all FHIR definitions:
[command]
wsdl2h -o fhir.h https://hl7.org/implement/standards/fhir/fhir-single.xsd
soapcpp2 -0 -I path/gsoap/import fhir.h
where `-0` means we won't be using SOAP and `-I path/gsoap/import` is a path to the `gsoap/import` directory in the gSOAP source code tree. To generate C code instead of C++, use wsdl2h option `-c`.
This produces the XML data bindings for HL7 FHIR.
To implement REST XML with HTTP/S XML message exchanges, create a new header file `fhirx.h` with a wrapper function for each message exchange that you need. For example, a wrapper function for `` would be:
#import "fhir.h"
int __fhir__Account(
fhir__Appointment *fhir__Appointment_,
fhir__AppointmentResponse *fhir__AppointmentResponse_);
Keep adding more wrapper functions to `fhirx.h` as needed for your usage scenario. Note that `fhir.h` is imported, which was generated by wsdl2h in the previous steps. When implementing C code, don't forget to use `struct fhir__Appointment` and so on. Then run soapcpp2 on `fhirx.h` as follows to produce the REST code for the server and client sides:
[command]
soapcpp2 -0 -w -I path/gsoap/import fhirx.h
To generate C++ service and proxy classes (which are convenient in C++), use soapcpp2 option `-j`:
[command]
soapcpp2 -0 -w -I path/gsoap/import fhirx.h
Your C++ application code can now simply calls `Proxy::Appointment` to send and receive appointment data, for example:
#include "soapProxy.h"
const char *host = "https://yourfhirserver";
Proxy fhir(host, SOAP_XML_DEFAULTNS); // use xmlns="https://hl7.org/fhir" form
fhir__Appointent app; // stack alloc appointment data
app.status = soap_new_fhir__AppointmentStatus(Proxy.soap);
... // populate app.status
fhir__Appointment_x002eParticipant participant; // create participant
particpant.status = soap_new_fhir__ParticipationStatus(Proxy.soap);
... // populate participant.status
app.participant.push_back(&participant); // add one participant
... // populate additional app members
fhir__AppointentResponse appresp; // stack alloc response data
if (fhir.Appointment(&app, &appresp) == SOAP_OK)
... // use appresp data
If C++ compilation fails with an error similar to "expected class member or base class name" referring to the class member `assert`, then add the following lines to the typemap.dat file and rerun wsdl2h:
[
#include
#include "stdsoap2.h"
#undef assert
]
If this still does not compile, then add `#undef assert` manually to the soapStub.h file after the includes or rename `assert` to `assert_` with a trailing underscore.
How do I use gSOAP with STIX, CYBOX, and TAXII?
---
We recommend to add the following XML namespace bindings to typemap.dat:
[command]
# TAXII prefixes
taxi_111 = "https://docs.oasis-open.org/cti/ns/taxii/xml/binding-1.1.1"
tdq = "https://docs.oasis-open.org/cti/ns/taxii/default-query-1.1.1"
# STIX prefixes
campaign = "https://stix.mitre.org/Campaign-1"
coa = "https://stix.mitre.org/CourseOfAction-1"
et = "https://stix.mitre.org/ExploitTarget-1"
incident = "https://stix.mitre.org/Incident-1"
indicator = "https://stix.mitre.org/Indicator-2"
stixCommon = "https://stix.mitre.org/common-1"
stix = "https://stix.mitre.org/stix-1"
stixVocabs = "https://stix.mitre.org/default_vocabularies-1"
threat_actor = "https://stix.mitre.org/ThreatActor-1"
ttp = "https://stix.mitre.org/TTP-1"
report = "https://stix.mitre.org/Report-1"
stix-ciqaddress = "https://stix.mitre.org/extensions/Address#CIQAddress3.0-1"
capec = "https://stix.mitre.org/extensions/AP#CAPEC2.7-1"
stix-ciq = "https://stix.mitre.org/extensions/Identity#CIQIdentity3.0-1"
xpil = "urn:oasis:names:tc:ciq:xpil:3"
maec = "https://stix.mitre.org/extensions/Malware#MAEC4.1-1"
simpleMarking = "https://data-marking.mitre.org/extensions/MarkingStructure#Simple-1"
TOUMarking = "https://data-marking.mitre.org/extensions/MarkingStructure#Terms_Of_Use-1"
tlpMarking = "https://data-marking.mitre.org/extensions/MarkingStructure#TLP-1"
genericStructuredCOA = "https://stix.mitre.org/extensions/StructuredCOA#Generic-1"
genericTM = "https://stix.mitre.org/extensions/TestMechanism#Generic-1"
ioc-tr = "https://schemas.mandiant.com/2010/ioc/TR/"
ioc = "https://schemas.mandiant.com/2010/ioc"
oval = "https://stix.mitre.org/extensions/TestMechanism#OVAL5.10-1"
snortTM = "https://stix.mitre.org/extensions/TestMechanism#Snort-1"
yaraTM = "https://stix.mitre.org/extensions/TestMechanism#YARA-1"
stix-cvrf = "https://stix.mitre.org/extensions/Vulnerability#CVRF-1"
# CYBOX prefixes
cyboxCommon = "https://cybox.mitre.org/common-2"
cybox = "https://cybox.mitre.org/cybox-2"
cyboxVocabs = "https://cybox.mitre.org/default_vocabularies-2"
APIObj = "https://cybox.mitre.org/objects#APIObject-2"
ARPCacheObj = "https://cybox.mitre.org/objects#ARPCacheObject-1"
ASObj = "https://cybox.mitre.org/objects#ASObject-1"
AccountObj = "https://cybox.mitre.org/objects#AccountObject-2"
AddressObj = "https://cybox.mitre.org/objects#AddressObject-2"
ArchiveFileObj = "https://cybox.mitre.org/objects#ArchiveFileObject-1"
ArtifactObj = "https://cybox.mitre.org/objects#ArtifactObject-2"
CodeObj = "https://cybox.mitre.org/objects#CodeObject-2"
CustomObj = "https://cybox.mitre.org/objects#CustomObject-1"
DNSCacheObj = "https://cybox.mitre.org/objects#DNSCacheObject-2"
DNSQueryObj = "https://cybox.mitre.org/objects#DNSQueryObject-2"
DNSRecordObj = "https://cybox.mitre.org/objects#DNSRecordObject-2"
DeviceObj = "https://cybox.mitre.org/objects#DeviceObject-2"
DiskObj = "https://cybox.mitre.org/objects#DiskObject-2"
DiskPartitionObj = "https://cybox.mitre.org/objects#DiskPartitionObject-2"
DomainNameObj = "https://cybox.mitre.org/objects#DomainNameObject-1"
EmailMessageObj = "https://cybox.mitre.org/objects#EmailMessageObject-2"
FileObj = "https://cybox.mitre.org/objects#FileObject-2"
GUIDialogboxObj = "https://cybox.mitre.org/objects#GUIDialogboxObject-2"
GUIObj = "https://cybox.mitre.org/objects#GUIObject-2"
GUIWindowObj = "https://cybox.mitre.org/objects#GUIWindowObject-2"
HTTPSessionObj = "https://cybox.mitre.org/objects#HTTPSessionObject-2"
HostnameObj = "https://cybox.mitre.org/objects#HostnameObject-1"
ImageFileObj = "https://cybox.mitre.org/objects#ImageFileObject-1"
LibraryObj = "https://cybox.mitre.org/objects#LibraryObject-2"
LinkObj = "https://cybox.mitre.org/objects#LinkObject-1"
LinuxPackageObj = "https://cybox.mitre.org/objects#LinuxPackageObject-2"
MemoryObj = "https://cybox.mitre.org/objects#MemoryObject-2"
MutexObj = "https://cybox.mitre.org/objects#MutexObject-2"
NetworkConnectionObj = "https://cybox.mitre.org/objects#NetworkConnectionObject-2"
NetworkFlowObj = "https://cybox.mitre.org/objects#NetworkFlowObject-2"
NetworkPacketObj = "https://cybox.mitre.org/objects#PacketObject-2"
NetworkRouteEntryObj = "https://cybox.mitre.org/objects#NetworkRouteEntryObject-2"
NetworkRouteObj = "https://cybox.mitre.org/objects#NetworkRouteObject-2"
NetworkSocketObj = "https://cybox.mitre.org/objects#NetworkSocketObject-2"
NetworkSubnetObj = "https://cybox.mitre.org/objects#NetworkSubnetObject-2"
PDFFileObj = "https://cybox.mitre.org/objects#PDFFileObject-1"
PipeObj = "https://cybox.mitre.org/objects#PipeObject-2"
PortObj = "https://cybox.mitre.org/objects#PortObject-2"
ProcessObj = "https://cybox.mitre.org/objects#ProcessObject-2"
ProductObj = "https://cybox.mitre.org/objects#ProductObject-2"
SMSMessageObj = "https://cybox.mitre.org/objects#SMSMessageObject-1"
SemaphoreObj = "https://cybox.mitre.org/objects#SemaphoreObject-2"
SocketAddressObj = "https://cybox.mitre.org/objects#SocketAddressObject-1"
SystemObj = "https://cybox.mitre.org/objects#SystemObject-2"
URIObj = "https://cybox.mitre.org/objects#URIObject-2"
URLHistoryObj = "https://cybox.mitre.org/objects#URLHistoryObject-1"
UnixFileObj = "https://cybox.mitre.org/objects#UnixFileObject-2"
UnixNetworkRouteEntryObj = "https://cybox.mitre.org/objects#UnixNetworkRouteEntryObject-2"
UnixPipeObj = "https://cybox.mitre.org/objects#UnixPipeObject-2"
UnixProcessObj = "https://cybox.mitre.org/objects#UnixProcessObject-2"
UnixUserAccountObj = "https://cybox.mitre.org/objects#UnixUserAccountObject-2"
UnixVolumeObj = "https://cybox.mitre.org/objects#UnixVolumeObject-2"
UserAccountObj = "https://cybox.mitre.org/objects#UserAccountObject-2"
UserSessionObj = "https://cybox.mitre.org/objects#UserSessionObject-2"
VolumeObj = "https://cybox.mitre.org/objects#VolumeObject-2"
WhoisObj = "https://cybox.mitre.org/objects#WhoisObject-2"
WinComputerAccountObj = "https://cybox.mitre.org/objects#WinComputerAccountObject-2"
WinCriticalSectionObj = "https://cybox.mitre.org/objects#WinCriticalSectionObject-2"
WinDriverObj = "https://cybox.mitre.org/objects#WinDriverObject-3"
WinEventLogObj = "https://cybox.mitre.org/objects#WinEventLogObject-2"
WinEventObj = "https://cybox.mitre.org/objects#WinEventObject-2"
WinExecutableFileObj = "https://cybox.mitre.org/objects#WinExecutableFileObject-2"
WinFileObj = "https://cybox.mitre.org/objects#WinFileObject-2"
WinFilemappingObj = "https://cybox.mitre.org/objects#WinFilemappingObject-1"
WinHandleObj = "https://cybox.mitre.org/objects#WinHandleObject-2"
WinHookObj = "https://cybox.mitre.org/objects#WinHookObject-1"
WinKernelHookObj = "https://cybox.mitre.org/objects#WinKernelHookObject-2"
WinKernelObj = "https://cybox.mitre.org/objects#WinKernelObject-2"
WinMailslotObj = "https://cybox.mitre.org/objects#WinMailslotObject-2"
WinMemoryPageRegionObj = "https://cybox.mitre.org/objects#WinMemoryPageRegionObject-2"
WinMutexObj = "https://cybox.mitre.org/objects#WinMutexObject-2"
WinNetworkRouteEntryObj = "https://cybox.mitre.org/objects#WinNetworkRouteEntryObject-2"
WinNetworkShareObj = "https://cybox.mitre.org/objects#WinNetworkShareObject-2"
WinPipeObj = "https://cybox.mitre.org/objects#WinPipeObject-2"
WinPrefetchObj = "https://cybox.mitre.org/objects#WinPrefetchObject-2"
WinProcessObj = "https://cybox.mitre.org/objects#WinProcessObject-2"
WinRegistryKeyObj = "https://cybox.mitre.org/objects#WinRegistryKeyObject-2"
WinSemaphoreObj = "https://cybox.mitre.org/objects#WinSemaphoreObject-2"
WinServiceObj = "https://cybox.mitre.org/objects#WinServiceObject-2"
WinSystemObj = "https://cybox.mitre.org/objects#WinSystemObject-2"
WinSystemRestoreObj = "https://cybox.mitre.org/objects#WinSystemRestoreObject-2"
WinTaskObj = "https://cybox.mitre.org/objects#WinTaskObject-2"
WinThreadObj = "https://cybox.mitre.org/objects#WinThreadObject-2"
WinUserAccountObj = "https://cybox.mitre.org/objects#WinUserAccountObject-2"
WinVolumeObj = "https://cybox.mitre.org/objects#WinVolumeObject-2"
WinWaitableTimerObj = "https://cybox.mitre.org/objects#WinWaitableTimerObject-2"
X509CertificateObj = "https://cybox.mitre.org/objects#X509CertificateObject-2"
To run wsdl2h on the specifications we recommend to use option `-u` to fold C unions into structs. Furthermore, soapcpp2 will complain about duplicate member names for schema attribute declarations that are reduced to fixed values. The only concern here is that you will need to make sure that the fixed values are used in XML messaging.
How do I use gSOAP with the XLIFF 2.0 specification?
---
Use gSOAP 2.8.10 or greater. In the typemap.dat file used by wsdl2h, add:
[command]
xliff = "urn:oasis:names:tc:xliff:document:2.0"
xliff__priorityValue = typedef int xliff__priorityValue 1:10;
Run wsdl2h on the XLIFF 2.0 schema. We recommend option `-u` to remove `union` types, making the code cleaner. You may also want to use option `-d` to replace XML strings with DOM nodes.
[command]
wsdl2h -u -o xliff2.h https://docs.oasis-open.org/xliff/xliff-core/v2.0/os/schemas/xliff_core_2.0.xsd
Then run soapcpp2 and compile with your code soapC.cpp that contains the serializers (which are declared in the generated soapStub.h and soapH.h):
[command]
soapcpp2 -0 -I gsoap/import xliff2.h
c++ soapC.cpp ...
Here is an example that creates an xliff 2.0 document:
#include "soapH.h"
#include "xliff.nsmap"
// Make allocation and assignment of primitive values quick and easy:
template
T * soap_make(struct soap *soap, T val = T())
{
T *p = (T*)soap_malloc(soap, sizeof(T));
*p = val;
return p;
}
// Make allocation and assignment of std::string quick and easy:
std::string * soap_make_string(struct soap *soap, const char *s = "")
{
std::string *p = soap_new_std__string(soap);
*p = s;
return p;
}
...
// create a context
soap *soap = soap_new1(SOAP_XML_INDENT);
//create a XLIFF 2.0 doc
_xliff__xliff *doc = soap_new__xliff__xliff(soap);
doc->soap_default(soap);
doc->version = "2.0";
doc->srcLang = "en";
doc->trgLang = "fr";
// add
_xliff__file *file = soap_new__xliff__file(soap);
file->soap_default(soap);
doc->file.push_back(file);
file->id = "f1";
// add
_xliff__notes *notes = soap_new__xliff__notes(soap);
notes->soap_default(soap);
file->notes = notes;
// add
_xliff__note *note = soap_new__xliff__note(soap);
note->soap_default(soap);
notes->note.push_back(note);
note->id = soap_make_string(soap, "n1");
note->__mixed = (char*)"note for file.";
// add
_xliff__unit *unit = soap_new__xliff__unit(soap);
unit->soap_default(soap);
unit->id = "u1";
file->__size_file = 1;
file->__union_file = soap_new___xliff__union_file(soap, 1); // array of 1
file->__union_file->soap_default(soap);
file->__union_file->unit = unit;
// add
_xliff__segment *segment = soap_new__xliff__segment(soap);
segment->soap_default(soap);
segment->id = soap_make_string(soap, "s1");
unit->__size_unit = 1;
unit->__union_unit = soap_new___xliff__union_unit(soap, 1); // array of 1
unit->__union_unit->soap_default(soap);
unit->__union_unit->segment = segment;
// add