r99590 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r99589‎ | r99590 | r99591 >
Date:22:30, 11 October 2011
Author:nelson
Status:deferred
Tags:
Comment:
Fixed FileRepo::storeBatch() to check for overwrites, and edited TODO accordingly; reverted php-cloudfiles.
Modified paths:
  • /trunk/extensions/SwiftMedia/SwiftMedia.body.php (modified) (history)
  • /trunk/extensions/SwiftMedia/SwiftMedia.php (modified) (history)
  • /trunk/extensions/SwiftMedia/TODO (modified) (history)
  • /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/SwiftMedia.php
@@ -12,7 +12,7 @@
1313 $wgAutoloadClasses['SwiftForeignDBFile'] =
1414 $wgAutoloadClasses['SwiftForeignDBRepo'] =
1515 $wgAutoloadClasses['SwiftForeignDBviaLBRepo'] =
16 - $wgAutoloadClasses['SwiftRepo'] = dirname( __FILE__ ) . '/SwiftMedia.body.php';
 16+ $wgAutoloadClasses['SwiftRepo'] = dirname(__FILE__) . '/SwiftMedia.body.php';
1717 $wgAutoloadClasses['CF_Authentication'] =
1818 $wgAutoloadClasses['CF_Connection'] =
1919 $wgAutoloadClasses['CF_Container'] =
Index: trunk/extensions/SwiftMedia/TODO
@@ -15,11 +15,6 @@
1616 12) Why is anybody calling resolveVirtualUrl()? It's defined in the Repo, but getPath() is defined against a file.
1717 Why is UploadStashFile() being called with a virtual URL? Once the file has been stashed() it has an object name. The container name is implicit.
1818 Should UploadStashFile *always* (in our case) be called with a virtual URL?
19 -21) TS: "// Check overwriting
20 - if (0) { #FIXME
21 -
22 -Fix that. It's important to avoid data loss in file rename operations."
23 -22) TS: "I think this [MD65] validation feature in FSRepo is just a hack for NFS. Okay to remove it."
2419 23) TS: "When you get around to implementing SwiftRepo::append(), it will need some sort of concurrency control to avoid having chunks overwrite each other. "
2520 24) TS: "SwiftRepo::swiftcopy() should return a Status object instead of throwing exceptions."
2621
@@ -30,6 +25,11 @@
3126
3227 Resolved:
3328
 29+21a) TS: "// Check overwriting
 30+ if (0) { #FIXME
 31+
 32+Fix that. It's important to avoid data loss in file rename operations."
 33+22) TS: "I think this [MD65] validation feature in FSRepo is just a hack for NFS. Okay to remove it."
3434 5) The Upload seems to take more time than I expect, but that could be a function of generating the six thumbnails.
3535 It *is* a function of generating the seven (we generate 800x600 twice) thumbnails. Each one takes 1/2 second.
3636 8) Test cases (but of course that could be done until the cows come home).
Index: trunk/extensions/SwiftMedia/SwiftMedia.body.php
@@ -54,11 +54,6 @@
5555 /**#@-*/
5656
5757 /**
58 - * @var SwiftRepo
59 - */
60 - protected $repo;
61 -
62 - /**
6358 * Create a LocalFile from a title
6459 * Do not call this except from inside a repo class.
6560 *
@@ -406,69 +401,95 @@
407402 wfDebug( __METHOD__ . ': Storing ' . count( $triplets ) .
408403 " triplets; flags: {$flags}\n" );
409404
410 - // Validate each triplet
411405 $status = $this->newGood();
412 - foreach ( $triplets as $triplet ) {
413 - list( $srcPath, $dstZone, $dstRel ) = $triplet;
414406
415 - if ( !$this->validateFilename( $dstRel ) ) {
416 - throw new MWException( "Validation error in $dstRel" );
417 - }
418 -
419 - // Check overwriting
420 - if ( 0 ) { # FIXME
421 - if ( !( $flags & self::OVERWRITE ) && file_exists( $dstPath ) ) { // FIXME: $dstPath is undefined
422 - if ( $flags & self::OVERWRITE_SAME ) {
423 - $hashSource = sha1_file( $srcPath );
424 - $hashDest = sha1_file( $dstPath );
425 - if ( $hashSource != $hashDest ) {
426 - $status->fatal( 'fileexistserror', $dstPath );
427 - }
428 - } else {
429 - $status->fatal( 'fileexistserror', $dstPath );
430 - }
431 - }
432 - }
433 - }
434 -
435 - // Abort now on failure
436 - if ( !$status->ok ) {
437 - return $status;
438 - }
439 -
440407 // Execute the store operation for each triplet
441408 $conn = $this->connect();
442409
443410 foreach ( $triplets as $i => $triplet ) {
444411 list( $srcPath, $dstZone, $dstRel ) = $triplet;
445412
 413+ wfDebug( __METHOD__ . ": Storing $srcPath into $dstZone::$dstRel\n");
 414+
446415 // Point to the container.
447416 $dstContainer = $this->getZoneContainer( $dstZone );
448 - $dstc = $this->get_container( $conn, $dstContainer );
 417+ $dstc = $this->get_container($conn, $dstContainer);
449418
450419 $good = true;
451420
452421 // Where are we copying this from?
453 - if ( self::isVirtualUrl( $srcPath ) ) {
 422+ if (self::isVirtualUrl( $srcPath )) {
454423 $src = $this->getContainerRel( $srcPath );
455 - list ( $srcContainer, $srcRel ) = $src;
456 - $srcc = $this->get_container( $conn, $srcContainer );
 424+ list ($srcContainer, $srcRel) = $src;
 425+ $srcc = $this->get_container($conn, $srcContainer);
457426
458 - $this->swiftcopy( $srcc, $srcRel, $dstc, $dstRel );
459 - if ( $flags & self::DELETE_SOURCE ) {
460 - $this->swift_delete( $srcc, $srcRel );
 427+ // See if we're not supposed to overwrite an existing file.
 428+ if ( !( $flags & self::OVERWRITE ) ) {
 429+ // does it exist?
 430+ try {
 431+ $objd = $dstc->get_object($dstRel);
 432+ // and if it does, are we allowed to overwrite it?
 433+ if ( $flags & self::OVERWRITE_SAME ) {
 434+ $objs = $srcc->get_object($srcRel);
 435+ if ( $objd->getETag() != $objs->getETag() ) {
 436+ $status->fatal( 'fileexistserror', $dstRel );
 437+ $good = false;
 438+ }
 439+ } else {
 440+ $status->fatal( 'fileexistserror', $dstRel );
 441+ $good = false;
 442+ }
 443+ $exists = true;
 444+ } catch (NoSuchObjectException $e) {
 445+ $exists = false;
 446+ }
461447 }
 448+
 449+ if ($good) {
 450+ try {
 451+ $this->swiftcopy($srcc, $srcRel, $dstc, $dstRel);
 452+ } catch (InvalidResponseException $e ) {
 453+ $status->error( 'filecopyerror', $srcPath, "{$dstc->name}/$dstRel");
 454+ $good = false;
 455+ }
 456+ if ( $flags & self::DELETE_SOURCE ) {
 457+ $this->swift_delete( $srcc, $srcRel );
 458+ }
 459+ }
462460 } else {
463 - $this->write_swift_object( $srcPath, $dstc, $dstRel );
464 - // php-cloudfiles throws exceptions, so failure never gets here.
465 - if ( $flags & self::DELETE_SOURCE ) {
466 - unlink ( $srcPath );
 461+ // See if we're not supposed to overwrite an existing file.
 462+ if ( !( $flags & self::OVERWRITE ) ) {
 463+ // does it exist?
 464+ try {
 465+ $objd = $dstc->get_object($dstRel);
 466+ // and if it does, are we allowed to overwrite it?
 467+ if ( $flags & self::OVERWRITE_SAME ) {
 468+ if ( $objd->getETag() != md5_file($srcPath) ) {
 469+ $status->fatal( 'fileexistserror', $dstRel );
 470+ $good = false;
 471+ }
 472+ } else {
 473+ $status->fatal( 'fileexistserror', $dstRel );
 474+ $good = false;
 475+ }
 476+ $exists = true;
 477+ } catch (NoSuchObjectException $e) {
 478+ $exists = false;
 479+ }
467480 }
 481+ if ($good) {
 482+ wfDebug( __METHOD__ . ": Writing $srcPath to {$dstc->name}/$dstRel\n");
 483+ try {
 484+ $this->write_swift_object( $srcPath, $dstc, $dstRel);
 485+ } catch (InvalidResponseException $e ) {
 486+ $status->error( 'filecopyerror', $srcPath, "{$dstc->name}/$dstRel");
 487+ $good = false;
 488+ }
 489+ if ( $flags & self::DELETE_SOURCE ) {
 490+ unlink ( $srcPath );
 491+ }
 492+ }
468493 }
469 - if ( 0 ) {
470 - $status->error( 'filecopyerror', $srcPath, $dstPath );
471 - $good = false;
472 - }
473494 if ( $good ) {
474495 $status->successCount++;
475496 } else {
@@ -901,7 +922,6 @@
902923 * copy of the file MUST delete the produced file, or else store it in
903924 * SwiftFile->tempPath so it will be deleted when the object goes out of
904925 * scope.
905 - * FIXME: how do we return a fatal error from Swift?
906926 */
907927 function getLocalCopy( $container, $rel ) {
908928
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 < 200 || $status > 299) {
 212+ if ($status != 204 && $status != 200) {
213213 throw new InvalidResponseException(
214214 "Unexpected response (".$status."): ".$reason);
215215 }
@@ -923,7 +923,6 @@
924924 public $bytes_used;
925925
926926 public $cdn_enabled;
927 - public $cdn_streaming_uri;
928927 public $cdn_ssl_uri;
929928 public $cdn_uri;
930929 public $cdn_ttl;
@@ -962,7 +961,6 @@
963962 $this->cdn_enabled = NULL;
964963 $this->cdn_uri = NULL;
965964 $this->cdn_ssl_uri = NULL;
966 - $this->cdn_streaming_uri = NULL;
967965 $this->cdn_ttl = NULL;
968966 $this->cdn_log_retention = NULL;
969967 $this->cdn_acl_user_agent = NULL;
@@ -1278,7 +1276,6 @@
12791277 $this->cdn_ttl = NULL;
12801278 $this->cdn_uri = NULL;
12811279 $this->cdn_ssl_uri = NULL;
1282 - $this->cdn_streaming_uri - NULL;
12831280 $this->cdn_log_retention = NULL;
12841281 $this->cdn_acl_user_agent = NULL;
12851282 $this->cdn_acl_referrer = NULL;
@@ -1496,235 +1493,6 @@
14971494 }
14981495
14991496 /**
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 - /**
17291497 * Delete a remote storage Object
17301498 *
17311499 * Given an Object instance or name, permanently remove the remote Object
@@ -1744,13 +1512,12 @@
17451513 * </code>
17461514 *
17471515 * @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)
17491516 * @return boolean <kbd>True</kbd> if successfully removed
17501517 * @throws SyntaxException invalid Object name
17511518 * @throws NoSuchObjectException remote Object does not exist
17521519 * @throws InvalidResponseException unexpected response
17531520 */
1754 - function delete_object($obj,$container=NULL)
 1521+ function delete_object($obj)
17551522 {
17561523 $obj_name = NULL;
17571524 if (is_object($obj)) {
@@ -1764,32 +1531,12 @@
17651532 if (!$obj_name) {
17661533 throw new SyntaxException("Object name not set.");
17671534 }
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);
 1535+ $status = $this->cfs_http->delete_object($this->name, $obj_name);
17891536 #if ($status == 401 && $this->_re_auth()) {
17901537 # return $this->delete_object($obj);
17911538 #}
17921539 if ($status == 404) {
1793 - $m = "Specified object '".$container_name."/".$obj_name;
 1540+ $m = "Specified object '".$this->name."/".$obj_name;
17941541 $m.= "' did not exist to delete.";
17951542 throw new NoSuchObjectException($m);
17961543 }
@@ -1805,7 +1552,7 @@
18061553 *
18071554 * Given an Object whos name contains '/' path separators, this function
18081555 * will create the "directory marker" Objects of one byte with the
1809 - * Content-Type of "application/directory".
 1556+ * Content-Type of "application/folder".
18101557 *
18111558 * It assumes the last element of the full path is the "real" Object
18121559 * and does NOT create a remote storage Object for that last element.
@@ -1836,7 +1583,7 @@
18371584 */
18381585 private function _cdn_initialize()
18391586 {
1840 - list($status, $reason, $cdn_enabled, $cdn_ssl_uri, $cdn_streaming_uri, $cdn_uri, $cdn_ttl,
 1587+ list($status, $reason, $cdn_enabled, $cdn_ssl_uri, $cdn_uri, $cdn_ttl,
18411588 $cdn_log_retention, $cdn_acl_user_agent, $cdn_acl_referrer) =
18421589 $this->cfs_http->head_cdn_container($this->name);
18431590 #if ($status == 401 && $this->_re_auth()) {
@@ -1847,7 +1594,6 @@
18481595 "Invalid response (".$status."): ".$this->cfs_http->get_error());
18491596 }
18501597 $this->cdn_enabled = $cdn_enabled;
1851 - $this->cdn_streaming_uri = $cdn_streaming_uri;
18521598 $this->cdn_ssl_uri = $cdn_ssl_uri;
18531599 $this->cdn_uri = $cdn_uri;
18541600 $this->cdn_ttl = $cdn_ttl;
@@ -1888,7 +1634,6 @@
18891635 public $content_type;
18901636 public $content_length;
18911637 public $metadata;
1892 - public $headers;
18931638 public $manifest;
18941639 private $etag;
18951640
@@ -1918,7 +1663,6 @@
19191664 $this->content_type = NULL;
19201665 $this->content_length = 0;
19211666 $this->metadata = array();
1922 - $this->headers = array();
19231667 $this->manifest = NULL;
19241668 if ($dohead) {
19251669 if (!$this->_initialize() && $force_exists) {
@@ -2056,31 +1800,6 @@
20571801 }
20581802 return NULL;
20591803 }
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 - }
20851804
20861805 /**
20871806 * Read the remote Object's data
@@ -2204,12 +1923,6 @@
22051924 * "Version" => "1.2.2"
22061925 * );
22071926 *
2208 - * # Define additional headers for the object
2209 - * #
2210 - * $doc->headers = array(
2211 - * "Content-Disposition" => "attachment",
2212 - * );
2213 - *
22141927 * # Push the new metadata up to the storage system
22151928 * #
22161929 * $doc->sync_metadata();
@@ -2220,7 +1933,7 @@
22211934 */
22221935 function sync_metadata()
22231936 {
2224 - if (!empty($this->metadata) || !empty($this->headers) || $this->manifest) {
 1937+ if (!empty($this->metadata) || $this->manifest) {
22251938 $status = $this->container->cfs_http->update_object($this);
22261939 #if ($status == 401 && $this->_re_auth()) {
22271940 # return $this->sync_metadata();
@@ -2263,8 +1976,8 @@
22641977 function sync_manifest()
22651978 {
22661979 return $this->sync_metadata();
2267 - }
2268 - /**
 1980+ }
 1981+ /**
22691982 * Upload Object's data to Cloud Files
22701983 *
22711984 * Write data to the remote Object. The $data argument can either be a
@@ -2361,6 +2074,54 @@
23622075 return True;
23632076 }
23642077
 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+
23652126 /**
23662127 * Upload Object data from local filename
23672128 *
@@ -2544,8 +2305,8 @@
25452306 private function _initialize()
25462307 {
25472308 list($status, $reason, $etag, $last_modified, $content_type,
2548 - $content_length, $metadata, $manifest, $headers) =
2549 - $this->container->cfs_http->head_object($this);
 2309+ $content_length, $metadata) =
 2310+ $this->container->cfs_http->head_object($this);
25502311 #if ($status == 401 && $this->_re_auth()) {
25512312 # return $this->_initialize();
25522313 #}
@@ -2561,8 +2322,7 @@
25622323 $this->content_type = $content_type;
25632324 $this->content_length = $content_length;
25642325 $this->metadata = $metadata;
2565 - $this->headers = $headers;
2566 - $this->manifest = $manifest;
 2326+ $this->manifest = NULL;
25672327 return True;
25682328 }
25692329
@@ -2589,4 +2349,4 @@
25902350 * c-hanging-comment-ender-p: nil
25912351 * End:
25922352 */
2593 -?>
\ No newline at end of file
 2353+?>
Index: trunk/extensions/SwiftMedia/php-cloudfiles/cloudfiles_http.php
@@ -29,22 +29,16 @@
3030 */
3131 require_once("cloudfiles_exceptions.php");
3232
33 -define("PHP_CF_VERSION", "1.7.10");
 33+define("PHP_CF_VERSION", "1.7.9");
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);
3735 define("ACCOUNT_CONTAINER_COUNT", "X-Account-Container-Count");
3836 define("ACCOUNT_BYTES_USED", "X-Account-Bytes-Used");
3937 define("CONTAINER_OBJ_COUNT", "X-Container-Object-Count");
4038 define("CONTAINER_BYTES_USED", "X-Container-Bytes-Used");
 39+define("METADATA_HEADER", "X-Object-Meta-");
4140 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");
4641 define("CDN_URI", "X-CDN-URI");
4742 define("CDN_SSL_URI", "X-CDN-SSL-URI");
48 -define("CDN_STREAMING_URI", "X-CDN-Streaming-URI");
4943 define("CDN_ENABLED", "X-CDN-Enabled");
5044 define("CDN_LOG_RETENTION", "X-Log-Retention");
5145 define("CDN_ACL_USER_AGENT", "X-User-Agent-ACL");
@@ -59,13 +53,6 @@
6054 define("AUTH_KEY_HEADER_LEGACY", "X-Storage-Pass");
6155 define("AUTH_TOKEN_LEGACY", "X-Storage-Token");
6256 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 -
7057 /**
7158 * HTTP/cURL wrapper for Cloud Files
7259 *
@@ -108,13 +95,11 @@
10996 private $_obj_content_type;
11097 private $_obj_content_length;
11198 private $_obj_metadata;
112 - private $_obj_headers;
11399 private $_obj_manifest;
114100 private $_obj_write_resource;
115101 private $_obj_write_string;
116102 private $_cdn_enabled;
117103 private $_cdn_ssl_uri;
118 - private $_cdn_streaming_uri;
119104 private $_cdn_uri;
120105 private $_cdn_ttl;
121106 private $_cdn_log_retention;
@@ -146,7 +131,6 @@
147132 "HEAD" => NULL, # HEAD requests
148133 "PUT_CONT" => NULL, # PUT container
149134 "DEL_POST" => NULL, # DELETE containers/objects, POST objects
150 - "COPY" => null, # COPY objects
151135 );
152136
153137 $this->_user_read_progress_callback_func = NULL;
@@ -166,10 +150,8 @@
167151 $this->_obj_content_length = NULL;
168152 $this->_obj_metadata = array();
169153 $this->_obj_manifest = NULL;
170 - $this->_obj_headers = NULL;
171154 $this->_cdn_enabled = NULL;
172155 $this->_cdn_ssl_uri = NULL;
173 - $this->_cdn_streaming_uri = NULL;
174156 $this->_cdn_uri = NULL;
175157 $this->_cdn_ttl = NULL;
176158 $this->_cdn_log_retention = NULL;
@@ -230,6 +212,7 @@
231213 curl_setopt($curl_ch, CURLOPT_SSL_VERIFYPEER, True);
232214 curl_setopt($curl_ch, CURLOPT_CAINFO, $this->cabundle_path);
233215 }
 216+ curl_setopt($curl_ch, CURLOPT_SSL_VERIFYPEER, False);
234217 curl_setopt($curl_ch, CURLOPT_VERBOSE, $this->dbug);
235218 curl_setopt($curl_ch, CURLOPT_FOLLOWLOCATION, 1);
236219 curl_setopt($curl_ch, CURLOPT_MAXREDIRS, 4);
@@ -266,7 +249,7 @@
267250 }
268251 if (!$return_code) {
269252 $this->error_str .= ": Failed to obtain valid HTTP response.";
270 - return array(0,$this->error_str,array());
 253+ array(0,$this->error_str,array());
271254 }
272255 if ($return_code == 401) {
273256 return array($return_code,"Unauthorized",array());
@@ -410,18 +393,17 @@
411394
412395 if (!$return_code) {
413396 $this->error_str .= ": Failed to obtain valid HTTP response.";
414 - return array(0,$this->error_str,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
 397+ return array(0,$this->error_str,NULL,NULL,NULL,NULL,NULL,NULL);
415398 }
416399 if ($return_code == 401) {
417 - return array($return_code,"Unauthorized",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
 400+ return array($return_code,"Unauthorized",NULL,NULL,NULL,NULL,NULL,NULL);
418401 }
419402 if ($return_code == 404) {
420 - return array($return_code,"Account not found.",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
 403+ return array($return_code,"Account not found.",NULL,NULL,NULL,NULL,NULL,NULL);
421404 }
422405 if ($return_code == 204) {
423406 return array($return_code,$this->response_reason,
424407 $this->_cdn_enabled, $this->_cdn_ssl_uri,
425 - $this->_cdn_streaming_uri,
426408 $this->_cdn_uri, $this->_cdn_ttl,
427409 $this->_cdn_log_retention,
428410 $this->_cdn_acl_user_agent,
@@ -429,11 +411,10 @@
430412 );
431413 }
432414 return array($return_code,$this->response_reason,
433 - NULL,NULL,NULL,NULL,
 415+ NULL,NULL,NULL,
434416 $this->_cdn_log_retention,
435417 $this->_cdn_acl_user_agent,
436 - $this->_cdn_acl_referrer,
437 - NULL
 418+ $this->_cdn_acl_referrer
438419 );
439420 }
440421
@@ -530,7 +511,7 @@
531512
532513 if (!$return_code) {
533514 $this->error_str .= ": Failed to obtain valid HTTP response.";
534 - return array(0,$this->error_str,0,0);
 515+ array(0,$this->error_str,0,0);
535516 }
536517 if ($return_code == 404) {
537518 return array($return_code,"Account not found.",0,0);
@@ -575,19 +556,16 @@
576557 $url_path = $this->_make_path("STORAGE", $container_name);
577558 $return_code = $this->_send_request("DEL_POST",$url_path,array(),"DELETE");
578559
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:
 560+ if (!$return_code) {
 561+ $this->error_str .= ": Failed to obtain valid HTTP response.";
 562+ }
 563+ if ($return_code == 409) {
586564 $this->error_str = "Container must be empty prior to removing it.";
587 - break;
588 - case 404:
 565+ }
 566+ if ($return_code == 404) {
589567 $this->error_str = "Specified container did not exist to delete.";
590 - break;
591 - default:
 568+ }
 569+ if ($return_code != 204) {
592570 $this->error_str = "Unexpected HTTP return code: $return_code.";
593571 }
594572 return $return_code;
@@ -723,7 +701,7 @@
724702
725703 if (!$return_code) {
726704 $this->error_str .= ": Failed to obtain valid HTTP response.";
727 - return array(0,$this->error_str,0,0);
 705+ array(0,$this->error_str,0,0);
728706 }
729707 if ($return_code == 404) {
730708 return array($return_code,"Container not found.",0,0);
@@ -810,7 +788,10 @@
811789 throw new SyntaxException(
812790 "Method argument is not a valid CF_Object.");
813791 }
814 - if (!is_resource($fp)) {
 792+ $source = NULL;
 793+ if (is_string($fp)) {
 794+ $source = $fp;
 795+ } elseif (!is_resource($fp)) {
815796 throw new SyntaxException(
816797 "File pointer argument is not a valid resource.");
817798 }
@@ -818,32 +799,40 @@
819800 $conn_type = "PUT_OBJ";
820801 $url_path = $this->_make_path("STORAGE", $obj->container->name,$obj->name);
821802
822 - $hdrs = $this->_headers($obj);
 803+ $hdrs = $this->_metadata_headers($obj);
823804
824805 $etag = $obj->getETag();
825 - if (isset($etag)) {
 806+ if (!$source && isset($etag)) {
826807 $hdrs[] = "ETag: " . $etag;
827808 }
828 - if (!$obj->content_type) {
 809+ if ($source) {
 810+ // If we don't include a content-type it will copy over the existing one.
 811+ } elseif (!$obj->content_type) {
829812 $hdrs[] = "Content-Type: application/octet-stream";
830813 } else {
831814 $hdrs[] = "Content-Type: " . $obj->content_type;
832815 }
833816
834817 $this->_init($conn_type);
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 - #
 818+ if ($source) {
 819+ $hdrs[] = "X-Copy-From: " . rawurlencode($source);
845820 curl_setopt($this->connections[$conn_type],
846 - CURLOPT_INFILESIZE, $obj->content_length);
847 - }
 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+ }
848837 $return_code = $this->_send_request($conn_type,$url_path,$hdrs);
849838
850839 if (!$return_code) {
@@ -874,29 +863,25 @@
875864 "Method argument is not a valid CF_Object.");
876865 }
877866
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.";
 867+ if (!is_array($obj->metadata) && !$obj->manifest) {
 868+
 869+ $this->error_str = "Metadata array is empty.";
881870 return 0;
882871 }
883872
884873 $url_path = $this->_make_path("STORAGE", $obj->container->name,$obj->name);
885874
886 - $hdrs = $this->_headers($obj);
 875+ $hdrs = $this->_metadata_headers($obj);
887876 $return_code = $this->_send_request("DEL_POST",$url_path,$hdrs,"POST");
888 - switch ($return_code) {
889 - case 202:
890 - break;
891 - case 0:
 877+ if (!$return_code) {
892878 $this->error_str .= ": Failed to obtain valid HTTP response.";
893 - $return_code = 0;
894 - break;
895 - case 404:
 879+ return 0;
 880+ }
 881+ if ($return_code == 404) {
896882 $this->error_str = "Account, Container, or Object not found.";
897 - break;
898 - default:
 883+ }
 884+ if ($return_code != 202) {
899885 $this->error_str = "Unexpected HTTP return code: $return_code";
900 - break;
901886 }
902887 return $return_code;
903888 }
@@ -918,12 +903,12 @@
919904 if (!$return_code) {
920905 $this->error_str .= ": Failed to obtain valid HTTP response.";
921906 return array(0, $this->error_str." ".$this->response_reason,
922 - NULL, NULL, NULL, NULL, array(), NULL, array());
 907+ NULL, NULL, NULL, NULL, array());
923908 }
924909
925910 if ($return_code == 404) {
926911 return array($return_code, $this->response_reason,
927 - NULL, NULL, NULL, NULL, array(), NULL, array());
 912+ NULL, NULL, NULL, NULL, array());
928913 }
929914 if ($return_code == 204 || $return_code == 200) {
930915 return array($return_code,$this->response_reason,
@@ -932,68 +917,13 @@
933918 $this->_obj_content_type,
934919 $this->_obj_content_length,
935920 $this->_obj_metadata,
936 - $this->_obj_manifest,
937 - $this->_obj_headers);
 921+ $this->_obj_manifest);
938922 }
939923 $this->error_str = "Unexpected HTTP return code: $return_code";
940924 return array($return_code, $this->error_str." ".$this->response_reason,
941 - NULL, NULL, NULL, NULL, array(), NULL, array());
 925+ NULL, NULL, NULL, NULL, array());
942926 }
943927
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 -
998928 # DELETE /v1/Account/Container/Object
999929 #
1000930 function delete_object($container_name, $object_name)
@@ -1015,17 +945,14 @@
1016946
1017947 $url_path = $this->_make_path("STORAGE", $container_name,$object_name);
1018948 $return_code = $this->_send_request("DEL_POST",$url_path,NULL,"DELETE");
1019 - switch ($return_code) {
1020 - case 204:
1021 - break;
1022 - case 0:
 949+ if (!$return_code) {
1023950 $this->error_str .= ": Failed to obtain valid HTTP response.";
1024 - $return_code = 0;
1025 - break;
1026 - case 404:
 951+ return 0;
 952+ }
 953+ if ($return_code == 404) {
1027954 $this->error_str = "Specified container did not exist to delete.";
1028 - break;
1029 - default:
 955+ }
 956+ if ($return_code != 204) {
1030957 $this->error_str = "Unexpected HTTP return code: $return_code.";
1031958 }
1032959 return $return_code;
@@ -1084,85 +1011,112 @@
10851012
10861013 private function _header_cb($ch, $header)
10871014 {
1088 - $header_len = strlen($header);
 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+ }
10891054
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;
 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);
10941059 }
10951060
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 - }
 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);
11651065 }
1166 - return $header_len;
 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);
11671121 }
11681122
11691123 private function _read_cb($ch, $fd, $length)
@@ -1229,23 +1183,28 @@
12301184 if (is_array($hdrs)) {
12311185 foreach ($hdrs as $h => $v) {
12321186 if (is_int($h)) {
1233 - list($h, $v) = explode(":", $v, 2);
 1187+ $parts = explode(":", $v);
 1188+ $header = $parts[0];
 1189+ $value = trim(substr(strstr($v, ":"), 1));
 1190+ } else {
 1191+ $header = $h;
 1192+ $value = trim($v);
12341193 }
12351194
1236 - if (strncasecmp($h, AUTH_TOKEN, strlen(AUTH_TOKEN)) === 0) {
 1195+ if (stripos($header, AUTH_TOKEN) === 0) {
12371196 $has_stoken = True;
12381197 }
1239 - if (strncasecmp($h, USER_AGENT_HEADER, strlen(USER_AGENT_HEADER)) === 0) {
 1198+ if (stripos($header, "user-agent") === 0) {
12401199 $has_uagent = True;
12411200 }
1242 - $new_headers[] = $h . ": " . trim($v);
 1201+ $new_headers[] = $header . ": " . $value;
12431202 }
12441203 }
12451204 if (!$has_stoken) {
12461205 $new_headers[] = AUTH_TOKEN . ": " . $this->auth_token;
12471206 }
12481207 if (!$has_uagent) {
1249 - $new_headers[] = USER_AGENT_HEADER . ": " . USER_AGENT;
 1208+ $new_headers[] = "User-Agent: " . USER_AGENT;
12501209 }
12511210 return $new_headers;
12521211 }
@@ -1269,7 +1228,7 @@
12701229 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, True);
12711230 curl_setopt($ch, CURLOPT_CAINFO, $this->cabundle_path);
12721231 }
1273 - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, True);
 1232+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, False);
12741233 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
12751234 curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
12761235 curl_setopt($ch, CURLOPT_MAXREDIRS, 4);
@@ -1297,9 +1256,6 @@
12981257 if ($conn_type == "DEL_POST") {
12991258 curl_setopt($ch, CURLOPT_NOBODY, 1);
13001259 }
1301 - if ($conn_type == "COPY") {
1302 - curl_setopt($ch, CURLOPT_NOBODY, 1);
1303 - }
13041260 $this->connections[$conn_type] = $ch;
13051261 return;
13061262 }
@@ -1318,9 +1274,7 @@
13191275 $this->_obj_content_length = NULL;
13201276 $this->_obj_metadata = array();
13211277 $this->_obj_manifest = NULL;
1322 - $this->_obj_headers = NULL;
13231278 $this->_obj_write_string = "";
1324 - $this->_cdn_streaming_uri = NULL;
13251279 $this->_cdn_enabled = NULL;
13261280 $this->_cdn_ssl_uri = NULL;
13271281 $this->_cdn_uri = NULL;
@@ -1352,71 +1306,30 @@
13531307 return implode("/",$path);
13541308 }
13551309
1356 - private function _headers(&$obj)
 1310+ private function _metadata_headers(&$obj)
13571311 {
1358 - $hdrs = self::_process_headers($obj->metadata, $obj->headers);
 1312+ $hdrs = array();
13591313 if ($obj->manifest)
13601314 $hdrs[MANIFEST_HEADER] = $obj->manifest;
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));
 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;
14061327 }
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;
 1328+ $hdrs[] = sprintf("%s%s: %s", METADATA_HEADER, $k, trim($v));
14151329 }
14161330 }
1417 -
14181331 return $hdrs;
14191332 }
1420 -
 1333+
14211334 private function _send_request($conn_type, $url_path, $hdrs=NULL, $method="GET", $force_new=False)
14221335 {
14231336 $this->_init($conn_type, $force_new);
@@ -1429,10 +1342,6 @@
14301343 );
14311344
14321345 switch ($method) {
1433 - case "COPY":
1434 - curl_setopt($this->connections[$conn_type],
1435 - CURLOPT_CUSTOMREQUEST, "COPY");
1436 - break;
14371346 case "DELETE":
14381347 curl_setopt($this->connections[$conn_type],
14391348 CURLOPT_CUSTOMREQUEST, "DELETE");
@@ -1485,4 +1394,4 @@
14861395 * c-hanging-comment-ender-p: nil
14871396 * End:
14881397 */
1489 -?>
\ No newline at end of file
 1398+?>

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r99433Noticed a couple of usages of undefined variables...reedy21:36, 10 October 2011
r99441Remove some dupe comments...reedy22:43, 10 October 2011

Status & tagging log