~ifolder-dev/simias/trunk-packaging

« back to all changes in this revision

Viewing changes to tools/gsoap/gsoap-linux-2.7/doc/wsa/.svn/text-base/wsaapi.c.svn-base

  • Committer: Jorge O. Castro
  • Date: 2007-12-03 06:56:46 UTC
  • Revision ID: jorge@ubuntu.com-20071203065646-mupcnjcwgm5mnhyt
* Remove a bunch of .svn directories we no longer need.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 
3
 
wsaapi.c
4
 
 
5
 
WS-Addressing plugin for stand-alone services.
6
 
 
7
 
gSOAP XML Web services tools
8
 
Copyright (C) 2000-2007, Robert van Engelen, Genivia Inc., All Rights Reserved.
9
 
This part of the software is released under one of the following licenses:
10
 
GPL, the gSOAP public license, or Genivia's license for commercial use.
11
 
--------------------------------------------------------------------------------
12
 
gSOAP public license.
13
 
 
14
 
The contents of this file are subject to the gSOAP Public License Version 1.3
15
 
(the "License"); you may not use this file except in compliance with the
16
 
License. You may obtain a copy of the License at
17
 
http://www.cs.fsu.edu/~engelen/soaplicense.html
18
 
Software distributed under the License is distributed on an "AS IS" basis,
19
 
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
20
 
for the specific language governing rights and limitations under the License.
21
 
 
22
 
The Initial Developer of the Original Code is Robert A. van Engelen.
23
 
Copyright (C) 2000-2007, Robert van Engelen, Genivia Inc., All Rights Reserved.
24
 
--------------------------------------------------------------------------------
25
 
GPL license.
26
 
 
27
 
This program is free software; you can redistribute it and/or modify it under
28
 
the terms of the GNU General Public License as published by the Free Software
29
 
Foundation; either version 2 of the License, or (at your option) any later
30
 
version.
31
 
 
32
 
This program is distributed in the hope that it will be useful, but WITHOUT ANY
33
 
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
34
 
PARTICULAR PURPOSE. See the GNU General Public License for more details.
35
 
 
36
 
You should have received a copy of the GNU General Public License along with
37
 
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
38
 
Place, Suite 330, Boston, MA 02111-1307 USA
39
 
 
40
 
Author contact information:
41
 
engelen@genivia.com / engelen@acm.org
42
 
--------------------------------------------------------------------------------
43
 
A commercial use license is available from Genivia, Inc., contact@genivia.com
44
 
--------------------------------------------------------------------------------
45
 
*/
46
 
 
47
 
/**
48
 
 
49
 
@mainpage
50
 
 
51
 
- @ref wsa documents the wsa plugin for WS-Addressing (2003/2004/2005
52
 
  standards) support.
53
 
 
54
 
*/
55
 
 
56
 
/**
57
 
 
58
 
@page wsa The wsa plugin for stand-alone services
59
 
 
60
 
@section wsa_1 WS-Addressing Setup
61
 
 
62
 
The material in this section relates to the WS-Addressing specification.
63
 
 
64
 
To use the wsa plugin:
65
 
-# Run wsdl2h -t typemap.dat on a WSDL of a service that requires WS-Addressing
66
 
   headers. The typemap.dat file included in the gSOAP package is used to
67
 
   recognize and translate Addressing header blocks.
68
 
-# Run soapcpp2 -a on the header file produced by wsdl2h. To enable
69
 
   addressing-based service operation selection, you MUST use soapcpp2 option
70
 
   -a. This allows the service to dispatch methods based on the WS-Addressing
71
 
   action information header value (assuming the wsa plugin is registered).
72
 
-# (Re-)compile stdsoap2.c/pp, dom.c/pp, wsaapi.c and the generated
73
 
   source files.
74
 
-# Use the wsa plugin API functions described below.
75
 
 
76
 
An example wsa client/server application can be found in samples/wsa.
77
 
 
78
 
To use WS-Addressing, the gSOAP header file for a service should declare a SOAP
79
 
Header with the required WS-Addressing information headers. The header file is
80
 
automatically generated by wsdl2h for a set of WSDLs. The gSOAP header file is
81
 
further processed by soapcpp2 to generate the binding code.
82
 
 
83
 
The SOAP Header structure contains the WS-Addressing information headers
84
 
extracted from the WSDL and the WS-Addressing specification. For example:
85
 
@code
86
 
#import "soap12.h"
87
 
#import "wsa.h" // or wsa3.h (2003/03), wsa4.h (2004/03), wsa5.h (2005/03)
88
 
 
89
 
struct SOAP_ENV__Header
90
 
{
91
 
                 _wsa__MessageID  wsa__MessageID 0;
92
 
                 _wsa__RelatesTo *wsa__RelatesTo 0;
93
 
                 _wsa__From      *wsa__From      0;
94
 
  mustUnderstand _wsa__ReplyTo   *wsa__ReplyTo   0;
95
 
  mustUnderstand _wsa__FaultTo   *wsa__FaultTo   0;
96
 
  mustUnderstand _wsa__To         wsa__To        0;
97
 
  mustUnderstand _wsa__Action     wsa__Action    0;
98
 
};
99
 
@endcode
100
 
Note: when importing wsa3.h, wsa4.h, or wsa5.h use type and member names
101
 
prefixed with wsa3, wsa4, and wsa5, respectively. The mustUnderstand qualifier
102
 
ensures that the information headers must be understood by a receiving SOAP
103
 
processor.
104
 
 
105
 
The SOAP Header struct is automatically generated by wsdl2h from a WSDL. But it
106
 
must be manually defined when creating new services from gSOAP header files.
107
 
In either case, the gSOAP header file is processed with soapcpp2 to generate
108
 
the client-side and/or server-side binding code.
109
 
 
110
 
Note that the wsa.h header file located in the import directory of the gSOAP
111
 
package declares the WS-Addressing information header elements and types. The
112
 
soap12.h header file enables SOAP 1.2 messaging.
113
 
 
114
 
For developers: the WS-Addressing header blocks in wsa.h were generated from
115
 
the WS-Addressing schema with the wsdl2h tool and WS/WS-typemap.dat as follows:
116
 
 
117
 
@code
118
 
    $ wsdl2h -cegy -o wsa.h -t WS/WS-typemap.dat WS/WS-Addressing.xsd
119
 
@endcode
120
 
Refer to wsa.h for more details.
121
 
 
122
 
@section wsa_2 Client-side Usage
123
 
 
124
 
@subsection wsa_2_1 Constructing WS-Addressing Information Headers
125
 
 
126
 
To associate WS-Addressing information headers with service operations, the
127
 
SOAP Header struct must have been defined and for each service operation that
128
 
uses WS-Addressing method-header-part directives should be used in the gSOAP
129
 
header file of the service as follows:
130
 
@code
131
 
#import "wsa.h"
132
 
 
133
 
struct SOAP_ENV__Header { ... };
134
 
 
135
 
//gsoap ns service method-header-part: example wsa__MessageID
136
 
//gsoap ns service method-header-part: example wsa__RelatesTo
137
 
//gsoap ns service method-header-part: example wsa__From
138
 
//gsoap ns service method-header-part: example wsa__ReplyTo
139
 
//gsoap ns service method-header-part: example wsa__FaultTo
140
 
//gsoap ns service method-header-part: example wsa__To
141
 
//gsoap ns service method-header-part: example wsa__Action
142
 
//gsoap ns service method-action: example urn:example/examplePort/example
143
 
int ns__example(char *in, struct ns__exampleResponse *out);
144
 
@endcode
145
 
 
146
 
In the client-side code, the WS-Addressing information headers are set with
147
 
soap_wsa_request() by passing an optional message UUID string, a mandatory
148
 
destination address URI string, and a mandatory request action URI string. The
149
 
wsa plugin should be registered with the currenct soap struct context. An
150
 
optional source address information header can be added with
151
 
soap_wsa_add_From() (must be invoked after the soap_wsa_request call).
152
 
 
153
 
For example:
154
 
@code
155
 
soap_register_plugin(soap, soap_wsa);
156
 
 
157
 
soap_wsa_request(soap, RequestMessageID, ToAddress, RequestAction);
158
 
soap_wsa_add_From(soap, FromAddress); // optional: add a 'From' address
159
 
 
160
 
if (soap_call_ns__example(soap, ToAddress, NULL, ...))
161
 
  soap_print_fault(soap, stderr); // an error occurred
162
 
else
163
 
  // process the response 
164
 
@endcode
165
 
 
166
 
@subsection wsa_2_2 Information Headers for Relaying Server Responses
167
 
 
168
 
To relay the response to another destination, the WS-Addressing ReplyTo
169
 
information header is added with soap_wsa_add_ReplyTo() by passing a reply
170
 
address URI string. The service returns HTTP 202 ACCEPTED to the client when
171
 
the response message relay was successful.
172
 
 
173
 
For example:
174
 
@code
175
 
soap_register_plugin(soap, soap_wsa);
176
 
 
177
 
soap_wsa_request(soap, RequestMessageID, ToAddress, RequestAction);
178
 
soap_wsa_add_From(soap, FromAddress); // optional: add a 'From' address
179
 
soap_wsa_add_ReplyTo(soap, ReplyToAddress);
180
 
 
181
 
if (soap_call_ns__example(soap, ToAddress, NULL, ...))
182
 
{
183
 
  if (soap->error == 202) // HTTP ACCEPTED
184
 
    printf("Request was accepted and results were forwarded\n");
185
 
  else
186
 
    soap_print_fault(soap, stderr); // an error occurred
187
 
}
188
 
else
189
 
  // error: for some reason the response was not relayed
190
 
@endcode
191
 
 
192
 
Note: the response message will be relayed when the From address is absent or
193
 
different than the ReplyTo address
194
 
 
195
 
@subsection wsa_2_3 Information Headers for Relaying Server Faults
196
 
 
197
 
To relay a server fault message to another destination, the WS-Addressing
198
 
FaultTo information header is added with soap_wsa_add_FaultTo() by passing a
199
 
relay address URI string. The service returns HTTP 202 ACCEPTED to the client
200
 
when the fault was relayed.
201
 
 
202
 
For example:
203
 
@code
204
 
soap_register_plugin(soap, soap_wsa);
205
 
 
206
 
soap_wsa_request(soap, RequestMessageID, ToAddress, RequestAction);
207
 
soap_wsa_add_From(soap, FromAddress); // optional: add a 'From' address
208
 
soap_wsa_add_FaultTo(soap, FaultToAddress);
209
 
 
210
 
if (soap_call_ns__example(soap, ToAddress, NULL, ...))
211
 
{
212
 
  if (soap->error == 202) // HTTP ACCEPTED
213
 
    printf("A fault occurred and the fault details were forwarded\n");
214
 
  else
215
 
    soap_print_fault(soap, stderr); // a connection error occurred
216
 
}
217
 
else
218
 
  // process response 
219
 
@endcode
220
 
 
221
 
Note that the call can still return a fault, such as a connection error when
222
 
the service is not responding. In addition to the fault relay, the responses
223
 
can be relayed with soap_wsa_add_ReplyTo().
224
 
 
225
 
@subsection wsa_2_4 Error Handling
226
 
 
227
 
SOAP and HTTP errors set the soap->error attribute, as shown in this example:
228
 
@code
229
 
if (soap_call_ns__example(soap, ToAddress, NULL, ...))
230
 
{
231
 
  if (soap->error == 202) // HTTP ACCEPTED
232
 
    printf("A fault occurred and the fault details were forwarded\n");
233
 
  else
234
 
    soap_print_fault(soap, stderr); // a connection error occurred
235
 
}
236
 
else
237
 
  // process response 
238
 
@endcode
239
 
When a WS-Addressing error occurred, the a wsa error code is stored in the SOAP
240
 
Fault Subcode field. This information can be retrieved with:
241
 
@code
242
 
wsa__FaultSubcodeValues fault;
243
 
if (soap_wsa_check_fault(soap, &fault))
244
 
{
245
 
  switch (fault)
246
 
  {
247
 
    case wsa__InvalidMessageInformationHeader: ...
248
 
    case wsa__MessageInformationHeaderRequired: ...
249
 
    case wsa__DestinationUreachable: ...
250
 
    case wsa__ActionNotSupported: ...
251
 
    case wsa__EndpointUnavailable: ...
252
 
  }
253
 
}
254
 
@endcode
255
 
When using wsa5.h, please refer to the standards and fault codes for this
256
 
implementation. For the wsa5.h 2005/03 standard, several faults have an
257
 
additional parameter (SOAP Fault detail):
258
 
@code
259
 
wsa5__FaultCodesType fault;
260
 
char *info;
261
 
if (soap_wsa_check_fault(soap, &fault, &info))
262
 
{
263
 
  switch (fault)
264
 
  {
265
 
    case wsa5__InvalidAddressingHeader:
266
 
      if (info)
267
 
        printf("The invalid addressing header element is %s\n", info);
268
 
    ...
269
 
  }
270
 
}
271
 
@endcode
272
 
 
273
 
@section wsa_3 Server-side Usage
274
 
 
275
 
The wsa plugin should be registered with:
276
 
@code
277
 
soap_register_plugin(soap, soap_wsa);
278
 
@endcode
279
 
 
280
 
Once the plugin is registered, the soap_bind(), soap_accept(), and soap_serve() functions can be called to process requests.
281
 
 
282
 
Important: to dispatch service operations based on the WS-Addressing wsa:Action
283
 
information header, use soapcpp2 option -a. The generates a new dispatcher (in
284
 
soapServer.c) based on the action value.
285
 
 
286
 
A service operation implementation should use soap_wsa_check() to verify the
287
 
validity of the WS-Addressing information headers in the SOAP request message.
288
 
To allow response message to be automatically relayed based on the ReplyTo
289
 
information header, the service operation should return soap_wsa_reply() with
290
 
an optional message UUID string and a mandatory response action string.
291
 
 
292
 
For example:
293
 
@code
294
 
int ns__example(struct soap *soap, char *in, struct ns__exampleResponse *out)
295
 
{ if (soap_wsa_check(soap))
296
 
    return soap->error;
297
 
  // ... service logic
298
 
  return soap_wsa_reply(soap, ResponseMessageID, ResponseAction);
299
 
}
300
 
@endcode
301
 
 
302
 
To return a SOAP fault that is automatically relayed to a fault service based
303
 
on the FaultTo information header, the soap_wsa_sender_fault(),
304
 
soap_wsa_receiver_fault(), soap_wsa_sender_fault_subcode(), and
305
 
soap_wsa_receiver_fault_subcode() functions should be used instead of the
306
 
soap_sender_fault(), soap_receiver_fault(), soap_sender_fault_subcode(), and
307
 
soap_receiver_fault_subcode(), respectively.
308
 
 
309
 
For example:
310
 
@code
311
 
int ns__example(struct soap *soap, char *in, struct ns__exampleResponse *out)
312
 
{ if (soap_wsa_check(soap))
313
 
    return soap->error;
314
 
  // ... service logic
315
 
  // ... an error occurred, need to return fault possibly to fault service:
316
 
    return soap_wsa_sender_fault(soap, "Exception in service operation", NULL);
317
 
  // ... normal execution continues
318
 
  return soap_wsa_reply(soap, ResponseMessageID, ResponseAction);
319
 
}
320
 
@endcode
321
 
 
322
 
@section wsa_4 Implementing a Server for Handling ReplyTo Response Messages
323
 
 
324
 
To implement a separate server for handling relayed SOAP response messages
325
 
based on the ReplyTo information header in the request message, the gSOAP
326
 
header file should include a one-way service operation for the response
327
 
message.
328
 
 
329
 
For example, suppose a service operation returns an exampleResponse message. We
330
 
declare the one-way exampleResponse operation as follows:
331
 
@code
332
 
#import "wsa.h"
333
 
 
334
 
struct SOAP_ENV__Header { ... };
335
 
 
336
 
//gsoap ns service method-header-part: exampleResult wsa__MessageID
337
 
//gsoap ns service method-header-part: exampleResult wsa__RelatesTo
338
 
//gsoap ns service method-header-part: exampleResult wsa__From
339
 
//gsoap ns service method-header-part: exampleResult wsa__ReplyTo
340
 
//gsoap ns service method-header-part: exampleResult wsa__FaultTo
341
 
//gsoap ns service method-header-part: exampleResult wsa__To
342
 
//gsoap ns service method-header-part: exampleResult wsa__Action
343
 
//gsoap ns service method-action: exampleResult urn:example/examplePort/exampleResponse
344
 
int ns__exampleResponse(char *out, void);
345
 
@endcode
346
 
 
347
 
Note that the action information is important, because it is used by the
348
 
service dispatcher (assuming soapcpp2 option -a is used).
349
 
 
350
 
The implementation in the server code uses soap_wsa_check() to check the
351
 
presense and validity of the WS-Addressing information header in the message.
352
 
The soap_send_empty_response() function should be used to return an
353
 
acknowledgment HTTP header with HTTP 202 ACCEPTED to the sender:
354
 
@code
355
 
int ns__exampleResponse(struct soap *soap, char *out)
356
 
{ if (soap_wsa_check(soap))
357
 
    return soap_send_empty_response(soap, 500); // HTTP 500 Internal Server Error
358
 
  // ... service logic
359
 
  return soap_send_empty_response(soap, SOAP_OK); // HTTP 202 ACCEPTED
360
 
}
361
 
@endcode
362
 
 
363
 
@section wsa_5 Implementing a Server for Handling FaultTo Fault Messages
364
 
 
365
 
To implement a separate server for handling relayed SOAP fault messages based
366
 
on the FaultTo information header in the request message, the gSOAP header file
367
 
for soapcpp2 should include a SOAP fault service operation. This operation
368
 
accepts fault messages that are relayed by other services.
369
 
 
370
 
Basically, we use a trick to generate the SOAP-ENV:Fault struct via a one-way
371
 
service operation. This allows us both to implement a one-way service operation
372
 
that accepts faults and to automatically generate the fault struct for fault
373
 
data storage and manipulation. 
374
 
 
375
 
The fault operation in the header file should be declared as follows (for the
376
 
2004/08 standard):
377
 
@code
378
 
//gsoap SOAP_ENV service method-action: Fault http://schemas.xmlsoap.org/ws/2004/08/addressing/fault
379
 
int SOAP_ENV__Fault
380
 
(       _QName                   faultcode,             // SOAP 1.1
381
 
        char                    *faultstring,           // SOAP 1.1
382
 
        char                    *faultactor,            // SOAP 1.1
383
 
        struct SOAP_ENV__Detail *detail,                // SOAP 1.1
384
 
        struct SOAP_ENV__Code   *SOAP_ENV__Code,        // SOAP 1.2
385
 
        struct SOAP_ENV__Reason *SOAP_ENV__Reason,      // SOAP 1.2
386
 
        char                    *SOAP_ENV__Node,        // SOAP 1.2
387
 
        char                    *SOAP_ENV__Role,        // SOAP 1.2
388
 
        struct SOAP_ENV__Detail *SOAP_ENV__Detail,      // SOAP 1.2
389
 
        void
390
 
);
391
 
@endcode
392
 
 
393
 
Because each service operation has a struct to hold its input parameters, we
394
 
automatically generate the (original) SOAP_ENV__Fault struct on the fly!
395
 
 
396
 
Note: it is important to associate the wsa fault action with this operation as
397
 
shown above.
398
 
 
399
 
The implementation of the service operation in the server code is:
400
 
@code
401
 
int SOAP_ENV__Fault(struct soap *soap, char *faultcode, char *faultstring, char *faultactor, struct SOAP_ENV__Detail *detail, struct SOAP_ENV__Code *SOAP_ENV__Code, struct SOAP_ENV__Reason *SOAP_ENV__Reason, char *SOAP_ENV__Node, char *SOAP_ENV__Role, struct SOAP_ENV__Detail *SOAP_ENV__Detail)
402
 
403
 
  ... = faultcode; // SOAP 1.1 fault code string (QName)
404
 
  ... = faultstring; // SOAP 1.1 fault string
405
 
  ... = faultactor; // SOAP 1.1 fault actor string
406
 
  ... = detail; // SOAP 1.1 fault detail struct
407
 
  ... = SOAP_ENV__Code; // SOAP 1.2 fault code struct
408
 
  ... = SOAP_ENV__Reason; // SOAP 1.2 reason struct
409
 
  ... = SOAP_ENV__Node; // SOAP 1.2 node string
410
 
  ... = SOAP_ENV__Role; // SOAP 1.2 role string
411
 
  ... = SOAP_ENV__Detail; // SOAP 1.2 detail struct
412
 
  return SOAP_OK;
413
 
}
414
 
@endcode
415
 
 
416
 
Note that SOAP 1.1 or SOAP 1.2 parameters are set based on the 1.1/1.2
417
 
messaging requirements.
418
 
 
419
 
*/
420
 
 
421
 
#include "wsaapi.h"
422
 
 
423
 
/** Plugin identification for plugin registry */
424
 
const char soap_wsa_id[13] = SOAP_WSA_ID;
425
 
 
426
 
#if defined(SOAP_WSA_2003)
427
 
/** Anonymous Reply/To endpoint address */
428
 
const char *soap_wsa_anonymousURI = "http://schemas.xmlsoap.org/ws/2003/03/addressing/role/anonymous";
429
 
/** Specifies no Reply endpoint address (no reply) */
430
 
const char *soap_wsa_noneURI = "addressing/none not supported";
431
 
const char *soap_wsa_faultAction = "http://schemas.xmlsoap.org/ws/2003/03/addressing/fault";
432
 
#elif defined(SOAP_WSA_2004)
433
 
/** Anonymous Reply/To endpoint address */
434
 
const char *soap_wsa_anonymousURI = "http://schemas.xmlsoap.org/ws/2004/03/addressing/role/anonymous";
435
 
/** Specifies no Reply endpoint address (no reply) */
436
 
const char *soap_wsa_noneURI = "addressing/none not supported";
437
 
const char *soap_wsa_faultAction = "http://schemas.xmlsoap.org/ws/2004/03/addressing/fault";
438
 
#elif defined(SOAP_WSA_2005)
439
 
/** Anonymous Reply/To endpoint address */
440
 
const char *soap_wsa_anonymousURI = "http://www.w3.org/2005/08/addressing/anonymous";
441
 
/** Specifies no Reply endpoint address (no reply) */
442
 
const char *soap_wsa_noneURI = "http://www.w3.org/2005/08/addressing/none";
443
 
const char *soap_wsa_faultAction = "http://www.w3.org/2005/08/addressing/soap/fault";
444
 
#else
445
 
/** Anonymous Reply/To endpoint address */
446
 
const char *soap_wsa_anonymousURI = "http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous";
447
 
/** Specifies no Reply endpoint address (no reply) */
448
 
const char *soap_wsa_noneURI = "addressing/none not supported";
449
 
const char *soap_wsa_faultAction = "http://schemas.xmlsoap.org/ws/2004/08/addressing/fault";
450
 
#endif
451
 
 
452
 
/******************************************************************************\
453
 
 *
454
 
 * Static protos
455
 
 *
456
 
\******************************************************************************/
457
 
 
458
 
static int soap_wsa_fault_subcode(struct soap *soap, int flag, const char *faultsubcode, const char *faultstring, const char *faultdetail);
459
 
 
460
 
static int soap_wsa_init(struct soap *soap, struct soap_wsa_data *data);
461
 
static void soap_wsa_delete(struct soap *soap, struct soap_plugin *p);
462
 
 
463
 
static int soap_wsa_header(struct soap *soap);
464
 
static void soap_wsa_set_error(struct soap *soap, const char **c, const char **s);
465
 
static int soap_wsa_response(struct soap *soap, int status, size_t count);
466
 
 
467
 
static int soap_wsa_alloc_header(struct soap *soap);
468
 
 
469
 
/******************************************************************************\
470
 
 *
471
 
 * Client-side Request
472
 
 *
473
 
\******************************************************************************/
474
 
 
475
 
/**
476
 
@fn int soap_wsa_request(struct soap *soap, const char *id, const char *to, const char *action)
477
 
@brief Sets the WS-Addressing information header for the next request message
478
 
with optional MessageID, To (required), and Action (required).
479
 
@param soap
480
 
context
481
 
@param[in] id is the message ID (optional)
482
 
@param[in] to is the target endpoint (required)
483
 
@param[in] action is the target action (required)
484
 
@return SOAP_OK
485
 
 
486
 
Note: use soap_wsa_add_From, soap_wsa_add_ReplyTo, soap_wsa_add_FaultTo to add
487
 
other addressing fields following this function call.
488
 
*/
489
 
int
490
 
soap_wsa_request(struct soap *soap, const char *id, const char *to, const char *action)
491
 
{ soap_wsa_alloc_header(soap);
492
 
  soap_default_SOAP_ENV__Header(soap, soap->header);
493
 
  soap->header->SOAP_WSA(MessageID) = soap_strdup(soap, id);
494
 
  soap->header->SOAP_WSA(To) = soap_strdup(soap, to);
495
 
  soap->header->SOAP_WSA(Action) = soap_strdup(soap, action);
496
 
  return SOAP_OK;
497
 
}
498
 
 
499
 
/**
500
 
@fn int soap_wsa_add_From(struct soap *soap, const char *from)
501
 
@brief Sets WS-Addressing From header for request message.
502
 
@param soap context
503
 
@param[in] from endpoint URI 
504
 
@return SOAP_OK or SOAP_ERR
505
 
 
506
 
Use soap_wsa_request to populate the WS-Addressing header first.
507
 
*/
508
 
int
509
 
soap_wsa_add_From(struct soap *soap, const char *from)
510
 
{ if (!soap->header)
511
 
    return SOAP_ERR;
512
 
  soap->header->SOAP_WSA(From) = (SOAP_WSA_(,From)*)soap_malloc(soap, sizeof(SOAP_WSA_(,From)));
513
 
  SOAP_WSA_(soap_default,EndpointReferenceType)(soap, soap->header->SOAP_WSA(From));
514
 
  soap->header->SOAP_WSA(From)->Address = soap_strdup(soap, from);
515
 
  return SOAP_OK;
516
 
}
517
 
 
518
 
/**
519
 
@fn int soap_wsa_add_NoReply(struct soap *soap)
520
 
@brief Sets WS-Addressing ReplyTo header to 'none' (no reply)
521
 
@param soap context
522
 
@return SOAP_OK or SOAP_ERR
523
 
 
524
 
Note: WS-Addressing 2005/08 standard.
525
 
 
526
 
Use soap_wsa_request to populate the WS-Addressing header.
527
 
*/
528
 
int
529
 
soap_wsa_add_NoReply(struct soap *soap)
530
 
{ return soap_wsa_add_ReplyTo(soap, soap_wsa_noneURI); 
531
 
}
532
 
 
533
 
/**
534
 
@fn int soap_wsa_add_ReplyTo(struct soap *soap, const char *replyTo)
535
 
@brief Sets WS-Addressing ReplyTo header for request message.
536
 
@param soap context
537
 
@param[in] replyTo endpoint URI 
538
 
@return SOAP_OK or SOAP_ERR
539
 
 
540
 
Use soap_wsa_request to populate the WS-Addressing header.
541
 
*/
542
 
int
543
 
soap_wsa_add_ReplyTo(struct soap *soap, const char *replyTo)
544
 
{ if (!soap->header)
545
 
    return SOAP_ERR;
546
 
  if (replyTo)
547
 
  { soap->header->SOAP_WSA(ReplyTo) = (SOAP_WSA_(,ReplyTo)*)soap_malloc(soap, sizeof(SOAP_WSA_(,ReplyTo)));
548
 
    SOAP_WSA_(soap_default,EndpointReferenceType)(soap, soap->header->SOAP_WSA(ReplyTo));
549
 
    soap->header->SOAP_WSA(ReplyTo)->Address = soap_strdup(soap, replyTo);
550
 
  }
551
 
  return SOAP_OK;
552
 
}
553
 
 
554
 
/**
555
 
@fn int soap_wsa_add_FaultTo(struct soap *soap, const char *faultTo)
556
 
@brief Sets WS-Addressing FaultTo header for request message.
557
 
@param soap context
558
 
@param[in] faultTo endpoint URI 
559
 
@return SOAP_OK or SOAP_ERR
560
 
 
561
 
Use soap_wsa_request to populate the WS-Addressing header first.
562
 
*/
563
 
int
564
 
soap_wsa_add_FaultTo(struct soap *soap, const char *faultTo)
565
 
{ if (!soap->header)
566
 
    return SOAP_ERR;
567
 
  if (faultTo)
568
 
  { soap->header->SOAP_WSA(FaultTo) = (SOAP_WSA_(,FaultTo)*)soap_malloc(soap, sizeof(SOAP_WSA_(,FaultTo)));
569
 
    SOAP_WSA_(soap_default,EndpointReferenceType)(soap, soap->header->SOAP_WSA(FaultTo));
570
 
    soap->header->SOAP_WSA(FaultTo)->Address = soap_strdup(soap, faultTo);
571
 
  }
572
 
  return SOAP_OK;
573
 
}
574
 
 
575
 
/******************************************************************************\
576
 
 *
577
 
 * Server-side Check
578
 
 *
579
 
\******************************************************************************/
580
 
 
581
 
/**
582
 
@fn int soap_wsa_check(struct soap *soap)
583
 
@brief Checks the presence and validity of WS-Addressing information headers.
584
 
@param soap context
585
 
@return SOAP_OK or fault
586
 
*/
587
 
int
588
 
soap_wsa_check(struct soap *soap)
589
 
{ if (!soap->header || !soap->header->SOAP_WSA(To) || !soap->header->SOAP_WSA(Action))
590
 
#if defined(SOAP_WSA_2005)
591
 
    return soap_wsa_error(soap, wsa5__MessageAddressingHeaderRequired, NULL);
592
 
#elif defined(SOAP_WSA_2003)
593
 
    return soap_wsa_error(soap, "WS-Addressing header missing");
594
 
#else
595
 
    return soap_wsa_error(soap, SOAP_WSA(MessageInformationHeaderRequired));
596
 
#endif
597
 
  return SOAP_OK;
598
 
}
599
 
 
600
 
/******************************************************************************\
601
 
 *
602
 
 * Server-side Reply
603
 
 *
604
 
\******************************************************************************/
605
 
 
606
 
/**
607
 
@fn int soap_wsa_reply(struct soap *soap, const char *id, const char *action)
608
 
@brief Sets WS-Addressing header fields for server response.
609
 
@param soap context
610
 
@param[in] id is the messageID (optional)
611
 
@param[in] action is the target action (required)
612
 
@return SOAP_OK or fault
613
 
*/
614
 
int
615
 
soap_wsa_reply(struct soap *soap, const char *id, const char *action)
616
 
{ struct soap_wsa_data *data = (struct soap_wsa_data*)soap_lookup_plugin(soap, soap_wsa_id);
617
 
  struct SOAP_ENV__Header *header;
618
 
  DBGFUN1("soap_wsa_reply", "action=%s", action?action:"");
619
 
  if (!data)
620
 
    return SOAP_PLUGIN_ERROR;
621
 
  /* if endpoint address for reply is 'none' return immediately */
622
 
  if (soap->header && soap->header->SOAP_WSA(ReplyTo) && soap->header->SOAP_WSA(ReplyTo)->Address && !strcmp(soap->header->SOAP_WSA(ReplyTo)->Address, soap_wsa_noneURI))
623
 
    return soap_send_empty_response(soap, SOAP_OK);
624
 
  header = (struct SOAP_ENV__Header*)soap_malloc(soap, sizeof(struct SOAP_ENV__Header));
625
 
  soap_default_SOAP_ENV__Header(soap, header);
626
 
  if (soap->header && soap->header->SOAP_WSA(MessageID))
627
 
  { header->SOAP_WSA(RelatesTo) = (SOAP_WSA_(,RelatesTo)*)soap_malloc(soap, sizeof(SOAP_WSA_(,RelatesTo)));
628
 
    SOAP_WSA_(soap_default_,RelatesTo)(soap, header->SOAP_WSA(RelatesTo));
629
 
    header->SOAP_WSA(RelatesTo)->__item = soap->header->SOAP_WSA(MessageID);
630
 
  }
631
 
  header->SOAP_WSA(MessageID) = soap_strdup(soap, id);
632
 
  header->SOAP_WSA(Action) = soap_strdup(soap, action);
633
 
  if (soap->header && soap->header->SOAP_WSA(ReplyTo) && soap->header->SOAP_WSA(ReplyTo)->Address && strcmp(soap->header->SOAP_WSA(ReplyTo)->Address, soap_wsa_anonymousURI))
634
 
  { header->SOAP_WSA(To) = soap->header->SOAP_WSA(ReplyTo)->Address;
635
 
    /* (re)connect to fault endpoint if From != ReplyTo */
636
 
    if (!soap->header->SOAP_WSA(From) || !soap->header->SOAP_WSA(From)->Address || strcmp(soap->header->SOAP_WSA(From)->Address, soap->header->SOAP_WSA(ReplyTo)->Address))
637
 
    { struct soap *reply_soap = soap_copy(soap);
638
 
      if (reply_soap)
639
 
      { soap_copy_stream(reply_soap, soap);
640
 
        soap_clr_omode(reply_soap, SOAP_ENC_MIME | SOAP_ENC_DIME | SOAP_ENC_MTOM);
641
 
        soap->socket = SOAP_INVALID_SOCKET; /* prevents close */
642
 
        if (soap_connect(soap, header->SOAP_WSA(To), header->SOAP_WSA(Action)))
643
 
        { int err; 
644
 
          soap_copy_stream(soap, reply_soap);
645
 
#if defined(SOAP_WSA_2005)
646
 
          err = soap_wsa_error(soap, SOAP_WSA(DestinationUnreachable), header->SOAP_WSA(To));
647
 
#elif defined(SOAP_WSA_2003)
648
 
          err = soap_wsa_error(soap, "WS-Addessing destination unreachable");
649
 
#else
650
 
          err = soap_wsa_error(soap, SOAP_WSA(DestinationUnreachable));
651
 
#endif
652
 
          reply_soap->socket = SOAP_INVALID_SOCKET;
653
 
          soap_end(reply_soap);
654
 
          soap_free(reply_soap);
655
 
          return err;
656
 
        }
657
 
        soap_send_empty_response(reply_soap, SOAP_OK);  /* HTTP ACCEPTED */
658
 
        soap_closesock(reply_soap);
659
 
        soap_end(reply_soap);
660
 
        soap_free(reply_soap);
661
 
        data->fresponse = soap->fresponse;
662
 
        soap->fresponse = soap_wsa_response;    /* response will be a POST */
663
 
      }
664
 
    }
665
 
  }
666
 
  else if (soap->header && soap->header->SOAP_WSA(From))
667
 
    header->SOAP_WSA(To) = soap->header->SOAP_WSA(From)->Address;
668
 
  else
669
 
    header->SOAP_WSA(To) = (char*)soap_wsa_anonymousURI;
670
 
  soap->header = header;
671
 
  return SOAP_OK;
672
 
}
673
 
 
674
 
/******************************************************************************\
675
 
 *
676
 
 * Server-side SOAP Fault
677
 
 *
678
 
\******************************************************************************/
679
 
 
680
 
/**
681
 
@fn int soap_wsa_fault_subcode(struct soap *soap, int flag, const char *faultsubcode, const char *faultstring, const char *faultdetail)
682
 
@brief Sets sender/receiver SOAP Fault (sub)code for server fault response.
683
 
@param soap context
684
 
@param[in] flag 0=receiver, 1=sender
685
 
@param[in] faultsubcode sub code string
686
 
@param[in] faultstring fault string
687
 
@param[in] faultdetail detail string
688
 
@return SOAP_FAULT
689
 
*/
690
 
static int
691
 
soap_wsa_fault_subcode(struct soap *soap, int flag, const char *faultsubcode, const char *faultstring, const char *faultdetail)
692
 
{ struct soap_wsa_data *data = (struct soap_wsa_data*)soap_lookup_plugin(soap, soap_wsa_id);
693
 
  struct SOAP_ENV__Header *header = (struct SOAP_ENV__Header*)soap_malloc(soap, sizeof(struct SOAP_ENV__Header));
694
 
  DBGFUN2("soap_wsa_fault_subcode", "faultsubcode=%s", faultsubcode?faultsubcode:"", "faultstring=%s", faultstring?faultstring:"");
695
 
  if (!data)
696
 
    return SOAP_PLUGIN_ERROR;
697
 
  soap_default_SOAP_ENV__Header(soap, header);
698
 
  soap_wsa_alloc_header(soap);
699
 
  if (soap->header && soap->header->SOAP_WSA(MessageID))
700
 
  { header->SOAP_WSA(RelatesTo) = (SOAP_WSA_(,RelatesTo)*)soap_malloc(soap, sizeof(SOAP_WSA_(,RelatesTo)));
701
 
    SOAP_WSA_(soap_default_,RelatesTo)(soap, header->SOAP_WSA(RelatesTo));
702
 
    header->SOAP_WSA(RelatesTo)->__item = soap->header->SOAP_WSA(MessageID);
703
 
  }
704
 
  /* header->wsa__MessageID = "..."; */
705
 
  header->SOAP_WSA(Action) = (char*)soap_wsa_faultAction;
706
 
  if (soap->header && soap->header->SOAP_WSA(FaultTo) && soap->header->SOAP_WSA(FaultTo)->Address && strcmp(soap->header->SOAP_WSA(FaultTo)->Address, soap_wsa_anonymousURI))
707
 
  { header->SOAP_WSA(To) = soap->header->SOAP_WSA(FaultTo)->Address;
708
 
    /* (re)connect to fault endpoint if To != FaultTo */
709
 
    if (!soap->header->SOAP_WSA(From) || !soap->header->SOAP_WSA(From)->Address || strcmp(soap->header->SOAP_WSA(From)->Address, soap->header->SOAP_WSA(ReplyTo)->Address))
710
 
    { soap->keep_alive = 0;
711
 
      soap_send_empty_response(soap, SOAP_OK);  /* HTTP ACCEPTED */
712
 
      if (soap_connect(soap, header->SOAP_WSA(To), header->SOAP_WSA(Action)))
713
 
        return SOAP_STOP;       /* nowhere to go */
714
 
      soap_set_endpoint(soap, header->SOAP_WSA(To));
715
 
      soap->action = header->SOAP_WSA(Action);
716
 
      data->fresponse = soap->fresponse;
717
 
      soap->fresponse = soap_wsa_response;      /* response will be a POST */
718
 
    }
719
 
  }
720
 
  else if (soap->header && soap->header->SOAP_WSA(From))
721
 
    header->SOAP_WSA(To) = soap->header->SOAP_WSA(From)->Address;
722
 
  else
723
 
    header->SOAP_WSA(To) = (char*)soap_wsa_anonymousURI;
724
 
  soap->header = header;
725
 
  if (flag)
726
 
    return soap_sender_fault_subcode(soap, faultsubcode, faultstring, faultdetail);
727
 
  return soap_receiver_fault_subcode(soap, faultsubcode, faultstring, faultdetail);
728
 
}
729
 
 
730
 
/**
731
 
@fn int soap_wsa_sender_fault_subcode(struct soap *soap, const char *faultsubcode, const char *faultstring, const char *faultdetail)
732
 
@brief Sets sender SOAP Fault (sub)code for server fault response.
733
 
@param soap context
734
 
@param[in] faultsubcode sub code string
735
 
@param[in] faultstring fault string
736
 
@param[in] faultdetail detail string
737
 
@return SOAP_FAULT
738
 
*/
739
 
int
740
 
soap_wsa_sender_fault_subcode(struct soap *soap, const char *faultsubcode, const char *faultstring, const char *faultdetail)
741
 
{ return soap_wsa_fault_subcode(soap, 1, faultsubcode, faultstring, faultdetail);
742
 
}
743
 
 
744
 
/**
745
 
@fn int soap_wsa_receiver_fault_subcode(struct soap *soap, const char *faultsubcode, const char *faultstring, const char *faultdetail)
746
 
@brief Sets receiver SOAP Fault (sub)code for server fault response.
747
 
@param soap context
748
 
@param[in] faultsubcode sub code string
749
 
@param[in] faultstring fault string
750
 
@param[in] faultdetail detail string
751
 
@return SOAP_FAULT
752
 
*/
753
 
int
754
 
soap_wsa_receiver_fault_subcode(struct soap *soap, const char *faultsubcode, const char *faultstring, const char *faultdetail)
755
 
{ return soap_wsa_fault_subcode(soap, 0, faultsubcode, faultstring, faultdetail);
756
 
}
757
 
 
758
 
/**
759
 
@fn int soap_wsa_sender_fault(struct soap *soap, const char *faultstring, const char *faultdetail)
760
 
@brief Sets sender SOAP Fault for server fault response.
761
 
@param soap context
762
 
@param[in] faultstring fault string
763
 
@param[in] faultdetail detail string
764
 
@return SOAP_FAULT
765
 
*/
766
 
int
767
 
soap_wsa_sender_fault(struct soap *soap, const char *faultstring, const char *faultdetail)
768
 
{ return soap_wsa_fault_subcode(soap, 1, NULL, faultstring, faultdetail);
769
 
}
770
 
 
771
 
/**
772
 
@fn int soap_wsa_receiver_fault(struct soap *soap, const char *faultstring, const char *faultdetail)
773
 
@brief Sets receiver SOAP Fault for server fault response.
774
 
@param soap context
775
 
@param[in] faultstring fault string
776
 
@param[in] faultdetail detail string
777
 
@return SOAP_FAULT
778
 
*/
779
 
int
780
 
soap_wsa_receiver_fault(struct soap *soap, const char *faultstring, const char *faultdetail)
781
 
{ return soap_wsa_fault_subcode(soap, 0, NULL, faultstring, faultdetail);
782
 
}
783
 
 
784
 
/******************************************************************************\
785
 
 *
786
 
 * WS-Addressing Fault
787
 
 *
788
 
\******************************************************************************/
789
 
 
790
 
#if defined(SOAP_WSA_2005)
791
 
/**
792
 
@fn int soap_wsa_check_fault(struct soap *soap, SOAP_WSA(FaultCodesType) *fault, char **info)
793
 
@brief Checks the presence of a WS-Addressing fault
794
 
@param soap context
795
 
@param[out] fault code
796
 
@param[out] info string pointer related to the wsa fault (or set to NULL)
797
 
@return SOAP_OK (no fault) or fault code
798
 
*/
799
 
int
800
 
soap_wsa_check_fault(struct soap *soap, SOAP_WSA(FaultCodesType) *fault, char **info)
801
 
{ if (soap->error && soap->fault && soap->fault->SOAP_ENV__Code)
802
 
  { const char *code = *soap_faultsubcode(soap);
803
 
    if (code)
804
 
    { SOAP_WSA__(soap_s2,FaultCodesType)(soap, code, fault);
805
 
      if (info)
806
 
      { struct SOAP_ENV__Detail *detail;
807
 
        *info = NULL;
808
 
        if (soap->fault->detail)
809
 
          detail = soap->fault->detail;
810
 
        else
811
 
          detail = soap->fault->SOAP_ENV__Detail;
812
 
        if (detail)
813
 
        { switch (detail->__type)
814
 
          { case SOAP_WSA_(SOAP_TYPE_,ProblemHeaderQName):
815
 
            case SOAP_WSA_(SOAP_TYPE_,ProblemIRI):
816
 
              *info = (char*)detail->fault;
817
 
              break;
818
 
            case SOAP_WSA_(SOAP_TYPE_,ProblemAction):
819
 
              *info = ((SOAP_WSA_(,ProblemAction)*)detail->fault)->Action;
820
 
              break;
821
 
            default:
822
 
              break;
823
 
          }
824
 
        }
825
 
      }
826
 
      return soap->error;
827
 
    } 
828
 
  }
829
 
  return SOAP_OK;
830
 
}
831
 
#elif defined(SOAP_WSA_2003)
832
 
int
833
 
soap_wsa_check_fault(struct soap *soap, char **fault)
834
 
{ struct SOAP_ENV__Detail detail;
835
 
  *fault = NULL;
836
 
  if (soap->error && soap->fault)
837
 
  { if (soap->fault->detail)
838
 
      detail = soap->fault->detail;
839
 
    else
840
 
      detail = soap->fault->SOAP_ENV__Detail;
841
 
  }
842
 
  if (detail)
843
 
  { *fault = detail->__any;
844
 
    if (*fault)
845
 
      return soap->error;
846
 
  }
847
 
  return SOAP_OK;
848
 
}
849
 
#else
850
 
/**
851
 
@fn int soap_wsa_check_fault(struct soap *soap, SOAP_WSA(FaultSubcodeValues) *fault)
852
 
@brief Checks the presence of a WS-Addressing fault
853
 
@param soap context
854
 
@param[out] fault code
855
 
@return SOAP_OK (no fault) or fault code
856
 
*/
857
 
int
858
 
soap_wsa_check_fault(struct soap *soap, SOAP_WSA(FaultSubcodeValues) *fault)
859
 
{ if (soap->error && soap->fault && soap->fault->SOAP_ENV__Code)
860
 
  { const char *code = *soap_faultsubcode(soap);
861
 
    if (code)
862
 
    { SOAP_WSA__(soap_s2,FaultSubcodeValues)(soap, code, fault);
863
 
      return soap->error;
864
 
    } 
865
 
  }
866
 
  return SOAP_OK;
867
 
}
868
 
#endif
869
 
 
870
 
#if defined(SOAP_WSA_2005)
871
 
/**
872
 
@fn int soap_wsa_error(struct soap *soap, SOAP_WSA(FaultCodesType) fault, const char *info)
873
 
@brief Sets SOAP Fault (sub)code for server WS-Addressing fault response.
874
 
@param soap context
875
 
@param[in] fault is one of wsa:FaultCodesType enumeration values
876
 
@param[in] info is the value of the element in the Fault detail field
877
 
@return SOAP_FAULT
878
 
*/
879
 
int
880
 
soap_wsa_error(struct soap *soap, SOAP_WSA(FaultCodesType) fault, const char *info)
881
 
{ const char *code = SOAP_WSA_(soap,FaultCodesType2s)(soap, fault);
882
 
  /* populate the SOAP Fault as per WS-Addressing spec */
883
 
  switch (fault)
884
 
  { case SOAP_WSA(InvalidAddressingHeader):
885
 
      soap_wsa_sender_fault_subcode(soap, code, "A header representing a Message Addressing Property is not valid and the message cannot be processed.", NULL);
886
 
      soap_faultdetail(soap);
887
 
      if (soap->version == 1)
888
 
      { soap->fault->detail->__type = SOAP_WSA_(SOAP_TYPE_,ProblemHeaderQName);
889
 
        soap->fault->detail->fault = (void*)info;
890
 
      }
891
 
      else
892
 
      { soap->fault->SOAP_ENV__Detail->__type = SOAP_WSA_(SOAP_TYPE_,ProblemHeaderQName);
893
 
        soap->fault->SOAP_ENV__Detail->fault = (void*)info;
894
 
      }
895
 
      break;
896
 
    case SOAP_WSA(InvalidAddress):
897
 
      soap_wsa_sender_fault_subcode(soap, code, "Invalid address.", NULL);
898
 
      break;
899
 
    case SOAP_WSA(InvalidEPR):
900
 
      soap_wsa_sender_fault_subcode(soap, code, "Invalid EPR.", NULL);
901
 
      break;
902
 
    case SOAP_WSA(InvalidCardinality):
903
 
      soap_wsa_sender_fault_subcode(soap, code, "Invalid cardinality of headers.", NULL);
904
 
      break;
905
 
    case SOAP_WSA(MissingAddressInEPR):
906
 
      soap_wsa_sender_fault_subcode(soap, code, "Missing EPR address.", NULL);
907
 
      break;
908
 
    case SOAP_WSA(DuplicateMessageID):
909
 
      soap_wsa_sender_fault_subcode(soap, code, "Message contains the message ID of a message already received.", NULL);
910
 
      break;
911
 
    case SOAP_WSA(ActionMismatch):
912
 
      soap_wsa_sender_fault_subcode(soap, code, "Action and SOAP action of the message do not match.", NULL);
913
 
      break;
914
 
    case SOAP_WSA(MessageAddressingHeaderRequired):
915
 
      soap_wsa_sender_fault_subcode(soap, code, "A required header representing a Message Addressing Property is not present.", NULL);
916
 
      soap_faultdetail(soap);
917
 
      if (soap->version == 1)
918
 
      { soap->fault->detail->__type = SOAP_WSA_(SOAP_TYPE_,ProblemHeaderQName);
919
 
        soap->fault->detail->fault = (void*)info;
920
 
      }
921
 
      else
922
 
      { soap->fault->SOAP_ENV__Detail->__type = SOAP_WSA_(SOAP_TYPE_,ProblemHeaderQName);
923
 
        soap->fault->SOAP_ENV__Detail->fault = (void*)info;
924
 
      }
925
 
      break;
926
 
    case SOAP_WSA(DestinationUnreachable):
927
 
      soap_wsa_sender_fault_subcode(soap, code, "No route can be determined to reach [destination]", NULL);
928
 
      soap_faultdetail(soap);
929
 
      if (soap->version == 1)
930
 
      { soap->fault->detail->__type = SOAP_WSA_(SOAP_TYPE_,ProblemIRI);
931
 
        soap->fault->detail->fault = (void*)info;
932
 
      }
933
 
      else
934
 
      { soap->fault->SOAP_ENV__Detail->__type = SOAP_WSA_(SOAP_TYPE_,ProblemIRI);
935
 
        soap->fault->SOAP_ENV__Detail->fault = (void*)info;
936
 
      }
937
 
      break;
938
 
    case SOAP_WSA(ActionNotSupported):
939
 
      soap_wsa_sender_fault_subcode(soap, code, "The [action] cannot be processed at the receiver.", NULL);
940
 
      soap_faultdetail(soap);
941
 
      if (soap->version == 1)
942
 
      { soap->fault->detail->__type = SOAP_WSA_(SOAP_TYPE_,ProblemAction);
943
 
        soap->fault->detail->fault = (void*)soap_malloc(soap, sizeof(SOAP_WSA_(,ProblemAction)));
944
 
        SOAP_WSA_(soap_default_,ProblemAction)(soap, (SOAP_WSA_(,ProblemAction)*)soap->fault->detail->fault);
945
 
        ((SOAP_WSA_(,ProblemAction)*)soap->fault->detail->fault)->Action = (char*)info;
946
 
      }
947
 
      else
948
 
      { soap->fault->SOAP_ENV__Detail->__type = SOAP_WSA_(SOAP_TYPE_,ProblemAction);
949
 
        soap->fault->SOAP_ENV__Detail->fault = (void*)soap_malloc(soap, sizeof(SOAP_WSA_(,ProblemAction)));
950
 
        SOAP_WSA_(soap_default_,ProblemAction)(soap, (SOAP_WSA_(,ProblemAction)*)soap->fault->SOAP_ENV__Detail->fault);
951
 
        ((SOAP_WSA_(,ProblemAction)*)soap->fault->SOAP_ENV__Detail->fault)->Action = (char*)info;
952
 
      }
953
 
      break;
954
 
    case SOAP_WSA(EndpointUnavailable):
955
 
      soap_wsa_receiver_fault_subcode(soap, code, "The endpoint is unable to process the message at this time.", NULL);
956
 
      soap_faultdetail(soap);
957
 
      if (soap->version == 1)
958
 
      { soap->fault->detail->__type = SOAP_WSA_(SOAP_TYPE_,ProblemIRI);
959
 
        soap->fault->detail->fault = (void*)info;
960
 
      }
961
 
      else
962
 
      { soap->fault->SOAP_ENV__Detail->__type = SOAP_WSA_(SOAP_TYPE_,ProblemIRI);
963
 
        soap->fault->SOAP_ENV__Detail->fault = (void*)info;
964
 
      }
965
 
      break;
966
 
    default:
967
 
      break;
968
 
  }
969
 
  return SOAP_FAULT;
970
 
}
971
 
#elif defined(SOAP_WSA_2003)
972
 
int
973
 
soap_wsa_error(struct soap *soap, const char *fault)
974
 
{ return soap_wsa_sender_fault_subcode(soap, NULL, fault, NULL);
975
 
}
976
 
#else
977
 
/**
978
 
@fn int soap_wsa_error(struct soap *soap, SOAP_WSA(FaultSubcodeValues) fault)
979
 
@brief Sets SOAP Fault (sub)code for server WS-Addressing fault response.
980
 
@param soap context
981
 
@param[in] fault is one of wsa:FaultSubcodeValues
982
 
@return SOAP_FAULT
983
 
*/
984
 
int
985
 
soap_wsa_error(struct soap *soap, SOAP_WSA(FaultSubcodeValues) fault)
986
 
{ const char *code = SOAP_WSA_(soap,FaultSubcodeValues2s)(soap, fault);
987
 
  /* populate the SOAP Fault as per WS-Addressing spec */
988
 
  switch (fault)
989
 
  { case SOAP_WSA(InvalidMessageInformationHeader):
990
 
      return soap_wsa_sender_fault_subcode(soap, code, "A message information header is not valid and the message cannot be processed. The validity failure can be either structural or semantic, e.g. a [destination] that is not a URI or a [relationship] to a [message id] that was never issued.", "Invalid header");
991
 
    case SOAP_WSA(MessageInformationHeaderRequired):
992
 
      return soap_wsa_sender_fault_subcode(soap, code, "A required message information header, To, MessageID, or Action, is not present.", "Missing Header QName");
993
 
    case SOAP_WSA(DestinationUnreachable):
994
 
      return soap_wsa_sender_fault_subcode(soap, code, "No route can be determined to reach the destination role defined by the WS-Addressing To.", NULL);
995
 
    case SOAP_WSA(ActionNotSupported):
996
 
      return soap_wsa_sender_fault_subcode(soap, code, "The [action] cannot be processed at the receiver.", soap->action);
997
 
    case SOAP_WSA(EndpointUnavailable):
998
 
      return soap_wsa_receiver_fault_subcode(soap, code, "The endpoint is unable to process the message at this time.", NULL);
999
 
    default:
1000
 
      break;
1001
 
  }
1002
 
  return SOAP_FAULT;
1003
 
}
1004
 
#endif
1005
 
 
1006
 
/******************************************************************************\
1007
 
 *
1008
 
 * Plugin registry functions
1009
 
 *
1010
 
\******************************************************************************/
1011
 
 
1012
 
/**
1013
 
@fn int soap_wsa(struct soap *soap, struct soap_plugin *p, void *arg)
1014
 
@brief Plugin registry function, used with soap_register_plugin.
1015
 
@param soap context
1016
 
@param[in,out] p plugin created in registry
1017
 
@param[in] arg passed from soap_register_plugin_arg
1018
 
@return SOAP_OK
1019
 
*/
1020
 
int
1021
 
soap_wsa(struct soap *soap, struct soap_plugin *p, void *arg)
1022
 
{ DBGFUN("soap_wsa");
1023
 
  p->id = soap_wsa_id;
1024
 
  p->data = (void*)SOAP_MALLOC(soap, sizeof(struct soap_wsa_data));
1025
 
  p->fcopy = NULL;
1026
 
  p->fdelete = soap_wsa_delete;
1027
 
  if (p->data)
1028
 
  { if (soap_wsa_init(soap, (struct soap_wsa_data*)p->data))
1029
 
    { SOAP_FREE(soap, p->data);
1030
 
      return SOAP_EOM;
1031
 
    }
1032
 
  }
1033
 
  return SOAP_OK;
1034
 
}
1035
 
 
1036
 
/**
1037
 
@fn int soap_wsa_init(struct soap *soap, struct soap_wsa_data *data)
1038
 
@brief Initializes plugin data.
1039
 
@param soap context
1040
 
@param[in,out] data plugin data
1041
 
@return SOAP_OK
1042
 
*/
1043
 
static int
1044
 
soap_wsa_init(struct soap *soap, struct soap_wsa_data *data)
1045
 
{ DBGFUN("soap_wsa_init");
1046
 
  data->fheader = soap->fheader;
1047
 
  data->fseterror = soap->fseterror;
1048
 
  soap->fheader = soap_wsa_header;
1049
 
  soap->fseterror = soap_wsa_set_error;
1050
 
  return SOAP_OK;
1051
 
}
1052
 
 
1053
 
/**
1054
 
@fn void soap_wsa_delete(struct soap *soap, struct soap_plugin *p)
1055
 
@brief Deletes plugin data.
1056
 
@param soap context
1057
 
@param[in,out] p plugin
1058
 
@return SOAP_OK
1059
 
*/
1060
 
static void
1061
 
soap_wsa_delete(struct soap *soap, struct soap_plugin *p)
1062
 
{ DBGFUN("soap_wsa_delete");
1063
 
  SOAP_FREE(soap, p->data);
1064
 
}
1065
 
 
1066
 
/******************************************************************************\
1067
 
 *
1068
 
 * Callbacks registered by plugin
1069
 
 *
1070
 
\******************************************************************************/
1071
 
 
1072
 
/**
1073
 
@fn int soap_wsa_header(struct soap *soap)
1074
 
@brief Copies WS-Addressing action to SOAP action
1075
 
@param soap context
1076
 
@return SOAP_OK or fault
1077
 
 
1078
 
This callback is invoked to copy the WS-Addressing action to the SOAP action
1079
 
before invoking the service operation.
1080
 
*/
1081
 
static int
1082
 
soap_wsa_header(struct soap *soap)
1083
 
{ struct soap_wsa_data *data = (struct soap_wsa_data*)soap_lookup_plugin(soap, soap_wsa_id);
1084
 
  DBGFUN("soap_wsa_header");
1085
 
  if (!data)
1086
 
    return SOAP_PLUGIN_ERROR;
1087
 
  if (data->fheader && data->fheader(soap))
1088
 
    return soap->error;
1089
 
  if (soap->header && soap->header->SOAP_WSA(Action))
1090
 
    soap->action = soap->header->SOAP_WSA(Action);
1091
 
  return SOAP_OK;
1092
 
}
1093
 
 
1094
 
/**
1095
 
@fn void soap_wsa_set_error(struct soap *soap, const char **c, const char **s)
1096
 
@brief Copies WS-Addressing action to SOAP action
1097
 
@param soap context
1098
 
@param c fault code
1099
 
@param s fault string
1100
 
*/
1101
 
static void
1102
 
soap_wsa_set_error(struct soap *soap, const char **c, const char **s)
1103
 
{ struct soap_wsa_data *data = (struct soap_wsa_data*)soap_lookup_plugin(soap, soap_wsa_id);
1104
 
  DBGFUN("soap_wsa_set_error");
1105
 
  if (!data)
1106
 
    return;
1107
 
  if (data->fseterror)
1108
 
    data->fseterror(soap, c, s);
1109
 
  if (soap->error == SOAP_NO_METHOD)
1110
 
  {
1111
 
#if defined(SOAP_WSA_2005)
1112
 
    soap->error = soap_wsa_error(soap, SOAP_WSA(ActionNotSupported), soap->action);
1113
 
#elif defined(SOAP_WSA_2003)
1114
 
    soap->error = soap_wsa_error(soap, "Action not supported");
1115
 
#else
1116
 
    soap->error = soap_wsa_error(soap, SOAP_WSA(ActionNotSupported));
1117
 
#endif
1118
 
  }
1119
 
}
1120
 
 
1121
 
/**
1122
 
@fn int soap_wsa_response(struct soap *soap, int status, size_t count)
1123
 
@brief Overrides the HTTP response operations to send an HTTP POST
1124
 
@param soap context
1125
 
@param status code
1126
 
@param count message length (if non-chunked)
1127
 
*/
1128
 
static int
1129
 
soap_wsa_response(struct soap *soap, int status, size_t count)
1130
 
{ struct soap_wsa_data *data = (struct soap_wsa_data*)soap_lookup_plugin(soap, soap_wsa_id);
1131
 
  DBGFUN2("soap_wsa_response", "status=%d", status, "count=%lu", (unsigned long)count);
1132
 
  if (!data)
1133
 
    return SOAP_PLUGIN_ERROR;
1134
 
  soap->fresponse = data->fresponse;    /* reset (HTTP response) */
1135
 
  return soap->fpost(soap, soap_strdup(soap, soap->endpoint), soap->host, soap->port, soap->path, soap->action, count);
1136
 
}
1137
 
 
1138
 
/******************************************************************************\
1139
 
 *
1140
 
 * Misc.
1141
 
 *
1142
 
\******************************************************************************/
1143
 
 
1144
 
/**
1145
 
@fn int soap_wsa_alloc_header(struct soap *soap)
1146
 
@brief Adds SOAP Header if not present.
1147
 
@param soap context
1148
 
@return SOAP_OK
1149
 
*/
1150
 
static int
1151
 
soap_wsa_alloc_header(struct soap *soap)
1152
 
{ soap_header(soap);
1153
 
  return SOAP_OK;
1154
 
}