CVE-2017-1000490
Description
Mautic versions 1.0.0 - 2.11.0 are vulnerable to allowing any authorized Mautic user session (must be logged into Mautic) to use the Filemanager to download any file from the server that the web user has access to.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Mautic versions 1.0.0 to 2.11.0 allow authenticated users to download arbitrary files via path traversal in Filemanager.
Vulnerability
Mautic versions 1.0.0 to 2.11.0 contain a path traversal vulnerability in the Filemanager component. An authenticated user can manipulate the path GET parameter with ....// sequences to bypass sanitization and download any file on the server that the web server user can access. [1][2]
Exploitation
An attacker must be logged into Mautic as an authorized user. By sending a request to the Filemanager connector with a path parameter containing directory traversal sequences such as ....//, the attacker can read arbitrary files. The fix addressed this by replacing the single str_replace('../') with a loop to catch multiple occurrences. [2][3]
Impact
A successful attack allows an authenticated user to download any file accessible to the web server user, leading to information disclosure of sensitive data such as configuration files, database credentials, or source code. [1][4]
Mitigation
Update to Mautic 2.12.0 or later, which includes a fix that properly sanitizes the path parameter. No workarounds are available. [2][4]
AI Insight generated on May 22, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
mautic/corePackagist | >= 1.0.0, < 2.12.0 | 2.12.0 |
Affected products
1Patches
13b01786433aeClose security vulnerability that allowed download of any file accessible to the web server user
12 files changed · +15 −23766
app/bundles/CoreBundle/Assets/js/libraries/ckeditor/filemanager/connectors/php/filemanager.class.php+15 −6 modified@@ -950,7 +950,7 @@ public function download() $this->__log(__METHOD__.' - downloading '.$current_path); exit(); } else { - $this->error(sprintf($this->lang('FILE_DOES_NOT_EXIST'), $current_path)); + $this->error(sprintf($this->lang('FILE_DOES_NOT_EXIST'), $this->getRelPath())); } } @@ -976,7 +976,7 @@ public function preview($thumbnail) exit(); } else { - $this->error(sprintf($this->lang('FILE_DOES_NOT_EXIST'), $current_path)); + $this->error(sprintf($this->lang('FILE_DOES_NOT_EXIST'), $this->getRelPath())); } } @@ -1107,9 +1107,7 @@ private function get_file_info($path = '', $thumbnail = false) private function getFullPath($path = '') { if ($path == '') { - if (isset($this->get['path'])) { - $path = $this->get['path']; - } + $path = $this->getRelPath(); } if ($this->config['options']['fileRoot'] !== false) { @@ -1130,6 +1128,14 @@ private function getFullPath($path = '') return $full_path; } + /** + * @return mixed|string + */ + private function getRelPath() + { + return (isset($this->get['path'])) ? $this->get['path'] : ''; + } + /** * format path regarding the initial configuration. * @@ -1462,7 +1468,10 @@ private function sanitize($var) $sanitized = strip_tags($var); $sanitized = str_replace('http://', '', $sanitized); $sanitized = str_replace('https://', '', $sanitized); - $sanitized = str_replace('../', '', $sanitized); + $count = 1; + while ($count > 0) { + $sanitized = str_replace('../', '', $sanitized, $count); + } return $sanitized; }
app/bundles/CoreBundle/Assets/js/libraries/ckeditor/filemanager/connectors/php/plugins/rsc/cloudfiles_exceptions.php+0 −64 removed@@ -1,64 +0,0 @@ -<?php -/** - * Custom Exceptions for the CloudFiles API. - * - * Requres PHP 5.x (for Exceptions and OO syntax) - * - * See COPYING for license information. - * - * @author Eric "EJ" Johnson <ej@racklabs.com> - * @copyright Copyright (c) 2008, Rackspace US, Inc - */ - -/** - * Custom Exceptions for the CloudFiles API. - */ -class SyntaxException extends Exception -{ -} -class AuthenticationException extends Exception -{ -} -class InvalidResponseException extends Exception -{ -} -class NonEmptyContainerException extends Exception -{ -} -class NoSuchObjectException extends Exception -{ -} -class NoSuchContainerException extends Exception -{ -} -class NoSuchAccountException extends Exception -{ -} -class MisMatchedChecksumException extends Exception -{ -} -class IOException extends Exception -{ -} -class CDNNotEnabledException extends Exception -{ -} -class BadContentTypeException extends Exception -{ -} -class InvalidUTF8Exception extends Exception -{ -} -class ConnectionNotOpenException extends Exception -{ -} - -/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * c-hanging-comment-ender-p: nil - * End: - */
app/bundles/CoreBundle/Assets/js/libraries/ckeditor/filemanager/connectors/php/plugins/rsc/cloudfiles_http.php+0 −1461 removed@@ -1,1461 +0,0 @@ -<?php -/** - * This is an HTTP client class for Cloud Files. It uses PHP's cURL module - * to handle the actual HTTP request/response. This is NOT a generic HTTP - * client class and is only used to abstract out the HTTP communication for - * the PHP Cloud Files API. - * - * This module was designed to re-use existing HTTP(S) connections between - * subsequent operations. For example, performing multiple PUT operations - * will re-use the same connection. - * - * This modules also provides support for streaming content into and out - * of Cloud Files. The majority (all?) of the PHP HTTP client modules expect - * to read the server's response into a string variable. This will not work - * with large files without killing your server. Methods like, - * get_object_to_stream() and put_object() take an open filehandle - * argument for streaming data out of or into Cloud Files. - * - * Requres PHP 5.x (for Exceptions and OO syntax) - * - * See COPYING for license information. - * - * @author Eric "EJ" Johnson <ej@racklabs.com> - * @copyright Copyright (c) 2008, Rackspace US, Inc - */ -require_once 'cloudfiles_exceptions.php'; - -define('PHP_CF_VERSION', '1.7.7'); -define('USER_AGENT', sprintf('PHP-CloudFiles/%s', PHP_CF_VERSION)); -define('ACCOUNT_CONTAINER_COUNT', 'X-Account-Container-Count'); -define('ACCOUNT_BYTES_USED', 'X-Account-Bytes-Used'); -define('CONTAINER_OBJ_COUNT', 'X-Container-Object-Count'); -define('CONTAINER_BYTES_USED', 'X-Container-Bytes-Used'); -define('METADATA_HEADER', 'X-Object-Meta-'); -define('CDN_URI', 'X-CDN-URI'); -define('CDN_ENABLED', 'X-CDN-Enabled'); -define('CDN_LOG_RETENTION', 'X-Log-Retention'); -define('CDN_ACL_USER_AGENT', 'X-User-Agent-ACL'); -define('CDN_ACL_REFERRER', 'X-Referrer-ACL'); -define('CDN_TTL', 'X-TTL'); -define('CDNM_URL', 'X-CDN-Management-Url'); -define('STORAGE_URL', 'X-Storage-Url'); -define('AUTH_TOKEN', 'X-Auth-Token'); -define('AUTH_USER_HEADER', 'X-Auth-User'); -define('AUTH_KEY_HEADER', 'X-Auth-Key'); -define('AUTH_USER_HEADER_LEGACY', 'X-Storage-User'); -define('AUTH_KEY_HEADER_LEGACY', 'X-Storage-Pass'); -define('AUTH_TOKEN_LEGACY', 'X-Storage-Token'); -define('CDN_EMAIL', 'X-Purge-Email'); -/** - * HTTP/cURL wrapper for Cloud Files. - * - * This class should not be used directly. It's only purpose is to abstract - * out the HTTP communication from the main API. - */ -class CF_Http -{ - private $error_str; - private $dbug; - private $cabundle_path; - private $api_version; - - // Authentication instance variables - - private $storage_url; - private $cdnm_url; - private $auth_token; - - // Request/response variables - - private $response_status; - private $response_reason; - private $connections; - - // Variables used for content/header callbacks - - private $_user_read_progress_callback_func; - private $_user_write_progress_callback_func; - private $_write_callback_type; - private $_text_list; - private $_account_container_count; - private $_account_bytes_used; - private $_container_object_count; - private $_container_bytes_used; - private $_obj_etag; - private $_obj_last_modified; - private $_obj_content_type; - private $_obj_content_length; - private $_obj_metadata; - private $_obj_write_resource; - private $_obj_write_string; - private $_cdn_enabled; - private $_cdn_uri; - private $_cdn_ttl; - private $_cdn_log_retention; - private $_cdn_acl_user_agent; - private $_cdn_acl_referrer; - - public function __construct($api_version) - { - $this->dbug = false; - $this->cabundle_path = null; - $this->api_version = $api_version; - $this->error_str = null; - - $this->storage_url = null; - $this->cdnm_url = null; - $this->auth_token = null; - - $this->response_status = null; - $this->response_reason = null; - - // Curl connections array - since there is no way to "re-set" the - // connection paramaters for a cURL handle, we keep an array of - // the unique use-cases and funnel all of those same type - // requests through the appropriate curl connection. - - $this->connections = [ - 'GET_CALL' => null, // GET objects/containers/lists - 'PUT_OBJ' => null, // PUT object - 'HEAD' => null, // HEAD requests - 'PUT_CONT' => null, // PUT container - 'DEL_POST' => null, // DELETE containers/objects, POST objects - ]; - - $this->_user_read_progress_callback_func = null; - $this->_user_write_progress_callback_func = null; - $this->_write_callback_type = null; - $this->_text_list = []; - $this->_return_list = null; - $this->_account_container_count = 0; - $this->_account_bytes_used = 0; - $this->_container_object_count = 0; - $this->_container_bytes_used = 0; - $this->_obj_write_resource = null; - $this->_obj_write_string = ''; - $this->_obj_etag = null; - $this->_obj_last_modified = null; - $this->_obj_content_type = null; - $this->_obj_content_length = null; - $this->_obj_metadata = []; - $this->_cdn_enabled = null; - $this->_cdn_uri = null; - $this->_cdn_ttl = null; - $this->_cdn_log_retention = null; - $this->_cdn_acl_user_agent = null; - $this->_cdn_acl_referrer = null; - - // The OS list with a PHP without an updated CA File for CURL to - // connect to SSL Websites. It is the first 3 letters of the PHP_OS - // variable. - $OS_CAFILE_NONUPDATED = [ - 'win', 'dar', - ]; - - if (in_array((strtolower(substr(PHP_OS, 0, 3))), $OS_CAFILE_NONUPDATED)) { - $this->ssl_use_cabundle(); - } - } - - public function ssl_use_cabundle($path = null) - { - if ($path) { - $this->cabundle_path = $path; - } else { - $this->cabundle_path = dirname(__FILE__).'/share/cacert.pem'; - } - if (!file_exists($this->cabundle_path)) { - throw new IOException('Could not use CA bundle: ' - .$this->cabundle_path); - } - - return; - } - - // Uses separate cURL connection to authenticate - - public function authenticate($user, $pass, $acct = null, $host = null) - { - $path = []; - if (isset($acct)) { - $headers = [ - sprintf('%s: %s', AUTH_USER_HEADER_LEGACY, $user), - sprintf('%s: %s', AUTH_KEY_HEADER_LEGACY, $pass), - ]; - $path[] = $host; - $path[] = rawurlencode(sprintf('v%d', $this->api_version)); - $path[] = rawurlencode($acct); - } else { - $headers = [ - sprintf('%s: %s', AUTH_USER_HEADER, $user), - sprintf('%s: %s', AUTH_KEY_HEADER, $pass), - ]; - $path[] = $host; - } - $path[] = 'v1.0'; - $url = implode('/', $path); - - $curl_ch = curl_init(); - if (!is_null($this->cabundle_path)) { - curl_setopt($curl_ch, CURLOPT_SSL_VERIFYPEER, true); - curl_setopt($curl_ch, CURLOPT_CAINFO, $this->cabundle_path); - } - curl_setopt($curl_ch, CURLOPT_VERBOSE, $this->dbug); - curl_setopt($curl_ch, CURLOPT_FOLLOWLOCATION, 1); - curl_setopt($curl_ch, CURLOPT_MAXREDIRS, 4); - curl_setopt($curl_ch, CURLOPT_HEADER, 0); - curl_setopt($curl_ch, CURLOPT_HTTPHEADER, $headers); - curl_setopt($curl_ch, CURLOPT_USERAGENT, USER_AGENT); - curl_setopt($curl_ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($curl_ch, CURLOPT_HEADERFUNCTION, [&$this, '_auth_hdr_cb']); - curl_setopt($curl_ch, CURLOPT_CONNECTTIMEOUT, 10); - curl_setopt($curl_ch, CURLOPT_URL, $url); - curl_exec($curl_ch); - curl_close($curl_ch); - - return [$this->response_status, $this->response_reason, - $this->storage_url, $this->cdnm_url, $this->auth_token, ]; - } - - // (CDN) GET /v1/Account - - public function list_cdn_containers($enabled_only) - { - $conn_type = 'GET_CALL'; - $url_path = $this->_make_path('CDN'); - - $this->_write_callback_type = 'TEXT_LIST'; - if ($enabled_only) { - $return_code = $this->_send_request($conn_type, $url_path. - '/?enabled_only=true'); - } else { - $return_code = $this->_send_request($conn_type, $url_path); - } - if (!$return_code) { - $this->error_str .= ': Failed to obtain valid HTTP response.'; - [0, $this->error_str, []]; - } - if ($return_code == 401) { - return [$return_code, 'Unauthorized', []]; - } - if ($return_code == 404) { - return [$return_code, 'Account not found.', []]; - } - if ($return_code == 204) { - return [$return_code, 'Account has no CDN enabled Containers.', - [], ]; - } - if ($return_code == 200) { - $this->create_array(); - - return [$return_code, $this->response_reason, $this->_text_list]; - } - $this->error_str = 'Unexpected HTTP response: '.$this->response_reason; - - return [$return_code, $this->error_str, []]; - } - - // (CDN) DELETE /v1/Account/Container or /v1/Account/Container/Object - - public function purge_from_cdn($path, $email = null) - { - if (!$path) { - throw new SyntaxException('Path not set'); - } - $url_path = $this->_make_path('CDN', null, $path); - if ($email) { - $hdrs = [CDN_EMAIL => $email]; - $return_code = $this->_send_request('DEL_POST', $url_path, $hdrs, 'DELETE'); - } else { - $return_code = $this->_send_request('DEL_POST', $url_path, null, 'DELETE'); - } - - return $return_code; - } - - // (CDN) POST /v1/Account/Container - public function update_cdn_container($container_name, $ttl, $cdn_log_retention, - $cdn_acl_user_agent, $cdn_acl_referrer) - { - if ($container_name == '') { - throw new SyntaxException('Container name not set.'); - } - - if ($container_name != '0' and !isset($container_name)) { - throw new SyntaxException('Container name not set.'); - } - - $url_path = $this->_make_path('CDN', $container_name); - $hdrs = [ - CDN_ENABLED => 'True', - CDN_TTL => $ttl, - CDN_LOG_RETENTION => $cdn_log_retention ? 'True' : 'False', - CDN_ACL_USER_AGENT => $cdn_acl_user_agent, - CDN_ACL_REFERRER => $cdn_acl_referrer, - ]; - $return_code = $this->_send_request('DEL_POST', $url_path, $hdrs, 'POST'); - if ($return_code == 401) { - $this->error_str = 'Unauthorized'; - - return [$return_code, $this->error_str, null]; - } - if ($return_code == 404) { - $this->error_str = 'Container not found.'; - - return [$return_code, $this->error_str, null]; - } - if ($return_code != 202) { - $this->error_str = 'Unexpected HTTP response: '.$this->response_reason; - - return [$return_code, $this->error_str, null]; - } - - return [$return_code, 'Accepted', $this->_cdn_uri]; - } - - // (CDN) PUT /v1/Account/Container - - public function add_cdn_container($container_name, $ttl = 86400) - { - if ($container_name == '') { - throw new SyntaxException('Container name not set.'); - } - - if ($container_name != '0' and !isset($container_name)) { - throw new SyntaxException('Container name not set.'); - } - - $url_path = $this->_make_path('CDN', $container_name); - $hdrs = [ - CDN_ENABLED => 'True', - CDN_TTL => $ttl, - ]; - $return_code = $this->_send_request('PUT_CONT', $url_path, $hdrs); - if ($return_code == 401) { - $this->error_str = 'Unauthorized'; - - return [$return_code, $this->response_reason, false]; - } - if (!in_array($return_code, [201, 202])) { - $this->error_str = 'Unexpected HTTP response: '.$this->response_reason; - - return [$return_code, $this->response_reason, false]; - } - - return [$return_code, $this->response_reason, $this->_cdn_uri]; - } - - // (CDN) POST /v1/Account/Container - - public function remove_cdn_container($container_name) - { - if ($container_name == '') { - throw new SyntaxException('Container name not set.'); - } - - if ($container_name != '0' and !isset($container_name)) { - throw new SyntaxException('Container name not set.'); - } - - $url_path = $this->_make_path('CDN', $container_name); - $hdrs = [CDN_ENABLED => 'False']; - $return_code = $this->_send_request('DEL_POST', $url_path, $hdrs, 'POST'); - if ($return_code == 401) { - $this->error_str = 'Unauthorized'; - - return [$return_code, $this->error_str]; - } - if ($return_code == 404) { - $this->error_str = 'Container not found.'; - - return [$return_code, $this->error_str]; - } - if ($return_code != 202) { - $this->error_str = 'Unexpected HTTP response: '.$this->response_reason; - - return [$return_code, $this->error_str]; - } - - return [$return_code, 'Accepted']; - } - - // (CDN) HEAD /v1/Account - - public function head_cdn_container($container_name) - { - if ($container_name == '') { - throw new SyntaxException('Container name not set.'); - } - - if ($container_name != '0' and !isset($container_name)) { - throw new SyntaxException('Container name not set.'); - } - - $conn_type = 'HEAD'; - $url_path = $this->_make_path('CDN', $container_name); - $return_code = $this->_send_request($conn_type, $url_path, null, 'GET', true); - - if (!$return_code) { - $this->error_str .= ': Failed to obtain valid HTTP response.'; - - return [0, $this->error_str, null, null, null, null, null, null]; - } - if ($return_code == 401) { - return [$return_code, 'Unauthorized', null, null, null, null, null, null]; - } - if ($return_code == 404) { - return [$return_code, 'Account not found.', null, null, null, null, null, null]; - } - if ($return_code == 204) { - return [$return_code, $this->response_reason, - $this->_cdn_enabled, $this->_cdn_uri, $this->_cdn_ttl, - $this->_cdn_log_retention, - $this->_cdn_acl_user_agent, - $this->_cdn_acl_referrer, - ]; - } - - return [$return_code, $this->response_reason, - null, null, null, - $this->_cdn_log_retention, - $this->_cdn_acl_user_agent, - $this->_cdn_acl_referrer, - ]; - } - - // GET /v1/Account - - public function list_containers($limit = 0, $marker = null) - { - $conn_type = 'GET_CALL'; - $url_path = $this->_make_path(); - - $limit = intval($limit); - $params = []; - if ($limit > 0) { - $params[] = "limit=$limit"; - } - if ($marker) { - $params[] = 'marker='.rawurlencode($marker); - } - if (!empty($params)) { - $url_path .= '?'.implode('&', $params); - } - - $this->_write_callback_type = 'TEXT_LIST'; - $return_code = $this->_send_request($conn_type, $url_path); - - if (!$return_code) { - $this->error_str .= ': Failed to obtain valid HTTP response.'; - - return [0, $this->error_str, []]; - } - if ($return_code == 204) { - return [$return_code, 'Account has no containers.', []]; - } - if ($return_code == 404) { - $this->error_str = 'Invalid account name for authentication token.'; - - return [$return_code, $this->error_str, []]; - } - if ($return_code == 200) { - $this->create_array(); - - return [$return_code, $this->response_reason, $this->_text_list]; - } - $this->error_str = 'Unexpected HTTP response: '.$this->response_reason; - - return [$return_code, $this->error_str, []]; - } - - // GET /v1/Account?format=json - - public function list_containers_info($limit = 0, $marker = null) - { - $conn_type = 'GET_CALL'; - $url_path = $this->_make_path().'?format=json'; - - $limit = intval($limit); - $params = []; - if ($limit > 0) { - $params[] = "limit=$limit"; - } - if ($marker) { - $params[] = 'marker='.rawurlencode($marker); - } - if (!empty($params)) { - $url_path .= '&'.implode('&', $params); - } - - $this->_write_callback_type = 'OBJECT_STRING'; - $return_code = $this->_send_request($conn_type, $url_path); - - if (!$return_code) { - $this->error_str .= ': Failed to obtain valid HTTP response.'; - - return [0, $this->error_str, []]; - } - if ($return_code == 204) { - return [$return_code, 'Account has no containers.', []]; - } - if ($return_code == 404) { - $this->error_str = 'Invalid account name for authentication token.'; - - return [$return_code, $this->error_str, []]; - } - if ($return_code == 200) { - $json_body = json_decode($this->_obj_write_string, true); - - return [$return_code, $this->response_reason, $json_body]; - } - $this->error_str = 'Unexpected HTTP response: '.$this->response_reason; - - return [$return_code, $this->error_str, []]; - } - - // HEAD /v1/Account - - public function head_account() - { - $conn_type = 'HEAD'; - - $url_path = $this->_make_path(); - $return_code = $this->_send_request($conn_type, $url_path); - - if (!$return_code) { - $this->error_str .= ': Failed to obtain valid HTTP response.'; - [0, $this->error_str, 0, 0]; - } - if ($return_code == 404) { - return [$return_code, 'Account not found.', 0, 0]; - } - if ($return_code == 204) { - return [$return_code, $this->response_reason, - $this->_account_container_count, $this->_account_bytes_used, ]; - } - - return [$return_code, $this->response_reason, 0, 0]; - } - - // PUT /v1/Account/Container - - public function create_container($container_name) - { - if ($container_name == '') { - throw new SyntaxException('Container name not set.'); - } - - if ($container_name != '0' and !isset($container_name)) { - throw new SyntaxException('Container name not set.'); - } - - $url_path = $this->_make_path('STORAGE', $container_name); - $return_code = $this->_send_request('PUT_CONT', $url_path); - - if (!$return_code) { - $this->error_str .= ': Failed to obtain valid HTTP response.'; - - return false; - } - - return $return_code; - } - - // DELETE /v1/Account/Container - - public function delete_container($container_name) - { - if ($container_name == '') { - throw new SyntaxException('Container name not set.'); - } - - if ($container_name != '0' and !isset($container_name)) { - throw new SyntaxException('Container name not set.'); - } - - $url_path = $this->_make_path('STORAGE', $container_name); - $return_code = $this->_send_request('DEL_POST', $url_path, [], 'DELETE'); - - if (!$return_code) { - $this->error_str .= ': Failed to obtain valid HTTP response.'; - } - if ($return_code == 409) { - $this->error_str = 'Container must be empty prior to removing it.'; - } - if ($return_code == 404) { - $this->error_str = 'Specified container did not exist to delete.'; - } - if ($return_code != 204) { - $this->error_str = "Unexpected HTTP return code: $return_code."; - } - - return $return_code; - } - - // GET /v1/Account/Container - - public function list_objects($cname, $limit = 0, $marker = null, $prefix = null, $path = null) - { - if (!$cname) { - $this->error_str = 'Container name not set.'; - - return [0, $this->error_str, []]; - } - - $url_path = $this->_make_path('STORAGE', $cname); - - $limit = intval($limit); - $params = []; - if ($limit > 0) { - $params[] = "limit=$limit"; - } - if ($marker) { - $params[] = 'marker='.rawurlencode($marker); - } - if ($prefix) { - $params[] = 'prefix='.rawurlencode($prefix); - } - if ($path) { - $params[] = 'path='.rawurlencode($path); - } - if (!empty($params)) { - $url_path .= '?'.implode('&', $params); - } - - $conn_type = 'GET_CALL'; - $this->_write_callback_type = 'TEXT_LIST'; - $return_code = $this->_send_request($conn_type, $url_path); - - if (!$return_code) { - $this->error_str .= ': Failed to obtain valid HTTP response.'; - - return [0, $this->error_str, []]; - } - if ($return_code == 204) { - $this->error_str = 'Container has no Objects.'; - - return [$return_code, $this->error_str, []]; - } - if ($return_code == 404) { - $this->error_str = 'Container has no Objects.'; - - return [$return_code, $this->error_str, []]; - } - if ($return_code == 200) { - $this->create_array(); - - return [$return_code, $this->response_reason, $this->_text_list]; - } - $this->error_str = "Unexpected HTTP response code: $return_code"; - - return [0, $this->error_str, []]; - } - - // GET /v1/Account/Container?format=json - - public function get_objects($cname, $limit = 0, $marker = null, $prefix = null, $path = null) - { - if (!$cname) { - $this->error_str = 'Container name not set.'; - - return [0, $this->error_str, []]; - } - - $url_path = $this->_make_path('STORAGE', $cname); - - $limit = intval($limit); - $params = []; - $params[] = 'format=json'; - if ($limit > 0) { - $params[] = "limit=$limit"; - } - if ($marker) { - $params[] = 'marker='.rawurlencode($marker); - } - if ($prefix) { - $params[] = 'prefix='.rawurlencode($prefix); - } - if ($path) { - $params[] = 'path='.rawurlencode($path); - } - if (!empty($params)) { - $url_path .= '?'.implode('&', $params); - } - - $conn_type = 'GET_CALL'; - $this->_write_callback_type = 'OBJECT_STRING'; - $return_code = $this->_send_request($conn_type, $url_path); - - if (!$return_code) { - $this->error_str .= ': Failed to obtain valid HTTP response.'; - - return [0, $this->error_str, []]; - } - if ($return_code == 204) { - $this->error_str = 'Container has no Objects.'; - - return [$return_code, $this->error_str, []]; - } - if ($return_code == 404) { - $this->error_str = 'Container has no Objects.'; - - return [$return_code, $this->error_str, []]; - } - if ($return_code == 200) { - $json_body = json_decode($this->_obj_write_string, true); - - return [$return_code, $this->response_reason, $json_body]; - } - $this->error_str = "Unexpected HTTP response code: $return_code"; - - return [0, $this->error_str, []]; - } - - // HEAD /v1/Account/Container - - public function head_container($container_name) - { - if ($container_name == '') { - $this->error_str = 'Container name not set.'; - - return false; - } - - if ($container_name != '0' and !isset($container_name)) { - $this->error_str = 'Container name not set.'; - - return false; - } - - $conn_type = 'HEAD'; - - $url_path = $this->_make_path('STORAGE', $container_name); - $return_code = $this->_send_request($conn_type, $url_path); - - if (!$return_code) { - $this->error_str .= ': Failed to obtain valid HTTP response.'; - [0, $this->error_str, 0, 0]; - } - if ($return_code == 404) { - return [$return_code, 'Container not found.', 0, 0]; - } - if ($return_code == 204 || $return_code == 200) { - return [$return_code, $this->response_reason, - $this->_container_object_count, $this->_container_bytes_used, ]; - } - - return [$return_code, $this->response_reason, 0, 0]; - } - - // GET /v1/Account/Container/Object - - public function get_object_to_string(&$obj, $hdrs = []) - { - if (!is_object($obj) || get_class($obj) != 'CF_Object') { - throw new SyntaxException( - 'Method argument is not a valid CF_Object.'); - } - - $conn_type = 'GET_CALL'; - - $url_path = $this->_make_path('STORAGE', $obj->container->name, $obj->name); - $this->_write_callback_type = 'OBJECT_STRING'; - $return_code = $this->_send_request($conn_type, $url_path, $hdrs); - - if (!$return_code) { - $this->error_str .= ': Failed to obtain valid HTTP response.'; - - return [$return_code0, $this->error_str, null]; - } - if ($return_code == 404) { - $this->error_str = 'Object not found.'; - - return [$return_code0, $this->error_str, null]; - } - if (($return_code < 200) || ($return_code > 299 - && $return_code != 412 && $return_code != 304)) { - $this->error_str = "Unexpected HTTP return code: $return_code"; - - return [$return_code, $this->error_str, null]; - } - - return [$return_code, $this->response_reason, $this->_obj_write_string]; - } - - // GET /v1/Account/Container/Object - - public function get_object_to_stream(&$obj, &$resource = null, $hdrs = []) - { - if (!is_object($obj) || get_class($obj) != 'CF_Object') { - throw new SyntaxException( - 'Method argument is not a valid CF_Object.'); - } - if (!is_resource($resource)) { - throw new SyntaxException( - 'Resource argument not a valid PHP resource.'); - } - - $conn_type = 'GET_CALL'; - - $url_path = $this->_make_path('STORAGE', $obj->container->name, $obj->name); - $this->_obj_write_resource = $resource; - $this->_write_callback_type = 'OBJECT_STREAM'; - $return_code = $this->_send_request($conn_type, $url_path, $hdrs); - - if (!$return_code) { - $this->error_str .= ': Failed to obtain valid HTTP response.'; - - return [$return_code, $this->error_str]; - } - if ($return_code == 404) { - $this->error_str = 'Object not found.'; - - return [$return_code, $this->error_str]; - } - if (($return_code < 200) || ($return_code > 299 - && $return_code != 412 && $return_code != 304)) { - $this->error_str = "Unexpected HTTP return code: $return_code"; - - return [$return_code, $this->error_str]; - } - - return [$return_code, $this->response_reason]; - } - - // PUT /v1/Account/Container/Object - - public function put_object(&$obj, &$fp) - { - if (!is_object($obj) || get_class($obj) != 'CF_Object') { - throw new SyntaxException( - 'Method argument is not a valid CF_Object.'); - } - if (!is_resource($fp)) { - throw new SyntaxException( - 'File pointer argument is not a valid resource.'); - } - - $conn_type = 'PUT_OBJ'; - $url_path = $this->_make_path('STORAGE', $obj->container->name, $obj->name); - - $hdrs = $this->_metadata_headers($obj); - - $etag = $obj->getETag(); - if (isset($etag)) { - $hdrs[] = 'ETag: '.$etag; - } - if (!$obj->content_type) { - $hdrs[] = 'Content-Type: application/octet-stream'; - } else { - $hdrs[] = 'Content-Type: '.$obj->content_type; - } - - $this->_init($conn_type); - curl_setopt($this->connections[$conn_type], - CURLOPT_INFILE, $fp); - if (!$obj->content_length) { - // We don''t know the Content-Length, so assumed "chunked" PUT - - curl_setopt($this->connections[$conn_type], CURLOPT_UPLOAD, true); - $hdrs[] = 'Transfer-Encoding: chunked'; - } else { - // We know the Content-Length, so use regular transfer - - curl_setopt($this->connections[$conn_type], - CURLOPT_INFILESIZE, $obj->content_length); - } - $return_code = $this->_send_request($conn_type, $url_path, $hdrs); - - if (!$return_code) { - $this->error_str .= ': Failed to obtain valid HTTP response.'; - - return [0, $this->error_str, null]; - } - if ($return_code == 412) { - $this->error_str = 'Missing Content-Type header'; - - return [$return_code, $this->error_str, null]; - } - if ($return_code == 422) { - $this->error_str = 'Derived and computed checksums do not match.'; - - return [$return_code, $this->error_str, null]; - } - if ($return_code != 201) { - $this->error_str = "Unexpected HTTP return code: $return_code"; - - return [$return_code, $this->error_str, null]; - } - - return [$return_code, $this->response_reason, $this->_obj_etag]; - } - - // POST /v1/Account/Container/Object - - public function update_object(&$obj) - { - if (!is_object($obj) || get_class($obj) != 'CF_Object') { - throw new SyntaxException( - 'Method argument is not a valid CF_Object.'); - } - - if (!is_array($obj->metadata) || empty($obj->metadata)) { - $this->error_str = 'Metadata array is empty.'; - - return 0; - } - - $url_path = $this->_make_path('STORAGE', $obj->container->name, $obj->name); - - $hdrs = $this->_metadata_headers($obj); - $return_code = $this->_send_request('DEL_POST', $url_path, $hdrs, 'POST'); - if (!$return_code) { - $this->error_str .= ': Failed to obtain valid HTTP response.'; - - return 0; - } - if ($return_code == 404) { - $this->error_str = 'Account, Container, or Object not found.'; - } - if ($return_code != 202) { - $this->error_str = "Unexpected HTTP return code: $return_code"; - } - - return $return_code; - } - - // HEAD /v1/Account/Container/Object - - public function head_object(&$obj) - { - if (!is_object($obj) || get_class($obj) != 'CF_Object') { - throw new SyntaxException( - 'Method argument is not a valid CF_Object.'); - } - - $conn_type = 'HEAD'; - - $url_path = $this->_make_path('STORAGE', $obj->container->name, $obj->name); - $return_code = $this->_send_request($conn_type, $url_path); - - if (!$return_code) { - $this->error_str .= ': Failed to obtain valid HTTP response.'; - - return [0, $this->error_str.' '.$this->response_reason, - null, null, null, null, [], ]; - } - - if ($return_code == 404) { - return [$return_code, $this->response_reason, - null, null, null, null, [], ]; - } - if ($return_code == 204 || $return_code == 200) { - return [$return_code, $this->response_reason, - $this->_obj_etag, - $this->_obj_last_modified, - $this->_obj_content_type, - $this->_obj_content_length, - $this->_obj_metadata, ]; - } - $this->error_str = "Unexpected HTTP return code: $return_code"; - - return [$return_code, $this->error_str.' '.$this->response_reason, - null, null, null, null, [], ]; - } - - // DELETE /v1/Account/Container/Object - - public function delete_object($container_name, $object_name) - { - if ($container_name == '') { - $this->error_str = 'Container name not set.'; - - return 0; - } - - if ($container_name != '0' and !isset($container_name)) { - $this->error_str = 'Container name not set.'; - - return 0; - } - - if (!$object_name) { - $this->error_str = 'Object name not set.'; - - return 0; - } - - $url_path = $this->_make_path('STORAGE', $container_name, $object_name); - $return_code = $this->_send_request('DEL_POST', $url_path, null, 'DELETE'); - if (!$return_code) { - $this->error_str .= ': Failed to obtain valid HTTP response.'; - - return 0; - } - if ($return_code == 404) { - $this->error_str = 'Specified container did not exist to delete.'; - } - if ($return_code != 204) { - $this->error_str = "Unexpected HTTP return code: $return_code."; - } - - return $return_code; - } - - public function get_error() - { - return $this->error_str; - } - - public function setDebug($bool) - { - $this->dbug = $bool; - foreach ($this->connections as $k => $v) { - if (!is_null($v)) { - curl_setopt($this->connections[$k], CURLOPT_VERBOSE, $this->dbug); - } - } - } - - public function getCDNMUrl() - { - return $this->cdnm_url; - } - - public function getStorageUrl() - { - return $this->storage_url; - } - - public function getAuthToken() - { - return $this->auth_token; - } - - public function setCFAuth($cfs_auth, $servicenet = false) - { - if ($servicenet) { - $this->storage_url = 'https://snet-'.substr($cfs_auth->storage_url, 8); - } else { - $this->storage_url = $cfs_auth->storage_url; - } - $this->auth_token = $cfs_auth->auth_token; - $this->cdnm_url = $cfs_auth->cdnm_url; - } - - public function setReadProgressFunc($func_name) - { - $this->_user_read_progress_callback_func = $func_name; - } - - public function setWriteProgressFunc($func_name) - { - $this->_user_write_progress_callback_func = $func_name; - } - - private function _header_cb($ch, $header) - { - preg_match("/^HTTP\/1\.[01] (\d{3}) (.*)/", $header, $matches); - if (isset($matches[1])) { - $this->response_status = $matches[1]; - } - if (isset($matches[2])) { - $this->response_reason = $matches[2]; - } - if (stripos($header, CDN_ENABLED) === 0) { - $val = trim(substr($header, strlen(CDN_ENABLED) + 1)); - if (strtolower($val) == 'true') { - $this->_cdn_enabled = true; - } elseif (strtolower($val) == 'false') { - $this->_cdn_enabled = false; - } else { - $this->_cdn_enabled = null; - } - - return strlen($header); - } - if (stripos($header, CDN_URI) === 0) { - $this->_cdn_uri = trim(substr($header, strlen(CDN_URI) + 1)); - - return strlen($header); - } - if (stripos($header, CDN_TTL) === 0) { - $this->_cdn_ttl = trim(substr($header, strlen(CDN_TTL) + 1)) + 0; - - return strlen($header); - } - if (stripos($header, CDN_LOG_RETENTION) === 0) { - $this->_cdn_log_retention = - trim(substr($header, strlen(CDN_LOG_RETENTION) + 1)) == 'True' ? true : false; - - return strlen($header); - } - - if (stripos($header, CDN_ACL_USER_AGENT) === 0) { - $this->_cdn_acl_user_agent = - trim(substr($header, strlen(CDN_ACL_USER_AGENT) + 1)); - - return strlen($header); - } - - if (stripos($header, CDN_ACL_REFERRER) === 0) { - $this->_cdn_acl_referrer = - trim(substr($header, strlen(CDN_ACL_REFERRER) + 1)); - - return strlen($header); - } - - if (stripos($header, ACCOUNT_CONTAINER_COUNT) === 0) { - $this->_account_container_count = (float) trim(substr($header, - strlen(ACCOUNT_CONTAINER_COUNT) + 1)) + 0; - - return strlen($header); - } - if (stripos($header, ACCOUNT_BYTES_USED) === 0) { - $this->_account_bytes_used = (float) trim(substr($header, - strlen(ACCOUNT_BYTES_USED) + 1)) + 0; - - return strlen($header); - } - if (stripos($header, CONTAINER_OBJ_COUNT) === 0) { - $this->_container_object_count = (float) trim(substr($header, - strlen(CONTAINER_OBJ_COUNT) + 1)) + 0; - - return strlen($header); - } - if (stripos($header, CONTAINER_BYTES_USED) === 0) { - $this->_container_bytes_used = (float) trim(substr($header, - strlen(CONTAINER_BYTES_USED) + 1)) + 0; - - return strlen($header); - } - if (stripos($header, METADATA_HEADER) === 0) { - // $header => X-Object-Meta-Foo: bar baz - $temp = substr($header, strlen(METADATA_HEADER)); - // $temp => Foo: bar baz - $parts = explode(':', $temp); - // $parts[0] => Foo - $val = substr(strstr($temp, ':'), 1); - // $val => bar baz - $this->_obj_metadata[$parts[0]] = trim($val); - - return strlen($header); - } - if (stripos($header, 'ETag:') === 0) { - // $header => ETag: abc123def456... - $val = substr(strstr($header, ':'), 1); - // $val => abc123def456... - $this->_obj_etag = trim($val); - - return strlen($header); - } - if (stripos($header, 'Last-Modified:') === 0) { - $val = substr(strstr($header, ':'), 1); - $this->_obj_last_modified = trim($val); - - return strlen($header); - } - if (stripos($header, 'Content-Type:') === 0) { - $val = substr(strstr($header, ':'), 1); - $this->_obj_content_type = trim($val); - - return strlen($header); - } - if (stripos($header, 'Content-Length:') === 0) { - $val = substr(strstr($header, ':'), 1); - $this->_obj_content_length = (float) trim($val) + 0; - - return strlen($header); - } - - return strlen($header); - } - - private function _read_cb($ch, $fd, $length) - { - $data = fread($fd, $length); - $len = strlen($data); - if (isset($this->_user_write_progress_callback_func)) { - call_user_func($this->_user_write_progress_callback_func, $len); - } - - return $data; - } - - private function _write_cb($ch, $data) - { - $dlen = strlen($data); - switch ($this->_write_callback_type) { - case 'TEXT_LIST': - $this->_return_list = $this->_return_list.$data; - //= explode("\n",$data); # keep tab,space - //his->_text_list[] = rtrim($data,"\n\r\x0B"); # keep tab,space - break; - case 'OBJECT_STREAM': - fwrite($this->_obj_write_resource, $data, $dlen); - break; - case 'OBJECT_STRING': - $this->_obj_write_string .= $data; - break; - } - if (isset($this->_user_read_progress_callback_func)) { - call_user_func($this->_user_read_progress_callback_func, $dlen); - } - - return $dlen; - } - - private function _auth_hdr_cb($ch, $header) - { - preg_match("/^HTTP\/1\.[01] (\d{3}) (.*)/", $header, $matches); - if (isset($matches[1])) { - $this->response_status = $matches[1]; - } - if (isset($matches[2])) { - $this->response_reason = $matches[2]; - } - if (stripos($header, STORAGE_URL) === 0) { - $this->storage_url = trim(substr($header, strlen(STORAGE_URL) + 1)); - } - if (stripos($header, CDNM_URL) === 0) { - $this->cdnm_url = trim(substr($header, strlen(CDNM_URL) + 1)); - } - if (stripos($header, AUTH_TOKEN) === 0) { - $this->auth_token = trim(substr($header, strlen(AUTH_TOKEN) + 1)); - } - if (stripos($header, AUTH_TOKEN_LEGACY) === 0) { - $this->auth_token = trim(substr($header, strlen(AUTH_TOKEN_LEGACY) + 1)); - } - - return strlen($header); - } - - private function _make_headers($hdrs = null) - { - $new_headers = []; - $has_stoken = false; - $has_uagent = false; - if (is_array($hdrs)) { - foreach ($hdrs as $h => $v) { - if (is_int($h)) { - $parts = explode(':', $v); - $header = $parts[0]; - $value = trim(substr(strstr($v, ':'), 1)); - } else { - $header = $h; - $value = trim($v); - } - - if (stripos($header, AUTH_TOKEN) === 0) { - $has_stoken = true; - } - if (stripos($header, 'user-agent') === 0) { - $has_uagent = true; - } - $new_headers[] = $header.': '.$value; - } - } - if (!$has_stoken) { - $new_headers[] = AUTH_TOKEN.': '.$this->auth_token; - } - if (!$has_uagent) { - $new_headers[] = 'User-Agent: '.USER_AGENT; - } - - return $new_headers; - } - - private function _init($conn_type, $force_new = false) - { - if (!array_key_exists($conn_type, $this->connections)) { - $this->error_str = 'Invalid CURL_XXX connection type'; - - return false; - } - - if (is_null($this->connections[$conn_type]) || $force_new) { - $ch = curl_init(); - } else { - return; - } - - if ($this->dbug) { - curl_setopt($ch, CURLOPT_VERBOSE, 1); - } - - if (!is_null($this->cabundle_path)) { - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); - curl_setopt($ch, CURLOPT_CAINFO, $this->cabundle_path); - } - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); - curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); - curl_setopt($ch, CURLOPT_MAXREDIRS, 4); - curl_setopt($ch, CURLOPT_HEADER, 0); - curl_setopt($ch, CURLOPT_HEADERFUNCTION, [&$this, '_header_cb']); - - if ($conn_type == 'GET_CALL') { - curl_setopt($ch, CURLOPT_WRITEFUNCTION, [&$this, '_write_cb']); - } - - if ($conn_type == 'PUT_OBJ') { - curl_setopt($ch, CURLOPT_PUT, 1); - curl_setopt($ch, CURLOPT_READFUNCTION, [&$this, '_read_cb']); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); - } - if ($conn_type == 'HEAD') { - curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'HEAD'); - curl_setopt($ch, CURLOPT_NOBODY, 1); - } - if ($conn_type == 'PUT_CONT') { - curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT'); - curl_setopt($ch, CURLOPT_INFILESIZE, 0); - curl_setopt($ch, CURLOPT_NOBODY, 1); - } - if ($conn_type == 'DEL_POST') { - curl_setopt($ch, CURLOPT_NOBODY, 1); - } - $this->connections[$conn_type] = $ch; - - return; - } - - private function _reset_callback_vars() - { - $this->_text_list = []; - $this->_return_list = null; - $this->_account_container_count = 0; - $this->_account_bytes_used = 0; - $this->_container_object_count = 0; - $this->_container_bytes_used = 0; - $this->_obj_etag = null; - $this->_obj_last_modified = null; - $this->_obj_content_type = null; - $this->_obj_content_length = null; - $this->_obj_metadata = []; - $this->_obj_write_string = ''; - $this->_cdn_enabled = null; - $this->_cdn_uri = null; - $this->_cdn_ttl = null; - $this->response_status = 0; - $this->response_reason = ''; - } - - private function _make_path($t = 'STORAGE', $c = null, $o = null) - { - $path = []; - switch ($t) { - case 'STORAGE': - $path[] = $this->storage_url; break; - case 'CDN': - $path[] = $this->cdnm_url; break; - } - if ($c == '0') { - $path[] = rawurlencode($c); - } - - if ($c) { - $path[] = rawurlencode($c); - } - if ($o) { - // mimic Python''s urllib.quote() feature of a "safe" '/' character - - $path[] = str_replace('%2F', '/', rawurlencode($o)); - } - - return implode('/', $path); - } - - private function _metadata_headers(&$obj) - { - $hdrs = []; - foreach ($obj->metadata as $k => $v) { - if (strpos($k, ':') !== false) { - throw new SyntaxException( - "Metadata keys cannot contain a ':' character."); - } - $k = trim($k); - $key = sprintf('%s%s', METADATA_HEADER, $k); - if (!array_key_exists($key, $hdrs)) { - if (strlen($k) > 128 || strlen($v) > 256) { - $this->error_str = 'Metadata key or value exceeds '; - $this->error_str .= "maximum length: ($k: $v)"; - - return 0; - } - $hdrs[] = sprintf('%s%s: %s', METADATA_HEADER, $k, trim($v)); - } - } - - return $hdrs; - } - - private function _send_request($conn_type, $url_path, $hdrs = null, $method = 'GET', $force_new = false) - { - $this->_init($conn_type, $force_new); - $this->_reset_callback_vars(); - $headers = $this->_make_headers($hdrs); - - if (gettype($this->connections[$conn_type]) == 'unknown type') { - throw new ConnectionNotOpenException( - 'Connection is not open.' - ); - } - - switch ($method) { - case 'DELETE': - curl_setopt($this->connections[$conn_type], - CURLOPT_CUSTOMREQUEST, 'DELETE'); - break; - case 'POST': - curl_setopt($this->connections[$conn_type], - CURLOPT_CUSTOMREQUEST, 'POST'); - default: - break; - } - - curl_setopt($this->connections[$conn_type], - CURLOPT_HTTPHEADER, $headers); - - curl_setopt($this->connections[$conn_type], - CURLOPT_URL, $url_path); - - if (!curl_exec($this->connections[$conn_type]) && curl_errno($this->connections[$conn_type]) !== 0) { - $this->error_str = '(curl error: ' - .curl_errno($this->connections[$conn_type]).') '; - $this->error_str .= curl_error($this->connections[$conn_type]); - - return false; - } - - return curl_getinfo($this->connections[$conn_type], CURLINFO_HTTP_CODE); - } - - public function close() - { - foreach ($this->connections as $cnx) { - if (isset($cnx)) { - curl_close($cnx); - $this->connections[$cnx] = null; - } - } - } - - private function create_array() - { - $this->_text_list = explode("\n", rtrim($this->_return_list, "\n\x0B")); - - return true; - } -} - -/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * c-hanging-comment-ender-p: nil - * End: - */
app/bundles/CoreBundle/Assets/js/libraries/ckeditor/filemanager/connectors/php/plugins/rsc/cloudfiles.php+0 −2322 removed@@ -1,2322 +0,0 @@ -<?php -/** - * This is the PHP Cloud Files API. - * - * <code> - * # Authenticate to Cloud Files. The default is to automatically try - * # to re-authenticate if an authentication token expires. - * # - * # NOTE: Some versions of cURL include an outdated certificate authority (CA) - * # file. This API ships with a newer version obtained directly from - * # cURL's web site (http://curl.haxx.se). To use the newer CA bundle, - * # call the CF_Authentication instance's 'ssl_use_cabundle()' method. - * # - * $auth = new CF_Authentication($username, $api_key); - * # $auth->ssl_use_cabundle(); # bypass cURL's old CA bundle - * $auth->authenticate(); - * - * # Establish a connection to the storage system - * # - * # NOTE: Some versions of cURL include an outdated certificate authority (CA) - * # file. This API ships with a newer version obtained directly from - * # cURL's web site (http://curl.haxx.se). To use the newer CA bundle, - * # call the CF_Connection instance's 'ssl_use_cabundle()' method. - * # - * $conn = new CF_Connection($auth); - * # $conn->ssl_use_cabundle(); # bypass cURL's old CA bundle - * - * # Create a remote Container and storage Object - * # - * $images = $conn->create_container("photos"); - * $bday = $images->create_object("first_birthday.jpg"); - * - * # Upload content from a local file by streaming it. Note that we use - * # a "float" for the file size to overcome PHP's 32-bit integer limit for - * # very large files. - * # - * $fname = "/home/user/photos/birthdays/birthday1.jpg"; # filename to upload - * $size = (float) sprintf("%u", filesize($fname)); - * $fp = open($fname, "r"); - * $bday->write($fp, $size); - * - * # Or... use a convenience function instead - * # - * $bday->load_from_filename("/home/user/photos/birthdays/birthday1.jpg"); - * - * # Now, publish the "photos" container to serve the images by CDN. - * # Use the "$uri" value to put in your web pages or send the link in an - * # email message, etc. - * # - * $uri = $images->make_public(); - * - * # Or... print out the Object's public URI - * # - * print $bday->public_uri(); - * </code> - * - * See the included tests directory for additional sample code. - * - * Requres PHP 5.x (for Exceptions and OO syntax) and PHP's cURL module. - * - * It uses the supporting "cloudfiles_http.php" module for HTTP(s) support and - * allows for connection re-use and streaming of content into/out of Cloud Files - * via PHP's cURL module. - * - * See COPYING for license information. - * - * @author Eric "EJ" Johnson <ej@racklabs.com> - * @copyright Copyright (c) 2008, Rackspace US, Inc - */ -require_once 'cloudfiles_exceptions.php'; -require 'cloudfiles_http.php'; -define('DEFAULT_CF_API_VERSION', 1); -define('MAX_CONTAINER_NAME_LEN', 256); -define('MAX_OBJECT_NAME_LEN', 1024); -define('MAX_OBJECT_SIZE', 5 * 1024 * 1024 * 1024 + 1); -define('US_AUTHURL', 'https://auth.api.rackspacecloud.com'); -define('UK_AUTHURL', 'https://lon.auth.api.rackspacecloud.com'); -/** - * Class for handling Cloud Files Authentication, call it's {@link authenticate()} - * method to obtain authorized service urls and an authentication token. - * - * Example: - * <code> - * # Create the authentication instance - * # - * $auth = new CF_Authentication("username", "api_key"); - * - * # NOTE: For UK Customers please specify your AuthURL Manually - * # There is a Predfined constant to use EX: - * # - * # $auth = new CF_Authentication("username, "api_key", NULL, UK_AUTHURL); - * # Using the UK_AUTHURL keyword will force the api to use the UK AuthUrl. - * # rather then the US one. The NULL Is passed for legacy purposes and must - * # be passed to function correctly. - * - * # NOTE: Some versions of cURL include an outdated certificate authority (CA) - * # file. This API ships with a newer version obtained directly from - * # cURL's web site (http://curl.haxx.se). To use the newer CA bundle, - * # call the CF_Authentication instance's 'ssl_use_cabundle()' method. - * # - * # $auth->ssl_use_cabundle(); # bypass cURL's old CA bundle - * - * # Perform authentication request - * # - * $auth->authenticate(); - * </code> - */ -class CF_Authentication -{ - public $dbug; - public $username; - public $api_key; - public $auth_host; - public $account; - - /** - * Instance variables that are set after successful authentication. - */ - public $storage_url; - public $cdnm_url; - public $auth_token; - - /** - * Class constructor (PHP 5 syntax). - * - * @param string $username Mosso username - * @param string $api_key Mosso API Access Key - * @param string $account <i>Account name</i> - * @param string $auth_host <i>Authentication service URI</i> - */ - public function __construct($username = null, $api_key = null, $account = null, $auth_host = US_AUTHURL) - { - $this->dbug = false; - $this->username = $username; - $this->api_key = $api_key; - $this->account_name = $account; - $this->auth_host = $auth_host; - - $this->storage_url = null; - $this->cdnm_url = null; - $this->auth_token = null; - - $this->cfs_http = new CF_Http(DEFAULT_CF_API_VERSION); - } - - /** - * Use the Certificate Authority bundle included with this API. - * - * Most versions of PHP with cURL support include an outdated Certificate - * Authority (CA) bundle (the file that lists all valid certificate - * signing authorities). The SSL certificates used by the Cloud Files - * storage system are perfectly valid but have been created/signed by - * a CA not listed in these outdated cURL distributions. - * - * As a work-around, we've included an updated CA bundle obtained - * directly from cURL's web site (http://curl.haxx.se). You can direct - * the API to use this CA bundle by calling this method prior to making - * any remote calls. The best place to use this method is right after - * the CF_Authentication instance has been instantiated. - * - * You can specify your own CA bundle by passing in the full pathname - * to the bundle. You can use the included CA bundle by leaving the - * argument blank. - * - * @param string $path Specify path to CA bundle (default to included) - */ - public function ssl_use_cabundle($path = null) - { - $this->cfs_http->ssl_use_cabundle($path); - } - - /** - * Attempt to validate Username/API Access Key. - * - * Attempts to validate credentials with the authentication service. It - * either returns <kbd>True</kbd> or throws an Exception. Accepts a single - * (optional) argument for the storage system API version. - * - * Example: - * <code> - * # Create the authentication instance - * # - * $auth = new CF_Authentication("username", "api_key"); - * - * # Perform authentication request - * # - * $auth->authenticate(); - * </code> - * - * @param string $version API version for Auth service (optional) - * - * @return bool <kbd>True</kbd> if successfully authenticated - * - * @throws AuthenticationException invalid credentials - * @throws InvalidResponseException invalid response - */ - public function authenticate($version = DEFAULT_CF_API_VERSION) - { - list($status, $reason, $surl, $curl, $atoken) = - $this->cfs_http->authenticate($this->username, $this->api_key, - $this->account_name, $this->auth_host); - - if ($status == 401) { - throw new AuthenticationException('Invalid username or access key.'); - } - if ($status != 204) { - throw new InvalidResponseException( - 'Unexpected response ('.$status.'): '.$reason); - } - - if (!($surl || $curl) || !$atoken) { - throw new InvalidResponseException( - 'Expected headers missing from auth service.'); - } - $this->storage_url = $surl; - $this->cdnm_url = $curl; - $this->auth_token = $atoken; - - return true; - } - - /** - * Use Cached Token and Storage URL's rather then grabbing from the Auth System. - * - * Example: - * <code> - * #Create an Auth instance - * $auth = new CF_Authentication(); - * #Pass Cached URL's and Token as Args - * $auth->load_cached_credentials("auth_token", "storage_url", "cdn_management_url"); - * </code> - * - * @param string $auth_token A Cloud Files Auth Token (Required) - * @param string $storage_url The Cloud Files Storage URL (Required) - * @param string $cdnm_url CDN Management URL (Required) - * - * @return bool <kbd>True</kbd> if successful - * - * @throws SyntaxException If any of the Required Arguments are missing - */ - public function load_cached_credentials($auth_token, $storage_url, $cdnm_url) - { - if (!$storage_url || !$cdnm_url) { - throw new SyntaxException("Missing Required Interface URL's!"); - } - if (!$auth_token) { - throw new SyntaxException('Missing Auth Token!'); - } - - $this->storage_url = $storage_url; - $this->cdnm_url = $cdnm_url; - $this->auth_token = $auth_token; - - return true; - } - - /** - * Grab Cloud Files info to be Cached for later use with the load_cached_credentials method. - * - * Example: - * <code> - * #Create an Auth instance - * $auth = new CF_Authentication("UserName","API_Key"); - * $auth->authenticate(); - * $array = $auth->export_credentials(); - * </code> - * - * @return array of url's and an auth token - */ - public function export_credentials() - { - $arr = []; - $arr['storage_url'] = $this->storage_url; - $arr['cdnm_url'] = $this->cdnm_url; - $arr['auth_token'] = $this->auth_token; - - return $arr; - } - - /** - * Make sure the CF_Authentication instance has authenticated. - * - * Ensures that the instance variables necessary to communicate with - * Cloud Files have been set from a previous authenticate() call. - * - * @return bool <kbd>True</kbd> if successfully authenticated - */ - public function authenticated() - { - if (!($this->storage_url || $this->cdnm_url) || !$this->auth_token) { - return false; - } - - return true; - } - - /** - * Toggle debugging - set cURL verbose flag. - */ - public function setDebug($bool) - { - $this->dbug = $bool; - $this->cfs_http->setDebug($bool); - } -} - -/** - * Class for establishing connections to the Cloud Files storage system. - * Connection instances are used to communicate with the storage system at - * the account level; listing and deleting Containers and returning Container - * instances. - * - * Example: - * <code> - * # Create the authentication instance - * # - * $auth = new CF_Authentication("username", "api_key"); - * - * # Perform authentication request - * # - * $auth->authenticate(); - * - * # Create a connection to the storage/cdn system(s) and pass in the - * # validated CF_Authentication instance. - * # - * $conn = new CF_Connection($auth); - * - * # NOTE: Some versions of cURL include an outdated certificate authority (CA) - * # file. This API ships with a newer version obtained directly from - * # cURL's web site (http://curl.haxx.se). To use the newer CA bundle, - * # call the CF_Authentication instance's 'ssl_use_cabundle()' method. - * # - * # $conn->ssl_use_cabundle(); # bypass cURL's old CA bundle - * </code> - */ -class CF_Connection -{ - public $dbug; - public $cfs_http; - public $cfs_auth; - - /** - * Pass in a previously authenticated CF_Authentication instance. - * - * Example: - * <code> - * # Create the authentication instance - * # - * $auth = new CF_Authentication("username", "api_key"); - * - * # Perform authentication request - * # - * $auth->authenticate(); - * - * # Create a connection to the storage/cdn system(s) and pass in the - * # validated CF_Authentication instance. - * # - * $conn = new CF_Connection($auth); - * - * # If you are connecting via Rackspace servers and have access - * # to the servicenet network you can set the $servicenet to True - * # like this. - * - * $conn = new CF_Connection($auth, $servicenet=True); - * - * </code> - * - * If the environement variable RACKSPACE_SERVICENET is defined it will - * force to connect via the servicenet. - * - * @param obj $cfs_auth previously authenticated CF_Authentication instance - * @param bool $servicenet enable/disable access via Rackspace servicenet - * - * @throws AuthenticationException not authenticated - */ - public function __construct($cfs_auth, $servicenet = false) - { - if (isset($_ENV['RACKSPACE_SERVICENET'])) { - $servicenet = true; - } - $this->cfs_http = new CF_Http(DEFAULT_CF_API_VERSION); - $this->cfs_auth = $cfs_auth; - if (!$this->cfs_auth->authenticated()) { - $e = 'Need to pass in a previously authenticated '; - $e .= 'CF_Authentication instance.'; - throw new AuthenticationException($e); - } - $this->cfs_http->setCFAuth($this->cfs_auth, $servicenet = $servicenet); - $this->dbug = false; - } - - /** - * Toggle debugging of instance and back-end HTTP module. - * - * @param bool $bool enable/disable cURL debugging - */ - public function setDebug($bool) - { - $this->dbug = (bool) $bool; - $this->cfs_http->setDebug($this->dbug); - } - - /** - * Close a connection. - * - * Example: - * <code> - * - * $conn->close(); - * - * </code> - * - * Will close all current cUrl active connections. - */ - public function close() - { - $this->cfs_http->close(); - } - - /** - * Cloud Files account information. - * - * Return an array of two floats (since PHP only supports 32-bit integers); - * number of containers on the account and total bytes used for the account. - * - * Example: - * <code> - * # ... authentication code excluded (see previous examples) ... - * # - * $conn = new CF_Authentication($auth); - * - * list($quantity, $bytes) = $conn->get_info(); - * print "Number of containers: " . $quantity . "\n"; - * print "Bytes stored in container: " . $bytes . "\n"; - * </code> - * - * @return array (number of containers, total bytes stored) - * - * @throws InvalidResponseException unexpected response - */ - public function get_info() - { - list($status, $reason, $container_count, $total_bytes) = - $this->cfs_http->head_account(); - //if ($status == 401 && $this->_re_auth()) { - // return $this->get_info(); - //} - if ($status < 200 || $status > 299) { - throw new InvalidResponseException( - 'Invalid response ('.$status.'): '.$this->cfs_http->get_error()); - } - - return [$container_count, $total_bytes]; - } - - /** - * Create a Container. - * - * Given a Container name, return a Container instance, creating a new - * remote Container if it does not exit. - * - * Example: - * <code> - * # ... authentication code excluded (see previous examples) ... - * # - * $conn = new CF_Authentication($auth); - * - * $images = $conn->create_container("my photos"); - * </code> - * - * @param string $container_name container name - * - * @return CF_Container - * - * @throws SyntaxException invalid name - * @throws InvalidResponseException unexpected response - */ - public function create_container($container_name = null) - { - if ($container_name != '0' and !isset($container_name)) { - throw new SyntaxException('Container name not set.'); - } - - if (!isset($container_name) or $container_name == '') { - throw new SyntaxException('Container name not set.'); - } - - if (strpos($container_name, '/') !== false) { - $r = "Container name '".$container_name; - $r .= "' cannot contain a '/' character."; - throw new SyntaxException($r); - } - if (strlen($container_name) > MAX_CONTAINER_NAME_LEN) { - throw new SyntaxException(sprintf( - 'Container name exeeds %d bytes.', - MAX_CONTAINER_NAME_LEN)); - } - - $return_code = $this->cfs_http->create_container($container_name); - if (!$return_code) { - throw new InvalidResponseException('Invalid response (' - .$return_code.'): '.$this->cfs_http->get_error()); - } - //if ($status == 401 && $this->_re_auth()) { - // return $this->create_container($container_name); - //} - if ($return_code != 201 && $return_code != 202) { - throw new InvalidResponseException( - 'Invalid response ('.$return_code.'): ' - .$this->cfs_http->get_error()); - } - - return new CF_Container($this->cfs_auth, $this->cfs_http, $container_name); - } - - /** - * Delete a Container. - * - * Given either a Container instance or name, remove the remote Container. - * The Container must be empty prior to removing it. - * - * Example: - * <code> - * # ... authentication code excluded (see previous examples) ... - * # - * $conn = new CF_Authentication($auth); - * - * $conn->delete_container("my photos"); - * </code> - * - * @param string|obj $container container name or instance - * - * @return bool <kbd>True</kbd> if successfully deleted - * - * @throws SyntaxException missing proper argument - * @throws InvalidResponseException invalid response - * @throws NonEmptyContainerException container not empty - * @throws NoSuchContainerException remote container does not exist - */ - public function delete_container($container = null) - { - $container_name = null; - - if (is_object($container)) { - if (get_class($container) == 'CF_Container') { - $container_name = $container->name; - } - } - if (is_string($container)) { - $container_name = $container; - } - - if ($container_name != '0' and !isset($container_name)) { - throw new SyntaxException('Must specify container object or name.'); - } - - $return_code = $this->cfs_http->delete_container($container_name); - - if (!$return_code) { - throw new InvalidResponseException('Failed to obtain http response'); - } - //if ($status == 401 && $this->_re_auth()) { - // return $this->delete_container($container); - //} - if ($return_code == 409) { - throw new NonEmptyContainerException( - 'Container must be empty prior to removing it.'); - } - if ($return_code == 404) { - throw new NoSuchContainerException( - 'Specified container did not exist to delete.'); - } - if ($return_code != 204) { - throw new InvalidResponseException( - 'Invalid response ('.$return_code.'): ' - .$this->cfs_http->get_error()); - } - - return true; - } - - /** - * Return a Container instance. - * - * For the given name, return a Container instance if the remote Container - * exists, otherwise throw a Not Found exception. - * - * Example: - * <code> - * # ... authentication code excluded (see previous examples) ... - * # - * $conn = new CF_Authentication($auth); - * - * $images = $conn->get_container("my photos"); - * print "Number of Objects: " . $images->count . "\n"; - * print "Bytes stored in container: " . $images->bytes . "\n"; - * </code> - * - * @param string $container_name name of the remote Container - * - * @return container CF_Container instance - * - * @throws NoSuchContainerException thrown if no remote Container - * @throws InvalidResponseException unexpected response - */ - public function get_container($container_name = null) - { - list($status, $reason, $count, $bytes) = - $this->cfs_http->head_container($container_name); - //if ($status == 401 && $this->_re_auth()) { - // return $this->get_container($container_name); - //} - if ($status == 404) { - throw new NoSuchContainerException('Container not found.'); - } - if ($status < 200 || $status > 299) { - throw new InvalidResponseException( - 'Invalid response: '.$this->cfs_http->get_error()); - } - - return new CF_Container($this->cfs_auth, $this->cfs_http, - $container_name, $count, $bytes); - } - - /** - * Return array of Container instances. - * - * Return an array of CF_Container instances on the account. The instances - * will be fully populated with Container attributes (bytes stored and - * Object count) - * - * Example: - * <code> - * # ... authentication code excluded (see previous examples) ... - * # - * $conn = new CF_Authentication($auth); - * - * $clist = $conn->get_containers(); - * foreach ($clist as $cont) { - * print "Container name: " . $cont->name . "\n"; - * print "Number of Objects: " . $cont->count . "\n"; - * print "Bytes stored in container: " . $cont->bytes . "\n"; - * } - * </code> - * - * @return array An array of CF_Container instances - * - * @throws InvalidResponseException unexpected response - */ - public function get_containers($limit = 0, $marker = null) - { - list($status, $reason, $container_info) = - $this->cfs_http->list_containers_info($limit, $marker); - //if ($status == 401 && $this->_re_auth()) { - // return $this->get_containers(); - //} - if ($status < 200 || $status > 299) { - throw new InvalidResponseException( - 'Invalid response: '.$this->cfs_http->get_error()); - } - $containers = []; - foreach ($container_info as $name => $info) { - $containers[] = new CF_Container($this->cfs_auth, $this->cfs_http, - $info['name'], $info['count'], $info['bytes'], false); - } - - return $containers; - } - - /** - * Return list of remote Containers. - * - * Return an array of strings containing the names of all remote Containers. - * - * Example: - * <code> - * # ... authentication code excluded (see previous examples) ... - * # - * $conn = new CF_Authentication($auth); - * - * $container_list = $conn->list_containers(); - * print_r($container_list); - * Array - * ( - * [0] => "my photos", - * [1] => "my docs" - * ) - * </code> - * - * @param int $limit restrict results to $limit Containers - * @param string $marker return results greater than $marker - * - * @return array list of remote Containers - * - * @throws InvalidResponseException unexpected response - */ - public function list_containers($limit = 0, $marker = null) - { - list($status, $reason, $containers) = - $this->cfs_http->list_containers($limit, $marker); - //if ($status == 401 && $this->_re_auth()) { - // return $this->list_containers($limit, $marker); - //} - if ($status < 200 || $status > 299) { - throw new InvalidResponseException( - 'Invalid response ('.$status.'): '.$this->cfs_http->get_error()); - } - - return $containers; - } - - /** - * Return array of information about remote Containers. - * - * Return a nested array structure of Container info. - * - * Example: - * <code> - * # ... authentication code excluded (see previous examples) ... - * # - * - * $container_info = $conn->list_containers_info(); - * print_r($container_info); - * Array - * ( - * ["my photos"] => - * Array - * ( - * ["bytes"] => 78, - * ["count"] => 2 - * ) - * ["docs"] => - * Array - * ( - * ["bytes"] => 37323, - * ["count"] => 12 - * ) - * ) - * </code> - * - * @param int $limit restrict results to $limit Containers - * @param string $marker return results greater than $marker - * - * @return array nested array structure of Container info - * - * @throws InvalidResponseException unexpected response - */ - public function list_containers_info($limit = 0, $marker = null) - { - list($status, $reason, $container_info) = - $this->cfs_http->list_containers_info($limit, $marker); - //if ($status == 401 && $this->_re_auth()) { - // return $this->list_containers_info($limit, $marker); - //} - if ($status < 200 || $status > 299) { - throw new InvalidResponseException( - 'Invalid response ('.$status.'): '.$this->cfs_http->get_error()); - } - - return $container_info; - } - - /** - * Return list of Containers that have been published to the CDN. - * - * Return an array of strings containing the names of published Containers. - * Note that this function returns the list of any Container that has - * ever been CDN-enabled regardless of it's existence in the storage - * system. - * - * Example: - * <code> - * # ... authentication code excluded (see previous examples) ... - * # - * $conn = new CF_Authentication($auth); - * - * $public_containers = $conn->list_public_containers(); - * print_r($public_containers); - * Array - * ( - * [0] => "images", - * [1] => "css", - * [2] => "javascript" - * ) - * </code> - * - * @param bool $enabled_only Will list all containers ever CDN enabled if * set to false or only currently enabled CDN containers if set to true. * Defaults to false - * - * @return array list of published Container names - * - * @throws InvalidResponseException unexpected response - */ - public function list_public_containers($enabled_only = false) - { - list($status, $reason, $containers) = - $this->cfs_http->list_cdn_containers($enabled_only); - //if ($status == 401 && $this->_re_auth()) { - // return $this->list_public_containers(); - //} - if ($status < 200 || $status > 299) { - throw new InvalidResponseException( - 'Invalid response ('.$status.'): '.$this->cfs_http->get_error()); - } - - return $containers; - } - - /** - * Set a user-supplied callback function to report download progress. - * - * The callback function is used to report incremental progress of a data - * download functions (e.g. $container->list_objects(), $obj->read(), etc). - * The specified function will be periodically called with the number of - * bytes transferred until the entire download is complete. This callback - * function can be useful for implementing "progress bars" for large - * downloads. - * - * The specified callback function should take a single integer parameter. - * - * <code> - * function read_callback($bytes_transferred) { - * print ">> downloaded " . $bytes_transferred . " bytes.\n"; - * # ... do other things ... - * return; - * } - * - * $conn = new CF_Connection($auth_obj); - * $conn->set_read_progress_function("read_callback"); - * print_r($conn->list_containers()); - * - * # output would look like this: - * # - * >> downloaded 10 bytes. - * >> downloaded 11 bytes. - * Array - * ( - * [0] => fuzzy.txt - * [1] => space name - * ) - * </code> - * - * @param string $func_name the name of the user callback function - */ - public function set_read_progress_function($func_name) - { - $this->cfs_http->setReadProgressFunc($func_name); - } - - /** - * Set a user-supplied callback function to report upload progress. - * - * The callback function is used to report incremental progress of a data - * upload functions (e.g. $obj->write() call). The specified function will - * be periodically called with the number of bytes transferred until the - * entire upload is complete. This callback function can be useful - * for implementing "progress bars" for large uploads/downloads. - * - * The specified callback function should take a single integer parameter. - * - * <code> - * function write_callback($bytes_transferred) { - * print ">> uploaded " . $bytes_transferred . " bytes.\n"; - * # ... do other things ... - * return; - * } - * - * $conn = new CF_Connection($auth_obj); - * $conn->set_write_progress_function("write_callback"); - * $container = $conn->create_container("stuff"); - * $obj = $container->create_object("foo"); - * $obj->write("The callback function will be called during upload."); - * - * # output would look like this: - * # >> uploaded 51 bytes. - * # - * </code> - * - * @param string $func_name the name of the user callback function - */ - public function set_write_progress_function($func_name) - { - $this->cfs_http->setWriteProgressFunc($func_name); - } - - /** - * Use the Certificate Authority bundle included with this API. - * - * Most versions of PHP with cURL support include an outdated Certificate - * Authority (CA) bundle (the file that lists all valid certificate - * signing authorities). The SSL certificates used by the Cloud Files - * storage system are perfectly valid but have been created/signed by - * a CA not listed in these outdated cURL distributions. - * - * As a work-around, we've included an updated CA bundle obtained - * directly from cURL's web site (http://curl.haxx.se). You can direct - * the API to use this CA bundle by calling this method prior to making - * any remote calls. The best place to use this method is right after - * the CF_Authentication instance has been instantiated. - * - * You can specify your own CA bundle by passing in the full pathname - * to the bundle. You can use the included CA bundle by leaving the - * argument blank. - * - * @param string $path Specify path to CA bundle (default to included) - */ - public function ssl_use_cabundle($path = null) - { - $this->cfs_http->ssl_use_cabundle($path); - } - - //private function _re_auth() - //{ - // $new_auth = new CF_Authentication( - // $this->cfs_auth->username, - // $this->cfs_auth->api_key, - // $this->cfs_auth->auth_host, - // $this->cfs_auth->account); - // $new_auth->authenticate(); - // $this->cfs_auth = $new_auth; - // $this->cfs_http->setCFAuth($this->cfs_auth); - // return True; - //} -} - -/** - * Container operations. - * - * Containers are storage compartments where you put your data (objects). - * A container is similar to a directory or folder on a conventional filesystem - * with the exception that they exist in a flat namespace, you can not create - * containers inside of containers. - * - * You also have the option of marking a Container as "public" so that the - * Objects stored in the Container are publicly available via the CDN. - */ -class CF_Container -{ - public $cfs_auth; - public $cfs_http; - public $name; - public $object_count; - public $bytes_used; - - public $cdn_enabled; - public $cdn_uri; - public $cdn_ttl; - public $cdn_log_retention; - public $cdn_acl_user_agent; - public $cdn_acl_referrer; - - /** - * Class constructor. - * - * Constructor for Container - * - * @param obj $cfs_auth CF_Authentication instance - * @param obj $cfs_http HTTP connection manager - * @param string $name name of Container - * @param int $count number of Objects stored in this Container - * @param int $bytes number of bytes stored in this Container - * - * @throws SyntaxException invalid Container name - */ - public function __construct(&$cfs_auth, &$cfs_http, $name, $count = 0, - $bytes = 0, $docdn = true) - { - if (strlen($name) > MAX_CONTAINER_NAME_LEN) { - throw new SyntaxException('Container name exceeds ' - .'maximum allowed length.'); - } - if (strpos($name, '/') !== false) { - throw new SyntaxException( - "Container names cannot contain a '/' character."); - } - $this->cfs_auth = $cfs_auth; - $this->cfs_http = $cfs_http; - $this->name = $name; - $this->object_count = $count; - $this->bytes_used = $bytes; - $this->cdn_enabled = null; - $this->cdn_uri = null; - $this->cdn_ttl = null; - $this->cdn_log_retention = null; - $this->cdn_acl_user_agent = null; - $this->cdn_acl_referrer = null; - if ($this->cfs_http->getCDNMUrl() != null && $docdn) { - $this->_cdn_initialize(); - } - } - - /** - * String representation of Container. - * - * Pretty print the Container instance. - * - * @return string Container details - */ - public function __toString() - { - $me = sprintf('name: %s, count: %.0f, bytes: %.0f', - $this->name, $this->object_count, $this->bytes_used); - if ($this->cfs_http->getCDNMUrl() != null) { - $me .= sprintf(', cdn: %s, cdn uri: %s, cdn ttl: %.0f, logs retention: %s', - $this->is_public() ? 'Yes' : 'No', - $this->cdn_uri, $this->cdn_ttl, - $this->cdn_log_retention ? 'Yes' : 'No' - ); - - if ($this->cdn_acl_user_agent != null) { - $me .= ', cdn acl user agent: '.$this->cdn_acl_user_agent; - } - - if ($this->cdn_acl_referrer != null) { - $me .= ', cdn acl referrer: '.$this->cdn_acl_referrer; - } - } - - return $me; - } - - /** - * Enable Container content to be served via CDN or modify CDN attributes. - * - * Either enable this Container's content to be served via CDN or - * adjust its CDN attributes. This Container will always return the - * same CDN-enabled URI each time it is toggled public/private/public. - * - * Example: - * <code> - * # ... authentication code excluded (see previous examples) ... - * # - * $conn = new CF_Authentication($auth); - * - * $public_container = $conn->create_container("public"); - * - * # CDN-enable the container and set it's TTL for a month - * # - * $public_container->make_public(86400/2); # 12 hours (86400 seconds/day) - * </code> - * - * @param int $ttl the time in seconds content will be cached in the CDN - * @returns string the CDN enabled Container's URI - * - * @throws CDNNotEnabledException CDN functionality not returned during auth - * @throws AuthenticationException if auth token is not valid/expired - * @throws InvalidResponseException unexpected response - */ - public function make_public($ttl = 86400) - { - if ($this->cfs_http->getCDNMUrl() == null) { - throw new CDNNotEnabledException( - 'Authentication response did not indicate CDN availability'); - } - if ($this->cdn_uri != null) { - // previously published, assume we're setting new attributes - list($status, $reason, $cdn_uri) = - $this->cfs_http->update_cdn_container($this->name, $ttl, - $this->cdn_log_retention, - $this->cdn_acl_user_agent, - $this->cdn_acl_referrer); - //if ($status == 401 && $this->_re_auth()) { - // return $this->make_public($ttl); - //} - if ($status == 404) { - // this instance _thinks_ the container was published, but the - // cdn management system thinks otherwise - try again with a PUT - list($status, $reason, $cdn_uri) = - $this->cfs_http->add_cdn_container($this->name, $ttl); - } - } else { - // publish it for first time - list($status, $reason, $cdn_uri) = - $this->cfs_http->add_cdn_container($this->name, $ttl); - } - //if ($status == 401 && $this->_re_auth()) { - // return $this->make_public($ttl); - //} - if (!in_array($status, [201, 202])) { - throw new InvalidResponseException( - 'Invalid response ('.$status.'): '.$this->cfs_http->get_error()); - } - $this->cdn_enabled = true; - $this->cdn_ttl = $ttl; - $this->cdn_uri = $cdn_uri; - $this->cdn_log_retention = false; - $this->cdn_acl_user_agent = ''; - $this->cdn_acl_referrer = ''; - - return $this->cdn_uri; - } - - /** - * Purge Containers objects from CDN Cache. - * Example: - * <code> - * # ... authentication code excluded (see previous examples) ... - * # - * $conn = new CF_Authentication($auth); - * $container = $conn->get_container("cdn_enabled"); - * $container->purge_from_cdn("user@domain.com"); - * # or - * $container->purge_from_cdn(); - * # or - * $container->purge_from_cdn("user1@domain.com,user2@domain.com");. - * - * @returns boolean True if successful - * - * @throws CDNNotEnabledException if CDN Is not enabled on this connection - * @throws InvalidResponseException if the response expected is not returned - */ - public function purge_from_cdn($email = null) - { - if (!$this->cfs_http->getCDNMUrl()) { - throw new CDNNotEnabledException( - 'Authentication response did not indicate CDN availability'); - } - $status = $this->cfs_http->purge_from_cdn($this->name, $email); - if ($status < 199 or $status > 299) { - throw new InvalidResponseException( - 'Invalid response ('.$status.'): '.$this->cfs_http->get_error()); - } - - return true; - } - - /** - * Enable ACL restriction by User Agent for this container. - * - * Example: - * <code> - * # ... authentication code excluded (see previous examples) ... - * # - * $conn = new CF_Authentication($auth); - * - * $public_container = $conn->get_container("public"); - * - * # Enable ACL by Referrer - * $public_container->acl_referrer("Mozilla"); - * </code> - * - * @returns boolean True if successful - * - * @throws CDNNotEnabledException CDN functionality not returned during auth - * @throws AuthenticationException if auth token is not valid/expired - * @throws InvalidResponseException unexpected response - */ - public function acl_user_agent($cdn_acl_user_agent = '') - { - if ($this->cfs_http->getCDNMUrl() == null) { - throw new CDNNotEnabledException( - 'Authentication response did not indicate CDN availability'); - } - list($status, $reason) = - $this->cfs_http->update_cdn_container($this->name, - $this->cdn_ttl, - $this->cdn_log_retention, - $cdn_acl_user_agent, - $this->cdn_acl_referrer - ); - if (!in_array($status, [202, 404])) { - throw new InvalidResponseException( - 'Invalid response ('.$status.'): '.$this->cfs_http->get_error()); - } - $this->cdn_acl_user_agent = $cdn_acl_user_agent; - - return true; - } - - /** - * Enable ACL restriction by referer for this container. - * - * Example: - * <code> - * # ... authentication code excluded (see previous examples) ... - * # - * $conn = new CF_Authentication($auth); - * - * $public_container = $conn->get_container("public"); - * - * # Enable Referrer - * $public_container->acl_referrer("http://www.example.com/gallery.php"); - * </code> - * - * @returns boolean True if successful - * - * @throws CDNNotEnabledException CDN functionality not returned during auth - * @throws AuthenticationException if auth token is not valid/expired - * @throws InvalidResponseException unexpected response - */ - public function acl_referrer($cdn_acl_referrer = '') - { - if ($this->cfs_http->getCDNMUrl() == null) { - throw new CDNNotEnabledException( - 'Authentication response did not indicate CDN availability'); - } - list($status, $reason) = - $this->cfs_http->update_cdn_container($this->name, - $this->cdn_ttl, - $this->cdn_log_retention, - $this->cdn_acl_user_agent, - $cdn_acl_referrer - ); - if (!in_array($status, [202, 404])) { - throw new InvalidResponseException( - 'Invalid response ('.$status.'): '.$this->cfs_http->get_error()); - } - $this->cdn_acl_referrer = $cdn_acl_referrer; - - return true; - } - - /** - * Enable log retention for this CDN container. - * - * Enable CDN log retention on the container. If enabled logs will - * be periodically (at unpredictable intervals) compressed and - * uploaded to a ".CDN_ACCESS_LOGS" container in the form of - * "container_name.YYYYMMDDHH-XXXX.gz". Requires CDN be enabled on - * the account. - * - * Example: - * <code> - * # ... authentication code excluded (see previous examples) ... - * # - * $conn = new CF_Authentication($auth); - * - * $public_container = $conn->get_container("public"); - * - * # Enable logs retention. - * $public_container->log_retention(True); - * </code> - * - * @returns boolean True if successful - * - * @throws CDNNotEnabledException CDN functionality not returned during auth - * @throws AuthenticationException if auth token is not valid/expired - * @throws InvalidResponseException unexpected response - */ - public function log_retention($cdn_log_retention = false) - { - if ($this->cfs_http->getCDNMUrl() == null) { - throw new CDNNotEnabledException( - 'Authentication response did not indicate CDN availability'); - } - list($status, $reason) = - $this->cfs_http->update_cdn_container($this->name, - $this->cdn_ttl, - $cdn_log_retention, - $this->cdn_acl_user_agent, - $this->cdn_acl_referrer - ); - if (!in_array($status, [202, 404])) { - throw new InvalidResponseException( - 'Invalid response ('.$status.'): '.$this->cfs_http->get_error()); - } - $this->cdn_log_retention = $cdn_log_retention; - - return true; - } - - /** - * Disable the CDN sharing for this container. - * - * Use this method to disallow distribution into the CDN of this Container's - * content. - * - * NOTE: Any content already cached in the CDN will continue to be served - * from its cache until the TTL expiration transpires. The default - * TTL is typically one day, so "privatizing" the Container will take - * up to 24 hours before the content is purged from the CDN cache. - * - * Example: - * <code> - * # ... authentication code excluded (see previous examples) ... - * # - * $conn = new CF_Authentication($auth); - * - * $public_container = $conn->get_container("public"); - * - * # Disable CDN accessability - * # ... still cached up to a month based on previous example - * # - * $public_container->make_private(); - * </code> - * - * @returns boolean True if successful - * - * @throws CDNNotEnabledException CDN functionality not returned during auth - * @throws AuthenticationException if auth token is not valid/expired - * @throws InvalidResponseException unexpected response - */ - public function make_private() - { - if ($this->cfs_http->getCDNMUrl() == null) { - throw new CDNNotEnabledException( - 'Authentication response did not indicate CDN availability'); - } - list($status, $reason) = $this->cfs_http->remove_cdn_container($this->name); - //if ($status == 401 && $this->_re_auth()) { - // return $this->make_private(); - //} - if (!in_array($status, [202, 404])) { - throw new InvalidResponseException( - 'Invalid response ('.$status.'): '.$this->cfs_http->get_error()); - } - $this->cdn_enabled = false; - $this->cdn_ttl = null; - $this->cdn_uri = null; - $this->cdn_log_retention = null; - $this->cdn_acl_user_agent = null; - $this->cdn_acl_referrer = null; - - return true; - } - - /** - * Check if this Container is being publicly served via CDN. - * - * Use this method to determine if the Container's content is currently - * available through the CDN. - * - * Example: - * <code> - * # ... authentication code excluded (see previous examples) ... - * # - * $conn = new CF_Authentication($auth); - * - * $public_container = $conn->get_container("public"); - * - * # Display CDN accessability - * # - * $public_container->is_public() ? print "Yes" : print "No"; - * </code> - * - * @returns boolean True if enabled, False otherwise - */ - public function is_public() - { - return $this->cdn_enabled == true ? true : false; - } - - /** - * Create a new remote storage Object. - * - * Return a new Object instance. If the remote storage Object exists, - * the instance's attributes are populated. - * - * Example: - * <code> - * # ... authentication code excluded (see previous examples) ... - * # - * $conn = new CF_Authentication($auth); - * - * $public_container = $conn->get_container("public"); - * - * # This creates a local instance of a storage object but only creates - * # it in the storage system when the object's write() method is called. - * # - * $pic = $public_container->create_object("baby.jpg"); - * </code> - * - * @param string $obj_name name of storage Object - * - * @return obj CF_Object instance - */ - public function create_object($obj_name = null) - { - return new CF_Object($this, $obj_name); - } - - /** - * Return an Object instance for the remote storage Object. - * - * Given a name, return a Object instance representing the - * remote storage object. - * - * Example: - * <code> - * # ... authentication code excluded (see previous examples) ... - * # - * $conn = new CF_Authentication($auth); - * - * $public_container = $conn->get_container("public"); - * - * # This call only fetches header information and not the content of - * # the storage object. Use the Object's read() or stream() methods - * # to obtain the object's data. - * # - * $pic = $public_container->get_object("baby.jpg"); - * </code> - * - * @param string $obj_name name of storage Object - * - * @return obj CF_Object instance - */ - public function get_object($obj_name = null) - { - return new CF_Object($this, $obj_name, true); - } - - /** - * Return a list of Objects. - * - * Return an array of strings listing the Object names in this Container. - * - * Example: - * <code> - * # ... authentication code excluded (see previous examples) ... - * # - * $images = $conn->get_container("my photos"); - * - * # Grab the list of all storage objects - * # - * $all_objects = $images->list_objects(); - * - * # Grab subsets of all storage objects - * # - * $first_ten = $images->list_objects(10); - * - * # Note the use of the previous result's last object name being - * # used as the 'marker' parameter to fetch the next 10 objects - * # - * $next_ten = $images->list_objects(10, $first_ten[count($first_ten)-1]); - * - * # Grab images starting with "birthday_party" and default limit/marker - * # to match all photos with that prefix - * # - * $prefixed = $images->list_objects(0, NULL, "birthday"); - * - * # Assuming you have created the appropriate directory marker Objects, - * # you can traverse your pseudo-hierarchical containers - * # with the "path" argument. - * # - * $animals = $images->list_objects(0,NULL,NULL,"pictures/animals"); - * $dogs = $images->list_objects(0,NULL,NULL,"pictures/animals/dogs"); - * </code> - * - * @param int $limit <i>optional</i> only return $limit names - * @param int $marker <i>optional</i> subset of names starting at $marker - * @param string $prefix <i>optional</i> Objects whose names begin with $prefix - * @param string $path <i>optional</i> only return results under "pathname" - * - * @return array array of strings - * - * @throws InvalidResponseException unexpected response - */ - public function list_objects($limit = 0, $marker = null, $prefix = null, $path = null) - { - list($status, $reason, $obj_list) = - $this->cfs_http->list_objects($this->name, $limit, - $marker, $prefix, $path); - //if ($status == 401 && $this->_re_auth()) { - // return $this->list_objects($limit, $marker, $prefix, $path); - //} - if ($status < 200 || $status > 299) { - throw new InvalidResponseException( - 'Invalid response ('.$status.'): '.$this->cfs_http->get_error()); - } - - return $obj_list; - } - - /** - * Return an array of Objects. - * - * Return an array of Object instances in this Container. - * - * Example: - * <code> - * # ... authentication code excluded (see previous examples) ... - * # - * $images = $conn->get_container("my photos"); - * - * # Grab the list of all storage objects - * # - * $all_objects = $images->get_objects(); - * - * # Grab subsets of all storage objects - * # - * $first_ten = $images->get_objects(10); - * - * # Note the use of the previous result's last object name being - * # used as the 'marker' parameter to fetch the next 10 objects - * # - * $next_ten = $images->list_objects(10, $first_ten[count($first_ten)-1]); - * - * # Grab images starting with "birthday_party" and default limit/marker - * # to match all photos with that prefix - * # - * $prefixed = $images->get_objects(0, NULL, "birthday"); - * - * # Assuming you have created the appropriate directory marker Objects, - * # you can traverse your pseudo-hierarchical containers - * # with the "path" argument. - * # - * $animals = $images->get_objects(0,NULL,NULL,"pictures/animals"); - * $dogs = $images->get_objects(0,NULL,NULL,"pictures/animals/dogs"); - * </code> - * - * @param int $limit <i>optional</i> only return $limit names - * @param int $marker <i>optional</i> subset of names starting at $marker - * @param string $prefix <i>optional</i> Objects whose names begin with $prefix - * @param string $path <i>optional</i> only return results under "pathname" - * - * @return array array of strings - * - * @throws InvalidResponseException unexpected response - */ - public function get_objects($limit = 0, $marker = null, $prefix = null, $path = null) - { - list($status, $reason, $obj_array) = - $this->cfs_http->get_objects($this->name, $limit, - $marker, $prefix, $path); - //if ($status == 401 && $this->_re_auth()) { - // return $this->get_objects($limit, $marker, $prefix, $path); - //} - if ($status < 200 || $status > 299) { - throw new InvalidResponseException( - 'Invalid response ('.$status.'): '.$this->cfs_http->get_error()); - } - $objects = []; - foreach ($obj_array as $obj) { - $tmp = new CF_Object($this, $obj['name'], false, false); - $tmp->content_type = $obj['content_type']; - $tmp->content_length = (float) $obj['bytes']; - $tmp->set_etag($obj['hash']); - $tmp->last_modified = $obj['last_modified']; - $objects[] = $tmp; - } - - return $objects; - } - - /** - * Delete a remote storage Object. - * - * Given an Object instance or name, permanently remove the remote Object - * and all associated metadata. - * - * Example: - * <code> - * # ... authentication code excluded (see previous examples) ... - * # - * $conn = new CF_Authentication($auth); - * - * $images = $conn->get_container("my photos"); - * - * # Delete specific object - * # - * $images->delete_object("disco_dancing.jpg"); - * </code> - * - * @param obj $obj name or instance of Object to delete - * - * @return bool <kbd>True</kbd> if successfully removed - * - * @throws SyntaxException invalid Object name - * @throws NoSuchObjectException remote Object does not exist - * @throws InvalidResponseException unexpected response - */ - public function delete_object($obj) - { - $obj_name = null; - if (is_object($obj)) { - if (get_class($obj) == 'CF_Object') { - $obj_name = $obj->name; - } - } - if (is_string($obj)) { - $obj_name = $obj; - } - if (!$obj_name) { - throw new SyntaxException('Object name not set.'); - } - $status = $this->cfs_http->delete_object($this->name, $obj_name); - //if ($status == 401 && $this->_re_auth()) { - // return $this->delete_object($obj); - //} - if ($status == 404) { - $m = "Specified object '".$this->name.'/'.$obj_name; - $m .= "' did not exist to delete."; - throw new NoSuchObjectException($m); - } - if ($status != 204) { - throw new InvalidResponseException( - 'Invalid response ('.$status.'): '.$this->cfs_http->get_error()); - } - - return true; - } - - /** - * Helper function to create "path" elements for a given Object name. - * - * Given an Object whos name contains '/' path separators, this function - * will create the "directory marker" Objects of one byte with the - * Content-Type of "application/folder". - * - * It assumes the last element of the full path is the "real" Object - * and does NOT create a remote storage Object for that last element. - */ - public function create_paths($path_name) - { - if ($path_name[0] == '/') { - $path_name = mb_substr($path_name, 0, 1); - } - $elements = explode('/', $path_name, -1); - $build_path = ''; - foreach ($elements as $idx => $val) { - if (!$build_path) { - $build_path = $val; - } else { - $build_path .= '/'.$val; - } - $obj = new CF_Object($this, $build_path); - $obj->content_type = 'application/directory'; - $obj->write('.', 1); - } - } - - /** - * Internal method to grab CDN/Container info if appropriate to do so. - * - * @throws InvalidResponseException unexpected response - */ - private function _cdn_initialize() - { - list($status, $reason, $cdn_enabled, $cdn_uri, $cdn_ttl, - $cdn_log_retention, $cdn_acl_user_agent, $cdn_acl_referrer) = - $this->cfs_http->head_cdn_container($this->name); - //if ($status == 401 && $this->_re_auth()) { - // return $this->_cdn_initialize(); - //} - if (!in_array($status, [204, 404])) { - throw new InvalidResponseException( - 'Invalid response ('.$status.'): '.$this->cfs_http->get_error()); - } - $this->cdn_enabled = $cdn_enabled; - $this->cdn_uri = $cdn_uri; - $this->cdn_ttl = $cdn_ttl; - $this->cdn_log_retention = $cdn_log_retention; - $this->cdn_acl_user_agent = $cdn_acl_user_agent; - $this->cdn_acl_referrer = $cdn_acl_referrer; - } - - //private function _re_auth() - //{ - // $new_auth = new CF_Authentication( - // $this->cfs_auth->username, - // $this->cfs_auth->api_key, - // $this->cfs_auth->auth_host, - // $this->cfs_auth->account); - // $new_auth->authenticate(); - // $this->cfs_auth = $new_auth; - // $this->cfs_http->setCFAuth($this->cfs_auth); - // return True; - //} -} - -/** - * Object operations. - * - * An Object is analogous to a file on a conventional filesystem. You can - * read data from, or write data to your Objects. You can also associate - * arbitrary metadata with them. - */ -class CF_Object -{ - public $container; - public $name; - public $last_modified; - public $content_type; - public $content_length; - public $metadata; - private $etag; - - /** - * Class constructor. - * - * @param obj $container CF_Container instance - * @param string $name name of Object - * @param bool $force_exists if set, throw an error if Object doesn't exist - */ - public function __construct(&$container, $name, $force_exists = false, $dohead = true) - { - if ($name[0] == '/') { - $r = "Object name '".$name; - $r .= "' cannot contain begin with a '/' character."; - throw new SyntaxException($r); - } - if (strlen($name) > MAX_OBJECT_NAME_LEN) { - throw new SyntaxException('Object name exceeds ' - .'maximum allowed length.'); - } - $this->container = $container; - $this->name = $name; - $this->etag = null; - $this->_etag_override = false; - $this->last_modified = null; - $this->content_type = null; - $this->content_length = 0; - $this->metadata = []; - if ($dohead) { - if (!$this->_initialize() && $force_exists) { - throw new NoSuchObjectException("No such object '".$name."'"); - } - } - } - - /** - * String representation of Object. - * - * Pretty print the Object's location and name - * - * @return string Object information - */ - public function __toString() - { - return $this->container->name.'/'.$this->name; - } - - /** - * Internal check to get the proper mimetype. - * - * This function would go over the available PHP methods to get - * the MIME type. - * - * By default it will try to use the PHP fileinfo library which is - * available from PHP 5.3 or as an PECL extension - * (http://pecl.php.net/package/Fileinfo). - * - * It will get the magic file by default from the system wide file - * which is usually available in /usr/share/magic on Unix or try - * to use the file specified in the source directory of the API - * (share directory). - * - * if fileinfo is not available it will try to use the internal - * mime_content_type function. - * - * @param string $handle name of file or buffer to guess the type from - * - * @return bool <kbd>True</kbd> if successful - * - * @throws BadContentTypeException - */ - public function _guess_content_type($handle) - { - if ($this->content_type) { - return true; - } - - if (function_exists('finfo_open')) { - $local_magic = dirname(__FILE__).'/share/magic'; - $finfo = @finfo_open(FILEINFO_MIME, $local_magic); - - if (!$finfo) { - $finfo = @finfo_open(FILEINFO_MIME); - } - - if ($finfo) { - if (is_file((string) $handle)) { - $ct = @finfo_file($finfo, $handle); - } else { - $ct = @finfo_buffer($finfo, $handle); - } - - /* PHP 5.3 fileinfo display extra information like - charset so we remove everything after the ; since - we are not into that stuff */ - if ($ct) { - $extra_content_type_info = strpos($ct, '; '); - if ($extra_content_type_info) { - $ct = substr($ct, 0, $extra_content_type_info); - } - } - - if ($ct && $ct != 'application/octet-stream') { - $this->content_type = $ct; - } - - @finfo_close($finfo); - } - } - - if (!$this->content_type && (string) is_file($handle) && function_exists('mime_content_type')) { - $this->content_type = @mime_content_type($handle); - } - - if (!$this->content_type) { - throw new BadContentTypeException('Required Content-Type not set'); - } - - return true; - } - - /** - * String representation of the Object's public URI. - * - * A string representing the Object's public URI assuming that it's - * parent Container is CDN-enabled. - * - * Example: - * <code> - * # ... authentication/connection/container code excluded - * # ... see previous examples - * - * # Print out the Object's CDN URI (if it has one) in an HTML img-tag - * # - * print "<img src='$pic->public_uri()' />\n"; - * </code> - * - * @return string Object's public URI or NULL - */ - public function public_uri() - { - if ($this->container->cdn_enabled) { - return $this->container->cdn_uri.'/'.$this->name; - } - - return null; - } - - /** - * Read the remote Object's data. - * - * Returns the Object's data. This is useful for smaller Objects such - * as images or office documents. Object's with larger content should use - * the stream() method below. - * - * Pass in $hdrs array to set specific custom HTTP headers such as - * If-Match, If-None-Match, If-Modified-Since, Range, etc. - * - * Example: - * <code> - * # ... authentication/connection/container code excluded - * # ... see previous examples - * - * $my_docs = $conn->get_container("documents"); - * $doc = $my_docs->get_object("README"); - * $data = $doc->read(); # read image content into a string variable - * print $data; - * - * # Or see stream() below for a different example. - * # - ... [truncated]
app/bundles/CoreBundle/Assets/js/libraries/ckeditor/filemanager/connectors/php/plugins/rsc/COPYING+0 −26 removed@@ -1,26 +0,0 @@ -Unless otherwise noted, all files are released under the MIT license, -exceptions contain licensing information in them. - - Copyright (C) 2008 Rackspace US, Inc. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -Except as contained in this notice, the name of Rackspace US, Inc. shall not -be used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from Rackspace US, Inc. \ No newline at end of file
app/bundles/CoreBundle/Assets/js/libraries/ckeditor/filemanager/connectors/php/plugins/rsc/filemanager.rsc.class.php+0 −411 removed@@ -1,411 +0,0 @@ -<?php -/** -* Filemanager PHP RSC plugin class. -* -* filemanager.rsc.class.php -* class for the filemanager.php connector which utilizes the Rackspace Cloud Files API -* instead of the local filesystem -* -* @license MIT License -* @author Alan Blount <alan (at) zeroasterisk (dot) com> -* @author Riaan Los <mail (at) riaanlos (dot) nl> -* @author Simon Georget <simon (at) linea21 (dot) com> -* @copyright Authors -*/ -class FilemanagerRSC extends Filemanager -{ - public function __construct($config) - { - $return = parent::__construct($config); - require_once 'cloudfiles.php'; - $auth = new CF_Authentication($this->config['rsc-username'], $this->config['rsc-apikey']); - $auth->authenticate(); - $this->conn = new CF_Connection($auth); - if ($this->config['rsc-ssl_use_cabundle']) { - $this->conn->ssl_use_cabundle(); - } - - return $return; - } - - public function getinfo() - { - $object = $this->get_object(); - if (isset($object->name)) { - $object = $this->get_file_info($object); - - return [ - 'Path' => $object->path, - 'Filename' => $object->name, - 'File Type' => $object->filetype, - 'Preview' => $object->preview, - 'Properties' => $object->properties, - 'Error' => '', - 'Code' => 0, - ]; - } - - $container = $this->get_container(); - if (isset($container->name)) { - return [ - 'Path' => $container->path, - 'Filename' => $container->name, - 'File Type' => 'dir', - 'Preview' => $this->config['icons']['path'].$this->config['icons']['directory'], - 'Properties' => [ - 'Date Created' => null, - 'Date Modified' => null, - 'Height' => null, - 'Width' => null, - 'Size' => null, - ], - 'Error' => '', - 'Code' => 0, - ]; - } - - return []; - } - - public function getfolder() - { - $container = trim($this->get['path'], '/ '); - $containerParts = explode('/', $container); - if ($containerParts[0] == 'containers') { - array_shift($containerParts); - } - $array = []; - if (empty($containerParts) || trim($this->get['path'], '/ ') == 'containers') { - $containers = $this->conn->list_containers(); - $containers = array_diff($containers, $this->config['unallowed_dirs']); - foreach ($containers as $container) { - $array['/containers/'.$container.'/'] = [ - 'Path' => '/containers/'.$container.'/', - 'Filename' => $container, - 'File Type' => 'dir', - 'Preview' => $this->config['icons']['path'].$this->config['icons']['directory'], - 'Properties' => [ - 'Date Created' => null, - 'Date Modified' => null, - 'Height' => null, - 'Width' => null, - 'Size' => null, - ], - 'Error' => '', - 'Code' => 0, - ]; - } - } else { - $container = array_shift($containerParts); - $limit = 0; - $marker = null; // last record returned from a dataset - $prefix = null; // search term (starts with) - $path = null; // pseudo-hierarchical containers - if (!empty($containerParts)) { - $path = implode('/', $containerParts); - } - $container = $this->conn->get_container($container); - //$list = $container->list_objects($limit, $marker, $prefix, $path); - $objects = $container->get_objects($limit, $marker, $prefix, $path); - foreach ($objects as $object) { - if (!isset($this->params['type']) || (isset($this->params['type']) && strtolower($this->params['type']) == 'images' && in_array(strtolower($object->content_type), $this->config['images']))) { - if ($this->config['upload']['imagesonly'] == false || ($this->config['upload']['imagesonly'] == true && in_array(strtolower($object->content_type), $this->config['images']))) { - $object = $this->get_file_info($object); - $array[$object->url] = [ - 'Path' => $object->path, - 'Filename' => $object->name, - 'File Type' => $object->filetype, - 'Mime Type' => $object->content_type, - 'Preview' => $object->preview, - 'Properties' => $object->properties, - 'Error' => '', - 'Code' => 0, - ]; - } - } - } - } - - return $array; - } - - public function rename() - { - // keep old filename, if missing from new - $newNameParts = explode('.', $this->get['new']); - $newNameExt = $newNameParts[(count($newNameParts) - 1)]; - if (strlen($newNameExt) > 5 || count($newNameParts) == 1) { - $this->get['new'] .= '.'.array_pop(explode('.', $this->get['old'])); - } - // get old - $object = $this->get_object($this->get['old']); - if (!isset($object->container)) { - $this->error(sprintf($this->lang('FILE_DOES_NOT_EXIST'), $path)); - } - if (in_array($this->get['new'], $object->container->list_objects())) { - $this->error(sprintf($this->lang('FILE_ALREADY_EXISTS'), $this->get['new'])); - - return false; - } - // create to new - $new = $object->container->create_object($this->get['new']); - $new->content_type = $object->content_type; - $data = $object->read(); - $new->write($data); - if (!empty($object->metadata)) { - $new->metadata = $object->metadata; - $object->sync_metadata(); // save back to RSC - } - $object->container->delete_object($object->name); - $array = [ - 'Error' => '', - 'Code' => 0, - 'Old Path' => $object->path, - 'Old Name' => $object->name, - 'New Path' => $new->path, - 'New Name' => $new->name, - ]; - - return $array; - } - - public function delete() - { - $object = $this->get_object(); - if (isset($object->name)) { - $object->container->delete_object($object->name); - - return [ - 'Error' => '', - 'Code' => 0, - 'Path' => $this->get['path'], - ]; - } - $container = $this->get_container(); - if (isset($container->name)) { - $list = $container->list_objects(5); - if (!empty($list)) { - $this->error('Unable to Delete Container, it is not empty.'); - - return false; - } - $this->conn->delete_container($container->name); - - return [ - 'Error' => '', - 'Code' => 0, - 'Path' => $this->get['path'], - ]; - } - $this->error(sprintf($this->lang('INVALID_DIRECTORY_OR_FILE'))); - } - - public function add() - { - $this->setParams(); - if (!isset($_FILES['newfile']) || !is_uploaded_file($_FILES['newfile']['tmp_name'])) { - $this->error(sprintf($this->lang('INVALID_FILE_UPLOAD')), true); - } - if (($this->config['upload']['size'] != false && is_numeric($this->config['upload']['size'])) && ($_FILES['newfile']['size'] > ($this->config['upload']['size'] * 1024 * 1024))) { - $this->error(sprintf($this->lang('UPLOAD_FILES_SMALLER_THAN'), $this->config['upload']['size'].'Mb'), true); - } - - $size = @getimagesize($_FILES['newfile']['tmp_name']); - if ($this->config['upload']['imagesonly'] || (isset($this->params['type']) && strtolower($this->params['type']) == 'images')) { - if (empty($size) || !is_array($size)) { - $this->error(sprintf($this->lang('UPLOAD_IMAGES_ONLY')), true); - } - if (!in_array($size[2], [1, 2, 3, 7, 8])) { - $this->error(sprintf($this->lang('UPLOAD_IMAGES_TYPE_JPEG_GIF_PNG')), true); - } - } - $_FILES['newfile']['name'] = $this->cleanString($_FILES['newfile']['name'], ['.', '-']); - - $container = $this->get_container($this->post['currentpath']); - - if (!$this->config['upload']['overwrite']) { - $list = $container->list_objects(); - $i = 0; - while (in_array($_FILES['newfile']['name'], $list)) { - ++$i; - $parts = explode('.', $_FILES['newfile']['name']); - $ext = array_pop($parts); - $parts = array_diff($parts, ["copy{$i}", 'copy'.($i - 1)]); - $parts[] = "copy{$i}"; - $parts[] = $ext; - $_FILES['newfile']['name'] = implode('.', $parts); - } - } - - $object = $container->create_object($_FILES['newfile']['name']); - $object->load_from_filename($_FILES['newfile']['tmp_name']); - // set image details - if (is_array($size) && count($size) > 1) { - $object->metadata->height = $object->height = $size[1]; - $object->metadata->width = $object->width = $size[0]; - $object->sync_metadata(); // save back to RSC - } - unlink($_FILES['newfile']['tmp_name']); - - $response = [ - 'Path' => $this->post['currentpath'], - 'Name' => $_FILES['newfile']['name'], - 'Error' => '', - 'Code' => 0, - ]; - echo '<textarea>'.json_encode($response).'</textarea>'; - die(); - } - - public function addfolder() - { - $container = trim($this->get['path'], '/ '); - $containerParts = explode('/', $container); - if ($containerParts[0] == 'containers') { - array_shift($containerParts); - } - if (!empty($containerParts)) { - $this->error(sprintf($this->lang('UNABLE_TO_CREATE_DIRECTORY'), $newdir)); - } - $newdir = $this->cleanString($this->get['name']); - $container = $this->conn->create_container($newdir); - $container->make_public(86400 / 2); - - return [ - 'Parent' => "/containers/{$container->name}", - 'Name' => $container->name, - 'Error' => '', - 'Code' => 0, - ]; - } - - public function download() - { - $object = $this->get_object(); - if (isset($object->name)) { - header('Content-type: application/force-download'); - header('Content-Disposition: inline; filename="'.$object->name.'"'); - header('Content-Type: '.$doc->content_type); - $output = fopen('php://output', 'w'); - $object->stream($output); // stream object content to PHP's output buffer - fclose($output); - - return true; - } - $this->error(sprintf($this->lang('FILE_DOES_NOT_EXIST'), $this->get['path'])); - } - - public function preview() - { - if (isset($this->get['path']) && file_exists($this->doc_root.$this->get['path'])) { - header('Content-type: image/'.$ext = pathinfo($this->get['path'], PATHINFO_EXTENSION)); - header('Content-Transfer-Encoding: Binary'); - header('Content-length: '.filesize($this->doc_root.$this->get['path'])); - header('Content-Disposition: inline; filename="'.basename($this->get['path']).'"'); - readfile($this->doc_root.$this->get['path']); - } else { - $this->error(sprintf($this->lang('FILE_DOES_NOT_EXIST'), $this->get['path'])); - } - } - - private function get_container($path = null, $showError = false) - { - if (empty($path)) { - $path = $this->get['path']; - } - $container = trim($path, '/ '); - $containerParts = explode('/', $container); - if ($containerParts[0] == 'containers') { - array_shift($containerParts); - } - $array = []; - if (count($containerParts) > 0) { - $container = $this->conn->get_container(array_shift($containerParts)); - if (isset($container->name)) { - $container->path = '/containers/'.$container->name; - - return $container; - } - } - if ($showError) { - $this->error(sprintf($this->lang('FILE_DOES_NOT_EXIST'), $path)); - } - - return false; - } - - private function get_object($path = null, $showError = false) - { - if (empty($path)) { - $path = $this->get['path']; - } - $container = trim($path, '/ '); - $containerParts = explode('/', $container); - if ($containerParts[0] == 'containers') { - array_shift($containerParts); - } - $array = []; - if (count($containerParts) > 1) { - $container = $this->conn->get_container(array_shift($containerParts)); - $object = $container->get_object(array_shift($containerParts)); - if (isset($object->name) && isset($object->container->name)) { - $object->path = '/containers/'.$object->container->name.'/'.$object->name; - - return $object; - } - } - if ($showError) { - $this->error(sprintf($this->lang('FILE_DOES_NOT_EXIST'), $path)); - } - - return false; - } - - private function get_file_info($object = null) - { - if (empty($object) || !is_object($object)) { - return null; - } - // parse into file extension types - //$object->filetype = array_pop(explode('/', $object->content_type)); - $object->filetype = array_pop(explode('.', $object->name)); - // setup values - $object->height = null; - $object->width = null; - if (isset($object->metadata->height)) { - $object->height = $object->metadata->height; - } - if (isset($object->metadata->width)) { - $object->width = $object->metadata->width; - } - $preview = $this->config['icons']['path'].$this->config['icons']['default']; - if (file_exists($this->root.$this->config['icons']['path'].strtolower($object->filetype).'.png')) { - $preview = $this->config['icons']['path'].strtolower($object->filetype).'.png'; - } - if (in_array(strtolower($object->filetype), $this->config['images'])) { - $preview = $object->container->cdn_uri.'/'.$object->name; - if (empty($object->height) && empty($object->width) && isset($this->config['rsc-getsize']) && !empty($get['rsc-getsize'])) { - list($width, $height, $type, $attr) = getimagesize($this->doc_root.$path); - $object->metadata->height = $object->height = $height; - $object->metadata->width = $object->width = $width; - $object->sync_metadata(); // save back to RSC - } - } - $object->filename = $object->name; - $object->path = '/containers/'.$object->container->name.'/'.$object->name; - $object->url = $object->container->cdn_uri.'/'.$object->name; - $object->mimetype = $object->content_type; - $object->filemtime = $object->last_modified; - $object->preview = $preview; - $object->size = $object->content_length; - $object->date = date($this->config['date'], strtotime($object->last_modified)); - $object->properties = [ - 'Date Modified' => $object->date, - 'Size' => $object->size, - 'Height' => $object->height, - 'Width' => $object->width, - ]; - - return $object; - } -}
app/bundles/CoreBundle/Assets/js/libraries/ckeditor/filemanager/connectors/php/plugins/rsc/filemanager.rsc.config.php+0 −53 removed@@ -1,53 +0,0 @@ -<?php -/** -* Filemanager PHP RSC plugin configuration. -* -* filemanager.rsc.class.php -* This is a separate config file for the parameters needed for the RSC plugin -* You may over-ride any parameters set by the filemanager.config.php file here -* -* @license MIT License -* @author Alan Blount <alan (at) zeroasterisk (dot) com> -* @copyright Authors -*/ - -/** - * Language settings. - */ -$config['rsc-verbose'] = false; - -/* - * Language settings - */ -$config['rsc-username'] = 'your_username'; - -/* - * Language settings - */ -$config['rsc-apikey'] = 'your_api_key_hash'; - -/* - * RSC Account (optional) - */ -$config['rsc-account'] = null; - -/* - * RSC Account (optionally limit container to this, better accomplished by limiting the base path) - */ -$config['rsc-container'] = null; - -/* - * Language settings - */ -$config['rsc-ssl_use_cabundle'] = true; - -/* - * Language settings - */ -$config['rsc-getsize'] = true; - -/* - * Extension of the unallowed Dirs - */ -$config['unallowed_dirs'][] = '.CDN_ACCESS_LOGS'; -$config['unallowed_dirs'][] = 'cloudservers';
app/bundles/CoreBundle/Assets/js/libraries/ckeditor/filemanager/connectors/php/plugins/rsc/share/cacert.pem+0 −3113 removedapp/bundles/CoreBundle/Assets/js/libraries/ckeditor/filemanager/connectors/php/plugins/rsc/share/magic+0 −15283 removedapp/bundles/CoreBundle/Assets/js/libraries/ckeditor/filemanager/connectors/php/plugins/rsc/share/magic.mgc+0 −0 removedapp/bundles/CoreBundle/Assets/js/libraries/ckeditor/filemanager/connectors/php/plugins/rsc/share/magic.mime+0 −1027 removed@@ -1,1027 +0,0 @@ -# Magic data for KMimeMagic (originally for file(1) command) -# -# Note on adding additional MIME types: -# -# [RFC2045,RFC2046] specifies that Content Types, Content Subtypes, Character -# Sets, Access Types, and conversion values for MIME mail will be assigned and -# listed by the IANA. -# http://www.iana.org/assignments/media-types/ -# -# Any unregistered file type should be listed with a preceding x-, as in -# application/x-foo (RFC2045 5.1), or a x., as in application/x.foo (RFC4288 -# 4.3). Any non x-prefixed type should be registered with IANA and listed at -# the above address. Any other behavior is a MIME standards violation! -# -# It is preferred that when a registered MIME type exists, that -# the registered Content-Type and Subtype be used to refer to a file of -# that type, so don't use application/x-zip when application/zip is -# registered. -# -# If an active RFC suggests that a MIME registration for a new type is in -# progress, make a note of it pointing to that RFC. -# -# The format is 4-5 columns: -# Column #1: byte number to begin checking from, ">" indicates continuation -# Column #2: type of data to match -# Column #3: contents of data to match -# Column #4: MIME type of result -# Column #5: MIME encoding of result (optional) - -#------------------------------------------------------------------------------ -# Localstuff: file(1) magic for locally observed files -# Add any locally observed files here. - -# Real Audio (Magic .ra\0375) -0 belong 0x2e7261fd audio/x-pn-realaudio -0 string .RMF application/vnd.rn-realmedia - -#video/x-pn-realvideo -#video/vnd.rn-realvideo -#application/vnd.rn-realmedia -# sigh, there are many mimes for that but the above are the most common. - -# Taken from magic, converted to magic.mime -# mime types according to http://www.geocities.com/nevilo/mod.htm: -# audio/it .it -# audio/x-zipped-it .itz -# audio/xm fasttracker modules -# audio/x-s3m screamtracker modules -# audio/s3m screamtracker modules -# audio/x-zipped-mod mdz -# audio/mod mod -# audio/x-mod All modules (mod, s3m, 669, mtm, med, xm, it, mdz, stm, itz, xmz, s3z) - -# Taken from loader code from mikmod version 2.14 -# by Steve McIntyre (stevem@chiark.greenend.org.uk) -# <doj@cubic.org> added title printing on 2003-06-24 -0 string MAS_UTrack_V00 ->14 string >/0 audio/x-mod -#audio/x-tracker-module - -#0 string UN05 MikMod UNI format module sound data - -0 string Extended\ Module: audio/x-mod -#audio/x-tracker-module -##>17 string >\0 Title: "%s" - -21 string/c \!SCREAM! audio/x-mod -#audio/x-screamtracker-module -21 string BMOD2STM audio/x-mod -#audio/x-screamtracker-module -1080 string M.K. audio/x-mod -#audio/x-protracker-module -#>0 string >\0 Title: "%s" -1080 string M!K! audio/x-mod -#audio/x-protracker-module -#>0 string >\0 Title: "%s" -1080 string FLT4 audio/x-mod -#audio/x-startracker-module -#>0 string >\0 Title: "%s" -1080 string FLT8 audio/x-mod -#audio/x-startracker-module -#>0 string >\0 Title: "%s" -1080 string 4CHN audio/x-mod -#audio/x-fasttracker-module -#>0 string >\0 Title: "%s" -1080 string 6CHN audio/x-mod -#audio/x-fasttracker-module -#>0 string >\0 Title: "%s" -1080 string 8CHN audio/x-mod -#audio/x-fasttracker-module -#>0 string >\0 Title: "%s" -1080 string CD81 audio/x-mod -#audio/x-oktalyzer-tracker-module -#>0 string >\0 Title: "%s" -1080 string OKTA audio/x-mod -#audio/x-oktalyzer-tracker-module -#>0 string >\0 Title: "%s" -# Not good enough. -#1082 string CH -#>1080 string >/0 %.2s-channel Fasttracker "oktalyzer" module sound data -1080 string 16CN audio/x-mod -#audio/x-taketracker-module -#>0 string >\0 Title: "%s" -1080 string 32CN audio/x-mod -#audio/x-taketracker-module -#>0 string >\0 Title: "%s" - -# Impuse tracker module (it) -0 string IMPM audio/x-mod -#>4 string >\0 "%s" -#>40 leshort !0 compatible w/ITv%x -#>42 leshort !0 created w/ITv%x - -#------------------------------------------------------------------------------ -# end local stuff -#------------------------------------------------------------------------------ - -# xml based formats! - -# svg - -38 string \<\!DOCTYPE\040svg image/svg+xml - -0 belong 0xfeedfeed application/x-java-keystore - -0 belong 0xcececece application/x-java-jce-keystore - - -# xml -0 string \<?xml text/xml - - -#------------------------------------------------------------------------------ -# Java - -0 beshort 0xcafe ->2 beshort 0xbabe application/x-java-applet ->2 beshort 0xd00d application/x-java-pack200 - -#------------------------------------------------------------------------------ -# audio: file(1) magic for sound formats -# -# from Jan Nicolai Langfeldt <janl@ifi.uio.no>, -# - -# Sun/NeXT audio data -0 string .snd ->12 belong 1 audio/basic ->12 belong 2 audio/basic ->12 belong 3 audio/basic ->12 belong 4 audio/basic ->12 belong 5 audio/basic ->12 belong 6 audio/basic ->12 belong 7 audio/basic - ->12 belong 23 audio/x-adpcm - -# DEC systems (e.g. DECstation 5000) use a variant of the Sun/NeXT format -# that uses little-endian encoding and has a different magic number -# (0x0064732E in little-endian encoding). -0 lelong 0x0064732E ->12 lelong 1 audio/x-dec-basic ->12 lelong 2 audio/x-dec-basic ->12 lelong 3 audio/x-dec-basic ->12 lelong 4 audio/x-dec-basic ->12 lelong 5 audio/x-dec-basic ->12 lelong 6 audio/x-dec-basic ->12 lelong 7 audio/x-dec-basic -# compressed (G.721 ADPCM) ->12 lelong 23 audio/x-dec-adpcm - -# Bytes 0-3 of AIFF, AIFF-C, & 8SVX audio files are "FORM" -# AIFF audio data -8 string AIFF audio/x-aiff -# AIFF-C audio data -8 string AIFC audio/x-aiff -# IFF/8SVX audio data -8 string 8SVX audio/x-aiff - - - -# Creative Labs AUDIO stuff -# Standard MIDI data -0 string MThd audio/x-midi -#>9 byte >0 (format %d) -#>11 byte >1 using %d channels -0 string MThd audio/midi -# Creative Music (CMF) data -0 string CTMF audio/x-unknown -# SoundBlaster instrument data -0 string SBI audio/x-unknown -# Creative Labs voice data -0 string Creative\ Voice\ File audio/x-unknown -## is this next line right? it came this way... -#>19 byte 0x1A -#>23 byte >0 - version %d -#>22 byte >0 \b.%d - -# [GRR 950115: is this also Creative Labs? Guessing that first line -# should be string instead of unknown-endian long...] -#0 long 0x4e54524b MultiTrack sound data -#0 string NTRK MultiTrack sound data -#>4 long x - version %ld - -# Microsoft WAVE format (*.wav) -# [GRR 950115: probably all of the shorts and longs should be leshort/lelong] -# Microsoft RIFF -0 string RIFF -# - WAVE format ->8 string WAVE audio/x-wav ->8 string/B AVI video/x-msvideo -# ->8 string CDRA image/x-coreldraw - -# AAC (aka MPEG-2 NBC) -0 beshort&0xfff6 0xfff0 audio/X-HX-AAC-ADTS -0 string ADIF audio/X-HX-AAC-ADIF -0 beshort&0xffe0 0x56e0 audio/MP4A-LATM -0 beshort 0x4De1 audio/MP4A-LATM - -# MPEG Layer 3 sound files -# modified by Joerg Jenderek -# GRR the original test are too common for many DOS files -# so test 1 <= kbits nibble <= E -0 beshort &0xffe0 ->2 ubyte&0xF0 >0x0F ->>2 ubyte&0xF0 <0xE1 audio/mpeg -#MP3 with ID3 tag -0 string ID3 audio/mpeg -# Ogg/Vorbis -0 string OggS application/ogg - -#------------------------------------------------------------------------------ -# c-lang: file(1) magic for C programs or various scripts -# - -# XPM icons (Greg Roelofs, newt@uchicago.edu) -# ideally should go into "images", but entries below would tag XPM as C source -0 string /*\ XPM image/x-xpmi - -# 3DS (3d Studio files) Conflicts with diff output 0x3d '=' -#16 beshort 0x3d3d image/x-3ds - -# this first will upset you if you're a PL/1 shop... (are there any left?) -# in which case rm it; ascmagic will catch real C programs -# C or REXX program text -#0 string /* text/x-c -# C++ program text -#0 string // text/x-c++ - -#------------------------------------------------------------------------------ -# commands: file(1) magic for various shells and interpreters -# -#0 string :\ shell archive or commands for antique kernel text -0 string #!/bin/sh application/x-shellscript -0 string #!\ /bin/sh application/x-shellscript -0 string #!/bin/csh application/x-shellscript -0 string #!\ /bin/csh application/x-shellscript -# korn shell magic, sent by George Wu, gwu@clyde.att.com -0 string #!/bin/ksh application/x-shellscript -0 string #!\ /bin/ksh application/x-shellscript -0 string #!/bin/tcsh application/x-shellscript -0 string #!\ /bin/tcsh application/x-shellscript -0 string #!/usr/local/tcsh application/x-shellscript -0 string #!\ /usr/local/tcsh application/x-shellscript -0 string #!/usr/local/bin/tcsh application/x-shellscript -0 string #!\ /usr/local/bin/tcsh application/x-shellscript -# bash shell magic, from Peter Tobias (tobias@server.et-inf.fho-emden.de) -0 string #!/bin/bash application/x-shellscript -0 string #!\ /bin/bash application/x-shellscript -0 string #!/usr/local/bin/bash application/x-shellscript -0 string #!\ /usr/local/bin/bash application/x-shellscript - -# -# zsh/ash/ae/nawk/gawk magic from cameron@cs.unsw.oz.au (Cameron Simpson) -0 string #!/bin/zsh application/x-shellscript -0 string #!/usr/bin/zsh application/x-shellscript -0 string #!/usr/local/bin/zsh application/x-shellscript -0 string #!\ /usr/local/bin/zsh application/x-shellscript -0 string #!/usr/local/bin/ash application/x-shellscript -0 string #!\ /usr/local/bin/ash application/x-shellscript -#0 string #!/usr/local/bin/ae Neil Brown's ae -#0 string #!\ /usr/local/bin/ae Neil Brown's ae -0 string #!/bin/nawk application/x-nawk -0 string #!\ /bin/nawk application/x-nawk -0 string #!/usr/bin/nawk application/x-nawk -0 string #!\ /usr/bin/nawk application/x-nawk -0 string #!/usr/local/bin/nawk application/x-nawk -0 string #!\ /usr/local/bin/nawk application/x-nawk -0 string #!/bin/gawk application/x-gawk -0 string #!\ /bin/gawk application/x-gawk -0 string #!/usr/bin/gawk application/x-gawk -0 string #!\ /usr/bin/gawk application/x-gawk -0 string #!/usr/local/bin/gawk application/x-gawk -0 string #!\ /usr/local/bin/gawk application/x-gawk -# -0 string #!/bin/awk application/x-awk -0 string #!\ /bin/awk application/x-awk -0 string #!/usr/bin/awk application/x-awk -0 string #!\ /usr/bin/awk application/x-awk -# update to distinguish from *.vcf files by Joerg Jenderek: joerg dot jenderek at web dot de -# Too general, \EBEGIN matches in postscript -#0 regex BEGIN[[:space:]]*[{] application/x-awk - -# For Larry Wall's perl language. The ``eval'' line recognizes an -# outrageously clever hack for USG systems. -# Keith Waclena <keith@cerberus.uchicago.edu> -0 string #!/bin/perl application/x-perl -0 string #!\ /bin/perl application/x-perl -0 string eval\ "exec\ /bin/perl application/x-perl -0 string #!/usr/bin/perl application/x-perl -0 string #!\ /usr/bin/perl application/x-perl -0 string eval\ "exec\ /usr/bin/perl application/x-perl -0 string #!/usr/local/bin/perl application/x-perl -0 string #!\ /usr/local/bin/perl application/x-perl -0 string eval\ "exec\ /usr/local/bin/perl application/x-perl - -# Type: Lua scripting language -# URL: http://www.lua.org/ -# From: Reuben Thomas <rrt@sc3d.org> -0 string/B #!\ /usr/bin/lua application/x-lua -0 string/B #!\ /usr/local/bin/lua application/x-lua -0 string #!/usr/bin/env\ lua application/x-lua -0 string #!\ /usr/bin/env\ lua application/x-lua - -#------------------------------------------------------------------------------ -# compress: file(1) magic for pure-compression formats (no archives) -# -# compress, gzip, pack, compact, huf, squeeze, crunch, freeze, yabba, whap, etc. -# -# Formats for various forms of compressed data -# Formats for "compress" proper have been moved into "compress.c", -# because it tries to uncompress it to figure out what's inside. - -# standard unix compress -#0 string \037\235 application/x-compress - -# gzip (GNU zip, not to be confused with [Info-ZIP/PKWARE] zip archiver) -0 string \037\213 application/x-gzip - -0 string PK\003\004 application/zip - -# RAR archiver (Greg Roelofs, newt@uchicago.edu) -0 string Rar! application/x-rar - -# According to gzip.h, this is the correct byte order for packed data. -0 string \037\036 application/octet-stream -# -# This magic number is byte-order-independent. -# -0 short 017437 application/octet-stream - -# XXX - why *two* entries for "compacted data", one of which is -# byte-order independent, and one of which is byte-order dependent? -# -# compacted data -0 short 0x1fff application/octet-stream -0 string \377\037 application/octet-stream -# huf output -0 short 0145405 application/octet-stream - -# Squeeze and Crunch... -# These numbers were gleaned from the Unix versions of the programs to -# handle these formats. Note that I can only uncrunch, not crunch, and -# I didn't have a crunched file handy, so the crunch number is untested. -# Keith Waclena <keith@cerberus.uchicago.edu> -#0 leshort 0x76FF squeezed data (CP/M, DOS) -#0 leshort 0x76FE crunched data (CP/M, DOS) - -# Freeze -#0 string \037\237 Frozen file 2.1 -#0 string \037\236 Frozen file 1.0 (or gzip 0.5) - -# lzh? -#0 string \037\240 LZH compressed data - -257 string ustar\0 application/x-tar posix -257 string ustar\040\040\0 application/x-tar gnu - -0 short 070707 application/x-cpio -0 short 0143561 application/x-cpio swapped - -0 string =<ar> application/x-archive -0 string \!<arch> application/x-archive ->8 string debian application/x-debian-package - -#------------------------------------------------------------------------------ -# -# RPM: file(1) magic for Red Hat Packages Erik Troan (ewt@redhat.com) -# -0 beshort 0xedab ->2 beshort 0xeedb application/x-rpm - -0 lelong&0x8080ffff 0x0000081a application/x-arc lzw -0 lelong&0x8080ffff 0x0000091a application/x-arc squashed -0 lelong&0x8080ffff 0x0000021a application/x-arc uncompressed -0 lelong&0x8080ffff 0x0000031a application/x-arc packed -0 lelong&0x8080ffff 0x0000041a application/x-arc squeezed -0 lelong&0x8080ffff 0x0000061a application/x-arc crunched - -0 leshort 0xea60 application/x-arj - -# LHARC/LHA archiver (Greg Roelofs, newt@uchicago.edu) -2 string -lh0- application/x-lharc lh0 -2 string -lh1- application/x-lharc lh1 -2 string -lz4- application/x-lharc lz4 -2 string -lz5- application/x-lharc lz5 -# [never seen any but the last; -lh4- reported in comp.compression:] -2 string -lzs- application/x-lha lzs -2 string -lh\ - application/x-lha lh -2 string -lhd- application/x-lha lhd -2 string -lh2- application/x-lha lh2 -2 string -lh3- application/x-lha lh3 -2 string -lh4- application/x-lha lh4 -2 string -lh5- application/x-lha lh5 -2 string -lh6- application/x-lha lh6 -2 string -lh7- application/x-lha lh7 -# Shell archives -10 string #\ This\ is\ a\ shell\ archive application/octet-stream x-shell - -#------------------------------------------------------------------------------ -# frame: file(1) magic for FrameMaker files -# -# This stuff came on a FrameMaker demo tape, most of which is -# copyright, but this file is "published" as witness the following: -# -# Note that this is the Framemaker Maker Interchange Format, not the -# Normal format which would be application/vnd.framemaker. -# -0 string \<MakerFile application/x-mif -0 string \<MIFFile application/x-mif -0 string \<MakerDictionary application/x-mif -0 string \<MakerScreenFon application/x-mif -0 string \<MML application/x-mif -0 string \<Book application/x-mif -0 string \<Maker application/x-mif - -#------------------------------------------------------------------------------ -# html: file(1) magic for HTML (HyperText Markup Language) docs -# -# from Michael Piefel <piefel@debian.org> -# -0 string/cB \<!DOCTYPE\ html text/html -0 string/cb \<head text/html -0 string/cb \<title text/html -0 string/bc \<html text/html -0 string \<!-- text/html -0 string/c \<h1 text/html - -#------------------------------------------------------------------------------ -# images: file(1) magic for image formats (see also "c-lang" for XPM bitmaps) -# -# originally from jef@helios.ee.lbl.gov (Jef Poskanzer), -# additions by janl@ifi.uio.no as well as others. Jan also suggested -# merging several one- and two-line files into here. -# -# XXX - byte order for GIF and TIFF fields? -# [GRR: TIFF allows both byte orders; GIF is probably little-endian] -# - -# [GRR: what the hell is this doing in here?] -#0 string xbtoa btoa'd file - -# PBMPLUS -# PBM file -0 string P1 image/x-portable-bitmap -# PGM file -0 string P2 image/x-portable-greymap -# PPM file -0 string P3 image/x-portable-pixmap -# PBM "rawbits" file -0 string P4 image/x-portable-bitmap -# PGM "rawbits" file -0 string P5 image/x-portable-greymap -# PPM "rawbits" file -0 string P6 image/x-portable-pixmap - -# NIFF (Navy Interchange File Format, a modification of TIFF) -# [GRR: this *must* go before TIFF] -0 string IIN1 image/x-niff - -# TIFF and friends -# TIFF file, big-endian -0 string MM image/tiff -# TIFF file, little-endian -0 string II image/tiff - -# possible GIF replacements; none yet released! -# (Greg Roelofs, newt@uchicago.edu) -# -# GRR 950115: this was mine ("Zip GIF"): -# ZIF image (GIF+deflate alpha) -0 string GIF94z image/x-unknown -# -# GRR 950115: this is Jeremy Wohl's Free Graphics Format (better): -# FGF image (GIF+deflate beta) -0 string FGF95a image/x-unknown -# -# GRR 950115: this is Thomas Boutell's Portable Bitmap Format proposal -# (best; not yet implemented): -# PBF image (deflate compression) -0 string PBF image/x-unknown - -# GIF -0 string GIF image/gif - -# JPEG images -0 beshort 0xffd8 image/jpeg - -# PC bitmaps (OS/2, Windoze BMP files) (Greg Roelofs, newt@uchicago.edu) -0 string BM image/x-ms-bmp -#>14 byte 12 (OS/2 1.x format) -#>14 byte 64 (OS/2 2.x format) -#>14 byte 40 (Windows 3.x format) -#0 string IC icon -#0 string PI pointer -#0 string CI color icon -#0 string CP color pointer -#0 string BA bitmap array - -# CDROM Filesystems -32769 string CD001 application/x-iso9660-image - -# Newer StuffIt archives (grant@netbsd.org) -0 string StuffIt application/x-stuffit -#>162 string >0 : %s - -# BinHex is the Macintosh ASCII-encoded file format (see also "apple") -# Daniel Quinlan, quinlan@yggdrasil.com -11 string must\ be\ converted\ with\ BinHex\ 4 application/mac-binhex40 -##>41 string x \b, version %.3s - - -#------------------------------------------------------------------------------ -# lisp: file(1) magic for lisp programs -# -# various lisp types, from Daniel Quinlan (quinlan@yggdrasil.com) -0 string ;; text/plain -# Emacs 18 - this is always correct, but not very magical. -0 string \012( application/x-elc -# Emacs 19 -0 string ;ELC\023\000\000\000 application/x-elc - -#------------------------------------------------------------------------------ -# mail.news: file(1) magic for mail and news -# -# There are tests to ascmagic.c to cope with mail and news. -0 string Relay-Version: message/rfc822 -0 string #!\ rnews message/rfc822 -0 string N#!\ rnews message/rfc822 -0 string Forward\ to message/rfc822 -0 string Pipe\ to message/rfc822 -0 string Return-Path: message/rfc822 -0 string Received: message/rfc822 -0 string Path: message/news -0 string Xref: message/news -0 string From: message/rfc822 -0 string Article message/news -#------------------------------------------------------------------------------ -# msword: file(1) magic for MS Word files -# -# Contributor claims: -# Reversed-engineered MS Word magic numbers -# - -0 string \376\067\0\043 application/msword -# disable this one because it applies also to other -# Office/OLE documents for which msword is not correct. See PR#2608. -# from magic file of the apache -#0 string \320\317\021\340\241\261 application/msword -512 string \354\245\301 application/msword -0 string \333\245-\0\0\0 application/msword - - - -#------------------------------------------------------------------------------ -# printer: file(1) magic for printer-formatted files -# - -# PostScript -0 string %! application/postscript -0 string \004%! application/postscript - -# Acrobat -# (due to clamen@cs.cmu.edu) -0 string %PDF- application/pdf - -#------------------------------------------------------------------------------ -# sc: file(1) magic for "sc" spreadsheet -# -38 string Spreadsheet application/x-sc - -#------------------------------------------------------------------------------ -# tex: file(1) magic for TeX files -# -# XXX - needs byte-endian stuff (big-endian and little-endian DVI?) -# -# From <conklin@talisman.kaleida.com> - -# Although we may know the offset of certain text fields in TeX DVI -# and font files, we can't use them reliably because they are not -# zero terminated. [but we do anyway, christos] -0 string \367\002 application/x-dvi -#0 string \367\203 TeX generic font data -#0 string \367\131 TeX packed font data -#0 string \367\312 TeX virtual font data -#0 string This\ is\ TeX, TeX transcript text -#0 string This\ is\ METAFONT, METAFONT transcript text - -# There is no way to detect TeX Font Metric (*.tfm) files without -# breaking them apart and reading the data. The following patterns -# match most *.tfm files generated by METAFONT or afm2tfm. -2 string \000\021 application/x-tex-tfm -2 string \000\022 application/x-tex-tfm -#>34 string >\0 (%s) - -# Texinfo and GNU Info, from Daniel Quinlan (quinlan@yggdrasil.com) -0 string \\input\ texinfo text/x-texinfo -0 string This\ is\ Info\ file text/x-info - -# correct TeX magic for Linux (and maybe more) -# from Peter Tobias (tobias@server.et-inf.fho-emden.de) -# -0 leshort 0x02f7 application/x-dvi - -# RTF - Rich Text Format -0 string {\\rtf text/rtf - -# TeX documents, from Daniel Quinlan (quinlan@yggdrasil.com) -0 search/400 \\input text/x-tex -0 search/400 \\section text/x-tex -0 search/400 \\setlength text/x-tex -0 search/400 \\documentstyle text/x-tex -0 search/400 \\chapter text/x-tex -0 search/400 \\documentclass text/x-tex - -# Type: Inform interactive fiction language -# URL: http://www.inform-fiction.org/ -# From: Reuben Thomas <rrt@sc3d.org> -0 regex [Cc]onstant[[:space:]]+[Ss]tory text/x-inform - -#------------------------------------------------------------------------------ -# animation: file(1) magic for animation/movie formats -# -# animation formats, originally from vax@ccwf.cc.utexas.edu (VaX#n8) -# MPEG file -# MPEG sequences -0 belong 0x000001BA ->4 byte &0x40 video/mp2p ->4 byte ^0x40 video/mpeg -0 belong 0x000001BB video/mpeg -0 belong 0x000001B0 video/mp4v-es -0 belong 0x000001B5 video/mp4v-es -0 belong 0x000001B3 video/mpv -0 belong&0xFF5FFF1F 0x47400010 video/mp2t -0 belong 0x00000001 ->4 byte&0x1F 0x07 video/h264 - -# FLI animation format -0 leshort 0xAF11 video/x-fli -# FLC animation format -0 leshort 0xAF12 video/x-flc -# -# SGI and Apple formats -# Added ISO mimes -0 string MOVI video/x-sgi-movie -4 string moov video/quicktime -4 string mdat video/quicktime -4 string wide video/quicktime -4 string skip video/quicktime -4 string free video/quicktime -4 string idsc image/x-quicktime -4 string idat image/x-quicktime -4 string pckg application/x-quicktime-player -4 string/B jP image/jp2 -4 string ftyp ->8 string isom video/mp4 ->8 string mp41 video/mp4 ->8 string mp42 video/mp4 ->8 string/B jp2 image/jp2 ->8 string 3gp video/3gpp ->8 string avc1 video/3gpp ->8 string mmp4 video/mp4 ->8 string/B M4A audio/mp4 ->8 string/B M4V video/mp4 ->8 string/B qt video/quicktime -# The contributor claims: -# I couldn't find a real magic number for these, however, this -# -appears- to work. Note that it might catch other files, too, -# so BE CAREFUL! -# -# Note that title and author appear in the two 20-byte chunks -# at decimal offsets 2 and 22, respectively, but they are XOR'ed with -# 255 (hex FF)! DL format SUCKS BIG ROCKS. -# -# DL file version 1 , medium format (160x100, 4 images/screen) -0 byte 1 video/x-unknown -0 byte 2 video/x-unknown -# -# Databases -# -# GDBM magic numbers -# Will be maintained as part of the GDBM distribution in the future. -# <downsj@teeny.org> -0 belong 0x13579ace application/x-gdbm -0 lelong 0x13579ace application/x-gdbm -0 string GDBM application/x-gdbm -# -0 belong 0x061561 application/x-dbm -# -# Executables -# -0 string \177ELF ->16 leshort 0 application/octet-stream ->16 leshort 1 application/x-object ->16 leshort 2 application/x-executable ->16 leshort 3 application/x-sharedlib ->16 leshort 4 application/x-coredump ->16 beshort 0 application/octet-stream ->16 beshort 1 application/x-object ->16 beshort 2 application/x-executable ->16 beshort 3 application/x-sharedlib ->16 beshort 4 application/x-coredump -# -# DOS -0 string MZ application/x-dosexec -# -# KDE -0 string [KDE\ Desktop\ Entry] application/x-kdelnk -0 string #\ KDE\ Config\ File application/x-kdelnk -# xmcd database file for kscd -0 string #\ xmcd text/x-xmcd - -#------------------------------------------------------------------------------ -# pkgadd: file(1) magic for SysV R4 PKG Datastreams -# -0 string #\ PaCkAgE\ DaTaStReAm application/x-svr4-package - -#PNG Image Format -0 string \x89PNG image/png - -# MNG Video Format, <URL:http://www.libpng.org/pub/mng/spec/> -0 string \x8aMNG video/x-mng -0 string \x8aJNG video/x-jng - -#------------------------------------------------------------------------------ -# Hierarchical Data Format, used to facilitate scientific data exchange -# specifications at http://hdf.ncsa.uiuc.edu/ -#Hierarchical Data Format (version 4) data -0 belong 0x0e031301 application/x-hdf -#Hierarchical Data Format (version 5) data -0 string \211HDF\r\n\032 application/x-hdf - -# Adobe Photoshop -0 string 8BPS image/vnd.adobe.photoshop - -# Felix von Leitner <felix-file@fefe.de> -0 string d8:announce application/x-bittorrent - - -# lotus 1-2-3 document -0 belong 0x00001a00 application/x-123 -0 belong 0x00000200 application/x-123 - -# MS Access database -4 string Standard\ Jet\ DB application/x-msaccess - -## magic for XBase files -#0 byte 0x02 -#>8 leshort >0 -#>>12 leshort 0 application/x-dbf -# -#0 byte 0x03 -#>8 leshort >0 -#>>12 leshort 0 application/x-dbf -# -#0 byte 0x04 -#>8 leshort >0 -#>>12 leshort 0 application/x-dbf -# -#0 byte 0x05 -#>8 leshort >0 -#>>12 leshort 0 application/x-dbf -# -#0 byte 0x30 -#>8 leshort >0 -#>>12 leshort 0 application/x-dbf -# -#0 byte 0x43 -#>8 leshort >0 -#>>12 leshort 0 application/x-dbf -# -#0 byte 0x7b -#>8 leshort >0 -#>>12 leshort 0 application/x-dbf -# -#0 byte 0x83 -#>8 leshort >0 -#>>12 leshort 0 application/x-dbf -# -#0 byte 0x8b -#>8 leshort >0 -#>>12 leshort 0 application/x-dbf -# -#0 byte 0x8e -#>8 leshort >0 -#>>12 leshort 0 application/x-dbf -# -#0 byte 0xb3 -#>8 leshort >0 -#>>12 leshort 0 application/x-dbf -# -#0 byte 0xf5 -#>8 leshort >0 -#>>12 leshort 0 application/x-dbf -# -#0 leshort 0x0006 application/x-dbt - -# Debian has entries for the old PGP formats: -# pgp: file(1) magic for Pretty Good Privacy -# see http://lists.gnupg.org/pipermail/gnupg-devel/1999-September/016052.html -#0 beshort 0x9900 application/x-pgp-keyring -#0 beshort 0x9501 application/x-pgp-keyring -#0 beshort 0x9500 application/x-pgp-keyring -#0 beshort 0xa600 application/pgp-encrypted -#0 string -----BEGIN\040PGP text/PGP armored data -#>15 string PUBLIC\040KEY\040BLOCK- public key block -#>15 string MESSAGE- message -#>15 string SIGNED\040MESSAGE- signed message -#>15 string PGP\040SIGNATURE- signature -#0 beshort 0x8501 data -#text/PGP key public ring -0 beshort 0x9900 application/pgp -#text/PGP key security ring -0 beshort 0x9501 application/pgp -#text/PGP key security ring -0 beshort 0x9500 application/pgp -#text/PGP encrypted data -0 beshort 0xa600 application/pgp-encrypted -#text/PGP armored data -##public key block -2 string ---BEGIN\ PGP\ PUBLIC\ KEY\ BLOCK- application/pgp-keys -0 string -----BEGIN\040PGP\40MESSAGE- application/pgp -0 string -----BEGIN\040PGP\40SIGNATURE- application/pgp-signature - -# -# GnuPG Magic: -# -#0 beshort 0x9901 application/x-gnupg-keyring -#0 beshort 0x8501 text/OpenPGP data -#text/GnuPG key public ring -0 beshort 0x9901 application/pgp -#text/OpenPGP data -0 beshort 0x8501 application/pgp-encrypted - -# flash: file(1) magic for Macromedia Flash file format -# -# See -# -# http://www.macromedia.com/software/flash/open/ -# -0 string FWS ->3 byte x application/x-shockwave-flash -# Flash Video -0 string FLV video/x-flv - - -# The following paramaters are created for Namazu. -# <http://www.namazu.org/> -# -# 1999/08/13 -#0 string \<!--\ MHonArc text/html; x-type=mhonarc -0 string BZh application/x-bzip2 - -# 1999/09/09 -# VRML (suggested by Masao Takaku) -0 string #VRML\ V1.0\ ascii model/vrml -0 string #VRML\ V2.0\ utf8 model/vrml - -#------------------------------------------------------------------------------ -# ichitaro456: file(1) magic for Just System Word Processor Ichitaro -# -# Contributor kenzo-: -# Reversed-engineered JS Ichitaro magic numbers -# - -0 string DOC ->43 byte 0x14 application/x-ichitaro4 ->144 string JDASH application/x-ichitaro4 - -0 string DOC ->43 byte 0x15 application/x-ichitaro5 - -0 string DOC ->43 byte 0x16 application/x-ichitaro6 - -#------------------------------------------------------------------------------ -# office97: file(1) magic for MicroSoft Office files -# -# Contributor kenzo-: -# Reversed-engineered MS Office magic numbers -# - -#0 string \320\317\021\340\241\261\032\341 -#>48 byte 0x1B application/excel - -2080 string Microsoft\ Excel\ 5.0\ Worksheet application/vnd.ms-excel -2114 string Biff5 application/vnd.ms-excel - -0 string \224\246\056 application/msword - -0 belong 0x31be0000 application/msword - -0 string PO^Q` application/msword - -0 string \320\317\021\340\241\261\032\341 ->546 string bjbj application/msword ->546 string jbjb application/msword - -512 string R\0o\0o\0t\0\ \0E\0n\0t\0r\0y application/msword - -2080 string Microsoft\ Word\ 6.0\ Document application/msword -2080 string Documento\ Microsoft\ Word\ 6 application/msword -2112 string MSWordDoc application/msword - -#0 string \320\317\021\340\241\261\032\341 application/powerpoint -0 string \320\317\021\340\241\261\032\341 application/msword - -0 string #\ PaCkAgE\ DaTaStReAm application/x-svr4-package - - -# WinNT/WinCE PE files (Warner Losh, imp@village.org) -# -128 string PE\000\000 application/octet-stream -0 string PE\000\000 application/octet-stream - -# miscellaneous formats -0 string LZ application/octet-stream - -# DOS device drivers by Joerg Jenderek -0 belong 0xffffffff application/octet-stream - -# .EXE formats (Greg Roelofs, newt@uchicago.edu) -# -0 string MZ ->24 string @ application/octet-stream - -0 string MZ ->30 string Copyright\ 1989-1990\ PKWARE\ Inc. application/zip - -0 string MZ ->30 string PKLITE\ Copr. application/zip - -0 string MZ ->36 string LHa's\ SFX application/x-lha - -0 string MZ application/octet-stream - -# LHA archiver -2 string -lh ->6 string - application/x-lha - - -# Zoo archiver -20 lelong 0xfdc4a7dc application/x-zoo - -# ARC archiver -0 lelong&0x8080ffff 0x0000081a application/x-arc -0 lelong&0x8080ffff 0x0000091a application/x-arc -0 lelong&0x8080ffff 0x0000021a application/x-arc -0 lelong&0x8080ffff 0x0000031a application/x-arc -0 lelong&0x8080ffff 0x0000041a application/x-arc -0 lelong&0x8080ffff 0x0000061a application/x-arc - -# Microsoft Outlook's Transport Neutral Encapsulation Format (TNEF) -0 lelong 0x223e9f78 application/vnd.ms-tnef - -# From: stephane.loeuillet@tiscali.f -# http://www.djvuzone.org/ -0 string AT&TFORM image/vnd.djvu - -# Danny Milosavljevic <danny.milo@gmx.net> -# this are adrift (adventure game standard) game files, extension .taf -# depending on version magic continues with 0x93453E6139FA (V 4.0) -# 0x9445376139FA (V 3.90) -# 0x9445366139FA (V 3.80) -# this is from source (http://www.adrift.org.uk/) and I have some taf -# files, and checked them. -#0 belong 0x3C423FC9 -#>4 belong 0x6A87C2CF application/x-adrift -#0 string \000\000\001\000 image/x-ico - -# Quark Xpress 3 Files: -# (made the mimetype up) -0 string \0\0MMXPR3\0 application/x-quark-xpress-3 - -# EET archive -# From: Tilman Sauerbeck <tilman@code-monkey.de> -0 belong 0x1ee7ff00 application/x-eet - -# From: Denis Knauf, via gentoo. -0 string fLaC audio/x-flac -0 string CWS application/x-shockwave-flash - -# Hangul Document Files: -# Reversed-engineered HWP magic numbers -# From: Won-Kyu Park <wkpark@kldp.org> -512 string R\0o\0o\0t\0 application/x-hwp - -0 string/c BEGIN:VCARD text/x-vcard -0 string WordPro\0 application/vnd.lotus-wordpro -0 string WordPro\r\373 application/vnd.lotus-wordpro -0 string CPC\262 image/x-cpi - -# -128 string DICM application/dicom - -# Symbian installation files -8 lelong 0x10000419 application/vnd.symbian.install -0 lelong 0x10201A7A x-epoc/x-sisx-app -# FORTRAN source -0 string/c c\ text/x-fortran - -# Gnumeric spreadsheet -# This entry is only semi-helpful, as Gnumeric compresses its files, so -# they will ordinarily reported as "compressed", but at least -z helps -39 string =<gmr:Workbook application/x-gnumeric
app/bundles/CoreBundle/Assets/js/libraries/ckeditor/filemanager/connectors/php/plugins/rsc/share/magic.mime.mgc+0 −0 removed
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- github.com/advisories/GHSA-qpgw-2c72-4c89ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2017-1000490ghsaADVISORY
- github.com/mautic/mautic/commit/3b01786433ae15e9a23f1eb9b0d3dfdb065b6241ghsaWEB
- github.com/mautic/mautic/releases/tag/2.12.0ghsax_refsource_CONFIRMWEB
- github.com/mautic/mautic/security/advisories/GHSA-qpgw-2c72-4c89ghsaWEB
News mentions
0No linked articles in our index yet.