r99433 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r99432‎ | r99433 | r99434 >
Date:21:36, 10 October 2011
Author:reedy
Status:reverted (Comments)
Tags:
Comment:
Noticed a couple of usages of undefined variables...

Not actually fixed, upgrade to 1.7.10
Modified paths:
  • /trunk/extensions/SwiftMedia/php-cloudfiles/cloudfiles.php (modified) (history)
  • /trunk/extensions/SwiftMedia/php-cloudfiles/cloudfiles_http.php (modified) (history)

Diff [purge]

Index: trunk/extensions/SwiftMedia/php-cloudfiles/cloudfiles.php
@@ -208,7 +208,7 @@
209209 if ($status == 401) {
210210 throw new AuthenticationException("Invalid username or access key.");
211211 }
212 - if ($status != 204 && $status != 200) {
 212+ if ($status < 200 || $status > 299) {
213213 throw new InvalidResponseException(
214214 "Unexpected response (".$status."): ".$reason);
215215 }
@@ -923,6 +923,7 @@
924924 public $bytes_used;
925925
926926 public $cdn_enabled;
 927+ public $cdn_streaming_uri;
927928 public $cdn_ssl_uri;
928929 public $cdn_uri;
929930 public $cdn_ttl;
@@ -961,6 +962,7 @@
962963 $this->cdn_enabled = NULL;
963964 $this->cdn_uri = NULL;
964965 $this->cdn_ssl_uri = NULL;
 966+ $this->cdn_streaming_uri = NULL;
965967 $this->cdn_ttl = NULL;
966968 $this->cdn_log_retention = NULL;
967969 $this->cdn_acl_user_agent = NULL;
@@ -1276,6 +1278,7 @@
12771279 $this->cdn_ttl = NULL;
12781280 $this->cdn_uri = NULL;
12791281 $this->cdn_ssl_uri = NULL;
 1282+ $this->cdn_streaming_uri - NULL;
12801283 $this->cdn_log_retention = NULL;
12811284 $this->cdn_acl_user_agent = NULL;
12821285 $this->cdn_acl_referrer = NULL;
@@ -1493,6 +1496,235 @@
14941497 }
14951498
14961499 /**
 1500+ * Copy a remote storage Object to a target Container
 1501+ *
 1502+ * Given an Object instance or name and a target Container instance or name, copy copies the remote Object
 1503+ * and all associated metadata.
 1504+ *
 1505+ * Example:
 1506+ * <code>
 1507+ * # ... authentication code excluded (see previous examples) ...
 1508+ * #
 1509+ * $conn = new CF_Authentication($auth);
 1510+ *
 1511+ * $images = $conn->get_container("my photos");
 1512+ *
 1513+ * # Copy specific object
 1514+ * #
 1515+ * $images->copy_object_to("disco_dancing.jpg","container_target");
 1516+ * </code>
 1517+ *
 1518+ * @param obj $obj name or instance of Object to copy
 1519+ * @param obj $container_target name or instance of target Container
 1520+ * @param string $dest_obj_name name of target object (optional - uses source name if omitted)
 1521+ * @param array $metadata metadata array for new object (optional)
 1522+ * @param array $headers header fields array for the new object (optional)
 1523+ * @return boolean <kbd>true</kbd> if successfully copied
 1524+ * @throws SyntaxException invalid Object/Container name
 1525+ * @throws NoSuchObjectException remote Object does not exist
 1526+ * @throws InvalidResponseException unexpected response
 1527+ */
 1528+ function copy_object_to($obj,$container_target,$dest_obj_name=NULL,$metadata=NULL,$headers=NULL)
 1529+ {
 1530+ $obj_name = NULL;
 1531+ if (is_object($obj)) {
 1532+ if (get_class($obj) == "CF_Object") {
 1533+ $obj_name = $obj->name;
 1534+ }
 1535+ }
 1536+ if (is_string($obj)) {
 1537+ $obj_name = $obj;
 1538+ }
 1539+ if (!$obj_name) {
 1540+ throw new SyntaxException("Object name not set.");
 1541+ }
 1542+
 1543+ if ($dest_obj_name === NULL) {
 1544+ $dest_obj_name = $obj_name;
 1545+ }
 1546+
 1547+ $container_name_target = NULL;
 1548+ if (is_object($container_target)) {
 1549+ if (get_class($container_target) == "CF_Container") {
 1550+ $container_name_target = $container_target->name;
 1551+ }
 1552+ }
 1553+ if (is_string($container_target)) {
 1554+ $container_name_target = $container_target;
 1555+ }
 1556+ if (!$container_name_target) {
 1557+ throw new SyntaxException("Container name target not set.");
 1558+ }
 1559+
 1560+ $status = $this->cfs_http->copy_object($obj_name,$dest_obj_name,$this->name,$container_name_target,$metadata,$headers);
 1561+ if ($status == 404) {
 1562+ $m = "Specified object '".$this->name."/".$obj_name;
 1563+ $m.= "' did not exist as source to copy from or '".$container_name_target."' did not exist as target to copy to.";
 1564+ throw new NoSuchObjectException($m);
 1565+ }
 1566+ if ($status < 200 || $status > 299) {
 1567+ throw new InvalidResponseException(
 1568+ "Invalid response (".$status."): ".$this->cfs_http->get_error());
 1569+ }
 1570+ return true;
 1571+ }
 1572+
 1573+ /**
 1574+ * Copy a remote storage Object from a source Container
 1575+ *
 1576+ * Given an Object instance or name and a source Container instance or name, copy copies the remote Object
 1577+ * and all associated metadata.
 1578+ *
 1579+ * Example:
 1580+ * <code>
 1581+ * # ... authentication code excluded (see previous examples) ...
 1582+ * #
 1583+ * $conn = new CF_Authentication($auth);
 1584+ *
 1585+ * $images = $conn->get_container("my photos");
 1586+ *
 1587+ * # Copy specific object
 1588+ * #
 1589+ * $images->copy_object_from("disco_dancing.jpg","container_source");
 1590+ * </code>
 1591+ *
 1592+ * @param obj $obj name or instance of Object to copy
 1593+ * @param obj $container_source name or instance of source Container
 1594+ * @param string $dest_obj_name name of target object (optional - uses source name if omitted)
 1595+ * @param array $metadata metadata array for new object (optional)
 1596+ * @param array $headers header fields array for the new object (optional)
 1597+ * @return boolean <kbd>true</kbd> if successfully copied
 1598+ * @throws SyntaxException invalid Object/Container name
 1599+ * @throws NoSuchObjectException remote Object does not exist
 1600+ * @throws InvalidResponseException unexpected response
 1601+ */
 1602+ function copy_object_from($obj,$container_source,$dest_obj_name=NULL,$metadata=NULL,$headers=NULL)
 1603+ {
 1604+ $obj_name = NULL;
 1605+ if (is_object($obj)) {
 1606+ if (get_class($obj) == "CF_Object") {
 1607+ $obj_name = $obj->name;
 1608+ }
 1609+ }
 1610+ if (is_string($obj)) {
 1611+ $obj_name = $obj;
 1612+ }
 1613+ if (!$obj_name) {
 1614+ throw new SyntaxException("Object name not set.");
 1615+ }
 1616+
 1617+ if ($dest_obj_name === NULL) {
 1618+ $dest_obj_name = $obj_name;
 1619+ }
 1620+
 1621+ $container_name_source = NULL;
 1622+ if (is_object($container_source)) {
 1623+ if (get_class($container_source) == "CF_Container") {
 1624+ $container_name_source = $container_source->name;
 1625+ }
 1626+ }
 1627+ if (is_string($container_source)) {
 1628+ $container_name_source = $container_source;
 1629+ }
 1630+ if (!$container_name_source) {
 1631+ throw new SyntaxException("Container name source not set.");
 1632+ }
 1633+
 1634+ $status = $this->cfs_http->copy_object($obj_name,$dest_obj_name,$container_name_source,$this->name,$metadata,$headers);
 1635+ if ($status == 404) {
 1636+ $m = "Specified object '".$container_name_source."/".$obj_name;
 1637+ $m.= "' did not exist as source to copy from or '".$this->name."/".$obj_name."' did not exist as target to copy to.";
 1638+ throw new NoSuchObjectException($m);
 1639+ }
 1640+ if ($status < 200 || $status > 299) {
 1641+ throw new InvalidResponseException(
 1642+ "Invalid response (".$status."): ".$this->cfs_http->get_error());
 1643+ }
 1644+
 1645+ return true;
 1646+ }
 1647+
 1648+ /**
 1649+ * Move a remote storage Object to a target Container
 1650+ *
 1651+ * Given an Object instance or name and a target Container instance or name, move copies the remote Object
 1652+ * and all associated metadata and deletes the source Object afterwards
 1653+ *
 1654+ * Example:
 1655+ * <code>
 1656+ * # ... authentication code excluded (see previous examples) ...
 1657+ * #
 1658+ * $conn = new CF_Authentication($auth);
 1659+ *
 1660+ * $images = $conn->get_container("my photos");
 1661+ *
 1662+ * # Move specific object
 1663+ * #
 1664+ * $images->move_object_to("disco_dancing.jpg","container_target");
 1665+ * </code>
 1666+ *
 1667+ * @param obj $obj name or instance of Object to move
 1668+ * @param obj $container_target name or instance of target Container
 1669+ * @param string $dest_obj_name name of target object (optional - uses source name if omitted)
 1670+ * @param array $metadata metadata array for new object (optional)
 1671+ * @param array $headers header fields array for the new object (optional)
 1672+ * @return boolean <kbd>true</kbd> if successfully moved
 1673+ * @throws SyntaxException invalid Object/Container name
 1674+ * @throws NoSuchObjectException remote Object does not exist
 1675+ * @throws InvalidResponseException unexpected response
 1676+ */
 1677+ function move_object_to($obj,$container_target,$dest_obj_name=NULL,$metadata=NULL,$headers=NULL)
 1678+ {
 1679+ $retVal = false;
 1680+
 1681+ if(self::copy_object_to($obj,$container_target,$dest_obj_name,$metadata,$headers)) {
 1682+ $retVal = self::delete_object($obj,$this->name);
 1683+ }
 1684+
 1685+ return $retVal;
 1686+ }
 1687+
 1688+ /**
 1689+ * Move a remote storage Object from a source Container
 1690+ *
 1691+ * Given an Object instance or name and a source Container instance or name, move copies the remote Object
 1692+ * and all associated metadata and deletes the source Object afterwards
 1693+ *
 1694+ * Example:
 1695+ * <code>
 1696+ * # ... authentication code excluded (see previous examples) ...
 1697+ * #
 1698+ * $conn = new CF_Authentication($auth);
 1699+ *
 1700+ * $images = $conn->get_container("my photos");
 1701+ *
 1702+ * # Move specific object
 1703+ * #
 1704+ * $images->move_object_from("disco_dancing.jpg","container_target");
 1705+ * </code>
 1706+ *
 1707+ * @param obj $obj name or instance of Object to move
 1708+ * @param obj $container_source name or instance of target Container
 1709+ * @param string $dest_obj_name name of target object (optional - uses source name if omitted)
 1710+ * @param array $metadata metadata array for new object (optional)
 1711+ * @param array $headers header fields array for the new object (optional)
 1712+ * @return boolean <kbd>true</kbd> if successfully moved
 1713+ * @throws SyntaxException invalid Object/Container name
 1714+ * @throws NoSuchObjectException remote Object does not exist
 1715+ * @throws InvalidResponseException unexpected response
 1716+ */
 1717+ function move_object_from($obj,$container_source,$dest_obj_name=NULL,$metadata=NULL,$headers=NULL)
 1718+ {
 1719+ $retVal = false;
 1720+
 1721+ if(self::copy_object_from($obj,$container_source,$dest_obj_name,$metadata,$headers)) {
 1722+ $retVal = self::delete_object($obj,$container_source);
 1723+ }
 1724+
 1725+ return $retVal;
 1726+ }
 1727+
 1728+ /**
14971729 * Delete a remote storage Object
14981730 *
14991731 * Given an Object instance or name, permanently remove the remote Object
@@ -1512,12 +1744,13 @@
15131745 * </code>
15141746 *
15151747 * @param obj $obj name or instance of Object to delete
 1748+ * @param obj $container name or instance of Container in which the object resides (optional)
15161749 * @return boolean <kbd>True</kbd> if successfully removed
15171750 * @throws SyntaxException invalid Object name
15181751 * @throws NoSuchObjectException remote Object does not exist
15191752 * @throws InvalidResponseException unexpected response
15201753 */
1521 - function delete_object($obj)
 1754+ function delete_object($obj,$container=NULL)
15221755 {
15231756 $obj_name = NULL;
15241757 if (is_object($obj)) {
@@ -1531,12 +1764,32 @@
15321765 if (!$obj_name) {
15331766 throw new SyntaxException("Object name not set.");
15341767 }
1535 - $status = $this->cfs_http->delete_object($this->name, $obj_name);
 1768+
 1769+ $container_name = NULL;
 1770+
 1771+ if($container === NULL) {
 1772+ $container_name = $this->name;
 1773+ }
 1774+ else {
 1775+ if (is_object($container)) {
 1776+ if (get_class($container) == "CF_Container") {
 1777+ $container_name = $container->name;
 1778+ }
 1779+ }
 1780+ if (is_string($container)) {
 1781+ $container_name = $container;
 1782+ }
 1783+ if (!$container_name) {
 1784+ throw new SyntaxException("Container name source not set.");
 1785+ }
 1786+ }
 1787+
 1788+ $status = $this->cfs_http->delete_object($container_name, $obj_name);
15361789 #if ($status == 401 && $this->_re_auth()) {
15371790 # return $this->delete_object($obj);
15381791 #}
15391792 if ($status == 404) {
1540 - $m = "Specified object '".$this->name."/".$obj_name;
 1793+ $m = "Specified object '".$container_name."/".$obj_name;
15411794 $m.= "' did not exist to delete.";
15421795 throw new NoSuchObjectException($m);
15431796 }
@@ -1552,7 +1805,7 @@
15531806 *
15541807 * Given an Object whos name contains '/' path separators, this function
15551808 * will create the "directory marker" Objects of one byte with the
1556 - * Content-Type of "application/folder".
 1809+ * Content-Type of "application/directory".
15571810 *
15581811 * It assumes the last element of the full path is the "real" Object
15591812 * and does NOT create a remote storage Object for that last element.
@@ -1583,7 +1836,7 @@
15841837 */
15851838 private function _cdn_initialize()
15861839 {
1587 - list($status, $reason, $cdn_enabled, $cdn_ssl_uri, $cdn_uri, $cdn_ttl,
 1840+ list($status, $reason, $cdn_enabled, $cdn_ssl_uri, $cdn_streaming_uri, $cdn_uri, $cdn_ttl,
15881841 $cdn_log_retention, $cdn_acl_user_agent, $cdn_acl_referrer) =
15891842 $this->cfs_http->head_cdn_container($this->name);
15901843 #if ($status == 401 && $this->_re_auth()) {
@@ -1594,6 +1847,7 @@
15951848 "Invalid response (".$status."): ".$this->cfs_http->get_error());
15961849 }
15971850 $this->cdn_enabled = $cdn_enabled;
 1851+ $this->cdn_streaming_uri = $cdn_streaming_uri;
15981852 $this->cdn_ssl_uri = $cdn_ssl_uri;
15991853 $this->cdn_uri = $cdn_uri;
16001854 $this->cdn_ttl = $cdn_ttl;
@@ -1634,6 +1888,7 @@
16351889 public $content_type;
16361890 public $content_length;
16371891 public $metadata;
 1892+ public $headers;
16381893 public $manifest;
16391894 private $etag;
16401895
@@ -1663,6 +1918,7 @@
16641919 $this->content_type = NULL;
16651920 $this->content_length = 0;
16661921 $this->metadata = array();
 1922+ $this->headers = array();
16671923 $this->manifest = NULL;
16681924 if ($dohead) {
16691925 if (!$this->_initialize() && $force_exists) {
@@ -1800,6 +2056,31 @@
18012057 }
18022058 return NULL;
18032059 }
 2060+ /**
 2061+ * String representation of the Object's public Streaming URI
 2062+ *
 2063+ * A string representing the Object's public Streaming URI assuming that it's
 2064+ * parent Container is CDN-enabled.
 2065+ *
 2066+ * Example:
 2067+ * <code>
 2068+ * # ... authentication/connection/container code excluded
 2069+ * # ... see previous examples
 2070+ *
 2071+ * # Print out the Object's CDN Streaming URI (if it has one) in an HTML img-tag
 2072+ * #
 2073+ * print "<img src='$pic->public_streaming_uri()' />\n";
 2074+ * </code>
 2075+ *
 2076+ * @return string Object's public Streaming URI or NULL
 2077+ */
 2078+ function public_streaming_uri()
 2079+ {
 2080+ if ($this->container->cdn_enabled) {
 2081+ return $this->container->cdn_streaming_uri . "/" . $this->name;
 2082+ }
 2083+ return NULL;
 2084+ }
18042085
18052086 /**
18062087 * Read the remote Object's data
@@ -1923,6 +2204,12 @@
19242205 * "Version" => "1.2.2"
19252206 * );
19262207 *
 2208+ * # Define additional headers for the object
 2209+ * #
 2210+ * $doc->headers = array(
 2211+ * "Content-Disposition" => "attachment",
 2212+ * );
 2213+ *
19272214 * # Push the new metadata up to the storage system
19282215 * #
19292216 * $doc->sync_metadata();
@@ -1933,7 +2220,7 @@
19342221 */
19352222 function sync_metadata()
19362223 {
1937 - if (!empty($this->metadata) || $this->manifest) {
 2224+ if (!empty($this->metadata) || !empty($this->headers) || $this->manifest) {
19382225 $status = $this->container->cfs_http->update_object($this);
19392226 #if ($status == 401 && $this->_re_auth()) {
19402227 # return $this->sync_metadata();
@@ -1976,8 +2263,8 @@
19772264 function sync_manifest()
19782265 {
19792266 return $this->sync_metadata();
1980 - }
1981 - /**
 2267+ }
 2268+ /**
19822269 * Upload Object's data to Cloud Files
19832270 *
19842271 * Write data to the remote Object. The $data argument can either be a
@@ -2074,54 +2361,6 @@
20752362 return True;
20762363 }
20772364
2078 - /**
2079 - * Copy one Object to another Object to Cloud Files
2080 - *
2081 - * Example:
2082 - * <code>
2083 - * # ... authentication/connection/container code excluded
2084 - * # ... see previous examples
2085 - *
2086 - * $my_docs = $conn->get_container("documents");
2087 - * $doc = $my_docs->get_object("README");
2088 - *
2089 - * # Copy README.txt on top of this object (which you must have
2090 - * already written something to).
2091 - * #
2092 - * $doc->copy("/documents/README.txt");
2093 - * </code>
2094 - *
2095 - * @param string $source Name of existing object
2096 - * @return boolean <kbd>True</kbd> when data uploaded successfully
2097 - * @throws SyntaxException missing required parameters
2098 - * @throws BadContentTypeException if no Content-Type was/could be set
2099 - * @throws MisMatchedChecksumException $verify is set and checksums unequal
2100 - * @throws InvalidResponseException unexpected response
2101 - */
2102 - function copy($source)
2103 - {
2104 - if (!$source && !is_string($source)) {
2105 - throw new SyntaxException("Missing data source.");
2106 - }
2107 - list($status, $reason, $etag) =
2108 - $this->container->cfs_http->put_object($this, $source);
2109 - #if ($status == 401 && $this->_re_auth()) {
2110 - # return $this->copy($data, $source);
2111 - #}
2112 - if ($status == 412) {
2113 - throw new SyntaxException("Missing Content-Type header");
2114 - }
2115 - if ($status == 422) {
2116 - throw new MisMatchedChecksumException(
2117 - "Supplied and computed checksums do not match.");
2118 - }
2119 - if ($status != 201) {
2120 - throw new InvalidResponseException("Invalid response (".$status."): "
2121 - . $this->container->cfs_http->get_error());
2122 - }
2123 - return True;
2124 - }
2125 -
21262365 /**
21272366 * Upload Object data from local filename
21282367 *
@@ -2305,8 +2544,8 @@
23062545 private function _initialize()
23072546 {
23082547 list($status, $reason, $etag, $last_modified, $content_type,
2309 - $content_length, $metadata) =
2310 - $this->container->cfs_http->head_object($this);
 2548+ $content_length, $metadata, $manifest, $headers) =
 2549+ $this->container->cfs_http->head_object($this);
23112550 #if ($status == 401 && $this->_re_auth()) {
23122551 # return $this->_initialize();
23132552 #}
@@ -2322,7 +2561,8 @@
23232562 $this->content_type = $content_type;
23242563 $this->content_length = $content_length;
23252564 $this->metadata = $metadata;
2326 - $this->manifest = NULL;
 2565+ $this->headers = $headers;
 2566+ $this->manifest = $manifest;
23272567 return True;
23282568 }
23292569
@@ -2349,4 +2589,4 @@
23502590 * c-hanging-comment-ender-p: nil
23512591 * End:
23522592 */
2353 -?>
 2593+?>
\ No newline at end of file
Index: trunk/extensions/SwiftMedia/php-cloudfiles/cloudfiles_http.php
@@ -29,16 +29,22 @@
3030 */
3131 require_once("cloudfiles_exceptions.php");
3232
33 -define("PHP_CF_VERSION", "1.7.9");
 33+define("PHP_CF_VERSION", "1.7.10");
3434 define("USER_AGENT", sprintf("PHP-CloudFiles/%s", PHP_CF_VERSION));
 35+define("MAX_HEADER_NAME_LEN", 128);
 36+define("MAX_HEADER_VALUE_LEN", 256);
3537 define("ACCOUNT_CONTAINER_COUNT", "X-Account-Container-Count");
3638 define("ACCOUNT_BYTES_USED", "X-Account-Bytes-Used");
3739 define("CONTAINER_OBJ_COUNT", "X-Container-Object-Count");
3840 define("CONTAINER_BYTES_USED", "X-Container-Bytes-Used");
39 -define("METADATA_HEADER", "X-Object-Meta-");
4041 define("MANIFEST_HEADER", "X-Object-Manifest");
 42+define("METADATA_HEADER_PREFIX", "X-Object-Meta-");
 43+define("CONTENT_HEADER_PREFIX", "Content-");
 44+define("ACCESS_CONTROL_HEADER_PREFIX", "Access-Control-");
 45+define("ORIGIN_HEADER", "Origin");
4146 define("CDN_URI", "X-CDN-URI");
4247 define("CDN_SSL_URI", "X-CDN-SSL-URI");
 48+define("CDN_STREAMING_URI", "X-CDN-Streaming-URI");
4349 define("CDN_ENABLED", "X-CDN-Enabled");
4450 define("CDN_LOG_RETENTION", "X-Log-Retention");
4551 define("CDN_ACL_USER_AGENT", "X-User-Agent-ACL");
@@ -53,6 +59,13 @@
5460 define("AUTH_KEY_HEADER_LEGACY", "X-Storage-Pass");
5561 define("AUTH_TOKEN_LEGACY", "X-Storage-Token");
5662 define("CDN_EMAIL", "X-Purge-Email");
 63+define("DESTINATION", "Destination");
 64+define("ETAG_HEADER", "ETag");
 65+define("LAST_MODIFIED_HEADER", "Last-Modified");
 66+define("CONTENT_TYPE_HEADER", "Content-Type");
 67+define("CONTENT_LENGTH_HEADER", "Content-Length");
 68+define("USER_AGENT_HEADER", "User-Agent");
 69+
5770 /**
5871 * HTTP/cURL wrapper for Cloud Files
5972 *
@@ -95,11 +108,13 @@
96109 private $_obj_content_type;
97110 private $_obj_content_length;
98111 private $_obj_metadata;
 112+ private $_obj_headers;
99113 private $_obj_manifest;
100114 private $_obj_write_resource;
101115 private $_obj_write_string;
102116 private $_cdn_enabled;
103117 private $_cdn_ssl_uri;
 118+ private $_cdn_streaming_uri;
104119 private $_cdn_uri;
105120 private $_cdn_ttl;
106121 private $_cdn_log_retention;
@@ -131,6 +146,7 @@
132147 "HEAD" => NULL, # HEAD requests
133148 "PUT_CONT" => NULL, # PUT container
134149 "DEL_POST" => NULL, # DELETE containers/objects, POST objects
 150+ "COPY" => null, # COPY objects
135151 );
136152
137153 $this->_user_read_progress_callback_func = NULL;
@@ -150,8 +166,10 @@
151167 $this->_obj_content_length = NULL;
152168 $this->_obj_metadata = array();
153169 $this->_obj_manifest = NULL;
 170+ $this->_obj_headers = NULL;
154171 $this->_cdn_enabled = NULL;
155172 $this->_cdn_ssl_uri = NULL;
 173+ $this->_cdn_streaming_uri = NULL;
156174 $this->_cdn_uri = NULL;
157175 $this->_cdn_ttl = NULL;
158176 $this->_cdn_log_retention = NULL;
@@ -212,7 +230,6 @@
213231 curl_setopt($curl_ch, CURLOPT_SSL_VERIFYPEER, True);
214232 curl_setopt($curl_ch, CURLOPT_CAINFO, $this->cabundle_path);
215233 }
216 - curl_setopt($curl_ch, CURLOPT_SSL_VERIFYPEER, False);
217234 curl_setopt($curl_ch, CURLOPT_VERBOSE, $this->dbug);
218235 curl_setopt($curl_ch, CURLOPT_FOLLOWLOCATION, 1);
219236 curl_setopt($curl_ch, CURLOPT_MAXREDIRS, 4);
@@ -249,7 +266,7 @@
250267 }
251268 if (!$return_code) {
252269 $this->error_str .= ": Failed to obtain valid HTTP response.";
253 - array(0,$this->error_str,array());
 270+ return array(0,$this->error_str,array());
254271 }
255272 if ($return_code == 401) {
256273 return array($return_code,"Unauthorized",array());
@@ -393,17 +410,18 @@
394411
395412 if (!$return_code) {
396413 $this->error_str .= ": Failed to obtain valid HTTP response.";
397 - return array(0,$this->error_str,NULL,NULL,NULL,NULL,NULL,NULL);
 414+ return array(0,$this->error_str,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
398415 }
399416 if ($return_code == 401) {
400 - return array($return_code,"Unauthorized",NULL,NULL,NULL,NULL,NULL,NULL);
 417+ return array($return_code,"Unauthorized",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
401418 }
402419 if ($return_code == 404) {
403 - return array($return_code,"Account not found.",NULL,NULL,NULL,NULL,NULL,NULL);
 420+ return array($return_code,"Account not found.",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
404421 }
405422 if ($return_code == 204) {
406423 return array($return_code,$this->response_reason,
407424 $this->_cdn_enabled, $this->_cdn_ssl_uri,
 425+ $this->_cdn_streaming_uri,
408426 $this->_cdn_uri, $this->_cdn_ttl,
409427 $this->_cdn_log_retention,
410428 $this->_cdn_acl_user_agent,
@@ -411,10 +429,11 @@
412430 );
413431 }
414432 return array($return_code,$this->response_reason,
415 - NULL,NULL,NULL,
 433+ NULL,NULL,NULL,NULL,
416434 $this->_cdn_log_retention,
417435 $this->_cdn_acl_user_agent,
418 - $this->_cdn_acl_referrer
 436+ $this->_cdn_acl_referrer,
 437+ NULL
419438 );
420439 }
421440
@@ -511,7 +530,7 @@
512531
513532 if (!$return_code) {
514533 $this->error_str .= ": Failed to obtain valid HTTP response.";
515 - array(0,$this->error_str,0,0);
 534+ return array(0,$this->error_str,0,0);
516535 }
517536 if ($return_code == 404) {
518537 return array($return_code,"Account not found.",0,0);
@@ -556,16 +575,19 @@
557576 $url_path = $this->_make_path("STORAGE", $container_name);
558577 $return_code = $this->_send_request("DEL_POST",$url_path,array(),"DELETE");
559578
560 - if (!$return_code) {
561 - $this->error_str .= ": Failed to obtain valid HTTP response.";
562 - }
563 - if ($return_code == 409) {
 579+ switch ($return_code) {
 580+ case 204:
 581+ break;
 582+ case 0:
 583+ $this->error_str .= ": Failed to obtain valid HTTP response.";;
 584+ break;
 585+ case 409:
564586 $this->error_str = "Container must be empty prior to removing it.";
565 - }
566 - if ($return_code == 404) {
 587+ break;
 588+ case 404:
567589 $this->error_str = "Specified container did not exist to delete.";
568 - }
569 - if ($return_code != 204) {
 590+ break;
 591+ default:
570592 $this->error_str = "Unexpected HTTP return code: $return_code.";
571593 }
572594 return $return_code;
@@ -701,7 +723,7 @@
702724
703725 if (!$return_code) {
704726 $this->error_str .= ": Failed to obtain valid HTTP response.";
705 - array(0,$this->error_str,0,0);
 727+ return array(0,$this->error_str,0,0);
706728 }
707729 if ($return_code == 404) {
708730 return array($return_code,"Container not found.",0,0);
@@ -788,10 +810,7 @@
789811 throw new SyntaxException(
790812 "Method argument is not a valid CF_Object.");
791813 }
792 - $source = NULL;
793 - if (is_string($fp)) {
794 - $source = $fp;
795 - } elseif (!is_resource($fp)) {
 814+ if (!is_resource($fp)) {
796815 throw new SyntaxException(
797816 "File pointer argument is not a valid resource.");
798817 }
@@ -799,40 +818,32 @@
800819 $conn_type = "PUT_OBJ";
801820 $url_path = $this->_make_path("STORAGE", $obj->container->name,$obj->name);
802821
803 - $hdrs = $this->_metadata_headers($obj);
 822+ $hdrs = $this->_headers($obj);
804823
805824 $etag = $obj->getETag();
806 - if (!$source && isset($etag)) {
 825+ if (isset($etag)) {
807826 $hdrs[] = "ETag: " . $etag;
808827 }
809 - if ($source) {
810 - // If we don't include a content-type it will copy over the existing one.
811 - } elseif (!$obj->content_type) {
 828+ if (!$obj->content_type) {
812829 $hdrs[] = "Content-Type: application/octet-stream";
813830 } else {
814831 $hdrs[] = "Content-Type: " . $obj->content_type;
815832 }
816833
817834 $this->_init($conn_type);
818 - if ($source) {
819 - $hdrs[] = "X-Copy-From: " . rawurlencode($source);
 835+ curl_setopt($this->connections[$conn_type],
 836+ CURLOPT_INFILE, $fp);
 837+ if (!$obj->content_length) {
 838+ # We don''t know the Content-Length, so assumed "chunked" PUT
 839+ #
 840+ curl_setopt($this->connections[$conn_type], CURLOPT_UPLOAD, True);
 841+ $hdrs[] = 'Transfer-Encoding: chunked';
 842+ } else {
 843+ # We know the Content-Length, so use regular transfer
 844+ #
820845 curl_setopt($this->connections[$conn_type],
821 - CURLOPT_INFILESIZE, 0);
822 - } else {
823 - curl_setopt($this->connections[$conn_type],
824 - CURLOPT_INFILE, $fp);
825 - if (!$obj->content_length) {
826 - # We don''t know the Content-Length, so assumed "chunked" PUT
827 - #
828 - curl_setopt($this->connections[$conn_type], CURLOPT_UPLOAD, True);
829 - $hdrs[] = 'Transfer-Encoding: chunked';
830 - } else {
831 - # We know the Content-Length, so use regular transfer
832 - #
833 - curl_setopt($this->connections[$conn_type],
834 - CURLOPT_INFILESIZE, $obj->content_length);
835 - }
836 - }
 846+ CURLOPT_INFILESIZE, $obj->content_length);
 847+ }
837848 $return_code = $this->_send_request($conn_type,$url_path,$hdrs);
838849
839850 if (!$return_code) {
@@ -863,25 +874,29 @@
864875 "Method argument is not a valid CF_Object.");
865876 }
866877
867 - if (!is_array($obj->metadata) && !$obj->manifest) {
868 -
869 - $this->error_str = "Metadata array is empty.";
 878+ # TODO: The is_array check isn't in sync with the error message
 879+ if (!$obj->manifest && !(is_array($obj->metadata) || is_array($obj->headers))) {
 880+ $this->error_str = "Metadata and headers arrays are empty.";
870881 return 0;
871882 }
872883
873884 $url_path = $this->_make_path("STORAGE", $obj->container->name,$obj->name);
874885
875 - $hdrs = $this->_metadata_headers($obj);
 886+ $hdrs = $this->_headers($obj);
876887 $return_code = $this->_send_request("DEL_POST",$url_path,$hdrs,"POST");
877 - if (!$return_code) {
 888+ switch ($return_code) {
 889+ case 202:
 890+ break;
 891+ case 0:
878892 $this->error_str .= ": Failed to obtain valid HTTP response.";
879 - return 0;
880 - }
881 - if ($return_code == 404) {
 893+ $return_code = 0;
 894+ break;
 895+ case 404:
882896 $this->error_str = "Account, Container, or Object not found.";
883 - }
884 - if ($return_code != 202) {
 897+ break;
 898+ default:
885899 $this->error_str = "Unexpected HTTP return code: $return_code";
 900+ break;
886901 }
887902 return $return_code;
888903 }
@@ -903,12 +918,12 @@
904919 if (!$return_code) {
905920 $this->error_str .= ": Failed to obtain valid HTTP response.";
906921 return array(0, $this->error_str." ".$this->response_reason,
907 - NULL, NULL, NULL, NULL, array());
 922+ NULL, NULL, NULL, NULL, array(), NULL, array());
908923 }
909924
910925 if ($return_code == 404) {
911926 return array($return_code, $this->response_reason,
912 - NULL, NULL, NULL, NULL, array());
 927+ NULL, NULL, NULL, NULL, array(), NULL, array());
913928 }
914929 if ($return_code == 204 || $return_code == 200) {
915930 return array($return_code,$this->response_reason,
@@ -917,13 +932,68 @@
918933 $this->_obj_content_type,
919934 $this->_obj_content_length,
920935 $this->_obj_metadata,
921 - $this->_obj_manifest);
 936+ $this->_obj_manifest,
 937+ $this->_obj_headers);
922938 }
923939 $this->error_str = "Unexpected HTTP return code: $return_code";
924940 return array($return_code, $this->error_str." ".$this->response_reason,
925 - NULL, NULL, NULL, NULL, array());
 941+ NULL, NULL, NULL, NULL, array(), NULL, array());
926942 }
927943
 944+ # COPY /v1/Account/Container/Object
 945+ #
 946+ function copy_object($src_obj_name, $dest_obj_name, $container_name_source, $container_name_target, $metadata=NULL, $headers=NULL)
 947+ {
 948+ if (!$src_obj_name) {
 949+ $this->error_str = "Object name not set.";
 950+ return 0;
 951+ }
 952+
 953+ if ($container_name_source == "") {
 954+ $this->error_str = "Container name source not set.";
 955+ return 0;
 956+ }
 957+
 958+ if ($container_name_source != "0" and !isset($container_name_source)) {
 959+ $this->error_str = "Container name source not set.";
 960+ return 0;
 961+ }
 962+
 963+ if ($container_name_target == "") {
 964+ $this->error_str = "Container name target not set.";
 965+ return 0;
 966+ }
 967+
 968+ if ($container_name_target != "0" and !isset($container_name_target)) {
 969+ $this->error_str = "Container name target not set.";
 970+ return 0;
 971+ }
 972+
 973+ $conn_type = "COPY";
 974+
 975+ $url_path = $this->_make_path("STORAGE", $container_name_source, rawurlencode($src_obj_name));
 976+ $destination = rawurlencode($container_name_target."/".$dest_obj_name);
 977+
 978+ $hdrs = self::_process_headers($metadata, $headers);
 979+ $hdrs[DESTINATION] = $destination;
 980+
 981+ $return_code = $this->_send_request($conn_type,$url_path,$hdrs,"COPY");
 982+ switch ($return_code) {
 983+ case 201:
 984+ break;
 985+ case 0:
 986+ $this->error_str .= ": Failed to obtain valid HTTP response.";
 987+ $return_code = 0;
 988+ break;
 989+ case 404:
 990+ $this->error_str = "Specified container/object did not exist.";
 991+ break;
 992+ default:
 993+ $this->error_str = "Unexpected HTTP return code: $return_code.";
 994+ }
 995+ return $return_code;
 996+ }
 997+
928998 # DELETE /v1/Account/Container/Object
929999 #
9301000 function delete_object($container_name, $object_name)
@@ -945,14 +1015,17 @@
9461016
9471017 $url_path = $this->_make_path("STORAGE", $container_name,$object_name);
9481018 $return_code = $this->_send_request("DEL_POST",$url_path,NULL,"DELETE");
949 - if (!$return_code) {
 1019+ switch ($return_code) {
 1020+ case 204:
 1021+ break;
 1022+ case 0:
9501023 $this->error_str .= ": Failed to obtain valid HTTP response.";
951 - return 0;
952 - }
953 - if ($return_code == 404) {
 1024+ $return_code = 0;
 1025+ break;
 1026+ case 404:
9541027 $this->error_str = "Specified container did not exist to delete.";
955 - }
956 - if ($return_code != 204) {
 1028+ break;
 1029+ default:
9571030 $this->error_str = "Unexpected HTTP return code: $return_code.";
9581031 }
9591032 return $return_code;
@@ -1011,112 +1084,85 @@
10121085
10131086 private function _header_cb($ch, $header)
10141087 {
1015 - preg_match("/^HTTP\/1\.[01] (\d{3}) (.*)/", $header, $matches);
1016 - if (isset($matches[1])) {
1017 - $this->response_status = $matches[1];
1018 - }
1019 - if (isset($matches[2])) {
1020 - $this->response_reason = $matches[2];
1021 - }
1022 - if (stripos($header, CDN_ENABLED) === 0) {
1023 - $val = trim(substr($header, strlen(CDN_ENABLED)+1));
1024 - if (strtolower($val) == "true") {
1025 - $this->_cdn_enabled = True;
1026 - } elseif (strtolower($val) == "false") {
1027 - $this->_cdn_enabled = False;
1028 - } else {
1029 - $this->_cdn_enabled = NULL;
1030 - }
1031 - return strlen($header);
1032 - }
1033 - if (stripos($header, CDN_URI) === 0) {
1034 - $this->_cdn_uri = trim(substr($header, strlen(CDN_URI)+1));
1035 - return strlen($header);
1036 - }
1037 - if (stripos($header, CDN_SSL_URI) === 0) {
1038 - $this->_cdn_ssl_uri = trim(substr($header, strlen(CDN_SSL_URI)+1));
1039 - return strlen($header);
1040 - }
1041 - if (stripos($header, CDN_TTL) === 0) {
1042 - $this->_cdn_ttl = trim(substr($header, strlen(CDN_TTL)+1))+0;
1043 - return strlen($header);
1044 - }
1045 - if (stripos($header, MANIFEST_HEADER) === 0) {
1046 - $this->_obj_manifest = trim(substr($header, strlen(MANIFEST_HEADER)+1));
1047 - return strlen($header);
1048 - }
1049 - if (stripos($header, CDN_LOG_RETENTION) === 0) {
1050 - $this->_cdn_log_retention =
1051 - trim(substr($header, strlen(CDN_LOG_RETENTION)+1)) == "True" ? True : False;
1052 - return strlen($header);
1053 - }
 1088+ $header_len = strlen($header);
10541089
1055 - if (stripos($header, CDN_ACL_USER_AGENT) === 0) {
1056 - $this->_cdn_acl_user_agent =
1057 - trim(substr($header, strlen(CDN_ACL_USER_AGENT)+1));
1058 - return strlen($header);
 1090+ if (preg_match("/^(HTTP\/1\.[01]) (\d{3}) (.*)/", $header, $matches)) {
 1091+ $this->response_status = $matches[2];
 1092+ $this->response_reason = $matches[3];
 1093+ return $header_len;
10591094 }
10601095
1061 - if (stripos($header, CDN_ACL_REFERRER) === 0) {
1062 - $this->_cdn_acl_referrer =
1063 - trim(substr($header, strlen(CDN_ACL_REFERRER)+1));
1064 - return strlen($header);
 1096+ if (strpos($header, ":") === False)
 1097+ return $header_len;
 1098+ list($name, $value) = explode(":", $header, 2);
 1099+ $value = trim($value);
 1100+
 1101+ switch (strtolower($name)) {
 1102+ case strtolower(CDN_ENABLED):
 1103+ $this->_cdn_enabled = strtolower($value) == "true";
 1104+ break;
 1105+ case strtolower(CDN_URI):
 1106+ $this->_cdn_uri = $value;
 1107+ break;
 1108+ case strtolower(CDN_SSL_URI):
 1109+ $this->_cdn_ssl_uri = $value;
 1110+ break;
 1111+ case strtolower(CDN_STREAMING_URI):
 1112+ $this->_cdn_streaming_uri = $value;
 1113+ break;
 1114+ case strtolower(CDN_TTL):
 1115+ $this->_cdn_ttl = $value;
 1116+ break;
 1117+ case strtolower(MANIFEST_HEADER):
 1118+ $this->_obj_manifest = $value;
 1119+ break;
 1120+ case strtolower(CDN_LOG_RETENTION):
 1121+ $this->_cdn_log_retention = strtolower($value) == "true";
 1122+ break;
 1123+ case strtolower(CDN_ACL_USER_AGENT):
 1124+ $this->_cdn_acl_user_agent = $value;
 1125+ break;
 1126+ case strtolower(CDN_ACL_REFERRER):
 1127+ $this->_cdn_acl_referrer = $value;
 1128+ break;
 1129+ case strtolower(ACCOUNT_CONTAINER_COUNT):
 1130+ $this->_account_container_count = (float)$value+0;
 1131+ break;
 1132+ case strtolower(ACCOUNT_BYTES_USED):
 1133+ $this->_account_bytes_used = (float)$value+0;
 1134+ break;
 1135+ case strtolower(CONTAINER_OBJ_COUNT):
 1136+ $this->_container_object_count = (float)$value+0;
 1137+ break;
 1138+ case strtolower(CONTAINER_BYTES_USED):
 1139+ $this->_container_bytes_used = (float)$value+0;
 1140+ break;
 1141+ case strtolower(ETAG_HEADER):
 1142+ $this->_obj_etag = $value;
 1143+ break;
 1144+ case strtolower(LAST_MODIFIED_HEADER):
 1145+ $this->_obj_last_modified = $value;
 1146+ break;
 1147+ case strtolower(CONTENT_TYPE_HEADER):
 1148+ $this->_obj_content_type = $value;
 1149+ break;
 1150+ case strtolower(CONTENT_LENGTH_HEADER):
 1151+ $this->_obj_content_length = (float)$value+0;
 1152+ break;
 1153+ case strtolower(ORIGIN_HEADER):
 1154+ $this->_obj_headers[ORIGIN_HEADER] = $value;
 1155+ break;
 1156+ default:
 1157+ if (strncasecmp($name, METADATA_HEADER_PREFIX, strlen(METADATA_HEADER_PREFIX)) == 0) {
 1158+ $name = substr($name, strlen(METADATA_HEADER_PREFIX));
 1159+ $this->_obj_metadata[$name] = $value;
 1160+ }
 1161+ elseif ((strncasecmp($name, CONTENT_HEADER_PREFIX, strlen(CONTENT_HEADER_PREFIX)) == 0) ||
 1162+ (strncasecmp($name, ACCESS_CONTROL_HEADER_PREFIX, strlen(ACCESS_CONTROL_HEADER_PREFIX)) == 0)) {
 1163+ $this->_obj_headers[$name] = $value;
 1164+ }
10651165 }
1066 -
1067 - if (stripos($header, ACCOUNT_CONTAINER_COUNT) === 0) {
1068 - $this->_account_container_count = (float) trim(substr($header,
1069 - strlen(ACCOUNT_CONTAINER_COUNT)+1))+0;
1070 - return strlen($header);
1071 - }
1072 - if (stripos($header, ACCOUNT_BYTES_USED) === 0) {
1073 - $this->_account_bytes_used = (float) trim(substr($header,
1074 - strlen(ACCOUNT_BYTES_USED)+1))+0;
1075 - return strlen($header);
1076 - }
1077 - if (stripos($header, CONTAINER_OBJ_COUNT) === 0) {
1078 - $this->_container_object_count = (float) trim(substr($header,
1079 - strlen(CONTAINER_OBJ_COUNT)+1))+0;
1080 - return strlen($header);
1081 - }
1082 - if (stripos($header, CONTAINER_BYTES_USED) === 0) {
1083 - $this->_container_bytes_used = (float) trim(substr($header,
1084 - strlen(CONTAINER_BYTES_USED)+1))+0;
1085 - return strlen($header);
1086 - }
1087 - if (stripos($header, METADATA_HEADER) === 0) {
1088 - # $header => X-Object-Meta-Foo: bar baz
1089 - $temp = substr($header, strlen(METADATA_HEADER));
1090 - # $temp => Foo: bar baz
1091 - $parts = explode(":", $temp);
1092 - # $parts[0] => Foo
1093 - $val = substr(strstr($temp, ":"), 1);
1094 - # $val => bar baz
1095 - $this->_obj_metadata[$parts[0]] = trim($val);
1096 - return strlen($header);
1097 - }
1098 - if (stripos($header, "ETag:") === 0) {
1099 - # $header => ETag: abc123def456...
1100 - $val = substr(strstr($header, ":"), 1);
1101 - # $val => abc123def456...
1102 - $this->_obj_etag = trim($val);
1103 - return strlen($header);
1104 - }
1105 - if (stripos($header, "Last-Modified:") === 0) {
1106 - $val = substr(strstr($header, ":"), 1);
1107 - $this->_obj_last_modified = trim($val);
1108 - return strlen($header);
1109 - }
1110 - if (stripos($header, "Content-Type:") === 0) {
1111 - $val = substr(strstr($header, ":"), 1);
1112 - $this->_obj_content_type = trim($val);
1113 - return strlen($header);
1114 - }
1115 - if (stripos($header, "Content-Length:") === 0) {
1116 - $val = substr(strstr($header, ":"), 1);
1117 - $this->_obj_content_length = (float) trim($val)+0;
1118 - return strlen($header);
1119 - }
1120 - return strlen($header);
 1166+ return $header_len;
11211167 }
11221168
11231169 private function _read_cb($ch, $fd, $length)
@@ -1183,28 +1229,23 @@
11841230 if (is_array($hdrs)) {
11851231 foreach ($hdrs as $h => $v) {
11861232 if (is_int($h)) {
1187 - $parts = explode(":", $v);
1188 - $header = $parts[0];
1189 - $value = trim(substr(strstr($v, ":"), 1));
1190 - } else {
1191 - $header = $h;
1192 - $value = trim($v);
 1233+ list($h, $v) = explode(":", $v, 2);
11931234 }
11941235
1195 - if (stripos($header, AUTH_TOKEN) === 0) {
 1236+ if (strncasecmp($h, AUTH_TOKEN, strlen(AUTH_TOKEN)) === 0) {
11961237 $has_stoken = True;
11971238 }
1198 - if (stripos($header, "user-agent") === 0) {
 1239+ if (strncasecmp($h, USER_AGENT_HEADER, strlen(USER_AGENT_HEADER)) === 0) {
11991240 $has_uagent = True;
12001241 }
1201 - $new_headers[] = $header . ": " . $value;
 1242+ $new_headers[] = $h . ": " . trim($v);
12021243 }
12031244 }
12041245 if (!$has_stoken) {
12051246 $new_headers[] = AUTH_TOKEN . ": " . $this->auth_token;
12061247 }
12071248 if (!$has_uagent) {
1208 - $new_headers[] = "User-Agent: " . USER_AGENT;
 1249+ $new_headers[] = USER_AGENT_HEADER . ": " . USER_AGENT;
12091250 }
12101251 return $new_headers;
12111252 }
@@ -1228,7 +1269,7 @@
12291270 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, True);
12301271 curl_setopt($ch, CURLOPT_CAINFO, $this->cabundle_path);
12311272 }
1232 - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, False);
 1273+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, True);
12331274 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
12341275 curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
12351276 curl_setopt($ch, CURLOPT_MAXREDIRS, 4);
@@ -1256,6 +1297,9 @@
12571298 if ($conn_type == "DEL_POST") {
12581299 curl_setopt($ch, CURLOPT_NOBODY, 1);
12591300 }
 1301+ if ($conn_type == "COPY") {
 1302+ curl_setopt($ch, CURLOPT_NOBODY, 1);
 1303+ }
12601304 $this->connections[$conn_type] = $ch;
12611305 return;
12621306 }
@@ -1274,7 +1318,9 @@
12751319 $this->_obj_content_length = NULL;
12761320 $this->_obj_metadata = array();
12771321 $this->_obj_manifest = NULL;
 1322+ $this->_obj_headers = NULL;
12781323 $this->_obj_write_string = "";
 1324+ $this->_cdn_streaming_uri = NULL;
12791325 $this->_cdn_enabled = NULL;
12801326 $this->_cdn_ssl_uri = NULL;
12811327 $this->_cdn_uri = NULL;
@@ -1306,30 +1352,71 @@
13071353 return implode("/",$path);
13081354 }
13091355
1310 - private function _metadata_headers(&$obj)
 1356+ private function _headers(&$obj)
13111357 {
1312 - $hdrs = array();
 1358+ $hdrs = self::_process_headers($obj->metadata, $obj->headers);
13131359 if ($obj->manifest)
13141360 $hdrs[MANIFEST_HEADER] = $obj->manifest;
1315 - foreach ($obj->metadata as $k => $v) {
1316 - if (strpos($k,":") !== False) {
1317 - throw new SyntaxException(
1318 - "Metadata keys cannot contain a ':' character.");
1319 - }
1320 - $k = trim($k);
1321 - $key = sprintf("%s%s", METADATA_HEADER, $k);
1322 - if (!array_key_exists($key, $hdrs)) {
1323 - if (strlen($k) > 128 || strlen($v) > 256) {
1324 - $this->error_str = "Metadata key or value exceeds ";
1325 - $this->error_str .= "maximum length: ($k: $v)";
1326 - return 0;
 1361+
 1362+ return $hdrs;
 1363+ }
 1364+
 1365+ private function _process_headers($metadata=null, $headers=null)
 1366+ {
 1367+ $rules = array(
 1368+ array(
 1369+ 'prefix' => METADATA_HEADER_PREFIX,
 1370+ ),
 1371+ array(
 1372+ 'prefix' => '',
 1373+ 'filter' => array( # key order is important, first match decides
 1374+ CONTENT_TYPE_HEADER => false,
 1375+ CONTENT_LENGTH_HEADER => false,
 1376+ CONTENT_HEADER_PREFIX => true,
 1377+ ACCESS_CONTROL_HEADER_PREFIX => true,
 1378+ ORIGIN_HEADER => true,
 1379+ ),
 1380+ ),
 1381+ );
 1382+
 1383+ $hdrs = array();
 1384+ $argc = func_num_args();
 1385+ $argv = func_get_args();
 1386+ for ($argi = 0; $argi < $argc; $argi++) {
 1387+ if(!is_array($argv[$argi])) continue;
 1388+
 1389+ $rule = $rules[$argi];
 1390+ foreach ($argv[$argi] as $k => $v) {
 1391+ $k = trim($k);
 1392+ $v = trim($v);
 1393+ if (strpos($k, ":") !== False) throw new SyntaxException(
 1394+ "Header names cannot contain a ':' character.");
 1395+
 1396+ if (array_key_exists('filter', $rule)) {
 1397+ $result = null;
 1398+ foreach ($rule['filter'] as $p => $f) {
 1399+ if (strncasecmp($k, $p, strlen($p)) == 0) {
 1400+ $result = $f;
 1401+ break;
 1402+ }
 1403+ }
 1404+ if (!$result) throw new SyntaxException(sprintf(
 1405+ "Header name %s is not allowed", $k));
13271406 }
1328 - $hdrs[] = sprintf("%s%s: %s", METADATA_HEADER, $k, trim($v));
 1407+
 1408+ $k = $rule['prefix'] . $k;
 1409+ if (strlen($k) > MAX_HEADER_NAME_LEN || strlen($v) > MAX_HEADER_VALUE_LEN)
 1410+ throw new SyntaxException(sprintf(
 1411+ "Header %s exceeds maximum length: %d/%d",
 1412+ $k, strlen($k), strlen($v)));
 1413+
 1414+ $hdrs[$k] = $v;
13291415 }
13301416 }
 1417+
13311418 return $hdrs;
13321419 }
1333 -
 1420+
13341421 private function _send_request($conn_type, $url_path, $hdrs=NULL, $method="GET", $force_new=False)
13351422 {
13361423 $this->_init($conn_type, $force_new);
@@ -1342,6 +1429,10 @@
13431430 );
13441431
13451432 switch ($method) {
 1433+ case "COPY":
 1434+ curl_setopt($this->connections[$conn_type],
 1435+ CURLOPT_CUSTOMREQUEST, "COPY");
 1436+ break;
13461437 case "DELETE":
13471438 curl_setopt($this->connections[$conn_type],
13481439 CURLOPT_CUSTOMREQUEST, "DELETE");
@@ -1394,4 +1485,4 @@
13951486 * c-hanging-comment-ender-p: nil
13961487 * End:
13971488 */
1398 -?>
 1489+?>
\ No newline at end of file

Follow-up revisions

RevisionCommit summaryAuthorDate
r99590Fixed FileRepo::storeBatch() to check for overwrites, and edited TODO accordi...nelson22:30, 11 October 2011

Comments

#Comment by RussNelson (talk | contribs)   22:36, 11 October 2011

I fixed some problems in 1.7.9 which are still in 1.7.10 (that's why they're in CVS). Once those issues have been tracked down and verified as absent in 1.7.10 we might want to upgrade.

#Comment by Tim Starling (talk | contribs)   01:02, 12 December 2011

Was largely reverted by r99590

Status & tagging log