<?php
class Raven_Client
{
const VERSION = '1.9.x-dev';
const PROTOCOL = '6';
const DEBUG = 'debug';
const INFO = 'info';
const WARN = 'warning';
const WARNING = 'warning';
const ERROR = 'error';
const FATAL = 'fatal';
const MESSAGE_LIMIT = 1024;
public $breadcrumbs;
public $context;
public $extra_data;
public $severity_map;
public $store_errors_for_bulk_send = false;
protected $error_handler;
protected $error_types;
protected $serializer;
protected $reprSerializer;
protected $app_path;
protected $prefixes;
protected $excluded_app_paths;
protected $transport;
public $logger;
public $server;
public $secret_key;
public $public_key;
public $project;
public $auto_log_stacks;
public $name;
public $site;
public $tags;
public $release;
public $environment;
public $sample_rate;
public $trace;
public $timeout;
public $message_limit;
public $exclude;
public $excluded_exceptions;
public $http_proxy;
protected $send_callback;
public $curl_method;
public $curl_path;
public $curl_ipv4;
public $ca_cert;
public $verify_ssl;
public $curl_ssl_version;
public $trust_x_forwarded_proto;
public $mb_detect_order;
public $processors;
public $_lasterror;
protected $_last_sentry_error;
public $_last_event_id;
public $_user;
public $_pending_events;
public $sdk;
protected $_curl_handler;
protected $_curl_instance;
protected $_shutdown_function_has_been_set;
public $useCompression;
public function __construct($options_or_dsn = null, $options = array())
{
if (is_array($options_or_dsn)) {
$options = array_merge($options_or_dsn, $options);
}
if (!is_array($options_or_dsn) && !empty($options_or_dsn)) {
$dsn = $options_or_dsn;
} elseif (!empty($_SERVER['SENTRY_DSN'])) {
$dsn = @$_SERVER['SENTRY_DSN'];
} elseif (!empty($options['dsn'])) {
$dsn = $options['dsn'];
} else {
$dsn = null;
}
if (!empty($dsn)) {
$options = array_merge($options, self::parseDSN($dsn));
}
$this->logger = Raven_Util::get($options, 'logger', 'php');
$this->server = Raven_Util::get($options, 'server');
$this->secret_key = Raven_Util::get($options, 'secret_key');
$this->public_key = Raven_Util::get($options, 'public_key');
$this->project = Raven_Util::get($options, 'project', 1);
$this->auto_log_stacks = (bool) Raven_Util::get($options, 'auto_log_stacks', false);
$this->name = Raven_Util::get($options, 'name', Raven_Compat::gethostname());
$this->site = Raven_Util::get($options, 'site', self::_server_variable('SERVER_NAME'));
$this->tags = Raven_Util::get($options, 'tags', array());
$this->release = Raven_Util::get($options, 'release', null);
$this->environment = Raven_Util::get($options, 'environment', null);
$this->sample_rate = Raven_Util::get($options, 'sample_rate', 1);
$this->trace = (bool) Raven_Util::get($options, 'trace', true);
$this->timeout = Raven_Util::get($options, 'timeout', 2);
$this->message_limit = Raven_Util::get($options, 'message_limit', self::MESSAGE_LIMIT);
$this->exclude = Raven_Util::get($options, 'exclude', array());
$this->excluded_exceptions = Raven_Util::get($options, 'excluded_exceptions', array());
$this->severity_map = null;
$this->http_proxy = Raven_Util::get($options, 'http_proxy');
$this->extra_data = Raven_Util::get($options, 'extra', array());
$this->send_callback = Raven_Util::get($options, 'send_callback', null);
$this->curl_method = Raven_Util::get($options, 'curl_method', 'sync');
$this->curl_path = Raven_Util::get($options, 'curl_path', 'curl');
$this->curl_ipv4 = Raven_Util::get($options, 'curl_ipv4', true);
$this->ca_cert = Raven_Util::get($options, 'ca_cert', static::get_default_ca_cert());
$this->verify_ssl = Raven_Util::get($options, 'verify_ssl', true);
$this->curl_ssl_version = Raven_Util::get($options, 'curl_ssl_version');
$this->trust_x_forwarded_proto = Raven_Util::get($options, 'trust_x_forwarded_proto');
$this->transport = Raven_Util::get($options, 'transport', null);
$this->mb_detect_order = Raven_Util::get($options, 'mb_detect_order', null);
$this->error_types = Raven_Util::get($options, 'error_types', null);
$this->setAppPath(Raven_Util::get($options, 'app_path', null));
$this->setExcludedAppPaths(Raven_Util::get($options, 'excluded_app_paths', null));
$this->setPrefixes(Raven_Util::get($options, 'prefixes', static::getDefaultPrefixes()));
$this->processors = $this->setProcessorsFromOptions($options);
$this->_lasterror = null;
$this->_last_sentry_error = null;
$this->_curl_instance = null;
$this->_last_event_id = null;
$this->_user = null;
$this->_pending_events = array();
$this->context = new Raven_Context();
$this->breadcrumbs = new Raven_Breadcrumbs();
$this->_shutdown_function_has_been_set = false;
$this->useCompression = function_exists('gzcompress');
$this->sdk = Raven_Util::get($options, 'sdk', array(
'name' => 'sentry-php',
'version' => self::VERSION,
));
$this->serializer = new Raven_Serializer($this->mb_detect_order);
$this->reprSerializer = new Raven_ReprSerializer($this->mb_detect_order);
if ($this->curl_method == 'async') {
$this->_curl_handler = new Raven_CurlHandler($this->get_curl_options());
}
$this->transaction = new Raven_TransactionStack();
if (static::is_http_request() && isset($_SERVER['PATH_INFO'])) {
$this->transaction->push($_SERVER['PATH_INFO']);
}
if (Raven_Util::get($options, 'install_default_breadcrumb_handlers', true)) {
$this->registerDefaultBreadcrumbHandlers();
}
if (Raven_Util::get($options, 'install_shutdown_handler', true)) {
$this->registerShutdownFunction();
}
$this->triggerAutoload();
}
public function __destruct()
{
$this->close_curl_resource();
}
public function close_all_children_link()
{
$this->processors = array();
}
public function install()
{
if ($this->error_handler) {
throw new Raven_Exception(sprintf('%s->install() must only be called once', get_class($this)));
}
$this->error_handler = new Raven_ErrorHandler($this, false, $this->error_types);
$this->error_handler->registerExceptionHandler();
$this->error_handler->registerErrorHandler();
$this->error_handler->registerShutdownFunction();
if ($this->_curl_handler) {
$this->_curl_handler->registerShutdownFunction();
}
return $this;
}
public function getRelease()
{
return $this->release;
}
public function setRelease($value)
{
$this->release = $value;
return $this;
}
public function getEnvironment()
{
return $this->environment;
}
public function setEnvironment($value)
{
$this->environment = $value;
return $this;
}
protected static function getInputStream()
{
if (PHP_VERSION_ID < 50600) {
return null;
}
return file_get_contents('php://input');
}
private static function getDefaultPrefixes()
{
$value = get_include_path();
return explode(PATH_SEPARATOR, $value);
}
private static function _convertPath($value)
{
$path = @realpath($value);
if ($path === false) {
$path = $value;
}
if ($path{0} === DIRECTORY_SEPARATOR && substr($path, -1) !== DIRECTORY_SEPARATOR) {
$path .= DIRECTORY_SEPARATOR;
}
return $path;
}
public function getAppPath()
{
return $this->app_path;
}
public function setAppPath($value)
{
if ($value) {
$this->app_path = static::_convertPath($value);
} else {
$this->app_path = null;
}
return $this;
}
public function getExcludedAppPaths()
{
return $this->excluded_app_paths;
}
public function setExcludedAppPaths($value)
{
if ($value) {
$excluded_app_paths = array();
foreach ((array) $value as $path) {
$excluded_app_paths[] = substr($path, -4) !== '.php' ? self::_convertPath($path) : $path;
}
} else {
$excluded_app_paths = null;
}
$this->excluded_app_paths = $excluded_app_paths;
return $this;
}
public function getPrefixes()
{
return $this->prefixes;
}
public function setPrefixes($value)
{
$this->prefixes = $value ? array_map(array($this, '_convertPath'), $value) : $value;
return $this;
}
public function getSendCallback()
{
return $this->send_callback;
}
public function setSendCallback($value)
{
$this->send_callback = $value;
return $this;
}
public function getTransport()
{
return $this->transport;
}
public function getServerEndpoint($value = '')
{
return $this->server;
}
public static function getUserAgent()
{
return 'sentry-php/' . self::VERSION;
}
public function setTransport($value)
{
$this->transport = $value;
return $this;
}
public static function getDefaultProcessors()
{
return array(
'Raven_Processor_SanitizeDataProcessor',
);
}
public function setProcessorsFromOptions($options)
{
$processors = array();
foreach (Raven_util::get($options, 'processors', static::getDefaultProcessors()) as $processor) {
$new_processor = new $processor($this);
if (isset($options['processorOptions']) && is_array($options['processorOptions'])) {
if (isset($options['processorOptions'][$processor])
&& method_exists($processor, 'setProcessorOptions')
) {
$new_processor->setProcessorOptions($options['processorOptions'][$processor]);
}
}
$processors[] = $new_processor;
}
return $processors;
}
public static function parseDSN($dsn)
{
switch (strtolower($dsn)) {
case '':
case 'false':
case '(false)':
case 'empty':
case '(empty)':
case 'null':
case '(null)':
return array();
}
$url = parse_url($dsn);
$scheme = (isset($url['scheme']) ? $url['scheme'] : '');
if (!in_array($scheme, array('http', 'https'))) {
throw new InvalidArgumentException(
'Unsupported Sentry DSN scheme: '.
(!empty($scheme) ? $scheme : '<not set>')
);
}
$netloc = (isset($url['host']) ? $url['host'] : null);
$netloc .= (isset($url['port']) ? ':'.$url['port'] : null);
$rawpath = (isset($url['path']) ? $url['path'] : null);
if ($rawpath) {
$pos = strrpos($rawpath, '/', 1);
if ($pos !== false) {
$path = substr($rawpath, 0, $pos);
$project = substr($rawpath, $pos + 1);
} else {
$path = '';
$project = substr($rawpath, 1);
}
} else {
$project = null;
$path = '';
}
$username = (isset($url['user']) ? $url['user'] : null);
$password = (isset($url['pass']) ? $url['pass'] : null);
if (empty($netloc) || empty($project) || empty($username) || empty($password)) {
throw new InvalidArgumentException('Invalid Sentry DSN: ' . $dsn);
}
return array(
'server' => sprintf('%s://%s%s/api/%s/store/', $scheme, $netloc, $path, $project),
'project' => $project,
'public_key' => $username,
'secret_key' => $password,
);
}
public function getLastError()
{
return $this->_lasterror;
}
public function getIdent($ident)
{
return $ident;
}
public function message($message, $params = array(), $level = self::INFO,
$stack = false, $vars = null)
{
return $this->captureMessage($message, $params, $level, $stack, $vars);
}
public function exception($exception)
{
return $this->captureException($exception);
}
public function captureMessage($message, $params = array(), $data = array(),
$stack = false, $vars = null)
{
if (!empty($params)) {
$formatted_message = vsprintf($message, $params);
} else {
$formatted_message = $message;
}
if ($data === null) {
$data = array();
} elseif (!is_array($data)) {
$data = array(
'level' => $data,
);
}
$data['message'] = $formatted_message;
$data['sentry.interfaces.Message'] = array(
'message' => $message,
'params' => $params,
'formatted' => $formatted_message,
);
return $this->capture($data, $stack, $vars);
}
public function captureException($exception, $data = null, $logger = null, $vars = null)
{
$has_chained_exceptions = PHP_VERSION_ID >= 50300;
if (in_array(get_class($exception), $this->exclude)) {
return null;
}
foreach ($this->excluded_exceptions as $exclude) {
if ($exception instanceof $exclude) {
return null;
}
}
if ($data === null) {
$data = array();
}
$exc = $exception;
do {
$exc_data = array(
'value' => $this->serializer->serialize($exc->getMessage()),
'type' => get_class($exc),
);
$trace = $exc->getTrace();
$frame_where_exception_thrown = array(
'file' => $exc->getFile(),
'line' => $exc->getLine(),
);
array_unshift($trace, $frame_where_exception_thrown);
$exc_data['stacktrace'] = array(
'frames' => Raven_Stacktrace::get_stack_info(
$trace, $this->trace, $vars, $this->message_limit, $this->prefixes,
$this->app_path, $this->excluded_app_paths, $this->serializer, $this->reprSerializer
),
);
$exceptions[] = $exc_data;
} while ($has_chained_exceptions && $exc = $exc->getPrevious());
$data['exception'] = array(
'values' => array_reverse($exceptions),
);
if ($logger !== null) {
$data['logger'] = $logger;
}
if (empty($data['level'])) {
if (method_exists($exception, 'getSeverity')) {
$data['level'] = $this->translateSeverity($exception->getSeverity());
} else {
$data['level'] = self::ERROR;
}
}
return $this->capture($data, $trace, $vars);
}
public function captureLastError()
{
if (null === $error = error_get_last()) {
return null;
}
$e = new ErrorException(
@$error['message'], 0, @$error['type'],
@$error['file'], @$error['line']
);
return $this->captureException($e);
}
public function captureQuery($query, $level = self::INFO, $engine = '')
{
$data = array(
'message' => $query,
'level' => $level,
'sentry.interfaces.Query' => array(
'query' => $query
)
);
if ($engine !== '') {
$data['sentry.interfaces.Query']['engine'] = $engine;
}
return $this->capture($data, false);
}
public function getLastEventID()
{
return $this->_last_event_id;
}
protected function registerDefaultBreadcrumbHandlers()
{
$handler = new Raven_Breadcrumbs_ErrorHandler($this);
$handler->install();
}
protected function registerShutdownFunction()
{
if (!$this->_shutdown_function_has_been_set) {
$this->_shutdown_function_has_been_set = true;
register_shutdown_function(array($this, 'onShutdown'));
}
}
protected static function is_http_request()
{
return isset($_SERVER['REQUEST_METHOD']) && PHP_SAPI !== 'cli';
}
protected function get_http_data()
{
$headers = array();
foreach ($_SERVER as $key => $value) {
if (0 === strpos($key, 'HTTP_')) {
$header_key =
str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($key, 5)))));
$headers[$header_key] = $value;
} elseif (in_array($key, array('CONTENT_TYPE', 'CONTENT_LENGTH')) && $value !== '') {
$header_key = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', $key))));
$headers[$header_key] = $value;
}
}
$result = array(
'method' => self::_server_variable('REQUEST_METHOD'),
'url' => $this->get_current_url(),
'query_string' => self::_server_variable('QUERY_STRING'),
);
if (!empty($_POST)) {
$result['data'] = $_POST;
} elseif (isset($_SERVER['CONTENT_TYPE']) && stripos($_SERVER['CONTENT_TYPE'], 'application/json') === 0) {
$raw_data = $this->getInputStream() ?: false;
if ($raw_data !== false) {
$result['data'] = (array) json_decode($raw_data, true) ?: null;
}
}
if (!empty($_COOKIE)) {
$result['cookies'] = $_COOKIE;
}
if (!empty($headers)) {
$result['headers'] = $headers;
}
return array(
'request' => $result,
);
}
protected function get_user_data()
{
$user = $this->context->user;
if ($user === null) {
if (!function_exists('session_id') || !session_id()) {
return array();
}
$user = array(
'id' => session_id(),
);
if (!empty($_SERVER['REMOTE_ADDR'])) {
$user['ip_address'] = $_SERVER['REMOTE_ADDR'];
}
if (!empty($_SESSION)) {
$user['data'] = $_SESSION;
}
}
return array(
'user' => $user,
);
}
protected function get_extra_data()
{
return $this->extra_data;
}
public function get_default_data()
{
return array(
'server_name' => $this->name,
'project' => $this->project,
'site' => $this->site,
'logger' => $this->logger,
'tags' => $this->tags,
'platform' => 'php',
'sdk' => $this->sdk,
'culprit' => $this->transaction->peek(),
);
}
public function capture($data, $stack = null, $vars = null)
{
if (!isset($data['timestamp'])) {
$data['timestamp'] = gmdate('Y-m-d\TH:i:s\Z');
}
if (!isset($data['level'])) {
$data['level'] = self::ERROR;
}
if (!isset($data['tags'])) {
$data['tags'] = array();
}
if (!isset($data['extra'])) {
$data['extra'] = array();
}
if (!isset($data['event_id'])) {
$data['event_id'] = static::uuid4();
}
if (isset($data['message'])) {
$data['message'] = substr($data['message'], 0, $this->message_limit);
}
$data = array_merge($this->get_default_data(), $data);
if (static::is_http_request()) {
$data = array_merge($this->get_http_data(), $data);
}
$data = array_merge($this->get_user_data(), $data);
if ($this->release) {
$data['release'] = $this->release;
}
if ($this->environment) {
$data['environment'] = $this->environment;
}
$data['tags'] = array_merge(
$this->tags,
$this->context->tags,
$data['tags']);
$data['extra'] = array_merge(
$this->get_extra_data(),
$this->context->extra,
$data['extra']);
if (empty($data['extra'])) {
unset($data['extra']);
}
if (empty($data['tags'])) {
unset($data['tags']);
}
if (empty($data['user'])) {
unset($data['user']);
}
if (empty($data['request'])) {
unset($data['request']);
}
if (empty($data['site'])) {
unset($data['site']);
}
$existing_runtime_context = isset($data['contexts']['runtime']) ? $data['contexts']['runtime'] : array();
$runtime_context = array('version' => PHP_VERSION, 'name' => 'php');
$data['contexts']['runtime'] = array_merge($runtime_context, $existing_runtime_context);
if (!$this->breadcrumbs->is_empty()) {
$data['breadcrumbs'] = $this->breadcrumbs->fetch();
}
if ((!$stack && $this->auto_log_stacks) || $stack === true) {
$stack = debug_backtrace();
array_shift($stack);
}
if (! empty($stack) && ! isset($data['stacktrace']) && ! isset($data['exception'])) {
$data['stacktrace'] = array(
'frames' => Raven_Stacktrace::get_stack_info(
$stack, $this->trace, $vars, $this->message_limit, $this->prefixes,
$this->app_path, $this->excluded_app_paths, $this->serializer, $this->reprSerializer
),
);
}
$this->sanitize($data);
$this->process($data);
if (!$this->store_errors_for_bulk_send) {
$this->send($data);
} else {
$this->_pending_events[] = $data;
}
$this->_last_event_id = $data['event_id'];
return $data['event_id'];
}
public function sanitize(&$data)
{
if (!empty($data['request'])) {
$data['request'] = $this->serializer->serialize($data['request'], 5);
}
if (!empty($data['user'])) {
$data['user'] = $this->serializer->serialize($data['user'], 3);
}
if (!empty($data['extra'])) {
$data['extra'] = $this->serializer->serialize($data['extra']);
}
if (!empty($data['tags'])) {
foreach ($data['tags'] as $key => $value) {
$data['tags'][$key] = @(string)$value;
}
}
if (!empty($data['contexts'])) {
$data['contexts'] = $this->serializer->serialize($data['contexts'], 5);
}
if (!empty($data['breadcrumbs'])) {
$data['breadcrumbs'] = $this->serializer->serialize($data['breadcrumbs'], 5);
}
}
public function process(&$data)
{
foreach ($this->processors as $processor) {
$processor->process($data);
}
}
public function sendUnsentErrors()
{
foreach ($this->_pending_events as $data) {
$this->send($data);
}
$this->_pending_events = array();
if ($this->store_errors_for_bulk_send) {
$this->store_errors_for_bulk_send = !defined('RAVEN_CLIENT_END_REACHED');
}
}
public function encode(&$data)
{
$message = Raven_Compat::json_encode($data);
if ($message === false) {
if (function_exists('json_last_error_msg')) {
$this->_lasterror = json_last_error_msg();
} else {
$this->_lasterror = json_last_error();
}
return false;
}
if ($this->useCompression) {
$message = gzcompress($message);
}
$message = base64_encode($message);
return $message;
}
public function send(&$data)
{
if (is_callable($this->send_callback)
&& call_user_func_array($this->send_callback, array(&$data)) === false
) {
return;
}
if (!$this->server) {
return;
}
if ($this->transport) {
call_user_func($this->transport, $this, $data);
return;
}
if (rand(1, 100) / 100.0 > $this->sample_rate) {
return;
}
$message = $this->encode($data);
$headers = array(
'User-Agent' => static::getUserAgent(),
'X-Sentry-Auth' => $this->getAuthHeader(),
'Content-Type' => 'application/octet-stream'
);
$this->send_remote($this->server, $message, $headers);
}
protected function send_remote($url, $data, $headers = array())
{
$parts = parse_url($url);
$parts['netloc'] = $parts['host'].(isset($parts['port']) ? ':'.$parts['port'] : null);
$this->send_http($url, $data, $headers);
}
protected static function get_default_ca_cert()
{
return dirname(__FILE__) . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'cacert.pem';
}
protected function get_curl_options()
{
$options = array(
CURLOPT_VERBOSE => false,
CURLOPT_SSL_VERIFYHOST => 2,
CURLOPT_SSL_VERIFYPEER => $this->verify_ssl,
CURLOPT_CAINFO => $this->ca_cert,
CURLOPT_USERAGENT => 'sentry-php/' . self::VERSION,
);
if ($this->http_proxy) {
$options[CURLOPT_PROXY] = $this->http_proxy;
}
if ($this->curl_ssl_version) {
$options[CURLOPT_SSLVERSION] = $this->curl_ssl_version;
}
if ($this->curl_ipv4) {
$options[CURLOPT_IPRESOLVE] = CURL_IPRESOLVE_V4;
}
if (defined('CURLOPT_TIMEOUT_MS')) {
$timeout = max(1, ceil(1000 * $this->timeout));
if (!defined('CURLOPT_CONNECTTIMEOUT_MS')) {
define('CURLOPT_CONNECTTIMEOUT_MS', 156);
}
$options[CURLOPT_CONNECTTIMEOUT_MS] = $timeout;
$options[CURLOPT_TIMEOUT_MS] = $timeout;
} else {
$timeout = max(1, ceil($this->timeout));
$options[CURLOPT_CONNECTTIMEOUT] = $timeout;
$options[CURLOPT_TIMEOUT] = $timeout;
}
return $options;
}
protected function send_http($url, $data, $headers = array())
{
if ($this->curl_method == 'async') {
$this->_curl_handler->enqueue($url, $data, $headers);
} elseif ($this->curl_method == 'exec') {
$this->send_http_asynchronous_curl_exec($url, $data, $headers);
} else {
$this->send_http_synchronous($url, $data, $headers);
}
}
protected function buildCurlCommand($url, $data, $headers)
{
$cmd = $this->curl_path.' -X POST ';
foreach ($headers as $key => $value) {
$cmd .= '-H ' . escapeshellarg($key.': '.$value). ' ';
}
$cmd .= '-d ' . escapeshellarg($data) . ' ';
$cmd .= escapeshellarg($url) . ' ';
$cmd .= '-m 5 '; if (!$this->verify_ssl) {
$cmd .= '-k ';
}
$cmd .= '> /dev/null 2>&1 &';
return $cmd;
}
protected function send_http_asynchronous_curl_exec($url, $data, $headers)
{
exec($this->buildCurlCommand($url, $data, $headers));
return true; }
protected function send_http_synchronous($url, $data, $headers)
{
$new_headers = array();
foreach ($headers as $key => $value) {
array_push($new_headers, $key .': '. $value);
}
$new_headers[] = 'Expect:';
if (is_null($this->_curl_instance)) {
$this->_curl_instance = curl_init($url);
}
curl_setopt($this->_curl_instance, CURLOPT_POST, 1);
curl_setopt($this->_curl_instance, CURLOPT_HTTPHEADER, $new_headers);
curl_setopt($this->_curl_instance, CURLOPT_POSTFIELDS, $data);
curl_setopt($this->_curl_instance, CURLOPT_RETURNTRANSFER, true);
$options = $this->get_curl_options();
if (isset($options[CURLOPT_CAINFO])) {
$ca_cert = $options[CURLOPT_CAINFO];
unset($options[CURLOPT_CAINFO]);
} else {
$ca_cert = null;
}
curl_setopt_array($this->_curl_instance, $options);
$buffer = curl_exec($this->_curl_instance);
$errno = curl_errno($this->_curl_instance);
if ((($errno == 60) || ($errno == 77)) && !is_null($ca_cert)) {
curl_setopt($this->_curl_instance, CURLOPT_CAINFO, $ca_cert);
$buffer = curl_exec($this->_curl_instance);
}
if ($errno != 0) {
$this->_lasterror = curl_error($this->_curl_instance);
$this->_last_sentry_error = null;
return false;
}
$code = curl_getinfo($this->_curl_instance, CURLINFO_HTTP_CODE);
$success = ($code == 200);
if ($success) {
$this->_lasterror = null;
$this->_last_sentry_error = null;
} else {
$this->_lasterror = curl_error($this->_curl_instance);
$this->_last_sentry_error = @json_decode($buffer);
}
return $success;
}
protected static function get_auth_header($timestamp, $client, $api_key, $secret_key)
{
$header = array(
sprintf('sentry_timestamp=%F', $timestamp),
"sentry_client={$client}",
sprintf('sentry_version=%s', self::PROTOCOL),
);
if ($api_key) {
$header[] = "sentry_key={$api_key}";
}
if ($secret_key) {
$header[] = "sentry_secret={$secret_key}";
}
return sprintf('Sentry %s', implode(', ', $header));
}
public function getAuthHeader()
{
$timestamp = microtime(true);
return $this->get_auth_header(
$timestamp, static::getUserAgent(), $this->public_key, $this->secret_key
);
}
protected static function uuid4()
{
$uuid = sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
mt_rand(0, 0xffff), mt_rand(0, 0xffff),
mt_rand(0, 0xffff),
mt_rand(0, 0x0fff) | 0x4000,
mt_rand(0, 0x3fff) | 0x8000,
mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
);
return str_replace('-', '', $uuid);
}
protected function get_current_url()
{
if (!isset($_SERVER['REQUEST_URI'])) {
return null;
}
$host = (!empty($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST']
: (!empty($_SERVER['LOCAL_ADDR']) ? $_SERVER['LOCAL_ADDR']
: (!empty($_SERVER['SERVER_ADDR']) ? $_SERVER['SERVER_ADDR'] : '')));
$hasNonDefaultPort = !empty($_SERVER['SERVER_PORT']) && !in_array((int)$_SERVER['SERVER_PORT'], array(80, 443));
if ($hasNonDefaultPort && !preg_match('#:[0-9]*$#', $host)) {
$host .= ':' . $_SERVER['SERVER_PORT'];
}
$httpS = $this->isHttps() ? 's' : '';
return "http{$httpS}://{$host}{$_SERVER['REQUEST_URI']}";
}
protected function isHttps()
{
if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') {
return true;
}
if (!empty($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == 443) {
return true;
}
if (!empty($this->trust_x_forwarded_proto) &&
!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) &&
$_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
return true;
}
return false;
}
private static function _server_variable($key)
{
if (isset($_SERVER[$key])) {
return $_SERVER[$key];
}
return '';
}
public function translateSeverity($severity)
{
if (is_array($this->severity_map) && isset($this->severity_map[$severity])) {
return $this->severity_map[$severity];
}
switch ($severity) {
case E_ERROR: return Raven_Client::ERROR;
case E_WARNING: return Raven_Client::WARN;
case E_PARSE: return Raven_Client::ERROR;
case E_NOTICE: return Raven_Client::INFO;
case E_CORE_ERROR: return Raven_Client::ERROR;
case E_CORE_WARNING: return Raven_Client::WARN;
case E_COMPILE_ERROR: return Raven_Client::ERROR;
case E_COMPILE_WARNING: return Raven_Client::WARN;
case E_USER_ERROR: return Raven_Client::ERROR;
case E_USER_WARNING: return Raven_Client::WARN;
case E_USER_NOTICE: return Raven_Client::INFO;
case E_STRICT: return Raven_Client::INFO;
case E_RECOVERABLE_ERROR: return Raven_Client::ERROR;
}
if (PHP_VERSION_ID >= 50300) {
switch ($severity) {
case E_DEPRECATED: return Raven_Client::WARN;
case E_USER_DEPRECATED: return Raven_Client::WARN;
}
}
return Raven_Client::ERROR;
}
public function registerSeverityMap($map)
{
$this->severity_map = $map;
}
public function set_user_data($id, $email = null, $data = array())
{
$user = array('id' => $id);
if (isset($email)) {
$user['email'] = $email;
}
$this->user_context(array_merge($user, $data));
}
public function onShutdown()
{
if (!defined('RAVEN_CLIENT_END_REACHED')) {
define('RAVEN_CLIENT_END_REACHED', true);
}
$this->sendUnsentErrors();
if ($this->curl_method == 'async') {
$this->_curl_handler->join();
}
}
public function user_context($data, $merge = true)
{
if ($merge && $this->context->user !== null) {
if (!$data) {
return;
}
$this->context->user = array_merge($this->context->user, $data);
} else {
$this->context->user = $data;
}
}
public function tags_context($data)
{
$this->context->tags = array_merge($this->context->tags, $data);
}
public function extra_context($data)
{
$this->context->extra = array_merge($this->context->extra, $data);
}
public function setProcessors(array $processors)
{
$this->processors = $processors;
}
public function getLastSentryError()
{
return $this->_last_sentry_error;
}
public function getShutdownFunctionHasBeenSet()
{
return $this->_shutdown_function_has_been_set;
}
public function close_curl_resource()
{
if (!is_null($this->_curl_instance)) {
curl_close($this->_curl_instance);
$this->_curl_instance = null;
}
}
public function setSerializer(Raven_Serializer $serializer)
{
$this->serializer = $serializer;
}
public function setReprSerializer(Raven_ReprSerializer $reprSerializer)
{
$this->reprSerializer = $reprSerializer;
}
private function triggerAutoload()
{
if (! class_exists('Raven_Stacktrace')) {
spl_autoload_call('Raven_Stacktrace');
}
if (function_exists('mb_detect_encoding')) {
mb_detect_encoding('string');
}
if (function_exists('mb_convert_encoding')) {
mb_convert_encoding('string', 'UTF8');
}
}
}