Exemple #1
0
 public function resolve(Request $request, Response $response)
 {
     global $argv;
     // Debug access log
     if (System::environment() == 'debug') {
         switch ($request->client('type')) {
             case 'cli':
                 $message = implode(' ', array($request->client('type'), $request->uri()));
                 break;
             default:
                 $message = implode(' ', array($request->client('version'), strtoupper($request->method()), $request->uri('path')));
                 @Log::debug($message, array_filter(array('origin' => $request->client('referer'), 'userAgent' => util::cascade(@$request->client('userAgent'), 'Unknown'), 'timeElapsed' => round(microtime(1) - $request->timestamp(), 4) . ' secs')));
                 break;
         }
     }
 }
Exemple #2
0
<?php

/*! HeadlessWorker.php | Takes care of headless process ahead. */
require_once '.private/scripts/Initialize.php';
use core\Database;
use core\Log;
use framework\Bayeux;
use framework\Configuration as conf;
use framework\Service;
use models\WorkInstance;
use models\TaskInstance;
$taskInstance = new TaskInstance();
// Consumes Headless tasks ahead.
$tasks = Database::fetchArray('SELECT `nextTask` FROM `WorkInstance`
  WHERE `nextTask` IN (SELECT `uuid` FROM `TaskInstance` WHERE `type` = \'Headless\')
    AND `state` = \'Open\';');
$tasks = array_map(compose('core\\Utility::unpackUuid', prop('nextTask')), $tasks);
if ($tasks) {
    Log::debug(sprintf('%d headless tasks found!', count($tasks)), $tasks);
}
$serviceOptions = array('resolver' => new framework\Resolver());
$serviceOptions['resolver']->registerResolver(new resolvers\WebServiceResolver(array('prefix' => conf::get('web::resolvers.service.prefix', '/service'))));
foreach ($tasks as $taskUuid) {
    // renew response object for each call
    $serviceOptions['response'] = new framework\Response(array('autoOutput' => false));
    Service::call('_/WorkInstance', 'process', array($taskUuid), $serviceOptions);
    // todo: send bayeux update message to notify related users about the task update.
}
Exemple #3
0
 /**
  * Send HTTP request to a URL.
  *
  * The format is purposedly copied as much as possible from jQuery.ajax() function.
  *
  * To initiate multiple requests, pass it as an array and wrapping parameters of
  * each single request as an array.
  *
  * @param {string} $options['url'] Target request url
  * @param {?string} $options['type'] Request method, defaults to GET.
  * @param {?array|string} $options['data'] Either raw string or array to be encoded,
  *                                         to be sent as query string on GET, HEAD, DELETE and OPTION
  *                                         or message body on POST or PUT.
  * @param {?array} $options['headers'] Request headers to be sent.
  * @param {?callable} $options['progress'] Callback function for progress ticks.
  *                                         function($progress, $current, $maximum);
  * @param {?callable} $options['success'] Callback function on successful request.
  *                                        function($responseText, $curlOptions);
  * @param {?callable} $options['failure'] Callback function on request failure, with curl errors as parameters.
  *                                        function($errorNumber, $errorMessage, $curlOptions);
  * @param {?array} $options['__curlOpts'] Curl options to be passed directly to curl_setopt_array.
  *
  * @return void
  */
 public static function httpRequest($options)
 {
     $options = Utility::wrapAssoc((array) $options);
     $options = array_map(function (&$option) {
         if (is_string($option)) {
             $option = array('url' => $option);
         } else {
             if (!@$option['url']) {
                 throw new exceptions\CoreException('No URL set!');
             }
         }
         // Auto prepend http, default protocol.
         if (preg_match('/^(\\/\\/)/', $option['url'])) {
             $option['url'] = "http:" . $option['url'];
         }
         $curlOption = array(CURLOPT_URL => $option['url'], CURLOPT_RETURNTRANSFER => true, CURLOPT_SSL_VERIFYHOST => false, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_CAINFO => null, CURLOPT_CAPATH => null, CURLOPT_FOLLOWLOCATION => true);
         // Request method: 'GET', 'POST', 'PUT', 'HEAD', 'DELETE'
         if (!isset($option['type']) && is_array(@$option['data']) || preg_match('/^post$/i', @$option['type'])) {
             $curlOption[CURLOPT_POST] = true;
             $curlOption[CURLOPT_CUSTOMREQUEST] = 'POST';
         } elseif (preg_match('/^put$/i', @$option['type'])) {
             if (!@$option['file'] || !is_file($option['file'])) {
                 throw new exceptions\CoreException('Please specify the \'file\' option when using PUT method.');
             }
             $curlOption[CURLOPT_PUT] = true;
             $curlOption[CURLOPT_CUSTOMREQUEST] = 'PUT';
             $curlOption[CURLOPT_UPLOAD] = true;
             $curlOption[CURLOPT_INFILE] = fopen($option['file'], 'r');
             $curlOption[CURLOPT_INFILESIZE] = filesize($option['file']);
         } elseif (preg_match('/^head$/i', @$option['type'])) {
             $curlOption[CURLOPT_NOBODY] = true;
             $curlOption[CURLOPT_CUSTOMREQUEST] = 'HEAD';
         } elseif (preg_match('/^delete$/i', @$option['type'])) {
             $curlOption[CURLOPT_CUSTOMREQUEST] = 'DELETE';
         } else {
             $curlOption[CURLOPT_CUSTOMREQUEST] = 'GET';
         }
         // Query data, applicable for all request methods.
         if (@$option['data']) {
             $data = $option['data'];
             // The data contains traditional file POST value: "@/foo/bar"
             $hasPostFile = is_array($data) && array_reduce($data, function ($ret, $val) {
                 return $ret || is_a($val, 'CurlFile') || is_string($val) && strpos($val, '@') === 0 && file_exists(Utility::unwrapAssoc(explode(';', substr($val, 1))));
             }, false);
             // Build query regardless if file exists on PHP < 5.2.0, otherwise
             // only build when there is NOT files to be POSTed.
             // Skip the whole build if $data is not array or object.
             if ((version_compare(PHP_VERSION, '5.2.0', '<') || !$hasPostFile) && (is_array($data) || is_object($data))) {
                 $data = http_build_query($data);
             }
             if (version_compare(PHP_VERSION, '5.5.0', '>=') && $hasPostFile) {
                 array_walk_recursive($data, function (&$value, $key) {
                     if (is_string($value) && strpos($value, '@') === 0) {
                         @(list($path, $type) = explode(';', substr($value, 1)));
                         if (!$type) {
                             $type = Utility::getInfo($path, FILEINFO_MIME_TYPE);
                         }
                         $value = curl_file_create($path, $type, $key);
                     }
                 });
             }
             if (@$curlOption[CURLOPT_POST] === true) {
                 $curlOption[CURLOPT_POSTFIELDS] = $data;
             } else {
                 $url =& $curlOption[CURLOPT_URL];
                 $url .= (strpos($url, '?') === false ? '?' : '&') . $data;
             }
         }
         // HTTP Headers
         if (isset($option['headers'])) {
             $curlOption[CURLOPT_HTTPHEADER] =& $option['headers'];
         }
         // Data type converting
         if (isset($option['success'])) {
             $originalSuccess = @$option['success'];
             switch (@$option['dataType']) {
                 case 'json':
                     $option['success'] = function ($response, $curlOptions) use($option, $originalSuccess) {
                         $result = @ContentEncoder::json($response);
                         if ($result === false && $response) {
                             Utility::forceInvoke(@$option['failure'], array(3, 'Malformed JSON string returned.', $curlOptions));
                         } else {
                             Utility::forceInvoke(@$originalSuccess, array($result, $curlOptions));
                         }
                     };
                     break;
                 case 'xml':
                     $option['success'] = function ($response, $curlOptions) use($option, $originalSuccess) {
                         try {
                             $result = XMLConverter::fromXML($response);
                         } catch (\Exception $e) {
                             $result = NULL;
                         }
                         if ($result === NULL && $response) {
                             Utility::forceInvoke(@$option['failure'], array(2, 'Malformed XML string returned.', $curlOptions));
                         } else {
                             Utility::forceInvoke(@$originalSuccess, array($result, $curlOptions));
                         }
                     };
                     break;
             }
             unset($originalSuccess);
         }
         $curlOption['callbacks'] = array_filter(array('progress' => @$option['progress'], 'success' => @$option['success'], 'failure' => @$option['failure'], 'complete' => @$option['complete']));
         $curlOption = (array) @$option['__curlOpts'] + $curlOption;
         if (System::environment() == 'debug') {
             Log::debug('Net ' . $curlOption[CURLOPT_CUSTOMREQUEST] . ' to ' . $curlOption[CURLOPT_URL], $curlOption);
         }
         return $curlOption;
     }, $options);
     return self::curlRequest($options);
 }
Exemple #4
0
// Log the process output if available
$stdout = stream_get_contents($pipes[1]);
$stderr = stream_get_contents($pipes[2]);
if ("{$stdout}{$stderr}") {
    $method = $stderr ? 'error' : 'info';
    Log::$method(sprintf('Output captured from command line: %s', $process['command']), array_filter(array('stdout' => $stdout, 'stderr' => $stderr)));
    unset($method);
}
unset($stdout, $stderr);
// Handles cleanup after process exit
switch (strtolower($process['type'])) {
    // Permanent processes will be restarted upon death
    case 'permanent':
        core\Database::query('UPDATE `' . FRAMEWORK_COLLECTION_PROCESS . '` SET `pid` = NULL WHERE `id` = ?', $process['id']);
        Log::debug('Permanent process died, clearing pid.', [$res, $process]);
        break;
        // Sets pid to 0, prevents it fire again and double enqueue of the same time slot.
    // Sets pid to 0, prevents it fire again and double enqueue of the same time slot.
    case 'cron':
        core\Database::query('UPDATE `' . FRAMEWORK_COLLECTION_PROCESS . '` SET `pid` = 0 WHERE `id` = ?', $process['id']);
        break;
        // Deletes the process object upon exit
    // Deletes the process object upon exit
    default:
        $process = array_select($process, array(Node::FIELD_COLLECTION, 'id', 'pid'));
        $res = Node::delete($process);
        Log::debug("Deleting finished process, affected rows: {$res}.", [$res, $process]);
        break;
}
// Recursive process, spawn another worker.
Process::spawnWorker(@$_SERVER['env']);
Exemple #5
0
 /**
  * Login function, application commencement point.
  *
  * @param $username Username of the user.
  * @param $password SHA1 hash of the password.
  * @param $fingerprint Fingerprint extracted from current request, identifies
  *                     a requesting host as uniquely as possible.
  *
  * @return Possible return values are:
  *         1. Session identifier string on success,
  *         2. Empty string on session exists without override, or
  *         3. false on login mismatch.
  */
 static function validate($username, $password, $fingerprint = null)
 {
     // Search by username
     $user = (new User())->load($username);
     if (!$user->identity()) {
         return static::ERR_MISMATCH;
     }
     // Password crypt matching
     if (crypt($password, $user->password) !== $user->password) {
         return static::ERR_MISMATCH;
     }
     // Can login, generate sid and stores to PHP session.
     $session = array(Node::FIELD_COLLECTION => FRAMEWORK_COLLECTION_SESSION, 'sid' => Database::fetchField("SELECT UNHEX(REPLACE(UUID(), '-', ''))"), 'username' => $user->username);
     if (trim($fingerprint)) {
         $session['fingerprint'] = trim($fingerprint);
     }
     // Store session into database
     Node::set($session);
     // Reference to current session
     static::$currentSession = $session;
     // Log the sign in action.
     Log::debug('Session validated', $session);
     return util::unpackUuid($session['sid']);
 }