public function __construct($r = null, $t = null, $c = null) { $this->uri = $_SERVER['REQUEST_URI']; $this->path = parse_url($this->uri, PHP_URL_PATH); // set up basic delegation concepts (via params or htaccess) $this->container = presto_lib::_get('c', $c); $this->route = presto_lib::_get('r', $r); $this->type = presto_lib::_c(presto_lib::_get('t', $t), 'json'); $params = $this->params(); if (!array_key_exists('r', $_GET) || !array_key_exists('t', $_GET) || !array_key_exists('c', $_GET)) { presto_lib::_trace("Rewrite delegation setup for {$this->uri} is missing.", json_encode($_GET)); } unset($_GET['t']); unset($_GET['r']); unset($_GET['c']); // pop routing parameters // setup request parameters $this->method = strtolower($_SERVER['REQUEST_METHOD']); $this->action = presto_lib::_c($this->method, 'get'); // default to GET $this->host = $_SERVER['HTTP_HOST']; $this->referer = _server('HTTP_REFERER', ''); $this->refererPath = parse_url($this->referer, PHP_URL_PATH); $this->service = strstr($this->host, '.', -1); $this->tld = pathinfo($this->host, PATHINFO_EXTENSION); $this->scheme = _server_has('HTTPS', 'on') || _server_has('HTTP_X_FORWARDED_PROTO', 'https') || _server_has('HTTP_X_FORWARDED_SSL', 'on') ? 'https' : 'http'; $this->options = $_GET; $_GET = array(); // discourage use of $_GET }
public static function restart($key, $extra = null) { if (empty(self::$processes[$key])) { presto_lib::_trace(__METHOD__, "Failed to restart [{$key}]: it isn't being tracked."); return; } if (isset($extra) && !is_array($extra)) { presto_lib::_trace(__METHOD__, "Failed to restart [{$key}]: optional extra data must be an array."); return; } $p =& self::$processes[$key]; if ($p->state === 'stopped') { // toggle on $p->last_started = microtime(true) * 1000000; $p->state = 'running'; } if (is_array($extra)) { $p['extra'] = array_merge($p['extra'], $extra); } }
private function dispatch() { try { $this->call = self::$req->scheme(); $action = self::$req->action; // the request action (method) $obj = $this->call->class; $method = $this->call->method; $preflight = $this->call->preflight; $type = self::$req->type; $model = null; $res = $this->call->resource; // the root resource presto_lib::_trace('REQUEST', "[{$this->call->file}] {$obj}::{$method} ({$this->call->type})", json_encode($this->call->params), json_encode($this->call->options)); // Create an an instance of the API subclass (autoloaded) autoload_delegate($this->call); if (!class_exists($obj)) { throw new Exception("API class not found for {$obj}::{$method}", 404); } // Start the response setup self::$resp = new response($this->call); API::attach($this->call, self::$resp, self::$req); $o = new $obj(); // Verify the request if ($obj == 'error') { // disallow root component access throw new Exception('Root access not allowed', 403); } if (!method_exists($obj, $preflight)) { if (method_exists($obj, 'autoload_model')) { // try a default model autoloader "preflight" $model = $o->autoload_model($this->call->params, $this->call->options, self::$req->body(), $this->call->type); } else { // skip + trace missing preflight functions (data will be passed as standard HTTP params) presto_lib::_trace('PREFLIGHT', 'skipped', "[{$this->call->file}] {$obj}::{$preflight} ({$this->call->type})", json_encode($this->call->params), json_encode($this->call->options)); } } else { // attempt a custom "preflight" model autoload call $model = $o->{$preflight}($this->call->params, $this->call->options, self::$req->body(), $this->call->type); } if (!method_exists($obj, $method)) { // valid route? throw new Exception("Resource {$obj}->{$method} not found.", 404); } $this->call->exists = true; // Perform the actual sub delegation if (isset($model)) { $this->call->data = $o->{$method}($model, $this->call->type); } else { $this->call->data = $o->{$method}($this->call->params, $this->call->options, self::$req->body(), $this->call->type); } // Produce a response for the client presto_lib::_trace(PRESTO_TRACE_KEY, json_encode(Presto::trace_info())); $profiles = Profiler::profiles(); // add any process profiling to trace if (!empty($profiles)) { presto_lib::_trace(PROFILER_TRACE_KEY, json_encode($profiles)); } $encode = is_object($this->call->data) || is_array($this->call->data); return self::$resp->ok($this->call, $encode, $o->status(), $o->headers()); } catch (Exception $e) { if (self::$resp === null) { self::$resp = new response(); } self::$resp->hdr($e->getCode()); throw $e; } }
private function request() { // NOTE - this function needs to be refactored - DRY $c = curl_init(); $this->call->headers = $this->options->headers; $this->call->info = null; // set up options specific to each HTTP method switch ($this->call->method) { case 'get': // add URI parameters if any were passed to the call $params = $this->call->params; if (!empty($params)) { $params = http_build_query($params); $this->call->uri .= '?' . $params; } break; case 'put': case 'post': $opt = CURLOPT_POST; $val = 1; // custom request for PUT ensures POSTFIELDS as we are not PUTting a file if ($this->call->method === 'put') { $opt = CURLOPT_CUSTOMREQUEST; $val = 'PUT'; } curl_setopt($c, $opt, $val); if ($this->call->body) { $body = json_encode($this->call->body); curl_setopt($c, CURLOPT_POSTFIELDS, $body); $params = $this->call->params; if (!empty($params)) { $params = http_build_query($params); $this->call->uri .= '?' . $params; } } else { curl_setopt($c, CURLOPT_POSTFIELDS, $this->params()); } $this->call->headers[] = $this->contentType(); break; case 'options': curl_setopt($c, CURLOPT_POST, 1); curl_setopt($c, CURLOPT_POSTFIELDS, $this->params()); $this->call->headers[] = $this->contentType(); curl_setopt($c, CURLOPT_CUSTOMREQUEST, strtoupper($this->call->method)); break; case 'head': case 'delete': $params = $this->call->params; if (!empty($params)) { $params = http_build_query($params); $this->call->uri .= '?' . $params; } curl_setopt($c, CURLOPT_CUSTOMREQUEST, strtoupper($this->call->method)); break; default: throw new Exception('Unsupported HTTP method ' + $this->call->method); } // set other HTTP otions $options = array(CURLOPT_URL => $this->call->uri, CURLOPT_RETURNTRANSFER => 1, CURLOPT_TIMEOUT => 100, CURLOPT_FOLLOWLOCATION => 1, CURLOPT_VERBOSE => $this->options->debug == 1, CURLOPT_COOKIE => $this->call->cookie, CURLOPT_COOKIESESSION => 1, CURLOPT_HTTPHEADER => $this->call->headers, CURLOPT_REFERER => $this->options->referrer, CURLOPT_USERAGENT => $this->options->agent, CURLOPT_HEADERFUNCTION => array($this, 'header')); curl_setopt_array($c, $options); presto_lib::_trace('Service request', "{$this->call->method}: {$this->call->uri}"); presto_lib::_trace('Service request body', json_encode($this->call->body)); $this->result->body = curl_exec($c); $this->result->uri = $this->call->uri; $this->call->info = (object) curl_getinfo($c); presto_lib::_trace('Service response body', $this->result->body); $this->parseResults(); if ($this->result->error = curl_error($c)) { throw new Exception("{$this->call->info->http_code} - {$this->result->error} - " . json_encode(array('options' => $options, 'call' => $this->call))); } curl_close($c); if ($this->result->data === false) { throw new Exception("{$this->call->info->http_code}: service error, no data - {$this->call->method} {$this->call->uri}", $this->call->info->http_code); } // TODO - handle 300-class returns? if ($this->call->info->http_code >= 400) { $dump = $this->options->debug ? json_encode($this->result) : json_encode($this->result->data); throw new Exception("{$this->call->info->http_code} - service error in '{$this->call->method}' for '{$this->call->uri}' - {$dump}", $this->call->info->http_code); } return $this->data(); }