wsaapi.c
来自「linux下简单对象应用协议的开发库」· C语言 代码 · 共 1,166 行 · 第 1/3 页
C
1,166 行
);@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;#if defined(SOAP_WSA_2003)/** Anonymous Reply/To endpoint address */const char *soap_wsa_anonymousURI = "http://schemas.xmlsoap.org/ws/2003/03/addressing/role/anonymous";/** Specifies no Reply endpoint address (no reply) */const char *soap_wsa_noneURI = "addressing/none not supported";const char *soap_wsa_faultAction = "http://schemas.xmlsoap.org/ws/2003/03/addressing/fault";#elif defined(SOAP_WSA_2004)/** Anonymous Reply/To endpoint address */const char *soap_wsa_anonymousURI = "http://schemas.xmlsoap.org/ws/2004/03/addressing/role/anonymous";/** Specifies no Reply endpoint address (no reply) */const char *soap_wsa_noneURI = "addressing/none not supported";const char *soap_wsa_faultAction = "http://schemas.xmlsoap.org/ws/2004/03/addressing/fault";#elif defined(SOAP_WSA_2005)/** Anonymous Reply/To endpoint address */const char *soap_wsa_anonymousURI = "http://www.w3.org/2005/08/addressing/anonymous";/** Specifies no Reply endpoint address (no reply) */const char *soap_wsa_noneURI = "http://www.w3.org/2005/08/addressing/none";const char *soap_wsa_faultAction = "http://www.w3.org/2005/08/addressing/soap/fault";#else/** Anonymous Reply/To endpoint address */const char *soap_wsa_anonymousURI = "http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous";/** Specifies no Reply endpoint address (no reply) */const char *soap_wsa_noneURI = "addressing/none not supported";const char *soap_wsa_faultAction = "http://schemas.xmlsoap.org/ws/2004/08/addressing/fault";#endif/******************************************************************************\ * * 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->SOAP_WSA(MessageID) = soap_strdup(soap, id); soap->header->SOAP_WSA(To) = soap_strdup(soap, to); soap->header->SOAP_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->SOAP_WSA(From) = (SOAP_WSA_(,From)*)soap_malloc(soap, sizeof(SOAP_WSA_(,From))); SOAP_WSA_(soap_default,EndpointReferenceType)(soap, soap->header->SOAP_WSA(From)); soap->header->SOAP_WSA(From)->Address = soap_strdup(soap, from); return SOAP_OK;}/**@fn int soap_wsa_add_NoReply(struct soap *soap)@brief Sets WS-Addressing ReplyTo header to 'none' (no reply)@param soap context@return SOAP_OK or SOAP_ERRNote: WS-Addressing 2005/08 standard.Use soap_wsa_request to populate the WS-Addressing header.*/intsoap_wsa_add_NoReply(struct soap *soap){ return soap_wsa_add_ReplyTo(soap, soap_wsa_noneURI); }/**@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->SOAP_WSA(ReplyTo) = (SOAP_WSA_(,ReplyTo)*)soap_malloc(soap, sizeof(SOAP_WSA_(,ReplyTo))); SOAP_WSA_(soap_default,EndpointReferenceType)(soap, soap->header->SOAP_WSA(ReplyTo)); soap->header->SOAP_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->SOAP_WSA(FaultTo) = (SOAP_WSA_(,FaultTo)*)soap_malloc(soap, sizeof(SOAP_WSA_(,FaultTo))); SOAP_WSA_(soap_default,EndpointReferenceType)(soap, soap->header->SOAP_WSA(FaultTo)); soap->header->SOAP_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->SOAP_WSA(To) || !soap->header->SOAP_WSA(Action))#if defined(SOAP_WSA_2005) return soap_wsa_error(soap, wsa5__MessageAddressingHeaderRequired, NULL);#elif defined(SOAP_WSA_2003) return soap_wsa_error(soap, "WS-Addressing header missing");#else return soap_wsa_error(soap, SOAP_WSA(MessageInformationHeaderRequired));#endif 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 *oldheader, *newheader; DBGFUN1("soap_wsa_reply", "action=%s", action?action:""); if (!data) return SOAP_PLUGIN_ERROR; oldheader = soap->header; soap->header = NULL; /* if endpoint address for reply is 'none' return immediately */ if (oldheader && oldheader->SOAP_WSA(ReplyTo) && oldheader->SOAP_WSA(ReplyTo)->Address && !strcmp(oldheader->SOAP_WSA(ReplyTo)->Address, soap_wsa_noneURI)) return soap_send_empty_response(soap, SOAP_OK); /* allocate a new header */ soap_wsa_alloc_header(soap); newheader = soap->header; soap_default_SOAP_ENV__Header(soap, newheader); /* check current header content */ if (oldheader && oldheader->SOAP_WSA(MessageID)) { newheader->SOAP_WSA(RelatesTo) = (SOAP_WSA_(,RelatesTo)*)soap_malloc(soap, sizeof(SOAP_WSA_(,RelatesTo))); SOAP_WSA_(soap_default_,RelatesTo)(soap, newheader->SOAP_WSA(RelatesTo)); newheader->SOAP_WSA(RelatesTo)->__item = oldheader->SOAP_WSA(MessageID); } newheader->SOAP_WSA(MessageID) = soap_strdup(soap, id); newheader->SOAP_WSA(Action) = soap_strdup(soap, action); if (oldheader && oldheader->SOAP_WSA(ReplyTo) && oldheader->SOAP_WSA(ReplyTo)->Address && strcmp(oldheader->SOAP_WSA(ReplyTo)->Address, soap_wsa_anonymousURI)) { newheader->SOAP_WSA(To) = oldheader->SOAP_WSA(ReplyTo)->Address; /* (re)connect to fault endpoint if From != ReplyTo */ if (!oldheader->SOAP_WSA(From) || !oldheader->SOAP_WSA(From)->Address || strcmp(oldheader->SOAP_WSA(From)->Address, oldheader->SOAP_WSA(ReplyTo)->Address)) { struct soap *reply_soap = soap_copy(soap); if (reply_soap) { soap_copy_stream(reply_soap, soap); soap_clr_omode(reply_soap, SOAP_ENC_MIME | SOAP_ENC_DIME | SOAP_ENC_MTOM); soap->socket = SOAP_INVALID_SOCKET; /* prevents close */ if (soap_connect(soap, newheader->SOAP_WSA(To), newheader->SOAP_WSA(Action))) { int err; soap_copy_stream(soap, reply_soap);#if defined(SOAP_WSA_2005) err = soap_wsa_error(soap, SOAP_WSA(DestinationUnreachable), newheader->SOAP_WSA(To));#elif defined(SOAP_WSA_2003) err = soap_wsa_error(soap, "WS-Addessing destination unreachable");#else err = soap_wsa_error(soap, SOAP_WSA(DestinationUnreachable));#endif reply_soap->socket = SOAP_INVALID_SOCKET; soap_end(reply_soap); soap_free(reply_soap); soap->header = NULL; return err; } soap_send_empty_response(reply_soap, SOAP_OK); /* HTTP ACCEPTED */ soap_closesock(reply_soap); soap_end(reply_soap); soap_free(reply_soap); data->fresponse = soap->fresponse; soap->fresponse = soap_wsa_response; /* response will be a POST */ } } } else if (oldheader && oldheader->SOAP_WSA(From)) newheader->SOAP_WSA(To) = oldheader->SOAP_WSA(From)->Address; else newheader->SOAP_WSA(To) = (char*)soap_wsa_anonymousURI; soap->header = newheader; return SOAP_OK;}/******************************************************************************\ * * Server-side SOAP Fault *\******************************************************************************//**@fn int soap_wsa_fault_subcode(struct soap *soap, int flag, const char *faultsubcode, const char *faultstring, const char *faultdetail)@brief Sets sender/receiver SOAP Fault (sub)code for server fault response.@param soap context@param[in] flag 0=receiver, 1=sender@param[in] faultsubcode sub code string@param[in] faultstring fault string@param[in] faultdetail detail string@return SOAP_FAULT*/static intsoap_wsa_fault_subcode(struct soap *soap, int flag, const char *faultsubcode, const char *faultstring, const char *faultdetail){ struct soap_wsa_data *data = (struct soap_wsa_data*)soap_lookup_plugin(soap, soap_wsa_id); struct SOAP_ENV__Header *oldheader, *newheader; DBGFUN2("soap_wsa_fault_subcode", "faultsubcode=%s", faultsubcode?faultsubcode:"", "faultstring=%s", faultstring?faultstring:""); if (!data) return SOAP_PLUGIN_ERROR; oldheader = soap->header; soap->header = NULL; /* allocate a new header */ soap_wsa_alloc_header(soap); newheader = soap->header; soap_default_SOAP_ENV__Header(soap, newheader); /* check header */ if (oldheader && oldheader->SOAP_WSA(MessageID)) { newheader->SOAP_WSA(RelatesTo) = (SOAP_WSA_(,RelatesTo)*)soap_malloc(soap, sizeof(SOAP_WSA_(,RelatesTo))); SOAP_WSA_(soap_default_,RelatesTo)(soap, newheader->SOAP_WSA(RelatesTo)); newheader->SOAP_WSA(RelatesTo)->__item = oldheader->SOAP_WSA(MessageID); } /* header->wsa__MessageID = "..."; */ newheader->SOAP_WSA(Action) = (char*)soap_wsa_faultAction; if (oldheader && oldheader->SOAP_WSA(FaultTo) && oldheader->SOAP_WSA(FaultTo)->Address && strcmp(oldheader->SOAP_WSA(FaultTo)->Address, soap_wsa_anonymousURI)) { newheader->SOAP_WSA(To) = oldheader->SOAP_WSA(FaultTo)->Address; /* (re)connect to fault endpoint if To != FaultTo */ if (!oldheader->SOAP_WSA(From) || !oldheader->SOAP_WSA(From)->Address || strcmp(oldheader->SOAP_WSA(From)->Address, oldheader->SOAP_WSA(ReplyTo)->Address)) { soap->keep_alive = 0; soap_send_empty_response(soap, SOAP_OK); /* HTTP ACCEPTED */ if (soap_connect(soap, newheader->SOAP_WSA(To), newheader->SOAP_WSA(Action))) return SOAP_STOP; /* nowhere to go */ soap_set_endpoint(soap, newheader->SOAP_WSA(To)); soap->action = newheader->SOAP_WSA(Action); data->fresponse = soap->fresponse; soap->fresponse = soap_wsa_response; /* response will be a POST */ } } else if (oldheader && oldheader->SOAP_WSA(From)) newheader->SOAP_WSA(To) = oldheader->SOAP_WSA(From)->Address; else newheader->SOAP_WSA(To) = (char*)soap_wsa_anonymousURI; soap->header = newheader; if (flag) return soap_sender_fault_subcode(soap, faultsubcode, faultstring, faultdetail); return soap_receiver_fault_subcode(soap, faultsubcode, faultstring, faultdetail);}/**@fn int soap_wsa_sender_fault_subcode(struct soap *soap, const char *faultsubcode, const char *faultstring, const char *faultdetail)@brief Sets sender SOAP Fault (sub)code for server fault response.@param soap context@param[in] faultsubcode sub code string@param[in] faultstring fault string@param[in] faultdetail detail string@return SOAP_FAULT*/intsoap_wsa_sender_fault_subcode(struct soap *soap, const char *faultsubcode, const char *faultstring, const char *faultdetail){ return soap_wsa_fault_subcode(soap, 1, faultsubcode, faultstring, faultdetail);}/**@fn int soap_wsa_receiver_fault_subcode(struct soap *soap, const char *faultsubcode, const char *faultstring, const char *faultdetail)@brief Sets receiver SOAP Fault (sub)code for server fault response.@param soap context@param[in] faultsubcode sub code string@param[in] faultstring fault string@param[in] faultdetail detail string@return SOAP_FAULT*/intsoap_wsa_receiver_fault_subcode(struct soap *soap, const char *faultsubcode, const char *faultstring, const char *faultdetail){ return soap_wsa_fault_subcode(soap, 0, faultsubcode, faultstring, faultdetail);}/**@fn int soap_wsa_sender_fault(struct soap *soap, const char *faultstring, const char *faultdetail)@brief Sets sender SOAP Fault for server fault response.@param soap context@param[in] faultstring fault string@param[in] faultdetail detail string@return SOAP_FAULT*/intsoap_wsa_sender_fault(struct soap *soap, const char *faultstring, const char *faultdetail)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?