Index: trunk/extensions/SwiftMedia/SwiftMedia.php |
— | — | @@ -12,7 +12,7 @@ |
13 | 13 | $wgAutoloadClasses['SwiftForeignDBFile'] = |
14 | 14 | $wgAutoloadClasses['SwiftForeignDBRepo'] = |
15 | 15 | $wgAutoloadClasses['SwiftForeignDBviaLBRepo'] = |
16 | | - $wgAutoloadClasses['SwiftRepo'] = dirname( __FILE__ ) . '/SwiftMedia.body.php'; |
| 16 | + $wgAutoloadClasses['SwiftRepo'] = dirname(__FILE__) . '/SwiftMedia.body.php'; |
17 | 17 | $wgAutoloadClasses['CF_Authentication'] = |
18 | 18 | $wgAutoloadClasses['CF_Connection'] = |
19 | 19 | $wgAutoloadClasses['CF_Container'] = |
Index: trunk/extensions/SwiftMedia/TODO |
— | — | @@ -15,11 +15,6 @@ |
16 | 16 | 12) Why is anybody calling resolveVirtualUrl()? It's defined in the Repo, but getPath() is defined against a file. |
17 | 17 | 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. |
18 | 18 | 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." |
24 | 19 | 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. " |
25 | 20 | 24) TS: "SwiftRepo::swiftcopy() should return a Status object instead of throwing exceptions." |
26 | 21 | |
— | — | @@ -30,6 +25,11 @@ |
31 | 26 | |
32 | 27 | Resolved: |
33 | 28 | |
| 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." |
34 | 34 | 5) The Upload seems to take more time than I expect, but that could be a function of generating the six thumbnails. |
35 | 35 | It *is* a function of generating the seven (we generate 800x600 twice) thumbnails. Each one takes 1/2 second. |
36 | 36 | 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 @@ |
55 | 55 | /**#@-*/ |
56 | 56 | |
57 | 57 | /** |
58 | | - * @var SwiftRepo |
59 | | - */ |
60 | | - protected $repo; |
61 | | - |
62 | | - /** |
63 | 58 | * Create a LocalFile from a title |
64 | 59 | * Do not call this except from inside a repo class. |
65 | 60 | * |
— | — | @@ -406,69 +401,95 @@ |
407 | 402 | wfDebug( __METHOD__ . ': Storing ' . count( $triplets ) . |
408 | 403 | " triplets; flags: {$flags}\n" ); |
409 | 404 | |
410 | | - // Validate each triplet |
411 | 405 | $status = $this->newGood(); |
412 | | - foreach ( $triplets as $triplet ) { |
413 | | - list( $srcPath, $dstZone, $dstRel ) = $triplet; |
414 | 406 | |
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 | | - |
440 | 407 | // Execute the store operation for each triplet |
441 | 408 | $conn = $this->connect(); |
442 | 409 | |
443 | 410 | foreach ( $triplets as $i => $triplet ) { |
444 | 411 | list( $srcPath, $dstZone, $dstRel ) = $triplet; |
445 | 412 | |
| 413 | + wfDebug( __METHOD__ . ": Storing $srcPath into $dstZone::$dstRel\n"); |
| 414 | + |
446 | 415 | // Point to the container. |
447 | 416 | $dstContainer = $this->getZoneContainer( $dstZone ); |
448 | | - $dstc = $this->get_container( $conn, $dstContainer ); |
| 417 | + $dstc = $this->get_container($conn, $dstContainer); |
449 | 418 | |
450 | 419 | $good = true; |
451 | 420 | |
452 | 421 | // Where are we copying this from? |
453 | | - if ( self::isVirtualUrl( $srcPath ) ) { |
| 422 | + if (self::isVirtualUrl( $srcPath )) { |
454 | 423 | $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); |
457 | 426 | |
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 | + } |
461 | 447 | } |
| 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 | + } |
462 | 460 | } 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 | + } |
467 | 480 | } |
| 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 | + } |
468 | 493 | } |
469 | | - if ( 0 ) { |
470 | | - $status->error( 'filecopyerror', $srcPath, $dstPath ); |
471 | | - $good = false; |
472 | | - } |
473 | 494 | if ( $good ) { |
474 | 495 | $status->successCount++; |
475 | 496 | } else { |
— | — | @@ -901,7 +922,6 @@ |
902 | 923 | * copy of the file MUST delete the produced file, or else store it in |
903 | 924 | * SwiftFile->tempPath so it will be deleted when the object goes out of |
904 | 925 | * scope. |
905 | | - * FIXME: how do we return a fatal error from Swift? |
906 | 926 | */ |
907 | 927 | function getLocalCopy( $container, $rel ) { |
908 | 928 | |
Index: trunk/extensions/SwiftMedia/php-cloudfiles/cloudfiles.php |
— | — | @@ -208,7 +208,7 @@ |
209 | 209 | if ($status == 401) { |
210 | 210 | throw new AuthenticationException("Invalid username or access key."); |
211 | 211 | } |
212 | | - if ($status < 200 || $status > 299) { |
| 212 | + if ($status != 204 && $status != 200) { |
213 | 213 | throw new InvalidResponseException( |
214 | 214 | "Unexpected response (".$status."): ".$reason); |
215 | 215 | } |
— | — | @@ -923,7 +923,6 @@ |
924 | 924 | public $bytes_used; |
925 | 925 | |
926 | 926 | public $cdn_enabled; |
927 | | - public $cdn_streaming_uri; |
928 | 927 | public $cdn_ssl_uri; |
929 | 928 | public $cdn_uri; |
930 | 929 | public $cdn_ttl; |
— | — | @@ -962,7 +961,6 @@ |
963 | 962 | $this->cdn_enabled = NULL; |
964 | 963 | $this->cdn_uri = NULL; |
965 | 964 | $this->cdn_ssl_uri = NULL; |
966 | | - $this->cdn_streaming_uri = NULL; |
967 | 965 | $this->cdn_ttl = NULL; |
968 | 966 | $this->cdn_log_retention = NULL; |
969 | 967 | $this->cdn_acl_user_agent = NULL; |
— | — | @@ -1278,7 +1276,6 @@ |
1279 | 1277 | $this->cdn_ttl = NULL; |
1280 | 1278 | $this->cdn_uri = NULL; |
1281 | 1279 | $this->cdn_ssl_uri = NULL; |
1282 | | - $this->cdn_streaming_uri - NULL; |
1283 | 1280 | $this->cdn_log_retention = NULL; |
1284 | 1281 | $this->cdn_acl_user_agent = NULL; |
1285 | 1282 | $this->cdn_acl_referrer = NULL; |
— | — | @@ -1496,235 +1493,6 @@ |
1497 | 1494 | } |
1498 | 1495 | |
1499 | 1496 | /** |
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 | | - /** |
1729 | 1497 | * Delete a remote storage Object |
1730 | 1498 | * |
1731 | 1499 | * Given an Object instance or name, permanently remove the remote Object |
— | — | @@ -1744,13 +1512,12 @@ |
1745 | 1513 | * </code> |
1746 | 1514 | * |
1747 | 1515 | * @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) |
1749 | 1516 | * @return boolean <kbd>True</kbd> if successfully removed |
1750 | 1517 | * @throws SyntaxException invalid Object name |
1751 | 1518 | * @throws NoSuchObjectException remote Object does not exist |
1752 | 1519 | * @throws InvalidResponseException unexpected response |
1753 | 1520 | */ |
1754 | | - function delete_object($obj,$container=NULL) |
| 1521 | + function delete_object($obj) |
1755 | 1522 | { |
1756 | 1523 | $obj_name = NULL; |
1757 | 1524 | if (is_object($obj)) { |
— | — | @@ -1764,32 +1531,12 @@ |
1765 | 1532 | if (!$obj_name) { |
1766 | 1533 | throw new SyntaxException("Object name not set."); |
1767 | 1534 | } |
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); |
1789 | 1536 | #if ($status == 401 && $this->_re_auth()) { |
1790 | 1537 | # return $this->delete_object($obj); |
1791 | 1538 | #} |
1792 | 1539 | if ($status == 404) { |
1793 | | - $m = "Specified object '".$container_name."/".$obj_name; |
| 1540 | + $m = "Specified object '".$this->name."/".$obj_name; |
1794 | 1541 | $m.= "' did not exist to delete."; |
1795 | 1542 | throw new NoSuchObjectException($m); |
1796 | 1543 | } |
— | — | @@ -1805,7 +1552,7 @@ |
1806 | 1553 | * |
1807 | 1554 | * Given an Object whos name contains '/' path separators, this function |
1808 | 1555 | * will create the "directory marker" Objects of one byte with the |
1809 | | - * Content-Type of "application/directory". |
| 1556 | + * Content-Type of "application/folder". |
1810 | 1557 | * |
1811 | 1558 | * It assumes the last element of the full path is the "real" Object |
1812 | 1559 | * and does NOT create a remote storage Object for that last element. |
— | — | @@ -1836,7 +1583,7 @@ |
1837 | 1584 | */ |
1838 | 1585 | private function _cdn_initialize() |
1839 | 1586 | { |
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, |
1841 | 1588 | $cdn_log_retention, $cdn_acl_user_agent, $cdn_acl_referrer) = |
1842 | 1589 | $this->cfs_http->head_cdn_container($this->name); |
1843 | 1590 | #if ($status == 401 && $this->_re_auth()) { |
— | — | @@ -1847,7 +1594,6 @@ |
1848 | 1595 | "Invalid response (".$status."): ".$this->cfs_http->get_error()); |
1849 | 1596 | } |
1850 | 1597 | $this->cdn_enabled = $cdn_enabled; |
1851 | | - $this->cdn_streaming_uri = $cdn_streaming_uri; |
1852 | 1598 | $this->cdn_ssl_uri = $cdn_ssl_uri; |
1853 | 1599 | $this->cdn_uri = $cdn_uri; |
1854 | 1600 | $this->cdn_ttl = $cdn_ttl; |
— | — | @@ -1888,7 +1634,6 @@ |
1889 | 1635 | public $content_type; |
1890 | 1636 | public $content_length; |
1891 | 1637 | public $metadata; |
1892 | | - public $headers; |
1893 | 1638 | public $manifest; |
1894 | 1639 | private $etag; |
1895 | 1640 | |
— | — | @@ -1918,7 +1663,6 @@ |
1919 | 1664 | $this->content_type = NULL; |
1920 | 1665 | $this->content_length = 0; |
1921 | 1666 | $this->metadata = array(); |
1922 | | - $this->headers = array(); |
1923 | 1667 | $this->manifest = NULL; |
1924 | 1668 | if ($dohead) { |
1925 | 1669 | if (!$this->_initialize() && $force_exists) { |
— | — | @@ -2056,31 +1800,6 @@ |
2057 | 1801 | } |
2058 | 1802 | return NULL; |
2059 | 1803 | } |
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 | | - } |
2085 | 1804 | |
2086 | 1805 | /** |
2087 | 1806 | * Read the remote Object's data |
— | — | @@ -2204,12 +1923,6 @@ |
2205 | 1924 | * "Version" => "1.2.2" |
2206 | 1925 | * ); |
2207 | 1926 | * |
2208 | | - * # Define additional headers for the object |
2209 | | - * # |
2210 | | - * $doc->headers = array( |
2211 | | - * "Content-Disposition" => "attachment", |
2212 | | - * ); |
2213 | | - * |
2214 | 1927 | * # Push the new metadata up to the storage system |
2215 | 1928 | * # |
2216 | 1929 | * $doc->sync_metadata(); |
— | — | @@ -2220,7 +1933,7 @@ |
2221 | 1934 | */ |
2222 | 1935 | function sync_metadata() |
2223 | 1936 | { |
2224 | | - if (!empty($this->metadata) || !empty($this->headers) || $this->manifest) { |
| 1937 | + if (!empty($this->metadata) || $this->manifest) { |
2225 | 1938 | $status = $this->container->cfs_http->update_object($this); |
2226 | 1939 | #if ($status == 401 && $this->_re_auth()) { |
2227 | 1940 | # return $this->sync_metadata(); |
— | — | @@ -2263,8 +1976,8 @@ |
2264 | 1977 | function sync_manifest() |
2265 | 1978 | { |
2266 | 1979 | return $this->sync_metadata(); |
2267 | | - } |
2268 | | - /** |
| 1980 | + } |
| 1981 | + /** |
2269 | 1982 | * Upload Object's data to Cloud Files |
2270 | 1983 | * |
2271 | 1984 | * Write data to the remote Object. The $data argument can either be a |
— | — | @@ -2361,6 +2074,54 @@ |
2362 | 2075 | return True; |
2363 | 2076 | } |
2364 | 2077 | |
| 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 | + |
2365 | 2126 | /** |
2366 | 2127 | * Upload Object data from local filename |
2367 | 2128 | * |
— | — | @@ -2544,8 +2305,8 @@ |
2545 | 2306 | private function _initialize() |
2546 | 2307 | { |
2547 | 2308 | 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); |
2550 | 2311 | #if ($status == 401 && $this->_re_auth()) { |
2551 | 2312 | # return $this->_initialize(); |
2552 | 2313 | #} |
— | — | @@ -2561,8 +2322,7 @@ |
2562 | 2323 | $this->content_type = $content_type; |
2563 | 2324 | $this->content_length = $content_length; |
2564 | 2325 | $this->metadata = $metadata; |
2565 | | - $this->headers = $headers; |
2566 | | - $this->manifest = $manifest; |
| 2326 | + $this->manifest = NULL; |
2567 | 2327 | return True; |
2568 | 2328 | } |
2569 | 2329 | |
— | — | @@ -2589,4 +2349,4 @@ |
2590 | 2350 | * c-hanging-comment-ender-p: nil |
2591 | 2351 | * End: |
2592 | 2352 | */ |
2593 | | -?> |
\ No newline at end of file |
| 2353 | +?> |
Index: trunk/extensions/SwiftMedia/php-cloudfiles/cloudfiles_http.php |
— | — | @@ -29,22 +29,16 @@ |
30 | 30 | */ |
31 | 31 | require_once("cloudfiles_exceptions.php"); |
32 | 32 | |
33 | | -define("PHP_CF_VERSION", "1.7.10"); |
| 33 | +define("PHP_CF_VERSION", "1.7.9"); |
34 | 34 | define("USER_AGENT", sprintf("PHP-CloudFiles/%s", PHP_CF_VERSION)); |
35 | | -define("MAX_HEADER_NAME_LEN", 128); |
36 | | -define("MAX_HEADER_VALUE_LEN", 256); |
37 | 35 | define("ACCOUNT_CONTAINER_COUNT", "X-Account-Container-Count"); |
38 | 36 | define("ACCOUNT_BYTES_USED", "X-Account-Bytes-Used"); |
39 | 37 | define("CONTAINER_OBJ_COUNT", "X-Container-Object-Count"); |
40 | 38 | define("CONTAINER_BYTES_USED", "X-Container-Bytes-Used"); |
| 39 | +define("METADATA_HEADER", "X-Object-Meta-"); |
41 | 40 | 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"); |
46 | 41 | define("CDN_URI", "X-CDN-URI"); |
47 | 42 | define("CDN_SSL_URI", "X-CDN-SSL-URI"); |
48 | | -define("CDN_STREAMING_URI", "X-CDN-Streaming-URI"); |
49 | 43 | define("CDN_ENABLED", "X-CDN-Enabled"); |
50 | 44 | define("CDN_LOG_RETENTION", "X-Log-Retention"); |
51 | 45 | define("CDN_ACL_USER_AGENT", "X-User-Agent-ACL"); |
— | — | @@ -59,13 +53,6 @@ |
60 | 54 | define("AUTH_KEY_HEADER_LEGACY", "X-Storage-Pass"); |
61 | 55 | define("AUTH_TOKEN_LEGACY", "X-Storage-Token"); |
62 | 56 | 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 | | - |
70 | 57 | /** |
71 | 58 | * HTTP/cURL wrapper for Cloud Files |
72 | 59 | * |
— | — | @@ -108,13 +95,11 @@ |
109 | 96 | private $_obj_content_type; |
110 | 97 | private $_obj_content_length; |
111 | 98 | private $_obj_metadata; |
112 | | - private $_obj_headers; |
113 | 99 | private $_obj_manifest; |
114 | 100 | private $_obj_write_resource; |
115 | 101 | private $_obj_write_string; |
116 | 102 | private $_cdn_enabled; |
117 | 103 | private $_cdn_ssl_uri; |
118 | | - private $_cdn_streaming_uri; |
119 | 104 | private $_cdn_uri; |
120 | 105 | private $_cdn_ttl; |
121 | 106 | private $_cdn_log_retention; |
— | — | @@ -146,7 +131,6 @@ |
147 | 132 | "HEAD" => NULL, # HEAD requests |
148 | 133 | "PUT_CONT" => NULL, # PUT container |
149 | 134 | "DEL_POST" => NULL, # DELETE containers/objects, POST objects |
150 | | - "COPY" => null, # COPY objects |
151 | 135 | ); |
152 | 136 | |
153 | 137 | $this->_user_read_progress_callback_func = NULL; |
— | — | @@ -166,10 +150,8 @@ |
167 | 151 | $this->_obj_content_length = NULL; |
168 | 152 | $this->_obj_metadata = array(); |
169 | 153 | $this->_obj_manifest = NULL; |
170 | | - $this->_obj_headers = NULL; |
171 | 154 | $this->_cdn_enabled = NULL; |
172 | 155 | $this->_cdn_ssl_uri = NULL; |
173 | | - $this->_cdn_streaming_uri = NULL; |
174 | 156 | $this->_cdn_uri = NULL; |
175 | 157 | $this->_cdn_ttl = NULL; |
176 | 158 | $this->_cdn_log_retention = NULL; |
— | — | @@ -230,6 +212,7 @@ |
231 | 213 | curl_setopt($curl_ch, CURLOPT_SSL_VERIFYPEER, True); |
232 | 214 | curl_setopt($curl_ch, CURLOPT_CAINFO, $this->cabundle_path); |
233 | 215 | } |
| 216 | + curl_setopt($curl_ch, CURLOPT_SSL_VERIFYPEER, False); |
234 | 217 | curl_setopt($curl_ch, CURLOPT_VERBOSE, $this->dbug); |
235 | 218 | curl_setopt($curl_ch, CURLOPT_FOLLOWLOCATION, 1); |
236 | 219 | curl_setopt($curl_ch, CURLOPT_MAXREDIRS, 4); |
— | — | @@ -266,7 +249,7 @@ |
267 | 250 | } |
268 | 251 | if (!$return_code) { |
269 | 252 | $this->error_str .= ": Failed to obtain valid HTTP response."; |
270 | | - return array(0,$this->error_str,array()); |
| 253 | + array(0,$this->error_str,array()); |
271 | 254 | } |
272 | 255 | if ($return_code == 401) { |
273 | 256 | return array($return_code,"Unauthorized",array()); |
— | — | @@ -410,18 +393,17 @@ |
411 | 394 | |
412 | 395 | if (!$return_code) { |
413 | 396 | $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); |
415 | 398 | } |
416 | 399 | 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); |
418 | 401 | } |
419 | 402 | 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); |
421 | 404 | } |
422 | 405 | if ($return_code == 204) { |
423 | 406 | return array($return_code,$this->response_reason, |
424 | 407 | $this->_cdn_enabled, $this->_cdn_ssl_uri, |
425 | | - $this->_cdn_streaming_uri, |
426 | 408 | $this->_cdn_uri, $this->_cdn_ttl, |
427 | 409 | $this->_cdn_log_retention, |
428 | 410 | $this->_cdn_acl_user_agent, |
— | — | @@ -429,11 +411,10 @@ |
430 | 412 | ); |
431 | 413 | } |
432 | 414 | return array($return_code,$this->response_reason, |
433 | | - NULL,NULL,NULL,NULL, |
| 415 | + NULL,NULL,NULL, |
434 | 416 | $this->_cdn_log_retention, |
435 | 417 | $this->_cdn_acl_user_agent, |
436 | | - $this->_cdn_acl_referrer, |
437 | | - NULL |
| 418 | + $this->_cdn_acl_referrer |
438 | 419 | ); |
439 | 420 | } |
440 | 421 | |
— | — | @@ -530,7 +511,7 @@ |
531 | 512 | |
532 | 513 | if (!$return_code) { |
533 | 514 | $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); |
535 | 516 | } |
536 | 517 | if ($return_code == 404) { |
537 | 518 | return array($return_code,"Account not found.",0,0); |
— | — | @@ -575,19 +556,16 @@ |
576 | 557 | $url_path = $this->_make_path("STORAGE", $container_name); |
577 | 558 | $return_code = $this->_send_request("DEL_POST",$url_path,array(),"DELETE"); |
578 | 559 | |
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) { |
586 | 564 | $this->error_str = "Container must be empty prior to removing it."; |
587 | | - break; |
588 | | - case 404: |
| 565 | + } |
| 566 | + if ($return_code == 404) { |
589 | 567 | $this->error_str = "Specified container did not exist to delete."; |
590 | | - break; |
591 | | - default: |
| 568 | + } |
| 569 | + if ($return_code != 204) { |
592 | 570 | $this->error_str = "Unexpected HTTP return code: $return_code."; |
593 | 571 | } |
594 | 572 | return $return_code; |
— | — | @@ -723,7 +701,7 @@ |
724 | 702 | |
725 | 703 | if (!$return_code) { |
726 | 704 | $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); |
728 | 706 | } |
729 | 707 | if ($return_code == 404) { |
730 | 708 | return array($return_code,"Container not found.",0,0); |
— | — | @@ -810,7 +788,10 @@ |
811 | 789 | throw new SyntaxException( |
812 | 790 | "Method argument is not a valid CF_Object."); |
813 | 791 | } |
814 | | - if (!is_resource($fp)) { |
| 792 | + $source = NULL; |
| 793 | + if (is_string($fp)) { |
| 794 | + $source = $fp; |
| 795 | + } elseif (!is_resource($fp)) { |
815 | 796 | throw new SyntaxException( |
816 | 797 | "File pointer argument is not a valid resource."); |
817 | 798 | } |
— | — | @@ -818,32 +799,40 @@ |
819 | 800 | $conn_type = "PUT_OBJ"; |
820 | 801 | $url_path = $this->_make_path("STORAGE", $obj->container->name,$obj->name); |
821 | 802 | |
822 | | - $hdrs = $this->_headers($obj); |
| 803 | + $hdrs = $this->_metadata_headers($obj); |
823 | 804 | |
824 | 805 | $etag = $obj->getETag(); |
825 | | - if (isset($etag)) { |
| 806 | + if (!$source && isset($etag)) { |
826 | 807 | $hdrs[] = "ETag: " . $etag; |
827 | 808 | } |
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) { |
829 | 812 | $hdrs[] = "Content-Type: application/octet-stream"; |
830 | 813 | } else { |
831 | 814 | $hdrs[] = "Content-Type: " . $obj->content_type; |
832 | 815 | } |
833 | 816 | |
834 | 817 | $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); |
845 | 820 | 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 | + } |
848 | 837 | $return_code = $this->_send_request($conn_type,$url_path,$hdrs); |
849 | 838 | |
850 | 839 | if (!$return_code) { |
— | — | @@ -874,29 +863,25 @@ |
875 | 864 | "Method argument is not a valid CF_Object."); |
876 | 865 | } |
877 | 866 | |
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."; |
881 | 870 | return 0; |
882 | 871 | } |
883 | 872 | |
884 | 873 | $url_path = $this->_make_path("STORAGE", $obj->container->name,$obj->name); |
885 | 874 | |
886 | | - $hdrs = $this->_headers($obj); |
| 875 | + $hdrs = $this->_metadata_headers($obj); |
887 | 876 | $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) { |
892 | 878 | $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) { |
896 | 882 | $this->error_str = "Account, Container, or Object not found."; |
897 | | - break; |
898 | | - default: |
| 883 | + } |
| 884 | + if ($return_code != 202) { |
899 | 885 | $this->error_str = "Unexpected HTTP return code: $return_code"; |
900 | | - break; |
901 | 886 | } |
902 | 887 | return $return_code; |
903 | 888 | } |
— | — | @@ -918,12 +903,12 @@ |
919 | 904 | if (!$return_code) { |
920 | 905 | $this->error_str .= ": Failed to obtain valid HTTP response."; |
921 | 906 | return array(0, $this->error_str." ".$this->response_reason, |
922 | | - NULL, NULL, NULL, NULL, array(), NULL, array()); |
| 907 | + NULL, NULL, NULL, NULL, array()); |
923 | 908 | } |
924 | 909 | |
925 | 910 | if ($return_code == 404) { |
926 | 911 | return array($return_code, $this->response_reason, |
927 | | - NULL, NULL, NULL, NULL, array(), NULL, array()); |
| 912 | + NULL, NULL, NULL, NULL, array()); |
928 | 913 | } |
929 | 914 | if ($return_code == 204 || $return_code == 200) { |
930 | 915 | return array($return_code,$this->response_reason, |
— | — | @@ -932,68 +917,13 @@ |
933 | 918 | $this->_obj_content_type, |
934 | 919 | $this->_obj_content_length, |
935 | 920 | $this->_obj_metadata, |
936 | | - $this->_obj_manifest, |
937 | | - $this->_obj_headers); |
| 921 | + $this->_obj_manifest); |
938 | 922 | } |
939 | 923 | $this->error_str = "Unexpected HTTP return code: $return_code"; |
940 | 924 | return array($return_code, $this->error_str." ".$this->response_reason, |
941 | | - NULL, NULL, NULL, NULL, array(), NULL, array()); |
| 925 | + NULL, NULL, NULL, NULL, array()); |
942 | 926 | } |
943 | 927 | |
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 | | - |
998 | 928 | # DELETE /v1/Account/Container/Object |
999 | 929 | # |
1000 | 930 | function delete_object($container_name, $object_name) |
— | — | @@ -1015,17 +945,14 @@ |
1016 | 946 | |
1017 | 947 | $url_path = $this->_make_path("STORAGE", $container_name,$object_name); |
1018 | 948 | $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) { |
1023 | 950 | $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) { |
1027 | 954 | $this->error_str = "Specified container did not exist to delete."; |
1028 | | - break; |
1029 | | - default: |
| 955 | + } |
| 956 | + if ($return_code != 204) { |
1030 | 957 | $this->error_str = "Unexpected HTTP return code: $return_code."; |
1031 | 958 | } |
1032 | 959 | return $return_code; |
— | — | @@ -1084,85 +1011,112 @@ |
1085 | 1012 | |
1086 | 1013 | private function _header_cb($ch, $header) |
1087 | 1014 | { |
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 | + } |
1089 | 1054 | |
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); |
1094 | 1059 | } |
1095 | 1060 | |
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); |
1165 | 1065 | } |
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); |
1167 | 1121 | } |
1168 | 1122 | |
1169 | 1123 | private function _read_cb($ch, $fd, $length) |
— | — | @@ -1229,23 +1183,28 @@ |
1230 | 1184 | if (is_array($hdrs)) { |
1231 | 1185 | foreach ($hdrs as $h => $v) { |
1232 | 1186 | 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); |
1234 | 1193 | } |
1235 | 1194 | |
1236 | | - if (strncasecmp($h, AUTH_TOKEN, strlen(AUTH_TOKEN)) === 0) { |
| 1195 | + if (stripos($header, AUTH_TOKEN) === 0) { |
1237 | 1196 | $has_stoken = True; |
1238 | 1197 | } |
1239 | | - if (strncasecmp($h, USER_AGENT_HEADER, strlen(USER_AGENT_HEADER)) === 0) { |
| 1198 | + if (stripos($header, "user-agent") === 0) { |
1240 | 1199 | $has_uagent = True; |
1241 | 1200 | } |
1242 | | - $new_headers[] = $h . ": " . trim($v); |
| 1201 | + $new_headers[] = $header . ": " . $value; |
1243 | 1202 | } |
1244 | 1203 | } |
1245 | 1204 | if (!$has_stoken) { |
1246 | 1205 | $new_headers[] = AUTH_TOKEN . ": " . $this->auth_token; |
1247 | 1206 | } |
1248 | 1207 | if (!$has_uagent) { |
1249 | | - $new_headers[] = USER_AGENT_HEADER . ": " . USER_AGENT; |
| 1208 | + $new_headers[] = "User-Agent: " . USER_AGENT; |
1250 | 1209 | } |
1251 | 1210 | return $new_headers; |
1252 | 1211 | } |
— | — | @@ -1269,7 +1228,7 @@ |
1270 | 1229 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, True); |
1271 | 1230 | curl_setopt($ch, CURLOPT_CAINFO, $this->cabundle_path); |
1272 | 1231 | } |
1273 | | - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, True); |
| 1232 | + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, False); |
1274 | 1233 | curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); |
1275 | 1234 | curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); |
1276 | 1235 | curl_setopt($ch, CURLOPT_MAXREDIRS, 4); |
— | — | @@ -1297,9 +1256,6 @@ |
1298 | 1257 | if ($conn_type == "DEL_POST") { |
1299 | 1258 | curl_setopt($ch, CURLOPT_NOBODY, 1); |
1300 | 1259 | } |
1301 | | - if ($conn_type == "COPY") { |
1302 | | - curl_setopt($ch, CURLOPT_NOBODY, 1); |
1303 | | - } |
1304 | 1260 | $this->connections[$conn_type] = $ch; |
1305 | 1261 | return; |
1306 | 1262 | } |
— | — | @@ -1318,9 +1274,7 @@ |
1319 | 1275 | $this->_obj_content_length = NULL; |
1320 | 1276 | $this->_obj_metadata = array(); |
1321 | 1277 | $this->_obj_manifest = NULL; |
1322 | | - $this->_obj_headers = NULL; |
1323 | 1278 | $this->_obj_write_string = ""; |
1324 | | - $this->_cdn_streaming_uri = NULL; |
1325 | 1279 | $this->_cdn_enabled = NULL; |
1326 | 1280 | $this->_cdn_ssl_uri = NULL; |
1327 | 1281 | $this->_cdn_uri = NULL; |
— | — | @@ -1352,71 +1306,30 @@ |
1353 | 1307 | return implode("/",$path); |
1354 | 1308 | } |
1355 | 1309 | |
1356 | | - private function _headers(&$obj) |
| 1310 | + private function _metadata_headers(&$obj) |
1357 | 1311 | { |
1358 | | - $hdrs = self::_process_headers($obj->metadata, $obj->headers); |
| 1312 | + $hdrs = array(); |
1359 | 1313 | if ($obj->manifest) |
1360 | 1314 | $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; |
1406 | 1327 | } |
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)); |
1415 | 1329 | } |
1416 | 1330 | } |
1417 | | - |
1418 | 1331 | return $hdrs; |
1419 | 1332 | } |
1420 | | - |
| 1333 | + |
1421 | 1334 | private function _send_request($conn_type, $url_path, $hdrs=NULL, $method="GET", $force_new=False) |
1422 | 1335 | { |
1423 | 1336 | $this->_init($conn_type, $force_new); |
— | — | @@ -1429,10 +1342,6 @@ |
1430 | 1343 | ); |
1431 | 1344 | |
1432 | 1345 | switch ($method) { |
1433 | | - case "COPY": |
1434 | | - curl_setopt($this->connections[$conn_type], |
1435 | | - CURLOPT_CUSTOMREQUEST, "COPY"); |
1436 | | - break; |
1437 | 1346 | case "DELETE": |
1438 | 1347 | curl_setopt($this->connections[$conn_type], |
1439 | 1348 | CURLOPT_CUSTOMREQUEST, "DELETE"); |
— | — | @@ -1485,4 +1394,4 @@ |
1486 | 1395 | * c-hanging-comment-ender-p: nil |
1487 | 1396 | * End: |
1488 | 1397 | */ |
1489 | | -?> |
\ No newline at end of file |
| 1398 | +?> |