Ejemplo n.º 1
0
static int osrfHttpTranslatorCheckStatus(osrfHttpTranslator* trans, transport_message* msg) {
    osrfMessage* omsgList[MAX_MSGS_PER_PACKET];
    int numMsgs = osrf_message_deserialize(msg->body, omsgList, MAX_MSGS_PER_PACKET);
    osrfLogDebug(OSRF_LOG_MARK, "parsed %d response messages", numMsgs);
    if(numMsgs == 0) return 0;

    osrfMessage* last = omsgList[numMsgs-1];
    if(last->m_type == STATUS) {
        if(last->status_code == OSRF_STATUS_TIMEOUT) {
            osrfLogDebug(OSRF_LOG_MARK, "removing cached session on request timeout");
            osrfCacheRemove(trans->thread);
            return 0;
        }
        // XXX hm, check for explicit status=COMPLETE message instead??
        if(last->status_code != OSRF_STATUS_CONTINUE)
            trans->complete = 1;
    }

    return 1;
}
Ejemplo n.º 2
0
/**
	@brief Unpack a transport_message into one or more osrfMessages, and process each one.
	@param msg Pointer to the transport_message to be unpacked and processed.
	@param my_service Application name (optional).
	@return Pointer to an osrfAppSession -- either a pre-existing one or a new one.

	Look for an existing osrfAppSession with which the message is associated.  Such a session
	may already exist if, for example, you're a client waiting for a response from some other
	application, or if you're a server that has opened a stateful session with a client.

	If you can't find an existing session for the current message, and the @a my_service
	parameter has provided an application name, then you're presumably a server receiving
	something from a new client.  Create an application server session to own the new message.

	Barring various errors and malformations, extract one or more osrfMessages from the
	transport_message.  Pass each one to the appropriate routine for processing, depending
	on whether you're acting as a client or as a server.
*/
struct osrf_app_session_struct* osrf_stack_transport_handler( transport_message* msg,
		const char* my_service ) {

	if(!msg) return NULL;

	osrfLogSetXid(msg->osrf_xid);

	osrfLogDebug( OSRF_LOG_MARK,  "Transport handler received new message \nfrom %s "
			"to %s with body \n\n%s\n", msg->sender, msg->recipient, msg->body );

	if( msg->is_error && ! msg->thread ) {
		osrfLogWarning( OSRF_LOG_MARK,
				"!! Received jabber layer error for %s ... exiting\n", msg->sender );
		message_free( msg );
		return NULL;
	}

	if(! msg->thread  && ! msg->is_error ) {
		osrfLogWarning( OSRF_LOG_MARK,
				"Received a non-error message with no thread trace... dropping");
		message_free( msg );
		return NULL;
	}

	osrfAppSession* session = osrf_app_session_find_session( msg->thread );

	if( !session && my_service )
		session = osrf_app_server_session_init( msg->thread, my_service, msg->sender);

	if( !session ) {
		message_free( msg );
		return NULL;
	}

	if(!msg->is_error)
		osrfLogDebug( OSRF_LOG_MARK, "Session [%s] found or built", session->session_id );

	osrf_app_session_set_remote( session, msg->sender );
	osrfMessage* arr[OSRF_MAX_MSGS_PER_PACKET];

	/* Convert the message body into one or more osrfMessages */
	int num_msgs = osrf_message_deserialize(msg->body, arr, OSRF_MAX_MSGS_PER_PACKET);

	osrfLogDebug( OSRF_LOG_MARK, "We received %d messages from %s", num_msgs, msg->sender );

	double starttime = get_timestamp_millis();

	int i;
	for( i = 0; i < num_msgs; i++ ) {

		/* if we've received a jabber layer error message (probably talking to
			someone who no longer exists) and we're not talking to the original
			remote id for this server, consider it a redirect and pass it up */
		if(msg->is_error) {
			osrfLogWarning( OSRF_LOG_MARK,  " !!! Received Jabber layer error message" );

			if( strcmp( session->remote_id, session->orig_remote_id ) ) {
				osrfLogWarning( OSRF_LOG_MARK, "Treating jabber error as redirect for tt [%d] "
					"and session [%s]", arr[i]->thread_trace, session->session_id );

				arr[i]->m_type = STATUS;
				arr[i]->status_code = OSRF_STATUS_REDIRECTED;

			} else {
				osrfLogWarning( OSRF_LOG_MARK, " * Jabber Error is for top level remote "
					" id [%s], no one to send my message to!  Cutting request short...",
					session->remote_id );
				session->transport_error = 1;
				break;
			}
		}

		// grab the ingress value from the first message.
		// they will all be the same
		if (i == 0) osrfAppSessionSetIngress(arr[i]->sender_ingress);

		if( session->type == OSRF_SESSION_CLIENT )
			_do_client( session, arr[i] );
		else
			_do_server( session, arr[i] );
	}

	double duration = get_timestamp_millis() - starttime;
	osrfLogInfo(OSRF_LOG_MARK, "Message processing duration %f", duration);

	message_free( msg );
	osrfLogDebug( OSRF_LOG_MARK, "after msg delete");

	return session;
}
Ejemplo n.º 3
0
/**
 * Parses the request body, logs any REQUEST messages to the activity log, 
 * stamps the translator ingress on each message, and returns the updated 
 * messages as a JSON string.
 */
static char* osrfHttpTranslatorParseRequest(osrfHttpTranslator* trans) {
    osrfMessage* msg;
    osrfMessage* msgList[MAX_MSGS_PER_PACKET];
    int numMsgs = osrf_message_deserialize(trans->body, msgList, MAX_MSGS_PER_PACKET);
    osrfLogDebug(OSRF_LOG_MARK, "parsed %d opensrf messages in this packet", numMsgs);

    if(numMsgs == 0)
        return NULL;

    // log request messages to the activity log
    int i;
    for(i = 0; i < numMsgs; i++) {
        msg = msgList[i];
        osrfMessageSetIngress(msg, TRANSLATOR_INGRESS);

        switch(msg->m_type) {

            case REQUEST: {
                const jsonObject* params = msg->_params;
                growing_buffer* act = buffer_init(128);	
                char* method = msg->method_name;
                buffer_fadd(act, "[%s] [%s] %s %s", trans->remoteHost, "",
                    trans->service, method);

                const jsonObject* obj = NULL;
                int i = 0;
                const char* str;
                int redactParams = 0;
                while( (str = osrfStringArrayGetString(log_protect_arr, i++)) ) {
                    //osrfLogInternal(OSRF_LOG_MARK, "Checking for log protection [%s]", str);
                    if(!strncmp(method, str, strlen(str))) {
                        redactParams = 1;
                        break;
                    }
                }
                if(redactParams) {
                    OSRF_BUFFER_ADD(act, " **PARAMS REDACTED**");
                } else {
                    i = 0;
                    while((obj = jsonObjectGetIndex(params, i++))) {
                        str = jsonObjectToJSON(obj);
                        if( i == 1 )
                            OSRF_BUFFER_ADD(act, " ");
                        else
                            OSRF_BUFFER_ADD(act, ", ");
                        OSRF_BUFFER_ADD(act, str);
                        free(str);
                    }
                }
                osrfLogActivity(OSRF_LOG_MARK, "%s", act->buf);
                buffer_free(act);
                break;
            }

            case CONNECT:
                trans->connecting = 1;
                if (numMsgs == 1) 
                    trans->connectOnly = 1;
                break;

            case DISCONNECT:
                trans->disconnecting = 1;
                if (numMsgs == 1) 
                    trans->disconnectOnly = 1;
                break;

            case RESULT:
                osrfLogWarning( OSRF_LOG_MARK, "Unexpected RESULT message received" );
                break;

            case STATUS:
                osrfLogWarning( OSRF_LOG_MARK, "Unexpected STATUS message received" );
                break;

            default:
                osrfLogWarning( OSRF_LOG_MARK, "Invalid message type %d received",
                    msg->m_type );
                break;
        }
    }

    char* jsonString = osrfMessageSerializeBatch(msgList, numMsgs);
    for(i = 0; i < numMsgs; i++) {
        osrfMessageFree(msgList[i]);
    }
    return jsonString;
}
static char* extract_inbound_messages(
        const request_rec *r, 
        const char* service, 
        const char* thread, 
        const char* recipient, 
        const jsonObject *osrf_msg) {

    int i;
    int num_msgs = osrf_msg->size;
    osrfMessage* msg;
    osrfMessage* msg_list[num_msgs];

    // here we do an extra json round-trip to get the data
    // in a form osrf_message_deserialize can understand
    // TODO: consider a version of osrf_message_init which can 
    // accept a jsonObject* instead of a JSON string.
    char *osrf_msg_json = jsonObjectToJSON(osrf_msg);
    osrf_message_deserialize(osrf_msg_json, msg_list, num_msgs);
    free(osrf_msg_json);

    // should we require the caller to always pass the service?
    if (service == NULL) service = "";

    for(i = 0; i < num_msgs; i++) {
        msg = msg_list[i];
        osrfMessageSetIngress(msg, WEBSOCKET_TRANSLATOR_INGRESS);

        switch(msg->m_type) {

            case REQUEST: {
                const jsonObject* params = msg->_params;
                growing_buffer* act = buffer_init(128);
                char* method = msg->method_name;
                buffer_fadd(act, "[%s] [%s] %s %s", 
                    get_client_ip(r), "", service, method);

                const jsonObject* obj = NULL;
                int i = 0;
                const char* str;
                int redactParams = 0;
                while( (str = osrfStringArrayGetString(log_protect_arr, i++)) ) {
                    if(!strncmp(method, str, strlen(str))) {
                        redactParams = 1;
                        break;
                    }
                }
                if(redactParams) {
                    OSRF_BUFFER_ADD(act, " **PARAMS REDACTED**");
                } else {
                    i = 0;
                    while((obj = jsonObjectGetIndex(params, i++))) {
                        char* str = jsonObjectToJSON(obj);
                        if( i == 1 )
                            OSRF_BUFFER_ADD(act, " ");
                        else
                            OSRF_BUFFER_ADD(act, ", ");
                        OSRF_BUFFER_ADD(act, str);
                        free(str);
                    }
                }
                osrfLogActivity(OSRF_LOG_MARK, "%s", act->buf);
                buffer_free(act);
                requests_in_flight++;
                break;
            }

            case DISCONNECT:
                clear_cached_recipient(thread);
                break;
        }
    }

    char* finalMsg = osrfMessageSerializeBatch(msg_list, num_msgs);

    // clean up our messages
    for(i = 0; i < num_msgs; i++) 
        osrfMessageFree(msg_list[i]);

    return finalMsg;
}