Ejemplo n.º 1
0
// Convert the OsDateTimeBase value to an OsTime value
// The OsTime value is relative to when the system was booted.
OsStatus OsDateTimeLinux::cvtToTimeSinceBoot(OsTime& rTime) const
{
   unsigned long curTimeAsSecsSinceBoot;
   time_t        curTimeAsTimeT;
   struct tm     thisTime;
   long          thisTimeAsSecsSinceBoot;
   time_t        thisTimeAsTimeT;

   // convert "this" OsDateTime to a time_t representation
   thisTime.tm_year = mYear - 1900;
   thisTime.tm_mon  = mMonth;
   thisTime.tm_mday = mDay;
   thisTime.tm_hour = mHour;
   thisTime.tm_min  = mMinute;
   thisTime.tm_sec  = mSecond;
   thisTimeAsTimeT  = mktime(&thisTime);
   assert(thisTimeAsTimeT >= 0);

   // get the current time as a time_t
   curTimeAsTimeT   = time(NULL);
   assert(curTimeAsTimeT >= 0);

   // get the current time as seconds since boot
   curTimeAsSecsSinceBoot = (unsigned long)secondsSinceBoot();

   // convert "this" time to seconds since boot
   thisTimeAsSecsSinceBoot = (thisTimeAsTimeT - curTimeAsTimeT) +
                             curTimeAsSecsSinceBoot;

   OsTime deltaOsTime(thisTimeAsSecsSinceBoot, 0);
   rTime = deltaOsTime;

   return OS_SUCCESS;
}
Ejemplo n.º 2
0
static int parseProgressInternal(void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow)
{
    unsigned long startTime = (uintptr_t) clientp;
    unsigned long nowTime = secondsSinceBoot();

    if (nowTime - startTime > PARSE_REQUEST_TIMEOUT_SECONDS) {
        parseLog(PARSE_LOG_WARN, "Request timeout after %i seconds.\n", nowTime - startTime);
        return 1;
    }

    return 0;
}
Ejemplo n.º 3
0
// Return the current time as an OsTime value
// The OsTime value is relative to when the system was booted.
void OsDateTimeLinux::getCurTimeSinceBoot(OsTime& rTime)
{
   double seconds;
   int secs;
   int usecs;

   seconds = secondsSinceBoot();
   secs  = (int)seconds;
   usecs = (int)((seconds - secs) * MICROSECS_PER_SEC);

   OsTime timeSinceBoot(secs, usecs);
   rTime = timeSinceBoot;
}
Ejemplo n.º 4
0
static void parseSendRequestInternal(
        ParseClient client,
        const char *httpVerb,
        const char* httpPath,
        const char* requestBody,
        parseRequestCallback callback,
        int useInstallationIdHeader)
{
    ParseClientInternal *clientInternal = getClient(client);

    int getRequestBody = 0;
    CURLcode result = CURLE_OK;
    CURL *curl = NULL;
    curl = curl_easy_init();
    if (curl == NULL) {
        if (callback != NULL) callback(client, CURLE_FAILED_INIT, 0, NULL);
        return;
    }

    result = curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, httpVerb);
    if (result != CURLE_OK) {
        if (callback != NULL) callback(client, result, 0, NULL);
        return;
    }

    if (requestBody != NULL) {
        if (strncmp(httpVerb, "GET", sizeof("GET"))) {
            result = curl_easy_setopt(curl, CURLOPT_POSTFIELDS, requestBody);
            if (result != CURLE_OK) {
                if (callback != NULL) callback(client, result, 0, NULL);
                return;
            }
            result = curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)strlen(requestBody));
            if (result != CURLE_OK) {
                if (callback != NULL) callback(client, result, 0, NULL);
                return;
            }
        } else {
            getRequestBody = 1;
        }
    }

    int urlSize = strlen("https://api.parse.com");
    urlSize += strlen(httpPath) + 1;
    char* getEncodedBody = NULL;
    if (getRequestBody) {
        urlSize += strlen(requestBody) + 1;
    }
    char *fullUrl = calloc(1, urlSize + 1);
    if (fullUrl == NULL) {
        parseLog(PARSE_LOG_ERROR, "%s:%s generated out of memory.\n", __FUNCTION__, __LINE__);
        if (callback != NULL) callback(client, ENOMEM, 0, NULL);
        return;
    }
    strncat(fullUrl, "https://api.parse.com", urlSize);
    strncat(fullUrl, httpPath, urlSize - strlen(fullUrl));
    if (getRequestBody) {
        strncat(fullUrl, "?", urlSize - strlen(fullUrl));
        strncat(fullUrl, requestBody, urlSize - strlen(fullUrl));
    }

    result = curl_easy_setopt(curl, CURLOPT_URL, fullUrl);
    free(fullUrl);

    if (result != CURLE_OK) {
        if (callback != NULL) callback(client, result, 0, NULL);
        return;
    }

    struct curl_slist *headers = NULL;

    char header[128] = {};
    snprintf(header, sizeof(header), "X-Parse-Application-Id: %s", clientInternal->applicationId);
    headers = curl_slist_append(headers, header);

    snprintf(header, sizeof(header), "X-Parse-Client-Version: c-embedded-%s", VERSION);
    headers = curl_slist_append(headers, header);

    snprintf(header, sizeof(header), "X-Parse-OS-Version: %s", clientInternal->osVersion);
    headers = curl_slist_append(headers, header);

    snprintf(header, sizeof(header), "X-Parse-Client-Key: %s", clientInternal->clientKey);
    headers = curl_slist_append(headers, header);

    if (useInstallationIdHeader && clientInternal->installationId) {
        snprintf(header, sizeof(header), "X-Parse-Installation-Id: %s", clientInternal->installationId);
        headers = curl_slist_append(headers, header);
    }

    if (clientInternal->sessionToken) {
        snprintf(header, sizeof(header), "X-Parse-Session-Token: %s", clientInternal->sessionToken);
        headers = curl_slist_append(headers, header);
    }

    headers = curl_slist_append(headers, "Content-Type: application/json; charset=utf-8");
    headers = curl_slist_append(headers, "Connection: close");
    headers = curl_slist_append(headers, "Accept:"); // This line removes 'Accpet' header.

    result = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    if (result != CURLE_OK) {
        if (callback != NULL) callback(client, result, 0, NULL);
        return;
    }
         
    result = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curlDataCallback);
    if (result != CURLE_OK) {
        if (callback != NULL) callback(client, result, 0, NULL);
        return;
    }
        
    ParseRequestDataInternal data;
    data.client = client;
    data.requestCallback = callback;
    data.curl = curl;

    result = curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&data);
    if (result != CURLE_OK) {
        if (callback != NULL) callback(client, result, 0, NULL);
        return;
    }

    result = curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
    if (result != CURLE_OK) {
        if (callback != NULL) callback(client, result, 0, NULL);
        return;
    }

    result = curl_easy_setopt(curl, CURLOPT_XFERINFODATA, (void*)((uintptr_t)secondsSinceBoot()));
    if (result != CURLE_OK) {
        if (callback != NULL) callback(client, result, 0, NULL);
        return;
    }

    result = curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, parseProgressInternal);
    if (result != CURLE_OK) {
        if (callback != NULL) callback(client, result, 0, NULL);
        return;
    }

    result = curl_easy_perform(curl);
    if (result != CURLE_OK) {
        // We use callback to implement timeout so let's report the
        // error as timeout in the case callback aborted the request.
        if (result == CURLE_ABORTED_BY_CALLBACK) result = CURLE_OPERATION_TIMEDOUT;
        if (callback != NULL) callback(client, result, 0, NULL);
        return;
    }
    curl_easy_cleanup(curl);
    curl_slist_free_all(headers);
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
int parseStartPushService(ParseClient client)
{
    ParseClientInternal *clientInternal = getClient(client);
    CURLcode result = CURLE_OK;
    CURL *curl = NULL;

    if (clientInternal->pushCurlHandle != NULL) {
        return 0;
    }

    parseCreateInstallationIdIfNeeded(client);
    parseLog(PARSE_LOG_INFO, "Installation id: %s\n", clientInternal->installationId);

    curl = curl_easy_init();
    if (curl == NULL) {
        return CURLE_FAILED_INIT;
    }

    result = curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 1L);
    if (result != CURLE_OK) {
        return result;
    }
    result = curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_ALL);
    if (result != CURLE_OK) {
        return result;
    }
    result = curl_easy_setopt(curl, CURLOPT_URL, "https://push.parse.com");
    if (result != CURLE_OK) {
        return result;
    }
    result = curl_easy_perform(curl);
    if (result != CURLE_OK) {
        return result;
    }

    clientInternal->pushCurlHandle = curl;

    size_t sent;

    char push[256];
    if (clientInternal->lastPushTime) {
        snprintf(push,
             sizeof(push),
             "{\"installation_id\":\"%s\", \"oauth_key\":\"%s\", \"v\":\"e1.0.0\", \"last\":\"%s\"}\n",
             clientInternal->installationId,
             clientInternal->applicationId,
             clientInternal->lastPushTime);
    } else {
        snprintf(push,
             sizeof(push),
             "{\"installation_id\":\"%s\", \"oauth_key\":\"%s\", \"v\":\"e1.0.0\", \"last\":null}\n",
             clientInternal->installationId,
             clientInternal->applicationId);
    }

    curl_easy_send(curl, push, strlen(push), &sent);

    parseLog(PARSE_LOG_INFO, "Sending %i chars in request '%s'\n", sent, push); 

    curl_easy_send(curl, "{}\n", 3, &sent);
    clientInternal->lastHearbeat = secondsSinceBoot();

    return 0;
}