📄 wsaapi.c
字号:
//gsoap ns service method-header-part: exampleResult wsa__MessageID//gsoap ns service method-header-part: exampleResult wsa__RelatesTo//gsoap ns service method-header-part: exampleResult wsa__From//gsoap ns service method-header-part: exampleResult wsa__ReplyTo//gsoap ns service method-header-part: exampleResult wsa__FaultTo//gsoap ns service method-header-part: exampleResult wsa__To//gsoap ns service method-header-part: exampleResult wsa__Action//gsoap ns service method-action: exampleResult urn:example/examplePort/exampleResponseint ns__exampleResponse(char *out, void);@endcodeNote that the action information is important, because it is used by theservice dispatcher (assuming soapcpp2 option -a is used).The implementation in the server code uses soap_wsa_check() to check thepresense and validity of the WS-Addressing information header in the message.The soap_send_empty_response() function should be used to return anacknowledgment HTTP header with HTTP 202 ACCEPTED to the sender:@codeint ns__exampleResponse(struct soap *soap, char *out){ if (soap_wsa_check(soap)) return soap_send_empty_response(soap, 500); // HTTP 500 Internal Server Error // ... service logic return soap_send_empty_response(soap, SOAP_OK); // HTTP 202 ACCEPTED}@endcode@section wsa_5 Implementing a Server for Handling FaultTo Fault MessagesTo implement a separate server for handling relayed SOAP fault messages basedon the FaultTo information header in the request message, the gSOAP header filefor soapcpp2 should include a SOAP fault service operation. This operationaccepts fault messages that are relayed by other services.Basically, we use a trick to generate the SOAP-ENV:Fault struct via a one-wayservice operation. This allows us both to implement a one-way service operationthat accepts faults and to automatically generate the fault struct for faultdata storage and manipulation. The fault operation in the header file should be declaraed as follows:@code//gsoap SOAP_ENV service method-action: Fault http://schemas.xmlsoap.org/ws/2004/08/addressing/faultint SOAP_ENV__Fault( _QName faultcode, // SOAP 1.1 char *faultstring, // SOAP 1.1 char *faultactor, // SOAP 1.1 struct SOAP_ENV__Detail *detail, // SOAP 1.1 struct SOAP_ENV__Code *SOAP_ENV__Code, // SOAP 1.2 struct SOAP_ENV__Reason *SOAP_ENV__Reason, // SOAP 1.2 char *SOAP_ENV__Node, // SOAP 1.2 char *SOAP_ENV__Role, // SOAP 1.2 struct SOAP_ENV__Detail *SOAP_ENV__Detail, // SOAP 1.2 void);@endcodeBecause each service operation has a struct to hold its input parameters, weautomatically generate the (original) SOAP_ENV__Fault struct on the fly!Note: it is important to associate the wsa fault action with this operation asshown above.The implementation of the service operation in the server code is:@codeint 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){ ... = faultcode; // SOAP 1.1 fault code string (QName) ... = faultstring; // SOAP 1.1 fault string ... = faultactor; // SOAP 1.1 fault actor string ... = detail; // SOAP 1.1 fault detail struct ... = SOAP_ENV__Code; // SOAP 1.2 fault code struct ... = SOAP_ENV__Reason; // SOAP 1.2 reason struct ... = SOAP_ENV__Node; // SOAP 1.2 node string ... = SOAP_ENV__Role; // SOAP 1.2 role string ... = SOAP_ENV__Detail; // SOAP 1.2 detail struct return SOAP_OK;}@endcodeNote that SOAP 1.1 or SOAP 1.2 parameters are set based on the 1.1/1.2messaging requirements.*/#include "wsaapi.h"/** Plugin identification for plugin registry */const char soap_wsa_id[13] = SOAP_WSA_ID;const char *soap_wsa_anonymousURI = "http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous";const char *soap_wsa_faultAction = "http://schemas.xmlsoap.org/ws/2004/08/addressing/fault";/******************************************************************************\ * * Static protos *\******************************************************************************/static int soap_wsa_fault_subcode(struct soap *soap, int flag, const char *faultsubcode, const char *faultstring, const char *faultdetail);static int soap_wsa_init(struct soap *soap, struct soap_wsa_data *data);static void soap_wsa_delete(struct soap *soap, struct soap_plugin *p);static int soap_wsa_header(struct soap *soap);static void soap_wsa_set_error(struct soap *soap, const char **c, const char **s);static int soap_wsa_response(struct soap *soap, int status, size_t count);static int soap_wsa_alloc_header(struct soap *soap);/******************************************************************************\ * * Client-side Request *\******************************************************************************//**@fn int soap_wsa_request(struct soap *soap, const char *id, const char *to, const char *action)@brief Sets the WS-Addressing information header for the next request messagewith optional MessageID, To (required), and Action (required).@param soapcontext@param[in] id is the message ID (optional)@param[in] to is the target endpoint (required)@param[in] action is the target action (required)@return SOAP_OKNote: use soap_wsa_add_From, soap_wsa_add_ReplyTo, soap_wsa_add_FaultTo to addother addressing fields following this function call.*/intsoap_wsa_request(struct soap *soap, const char *id, const char *to, const char *action){ soap_wsa_alloc_header(soap); soap_default_SOAP_ENV__Header(soap, soap->header); soap->header->wsa__MessageID = soap_strdup(soap, id); soap->header->wsa__To = soap_strdup(soap, to); soap->header->wsa__Action = soap_strdup(soap, action); return SOAP_OK;}/**@fn int soap_wsa_add_From(struct soap *soap, const char *from)@brief Sets WS-Addressing From header for request message.@param soap context@param[in] from endpoint URI @return SOAP_OK or SOAP_ERRUse soap_wsa_request to populate the WS-Addressing header first.*/intsoap_wsa_add_From(struct soap *soap, const char *from){ if (!soap->header) return SOAP_ERR; soap->header->wsa__From = (_wsa__From*)soap_malloc(soap, sizeof(_wsa__From)); soap_default_wsa__EndpointReferenceType(soap, soap->header->wsa__From); soap->header->wsa__From->Address = soap_strdup(soap, from); return SOAP_OK;}/**@fn int soap_wsa_add_ReplyTo(struct soap *soap, const char *replyTo)@brief Sets WS-Addressing ReplyTo header for request message.@param soap context@param[in] replyTo endpoint URI @return SOAP_OK or SOAP_ERRUse soap_wsa_request to populate the WS-Addressing header.*/intsoap_wsa_add_ReplyTo(struct soap *soap, const char *replyTo){ if (!soap->header) return SOAP_ERR; if (replyTo) { soap->header->wsa__ReplyTo = (_wsa__ReplyTo*)soap_malloc(soap, sizeof(_wsa__ReplyTo)); soap_default_wsa__EndpointReferenceType(soap, soap->header->wsa__ReplyTo); soap->header->wsa__ReplyTo->Address = soap_strdup(soap, replyTo); } return SOAP_OK;}/**@fn int soap_wsa_add_FaultTo(struct soap *soap, const char *faultTo)@brief Sets WS-Addressing FaultTo header for request message.@param soap context@param[in] faultTo endpoint URI @return SOAP_OK or SOAP_ERRUse soap_wsa_request to populate the WS-Addressing header first.*/intsoap_wsa_add_FaultTo(struct soap *soap, const char *faultTo){ if (!soap->header) return SOAP_ERR; if (faultTo) { soap->header->wsa__FaultTo = (_wsa__FaultTo*)soap_malloc(soap, sizeof(_wsa__FaultTo)); soap_default_wsa__EndpointReferenceType(soap, soap->header->wsa__FaultTo); soap->header->wsa__FaultTo->Address = soap_strdup(soap, faultTo); } return SOAP_OK;}/******************************************************************************\ * * Server-side Check *\******************************************************************************//**@fn int soap_wsa_check(struct soap *soap)@brief Checks the presence and validity of WS-Addressing information headers.@param soap context@return SOAP_OK or fault*/intsoap_wsa_check(struct soap *soap){ if (!soap->header || !soap->header->wsa__To || !soap->header->wsa__Action) return soap_wsa_error(soap, wsa__MessageInformationHeaderRequired); return SOAP_OK;}/******************************************************************************\ * * Server-side Reply *\******************************************************************************//**@fn int soap_wsa_reply(struct soap *soap, const char *id, const char *action)@brief Sets WS-Addressing header fields for server response.@param soap context@param[in] id is the messageID (optional)@param[in] action is the target action (required)@return SOAP_OK or fault*/intsoap_wsa_reply(struct soap *soap, const char *id, const char *action){ struct soap_wsa_data *data = (struct soap_wsa_data*)soap_lookup_plugin(soap, soap_wsa_id); struct SOAP_ENV__Header *header = (struct SOAP_ENV__Header*)soap_malloc(soap, sizeof(struct SOAP_ENV__Header)); DBGFUN1("soap_wsa_reply", "action=%s", action?action:""); if (!data) return SOAP_PLUGIN_ERROR; soap_default_SOAP_ENV__Header(soap, header); soap_wsa_alloc_header(soap); if (soap->header->wsa__MessageID) { header->wsa__RelatesTo = (struct wsa__Relationship*)soap_malloc(soap, sizeof(struct wsa__Relationship)); soap_default_wsa__Relationship(soap, header->wsa__RelatesTo); header->wsa__RelatesTo->__item = soap->header->wsa__MessageID; } header->wsa__MessageID = soap_strdup(soap, id); header->wsa__Action = soap_strdup(soap, action); if (soap->header && soap->header->wsa__ReplyTo && soap->header->wsa__ReplyTo->Address && strcmp(soap->header->wsa__ReplyTo->Address, soap_wsa_anonymousURI)) { header->wsa__To = soap->header->wsa__ReplyTo->Address; /* (re)connect to fault endpoint if From != ReplyTo */ if (!soap->header->wsa__From || !soap->header->wsa__From->Address || strcmp(soap->header->wsa__From->Address, soap->header->wsa__ReplyTo->Address)) { struct soap reply_soap; soap_init2(&reply_soap, soap->imode, soap->omode); if (soap_connect(&reply_soap, header->wsa__To, header->wsa__Action)) { soap_end(&reply_soap); soap_done(&reply_soap); return soap_wsa_error(soap, wsa__DestinationUnreachable); } soap->keep_alive = 0; soap_send_empty_response(soap, SOAP_OK); /* HTTP ACCEPTED */ soap_closesock(soap); soap_copy_stream(soap, &reply_soap); soap_set_endpoint(soap, header->wsa__To); soap->action = header->wsa__Action; data->fresponse = soap->fresponse; soap->fresponse = soap_wsa_response; /* response will be a POST */ reply_soap.socket = SOAP_INVALID_SOCKET; /* prevents close */ soap_end(&reply_soap); soap_done(&reply_soap); } } else if (soap->header->wsa__From) header->wsa__To = soap->header->wsa__From->Address; else header->wsa__To = (char*)soap_wsa_anonymousURI; soap->header = header; return SOAP_OK;}/******************************************************************************\ *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -