📄 soap_device.c
字号:
if( BodyNode == NULL ) { goto error_handler; } // Got action node here ActNode = ixmlNode_getFirstChild( BodyNode ); if( ActNode == NULL ) { goto error_handler; } //Test whether this is the action node nodeName = ixmlNode_getNodeName( ActNode ); if( nodeName == NULL ) { goto error_handler; } if( strstr( nodeName, NodeName ) == NULL ) { goto error_handler; } else { ActNodeName = ixmlPrintDocument( ActNode ); if( ActNodeName == NULL ) { goto error_handler; } ret_code = ixmlParseBufferEx( ActNodeName, RespNode ); if( ret_code != IXML_SUCCESS ) { ixmlFreeDOMString( ActNodeName ); ret_code = -1; goto error_handler; } } ret_code = 0; // success error_handler: ixmlFreeDOMString( ActNodeName ); if( nl ) ixmlNodeList_free( nl ); return ret_code;}/***************************************************************************** Function : check_soap_body** Parameters :* IN IXML_Document *doc : soap body xml document* IN const char *urn : * IN const char *actionName : Name of the requested action ** Description : This function checks the soap body xml came in the* SOAP request.** Return : int* UPNP_E_SUCCESS if successful else returns appropriate error** Note :****************************************************************************/static intcheck_soap_body( IN IXML_Document * doc, IN const char *urn, IN const char *actionName ){ IXML_NodeList *nl = NULL; IXML_Node *bodyNode = NULL; IXML_Node *actionNode = NULL; const DOMString ns = NULL; const DOMString name = NULL; int ret_code = UPNP_E_INVALID_ACTION; nl = ixmlDocument_getElementsByTagNameNS( doc, SOAP_URN, SOAP_BODY ); if( nl ) { bodyNode = ixmlNodeList_item( nl, 0 ); if( bodyNode ) { actionNode = ixmlNode_getFirstChild( bodyNode ); if( actionNode ) { ns = ixmlNode_getNamespaceURI( actionNode ); name = ixmlNode_getLocalName( actionNode ); if( ( !strcmp( actionName, name ) ) && ( !strcmp( urn, ns ) ) ) { ret_code = UPNP_E_SUCCESS; } } } ixmlNodeList_free( nl ); } return ret_code;}/***************************************************************************** Function : check_soap_action_header** Parameters :* IN http_message_t *request : HTTP request* IN const char *urn :* OUT char **actionName : name of the SOAP action** Description : This function checks the HTTP header of the SOAP request* coming from the control point** Return : static int* UPNP_E_SUCCESS if successful else returns appropriate error** Note :****************************************************************************/static intcheck_soap_action_header( IN http_message_t * request, IN const char *urn, OUT char **actionName ){ memptr header_name; http_header_t *soap_action_header = NULL; char *ns_compare = NULL; int tempSize = 0; int ret_code = UPNP_E_SUCCESS; char *temp_header_value = NULL; char *temp = NULL; char *temp2 = NULL; //check soap action header soap_action_header = httpmsg_find_hdr( request, HDR_SOAPACTION, &header_name ); if( !soap_action_header ) { ret_code = UPNP_E_INVALID_ACTION; return ret_code; } if( soap_action_header->value.length <= 0 ) { ret_code = UPNP_E_INVALID_ACTION; return ret_code; } temp_header_value = ( char * )malloc( soap_action_header->value.length + 1 ); if( !temp_header_value ) { ret_code = UPNP_E_OUTOF_MEMORY; free( temp_header_value ); return ret_code; } strncpy( temp_header_value, soap_action_header->value.buf, soap_action_header->value.length ); temp_header_value[soap_action_header->value.length] = 0; temp = strchr( temp_header_value, '#' ); if( !temp ) { free( temp_header_value ); ret_code = UPNP_E_INVALID_ACTION; return ret_code; } ( *temp ) = 0; //temp make string //check to see if it is Query State Variable or //Service Action tempSize = strlen( urn ) + 2; ns_compare = ( char * )malloc( tempSize ); if( !ns_compare ) { ret_code = UPNP_E_OUTOF_MEMORY; free( temp_header_value ); return ret_code; } snprintf( ns_compare, tempSize, "\"%s", urn ); if( strcmp( temp_header_value, ns_compare ) ) { ret_code = UPNP_E_INVALID_ACTION; } else { ret_code = UPNP_E_SUCCESS; temp++; temp2 = strchr( temp, '\"' ); if( temp2 ) //remove ending " if present { ( *temp2 ) = 0; } if( *temp ) ( *actionName ) = strdup( temp ); if( !*actionName ) { ret_code = UPNP_E_OUTOF_MEMORY; } } free( temp_header_value ); free( ns_compare ); return ret_code;}/***************************************************************************** Function : get_device_info** Parameters :* IN http_message_t* request : HTTP request* IN int isQuery : flag for a querry* IN IXML_Document *actionDoc : action request document* OUT char device_udn[LINE_SIZE] : Device UDN string* OUT char service_id[LINE_SIZE] : Service ID string* OUT Upnp_FunPtr *callback : callback function of the device * application* OUT void** cookie : cookie stored by device application * * Description : This function retrives all the information needed to * process the incoming SOAP request. It finds the device and service info* and also the callback function to hand-over the request to the device* application.** Return : int* UPNP_E_SUCCESS if successful else returns appropriate error** Note :****************************************************************************/static intget_device_info( IN http_message_t * request, IN int isQuery, IN IXML_Document * actionDoc, OUT char device_udn[LINE_SIZE], OUT char service_id[LINE_SIZE], OUT Upnp_FunPtr * callback, OUT void **cookie ){ struct Handle_Info *device_info; int device_hnd; service_info *serv_info; char save_char; int ret_code = -1; // error by default char *control_url; char *actionName = NULL; // null-terminate pathquery of url control_url = request->uri.pathquery.buff; save_char = control_url[request->uri.pathquery.size]; control_url[request->uri.pathquery.size] = '\0'; HandleLock( ); if( GetDeviceHandleInfo( &device_hnd, &device_info ) != HND_DEVICE ) { goto error_handler; } if( ( serv_info = FindServiceControlURLPath( &device_info->ServiceTable, control_url ) ) == NULL ) { goto error_handler; } if( isQuery ) { ret_code = check_soap_action_header( request, QUERY_STATE_VAR_URN, &actionName ); if( ( ret_code != UPNP_E_SUCCESS ) && ( ret_code != UPNP_E_OUTOF_MEMORY ) ) { ret_code = UPNP_E_INVALID_ACTION; goto error_handler; } //check soap body ret_code = check_soap_body( actionDoc, QUERY_STATE_VAR_URN, actionName ); free( actionName ); if( ret_code != UPNP_E_SUCCESS ) { goto error_handler; } } else { ret_code = check_soap_action_header( request, serv_info->serviceType, &actionName ); if( ( ret_code != UPNP_E_SUCCESS ) && ( ret_code != UPNP_E_OUTOF_MEMORY ) ) { ret_code = UPNP_E_INVALID_SERVICE; goto error_handler; } //check soap body ret_code = check_soap_body( actionDoc, serv_info->serviceType, actionName ); free( actionName ); if( ret_code != UPNP_E_SUCCESS ) { ret_code = UPNP_E_INVALID_SERVICE; goto error_handler; } } namecopy( service_id, serv_info->serviceId ); namecopy( device_udn, serv_info->UDN ); *callback = device_info->Callback; *cookie = device_info->Cookie; ret_code = 0; error_handler: control_url[request->uri.pathquery.size] = save_char; // restore HandleUnlock( ); return ret_code;}/***************************************************************************** Function : send_action_response** Parameters :* IN SOCKINFO *info : socket info* IN IXML_Document *action_resp : The response document * IN http_message_t* request : action request document** Description : This function sends the SOAP response ** Return : void** Note :****************************************************************************/static XINLINE voidsend_action_response( IN SOCKINFO * info, IN IXML_Document * action_resp, IN http_message_t * request ){ char *xml_response = NULL; membuffer headers; int major, minor; int err_code; int content_length; int ret_code; int timeout_secs = SOAP_TIMEOUT; static char *start_body = "<s:Envelope xmlns:s=\"http://schemas.xmlsoap." "org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap." "org/soap/encoding/\"><s:Body>\n"; static char *end_body = "</s:Body> </s:Envelope>"; // init http_CalcResponseVersion( request->major_version, request->minor_version, &major, &minor ); membuffer_init( &headers ); err_code = UPNP_E_OUTOF_MEMORY; // one error only // get xml xml_response = ixmlPrintDocument( ( IXML_Node * ) action_resp ); if( xml_response == NULL ) { goto error_handler; } content_length = strlen( start_body ) + strlen( xml_response ) + strlen( end_body ); // make headers
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -