Example #1
0
 public function testClone()
 {
     $filePath0 = CFile::createTemporary();
     $filePath1 = CFile::createTemporary();
     $filePath2 = CFile::createTemporary();
     $filePath3 = CFile::createTemporary();
     CFile::write($filePath0, "The quick");
     CFile::write($filePath1, " brown fox");
     CFile::write($filePath2, " jumps over");
     CFile::write($filePath3, " the lazy dog.");
     $hash0 = new CHash(CHash::SHA256);
     $hash0->computeMoreFromFile($filePath0);
     $hash0->computeMoreFromFile($filePath1);
     $hash0->computeMoreFromFile($filePath2);
     $hash0->computeMoreFromFile($filePath3);
     $hash1 = clone $hash0;
     $hash1->computeMoreFromFile($filePath0);
     $this->assertTrue($hash0->finalize()->equals("ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c"));
     $this->assertTrue($hash1->finalize()->equals("14dc40e99be202c4e59a0c6d1a8854bb50253624080435ed8c65bd6e5e880c95"));
     CFile::delete($filePath0);
     CFile::delete($filePath1);
     CFile::delete($filePath2);
     CFile::delete($filePath3);
 }
Example #2
0
 /**
  * @ignore
  */
 public static function maybeUpdateThirdParty()
 {
     if (!self::isInCliMode()) {
         // This method can be run in CLI mode only.
         assert('false', vs(isset($this), get_defined_vars()));
         return false;
     }
     $updates = CConfiguration::option("updates");
     $updatesAreEnabled = $updates["enable"];
     if ($updatesAreEnabled) {
         $minTimeBetweenDoUpdatesDays = $updates["minTimeBetweenDoUpdatesDays"];
         $components = $updates["components"];
         assert('is_int($minTimeBetweenDoUpdatesDays)', vs(isset($this), get_defined_vars()));
         // Logging.
         $logging = $updates["logging"];
         $loggingIsEnabled = $logging["enable"];
         $logFp = $logging["logFilePath"];
         if ($loggingIsEnabled) {
             assert('!CString::isEmpty($logFp)', vs(isset($this), get_defined_vars()));
             $logFp = CFilePath::frameworkPath($logFp);
             CShell::setLogging($logFp);
         }
         // Mailing.
         $mailing = $updates["mailing"];
         $mailingIsEnabled = $mailing["enable"];
         if ($mailingIsEnabled) {
             $adminMail = CConfiguration::option("admin.mail");
             $to = $adminMail["to"];
             $from = $adminMail["from"];
             $transport = $adminMail["transport"];
             assert('!CString::isEmpty($to) && !CString::isEmpty($from) && !CString::isEmpty($transport)', vs(isset($this), get_defined_vars()));
             $mail;
             if (CString::equalsCi($transport, "smtp")) {
                 $smtpOutgoingServer = $adminMail["smtpOutgoingServer"];
                 $smtpUsername = $adminMail["smtpUsername"];
                 $smtpPassword = $adminMail["smtpPassword"];
                 assert('!CString::isEmpty($smtpOutgoingServer) && !CString::isEmpty($smtpUsername) && ' . '!CString::isEmpty($smtpPassword)', vs(isset($this), get_defined_vars()));
                 $mail = CMail::makeSmtp($smtpOutgoingServer, $smtpUsername, $smtpPassword, $from, $to);
             } else {
                 if (CString::equalsCi($transport, "system")) {
                     $mail = CMail::makeSystem($from, $to);
                 } else {
                     assert('false', vs(isset($this), get_defined_vars()));
                 }
             }
             CShell::setMailing($mail);
         }
         $thirdPartyDp = $GLOBALS["PHRED_PATH_TO_THIRD_PARTY"];
         $lastUpdateTimeFp = CFilePath::add($thirdPartyDp, self::$ms_thirdPartyLastUpdateTimeFn);
         // Read the file containing the Unix seconds of the last update time stamp (if exists) and compare that
         // time with the current time.
         $numDaysSinceLastUpdate;
         if (CFile::exists($lastUpdateTimeFp)) {
             $lastUpdateTime = new CTime(CString::toInt(CFile::read($lastUpdateTimeFp)));
             $currTime = CTime::now();
             if ($lastUpdateTime->isBefore($currTime)) {
                 $numDaysSinceLastUpdate = $currTime->diffInDays($lastUpdateTime);
                 if ($numDaysSinceLastUpdate < $minTimeBetweenDoUpdatesDays) {
                     // It is too early for updates yet.
                     return false;
                 }
             } else {
                 assert('false', vs(isset($this), get_defined_vars()));
             }
         }
         $date = CShell::currentDate();
         CShell::say("Started on {$date}.");
         if (isset($numDaysSinceLastUpdate)) {
             CShell::say("It has been {$numDaysSinceLastUpdate} day(s) since last successful update.");
         }
         $concurrLockFp = CFilePath::add($thirdPartyDp, self::$ms_thirdPartyConcurrLockFn);
         // Try locking the operation.
         if (!self::setLock($concurrLockFp, false)) {
             assert('false', vs(isset($this), get_defined_vars()));
             CShell::onError(false, "Could not obtain a lock on the operation.");
             CShell::writeToLog("\n");
             return false;
         }
         $phpConfigNeedsReload = false;
         $totalNumComponents = CMap::length($components);
         $numComponentsUpdated = 0;
         // The Browser Capabilities Project (BrowsCap).
         if (CMap::hasKey($components, "browsCap")) {
             $browsCap = $components["browsCap"];
             $skip = $browsCap["skip"];
             if (!$skip) {
                 CShell::say("Updating the Browser Capabilities Project (BrowsCap) ...");
                 $lookupFileUrl = $browsCap["lookupFileUrl"];
                 assert('!CString::isEmpty($lookupFileUrl)', vs(isset($this), get_defined_vars()));
                 // Component-related constants.
                 static $s_configOptName = "browscap";
                 static $s_lookupFileDownloadTimeoutSeconds = 120;
                 if (self::hasConfigOption($s_configOptName)) {
                     $browsCapLookupFp = CString::trim(self::configOption($s_configOptName));
                     if (!CString::isEmpty($browsCapLookupFp)) {
                         $browsCapDp = CFilePath::directory($browsCapLookupFp);
                         CShell::say("Downloading a BrowsCap lookup file from '{$lookupFileUrl}' ...");
                         $temporaryFp = CFile::createTemporary($browsCapDp);
                         $downloadRes = CInetRequest::downloadFile($lookupFileUrl, $temporaryFp, $s_lookupFileDownloadTimeoutSeconds);
                         if ($downloadRes) {
                             // After the file is downloaded into a temporary one, move it to the destination,
                             // safely replacing the existing file, if any.
                             CFile::move($temporaryFp, $browsCapLookupFp);
                             $numComponentsUpdated++;
                             $phpConfigNeedsReload = true;
                             $downloadedFileSizeKB = CUUnit::convertStoragef((double) CFile::size($browsCapLookupFp), CUUnit::BYTE, CUUnit::KILOBYTE);
                             $downloadedFileSizeKB = CMathf::round($downloadedFileSizeKB, 2);
                             CShell::say("Done. The downloaded file is {$downloadedFileSizeKB} KB in size.");
                         } else {
                             CShell::onError(false, "Could not download a BrowsCap lookup file from '{$lookupFileUrl}'.");
                         }
                         // Just in case, check for any temporary files that could have been left by any previous
                         // operations in the directory.
                         $leftoverFiles = CFile::findFiles(CFilePath::add($browsCapDp, CFile::DEFAULT_TEMPORARY_FILE_PREFIX . "*"));
                         if (!CArray::isEmpty($leftoverFiles)) {
                             // Cleanup the directory from the temporary files.
                             $len = CArray::length($leftoverFiles);
                             for ($i = 0; $i < $len; $i++) {
                                 CFile::delete($leftoverFiles[$i]);
                             }
                         }
                     } else {
                         CShell::onError(false, "Could not read the value of '{$s_configOptName}' option " . "in the PHP CLI configuration file.");
                     }
                 } else {
                     CShell::onError(false, "Could not find '{$s_configOptName}' option in the PHP CLI configuration file.");
                 }
             } else {
                 CShell::say("Skipping the Browser Capabilities Project (BrowsCap).");
             }
         }
         // All the components have been processed. Unlock the operation.
         self::unsetLock($concurrLockFp);
         $date = CShell::currentDate();
         if ($numComponentsUpdated != 0) {
             // One or more third-party components have been updated. Put a time stamp on the directory where the
             // components are located.
             CFile::write($lastUpdateTimeFp, CString::fromInt(CTime::currentUTime()));
             if ($numComponentsUpdated == $totalNumComponents) {
                 CShell::speak("Success. All {$totalNumComponents} third-party component(s)");
             } else {
                 CShell::speak("Partial success. {$numComponentsUpdated} out of {$totalNumComponents} third-party component(s)");
             }
             CShell::say("have been updated. Completed on {$date}.");
         } else {
             CShell::say("No third-party components have been updated. Completed on {$date}.");
         }
         return $phpConfigNeedsReload;
     } else {
         return false;
     }
 }
Example #3
0
 /**
  * For any request that needs to upload a file, specifies the data to be uploaded and, for HTTP requests, the
  * file's metadata.
  *
  * For large data, `setUploadFile` method would be preferred to upload an already existing file.
  *
  * @param  data $data The data to be uploaded.
  * @param  string $mimeType **OPTIONAL.** *Required for `HTTP_UPLOAD` requests only.* The MIME type of the file.
  * @param  string $fileName **OPTIONAL.** *Required for `HTTP_UPLOAD` requests only.* The custom name of the file.
  * @param  string $fileId **OPTIONAL.** *Required for `HTTP_UPLOAD` requests only.* The ID under which the file is
  * to arrive to the destination server.
  *
  * @return void
  *
  * @link   #method_setUploadFile setUploadFile
  */
 public function setUploadData($data, $mimeType = null, $fileName = null, $fileId = null)
 {
     assert('is_cstring($data) && (!isset($mimeType) || is_cstring($mimeType)) && ' . '(!isset($fileName) || is_cstring($fileName)) && (!isset($fileId) || is_cstring($fileId))', vs(isset($this), get_defined_vars()));
     $this->m_fileUploadTempFp = CFile::createTemporary();
     CFile::write($this->m_fileUploadTempFp, $data);
     $this->setUploadFile($this->m_fileUploadTempFp, $mimeType, $fileName, $fileId);
 }
Example #4
0
 public function testIsPosPastEnd()
 {
     $filePath = CFile::createTemporary();
     CFile::write($filePath, "Hello");
     $file = new CFile($filePath, CFile::READ);
     $file->readBytes(5);
     $this->assertFalse($file->isPosPastEnd());
     $file->done();
     // only needed in these tests
     CFile::write($filePath, "Hello");
     $file = new CFile($filePath, CFile::READ);
     $file->setPosToEnd();
     $this->assertFalse($file->isPosPastEnd());
     $file->done();
     // only needed in these tests
     CFile::write($filePath, "Hello");
     $file = new CFile($filePath, CFile::READ);
     $file->readBytes(5);
     $data = $file->readAvailableBytes(5);
     $this->assertTrue($file->isPosPastEnd() && $data->equals(""));
     $file->done();
     // only needed in these tests
     CFile::delete($filePath);
 }
Example #5
-1
 /**
  * Starts a session by sending out the added requests.
  *
  * @param  reference $success **OPTIONAL. OUTPUT.** After the method is called with this parameter provided, the
  * parameter's value tells whether the session was successful.
  *
  * @return void
  */
 public function start(&$success = null)
 {
     $success = true;
     if ($this->m_hasError) {
         $success = false;
         return;
     }
     if (CArray::isEmpty($this->m_requestRecordsQueue)) {
         // Nothing to do.
         return;
     }
     // Current policy is to disable HTTP pipelining.
     $res = curl_multi_setopt($this->m_multiCurl, CURLMOPT_PIPELINING, 0);
     if (!$res) {
         // Should never get in here as long as cURL options are being set correctly, hence the assertion.
         assert('false', vs(isset($this), get_defined_vars()));
         $this->m_hasError = true;
         $this->m_errorMessage = "The 'curl_multi_setopt' function failed.";
         $success = false;
         $this->finalize();
         return;
     }
     $anySuccessfulRequests = false;
     // Disable the script's execution timeout before getting into the session.
     $timeoutPause = new CTimeoutPause();
     $numRunningRequests = 0;
     // also the index of the next request to send
     while (true) {
         // From the request queue, add as many normal cURL handles to the multi cURL handle as it is allowed by the
         // maximum number of concurrent requests, priorly setting internal options for every request.
         while ($numRunningRequests < CArray::length($this->m_requestRecordsQueue) && $numRunningRequests < $this->m_maxNumConcurrentRequests) {
             $requestRecord = $this->m_requestRecordsQueue[$numRunningRequests];
             $request = $requestRecord[0];
             $onCompleteCallback = $requestRecord[1];
             $newCookieSession = $requestRecord[2];
             $requestCurl = $request->curl();
             // Set cURL options for the normal cURL handle, having created a temporary file for cookie storage if
             // needed.
             $requestSetOptSuccess;
             if ($this->m_cookiesAreEnabled && $request->isHttp()) {
                 if (!isset($this->m_cookiesFp)) {
                     $this->m_cookiesFp = CFile::createTemporary();
                 }
                 $request->setInternalOptions($requestSetOptSuccess, $this->m_cookiesFp, $newCookieSession);
             } else {
                 $request->setInternalOptions($requestSetOptSuccess);
             }
             if (!$requestSetOptSuccess) {
                 if (isset($onCompleteCallback)) {
                     call_user_func($onCompleteCallback, false, "", $request, $this);
                 }
                 CArray::remove($this->m_requestRecordsQueue, $numRunningRequests);
                 continue;
             }
             // Add the normal cURL handle to the multi cURL handle.
             $res = curl_multi_add_handle($this->m_multiCurl, $requestCurl);
             if ($res != 0) {
                 $this->m_hasError = true;
                 $curlError = curl_multi_strerror($res);
                 $this->m_errorMessage = is_cstring($curlError) && !CString::isEmpty($curlError) ? $curlError : "The 'curl_multi_add_handle' function failed.";
                 $success = false;
                 $timeoutPause->end();
                 $this->finalize();
                 return;
             }
             $numRunningRequests++;
         }
         if ($numRunningRequests == 0) {
             break;
         }
         // Process the currently added requests until complete or no more data is available. Although
         // `CURLM_CALL_MULTI_PERFORM` is deprecated since libcurl 7.20, keep it for compatibility reasons.
         $numRunningTransfers;
         do {
             $multiExecRes = curl_multi_exec($this->m_multiCurl, $numRunningTransfers);
         } while ($multiExecRes == CURLM_CALL_MULTI_PERFORM);
         if ($multiExecRes != CURLM_OK) {
             $this->m_hasError = true;
             $curlError = curl_multi_strerror($multiExecRes);
             $this->m_errorMessage = is_cstring($curlError) && !CString::isEmpty($curlError) ? $curlError : "The 'curl_multi_exec' function failed.";
             $success = false;
             $timeoutPause->end();
             $this->finalize();
             return;
         }
         // Check for completed requests, call the callback function for any completed one (if such a function is
         // defined), finalize completed requests, and remove completed requests from the queue.
         while (true) {
             $completedRequestInfo = curl_multi_info_read($this->m_multiCurl);
             if (!is_cmap($completedRequestInfo)) {
                 break;
             }
             // A request has completed.
             assert('$completedRequestInfo["msg"] == CURLMSG_DONE', vs(isset($this), get_defined_vars()));
             $requestCurl = $completedRequestInfo["handle"];
             $requestRes = $completedRequestInfo["result"];
             $requestRecordPos;
             $found = CArray::find($this->m_requestRecordsQueue, $requestCurl, function ($requestRecord, $requestCurl) {
                 $request = $requestRecord[0];
                 return $request->curl() == $requestCurl;
             }, $requestRecordPos);
             assert('$found', vs(isset($this), get_defined_vars()));
             $requestRecord = $this->m_requestRecordsQueue[$requestRecordPos];
             $request = $requestRecord[0];
             $onCompleteCallback = $requestRecord[1];
             // Remove the normal cURL handle from the multi cURL handle.
             $res = curl_multi_remove_handle($this->m_multiCurl, $requestCurl);
             if ($res != 0) {
                 $this->m_hasError = true;
                 $curlError = curl_multi_strerror($res);
                 $this->m_errorMessage = is_cstring($curlError) && !CString::isEmpty($curlError) ? $curlError : "The 'curl_multi_remove_handle' function failed.";
                 $success = false;
                 $timeoutPause->end();
                 $this->finalize();
                 return;
             }
             if ($requestRes == CURLE_OK) {
                 // The request has succeeded.
                 if (isset($onCompleteCallback)) {
                     $response;
                     if ($request->isReturnTransferSet()) {
                         $response = curl_multi_getcontent($requestCurl);
                         assert('is_cstring($response)', vs(isset($this), get_defined_vars()));
                     } else {
                         $response = "";
                     }
                     $request->onRequestCompleteOk();
                     // also close the normal cURL handle
                     call_user_func($onCompleteCallback, true, $response, $request, $this);
                 } else {
                     $request->onRequestCompleteOk();
                     // also close the normal cURL handle
                 }
                 $anySuccessfulRequests = true;
             } else {
                 // The request has failed.
                 $curlError = curl_strerror($requestRes);
                 if (!is_cstring($curlError)) {
                     $curlError = "";
                 }
                 $request->onRequestCompleteWithError($curlError);
                 // also close the normal cURL handle
                 if (isset($onCompleteCallback)) {
                     call_user_func($onCompleteCallback, false, "", $request, $this);
                 }
             }
             CArray::remove($this->m_requestRecordsQueue, $requestRecordPos);
             $numRunningRequests--;
         }
         assert('$numRunningRequests == $numRunningTransfers', vs(isset($this), get_defined_vars()));
         if ($numRunningTransfers > 0) {
             // Some requests are still being processed (by remote machines). Wait for more data to appear on
             // sockets, without getting hard on the CPU.
             do {
                 $multiSelectRes = curl_multi_select($this->m_multiCurl);
             } while ($multiSelectRes == -1);
         } else {
             // No requests are being processed. Check if any requests are pending.
             if (CArray::isEmpty($this->m_requestRecordsQueue)) {
                 // No requests are pending.
                 break;
             }
         }
     }
     // Set the script's execution time limit like the session has never happened.
     $timeoutPause->end();
     if (!$anySuccessfulRequests) {
         $this->m_hasError = true;
         $this->m_errorMessage = "None of the session's requests succeeded.";
         $success = false;
     }
     $this->finalize();
 }