Esempio n. 1
0
static void startElementHandler(
    void *parser, const xmlChar *name, const xmlChar **atts) {

    osrfXMLGatewayParser* p = (osrfXMLGatewayParser*) parser;
    jsonObject* obj;

    char* hint = getXMLAttr(atts, "class_hint");

    if(!strcmp((char*) name, "null")) {
        appendChild(p, jsonNewObject(NULL));
        return;
    }

    if(!strcmp((char*) name, "string")) {
        p->inString = 1;
        return;
    }

    if(!strcmp((char*) name, "element")) {
       osrfListPush(p->keyStack, strdup(getXMLAttr(atts, "key")));
       return;
    }

    if(!strcmp((char*) name, "object")) {
        obj = jsonNewObject(NULL);
        jsonObjectSetClass(obj, hint); /* OK if hint is NULL */
        obj->type = JSON_HASH;
        appendChild(p, obj);
        osrfListPush(p->objStack, obj);
        return;
    }

    if(!strcmp((char*) name, "array")) {
        obj = jsonNewObject(NULL);
        jsonObjectSetClass(obj, hint); /* OK if hint is NULL */
        obj->type = JSON_ARRAY;
        appendChild(p, obj);
        osrfListPush(p->objStack, obj);
        return;
    }


    if(!strcmp((char*) name, "number")) {
        p->inNumber = 1;
        return;
    }

    if(!strcmp((char*) name, "boolean")) {
        obj = jsonNewObject(NULL);
        obj->type = JSON_BOOL;
        char* val = getXMLAttr(atts, "value");
        if(val && !strcmp(val, "true"))
            obj->value.b = 1;
        
        appendChild(p, obj);
        return;
    }
}
Esempio n. 2
0
/**
	@brief Translate a JSON array into an osrfList of osrfMessages.
	@param string The JSON string to be translated.
	@param list Pointer to an osrfList of osrfMessages (may be NULL)
	@return Pointer to an osrfList containing pointers to osrfMessages.

	The JSON string is expected to be a JSON array, with each element encoding an osrfMessage.

	Translate each element of the JSON array into an osrfMessage, and store a pointer to the
	osrfMessage in an osrfList.

	If the @a list parameter is NULL, create a new osrfList (with osrfMessageFree() as the
	callback function for freeing items), populate it, and return a pointer to it.  Otherwise
	clear the osrfList provided and reuse it.

	When calling osrfMessageDeserialize repeatedly, a reasonable strategy is to pass a NULL
	for the @a list parameter on the first call, and pass the value returned from the first
	call on subsequent calls.

	The calling code is responsible for eventually freeing the returned osrfList by calling
	osrfListFree().
 */
osrfList* osrfMessageDeserialize( const char* string, osrfList* list ) {

	if( list )
		osrfListClear( list );

	if( ! string  || ! *string ) {
		if( ! list ) {
			list = osrfNewList( 1 );
			list->freeItem = (void(*)(void*)) osrfMessageFree;
		}
		return list;                   // No string?  Return empty list.
	}
	
	// Parse the JSON
	jsonObject* json = jsonParse(string);
	if(!json) {
		osrfLogWarning( OSRF_LOG_MARK,
				"osrfMessageDeserialize() unable to parse data: \n%s\n", string);
		if( ! list ) {
			list = osrfNewList( 1 );
			list->freeItem = (void(*)(void*)) osrfMessageFree;
		}
		return list;                   // Bad JSON?  Return empty list.
	}

	const unsigned int count = (int) json->size;
	if( ! list ) {
		// Create a right-sized osrfList
		list = osrfNewList( count );
		list->freeItem = (void(*)(void*)) osrfMessageFree;
	}

	// Traverse the JSON_ARRAY, turning each element into an osrfMessage
	int i;
	for( i = 0; i < count; ++i ) {

		const jsonObject* message = jsonObjectGetIndex( json, i );
		if( message && message->type != JSON_NULL &&
				  message->classname && !strcmp(message->classname, "osrfMessage" )) {
			osrfListPush( list, deserialize_one_message( message ) );
		}
	}

	jsonObjectFree( json );
	return list;
}
Esempio n. 3
0
static int osrfHttpTranslatorProcess(osrfHttpTranslator* trans) {
    if(trans->body == NULL)
        return HTTP_BAD_REQUEST;

    if(!osrfHttpTranslatorSetTo(trans))
        return HTTP_BAD_REQUEST;

    char* jsonBody = osrfHttpTranslatorParseRequest(trans);
    if (NULL == jsonBody)
        return HTTP_BAD_REQUEST;

    while(client_recv(trans->handle, 0))
        continue; // discard any old status messages in the recv queue

    // send the message to the recipient
    transport_message* tmsg = message_init(
        jsonBody, NULL, trans->thread, trans->recipient, NULL);
    message_set_osrf_xid(tmsg, osrfLogGetXid());
    client_send_message(trans->handle, tmsg);
    message_free(tmsg); 
    free(jsonBody);

    if(trans->disconnectOnly) {
        osrfLogDebug(OSRF_LOG_MARK, "exiting early on disconnect");
        osrfCacheRemove(trans->thread);
        return OK;
    }

    // process the response from the opensrf service
    int firstWrite = 1;
    while(!trans->complete) {
        transport_message* msg = client_recv(trans->handle, trans->timeout);

        if(trans->handle->error) {
            osrfLogError(OSRF_LOG_MARK, "Transport error");
            osrfCacheRemove(trans->thread);
            return HTTP_INTERNAL_SERVER_ERROR;
        }

        if(msg == NULL)
            return HTTP_GATEWAY_TIME_OUT;

        if(msg->is_error) {
            osrfLogError(OSRF_LOG_MARK, "XMPP message resulted in error code %d", msg->error_code);
            osrfCacheRemove(trans->thread);
            return HTTP_NOT_FOUND;
        }

        if(!osrfHttpTranslatorCheckStatus(trans, msg))
            continue;

        if(firstWrite) {
            osrfHttpTranslatorInitHeaders(trans, msg);
            if(trans->connecting)
                osrfHttpTranslatorCacheSession(trans, msg->sender);
            firstWrite = 0;
        }

        if(trans->multipart) {
            osrfHttpTranslatorWriteChunk(trans, msg);
            if(trans->connectOnly)
                break;
        } else {
            if(!trans->messages)
                trans->messages = osrfNewList();
            osrfListPush(trans->messages, msg->body);

            if(trans->complete || trans->connectOnly) {
                growing_buffer* buf = buffer_init(128);
                unsigned int i;
                OSRF_BUFFER_ADD(buf, osrfListGetIndex(trans->messages, 0));
                for(i = 1; i < trans->messages->size; i++) {
                    buffer_chomp(buf); // chomp off the closing array bracket
                    char* body = osrfListGetIndex(trans->messages, i);
                    char newbuf[strlen(body)];
                    sprintf(newbuf, "%s", body+1); // chomp off the opening array bracket
                    OSRF_BUFFER_ADD_CHAR(buf, ',');
                    OSRF_BUFFER_ADD(buf, newbuf);
                }

                ap_rputs(buf->buf, trans->apreq);
                buffer_free(buf);
            }
        }
    }

    if(trans->disconnecting) // DISCONNECT within a multi-message batch
        osrfCacheRemove(trans->thread);

    return OK;
}