Example #1
0
 /**
  * compile root part of smd schema overwriting parent json compile method
  *
  * @error 14902
  * @param XO $obj expects reference variable of schema object
  * @return void
  */
 protected function compileRoot(&$obj)
 {
     $obj->SMDVersion = xapp_get_option(self::VERSION, $this);
     if (xapp_is_option(self::DESCRIPTION, $this)) {
         $obj->description = xapp_get_option(self::DESCRIPTION, $this);
     }
     if (xapp_is_option(self::CONTENT_TYPE, $this)) {
         $obj->contentType = xapp_get_option(self::CONTENT_TYPE, $this);
     }
     $obj->transport = xapp_get_option(self::TRANSPORT, $this);
     $obj->envelope = xapp_get_option(self::ENVELOPE, $this);
     if (xapp_is_option(self::CALLBACK, $this)) {
         $obj->jsonpCallbackParameter = xapp_get_option(self::CALLBACK, $this);
     }
     if (xapp_is_option(self::TARGET, $this)) {
         $obj->target = xapp_get_option(self::TARGET, $this);
     } else {
         $obj->target = $this->getTarget();
     }
 }
Example #2
0
 /**
  * executing requested service if found passing result from service invoking to response
  * or pass compile smd map to response if no service was called. if a callback was supplied
  * will wrap result into callback function
  *
  * @error 14706
  * @return void
  */
 protected function execute($call)
 {
     $get = $this->request()->getGet();
     $response = $this->response();
     try {
         $result = $this->invoke($call, $call[3]);
         $this->response()->skipHeader();
         if (array_key_exists(xapp_get_option(self::CALLBACK, $this), $get)) {
         } else {
             $result = $response->encode($result);
         }
         $response->body($result);
     } catch (Exception $e) {
         if (xapp_is_option(self::EXCEPTION_CALLBACK, $this)) {
             $e = call_user_func_array(xapp_get_option(self::EXCEPTION_CALLBACK, $this), array(&$e, $this, $call));
             if (!$e instanceof Exception) {
                 if (xapp_get_option(self::COMPLY_TO_JSONRPC_1_2, $this)) {
                     if (array_key_exists($e->getCode(), $this->codeMap)) {
                         xapp_set_option(Xapp_Rpc_Response::STATUS_CODE, $this->codeMap[$e->getCode()], $response);
                     } else {
                         xapp_set_option(Xapp_Rpc_Response::STATUS_CODE, 500, $response);
                     }
                 }
                 if (xapp_is_option(self::ERROR_CALLBACK, $this) && array_key_exists(xapp_get_option(self::ERROR_CALLBACK, $this), $get)) {
                     $e = $get[xapp_get_option(self::ERROR_CALLBACK, $this)] . '(' . $response->encode($e) . ')';
                 } else {
                     if (array_key_exists(xapp_get_option(self::CALLBACK, $this), $get)) {
                         $e = $get[xapp_get_option(self::CALLBACK, $this)] . '(' . $response->encode($e) . ')';
                     } else {
                         $e = $response->encode($e);
                     }
                 }
                 $response->body($e);
             }
         }
     }
 }
Example #3
0
 /**
  * IPugin interface impl.
  *
  * setup() must be called before load
  *
  * @error 15404
  * @return integer Returns error code due to the initialization.
  */
 function setup()
 {
     //extract service configuration
     $this->serviceConfig = xapp_get_option(self::SERVICE_CONF, $this);
     //logging
     if (xapp_is_option(self::LOGGING_CONF, $this) && $this->serviceConfig) {
         $logConfig = xapp_get_option(self::SERVICE_CONF);
         if ($logConfig && $logConfig[XC_CONF_LOGGER] != null) {
             $this->logger = $logConfig[XC_CONF_LOGGER];
         } else {
             //setup logger
         }
     }
     //cache
     if (xapp_is_option(self::CACHE_CONF, $this) && $this->serviceConfig) {
         $cacheConfig = xapp_get_option(self::CACHE_CONF);
         if ($cacheConfig) {
             $this->cache = Xapp_Cache::instance($this->CACHE_NS, "file", array(Xapp_Cache_Driver_File::PATH => xapp_get_option(XC_CONF_CACHE_PATH, $this->serviceConfig), Xapp_Cache_Driver_File::CACHE_EXTENSION => $this->CACHE_NS, Xapp_Cache_Driver_File::DEFAULT_EXPIRATION => 200));
         }
     }
 }
Example #4
0
 /**
  * expects the directories passed via class constructor to be stored as autoloadable directories for preloading
  * see Xapp_Autoloader for explanations.
  *
  * @see Xapp_Autoloader
  * @error 10709
  * @param null|string|array $dirs expects a directory path or multiple as array
  * @return void
  * @throws Xapp_Error
  */
 protected function init($dirs = null)
 {
     $this->_dirs[self::hash(xapp_path(XAPP_PATH_XAPP))] = array(xapp_path(XAPP_PATH_XAPP), 'Xapp');
     if (xapp_is_option(self::DIRECTORIES, $this)) {
         $dirs = array_merge((array) $dirs, xapp_get_option(self::DIRECTORIES, $this));
     }
     if ($dirs !== null && (is_array($dirs) || is_string($dirs))) {
         if (is_string($dirs)) {
             $dirs = array(array($dirs));
         } else {
             $dirs = (array) $dirs;
             foreach ($dirs as &$dir) {
                 if (!is_array($dir)) {
                     $dir = array($dir);
                 }
             }
         }
         unset($dir);
         foreach ($dirs as $key => $dir) {
             $tmp = null;
             $dir = (array) $dir;
             $hash = self::hash($dir[0]);
             if (array_key_exists(1, $dir)) {
                 $ns = array_slice($dir, 1);
             } else {
                 if (!is_int($key) && is_string($key)) {
                     $ns = array($key);
                 } else {
                     $ns = array();
                 }
             }
             if (is_dir($dir[0])) {
                 if (!array_key_exists($hash, $this->_dirs)) {
                     $this->_dirs[$hash] = array_merge(array(rtrim($dir[0], DS) . DS), $ns);
                     continue;
                 }
             } else {
                 if (stripos($dir[0], xapp_path(XAPP_PATH_ROOT)) === false) {
                     $tmp = (string) realpath(xapp_path(XAPP_PATH_ROOT) . $dir[0]);
                 }
                 if (!is_dir($tmp)) {
                     $tmp = null;
                 }
                 if ($tmp === null && stripos($dir[0], xapp_path(XAPP_PATH_BASE)) === false) {
                     $tmp = (string) realpath(xapp_path(XAPP_PATH_BASE) . $dir[0]);
                 }
                 if (!is_dir($tmp)) {
                     $tmp = null;
                 }
                 if ($tmp === null && stripos($dir[0], xapp_path(XAPP_PATH_XAPP)) === false) {
                     $tmp = (string) realpath(xapp_path(XAPP_PATH_XAPP) . $dir[0]);
                 }
                 if (!is_dir($tmp)) {
                     $tmp = null;
                 }
                 if ($tmp !== null) {
                     if (!array_key_exists($hash, $this->_dirs)) {
                         $this->_dirs[$hash] = array_merge(array(rtrim($tmp, DS) . DS), $ns);
                     }
                 } else {
                     throw new Xapp_Error(xapp_sprintf(_("relative dir: %s is not a valid dir"), $dir[0]), 1070901);
                 }
             }
         }
     }
     if (xapp_is_option(self::INCLUDE_PATHS, $this)) {
         $paths = explode(PATH_SEPARATOR, get_include_path());
         foreach ($paths as $path) {
             if (strpos($path, DS) !== false && is_readable($path)) {
                 $this->_dirs[self::hash($path)] = (array) $path;
             }
         }
     }
 }
Example #5
0
 /**
  * init instance by checking for memcached extension and validating server options
  *
  * @error 15801
  * @return void
  * @throws Xapp_Cache_Driver_Exception
  */
 protected function init()
 {
     if (!extension_loaded('memcached')) {
         throw new Xapp_Cache_Driver_Exception(_("memcached is not supported by this system"), 1580101);
     }
     if (xapp_is_option(self::COMPRESS, $this)) {
         xapp_set_option(self::OPTIONS, array(Memcached::OPT_COMPRESSION => xapp_get_option(self::COMPRESS, $this)), $this);
     }
     if (xapp_is_option(self::CONNECTION_TIMEOUT, $this)) {
         xapp_set_option(self::OPTIONS, array(Memcached::OPT_CONNECT_TIMEOUT => xapp_get_option(self::CONNECTION_TIMEOUT, $this)), $this);
     }
     if (xapp_is_option(self::INSTANCE, $this)) {
         $this->_memcached = xapp_get_option(self::INSTANCE, $this);
     } else {
         if (xapp_is_option(self::PERSISTENT_ID, $this)) {
             $this->_memcached = new Memcached(xapp_get_option(self::PERSISTENT_ID, $this));
         } else {
             $this->_memcached = new Memcached();
         }
         if (xapp_is_option(self::OPTIONS, $this)) {
             foreach (xapp_get_option(self::OPTIONS, $this) as $k => $v) {
                 if (!$this->_memcached->setOption((int) $k, $v)) {
                     throw new Xapp_Cache_Driver_Exception(xapp_sprintf(_("unable to set memcached option: %s"), $k), 1580102);
                 }
             }
         }
         $server = xapp_get_option(self::SERVER, $this);
         if (is_object($server)) {
             xapp_set_option(self::SERVER, array($server), $this, true);
         } else {
             if (is_array($server) && !array_key_exists(0, $server)) {
                 xapp_set_option(self::SERVER, array($server), $this, true);
             }
         }
         foreach ((array) xapp_get_option(self::SERVER, $this) as $server) {
             $server = (array) $server;
             if (!array_key_exists('host', $server)) {
                 throw new Xapp_Cache_Driver_Exception(_("memcached parameter: host must be set"), 1580103);
             }
             if (!array_key_exists('port', $server)) {
                 throw new Xapp_Cache_Driver_Exception(_("memcached parameter: port must be set"), 1580104);
             }
             if (!$this->_memcached->addServer($server['host'], (int) $server['port'], array_key_exists('weight', $server) ? (int) $server['weight'] : 0)) {
                 throw new Xapp_Cache_Driver_Exception(xapp_sprintf(_("unable to add server for host: %s and port: %d"), array($server['host'], $server['port'])), 1580105);
             }
         }
     }
 }
Example #6
0
 /**
  * flush exception as json error object encapsulated in js callback or custom error callback function if supplied
  *
  * @error 14708
  * @param Exception $error expects the exception to flush
  */
 public function error(Exception $error)
 {
     $get = $this->request()->getGet();
     $response = $this->response();
     if (xapp_get_option(self::COMPLY_TO_JSONRPC_1_2, $this)) {
         if (array_key_exists($error->getCode(), $this->codeMap)) {
             xapp_set_option(Xapp_Rpc_Response::STATUS_CODE, $this->codeMap[$error->getCode()], $response);
         } else {
             xapp_set_option(Xapp_Rpc_Response::STATUS_CODE, 500, $response);
         }
     }
     $error = $this->compileError($error);
     if (xapp_is_option(self::ERROR_CALLBACK, $this) && array_key_exists(xapp_get_option(self::ERROR_CALLBACK, $this), $get)) {
         $error = $get[xapp_get_option(self::ERROR_CALLBACK, $this)] . '(' . $response->encode($error) . ')';
     } else {
         if (array_key_exists(xapp_get_option(self::CALLBACK, $this), $get)) {
             $error = $get[xapp_get_option(self::CALLBACK, $this)] . '(' . $response->encode($error) . ')';
         } else {
             $error = $response->encode($error);
         }
     }
     $response->body($error);
     $this->flush();
 }
Example #7
0
 /**
  * compile a valid profile entry expecting a entry name id and a valid time value
  *
  * @error 15205
  * @param string $name expects a valid entry name id
  * @param float $time expects a valid microsecond value
  * @param array $args expects optional data to include in entry compiling
  * @return array
  */
 protected function compile($name, $time, array $args = array())
 {
     if (!array_key_exists($name, $this->_data)) {
         $this->_data[$name] = array();
     }
     if (!function_exists('_xapp_compile')) {
         function _xapp_compile($args, $sep = ', ')
         {
             foreach ($args as $k => &$v) {
                 if (is_array($v)) {
                     $v = implode((string) $sep, $v);
                 }
             }
             return $args;
         }
     }
     $args = _xapp_compile($args, xapp_get_option(self::STRING_SEPARATOR, $this));
     $log = array($name, number_format((double) $time * xapp_get_option(self::TIME_FACTOR, $this), 2, '.', ''));
     $log = array_merge($log, $args);
     if (xapp_is_option(self::PROFILE_MEMORY, $this)) {
         $log = array_merge($log, array(self::byteConv(memory_get_usage(true)), self::byteConv(memory_get_peak_usage(true))));
     }
     return $this->_data[$name][] = $log;
 }
Example #8
0
 /**
  * validates all options that have been defined throwing rpc gateway faults if any of the
  * options fail to validate. see constant descriptions for what each constant does
  *
  * @error 14015
  * @param string $option expects the option name
  * @param null|mixed $value expects the options value
  * @throws Xapp_Rpc_Gateway_Exception
  * @throws Xapp_Rpc_Fault
  */
 protected function validate($option, $value = null)
 {
     $user = null;
     $option = strtoupper($option);
     switch ($option) {
         case self::BASIC_AUTH:
             if ($this->request()->has('PHP_AUTH_USER', 'SERVER') && $this->request()->has('PHP_AUTH_PW', 'SERVER') && isset($value[0]) && isset($value[1])) {
                 if ($this->server()->request()->getFrom('PHP_AUTH_USER', 'SERVER') !== $value[0] || $this->server()->request()->getFrom('PHP_AUTH_PW', 'SERVER') !== $value[1]) {
                     Xapp_Rpc_Fault::t("basic auth error - user or password not correct", array(1401501, -32001));
                 }
             } else {
                 Xapp_Rpc_Fault::t("basic auth error - credentials not set", array(1401502, -32002));
             }
             break;
         case self::ALLOW_IP:
             if (Xapp_Rpc_Request::getClientIp() !== null && !in_array(Xapp_Rpc_Request::getClientIp(), $value)) {
                 Xapp_Rpc_Fault::t("request denied from service", array(1401503, -32003));
             }
             break;
         case self::DENY_IP:
             if (Xapp_Rpc_Request::getClientIp() !== null && in_array(Xapp_Rpc_Request::getClientIp(), $value)) {
                 Xapp_Rpc_Fault::t("request denied from service", array(1401503, -32003));
             }
             break;
         case self::DISABLE:
             if ((bool) $value) {
                 Xapp_Rpc_Fault::t("gateway is disabled", array(1401504, -32004));
             }
             break;
         case self::DISABLE_SERVICE:
             if ($this->server()->hasServices()) {
                 foreach ($this->server()->getServices() as $service) {
                     if (preg_match(Xapp_Rpc::regex($value), $service)) {
                         Xapp_Rpc_Fault::t("requested service: {$service} is disabled", array(1401505, -32005));
                     }
                 }
             }
             break;
         case self::ALLOW_HOST:
             if (Xapp_Rpc_Request::getHost() !== null && !in_array(Xapp_Rpc_Request::getHost(), $value)) {
                 Xapp_Rpc_Fault::t("host denied from service", array(1401506, -32006));
             }
             break;
         case self::DENY_HOST:
             if (Xapp_Rpc_Request::getHost() !== null && in_array(Xapp_Rpc_Request::getHost(), $value)) {
                 Xapp_Rpc_Fault::t("host denied from service", array(1401506, -32006));
             }
             break;
         case self::FORCE_HTTPS:
             if ((bool) $value && Xapp_Rpc_Request::getScheme() !== 'HTTPS') {
                 Xapp_Rpc_Fault::t("request from none http secure host denied", array(1401507, -32007));
             }
             break;
         case self::ALLOW_USER_AGENT:
             if ($this->request()->has('HTTP_USER_AGENT', 'SERVER') && !preg_match('/(' . implode('|', trim($value, '()')) . ')/i', $this->request()->getFrom('HTTP_USER_AGENT', 'SERVER'))) {
                 Xapp_Rpc_Fault::t("client denied from service", array(1401508, -32008));
             }
             break;
         case self::DENY_USER_AGENT:
             if ($this->request()->has('HTTP_USER_AGENT', 'SERVER') && preg_match('/(' . implode('|', trim($value, '()')) . ')/i', $this->request()->getFrom('HTTP_USER_AGENT', 'SERVER'))) {
                 Xapp_Rpc_Fault::t("client denied from service", array(1401508, -32008));
             }
             break;
         case self::ALLOW_REFERER:
             if (Xapp_Rpc_Request::getReferer() !== null && !preg_match('/(' . implode('|', trim($value, '()')) . ')/i', Xapp_Rpc_Request::getReferer())) {
                 Xapp_Rpc_Fault::t("referer denied from service", array(1401509, -32009));
             }
             break;
         case self::SIGNED_REQUEST:
             if ((bool) $value) {
                 $tmp = array();
                 if (xapp_is_option(self::SIGNED_REQUEST_EXCLUDES, $this)) {
                     foreach ($this->server()->getServices() as $service) {
                         if (!preg_match(Xapp_Rpc::regex(xapp_get_option(self::SIGNED_REQUEST_EXCLUDES, $this)), $service)) {
                             $tmp[] = $service;
                         }
                     }
                 }
                 if (sizeof($tmp) > 0) {
                     $sign = $this->request()->getParam(xapp_get_option(self::SIGNED_REQUEST_SIGN_PARAM, $this), false);
                     $method = strtolower(xapp_get_option(self::SIGNED_REQUEST_METHOD, $this));
                     switch ($method) {
                         case 'host':
                             $user = $this->request()->getHost();
                             break;
                         case 'ip':
                             $user = $this->request()->getClientIp();
                             break;
                         case 'user':
                             $user = $this->request()->getParam(xapp_get_option(self::SIGNED_REQUEST_USER_PARAM, $this), false);
                             break;
                         default:
                             throw new Xapp_Rpc_Gateway_Exception(_("unsupported signed request user identification method"), 1401514);
                     }
                     if ($user === false || $user === null) {
                         Xapp_Rpc_Fault::t(vsprintf("signed request value for: %s not found in request", array(xapp_get_option(self::SIGNED_REQUEST_USER_PARAM, $this))), array(1401512, -32011));
                     }
                     if ($sign === false || $sign === null) {
                         Xapp_Rpc_Fault::t(vsprintf("signed request value for: %s not found in request", array(xapp_get_option(self::SIGNED_REQUEST_SIGN_PARAM, $this))), array(1401513, -32011));
                     }
                     $key = $this->getKey($user, null);
                     $params = $this->request()->getParams();
                     if (array_key_exists('xdmTarget', $params)) {
                         unset($params['xdmTarget']);
                     }
                     if (array_key_exists('view', $params)) {
                         unset($params['view']);
                     }
                     if (array_key_exists('xfToken', $params)) {
                         unset($params['xfToken']);
                     }
                     if (array_key_exists('time', $params)) {
                         unset($params['time']);
                     }
                     if (array_key_exists('xdm_e', $params)) {
                         unset($params['xdm_e']);
                     }
                     if (array_key_exists('user', $params)) {
                         unset($params['user']);
                     }
                     if (array_key_exists('xdm_c', $params)) {
                         unset($params['xdm_c']);
                     }
                     if (array_key_exists('xdm_p', $params)) {
                         unset($params['xdm_p']);
                     }
                     if (xapp_is_option(self::SIGNED_REQUEST_CALLBACK, $this)) {
                         if (!(bool) call_user_func_array(xapp_get_option(self::SIGNED_REQUEST_CALLBACK, $this), array($this->request(), $params, $key))) {
                             Xapp_Rpc_Fault::t("verifying signed request failed", array(1401510, -32010));
                         }
                     } else {
                         if ($key !== null) {
                             if (isset($params[xapp_get_option(self::SIGNED_REQUEST_SIGN_PARAM, $this)])) {
                                 unset($params[xapp_get_option(self::SIGNED_REQUEST_SIGN_PARAM, $this)]);
                             }
                             if ($sign !== self::sign($params, $key)) {
                                 Xapp_Rpc_Fault::t("verifying signed request failed", array(1401510, -32010));
                             }
                         } else {
                             throw new Xapp_Rpc_Gateway_Exception(_("user identification key must be set when using internal signed request verification"), 1401511);
                         }
                     }
                 }
             }
             break;
         default:
     }
 }
Example #9
0
 /**
  * class destructor iterates through error stack an sorts all errors according to intended action
  * or target. since error have different severity level some errors need to be routed to specific
  * log writers only. therefore: the default implementation will route all errors to the designated
  * log writer. if the default log writers are overwritten than all errors are written to all registered
  * log writers at the same time - regardless of error log severity and mapped error action, e.g. only
  * mailing alert errors via email.
  *
  * @error 11605
  * @return void
  */
 public function __destruct()
 {
     $all = array();
     $mail = array();
     $file = array();
     $map = xapp_get_option(self::ACTION_MAP, $this);
     foreach ($this->stack as $k => $v) {
         if (!array_key_exists((int) $v->severity, $map)) {
             $v->severity = self::LOG;
         }
         if (array_key_exists((int) $v->severity, $map)) {
             $v->action = $map[(int) $v->severity];
         }
         if (isset($v->action) && !is_null($v->action)) {
             if (in_array($v->action, array(self::DUMP))) {
                 xapp_console($v->object, null, 'error');
             }
             if (in_array($v->action, array(self::LOG, self::LOG | self::MAIL))) {
                 $file[] = $v->message;
             }
             if (in_array($v->action, array(self::MAIL, self::LOG | self::MAIL))) {
                 $mail[] = $v->object;
             }
             $all[] = $v->object;
         }
     }
     if (xapp_is_option(self::WRITER, $this)) {
         $this->write($all);
     } else {
         if (sizeof($file) > 0) {
             $this->write($file, 'file');
         }
         if (sizeof($mail) > 0) {
             if (xapp_is_option(self::EMAIL, $this)) {
                 $this->write($mail, 'mail');
             }
         }
     }
 }
Example #10
0
 /**
  * compile service part of smd schema
  *
  * @error 14806
  * @param XO $obj expects reference variable of schema object
  * @return void
  */
 protected function compileService(&$obj)
 {
     $tmp = array();
     $separator = xapp_get_option(self::CLASS_METHOD_SEPARATOR, $this);
     if (xapp_is_option(self::SERVICE_OVER_GET, $this)) {
         foreach ($this->map() as $key => $val) {
             if (is_array($val)) {
                 foreach ($val as $k => $v) {
                     $v->transport = 'POST';
                     if (xapp_is_option(self::METHOD_TARGET, $this)) {
                         $v->target = $this->getTarget("{$key}.{$k}");
                     }
                     $tmp[$key . $separator . $k] = $v;
                 }
             } else {
                 $val->transport = 'POST';
                 if (xapp_is_option(self::METHOD_TARGET, $this)) {
                     $val->target = $this->getTarget($key);
                 }
                 $tmp[$key] = $val;
             }
         }
     } else {
         foreach ($this->map() as $key => $val) {
             if (is_array($val)) {
                 foreach ($val as $k => $v) {
                     $v->transport = 'POST';
                     $v->target = $this->getTarget();
                     $tmp[$key . $separator . $k] = $v;
                 }
             } else {
                 $val->transport = 'POST';
                 if (xapp_is_option(self::METHOD_TARGET, $this)) {
                     $val->target = $this->getTarget();
                 }
                 $tmp[$key] = $val;
             }
         }
     }
     $obj->services = $tmp;
 }
Example #11
0
 /**
  * setter/getter method to set or get headers. to get headers call method without any parameters
  * returning all registered header values as array. to set header either pass raw header to first
  * argument leaving second argument unset or pass header key => value pair as first and second
  * argument. the raw header must be passed as one string like "Pragma: public" otherwise pass
  * key to first argument "Pragma" and value "public" to second argument. you can also pass multiple
  * headers using the first two arguments passing an array of keys in first and array of values in
  * second argument. size of these arrays must match or will throw exception. pass replacement
  * value and header code in third and fourth parameter as if you would use phps internal header().
  * function will return always all registerd headers as array. when calling method without any arguments
  * will first time merge all header from class options to header array unsetting the class option
  *
  * @error 14505
  * @param null|string|array $mixed expects raw header string, header key as string or array of keys
  * @param null|mixed|array $value expects null for raw header, mixed for header value or array of values
  * @param null|bool $replace expects optional boolean value on whether to replace header
  * @param null|int $code expects optional response code
  * @return array
  * @throws Xapp_Rpc_Response_Exception
  */
 public function header($mixed = null, $value = null, $replace = null, $code = null)
 {
     if ($mixed !== null) {
         //raw header in first parameter
         if (is_string($mixed) && $value === null) {
             $mixed = explode(':', $mixed);
             if (sizeof($mixed) === 2) {
                 $mixed = array(array(trim($mixed[0]), trim($mixed[1])));
             } else {
                 throw new Xapp_Rpc_Response_Exception(_("response raw header passed is not valid"), 1450501);
             }
             //header with key => value pair in first and second parameter
         } else {
             if (is_string($mixed) && !is_array($value)) {
                 $mixed = array(array(trim($mixed), trim($value)));
                 //headers with key => value pairs as array in first and second parameter
             } else {
                 if (is_array($mixed) && is_array($value)) {
                     $mixed = array($mixed, $value);
                     //header not recognized
                 } else {
                     throw new Xapp_Rpc_Response_Exception(_("response header passed is not recognized"), 1450502);
                 }
             }
         }
         for ($i = 0; $i < sizeof($mixed); $i++) {
             if (isset($mixed[$i][0]) && isset($mixed[$i][1])) {
                 if (preg_match("/^content\\-type\\:\\s+([^\\s]+)\\s+charset\\=(.+)\$/i", $mixed[$i][0] . ': ' . $mixed[$i][1], $m)) {
                     xapp_set_option(self::CONTENT_TYPE, strtolower(trim($m[1], '; ')), $this);
                     xapp_set_option(self::CHARSET, strtolower(trim($m[2], '; ')), $this);
                 }
                 $obj = new XO();
                 $obj->name = $mixed[$i][0];
                 $obj->value = $mixed[$i][1];
                 $obj->replace = null;
                 $obj->code = null;
                 if ($replace !== null) {
                     $obj->replace = (bool) $replace;
                 }
                 if (isset($mixed[$i][2])) {
                     $obj->replace = (bool) $mixed[$i][2];
                 }
                 if ($code !== null) {
                     $obj->code = (int) $code;
                 }
                 if (isset($mixed[$i][3])) {
                     $obj->code = (int) $mixed[$i][3];
                 }
                 $this->_header[] = $obj;
             } else {
                 throw new Xapp_Rpc_Response_Exception(_("response header miss match when passing keys and values as arrays"), 1450503);
             }
         }
     } else {
         if (xapp_is_option(self::HEADER, $this)) {
             $header = xapp_get_option(self::HEADER, $this);
             if (!is_array($header[0])) {
                 $header = array($header);
             }
             xapp_unset_option(self::HEADER, $this);
             $this->header($header);
         }
     }
     return $this->_header;
 }
Example #12
0
 private function setup()
 {
     $this->serviceConfig = xapp_get_option(self::SERVICE_CONF, $this);
     //cache
     if (xapp_is_option(self::CACHE_CONF, $this) && $this->serviceConfig) {
         $cacheConfig = xapp_get_option(self::CACHE_CONF);
         if ($cacheConfig) {
             $this->cache = Xapp_Cache::instance("PluginManager", "file", array(Xapp_Cache_Driver_File::PATH => xapp_get_option(XC_CONF_CACHE_PATH, $this->serviceConfig), Xapp_Cache_Driver_File::CACHE_EXTENSION => "pmmanager", Xapp_Cache_Driver_File::DEFAULT_EXPIRATION => 200));
         }
     }
 }
Example #13
0
 /**
  * get the smd target path in absolute or relative mode for services or base url for smd
  * output if first parameter is not set. this function will return target in htaccess rewrite
  * style if the option REWRITE_URL is set. this option can be either boolean true let the smd
  * resolve the rewrite pattern automatically which is nothing but extending the base path of
  * the url to contain the service class and function parameter like: "/base/rpc/index.php"
  * becomes "/base/rpc/class.function" or "/base/rpc/function" because rewrite will remap this
  * rule to "/base/rpc/index.php?service=class.function". you can also pass a string with your
  * rewrite rule as "/base/rpc/foo/{$class}/{$function}" with {($|%)} $ or % placeholder values.
  * always make sure your htaccess rule reflects the rewrite rule and vice versa and that service
  * values are always rewritten to $_GET "service" parameter. the second parameter defines whether
  * to return the url as relative or absolute or if not set will look for global option RELATIVE_TARGETS
  *
  * @error 14113
  * @param null|string $service expects optional the service method/function and class in dot notation
  * @param null|bool $relative defined whether to return path absolute or relative
  * @return string
  * @throws Xapp_Rpc_Smd_Exception
  */
 protected function getTarget($service = null, $relative = null)
 {
     $class = null;
     $function = null;
     $separator = xapp_get_option(self::CLASS_METHOD_SEPARATOR, $this);
     $url = Xapp_Rpc_Request::url(null, -1);
     $host = rtrim($url['host'], '/ ');
     $path = trim($url['path'], '/ ');
     if (preg_match('/(\\.([^\\/]+|$))/i', $path, $m, PREG_OFFSET_CAPTURE)) {
         if (isset($m[1]) && is_array($m[1])) {
             $path = substr($path, 0, $m[1][1] + strlen($m[1][0]));
         }
     }
     if (xapp_is_option(self::REWRITE_URL, $this) && strpos($path, 'index.') !== false) {
         $path = substr($path, 0, strpos($path, 'index.'));
     }
     if ($service !== null) {
         if (strpos($service, $separator) !== false) {
             $class = substr($service, 0, strpos($service, $separator));
             $function = substr($service, strpos($service, $separator) + 1);
         } else {
             $class = null;
             $function = $service;
         }
     }
     if ($service !== null) {
         if (xapp_is_option(self::REWRITE_URL, $this)) {
             $_url = xapp_get_option(self::REWRITE_URL, $this);
             if (is_bool($_url) && $_url) {
                 $_url = rtrim($path, '/') . '/{$class}{$separator}{$function}';
             }
             $_url = trim($_url, '/ ');
             if (($_url = parse_url($_url)) !== false) {
                 $path = trim(preg_replace(array('/\\{(?:\\$|\\%)([^\\}]+)\\}/ie', '/\\/+/'), array("\$\$1", '/'), $_url['path']), '/ ');
             } else {
                 throw new Xapp_Rpc_Smd_Exception(xapp_sprintf(_("smd rewrite rule: %s is not a valid url or url path value"), $_url), 1411301);
             }
         } else {
             $path = $path . "?service={$service}";
         }
     }
     if ($relative === null) {
         $relative = xapp_get_option(self::RELATIVE_TARGETS, $this);
     }
     if ((bool) $relative) {
         return '/' . ltrim($path, '/ ');
     } else {
         return $url['scheme'] . '://' . $host . (isset($url['port']) && !empty($url['port']) ? ':' . $url['port'] : '') . '/' . $path;
     }
 }
Example #14
0
 /**
  * executing requested service/call by validating call and invoking requested class/method or function
  *
  * @error 14605
  * @param array $call expects the call to execute
  * @return void
  * @throws Exception
  */
 protected function execute($call)
 {
     $data = array();
     $version = $this->request()->getVersion($call[3], true);
     if (!is_null($version)) {
         $data[$version[0]] = $version[1];
     }
     try {
         $this->validate($call);
         $data['result'] = $this->invoke($call, array_key_exists('params', $call[3]) ? $call[3]['params'] : null);
         if (version_compare((string) xapp_get_option(self::VERSION), '2.0', '<')) {
             $data['error'] = null;
         }
     } catch (Exception $e) {
         if (xapp_get_option(self::COMPLY_TO_JSONRPC_1_2, $this)) {
             if (array_key_exists($e->getCode(), $this->codeMap)) {
                 xapp_set_option(Xapp_Rpc_Response::STATUS_CODE, $this->codeMap[$e->getCode()], $response);
             } else {
                 xapp_set_option(Xapp_Rpc_Response::STATUS_CODE, 500, $response);
             }
         }
         if (xapp_is_option(self::EXCEPTION_CALLBACK, $this)) {
             $e = call_user_func_array(xapp_get_option(self::EXCEPTION_CALLBACK, $this), array(&$e, $this, $call));
             if ($e instanceof Exception) {
                 $data['error'] = $this->compileError($e);
             } else {
                 $data['error'] = $e;
             }
         } else {
             if (sizeof($this->_calls) === 1) {
                 throw $e;
             } else {
                 $data['error'] = $this->compileError($e);
             }
         }
     }
     if (array_key_exists('id', $call[3])) {
         $data['id'] = $call[3]['id'];
     }
     $this->_data[] = $data;
     $data = null;
 }
Example #15
0
 /**
  * invoke class/method or function via rpc or outside rpc functionality for testing purposes. the first parameter
  * thus can be a valid callable when used outside of rpc service or the internal array containing all call parameters
  * from concrete rpc server implementation. throws exception with extended exception properties if in debug mode.
  * summarizes all caught applications exceptions when invoking callable to a general application error so sensitive
  * error messages can be omitted. when invoked with named parameters will reorder parameters to reflect
  * order of method/function call since call_user_func_array needs to pass parameter named or unnamed in
  * correct order
  *
  * @error 14211
  * @param array|callable $call expects either valid callable or array with all call parameters
  * @param array $params expects the parameters to pass to function/method to invoke
  * @return mixed
  * @throws Xapp_Rpc_Server_Exception
  * @throws Xapp_Rpc_Fault
  * @throws Exception
  */
 public function invoke($call, $params = null)
 {
     $key = null;
     $hash = null;
     $class = null;
     $return = null;
     $result = null;
     $callable = null;
     try {
         //invoke from outside of rpc service
         if (is_callable($call)) {
             $callable = $call;
             if (is_array($call)) {
                 $call = array(null, $call[1], is_object($call[0]) ? get_class($call[0]) : $call[0]);
                 $class = new ReflectionClass($call[2]);
             } else {
                 if (strpos((string) $call, '::') !== false) {
                     $call = array(null, substr($call, strpos($call, '::') + 2), substr($call, 0, strpos($call, '::')));
                     $class = new ReflectionClass($call[2]);
                 } else {
                     $call = array(null, $call, $call);
                     $class = null;
                 }
             }
         } else {
             if (is_array($call)) {
                 if ($call[2] !== null) {
                     if (xapp_get_option(self::NAMESPACE_IDENTIFIER, $this) === NAMESPACE_SEPARATOR) {
                         if (strpos($call[2], NAMESPACE_SEPARATOR) !== false) {
                             $call[2] = NAMESPACE_SEPARATOR . str_replace(array('\\', '/', '_', '.'), xapp_get_option(self::NAMESPACE_IDENTIFIER, $this), trim($call[2], ' ' . NAMESPACE_SEPARATOR));
                         } else {
                             $call[2] = str_replace(array('/', '_', '.'), xapp_get_option(self::NAMESPACE_IDENTIFIER, $this), trim($call[2]));
                         }
                     } else {
                         $call[2] = str_replace(array('\\', '/', '_', '.'), xapp_get_option(self::NAMESPACE_IDENTIFIER, $this), trim($call[2]));
                     }
                     $key = "{$call[2]}.{$call[1]}";
                     try {
                         if (array_key_exists(strtolower($call[2]), $this->_objects)) {
                             $class = new ReflectionClass($this->_objects[strtolower($call[2])]);
                         } else {
                             $class = new ReflectionClass($call[2]);
                         }
                         if ($class->hasMethod($call[1])) {
                             $method = $class->getMethod($call[1]);
                             if ($method->isPublic()) {
                                 if ($method->isStatic()) {
                                     $callable = array($class->getName(), $call[1]);
                                 } else {
                                     $callable = array(array_key_exists(strtolower($call[2]), $this->_objects) ? $this->_objects[strtolower($call[2])] : $class->newInstance(), $call[1]);
                                 }
                             } else {
                                 Xapp_Rpc_Fault::t("method: {$call[1]} of class: {$call[2]} is not public", array(1421105, -32601));
                             }
                         } else {
                             Xapp_Rpc_Fault::t("method: {$call[1]} of class: {$call[2]} does not exist", array(1421104, -32601));
                         }
                     } catch (ReflectionException $e) {
                         throw new Xapp_Rpc_Server_Exception(xapp_sprintf(_("unable to initialize class due to reflection error: %d, %s"), $e->getCode(), $e->getMessage()), 1421103);
                     }
                 } else {
                     $key = $call[1];
                     $callable = $call[1];
                 }
             } else {
                 throw new Xapp_Rpc_Server_Exception(_("invalid callable passed to invoke method"), 1421106);
             }
         }
         if (is_callable($callable)) {
             if (is_array($callable) && is_object($callable[0])) {
                 $this->_class = $callable[0];
             }
             if (!is_null($key) && !is_null($params) && array_values((array) $params) !== (array) $params) {
                 $tmp = array();
                 $arr = (array) $params;
                 $map = $this->smd()->get($key);
                 if (!is_null($map)) {
                     foreach ((array) $map->parameters as $p) {
                         if (array_key_exists($p->name, $arr)) {
                             $tmp[$p->name] = $arr[$p->name];
                         }
                     }
                 }
                 $params = $tmp;
                 $tmp = null;
                 $arr = null;
                 $map = null;
             }
             if (!is_null($key) && xapp_is_option(self::CACHE, $this) && preg_match(Xapp_Rpc::regex(xapp_get_option(self::CACHE_SERVICES, $this)), $call[0])) {
                 if (xapp_get_option(self::CACHE_BY_TRANSACTION_ID, $this)) {
                     $hash = $call[3]['id'];
                 } else {
                     $hash = Xapp_Cache::hash(serialize($call[0]) . serialize($params));
                 }
                 if (xapp_get_option(self::CACHE, $this)->has($hash)) {
                     return xapp_get_option(self::CACHE, $this)->get($hash);
                 }
             }
             if (!xapp_get_option(self::PARAMS_AS_ARRAY, $this)) {
                 $params = xapp_array_to_object($params);
             }
             xapp_event('xapp.rpc.server.beforeCall', array($this, array(&$result, $call[1], $call[2], $params)));
             if ($this->hasClass() && $class->implementsInterface('Xapp_Rpc_Interface_Callable')) {
                 $return = $this->getClass()->onBeforeCall($this, array(&$result, $call[1], $call[2], &$params));
             }
             if ($return !== false && $result === null) {
                 $this->response()->result($result = call_user_func_array($callable, (array) $params));
             }
             if ($return === false && $this->hasClass() && $class->implementsInterface('Xapp_Rpc_Interface_Callable')) {
                 $return = $this->getClass()->onAbort($this, array(&$result, $call[1], $call[2], &$params));
             } else {
                 $return = null;
             }
             if ($return !== null) {
                 $result = $return;
             }
             if ($this->hasClass() && $class->implementsInterface('Xapp_Rpc_Interface_Callable')) {
                 $return = $this->getClass()->onAfterCall($this, array(&$result));
             }
             if ($return !== null) {
                 $result = $return;
             }
             xapp_event('xapp.rpc.server.afterCall', array($this, array(&$result)));
             if (!is_null($hash)) {
                 if (!xapp_get_option(self::CACHE, $this)->has($hash)) {
                     xapp_get_option(self::CACHE, $this)->set($hash, $result);
                 }
             }
             $callable = null;
             $return = null;
             $params = null;
             $class = null;
             $hash = null;
             return $result;
         } else {
             throw new Xapp_Rpc_Server_Exception(_("unable to invoke function since first argument is not a callable"), 1421102);
         }
     } catch (Exception $e) {
         if ($this->hasClass() && $class->implementsInterface('Xapp_Rpc_Interface_Callable')) {
             $error = $this->getClass()->onError($this, $e);
             if ($error instanceof Exception) {
                 $e = $error;
                 $error = null;
             }
         }
         if (!$e instanceof Xapp_Rpc_Server_Exception) {
             $data = array();
             $debug = xapp_get_option(self::DEBUG, $this);
             if (is_bool($debug) && $debug === true || is_int($debug) && $debug === 1) {
                 $data['message'] = $e->getMessage();
                 $data['code'] = $e->getCode();
                 $data['class'] = get_class($e);
                 $data['file'] = $e->getFile();
                 $data['line'] = $e->getLine();
                 if ($e instanceof ErrorException) {
                     $data['severity'] = $e->getSeverity();
                 }
                 if ($e instanceof Xapp_Rpc_Fault && $e->hasData()) {
                     $data['data'] = $e->getData();
                 }
             } else {
                 if (is_int($debug) && $debug === 2) {
                     $data['message'] = $e->getMessage();
                     $data['code'] = $e->getCode();
                     if ($e instanceof ErrorException) {
                         $data['severity'] = $e->getSeverity();
                     }
                     if ($e instanceof Xapp_Rpc_Fault && $e->hasData()) {
                         $data['data'] = $e->getData();
                     }
                 }
             }
             if (xapp_is_option(self::APPLICATION_ERROR, $this)) {
                 if ($e instanceof Xapp_Rpc_Fault && $e->hasFault()) {
                     $f = $e->getFault();
                 } else {
                     $f = -32500;
                 }
                 if (($code = (int) $e->getCode()) !== 0) {
                     Xapp_Rpc_Fault::t(xapp_sprintf("application error: %d", array($code)), array(1421101, $f), XAPP_ERROR_IGNORE, $data);
                 } else {
                     Xapp_Rpc_Fault::t("application error", array(1421101, $f), XAPP_ERROR_IGNORE, $data);
                 }
             } else {
                 if ((bool) $debug) {
                     Xapp_Rpc_Fault::t($e->getMessage(), $e->getCode(), XAPP_ERROR_IGNORE, $data);
                 } else {
                     throw $e;
                 }
             }
         } else {
             throw $e;
         }
     }
     return null;
 }