コード例 #1
0
ファイル: soap_device.c プロジェクト: JDsolution/ipnc
/****************************************************************************
*	Function :	soap_device_callback
*
*	Parameters :
*		  IN http_parser_t *parser : Parsed request received by the device
*		  IN http_message_t* request :	HTTP request
*		  INOUT SOCKINFO *info :	socket info
*
*	Description :	This is a callback called by minisever after receiving
*		the request from the control point. This function will start
*		processing the request. It calls handle_invoke_action to handle the
*		SOAP action
*
*	Return :	void
*
*	Note :
****************************************************************************/
void
soap_device_callback( IN http_parser_t * parser,
                      IN http_message_t * request,
                      INOUT SOCKINFO * info )
{
    int err_code;
    const char *err_str;
    memptr action_name;
    IXML_Document *xml_doc = NULL;

    // set default error
    err_code = SOAP_INVALID_ACTION;
    err_str = Soap_Invalid_Action;

    // validate: content-type == text/xml
    if( !has_xml_content_type( request ) ) {
        goto error_handler;
    }
    // type of request
    if( get_request_type( request, &action_name ) != 0 ) {
        goto error_handler;
    }
    // parse XML
    err_code = ixmlParseBufferEx( request->entity.buf, &xml_doc );
    if( err_code != IXML_SUCCESS ) {
        if( err_code == IXML_INSUFFICIENT_MEMORY ) {
            err_code = UPNP_E_OUTOF_MEMORY;
        } else {
            err_code = SOAP_ACTION_FAILED;
        }

        err_str = "XML error";
        goto error_handler;
    }

    if( action_name.length == 0 ) {
        // query var
        handle_query_variable( info, request, xml_doc );
    } else {
        // invoke action
        handle_invoke_action( info, request, action_name, xml_doc );
    }

    err_code = 0;               // no error

error_handler:
    ixmlDocument_free( xml_doc );
    if( err_code != 0 ) {
        send_error_response( info, err_code, err_str, request );
    }
}
コード例 #2
0
ファイル: soap_device.c プロジェクト: karthagokul/pupnp
/*!
 * \brief This is a callback called by minisever after receiving the request
 * from the control point. This function will start processing the request.
 * It calls handle_invoke_action to handle the SOAP action.
 */
void soap_device_callback(
    int iface,
	/*! [in] Parsed request received by the device. */
	http_parser_t *parser,
	/*! [in] HTTP request. */
	http_message_t *request,
	/*! [in,out] Socket info. */
	SOCKINFO *info)
{
	int err_code;
	const char *err_str;
	memptr action_name;
	IXML_Document *xml_doc = NULL;

	/* set default error */
	err_code = SOAP_INVALID_ACTION;
	err_str = Soap_Invalid_Action;

	/* validate: content-type == text/xml */
	if (!has_xml_content_type(request))
		goto error_handler;
	/* type of request */
	if (get_request_type(request, &action_name) != 0)
		goto error_handler;
	/* parse XML */
	err_code = ixmlParseBufferEx(request->entity.buf, &xml_doc);
	if (err_code != IXML_SUCCESS) {
		if (err_code == IXML_INSUFFICIENT_MEMORY)
			err_code = UPNP_E_OUTOF_MEMORY;
		else
			err_code = SOAP_ACTION_FAILED;
		err_str = "XML error";
		goto error_handler;
	}
	if (action_name.length == 0)
		/* query var */
		handle_query_variable(iface, info, request, xml_doc);
	else
		/* invoke action */
		handle_invoke_action(iface, info, request, action_name, xml_doc);
	/* no error */
	err_code = 0;

 error_handler:
	ixmlDocument_free(xml_doc);
	if (err_code != 0)
		send_error_response(info, err_code, err_str, request);
	return;
	parser = parser;
}
コード例 #3
0
ファイル: gena_ctrlpt.c プロジェクト: brolee/EMule-GIFC
/************************************************************************
* Function : gena_process_notification_event
*																	
* Parameters:														
*	IN SOCKINFO *info: Socket structure containing the device socket 
*					information
*	IN http_message_t* event: The http message contains the GENA 
*								notification
*
* Description:														
*	This function processes NOTIFY events that are sent by devices. 
*	called by genacallback()
*
* Returns: void
*
* Note : called by genacallback()
****************************************************************************/
void
gena_process_notification_event( IN SOCKINFO * info,
                                 IN http_message_t * event )
{
    struct Upnp_Event event_struct;
    int eventKey;
    token sid;
    client_subscription *subscription;
    IXML_Document *ChangedVars;
    struct Handle_Info *handle_info;
    void *cookie;
    Upnp_FunPtr callback;
    UpnpClient_Handle client_handle;

    memptr sid_hdr;
    memptr nt_hdr,
      nts_hdr;
    memptr seq_hdr;

    // get SID
    if( httpmsg_find_hdr( event, HDR_SID, &sid_hdr ) == NULL ) {
        error_respond( info, HTTP_PRECONDITION_FAILED, event );

        return;
    }
    sid.buff = sid_hdr.buf;
    sid.size = sid_hdr.length;

    // get event key
    if( httpmsg_find_hdr( event, HDR_SEQ, &seq_hdr ) == NULL ||
        matchstr( seq_hdr.buf, seq_hdr.length, "%d%0", &eventKey )
        != PARSE_OK ) {
        error_respond( info, HTTP_BAD_REQUEST, event );

        return;
    }
    // get NT and NTS headers
    if( httpmsg_find_hdr( event, HDR_NT, &nt_hdr ) == NULL ||
        httpmsg_find_hdr( event, HDR_NTS, &nts_hdr ) == NULL ) {
        error_respond( info, HTTP_BAD_REQUEST, event );

        return;
    }
    // verify NT and NTS headers
    if( memptr_cmp( &nt_hdr, "upnp:event" ) != 0 ||
        memptr_cmp( &nts_hdr, "upnp:propchange" ) != 0 ) {
        error_respond( info, HTTP_PRECONDITION_FAILED, event );

        return;
    }
    // parse the content (should be XML)
    if( !has_xml_content_type( event ) ||
        event->msg.length == 0 ||
        ( ixmlParseBufferEx( event->entity.buf, &ChangedVars ) ) !=
        IXML_SUCCESS ) {
        error_respond( info, HTTP_BAD_REQUEST, event );

        return;
    }

    HandleLock(  );

    // get client info
    if( GetClientHandleInfo( &client_handle, &handle_info ) != HND_CLIENT ) {
        error_respond( info, HTTP_PRECONDITION_FAILED, event );
        HandleUnlock(  );
        ixmlDocument_free( ChangedVars );

        return;
    }
    // get subscription based on SID
    if( ( subscription = GetClientSubActualSID( handle_info->ClientSubList,
                                                &sid ) ) == NULL ) {
        if( eventKey == 0 ) {
            // wait until we've finished processing a subscription 
            //   (if we are in the middle)
            // this is to avoid mistakenly rejecting the first event if we 
            //   receive it before the subscription response
            HandleUnlock(  );

            // try and get Subscription Lock 
            //   (in case we are in the process of subscribing)
            SubscribeLock(  );

            // get HandleLock again
            HandleLock(  );

            if( GetClientHandleInfo( &client_handle, &handle_info )
                != HND_CLIENT ) {
                error_respond( info, HTTP_PRECONDITION_FAILED, event );
                SubscribeUnlock(  );
                HandleUnlock(  );
                ixmlDocument_free( ChangedVars );

                return;
            }

            if( ( subscription =
                  GetClientSubActualSID( handle_info->ClientSubList,
                                         &sid ) ) == NULL ) {
                error_respond( info, HTTP_PRECONDITION_FAILED, event );
                SubscribeUnlock(  );
                HandleUnlock(  );
                ixmlDocument_free( ChangedVars );

                return;
            }

            SubscribeUnlock(  );
        } else {
            error_respond( info, HTTP_PRECONDITION_FAILED, event );
            HandleUnlock(  );
            ixmlDocument_free( ChangedVars );

            return;
        }
    }

    error_respond( info, HTTP_OK, event );  // success

    // fill event struct
    strcpy( event_struct.Sid, subscription->sid );
    event_struct.EventKey = eventKey;
    event_struct.ChangedVariables = ChangedVars;

    // copy callback
    callback = handle_info->Callback;
    cookie = handle_info->Cookie;

    HandleUnlock(  );

    // make callback with event struct
    // In future, should find a way of mainting
    // that the handle is not unregistered in the middle of a
    // callback
    callback( UPNP_EVENT_RECEIVED, &event_struct, cookie );

    ixmlDocument_free( ChangedVars );
}
コード例 #4
0
ファイル: soap_ctrlpt.c プロジェクト: ashon-ikon/mediatomb
/****************************************************************************
*	Function :	get_response_value
*
*	Parameters :
*			IN http_message_t* hmsg :	HTTP response message
*			IN int code :	return code in the HTTP response
*			IN char*name :	name of the action
*			OUT int *upnp_error_code :	UPnP error code
*			OUT IXML_Node ** action_value :	SOAP response node 
*			OUT DOMString * str_value : state varible value ( in the case of 
*							querry state variable request)	
*
*	Description :	This function handles the response coming back from the 
*		device. This function parses the response and gives back the SOAP 
*		response node.
*
*	Return : int
*		return the type of the SOAP message if successful else returns 
*	appropriate error.
*
*	Note :
****************************************************************************/
static int
get_response_value( IN http_message_t * hmsg,
                    IN int code,
                    IN char *name,
                    OUT int *upnp_error_code,
                    OUT IXML_Node ** action_value,
                    OUT DOMString * str_value )
{
    IXML_Node *node = NULL;
    IXML_Node *root_node = NULL;
    IXML_Node *error_node = NULL;
    IXML_Document *doc = NULL;
    char *node_str = NULL;
    const char *temp_str = NULL;
    DOMString error_node_str = NULL;
    int err_code;
    xboolean done = FALSE;
    char *names[5];
    const DOMString nodeValue;

    err_code = UPNP_E_BAD_RESPONSE; // default error

    // only 200 and 500 status codes are relevant
    if( ( hmsg->status_code != HTTP_OK &&
          hmsg->status_code != HTTP_INTERNAL_SERVER_ERROR ) ||
        !has_xml_content_type( hmsg ) ) {

        goto error_handler;
    }

    if( ixmlParseBufferEx( hmsg->entity.buf, &doc ) != IXML_SUCCESS ) {

        goto error_handler;
    }

    root_node = ixmlNode_getFirstChild( ( IXML_Node * ) doc );
    if( root_node == NULL ) {

        goto error_handler;
    }

    if( code == SOAP_ACTION_RESP ) {
        //
        // try reading soap action response
        //
        assert( action_value != NULL );

        *action_value = NULL;

        names[0] = "Envelope";
        names[1] = "Body";
        names[2] = name;
        if( dom_find_deep_node( names, 3, root_node, &node ) ==
            UPNP_E_SUCCESS ) {
            node_str = ixmlPrintNode( node );
            if( node_str == NULL ) {
                err_code = UPNP_E_OUTOF_MEMORY;
                goto error_handler;
            }

            if( ixmlParseBufferEx( node_str,
                                   ( IXML_Document ** ) action_value ) !=
                IXML_SUCCESS ) {
                err_code = UPNP_E_BAD_RESPONSE;
                goto error_handler;
            }

            err_code = SOAP_ACTION_RESP;
            done = TRUE;
        }
    } else if( code == SOAP_VAR_RESP ) {
        // try reading var response
        assert( str_value != NULL );
        *str_value = NULL;

        names[0] = "Envelope";
        names[1] = "Body";
        names[2] = "QueryStateVariableResponse";
        names[3] = "return";
        if( dom_find_deep_node( names, 4, root_node, &node )
            == UPNP_E_SUCCESS ) {
            nodeValue = get_node_value( node );
            if( nodeValue == NULL ) {
                goto error_handler;
            }

            *str_value = ixmlCloneDOMString( nodeValue );
            err_code = SOAP_VAR_RESP;
            done = TRUE;
        }
    }

    if( !done ) {
        // not action or var resp; read error code and description
        *str_value = NULL;

        names[0] = "Envelope";
        names[1] = "Body";
        names[2] = "Fault";
        names[3] = "detail";
        names[4] = "UPnPError";
        if( dom_find_deep_node( names, 5, root_node, &error_node )
            != UPNP_E_SUCCESS ) {
            goto error_handler;
        }

        if( dom_find_node( "errorCode", error_node, &node )
            != UPNP_E_SUCCESS ) {
            goto error_handler;
        }

        temp_str = get_node_value( node );
        if( temp_str == NULL ) {
            goto error_handler;
        }

        *upnp_error_code = atoi( temp_str );
        if( *upnp_error_code > 400 ) {
            err_code = *upnp_error_code;
            goto error_handler; // bad SOAP error code
        }

        if( code == SOAP_VAR_RESP ) {
            if( dom_find_node( "errorDescription", error_node, &node )
                != UPNP_E_SUCCESS ) {
                goto error_handler;
            }

            nodeValue = get_node_value( node );
            if( nodeValue == NULL ) {
                goto error_handler;
            }
            *str_value = ixmlCloneDOMString( nodeValue );
            if( *str_value == NULL ) {
                goto error_handler;
            }
            err_code = SOAP_VAR_RESP_ERROR;
        }

        else if( code == SOAP_ACTION_RESP ) {
            error_node_str = ixmlPrintNode( error_node );
            if( error_node_str == NULL ) {
                err_code = UPNP_E_OUTOF_MEMORY;
                goto error_handler;
            }

            if( ixmlParseBufferEx( error_node_str,
                                   ( IXML_Document ** ) action_value ) !=
                IXML_SUCCESS ) {
                err_code = UPNP_E_BAD_RESPONSE;

                goto error_handler;
            }
            err_code = SOAP_ACTION_RESP_ERROR;
        }
    }

  error_handler:

    ixmlDocument_free( doc );
    ixmlFreeDOMString( node_str );
    ixmlFreeDOMString( error_node_str );
    return err_code;
}
コード例 #5
0
void gena_process_notification_event(
	SOCKINFO *info,
	http_message_t *event)
{
	struct Upnp_Event event_struct;
	IXML_Document *ChangedVars = NULL;
	int eventKey;
	token sid;
	ClientSubscription *subscription = NULL;
	struct Handle_Info *handle_info;
	void *cookie;
	Upnp_FunPtr callback;
	UpnpClient_Handle client_handle;
	const UpnpString *tmpSID = NULL;

	memptr sid_hdr;
	memptr nt_hdr,
	nts_hdr;
	memptr seq_hdr;

	/* get SID */
	if (httpmsg_find_hdr(event, HDR_SID, &sid_hdr) == NULL) {
		error_respond(info, HTTP_PRECONDITION_FAILED, event);
		goto exit_function;
	}
	sid.buff = sid_hdr.buf;
	sid.size = sid_hdr.length;

	/* get event key */
	if (httpmsg_find_hdr(event, HDR_SEQ, &seq_hdr) == NULL ||
	    matchstr(seq_hdr.buf, seq_hdr.length, "%d%0", &eventKey) != PARSE_OK) {
		error_respond( info, HTTP_BAD_REQUEST, event );
		goto exit_function;
	}

	/* get NT and NTS headers */
	if (httpmsg_find_hdr(event, HDR_NT, &nt_hdr) == NULL ||
	    httpmsg_find_hdr(event, HDR_NTS, &nts_hdr) == NULL) {
		error_respond( info, HTTP_BAD_REQUEST, event );
		goto exit_function;
	}

	/* verify NT and NTS headers */
	if (memptr_cmp(&nt_hdr, "upnp:event") != 0 ||
	    memptr_cmp(&nts_hdr, "upnp:propchange") != 0) {
		error_respond(info, HTTP_PRECONDITION_FAILED, event);
		goto exit_function;
	}

	/* parse the content (should be XML) */
	if (!has_xml_content_type(event) ||
	    event->msg.length == 0 ||
	    ixmlParseBufferEx(event->entity.buf, &ChangedVars) != IXML_SUCCESS) {
		error_respond(info, HTTP_BAD_REQUEST, event);
		goto exit_function;
	}

	HandleLock();

	/* get client info */
	if (GetClientHandleInfo(&client_handle, &handle_info) != HND_CLIENT) {
		error_respond(info, HTTP_PRECONDITION_FAILED, event);
		HandleUnlock();
		goto exit_function;
	}

	/* get subscription based on SID */
	subscription = GetClientSubActualSID(handle_info->ClientSubList, &sid);
	if (subscription == NULL) {
		if (eventKey == 0) {
			/* wait until we've finished processing a subscription  */
			/*   (if we are in the middle) */
			/* this is to avoid mistakenly rejecting the first event if we  */
			/*   receive it before the subscription response */
			HandleUnlock();

			/* try and get Subscription Lock  */
			/*   (in case we are in the process of subscribing) */
			SubscribeLock();

			/* get HandleLock again */
			HandleLock();

			if (GetClientHandleInfo(&client_handle, &handle_info) != HND_CLIENT) {
				error_respond(info, HTTP_PRECONDITION_FAILED, event);
				SubscribeUnlock();
				HandleUnlock();
				goto exit_function;
			}

			subscription = GetClientSubActualSID(handle_info->ClientSubList, &sid);
			if (subscription == NULL) {
				error_respond( info, HTTP_PRECONDITION_FAILED, event );
				SubscribeUnlock();
				HandleUnlock();
				goto exit_function;
			}

			SubscribeUnlock();
		} else {
			error_respond( info, HTTP_PRECONDITION_FAILED, event );
			HandleUnlock();
			goto exit_function;
		}
	}

	/* success */
	error_respond(info, HTTP_OK, event);

	/* fill event struct */
	tmpSID = UpnpClientSubscription_get_SID(subscription);
	memset(event_struct.Sid, 0, sizeof(event_struct.Sid));
	strncpy(event_struct.Sid, UpnpString_get_String(tmpSID),
		sizeof(event_struct.Sid) - 1);
	event_struct.EventKey = eventKey;
	event_struct.ChangedVariables = ChangedVars;

	/* copy callback */
	callback = handle_info->Callback;
	cookie = handle_info->Cookie;

	HandleUnlock();

	/* make callback with event struct */
	/* In future, should find a way of mainting */
	/* that the handle is not unregistered in the middle of a */
	/* callback */
	callback(UPNP_EVENT_RECEIVED, &event_struct, cookie);

exit_function:
	ixmlDocument_free(ChangedVars);
}