Version Description
- Updated AWS library
- Added support of set_sql_mode by dbcluster
- Improved support for webserver running on non-default port with disk-enhanced
- Improved menu icons
- Fixed php warning when remote service cannot be loaded
- Fixed php warnings on support page
Download this release
Release Info
Developer | fredericktownes |
Plugin | ![]() |
Version | 0.9.7.5 |
Comparing to | |
See all releases |
Code changes from version 0.9.7.4 to 0.9.7.5
- CdnEngine.php +2 -2
- CdnEngine_Azure.php +5 -11
- CdnEngine_Base.php +2 -8
- CdnEngine_CloudFront.php +345 -0
- CdnEngine_Mirror_CloudFront.php +324 -0
- CdnEngine_S3.php +188 -235
- CdnEngine_S3_Cf.php +0 -453
- CdnEngine_S3_Cf_Custom.php +0 -19
- CdnEngine_S3_Cf_S3.php +0 -10
- CdnEngine_S3_Compatible.php +6 -6
- Cdn_AdminActions.php +22 -17
- Cdn_Core_Admin.php +45 -57
- Cdn_Plugin_Admin.php +1 -1
- Cdn_Util.php +1 -0
- Cdnfsd_CloudFront_Api.php +0 -344
- Cdnfsd_CloudFront_Engine.php +46 -11
- Cdnfsd_CloudFront_Popup.php +114 -83
- Cdnfsd_CloudFront_Popup_View_Distribution.php +45 -47
- Config.php +13 -13
- ConfigKeys.php +0 -4
- DbCache_Wpdb.php +14 -0
- DbCache_WpdbInjection.php +8 -0
- Enterprise_CacheFlush_MakeSnsEvent.php +6 -3
- Enterprise_Dbcache_WpdbInjection_Cluster.php +1 -0
- Enterprise_SnsBase.php +13 -9
- Enterprise_SnsServer.php +14 -19
- Generic_Plugin.php +57 -34
- Generic_Plugin_Admin.php +4 -30
- Generic_WidgetServices_View.php +17 -17
- PgCache_ContentGrabber.php +3 -1
- PgCache_Flush.php +38 -18
- Root_AdminMenu.php +4 -4
- Support_Page.php +19 -22
- Support_Page_View_PageContent.php +10 -10
- Util_Admin.php +7 -21
- inc/mime/html.php +0 -1
- inc/options/browsercache.php +1 -1
- inc/options/general.php +285 -285
- lib/Aws/Aws/Api/AbstractModel.php +67 -0
- lib/Aws/Aws/Api/ApiProvider.php +244 -0
- lib/Aws/Aws/Api/DateTimeResult.php +41 -0
- lib/Aws/Aws/Api/DocModel.php +128 -0
- lib/Aws/Aws/Api/ErrorParser/JsonParserTrait.php +26 -0
- lib/Aws/Aws/Api/ErrorParser/JsonRpcErrorParser.php +31 -0
- lib/Aws/Aws/Api/ErrorParser/RestJsonErrorParser.php +35 -0
- lib/Aws/Aws/Api/ErrorParser/XmlErrorParser.php +82 -0
- lib/Aws/Aws/Api/ListShape.php +35 -0
- lib/Aws/Aws/Api/MapShape.php +54 -0
- lib/Aws/Aws/Api/Operation.php +97 -0
- lib/Aws/Aws/Api/Parser/AbstractParser.php +46 -0
- lib/Aws/Aws/Api/Parser/AbstractRestParser.php +173 -0
- lib/Aws/Aws/Api/Parser/Crc32ValidatingParser.php +54 -0
- lib/Aws/Aws/Api/Parser/DecodingEventStreamIterator.php +335 -0
- lib/Aws/Aws/Api/Parser/EventParsingIterator.php +107 -0
- lib/Aws/Aws/Api/Parser/Exception/ParserException.php +31 -0
- lib/Aws/Aws/Api/Parser/JsonParser.php +62 -0
- lib/Aws/Aws/Api/Parser/JsonRpcParser.php +51 -0
- lib/Aws/Aws/Api/Parser/PayloadParserTrait.php +61 -0
- lib/Aws/Aws/Api/Parser/QueryParser.php +60 -0
- lib/Aws/Aws/Api/Parser/RestJsonParser.php +49 -0
- lib/Aws/Aws/Api/Parser/RestXmlParser.php +42 -0
- lib/Aws/Aws/Api/Parser/XmlParser.php +138 -0
- lib/Aws/Aws/Api/Serializer/Ec2ParamBuilder.php +40 -0
- lib/Aws/Aws/Api/Serializer/JsonBody.php +96 -0
- lib/Aws/Aws/Api/Serializer/JsonRpcSerializer.php +69 -0
- lib/Aws/Aws/Api/Serializer/QueryParamBuilder.php +157 -0
- lib/Aws/Aws/Api/Serializer/QuerySerializer.php +69 -0
- lib/Aws/Aws/Api/Serializer/RestJsonSerializer.php +39 -0
- lib/Aws/Aws/Api/Serializer/RestSerializer.php +219 -0
- lib/Aws/Aws/Api/Serializer/RestXmlSerializer.php +34 -0
- lib/Aws/Aws/Api/Serializer/XmlBody.php +220 -0
- lib/Aws/Aws/Api/Service.php +448 -0
- lib/Aws/Aws/Api/Shape.php +69 -0
- lib/Aws/Aws/Api/ShapeMap.php +66 -0
- lib/Aws/Aws/Api/StructureShape.php +79 -0
- lib/Aws/Aws/Api/TimestampShape.php +48 -0
- lib/Aws/Aws/Api/Validator.php +286 -0
- lib/Aws/Aws/AwsClient.php +402 -0
- lib/Aws/Aws/AwsClientInterface.php +169 -0
- lib/Aws/Aws/AwsClientTrait.php +92 -0
- lib/Aws/Aws/CacheInterface.php +34 -0
- lib/Aws/Aws/ClientResolver.php +768 -0
- lib/Aws/Aws/ClientSideMonitoring/AbstractMonitoringMiddleware.php +275 -0
- lib/Aws/Aws/ClientSideMonitoring/ApiCallAttemptMonitoringMiddleware.php +262 -0
- lib/Aws/Aws/ClientSideMonitoring/ApiCallMonitoringMiddleware.php +176 -0
- lib/Aws/Aws/ClientSideMonitoring/Configuration.php +65 -0
- lib/Aws/Aws/ClientSideMonitoring/ConfigurationInterface.php +37 -0
- lib/Aws/Aws/ClientSideMonitoring/ConfigurationProvider.php +342 -0
- lib/Aws/Aws/ClientSideMonitoring/Exception/ConfigurationException.php +15 -0
- lib/Aws/Aws/ClientSideMonitoring/MonitoringMiddlewareInterface.php +35 -0
- lib/Aws/Aws/CloudFront/CloudFrontClient.php +190 -0
- lib/Aws/Aws/CloudFront/CookieSigner.php +65 -0
- lib/Aws/Aws/CloudFront/Exception/CloudFrontException.php +9 -0
- lib/Aws/Aws/CloudFront/Signer.php +117 -0
- lib/Aws/Aws/CloudFront/UrlSigner.php +119 -0
- lib/Aws/Aws/Command.php +62 -0
- lib/Aws/Aws/CommandInterface.php +42 -0
- lib/Aws/Aws/CommandPool.php +150 -0
- lib/Aws/Aws/Credentials/AssumeRoleCredentialProvider.php +64 -0
- lib/Aws/Aws/Credentials/CredentialProvider.php +488 -0
- lib/Aws/Aws/Credentials/Credentials.php +91 -0
- lib/Aws/Aws/Credentials/CredentialsInterface.php +52 -0
- lib/Aws/Aws/Credentials/EcsCredentialProvider.php +88 -0
- lib/Aws/Aws/Credentials/InstanceProfileProvider.php +118 -0
- lib/Aws/Aws/DoctrineCacheAdapter.php +55 -0
- lib/Aws/Aws/Endpoint/EndpointProvider.php +96 -0
- lib/Aws/Aws/Endpoint/Partition.php +183 -0
- lib/Aws/Aws/Endpoint/PartitionEndpointProvider.php +108 -0
- lib/Aws/Aws/Endpoint/PartitionInterface.php +56 -0
- lib/Aws/Aws/Endpoint/PatternEndpointProvider.php +51 -0
- lib/Aws/Aws/EndpointDiscovery/Configuration.php +48 -0
- lib/Aws/Aws/EndpointDiscovery/ConfigurationInterface.php +30 -0
- lib/Aws/Aws/EndpointDiscovery/ConfigurationProvider.php +333 -0
- lib/Aws/Aws/EndpointDiscovery/EndpointDiscoveryMiddleware.php +414 -0
- lib/Aws/Aws/EndpointDiscovery/EndpointList.php +85 -0
- lib/Aws/Aws/EndpointDiscovery/Exception/ConfigurationException.php +14 -0
- lib/Aws/Aws/EndpointParameterMiddleware.php +84 -0
- lib/Aws/Aws/Exception/AwsException.php +237 -0
- lib/Aws/Aws/Exception/CouldNotCreateChecksumException.php +25 -0
- lib/Aws/Aws/Exception/CredentialsException.php +11 -0
- lib/Aws/Aws/Exception/EventStreamDataException.php +38 -0
- lib/Aws/Aws/Exception/MultipartUploadException.php +63 -0
- lib/Aws/Aws/Exception/UnresolvedApiException.php +11 -0
- lib/Aws/Aws/Exception/UnresolvedEndpointException.php +11 -0
- lib/Aws/Aws/Exception/UnresolvedSignatureException.php +11 -0
- lib/Aws/Aws/Handler/GuzzleV5/GuzzleHandler.php +210 -0
- lib/Aws/Aws/Handler/GuzzleV5/GuzzleStream.php +24 -0
- lib/Aws/Aws/Handler/GuzzleV5/PsrStream.php +34 -0
- lib/Aws/Aws/Handler/GuzzleV6/GuzzleHandler.php +85 -0
- lib/Aws/Aws/HandlerList.php +451 -0
- lib/Aws/Aws/HasDataTrait.php +60 -0
- lib/Aws/Aws/HasMonitoringEventsTrait.php +39 -0
- lib/Aws/Aws/HashInterface.php +27 -0
- lib/Aws/Aws/HashingStream.php +60 -0
- lib/Aws/Aws/History.php +156 -0
- lib/Aws/Aws/IdempotencyTokenMiddleware.php +118 -0
- lib/Aws/Aws/JsonCompiler.php +25 -0
- lib/Aws/Aws/LruArrayCache.php +79 -0
- lib/Aws/Aws/Middleware.php +372 -0
- lib/Aws/Aws/MockHandler.php +145 -0
- lib/Aws/Aws/MonitoringEventsInterface.php +32 -0
- lib/Aws/Aws/MultiRegionClient.php +236 -0
- lib/Aws/Aws/PhpHash.php +81 -0
- lib/Aws/Aws/PresignUrlMiddleware.php +99 -0
- lib/Aws/Aws/Psr16CacheAdapter.php +30 -0
- lib/Aws/Aws/PsrCacheAdapter.php +38 -0
- lib/Aws/Aws/ResponseContainerInterface.php +13 -0
- lib/Aws/Aws/Result.php +57 -0
- lib/Aws/Aws/ResultInterface.php +54 -0
- lib/Aws/Aws/ResultPaginator.php +169 -0
- lib/Aws/Aws/RetryMiddleware.php +315 -0
- lib/Aws/Aws/S3/AmbiguousSuccessParser.php +68 -0
- lib/Aws/Aws/S3/ApplyChecksumMiddleware.php +78 -0
- lib/Aws/Aws/S3/BatchDelete.php +237 -0
- lib/Aws/Aws/S3/BucketEndpointMiddleware.php +75 -0
- lib/Aws/Aws/S3/Crypto/CryptoParamsTrait.php +75 -0
- lib/Aws/Aws/S3/Crypto/HeadersMetadataStrategy.php +52 -0
- lib/Aws/Aws/S3/Crypto/InstructionFileMetadataStrategy.php +90 -0
- lib/Aws/Aws/S3/Crypto/S3EncryptionClient.php +317 -0
- lib/Aws/Aws/S3/Crypto/S3EncryptionMultipartUploader.php +157 -0
- lib/Aws/Aws/S3/Exception/DeleteMultipleObjectsException.php +68 -0
- lib/Aws/Aws/S3/Exception/PermanentRedirectException.php +4 -0
- lib/Aws/Aws/S3/Exception/S3Exception.php +9 -0
- lib/Aws/Aws/S3/Exception/S3MultipartUploadException.php +84 -0
- lib/Aws/Aws/S3/GetBucketLocationParser.php +49 -0
- lib/Aws/Aws/S3/MultipartCopy.php +183 -0
- lib/Aws/Aws/S3/MultipartUploader.php +168 -0
- lib/Aws/Aws/S3/MultipartUploadingTrait.php +132 -0
- lib/Aws/Aws/S3/ObjectCopier.php +150 -0
- lib/Aws/Aws/S3/ObjectUploader.php +140 -0
- lib/Aws/Aws/S3/PermanentRedirectMiddleware.php +62 -0
- lib/Aws/Aws/S3/PostObject.php +160 -0
- lib/Aws/Aws/S3/PostObjectV4.php +195 -0
- lib/Aws/Aws/S3/PutObjectUrlMiddleware.php +57 -0
- lib/Aws/Aws/S3/RetryableMalformedResponseParser.php +56 -0
- lib/Aws/Aws/S3/S3Client.php +633 -0
- lib/Aws/Aws/S3/S3ClientInterface.php +322 -0
- lib/Aws/Aws/S3/S3ClientTrait.php +323 -0
- lib/Aws/Aws/S3/S3EndpointMiddleware.php +234 -0
- lib/Aws/Aws/S3/S3MultiRegionClient.php +339 -0
- lib/Aws/Aws/S3/S3UriParser.php +133 -0
- lib/Aws/Aws/S3/SSECMiddleware.php +75 -0
- lib/Aws/Aws/S3/StreamWrapper.php +958 -0
- lib/Aws/Aws/S3/Transfer.php +428 -0
- lib/Aws/Aws/Sdk.php +466 -0
- lib/Aws/Aws/Signature/AnonymousSignature.php +26 -0
- lib/Aws/Aws/Signature/S3SignatureV4.php +68 -0
- lib/Aws/Aws/Signature/SignatureInterface.php +44 -0
- lib/Aws/Aws/Signature/SignatureProvider.php +131 -0
- lib/Aws/Aws/Signature/SignatureTrait.php +49 -0
- lib/Aws/Aws/Signature/SignatureV4.php +412 -0
- lib/Aws/Aws/Sns/Exception/InvalidSnsMessageException.php +9 -0
- lib/Aws/Aws/Sns/Exception/SnsException.php +9 -0
- lib/Aws/Aws/Sns/Message.php +156 -0
- lib/Aws/Aws/Sns/MessageValidator.php +190 -0
- lib/Aws/Aws/Sns/SnsClient.php +76 -0
- lib/Aws/Aws/TraceMiddleware.php +314 -0
- lib/Aws/Aws/Waiter.php +262 -0
- lib/Aws/Aws/WrappedHttpHandler.php +203 -0
- lib/Aws/Aws/data/cloudfront/2015-07-27/api-2.json.php +3 -0
- lib/Aws/Aws/data/cloudfront/2015-07-27/paginators-1.json.php +3 -0
- lib/Aws/Aws/data/cloudfront/2015-07-27/waiters-2.json.php +3 -0
- lib/Aws/Aws/data/cloudfront/2016-01-28/api-2.json.php +3 -0
- lib/Aws/Aws/data/cloudfront/2016-01-28/paginators-1.json.php +3 -0
- lib/Aws/Aws/data/cloudfront/2016-01-28/waiters-2.json.php +3 -0
- lib/Aws/Aws/data/cloudfront/2016-08-01/api-2.json.php +3 -0
CdnEngine.php
CHANGED
@@ -32,11 +32,11 @@ class CdnEngine {
|
|
32 |
break;
|
33 |
|
34 |
case 'cf':
|
35 |
-
$instances[$instance_key] = new
|
36 |
break;
|
37 |
|
38 |
case 'cf2':
|
39 |
-
$instances[$instance_key] = new
|
40 |
break;
|
41 |
|
42 |
case 'cotendo':
|
32 |
break;
|
33 |
|
34 |
case 'cf':
|
35 |
+
$instances[$instance_key] = new CdnEngine_CloudFront( $config );
|
36 |
break;
|
37 |
|
38 |
case 'cf2':
|
39 |
+
$instances[$instance_key] = new CdnEngine_Mirror_CloudFront( $config );
|
40 |
break;
|
41 |
|
42 |
case 'cotendo':
|
CdnEngine_Azure.php
CHANGED
@@ -336,27 +336,24 @@ class CdnEngine_Azure extends CdnEngine_Base {
|
|
336 |
/**
|
337 |
* Creates bucket
|
338 |
*
|
339 |
-
* @param string $container_id
|
340 |
* @param string $error
|
341 |
* @return boolean
|
342 |
*/
|
343 |
-
function create_container(
|
344 |
if ( !$this->_init( $error ) ) {
|
345 |
-
|
346 |
}
|
347 |
|
348 |
try {
|
349 |
$containers = $this->_client->listContainers();
|
350 |
} catch ( \Exception $exception ) {
|
351 |
$error = sprintf( 'Unable to list containers (%s).', $exception->getMessage() );
|
352 |
-
|
353 |
-
return false;
|
354 |
}
|
355 |
|
356 |
if ( in_array( $this->_config['container'], (array) $containers ) ) {
|
357 |
$error = sprintf( 'Container already exists: %s.', $this->_config['container'] );
|
358 |
-
|
359 |
-
return false;
|
360 |
}
|
361 |
|
362 |
try {
|
@@ -367,11 +364,8 @@ class CdnEngine_Azure extends CdnEngine_Base {
|
|
367 |
$this->_client->createContainer( $this->_config['container'], $createContainerOptions );
|
368 |
} catch ( \Exception $exception ) {
|
369 |
$error = sprintf( 'Unable to create container: %s (%s)', $this->_config['container'], $exception->getMessage() );
|
370 |
-
|
371 |
-
return false;
|
372 |
}
|
373 |
-
|
374 |
-
return true;
|
375 |
}
|
376 |
|
377 |
/**
|
336 |
/**
|
337 |
* Creates bucket
|
338 |
*
|
|
|
339 |
* @param string $error
|
340 |
* @return boolean
|
341 |
*/
|
342 |
+
function create_container() {
|
343 |
if ( !$this->_init( $error ) ) {
|
344 |
+
throw new \Exception( $error );
|
345 |
}
|
346 |
|
347 |
try {
|
348 |
$containers = $this->_client->listContainers();
|
349 |
} catch ( \Exception $exception ) {
|
350 |
$error = sprintf( 'Unable to list containers (%s).', $exception->getMessage() );
|
351 |
+
throw new \Exception( $error );
|
|
|
352 |
}
|
353 |
|
354 |
if ( in_array( $this->_config['container'], (array) $containers ) ) {
|
355 |
$error = sprintf( 'Container already exists: %s.', $this->_config['container'] );
|
356 |
+
throw new \Exception( $error );
|
|
|
357 |
}
|
358 |
|
359 |
try {
|
364 |
$this->_client->createContainer( $this->_config['container'], $createContainerOptions );
|
365 |
} catch ( \Exception $exception ) {
|
366 |
$error = sprintf( 'Unable to create container: %s (%s)', $this->_config['container'], $exception->getMessage() );
|
367 |
+
throw new \Exception( $error );
|
|
|
368 |
}
|
|
|
|
|
369 |
}
|
370 |
|
371 |
/**
|
CdnEngine_Base.php
CHANGED
@@ -126,15 +126,9 @@ class CdnEngine_Base {
|
|
126 |
|
127 |
/**
|
128 |
* Create bucket / container for some CDN engines
|
129 |
-
*
|
130 |
-
* @param string $container_id
|
131 |
-
* @param string $error
|
132 |
-
* @return boolean
|
133 |
*/
|
134 |
-
function create_container(
|
135 |
-
|
136 |
-
|
137 |
-
return false;
|
138 |
}
|
139 |
|
140 |
/**
|
126 |
|
127 |
/**
|
128 |
* Create bucket / container for some CDN engines
|
|
|
|
|
|
|
|
|
129 |
*/
|
130 |
+
function create_container() {
|
131 |
+
throw new \Exception( 'Not implemented.' );
|
|
|
|
|
132 |
}
|
133 |
|
134 |
/**
|
CdnEngine_CloudFront.php
ADDED
@@ -0,0 +1,345 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace W3TC;
|
3 |
+
|
4 |
+
if ( !defined( 'W3TC_SKIPLIB_AWS' ) ) {
|
5 |
+
require_once W3TC_LIB_DIR . '/Aws/aws-autoloader.php';
|
6 |
+
}
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Amazon CloudFront (S3 origin) CDN engine
|
10 |
+
*/
|
11 |
+
class CdnEngine_CloudFront extends CdnEngine_Base {
|
12 |
+
private $s3;
|
13 |
+
private $api;
|
14 |
+
|
15 |
+
function __construct( $config = array() ) {
|
16 |
+
$config = array_merge( array(
|
17 |
+
'id' => ''
|
18 |
+
), $config );
|
19 |
+
|
20 |
+
parent::__construct( $config );
|
21 |
+
|
22 |
+
$this->s3 = new CdnEngine_S3( $config );
|
23 |
+
}
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Initialize
|
27 |
+
*/
|
28 |
+
function _init() {
|
29 |
+
if ( !is_null( $this->api ) ) {
|
30 |
+
return;
|
31 |
+
}
|
32 |
+
|
33 |
+
$credentials = new \Aws\Credentials\Credentials(
|
34 |
+
$this->_config['key'],
|
35 |
+
$this->_config['secret'] );
|
36 |
+
|
37 |
+
$this->api = new \Aws\CloudFront\CloudFrontClient( array(
|
38 |
+
'credentials' => $credentials,
|
39 |
+
'region' => $this->_config['bucket_location'],
|
40 |
+
'version' => '2018-11-05'
|
41 |
+
)
|
42 |
+
);
|
43 |
+
|
44 |
+
return true;
|
45 |
+
}
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Formats URL
|
49 |
+
*/
|
50 |
+
function _format_url( $path ) {
|
51 |
+
// the same limitation as S3 has
|
52 |
+
return $this->s3->_format_url( $path );
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Upload files
|
57 |
+
*
|
58 |
+
* @param array $files
|
59 |
+
* @param array $results
|
60 |
+
* @param boolean $force_rewrite
|
61 |
+
* @return boolean
|
62 |
+
*/
|
63 |
+
function upload( $files, &$results, $force_rewrite = false,
|
64 |
+
$timeout_time = NULL ) {
|
65 |
+
return $this->s3->upload( $files, $results, $force_rewrite,
|
66 |
+
$timeout_time );
|
67 |
+
}
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Delete files from CDN
|
71 |
+
*
|
72 |
+
* @param array $files
|
73 |
+
* @param array $results
|
74 |
+
* @return boolean
|
75 |
+
*/
|
76 |
+
function delete( $files, &$results ) {
|
77 |
+
return $this->s3->delete( $files, $results );
|
78 |
+
}
|
79 |
+
|
80 |
+
/**
|
81 |
+
* Purge files from CDN
|
82 |
+
*
|
83 |
+
* @param array $files
|
84 |
+
* @param array $results
|
85 |
+
* @return boolean
|
86 |
+
*/
|
87 |
+
function purge( $files, &$results ) {
|
88 |
+
if ( !$this->s3->upload( $files, $results, true ) ) {
|
89 |
+
return false;
|
90 |
+
}
|
91 |
+
|
92 |
+
try {
|
93 |
+
$this->_init();
|
94 |
+
$dist = $this->_get_distribution();
|
95 |
+
} catch ( \Exception $ex ) {
|
96 |
+
$results = $this->_get_results( $files, W3TC_CDN_RESULT_HALT, $ex->getMessage() );
|
97 |
+
return false;
|
98 |
+
}
|
99 |
+
|
100 |
+
$paths = array();
|
101 |
+
|
102 |
+
foreach ( $files as $file ) {
|
103 |
+
$remote_file = $file['remote_path'];
|
104 |
+
$paths[] = '/' . $remote_file;
|
105 |
+
}
|
106 |
+
|
107 |
+
try {
|
108 |
+
$invalidation = $this->api->createInvalidation( array(
|
109 |
+
'DistributionId' => $dist['Id'],
|
110 |
+
'InvalidationBatch' => array(
|
111 |
+
'CallerReference' => 'w3tc-' . microtime(),
|
112 |
+
'Paths' => array(
|
113 |
+
'Items' => $paths,
|
114 |
+
'Quantity' => count( $paths ),
|
115 |
+
),
|
116 |
+
)
|
117 |
+
)
|
118 |
+
);
|
119 |
+
} catch ( \Exception $ex ) {
|
120 |
+
$results = $this->_get_results( $files, W3TC_CDN_RESULT_HALT,
|
121 |
+
sprintf( 'Unable to create invalidation batch (%s).',
|
122 |
+
$ex->getMessage() ) );
|
123 |
+
|
124 |
+
return false;
|
125 |
+
}
|
126 |
+
|
127 |
+
$results = $this->_get_results( $files, W3TC_CDN_RESULT_OK, 'OK' );
|
128 |
+
return true;
|
129 |
+
}
|
130 |
+
|
131 |
+
/**
|
132 |
+
* Returns origin
|
133 |
+
*/
|
134 |
+
function _get_origin() {
|
135 |
+
return sprintf( '%s.s3.amazonaws.com', $this->_config['bucket'] );
|
136 |
+
}
|
137 |
+
|
138 |
+
/**
|
139 |
+
* Returns array of CDN domains
|
140 |
+
*/
|
141 |
+
public function get_domains() {
|
142 |
+
if ( !empty( $this->_config['cname'] ) ) {
|
143 |
+
return (array) $this->_config['cname'];
|
144 |
+
} elseif ( !empty( $this->_config['id'] ) ) {
|
145 |
+
$domain = sprintf( '%s.cloudfront.net', $this->_config['id'] );
|
146 |
+
|
147 |
+
return array(
|
148 |
+
$domain
|
149 |
+
);
|
150 |
+
}
|
151 |
+
|
152 |
+
return array();
|
153 |
+
}
|
154 |
+
|
155 |
+
/**
|
156 |
+
* Test CDN connectivity
|
157 |
+
*/
|
158 |
+
function test( &$error ) {
|
159 |
+
$this->_init();
|
160 |
+
if ( !$this->s3->test( $error ) ) {
|
161 |
+
return false;
|
162 |
+
}
|
163 |
+
|
164 |
+
/**
|
165 |
+
* Search active CF distribution
|
166 |
+
*/
|
167 |
+
$dists = $this->api->listDistributions();
|
168 |
+
|
169 |
+
if ( !isset( $dists['DistributionList']['Items'] ) ) {
|
170 |
+
$error = 'Unable to list distributions.';
|
171 |
+
return false;
|
172 |
+
}
|
173 |
+
|
174 |
+
if ( !count( $dists['DistributionList']['Items'] ) ) {
|
175 |
+
$error = 'No distributions found.';
|
176 |
+
|
177 |
+
return false;
|
178 |
+
}
|
179 |
+
|
180 |
+
$dist = $this->_get_distribution( $dists );
|
181 |
+
if ( $dist["Status"] != 'Deployed' ) {
|
182 |
+
$error = sprintf( 'Distribution status is not Deployed, but "%s".', $dist["Status"] );
|
183 |
+
return false;
|
184 |
+
}
|
185 |
+
|
186 |
+
if ( !$dist['Enabled'] ) {
|
187 |
+
$error = sprintf( 'Distribution for origin "%s" is disabled.', $origin );
|
188 |
+
return false;
|
189 |
+
}
|
190 |
+
|
191 |
+
if ( !empty( $this->_config['cname'] ) ) {
|
192 |
+
$domains = (array) $this->_config['cname'];
|
193 |
+
$cnames = ( isset( $dist['Aliases']['Items'] ) ? (array) $dist['Aliases']['Items'] : array() );
|
194 |
+
|
195 |
+
foreach ( $domains as $domain ) {
|
196 |
+
$_domains = array_map( 'trim', explode( ',', $domain ) );
|
197 |
+
|
198 |
+
foreach ( $_domains as $_domain ) {
|
199 |
+
if ( !in_array( $_domain, $cnames ) ) {
|
200 |
+
$error = sprintf( 'Domain name %s is not in distribution <acronym title="Canonical Name">CNAME</acronym> list.', $_domain );
|
201 |
+
|
202 |
+
return false;
|
203 |
+
}
|
204 |
+
}
|
205 |
+
}
|
206 |
+
} elseif ( !empty( $this->_config['id'] ) ) {
|
207 |
+
$domain = $this->get_domain();
|
208 |
+
|
209 |
+
if ( $domain != $dist['DomainName'] ) {
|
210 |
+
$error = sprintf( 'Distribution domain name mismatch (%s != %s).', $domain, $dist['DomainName'] );
|
211 |
+
|
212 |
+
return false;
|
213 |
+
}
|
214 |
+
}
|
215 |
+
|
216 |
+
return true;
|
217 |
+
}
|
218 |
+
|
219 |
+
/**
|
220 |
+
* Create bucket
|
221 |
+
*/
|
222 |
+
function create_container() {
|
223 |
+
$this->_init();
|
224 |
+
$this->s3->create_container();
|
225 |
+
|
226 |
+
// plugin cant set CNAMEs list since it CloudFront requires
|
227 |
+
// certificate to be specified associated with it
|
228 |
+
$cnames = array();
|
229 |
+
|
230 |
+
// make distibution
|
231 |
+
$originDomain = $this->_get_origin();
|
232 |
+
|
233 |
+
try {
|
234 |
+
$result = $this->api->createDistribution(array(
|
235 |
+
'DistributionConfig' => array(
|
236 |
+
'CallerReference' => $originDomain,
|
237 |
+
'Comment' => 'Created by W3-Total-Cache',
|
238 |
+
'DefaultCacheBehavior' => array(
|
239 |
+
'AllowedMethods' => array(
|
240 |
+
'CachedMethods' => array(
|
241 |
+
'Items' => array( 'HEAD', 'GET' ),
|
242 |
+
'Quantity' => 2,
|
243 |
+
),
|
244 |
+
'Items' => array( 'HEAD', 'GET' ),
|
245 |
+
'Quantity' => 2,
|
246 |
+
),
|
247 |
+
'Compress' => true,
|
248 |
+
'DefaultTTL' => 86400,
|
249 |
+
'FieldLevelEncryptionId' => '',
|
250 |
+
'ForwardedValues' => array(
|
251 |
+
'Cookies' => array(
|
252 |
+
'Forward' => 'none',
|
253 |
+
),
|
254 |
+
'Headers' => array(
|
255 |
+
'Quantity' => 0,
|
256 |
+
),
|
257 |
+
'QueryString' => false,
|
258 |
+
'QueryStringCacheKeys' => array(
|
259 |
+
'Quantity' => 0,
|
260 |
+
),
|
261 |
+
),
|
262 |
+
'LambdaFunctionAssociations' => array( 'Quantity' => 0),
|
263 |
+
'MinTTL' => 0,
|
264 |
+
'SmoothStreaming' => false,
|
265 |
+
'TargetOriginId' => $originDomain,
|
266 |
+
'TrustedSigners' => array(
|
267 |
+
'Enabled' => false,
|
268 |
+
'Quantity' => 0,
|
269 |
+
),
|
270 |
+
'ViewerProtocolPolicy' => 'allow-all',
|
271 |
+
),
|
272 |
+
'Enabled' => true,
|
273 |
+
'Origins' => array(
|
274 |
+
'Items' => array(
|
275 |
+
array(
|
276 |
+
'DomainName' => $originDomain,
|
277 |
+
'Id' => $originDomain,
|
278 |
+
'OriginPath' => '',
|
279 |
+
'CustomHeaders' => array( 'Quantity' => 0 ),
|
280 |
+
'S3OriginConfig' => array(
|
281 |
+
'OriginAccessIdentity' => ''
|
282 |
+
),
|
283 |
+
),
|
284 |
+
),
|
285 |
+
'Quantity' => 1,
|
286 |
+
),
|
287 |
+
'Aliases' => array(
|
288 |
+
'Items' => $cnames,
|
289 |
+
'Quantity' => count( $cnames )
|
290 |
+
)
|
291 |
+
)
|
292 |
+
));
|
293 |
+
|
294 |
+
// extract domain dynamic part stored later in a config
|
295 |
+
$domain = $result['Distribution']['DomainName'];
|
296 |
+
$container_id = '';
|
297 |
+
if ( preg_match( '~^(.+)\.cloudfront\.net$~', $domain, $matches ) ) {
|
298 |
+
$container_id = $matches[1];
|
299 |
+
}
|
300 |
+
|
301 |
+
return $container_id;
|
302 |
+
|
303 |
+
} catch ( \Exception $ex ) {
|
304 |
+
throw new \Exception( sprintf(
|
305 |
+
'Unable to create distribution for origin %s: %s', $originDomain,
|
306 |
+
$ex->getMessage() ) );
|
307 |
+
}
|
308 |
+
}
|
309 |
+
|
310 |
+
/**
|
311 |
+
* Returns via string
|
312 |
+
*
|
313 |
+
* @return string
|
314 |
+
*/
|
315 |
+
function get_via() {
|
316 |
+
$domain = $this->get_domain();
|
317 |
+
$via = ( $domain ? $domain : 'N/A' );
|
318 |
+
|
319 |
+
return sprintf( 'Amazon Web Services: CloudFront: %s', $via );
|
320 |
+
}
|
321 |
+
|
322 |
+
private function _get_distribution( $dists = null ) {
|
323 |
+
if ( is_null( $dists ) ) {
|
324 |
+
$dists = $this->api->listDistributions();
|
325 |
+
}
|
326 |
+
|
327 |
+
if ( !isset( $dists['DistributionList']['Items'] ) ||
|
328 |
+
!count( $dists['DistributionList']['Items'] ) ) {
|
329 |
+
throw new \Exception( 'No distributions found.' );
|
330 |
+
}
|
331 |
+
|
332 |
+
$dist = false;
|
333 |
+
$origin = $this->_get_origin();
|
334 |
+
|
335 |
+
$items = $dists['DistributionList']['Items'];
|
336 |
+
foreach ( $items as $dist ) {
|
337 |
+
if ( isset( $dist['Origins']['Items'][0]['DomainName'] ) &&
|
338 |
+
$dist['Origins']['Items'][0]['DomainName'] == $origin ) {
|
339 |
+
return $dist;
|
340 |
+
}
|
341 |
+
}
|
342 |
+
|
343 |
+
throw new \Exception( sprintf( 'Distribution for origin "%s" not found.', $origin ) );
|
344 |
+
}
|
345 |
+
}
|
CdnEngine_Mirror_CloudFront.php
ADDED
@@ -0,0 +1,324 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace W3TC;
|
3 |
+
|
4 |
+
if ( !defined( 'W3TC_SKIPLIB_AWS' ) ) {
|
5 |
+
require_once W3TC_LIB_DIR . '/Aws/aws-autoloader.php';
|
6 |
+
}
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Amazon CloudFront (mirror) CDN engine
|
10 |
+
*/
|
11 |
+
class CdnEngine_Mirror_CloudFront extends CdnEngine_Mirror {
|
12 |
+
private $api;
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Constructor
|
16 |
+
*/
|
17 |
+
function __construct( $config = array() ) {
|
18 |
+
parent::__construct( $config );
|
19 |
+
}
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Initializes S3 object
|
23 |
+
*
|
24 |
+
* @param string $error
|
25 |
+
* @return bool
|
26 |
+
*/
|
27 |
+
function _init() {
|
28 |
+
if ( !is_null( $this->api ) ) {
|
29 |
+
return;
|
30 |
+
}
|
31 |
+
|
32 |
+
$credentials = new \Aws\Credentials\Credentials(
|
33 |
+
$this->_config['key'],
|
34 |
+
$this->_config['secret'] );
|
35 |
+
|
36 |
+
$this->api = new \Aws\CloudFront\CloudFrontClient( array(
|
37 |
+
'credentials' => $credentials,
|
38 |
+
'region' => 'us-east-1',
|
39 |
+
'version' => '2018-11-05'
|
40 |
+
)
|
41 |
+
);
|
42 |
+
|
43 |
+
return true;
|
44 |
+
}
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Returns origin
|
48 |
+
*
|
49 |
+
* @return string
|
50 |
+
*/
|
51 |
+
function _get_origin() {
|
52 |
+
return Util_Environment::host_port();
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Purge files from CDN
|
57 |
+
*
|
58 |
+
* @param array $files
|
59 |
+
* @param array $results
|
60 |
+
* @return boolean
|
61 |
+
*/
|
62 |
+
function purge( $files, &$results ) {
|
63 |
+
try {
|
64 |
+
$this->_init();
|
65 |
+
$dist = $this->_get_distribution();
|
66 |
+
} catch ( \Exception $ex ) {
|
67 |
+
$results = $this->_get_results( $files, W3TC_CDN_RESULT_HALT, $ex->getMessage() );
|
68 |
+
return false;
|
69 |
+
}
|
70 |
+
|
71 |
+
$paths = array();
|
72 |
+
|
73 |
+
foreach ( $files as $file ) {
|
74 |
+
$remote_file = $file['remote_path'];
|
75 |
+
$paths[] = '/' . $remote_file;
|
76 |
+
}
|
77 |
+
|
78 |
+
try {
|
79 |
+
$invalidation = $this->api->createInvalidation( array(
|
80 |
+
'DistributionId' => $dist['Id'],
|
81 |
+
'InvalidationBatch' => array(
|
82 |
+
'CallerReference' => 'w3tc-' . microtime(),
|
83 |
+
'Paths' => array(
|
84 |
+
'Items' => $paths,
|
85 |
+
'Quantity' => count( $paths ),
|
86 |
+
),
|
87 |
+
)
|
88 |
+
)
|
89 |
+
);
|
90 |
+
} catch ( \Exception $ex ) {
|
91 |
+
$results = $this->_get_results( $files, W3TC_CDN_RESULT_HALT,
|
92 |
+
sprintf( 'Unable to create invalidation batch (%s).',
|
93 |
+
$ex->getMessage() ) );
|
94 |
+
|
95 |
+
return false;
|
96 |
+
}
|
97 |
+
|
98 |
+
$results = $this->_get_results( $files, W3TC_CDN_RESULT_OK, 'OK' );
|
99 |
+
return true;
|
100 |
+
}
|
101 |
+
|
102 |
+
/**
|
103 |
+
* Purge CDN completely
|
104 |
+
*
|
105 |
+
* @param unknown $results
|
106 |
+
* @return bool
|
107 |
+
*/
|
108 |
+
function purge_all( &$results ) {
|
109 |
+
return $this->purge( array( 'remote_path' => '*' ), $results );
|
110 |
+
}
|
111 |
+
|
112 |
+
/**
|
113 |
+
* Returns array of CDN domains
|
114 |
+
*
|
115 |
+
* @return array
|
116 |
+
*/
|
117 |
+
function get_domains() {
|
118 |
+
if ( !empty( $this->_config['cname'] ) ) {
|
119 |
+
return (array) $this->_config['cname'];
|
120 |
+
} elseif ( !empty( $this->_config['id'] ) ) {
|
121 |
+
$domain = sprintf( '%s.cloudfront.net', $this->_config['id'] );
|
122 |
+
|
123 |
+
return array(
|
124 |
+
$domain
|
125 |
+
);
|
126 |
+
}
|
127 |
+
|
128 |
+
return array();
|
129 |
+
}
|
130 |
+
|
131 |
+
/**
|
132 |
+
* Tests CF
|
133 |
+
*
|
134 |
+
* @param string $error
|
135 |
+
* @return boolean
|
136 |
+
*/
|
137 |
+
function test( &$error ) {
|
138 |
+
$this->_init();
|
139 |
+
|
140 |
+
/**
|
141 |
+
* Search active CF distribution
|
142 |
+
*/
|
143 |
+
$dists = $this->api->listDistributions();
|
144 |
+
|
145 |
+
if ( !isset( $dists['DistributionList']['Items'] ) ) {
|
146 |
+
$error = 'Unable to list distributions.';
|
147 |
+
return false;
|
148 |
+
}
|
149 |
+
|
150 |
+
if ( !count( $dists['DistributionList']['Items'] ) ) {
|
151 |
+
$error = 'No distributions found.';
|
152 |
+
|
153 |
+
return false;
|
154 |
+
}
|
155 |
+
|
156 |
+
$dist = $this->_get_distribution( $dists );
|
157 |
+
if ( $dist["Status"] != 'Deployed' ) {
|
158 |
+
$error = sprintf( 'Distribution status is not Deployed, but "%s".', $dist["Status"] );
|
159 |
+
return false;
|
160 |
+
}
|
161 |
+
|
162 |
+
if ( !$dist['Enabled'] ) {
|
163 |
+
$error = sprintf( 'Distribution for origin "%s" is disabled.', $origin );
|
164 |
+
return false;
|
165 |
+
}
|
166 |
+
|
167 |
+
if ( !empty( $this->_config['cname'] ) ) {
|
168 |
+
$domains = (array) $this->_config['cname'];
|
169 |
+
$cnames = ( isset( $dist['Aliases']['Items'] ) ? (array) $dist['Aliases']['Items'] : array() );
|
170 |
+
|
171 |
+
foreach ( $domains as $domain ) {
|
172 |
+
$_domains = array_map( 'trim', explode( ',', $domain ) );
|
173 |
+
|
174 |
+
foreach ( $_domains as $_domain ) {
|
175 |
+
if ( !in_array( $_domain, $cnames ) ) {
|
176 |
+
$error = sprintf( 'Domain name %s is not in distribution <acronym title="Canonical Name">CNAME</acronym> list.', $_domain );
|
177 |
+
|
178 |
+
return false;
|
179 |
+
}
|
180 |
+
}
|
181 |
+
}
|
182 |
+
} elseif ( !empty( $this->_config['id'] ) ) {
|
183 |
+
$domain = $this->get_domain();
|
184 |
+
|
185 |
+
if ( $domain != $dist['DomainName'] ) {
|
186 |
+
$error = sprintf( 'Distribution domain name mismatch (%s != %s).', $domain, $dist['DomainName'] );
|
187 |
+
|
188 |
+
return false;
|
189 |
+
}
|
190 |
+
}
|
191 |
+
|
192 |
+
return true;
|
193 |
+
}
|
194 |
+
|
195 |
+
/**
|
196 |
+
* Create distribution
|
197 |
+
*/
|
198 |
+
function create_container() {
|
199 |
+
$this->_init();
|
200 |
+
|
201 |
+
// plugin cant set CNAMEs list since it CloudFront requires
|
202 |
+
// certificate to be specified associated with it
|
203 |
+
$cnames = array();
|
204 |
+
|
205 |
+
// make distibution
|
206 |
+
$originDomain = $this->_get_origin();
|
207 |
+
|
208 |
+
try {
|
209 |
+
$result = $this->api->createDistribution( array(
|
210 |
+
'DistributionConfig' => array(
|
211 |
+
'CallerReference' => $originDomain,
|
212 |
+
'Comment' => 'Created by W3-Total-Cache',
|
213 |
+
'DefaultCacheBehavior' => array(
|
214 |
+
'AllowedMethods' => array(
|
215 |
+
'CachedMethods' => array(
|
216 |
+
'Items' => array( 'HEAD', 'GET' ),
|
217 |
+
'Quantity' => 2,
|
218 |
+
),
|
219 |
+
'Items' => array( 'HEAD', 'GET' ),
|
220 |
+
'Quantity' => 2,
|
221 |
+
),
|
222 |
+
'Compress' => true,
|
223 |
+
'DefaultTTL' => 86400,
|
224 |
+
'FieldLevelEncryptionId' => '',
|
225 |
+
'ForwardedValues' => array(
|
226 |
+
'Cookies' => array(
|
227 |
+
'Forward' => 'none',
|
228 |
+
),
|
229 |
+
'Headers' => array(
|
230 |
+
'Quantity' => 0,
|
231 |
+
),
|
232 |
+
'QueryString' => false,
|
233 |
+
'QueryStringCacheKeys' => array(
|
234 |
+
'Quantity' => 0,
|
235 |
+
),
|
236 |
+
),
|
237 |
+
'LambdaFunctionAssociations' => array( 'Quantity' => 0),
|
238 |
+
'MinTTL' => 0,
|
239 |
+
'SmoothStreaming' => false,
|
240 |
+
'TargetOriginId' => $originDomain,
|
241 |
+
'TrustedSigners' => array(
|
242 |
+
'Enabled' => false,
|
243 |
+
'Quantity' => 0,
|
244 |
+
),
|
245 |
+
'ViewerProtocolPolicy' => 'allow-all',
|
246 |
+
),
|
247 |
+
'Enabled' => true,
|
248 |
+
'Origins' => array(
|
249 |
+
'Items' => array(
|
250 |
+
array(
|
251 |
+
'DomainName' => $originDomain,
|
252 |
+
'Id' => $originDomain,
|
253 |
+
'OriginPath' => '',
|
254 |
+
'CustomHeaders' => array( 'Quantity' => 0 ),
|
255 |
+
'CustomOriginConfig' => array(
|
256 |
+
'HTTPPort' => 80,
|
257 |
+
'HTTPSPort' => 443,
|
258 |
+
'OriginProtocolPolicy' => 'match-viewer'
|
259 |
+
),
|
260 |
+
),
|
261 |
+
),
|
262 |
+
'Quantity' => 1,
|
263 |
+
),
|
264 |
+
'Aliases' => array(
|
265 |
+
'Items' => $cnames,
|
266 |
+
'Quantity' => count( $cnames )
|
267 |
+
)
|
268 |
+
)
|
269 |
+
));
|
270 |
+
|
271 |
+
// extract domain dynamic part stored later in a config
|
272 |
+
$domain = $result['Distribution']['DomainName'];
|
273 |
+
$container_id = '';
|
274 |
+
if ( preg_match( '~^(.+)\.cloudfront\.net$~', $domain, $matches ) ) {
|
275 |
+
$container_id = $matches[1];
|
276 |
+
}
|
277 |
+
|
278 |
+
return $container_id;
|
279 |
+
|
280 |
+
} catch ( \Aws\Exception\AwsException $ex ) {
|
281 |
+
throw new \Exception( sprintf(
|
282 |
+
'Unable to create distribution for origin %s: %s', $originDomain,
|
283 |
+
$ex->getAwsErrorMessage() ) );
|
284 |
+
} catch ( \Exception $ex ) {
|
285 |
+
throw new \Exception( sprintf(
|
286 |
+
'Unable to create distribution for origin %s: %s', $originDomain,
|
287 |
+
$ex->getMessage() ) );
|
288 |
+
}
|
289 |
+
}
|
290 |
+
|
291 |
+
/**
|
292 |
+
* Returns via string
|
293 |
+
*/
|
294 |
+
function get_via() {
|
295 |
+
$domain = $this->get_domain();
|
296 |
+
$via = ( $domain ? $domain : 'N/A' );
|
297 |
+
|
298 |
+
return sprintf( 'Amazon Web Services: CloudFront: %s', $via );
|
299 |
+
}
|
300 |
+
|
301 |
+
private function _get_distribution( $dists = null ) {
|
302 |
+
if ( is_null( $dists ) ) {
|
303 |
+
$dists = $this->api->listDistributions();
|
304 |
+
}
|
305 |
+
|
306 |
+
if ( !isset( $dists['DistributionList']['Items'] ) ||
|
307 |
+
!count( $dists['DistributionList']['Items'] ) ) {
|
308 |
+
throw new \Exception( 'No distributions found.' );
|
309 |
+
}
|
310 |
+
|
311 |
+
$dist = false;
|
312 |
+
$origin = $this->_get_origin();
|
313 |
+
|
314 |
+
$items = $dists['DistributionList']['Items'];
|
315 |
+
foreach ( $items as $dist ) {
|
316 |
+
if ( isset( $dist['Origins']['Items'][0]['DomainName'] ) &&
|
317 |
+
$dist['Origins']['Items'][0]['DomainName'] == $origin ) {
|
318 |
+
return $dist;
|
319 |
+
}
|
320 |
+
}
|
321 |
+
|
322 |
+
throw new \Exception( sprintf( 'Distribution for origin "%s" not found.', $origin ) );
|
323 |
+
}
|
324 |
+
}
|
CdnEngine_S3.php
CHANGED
@@ -1,31 +1,17 @@
|
|
1 |
<?php
|
2 |
namespace W3TC;
|
3 |
|
4 |
-
|
5 |
-
|
6 |
-
*/
|
7 |
-
|
8 |
-
if ( !class_exists( 'S3' ) ) {
|
9 |
-
require_once W3TC_LIB_DIR . '/S3.php';
|
10 |
}
|
11 |
|
12 |
/**
|
13 |
-
*
|
14 |
*/
|
15 |
class CdnEngine_S3 extends CdnEngine_Base {
|
16 |
-
|
17 |
-
* S3 object
|
18 |
-
*
|
19 |
-
* @var S3
|
20 |
-
*/
|
21 |
-
var $_s3 = null;
|
22 |
|
23 |
-
|
24 |
-
* PHP5 Constructor
|
25 |
-
*
|
26 |
-
* @param array $config
|
27 |
-
*/
|
28 |
-
function __construct( $config = array() ) {
|
29 |
$config = array_merge( array(
|
30 |
'key' => '',
|
31 |
'secret' => '',
|
@@ -39,9 +25,6 @@ class CdnEngine_S3 extends CdnEngine_Base {
|
|
39 |
|
40 |
/**
|
41 |
* Formats URL
|
42 |
-
*
|
43 |
-
* @param string $path
|
44 |
-
* @return string
|
45 |
*/
|
46 |
function _format_url( $path ) {
|
47 |
$domain = $this->get_domain( $path );
|
@@ -65,40 +48,33 @@ class CdnEngine_S3 extends CdnEngine_Base {
|
|
65 |
* @param string $error
|
66 |
* @return boolean
|
67 |
*/
|
68 |
-
function _init(
|
69 |
-
if (
|
70 |
-
|
|
|
71 |
|
72 |
-
|
|
|
73 |
}
|
74 |
|
75 |
if ( empty( $this->_config['secret'] ) ) {
|
76 |
-
|
77 |
-
|
78 |
-
return false;
|
79 |
}
|
80 |
|
81 |
if ( empty( $this->_config['bucket'] ) ) {
|
82 |
-
|
83 |
-
|
84 |
-
return false;
|
85 |
}
|
86 |
|
87 |
-
|
88 |
-
$
|
89 |
-
$
|
90 |
-
} else {
|
91 |
-
$region = $this->_config['bucket_location'];
|
92 |
-
$endpoint = 's3.dualstack.' . $region . '.amazonaws.com';
|
93 |
-
}
|
94 |
|
95 |
-
$this->
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
return true;
|
102 |
}
|
103 |
|
104 |
/**
|
@@ -109,13 +85,14 @@ class CdnEngine_S3 extends CdnEngine_Base {
|
|
109 |
* @param boolean $force_rewrite
|
110 |
* @return boolean
|
111 |
*/
|
112 |
-
function upload( $files, &$results, $force_rewrite = false,
|
113 |
$timeout_time = NULL ) {
|
114 |
$error = null;
|
115 |
|
116 |
-
|
117 |
-
$
|
118 |
-
|
|
|
119 |
return false;
|
120 |
}
|
121 |
|
@@ -148,7 +125,7 @@ class CdnEngine_S3 extends CdnEngine_Base {
|
|
148 |
* @param boolean $force_rewrite
|
149 |
* @return array
|
150 |
*/
|
151 |
-
function _upload( $file, $force_rewrite = false ) {
|
152 |
$local_path = $file['local_path'];
|
153 |
$remote_path = $file['remote_path'];
|
154 |
|
@@ -157,52 +134,51 @@ class CdnEngine_S3 extends CdnEngine_Base {
|
|
157 |
W3TC_CDN_RESULT_ERROR, 'Source file not found.', $file );
|
158 |
}
|
159 |
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
172 |
}
|
173 |
}
|
174 |
-
}
|
175 |
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
|
|
|
|
181 |
|
182 |
-
if ( $result ) {
|
183 |
return $this->_get_result( $local_path, $remote_path,
|
184 |
W3TC_CDN_RESULT_OK, 'OK', $file );
|
185 |
-
}
|
|
|
186 |
|
187 |
-
|
188 |
-
|
189 |
-
} else {
|
190 |
-
$error = sprintf( 'Unable to put object (%s).', $this->_get_last_error() );
|
191 |
}
|
192 |
-
|
193 |
-
return $this->_get_result( $local_path, $remote_path,
|
194 |
-
W3TC_CDN_RESULT_ERROR, $error, $file );
|
195 |
}
|
196 |
|
197 |
/**
|
198 |
* Uploads gzip version of file
|
199 |
-
*
|
200 |
-
* @param string $local_path
|
201 |
-
* @param string $remote_path
|
202 |
-
* @param boolean $force_rewrite
|
203 |
-
* @return array
|
204 |
*/
|
205 |
-
function _upload_gzip( $file, $force_rewrite = false ) {
|
206 |
$local_path = $file['local_path'];
|
207 |
$remote_path = $file['remote_path_gzip'];
|
208 |
|
@@ -225,45 +201,70 @@ class CdnEngine_S3 extends CdnEngine_Base {
|
|
225 |
|
226 |
$data = gzencode( $contents );
|
227 |
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
240 |
}
|
241 |
}
|
242 |
-
}
|
243 |
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
|
|
|
|
|
|
253 |
|
254 |
-
if ( $result ) {
|
255 |
return $this->_get_result( $local_path, $remote_path,
|
256 |
W3TC_CDN_RESULT_OK, 'OK', $file );
|
|
|
|
|
|
|
|
|
|
|
257 |
}
|
|
|
258 |
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
263 |
}
|
264 |
|
265 |
-
return $this->
|
266 |
-
W3TC_CDN_RESULT_ERROR, $error, $file );
|
267 |
}
|
268 |
|
269 |
/**
|
@@ -273,12 +274,13 @@ class CdnEngine_S3 extends CdnEngine_Base {
|
|
273 |
* @param array $results
|
274 |
* @return boolean
|
275 |
*/
|
276 |
-
function delete( $files, &$results ) {
|
277 |
$error = null;
|
278 |
|
279 |
-
|
280 |
-
$
|
281 |
-
|
|
|
282 |
return false;
|
283 |
}
|
284 |
|
@@ -286,36 +288,36 @@ class CdnEngine_S3 extends CdnEngine_Base {
|
|
286 |
$local_path = $file['local_path'];
|
287 |
$remote_path = $file['remote_path'];
|
288 |
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
$results[] = $this->_get_result( $local_path, $remote_path,
|
295 |
W3TC_CDN_RESULT_OK, 'OK', $file );
|
296 |
-
}
|
297 |
$results[] = $this->_get_result( $local_path, $remote_path,
|
298 |
W3TC_CDN_RESULT_ERROR,
|
299 |
sprintf( 'Unable to delete object (%s).',
|
300 |
-
$
|
301 |
$file );
|
302 |
}
|
303 |
|
304 |
if ( $this->_config['compression'] ) {
|
305 |
$remote_path_gzip = $remote_path . $this->_gzip_extension;
|
306 |
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
$results[] = $this->_get_result( $local_path,
|
313 |
-
|
314 |
-
}
|
315 |
-
$results[] = $this->_get_result( $local_path,
|
316 |
-
|
317 |
sprintf( 'Unable to delete object (%s).',
|
318 |
-
$
|
319 |
$file );
|
320 |
}
|
321 |
}
|
@@ -325,80 +327,57 @@ class CdnEngine_S3 extends CdnEngine_Base {
|
|
325 |
}
|
326 |
|
327 |
/**
|
328 |
-
*
|
329 |
-
*
|
330 |
-
* @param string $error
|
331 |
-
* @return boolean
|
332 |
*/
|
333 |
-
function test( &$error ) {
|
334 |
if ( !parent::test( $error ) ) {
|
335 |
return false;
|
336 |
}
|
337 |
|
338 |
-
$
|
339 |
-
|
340 |
-
if ( !$this->_init( $error ) ) {
|
341 |
-
return false;
|
342 |
-
}
|
343 |
-
|
344 |
-
$this->_set_error_handler();
|
345 |
-
|
346 |
-
$buckets = @$this->_s3->listBuckets();
|
347 |
-
|
348 |
-
if ( $buckets === false ) {
|
349 |
-
$error = sprintf( 'Unable to list buckets (%s).', $this->_get_last_error() );
|
350 |
-
|
351 |
-
$this->_restore_error_handler();
|
352 |
-
|
353 |
-
return false;
|
354 |
-
}
|
355 |
-
|
356 |
-
if ( !in_array( $this->_config['bucket'], (array) $buckets ) ) {
|
357 |
-
$error = sprintf( 'Bucket doesn\'t exist: %s.', $this->_config['bucket'] );
|
358 |
|
359 |
-
|
|
|
360 |
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
if ( strpos( $this->_get_last_error(), 'AWS4-HMAC-SHA256' ) !== false ) {
|
366 |
-
$error = "Bucket location region is incorrect. Please select the right one.";
|
367 |
-
} else {
|
368 |
-
$error = sprintf( 'Unable to put object (%s).', $this->_get_last_error() );
|
369 |
}
|
370 |
-
|
371 |
-
$this->_restore_error_handler();
|
372 |
-
|
373 |
-
return false;
|
374 |
}
|
375 |
|
376 |
-
if (
|
377 |
-
|
378 |
-
|
379 |
-
$this->_restore_error_handler();
|
380 |
-
|
381 |
-
return false;
|
382 |
}
|
383 |
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
|
|
|
|
389 |
|
390 |
-
|
391 |
-
|
|
|
|
|
392 |
|
393 |
-
if (
|
394 |
-
$error =
|
395 |
|
396 |
-
$this->
|
|
|
|
|
|
|
397 |
|
398 |
return false;
|
399 |
}
|
400 |
|
401 |
-
$this->
|
|
|
|
|
|
|
402 |
|
403 |
return true;
|
404 |
}
|
@@ -408,7 +387,7 @@ class CdnEngine_S3 extends CdnEngine_Base {
|
|
408 |
*
|
409 |
* @return array
|
410 |
*/
|
411 |
-
function get_domains() {
|
412 |
if ( !empty( $this->_config['cname'] ) ) {
|
413 |
return (array) $this->_config['cname'];
|
414 |
} elseif ( !empty( $this->_config['bucket'] ) ) {
|
@@ -427,61 +406,35 @@ class CdnEngine_S3 extends CdnEngine_Base {
|
|
427 |
*
|
428 |
* @return string
|
429 |
*/
|
430 |
-
function get_via() {
|
431 |
return sprintf( 'Amazon Web Services: S3: %s', parent::get_via() );
|
432 |
}
|
433 |
|
434 |
/**
|
435 |
* Creates bucket
|
436 |
-
*
|
437 |
-
* @param string $container_id
|
438 |
-
* @param string $error
|
439 |
-
* @return boolean
|
440 |
*/
|
441 |
-
function create_container(
|
442 |
-
|
443 |
-
return false;
|
444 |
-
}
|
445 |
-
|
446 |
-
$this->_set_error_handler();
|
447 |
-
|
448 |
-
$buckets = @$this->_s3->listBuckets();
|
449 |
-
|
450 |
-
if ( $buckets === false ) {
|
451 |
-
$error = sprintf( 'Unable to list buckets (%s).', $this->_get_last_error() );
|
452 |
-
|
453 |
-
$this->_restore_error_handler();
|
454 |
-
|
455 |
-
return false;
|
456 |
-
}
|
457 |
|
458 |
-
|
459 |
-
$
|
460 |
-
|
461 |
-
$
|
462 |
-
|
463 |
-
return false;
|
464 |
}
|
465 |
|
466 |
-
|
467 |
-
$this->_config['
|
468 |
-
|
469 |
-
|
470 |
-
if ( !isset( $this->_config['bucket_location'] ) ) {
|
471 |
-
$this->_config['bucket_location'] = \S3::LOCATION_US;
|
472 |
}
|
473 |
|
474 |
-
|
475 |
-
$
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
}
|
481 |
-
|
482 |
-
$this->_restore_error_handler();
|
483 |
-
|
484 |
-
return true;
|
485 |
}
|
486 |
|
487 |
/**
|
@@ -489,7 +442,7 @@ class CdnEngine_S3 extends CdnEngine_Base {
|
|
489 |
*
|
490 |
* @return string W3TC_CDN_HEADER_NONE, W3TC_CDN_HEADER_UPLOADABLE, W3TC_CDN_HEADER_MIRRORING
|
491 |
*/
|
492 |
-
function headers_support() {
|
493 |
return W3TC_CDN_HEADER_UPLOADABLE;
|
494 |
}
|
495 |
}
|
1 |
<?php
|
2 |
namespace W3TC;
|
3 |
|
4 |
+
if ( !defined( 'W3TC_SKIPLIB_AWS' ) ) {
|
5 |
+
require_once W3TC_LIB_DIR . '/Aws/aws-autoloader.php';
|
|
|
|
|
|
|
|
|
6 |
}
|
7 |
|
8 |
/**
|
9 |
+
* CDN engine for S3 push type
|
10 |
*/
|
11 |
class CdnEngine_S3 extends CdnEngine_Base {
|
12 |
+
private $api;
|
|
|
|
|
|
|
|
|
|
|
13 |
|
14 |
+
public function __construct( $config = array() ) {
|
|
|
|
|
|
|
|
|
|
|
15 |
$config = array_merge( array(
|
16 |
'key' => '',
|
17 |
'secret' => '',
|
25 |
|
26 |
/**
|
27 |
* Formats URL
|
|
|
|
|
|
|
28 |
*/
|
29 |
function _format_url( $path ) {
|
30 |
$domain = $this->get_domain( $path );
|
48 |
* @param string $error
|
49 |
* @return boolean
|
50 |
*/
|
51 |
+
public function _init() {
|
52 |
+
if ( !is_null( $this->api ) ) {
|
53 |
+
return;
|
54 |
+
}
|
55 |
|
56 |
+
if ( empty( $this->_config['key'] ) ) {
|
57 |
+
throw new \Exception( 'Empty access key.' );
|
58 |
}
|
59 |
|
60 |
if ( empty( $this->_config['secret'] ) ) {
|
61 |
+
throw new \Exception( 'Empty secret key.' );
|
|
|
|
|
62 |
}
|
63 |
|
64 |
if ( empty( $this->_config['bucket'] ) ) {
|
65 |
+
throw new \Exception( 'Empty bucket.' );
|
|
|
|
|
66 |
}
|
67 |
|
68 |
+
$credentials = new \Aws\Credentials\Credentials(
|
69 |
+
$this->_config['key'],
|
70 |
+
$this->_config['secret'] );
|
|
|
|
|
|
|
|
|
71 |
|
72 |
+
$this->api = new \Aws\S3\S3Client( array(
|
73 |
+
'credentials' => $credentials,
|
74 |
+
'region' => $this->_config['bucket_location'],
|
75 |
+
'version' => '2006-03-01'
|
76 |
+
)
|
77 |
+
);
|
|
|
78 |
}
|
79 |
|
80 |
/**
|
85 |
* @param boolean $force_rewrite
|
86 |
* @return boolean
|
87 |
*/
|
88 |
+
public function upload( $files, &$results, $force_rewrite = false,
|
89 |
$timeout_time = NULL ) {
|
90 |
$error = null;
|
91 |
|
92 |
+
try {
|
93 |
+
$this->_init();
|
94 |
+
} catch ( \Exception $ex ) {
|
95 |
+
$results = $this->_get_results( $files, W3TC_CDN_RESULT_HALT, $ex->getMessage() );
|
96 |
return false;
|
97 |
}
|
98 |
|
125 |
* @param boolean $force_rewrite
|
126 |
* @return array
|
127 |
*/
|
128 |
+
private function _upload( $file, $force_rewrite = false ) {
|
129 |
$local_path = $file['local_path'];
|
130 |
$remote_path = $file['remote_path'];
|
131 |
|
134 |
W3TC_CDN_RESULT_ERROR, 'Source file not found.', $file );
|
135 |
}
|
136 |
|
137 |
+
try {
|
138 |
+
if ( !$force_rewrite ) {
|
139 |
+
try {
|
140 |
+
$info = $this->api->headObject( array(
|
141 |
+
'Bucket' => $this->_config['bucket'],
|
142 |
+
'Key' => $remote_path )
|
143 |
+
);
|
144 |
+
|
145 |
+
$hash = '"' . @md5_file( $local_path ) . '"';
|
146 |
+
$s3_hash = ( isset( $info['ETag'] ) ? $info['ETag'] : '' );
|
147 |
+
|
148 |
+
if ( $hash === $s3_hash ) {
|
149 |
+
return $this->_get_result( $local_path, $remote_path,
|
150 |
+
W3TC_CDN_RESULT_OK, 'Object up-to-date.', $file );
|
151 |
+
}
|
152 |
+
} catch ( \Aws\Exception\AwsException $ex ) {
|
153 |
+
if ( $ex->getAwsErrorCode() == 'NotFound' ) {
|
154 |
+
} else {
|
155 |
+
throw $ex;
|
156 |
+
}
|
157 |
}
|
158 |
}
|
|
|
159 |
|
160 |
+
$headers = $this->_get_headers( $file );
|
161 |
+
$result = $this->_put_object( array(
|
162 |
+
'Key' => $remote_path,
|
163 |
+
'SourceFile' => $local_path,
|
164 |
+
'Metadata' => $headers
|
165 |
+
)
|
166 |
+
);
|
167 |
|
|
|
168 |
return $this->_get_result( $local_path, $remote_path,
|
169 |
W3TC_CDN_RESULT_OK, 'OK', $file );
|
170 |
+
} catch ( \Exception $ex ) {
|
171 |
+
$error = sprintf( 'Unable to put object (%s).', $ex->getMessage() );
|
172 |
|
173 |
+
return $this->_get_result( $local_path, $remote_path,
|
174 |
+
W3TC_CDN_RESULT_ERROR, $error, $file );
|
|
|
|
|
175 |
}
|
|
|
|
|
|
|
176 |
}
|
177 |
|
178 |
/**
|
179 |
* Uploads gzip version of file
|
|
|
|
|
|
|
|
|
|
|
180 |
*/
|
181 |
+
private function _upload_gzip( $file, $force_rewrite = false ) {
|
182 |
$local_path = $file['local_path'];
|
183 |
$remote_path = $file['remote_path_gzip'];
|
184 |
|
201 |
|
202 |
$data = gzencode( $contents );
|
203 |
|
204 |
+
try {
|
205 |
+
if ( !$force_rewrite ) {
|
206 |
+
try {
|
207 |
+
$info = $this->api->headObject( array(
|
208 |
+
'Bucket' => $this->_config['bucket'],
|
209 |
+
'Key' => $remote_path )
|
210 |
+
);
|
211 |
+
|
212 |
+
$hash = '"' . md5( $data ) . '"';
|
213 |
+
$s3_hash = ( isset( $info['ETag'] ) ? $info['ETag'] : '' );
|
214 |
+
|
215 |
+
if ( $hash === $s3_hash ) {
|
216 |
+
return $this->_get_result( $local_path, $remote_path,
|
217 |
+
W3TC_CDN_RESULT_OK, 'Object up-to-date.', $file );
|
218 |
+
}
|
219 |
+
} catch ( \Aws\Exception\AwsException $ex ) {
|
220 |
+
if ( $ex->getAwsErrorCode() == 'NotFound' ) {
|
221 |
+
} else {
|
222 |
+
throw $ex;
|
223 |
+
}
|
224 |
}
|
225 |
}
|
|
|
226 |
|
227 |
+
$headers = $this->_get_headers( $file );
|
228 |
+
$headers = array_merge( $headers, array(
|
229 |
+
'Vary' => 'Accept-Encoding',
|
230 |
+
'Content-Encoding' => 'gzip'
|
231 |
+
) );
|
232 |
+
|
233 |
+
$result = $this->_put_object( array(
|
234 |
+
'Key' => $remote_path,
|
235 |
+
'Body' => $data,
|
236 |
+
'Metadata' => $headers
|
237 |
+
)
|
238 |
+
);
|
239 |
|
|
|
240 |
return $this->_get_result( $local_path, $remote_path,
|
241 |
W3TC_CDN_RESULT_OK, 'OK', $file );
|
242 |
+
} catch ( \Exception $ex ) {
|
243 |
+
$error = sprintf( 'Unable to put object (%s).', $ex->getMessage() );
|
244 |
+
|
245 |
+
return $this->_get_result( $local_path, $remote_path,
|
246 |
+
W3TC_CDN_RESULT_ERROR, $error, $file );
|
247 |
}
|
248 |
+
}
|
249 |
|
250 |
+
/**
|
251 |
+
* Wrapper to set headers well
|
252 |
+
*/
|
253 |
+
private function _put_object( $data ) {
|
254 |
+
$data['ACL'] = 'public-read';
|
255 |
+
$data['Bucket'] = $this->_config['bucket'];
|
256 |
+
|
257 |
+
if ( isset( $data['Metadata']['Content-Type'] ) ) {
|
258 |
+
$data['ContentType'] = $data['Metadata']['Content-Type'];
|
259 |
+
}
|
260 |
+
if ( isset( $data['Metadata']['Content-Encoding'] ) ) {
|
261 |
+
$data['ContentEncoding'] = $data['Metadata']['Content-Encoding'];
|
262 |
+
}
|
263 |
+
if ( isset( $data['Metadata']['Cache-Control'] ) ) {
|
264 |
+
$data['CacheControl'] = $data['Metadata']['Cache-Control'];
|
265 |
}
|
266 |
|
267 |
+
return $this->api->putObject( $data );
|
|
|
268 |
}
|
269 |
|
270 |
/**
|
274 |
* @param array $results
|
275 |
* @return boolean
|
276 |
*/
|
277 |
+
public function delete( $files, &$results ) {
|
278 |
$error = null;
|
279 |
|
280 |
+
try {
|
281 |
+
$this->_init();
|
282 |
+
} catch ( \Exception $ex ) {
|
283 |
+
$results = $this->_get_results( $files, W3TC_CDN_RESULT_HALT, $ex->getMessage() );
|
284 |
return false;
|
285 |
}
|
286 |
|
288 |
$local_path = $file['local_path'];
|
289 |
$remote_path = $file['remote_path'];
|
290 |
|
291 |
+
try {
|
292 |
+
$this->api->deleteObject( array(
|
293 |
+
'Bucket' => $this->_config['bucket'],
|
294 |
+
'Key' => $remote_path
|
295 |
+
) );
|
296 |
$results[] = $this->_get_result( $local_path, $remote_path,
|
297 |
W3TC_CDN_RESULT_OK, 'OK', $file );
|
298 |
+
} catch ( \Exception $ex ) {
|
299 |
$results[] = $this->_get_result( $local_path, $remote_path,
|
300 |
W3TC_CDN_RESULT_ERROR,
|
301 |
sprintf( 'Unable to delete object (%s).',
|
302 |
+
$ex->getMessage() ),
|
303 |
$file );
|
304 |
}
|
305 |
|
306 |
if ( $this->_config['compression'] ) {
|
307 |
$remote_path_gzip = $remote_path . $this->_gzip_extension;
|
308 |
|
309 |
+
try {
|
310 |
+
$this->api->deleteObject( array(
|
311 |
+
'Bucket' => $this->_config['bucket'],
|
312 |
+
'Key' => $remote_path_gzip
|
313 |
+
) );
|
314 |
+
$results[] = $this->_get_result( $local_path, $remote_path_gzip,
|
315 |
+
W3TC_CDN_RESULT_OK, 'OK', $file );
|
316 |
+
} catch ( \Exception $ex ) {
|
317 |
+
$results[] = $this->_get_result( $local_path, $remote_path_gzip,
|
318 |
+
W3TC_CDN_RESULT_ERROR,
|
319 |
sprintf( 'Unable to delete object (%s).',
|
320 |
+
$ex->getMessage() ),
|
321 |
$file );
|
322 |
}
|
323 |
}
|
327 |
}
|
328 |
|
329 |
/**
|
330 |
+
* Test CDN connectivity works
|
|
|
|
|
|
|
331 |
*/
|
332 |
+
public function test( &$error ) {
|
333 |
if ( !parent::test( $error ) ) {
|
334 |
return false;
|
335 |
}
|
336 |
|
337 |
+
$key = 'test_s3_' . md5( time() );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
338 |
|
339 |
+
$this->_init();
|
340 |
+
$buckets = $this->api->listBuckets();
|
341 |
|
342 |
+
$bucket_found = false;
|
343 |
+
foreach ( $buckets['Buckets'] as $bucket ) {
|
344 |
+
if ( $bucket['Name'] == $this->_config['bucket'] ) {
|
345 |
+
$bucket_found = true;
|
|
|
|
|
|
|
|
|
346 |
}
|
|
|
|
|
|
|
|
|
347 |
}
|
348 |
|
349 |
+
if ( !$bucket_found ) {
|
350 |
+
throw new \Exception( 'Bucket doesn\'t exist: %s.', $this->_config['bucket'] );
|
|
|
|
|
|
|
|
|
351 |
}
|
352 |
|
353 |
+
$result = $this->api->putObject( array(
|
354 |
+
'ACL' => 'public-read',
|
355 |
+
'Bucket' => $this->_config['bucket'],
|
356 |
+
'Key' => $key,
|
357 |
+
'Body' => $key
|
358 |
+
)
|
359 |
+
);
|
360 |
|
361 |
+
$object = $this->api->getObject( array(
|
362 |
+
'Bucket' => $this->_config['bucket'],
|
363 |
+
'Key' => $key
|
364 |
+
) );
|
365 |
|
366 |
+
if ( $object['Body'] != $key ) {
|
367 |
+
$error = 'Objects are not equal.';
|
368 |
|
369 |
+
$this->api->deleteObject( array(
|
370 |
+
'Bucket' => $this->_config['bucket'],
|
371 |
+
'Key' => $key
|
372 |
+
) );
|
373 |
|
374 |
return false;
|
375 |
}
|
376 |
|
377 |
+
$this->api->deleteObject( array(
|
378 |
+
'Bucket' => $this->_config['bucket'],
|
379 |
+
'Key' => $key
|
380 |
+
) );
|
381 |
|
382 |
return true;
|
383 |
}
|
387 |
*
|
388 |
* @return array
|
389 |
*/
|
390 |
+
public function get_domains() {
|
391 |
if ( !empty( $this->_config['cname'] ) ) {
|
392 |
return (array) $this->_config['cname'];
|
393 |
} elseif ( !empty( $this->_config['bucket'] ) ) {
|
406 |
*
|
407 |
* @return string
|
408 |
*/
|
409 |
+
public function get_via() {
|
410 |
return sprintf( 'Amazon Web Services: S3: %s', parent::get_via() );
|
411 |
}
|
412 |
|
413 |
/**
|
414 |
* Creates bucket
|
|
|
|
|
|
|
|
|
415 |
*/
|
416 |
+
public function create_container() {
|
417 |
+
$this->_init();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
418 |
|
419 |
+
try {
|
420 |
+
$buckets = $this->api->listBuckets();
|
421 |
+
} catch ( \Exception $ex ) {
|
422 |
+
throw new \Exception( 'Unable to list buckets: ' . $ex->getMessage() );
|
|
|
|
|
423 |
}
|
424 |
|
425 |
+
foreach ( $buckets['Buckets'] as $bucket ) {
|
426 |
+
if ( $bucket['Name'] == $this->_config['bucket'] ) {
|
427 |
+
throw new \Exception( 'Bucket already exists: ' . $this->_config['bucket'] );
|
428 |
+
}
|
|
|
|
|
429 |
}
|
430 |
|
431 |
+
try {
|
432 |
+
$result = $this->api->createBucket( array(
|
433 |
+
'Bucket' => $this->_config['bucket'],
|
434 |
+
) );
|
435 |
+
} catch ( \Exception $e) {
|
436 |
+
throw new \Exception( 'Failed to create bucket: ' . $ex->getMessage() );
|
437 |
}
|
|
|
|
|
|
|
|
|
438 |
}
|
439 |
|
440 |
/**
|
442 |
*
|
443 |
* @return string W3TC_CDN_HEADER_NONE, W3TC_CDN_HEADER_UPLOADABLE, W3TC_CDN_HEADER_MIRRORING
|
444 |
*/
|
445 |
+
public function headers_support() {
|
446 |
return W3TC_CDN_HEADER_UPLOADABLE;
|
447 |
}
|
448 |
}
|
CdnEngine_S3_Cf.php
DELETED
@@ -1,453 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace W3TC;
|
3 |
-
|
4 |
-
/**
|
5 |
-
* Amazon CloudFront CDN engine
|
6 |
-
*/
|
7 |
-
|
8 |
-
define( 'W3TC_CDN_CF_TYPE_S3', 's3' );
|
9 |
-
define( 'W3TC_CDN_CF_TYPE_CUSTOM', 'custom' );
|
10 |
-
|
11 |
-
/**
|
12 |
-
* class CdnEngine_S3_Cf
|
13 |
-
*/
|
14 |
-
class CdnEngine_S3_Cf extends CdnEngine_S3 {
|
15 |
-
/**
|
16 |
-
* Type
|
17 |
-
*
|
18 |
-
* @var string
|
19 |
-
*/
|
20 |
-
var $type = '';
|
21 |
-
|
22 |
-
/**
|
23 |
-
* PHP5 Constructor
|
24 |
-
*
|
25 |
-
* @param array $config
|
26 |
-
*/
|
27 |
-
function __construct( $config = array() ) {
|
28 |
-
$config = array_merge( array(
|
29 |
-
'id' => ''
|
30 |
-
), $config );
|
31 |
-
|
32 |
-
parent::__construct( $config );
|
33 |
-
}
|
34 |
-
|
35 |
-
/**
|
36 |
-
* Initializes S3 object
|
37 |
-
*
|
38 |
-
* @param string $error
|
39 |
-
* @return bool
|
40 |
-
*/
|
41 |
-
function _init( &$error ) {
|
42 |
-
if ( empty( $this->type ) ) {
|
43 |
-
$error = 'Empty type.';
|
44 |
-
|
45 |
-
return false;
|
46 |
-
} elseif ( !in_array( $this->type, array( W3TC_CDN_CF_TYPE_S3, W3TC_CDN_CF_TYPE_CUSTOM ) ) ) {
|
47 |
-
$error = 'Invalid type.';
|
48 |
-
|
49 |
-
return false;
|
50 |
-
}
|
51 |
-
|
52 |
-
if ( empty( $this->_config['key'] ) ) {
|
53 |
-
$error = 'Empty access key.';
|
54 |
-
|
55 |
-
return false;
|
56 |
-
}
|
57 |
-
|
58 |
-
if ( empty( $this->_config['secret'] ) ) {
|
59 |
-
$error = 'Empty secret key.';
|
60 |
-
|
61 |
-
return false;
|
62 |
-
}
|
63 |
-
|
64 |
-
if ( $this->type == W3TC_CDN_CF_TYPE_S3 && empty( $this->_config['bucket'] ) ) {
|
65 |
-
$error = 'Empty bucket.';
|
66 |
-
|
67 |
-
return false;
|
68 |
-
}
|
69 |
-
|
70 |
-
if ( empty( $this->_config['bucket_location'] ) ) {
|
71 |
-
$region = '';
|
72 |
-
$endpoint = 's3.amazonaws.com';
|
73 |
-
} else {
|
74 |
-
$region = $this->_config['bucket_location'];
|
75 |
-
$endpoint = 's3.dualstack.'.$region.'.amazonaws.com';
|
76 |
-
}
|
77 |
-
|
78 |
-
$this->_s3 = new \S3( $this->_config['key'], $this->_config['secret'],
|
79 |
-
false, $endpoint, $region );
|
80 |
-
|
81 |
-
if ( empty( $region ) ) {
|
82 |
-
$this->_s3->setSignatureVersion( 'v2' );
|
83 |
-
}
|
84 |
-
|
85 |
-
return true;
|
86 |
-
}
|
87 |
-
|
88 |
-
/**
|
89 |
-
* Returns origin
|
90 |
-
*
|
91 |
-
* @return string
|
92 |
-
*/
|
93 |
-
function _get_origin() {
|
94 |
-
if ( $this->type == W3TC_CDN_CF_TYPE_S3 ) {
|
95 |
-
$origin = sprintf( '%s.s3.amazonaws.com', $this->_config['bucket'] );
|
96 |
-
} else {
|
97 |