laipower/wp-content/plugins/static-html-output-plugin/plugin/deployers/S3.php

8 lines
7.9 KiB
PHP
Raw Normal View History

2020-04-07 13:03:04 +00:00
<?php
class WP2Static_S3 extends WP2Static_SitePublisher { public function __construct() { $this->loadSettings( 's3' ); $this->previous_hashes_path = $this->settings['wp_uploads_path'] . '/WP2STATIC-S3-PREVIOUS-HASHES.txt'; if ( defined( 'WP_CLI' ) ) { return; } switch ( $_POST['ajax_action'] ) { case 'test_s3': $this->test_s3(); break; case 's3_prepare_export': $this->bootstrap(); $this->loadArchive(); $this->prepareDeploy(); break; case 's3_transfer_files': $this->bootstrap(); $this->loadArchive(); $this->upload_files(); break; case 'cloudfront_invalidate_all_items': $this->cloudfront_invalidate_all_items(); break; } } public function upload_files() { $this->files_remaining = $this->getRemainingItemsCount(); if ( $this->files_remaining < 0 ) { echo 'ERROR'; die(); } $this->initiateProgressIndicator(); $batch_size = $this->settings['deployBatchSize']; if ( $batch_size > $this->files_remaining ) { $batch_size = $this->files_remaining; } $lines = $this->getItemsToDeploy( $batch_size ); $this->openPreviousHashesFile(); require_once dirname( __FILE__ ) . '/../WP2Static/MimeTypes.php'; foreach ( $lines as $line ) { list($local_file, $this->target_path) = explode( ',', $line ); $local_file = $this->archive->path . $local_file; if ( ! is_file( $local_file ) ) { continue; } if ( isset( $this->settings['s3RemotePath'] ) ) { $this->target_path = $this->settings['s3RemotePath'] . '/' . $this->target_path; } $this->logAction( "Uploading {$local_file} to {$this->target_path} in S3" ); $this->local_file_contents = file_get_contents( $local_file ); $this->hash_key = $this->target_path . basename( $local_file ); if ( isset( $this->file_paths_and_hashes[ $this->hash_key ] ) ) { $prev = $this->file_paths_and_hashes[ $this->hash_key ]; $current = crc32( $this->local_file_contents ); if ( $prev != $current ) { try { $this->put_s3_object( $this->target_path . basename( $local_file ), $this->local_file_contents, GuessMimeType( $local_file ) ); } catch ( Exception $e ) { $this->handleException( $e ); } } else { $this->logAction( "Skipping {$this->hash_key} as identical " . 'to deploy cache' ); } } else { try { $this->put_s3_object( $this->target_path . basename( $local_file ), $this->local_file_contents, GuessMimeType( $local_file ) ); } catch ( Exception $e ) { $this->handleException( $e ); } } $this->recordFilePathAndHashInMemory( $this->hash_key, $this->local_file_contents ); $this->updateProgress(); } $this->writeFilePathAndHashesToFile(); $this->pauseBetweenAPICalls(); if ( $this->uploadsCompleted() ) { $this->finalizeDeployment(); } } public function test_s3() { try { $this->put_s3_object( '.tmp_wp2static.txt', 'Test WP2Static connectivity', 'text/plain' ); if ( ! defined( 'WP_CLI' ) ) { echo 'SUCCESS'; } } catch ( Exception $e ) { require_once dirname( __FILE__ ) . '/../WP2Static/WsLog.php'; WsLog::l( 'S3 ERROR RETURNED: ' . $e ); echo "There was an error testing S3.\n"; } } public function put_s3_object( $s3_path, $content, $content_type ) { $s3_path = str_replace( '@', '%40', $s3_path ); $this->logAction( "PUT'ing file to {$s3_path} in S3" ); $host_name = $this->settings['s3Bucket'] . '.s3.' . $this->settings['s3Region'] . '.amazonaws.com'; $this->logAction( "Using S3 Endpoint {$host_name}" ); $content_acl = 'public-read'; $content_title = $s3_path; $aws_service_name = 's3'; $timestamp = gmdate( 'Ymd\THis\Z' ); $date = gmdate( 'Ymd' ); $request_headers = array(); $request_headers['Content-Type'] = $content_type; $request_headers['Date'] = $timestamp; $request_headers['Host'] = $host_name; $request_headers['x-amz-acl'] = $content_acl; $request_headers['x-amz-content-sha256'] = hash( 'sha256', $content ); ksort( $request_headers ); $canonical_headers = array(); foreach ( $request_headers as $key => $value ) { $canonical_headers[] = strtolower( $key ) . ':' . $value; } $canonical_headers = implode( "\n", $canonical_headers ); $signed_headers = array(); foreach ( $request_headers as $key => $value ) { $signed_headers[] = strtolower( $key ); } $signed_headers = implode( ';', $signed_headers ); $canonical_request = array(); $canonical_request[
<InvalidationBatch>
<Path>/*</Path>
<CallerReference>{$distribution}{$epoch}</CallerReference>
</InvalidationBatch>
EOD;
$len = strlen( $xml ); $date = gmdate( 'D, d M Y G:i:s T' ); $sig = base64_encode( hash_hmac( 'sha1', $date, $secret_key, true ) ); $msg = 'POST /2010-11-01/distribution/'; $msg .= "{$distribution}/invalidation HTTP/1.0\r\n"; $msg .= "Host: cloudfront.amazonaws.com\r\n"; $msg .= "Date: {$date}\r\n"; $msg .= "Content-Type: text/xml; charset=UTF-8\r\n"; $msg .= "Authorization: AWS {$access_key}:{$sig}\r\n"; $msg .= "Content-Length: {$len}\r\n\r\n"; $msg .= $xml; $fp = fsockopen( 'ssl://cloudfront.amazonaws.com', 443, $errno, $errstr, 30 ); if ( ! $fp ) { require_once dirname( __FILE__ ) . '/../WP2Static/WsLog.php'; WsLog::l( "CLOUDFRONT CONNECTION ERROR: {$errno} {$errstr}" ); die( "Connection failed: {$errno} {$errstr}\n" ); } fwrite( $fp, $msg ); $resp = ''; while ( ! feof( $fp ) ) { $resp .= fgets( $fp, 1024 ); } $this->logAction( "CloudFront response body: {$resp}" ); fclose( $fp ); if ( ! defined( 'WP_CLI' ) ) { echo 'SUCCESS'; } } } $s3 = new WP2Static_S3();