Esempio n. 1
0
static void appendChild(osrfXMLGatewayParser* p, jsonObject* obj) {

    if(p->obj == NULL) 
        p->obj = obj;

    if(p->objStack->size == 0)
        return;
    
    jsonObject* parent = OSRF_LIST_GET_INDEX(p->objStack, p->objStack->size - 1);

    if(parent->type == JSON_ARRAY) {
        jsonObjectPush(parent, obj);
    } else {
        char* key = osrfListPop(p->keyStack);
        jsonObjectSetKey(parent, key, obj);
        free(key); /* the list is not setup for auto-freeing */
    }
}
void* osrf_responder_thread_main_body(transport_message *tmsg) {

    osrfList *msg_list = NULL;
    osrfMessage *one_msg = NULL;
    int i;

    osrfLogDebug(OSRF_LOG_MARK, 
        "WS received opensrf response for thread=%s", tmsg->thread);

    // first we need to perform some maintenance
    msg_list = osrfMessageDeserialize(tmsg->body, NULL);

    for (i = 0; i < msg_list->size; i++) {
        one_msg = OSRF_LIST_GET_INDEX(msg_list, i);

        osrfLogDebug(OSRF_LOG_MARK, 
            "WS returned response of type %d", one_msg->m_type);

        /*  if our client just successfully connected to an opensrf service,
            cache the sender so that future calls on this thread will use
            the correct recipient. */
        if (one_msg && one_msg->m_type == STATUS) {

            if (one_msg->status_code == OSRF_STATUS_OK) {

                if (!apr_hash_get(trans->stateful_session_cache, 
                        tmsg->thread, APR_HASH_KEY_STRING)) {

                    apr_size_t ses_size = 
                        apr_hash_count(trans->stateful_session_cache);

                    if (ses_size < MAX_ACTIVE_STATEFUL_SESSIONS) {

                        osrfLogDebug(OSRF_LOG_MARK, "WS caching sender "
                            "thread=%s, sender=%s; concurrent=%d", 
                            tmsg->thread, tmsg->sender, ses_size);

                        apr_hash_set(trans->stateful_session_cache, 
                            apr_pstrdup(trans->stateful_session_pool, tmsg->thread),
                            APR_HASH_KEY_STRING, 
                            apr_pstrdup(trans->stateful_session_pool, tmsg->sender));

                    } else {
                        osrfLogWarning(OSRF_LOG_MARK, 
                            "WS max concurrent sessions (%d) reached.  "
                            "Current session will not be tracked",
                            MAX_ACTIVE_STATEFUL_SESSIONS
                        );
                    }
                }

            } else {

                // connection timed out; clear the cached recipient
                if (one_msg->status_code == OSRF_STATUS_TIMEOUT) {
                    clear_cached_recipient(tmsg->thread);

                } else {
                    if (one_msg->status_code == OSRF_STATUS_COMPLETE)
                        requests_in_flight--;
                }
            }
        }
    }

    // osrfMessageDeserialize applies the freeItem handler to the 
    // newly created osrfList.  We only need to free the list and 
    // the individual osrfMessage's will be freed along with it
    osrfListFree(msg_list);
    
    // relay the response messages to the client
    jsonObject *msg_wrapper = NULL;
    char *msg_string = NULL;

    // build the wrapper object
    msg_wrapper = jsonNewObject(NULL);
    jsonObjectSetKey(msg_wrapper, "thread", jsonNewObject(tmsg->thread));
    jsonObjectSetKey(msg_wrapper, "log_xid", jsonNewObject(tmsg->osrf_xid));
    jsonObjectSetKey(msg_wrapper, "osrf_msg", jsonParseRaw(tmsg->body));

    if (tmsg->is_error) {
        osrfLogError(OSRF_LOG_MARK, 
            "WS received jabber error message in response to thread=%s", 
            tmsg->thread);
        jsonObjectSetKey(msg_wrapper, "transport_error", jsonNewBoolObject(1));
    }

    msg_string = jsonObjectToJSONRaw(msg_wrapper);

    // drop the JSON on the outbound wire
    trans->server->send(trans->server, MESSAGE_TYPE_TEXT, 
        (unsigned char*) msg_string, strlen(msg_string));

    free(msg_string);
    jsonObjectFree(msg_wrapper);
}