static void getSessionObjectCallback(ParseClient client, int error, int httpStatus, const char* httpResponseBody) {
    ParseClientInternal *clientInternal = getClient(client);

    if (error == 0 && httpResponseBody != NULL) {
        // extract objectId for the session if no object id, this is invalid token
        char objectId[16];
        if (simpleJsonProcessor(httpResponseBody, "objectId", objectId, sizeof(objectId))) {
            char installationId[40];
            if (simpleJsonProcessor(httpResponseBody, "installationId", installationId, sizeof(installationId))) {
                if(strncmp(clientInternal->installationId, installationId, sizeof(installationId))) {
                    // else if installation id does not match we cannot use this ession
                    // let it fall but disregard it. 
                    parseLog(PARSE_LOG_WARN, "InstallationId does not match.\n");
                    return;
                }
                // if it has installation id and it matches we are done
                parseLog(PARSE_LOG_INFO, "Session and installationId matched.\n");
            } else {
                // if no installation id this is new session and need to 
                // associate it with simple PUT /1/sessions/me with empty body {}
                // and header with installation id.
                parseSendRequest(client, "PUT", "/1/sessions/me", "{}", NULL);
            }
        } else {
            // no session found, do nothing
            parseLog(PARSE_LOG_WARN, "My session is not found\n");
        }
    } else {
        parseLog(PARSE_LOG_ERROR, "Did not manage to talk to the server.\n");
    }
}
Beispiel #2
0
static void pushCallback(ParseClient client, int error, const char *buffer) {
    if (error == 0 && buffer != NULL) {
        char data[64] = {0};
        char id[16] = {0};
        char orig[16] = {0};
        snprintf(orig, sizeof(orig), "%ld", run);
        if (simpleJsonProcessor(buffer, "data", data, sizeof(data))) {
            if (simpleJsonProcessor(data, "id", id, sizeof(id))) {
                if (strncmp(id, orig, sizeof(id)) == 0) {
                    pushCounter++;
                }
            }
        }
    }
}
int parseGetErrorCode(const char *httpResponseBody)
{
    char value[16];
    if (simpleJsonProcessor(httpResponseBody, "code", value, sizeof(value))) {
        return strtoumax(value, NULL, 10);
    }
    return 0;
}
static void getInstallationCallback(ParseClient client, int error, int httpStatus, const char* httpResponseBody) {
    ParseClientInternal *parseClient = getInternalClient(client);

    if ((error == 0) && (httpStatus >= 200 && httpStatus < 300)) {
        simpleJsonProcessor(httpResponseBody, "objectId", parseClient->installationObjectId, sizeof(parseClient->installationObjectId));
        simpleJsonProcessor(httpResponseBody, "installationId", parseClient->installationId, sizeof(parseClient->installationId));
#ifdef CLIENT_DEBUG
        DEBUG_PRINT("[Parse] Installation object id: %s.\r\n", parseClient->installationObjectId);
        DEBUG_PRINT("[Parse] Installation id: %s.\r\n", parseClient->installationId);
#endif /* CLIENT_DEBUG */
    } else {
#ifdef CLIENT_DEBUG
        DEBUG_PRINT("[Parse] Failed to get installation. Error: %d, HTTP status: %d\r\n", error, httpStatus);
#endif /* CLIENT_DEBUG */
        memset(parseClient->installationObjectId, 0, sizeof(parseClient->installationObjectId));
    }
}
int parseGetErrorCode(const char *httpResponseBody) {
    // Simple implementation, just extract the 'code' value
    char code[10] = {0};
    if (simpleJsonProcessor(httpResponseBody, "code", code, 10) != 0) {
        return atoi(code);
    }

    return 2;
}
static void setInstallationCallback(ParseClient client, int error, int httpStatus, const char* httpResponseBody)
{
    if (error != 0) {
        return;
    }

    ParseClientInternal *clientInternal = getClient(client);
    char value[64];
    if (simpleJsonProcessor(httpResponseBody, "objectId", value, sizeof(value))) {
        clientInternal->objectId = strdup(value);
    }
    parseLog(PARSE_LOG_INFO, "Got: %s\n", httpResponseBody);
}
int parseProcessNextPushNotification(ParseClient client)
{
    ParseClientInternal *clientInternal = getClient(client);
    if (clientInternal->pushCurlHandle != NULL) {
        size_t read = 0;;
        int length = -1;
        int start = 0;
        char* message = NULL;

        while (length == -1 && parse_push_message_size < sizeof(parse_push_message_buffer)) {
            CURLcode result = curl_easy_recv(clientInternal->pushCurlHandle,
                                             parse_push_message_buffer + parse_push_message_size,
                                             sizeof(parse_push_message_buffer) - parse_push_message_size,
                                             &read);
            if (result == CURLE_OK) {
                parseLog(PARSE_LOG_INFO, "got ok!\n");
                parse_push_message_size += read;
                message = (char *)getPushJson(parse_push_message_buffer,
                                              parse_push_message_size,
                                              &start,
                                              &length);
            } else if (result == CURLE_AGAIN) {
                break;
            } else {
                parseLog(PARSE_LOG_ERROR, "curl_easy_recv read %i an error %s\n", length, curl_easy_strerror(result));
                if (clientInternal->pushCallback != NULL) {
                    clientInternal->pushCallback(client, ECONNRESET, NULL);
                }
                return 0;
            }
        }
        if (length == -1 && parse_push_message_size == sizeof(parse_push_message_buffer)) {
            // this message is bigger than the buffer, we need to drop it :-(
            parse_push_message_size = 0;
            return 0;
        }

        parseLog(PARSE_LOG_INFO, "message = %p, start = %i, length = %i\n", message, start, length);

        if (length > 0 && message != NULL) {

            message[length] = '\0'; // We assume messages are separated by '\n'.
            parseLog(PARSE_LOG_INFO, "message = '%s'\n", message);

            char time[32];
            if (simpleJsonProcessor(message, "time", time, sizeof(time))) {
                if (clientInternal->lastPushTime) {
                    free(clientInternal->lastPushTime);
                }
                clientInternal->lastPushTime = strdup(time);
                parseOsStoreKey(clientInternal->applicationId, PARSE_LAST_PUSH_TIME, time);
                parseLog(PARSE_LOG_INFO, "lastPush = '%s'\n", clientInternal->lastPushTime);
            }
            if (strncmp("{}", message, 2) == 0) {
                // we got a hearbeat back
                parseLog(PARSE_LOG_DEBUG, "got heartbeat\n");
            } else if (clientInternal->pushCallback != NULL) {
                clientInternal->pushCallback(client, 0, message);
            }
            parse_push_message_size -= length + 1;
            if (parse_push_message_size > 0) {
                memmove(parse_push_message_buffer, parse_push_message_buffer + length + 1, parse_push_message_size);
            }

            return (parse_push_message_size > 0) ? 1 : 0;
        }

        unsigned int seconds = secondsSinceBoot();
        if (seconds > clientInternal->lastHearbeat + PARSE_HEARTBIT_INTERVAL_SECONDS) {
            clientInternal->lastHearbeat = seconds;
            size_t sent;
            curl_easy_send(clientInternal->pushCurlHandle, "{}\n", 3, &sent);
        }
    }
    return 0;
}
Beispiel #8
0
int main(int argc, char *argv[]) {

    // CREATE UNIQUE IDENTIFIER FOR THE RUN

    run = time(NULL);
    char classPathOne[128] = {0};
    char classPathTwo[128] = {0};
    char classPathThree[128] = {0};
    char objectId[11] = {0};
    char path[256]  = {0};

    snprintf(classPathOne, sizeof(classPathOne), "/classes/TestObjectOne%ld", run);


    // TEST INITIALIZATION
    ParseClient client = parseInitializeWithServerURL(YOUR_APP_IP, YOUR_CLIENT_KEY, YOUR_SERVER_URL);
    logResults(client != NULL, 1, "parseInitialize call", "failed to start parse");


    // TEST GENERATION OF INSTALLATION ID

    const char* id = parseGetInstallationId(client);
    logResults(id == NULL, 0, "parseGetInstallationId call", "remove .parse-embedded from home directory");

    parseSendRequest(client, "GET", "/classes/testObjectFake/1111111", NULL, NULL);

    id = parseGetInstallationId(client);
    logResults(id != NULL, 1, "parseGetInstallationId call", "did not create the installation id properly");

    logResults(verifyInstallationId(id), 0, "installation id generated correctly", "installation id is not correct");

    // TEST CREATING AND FETCHING OBJECTS ON/FROM THE SERVER

    clearCachedResults(); 

    parseSendRequest(client, "POST", classPathOne, "{\"test\":\"object1\", \"value\":1}", callback);   
    logResults(cachedRunResult != NULL, 0, "create test object 1", "creating object failed");
    memset(objectId, 0, sizeof(objectId));
    logResults(simpleJsonProcessor(cachedRunResult, "objectId", objectId, sizeof(objectId)), 0, "object 1 created", "could not create an object");

    clearCachedResults();

    memset(path, 0, sizeof(path));
    snprintf(path, sizeof(path), "%s/%s", classPathOne, objectId);
    parseSendRequest(client, "GET", classPathOne, NULL, callback);   
    logResults(cachedRunResult != NULL, 0, "fetch test object 1", "fetching object failed");

    clearCachedResults(); 

    parseSendRequest(client, "POST", classPathOne, "{\"test\":\"object1\", \"value\":2}", callback);   
    logResults(cachedRunResult != NULL, 0, "create test object 2", "creating object failed");
    memset(objectId, 0, sizeof(objectId));
    logResults(simpleJsonProcessor(cachedRunResult, "objectId", objectId, sizeof(objectId)), 0, "object 2 created", "could not create an object");
    
    clearCachedResults();

    memset(path, 0, sizeof(path));
    snprintf(path, sizeof(path), "%s/%s", classPathOne, objectId);
    parseSendRequest(client, "GET", classPathOne, NULL, callback);   
    logResults(cachedRunResult != NULL, 0, "fetch test object 2", "fetching object failed");

    clearCachedResults(); 

    parseSendRequest(client, "POST", classPathOne, "{\"test\":\"object1\", \"value\":3}", callback);   
    logResults(cachedRunResult != NULL, 0, "create test object 3", "creating object failed");
    char objectIdKeepAround[11] = {0};
    logResults(simpleJsonProcessor(cachedRunResult, "objectId", objectIdKeepAround, sizeof(objectIdKeepAround)), 0, "object 3 created", "could not create an object");

    clearCachedResults();

    memset(path, 0, sizeof(path));
    snprintf(path, sizeof(path), "%s/%s", classPathOne, objectIdKeepAround);
    parseSendRequest(client, "GET", classPathOne, NULL, callback);   
    logResults(cachedRunResult != NULL, 0, "fetch test object 3", "fetching object failed");

    clearCachedResults(); 

    parseSendRequest(client, "POST", classPathOne, "{\"test\":\"object1\", \"value\":2}", callback);   
    logResults(cachedRunResult != NULL, 0, "create test object 4", "creating object failed");
    memset(objectId, 0, sizeof(objectId));
    logResults(simpleJsonProcessor(cachedRunResult, "objectId", objectId, sizeof(objectId)), 0, "object 4 created", "could not create an object");
    
    clearCachedResults();

    memset(path, 0, sizeof(path));
    snprintf(path, sizeof(path), "%s/%s", classPathOne, objectId);
    parseSendRequest(client, "GET", classPathOne, NULL, callback);   
    logResults(cachedRunResult != NULL, 0, "fetch test object 4", "fetching object failed");

    // TEST QUERIES

    clearCachedResults();

    parseSendRequest(client, "GET", classPathOne, "where={\"value\":2}", callback);   
    logResults(cachedRunResult != NULL, 0, "query objects", "querying objects failed");

    const char* results = "{\"results\":[{\"";
    int cmp = !strncmp(cachedRunResult, results, strlen(results));
    char* location1 = strstr(cachedRunResult, "objectId");
    char* location2 = strstr(location1 + 1, "objectId");
    char* location3 = strstr(location2 + 1, "objectId");
    logResults(cmp && location1 && location2 && !location3, 0, "query value", "query results not valid");


    // TEST OBJECT MODIFICATION

    clearCachedResults(); 

    memset(path, 0, sizeof(path));
    snprintf(path, sizeof(path), "%s/%s", classPathOne, objectIdKeepAround);

    parseSendRequest(client, "PUT", path, "{\"test\":\"object1\", \"value\":2}", callback);   
    logResults(cachedRunResult != NULL, 0, "modify test object 3", "modifying object failed");

    clearCachedResults();

    parseSendRequest(client, "GET", classPathOne, "where={\"value\":2}", callback);   
    logResults(cachedRunResult != NULL, 0, "query objects after modification", "querying objects failed");

    results = "{\"results\":[{\"";
    cmp = !strncmp(cachedRunResult, results, strlen(results));
    location1 = strstr(cachedRunResult, "objectId");
    location2 = strstr(location1 + 1, "objectId");
    location3 = strstr(location2 + 1, "objectId");
    logResults(cmp && location1 && location2 && location3, 0, "query value after modifying an object", "query results not valid");

    // TEST DELETING AN OBJECT

    clearCachedResults(); 

    memset(path, 0, sizeof(path));
    snprintf(path, sizeof(path), "%s/%s", classPathOne, objectIdKeepAround);

    parseSendRequest(client, "DELETE", path, NULL, callback);   
    logResults(cachedRunResult != NULL, 0, "delete test object 3", "deleting object failed");

    clearCachedResults();

    parseSendRequest(client, "GET", classPathOne, "where={\"value\":2}", callback);   
    logResults(cachedRunResult != NULL, 0, "query objects after delete", "querying objects failed");

    results = "{\"results\":[{\"";
    cmp = !strncmp(cachedRunResult, results, strlen(results));
    location1 = strstr(cachedRunResult, "objectId");
    location2 = strstr(location1 + 1, "objectId");
    location3 = strstr(location2 + 1, "objectId");
    logResults(cmp && location1 && location2 && !location3, 0, "query value after deleting an object", "query results not valid");

    // TEST PUSH

    parseSetPushCallback(client, pushCallback);
    parseStartPushService(client);
    int socket = parseGetPushSocket(client);

    int loopCount = 20;


    printf("[!!!!!!!] Run ./push.sh %s %ld\n", id, run);

    while(loopCount--) {
        struct timeval tv;
        fd_set receive, send, error;

        tv.tv_sec = 10;
        tv.tv_usec= 0;
        FD_ZERO(&receive);
        FD_ZERO(&send);
        FD_ZERO(&error);
        FD_SET(socket, &error);
        FD_SET(socket, &receive);
        select(socket + 1, &receive, &send, &error, &tv);

        parseProcessNextPushNotification(client);

        if (pushCounter == 10) loopCount = loopCount > 2 ? 2 : loopCount;
    }

    logResults(pushCounter == 10, 0, "receive push notifications", "did not receive the push notifications correctly");

    logSummary();
    return 0;
}