From 5676f4513e6ca665aab105c3c69034eab68e99e7 Mon Sep 17 00:00:00 2001 From: Aaron Edwards Date: Tue, 24 Oct 2023 22:23:00 -0500 Subject: [PATCH] Fix aws config error in safe mode Speed up head object --- inc/class-infinite-uploads-stream-wrapper.php | 2 +- inc/class-infinite-uploads-wp-mail.php | 496 ++++++++++++++++++ inc/class-infinite-uploads.php | 2 + infinite-uploads.php | 6 +- 4 files changed, 503 insertions(+), 3 deletions(-) create mode 100644 inc/class-infinite-uploads-wp-mail.php diff --git a/inc/class-infinite-uploads-stream-wrapper.php b/inc/class-infinite-uploads-stream-wrapper.php index 4c614c6..5d88750 100644 --- a/inc/class-infinite-uploads-stream-wrapper.php +++ b/inc/class-infinite-uploads-stream-wrapper.php @@ -930,7 +930,7 @@ private function createSubfolder( $path, array $params ) { //Cache the stat for this file so we don't have to do another HeadObject in the same request $cache_key = "iu://{$params['Bucket']}/{$params['Key']}"; if ( $bool ) { - $this->getCacheStorage()->set( $cache_key, $this->formatUrlStat( [ 'ContentLength' => $params['Body']->getSize(), 'LastModified' => time() ] ) ); + $this->getCacheStorage()->set( $cache_key, $this->formatUrlStat( [ 'ContentLength' => 0, 'LastModified' => time() ] ) ); $this->debug_cache( 'SET', $cache_key ); //purposely don't cache this 0-length fake file } diff --git a/inc/class-infinite-uploads-wp-mail.php b/inc/class-infinite-uploads-wp-mail.php new file mode 100644 index 0000000..f01b0fa --- /dev/null +++ b/inc/class-infinite-uploads-wp-mail.php @@ -0,0 +1,496 @@ + 0 ) { + $from_name = substr( $content, 0, $bracket_pos ); + $from_name = str_replace( '"', '', $from_name ); + $from_name = trim( $from_name ); + } + + $from_email = substr( $content, $bracket_pos + 1 ); + $from_email = str_replace( '>', '', $from_email ); + $from_email = trim( $from_email ); + + // Avoid setting an empty $from_email. + } elseif ( '' !== trim( $content ) ) { + $from_email = trim( $content ); + } + break; + case 'content-type': + if ( strpos( $content, ';' ) !== false ) { + list( $type, $charset_content ) = explode( ';', $content ); + $content_type = trim( $type ); + if ( false !== stripos( $charset_content, 'charset=' ) ) { + $charset = trim( str_replace( array( 'charset=', '"' ), '', $charset_content ) ); + } elseif ( false !== stripos( $charset_content, 'boundary=' ) ) { + $boundary = trim( str_replace( array( 'BOUNDARY=', 'boundary=', '"' ), '', $charset_content ) ); + $charset = ''; + } + + // Avoid setting an empty $content_type. + } elseif ( '' !== trim( $content ) ) { + $content_type = trim( $content ); + } + break; + case 'cc': + $cc = array_merge( (array) $cc, explode( ',', $content ) ); + break; + case 'bcc': + $bcc = array_merge( (array) $bcc, explode( ',', $content ) ); + break; + case 'reply-to': + $reply_to = array_merge( (array) $reply_to, explode( ',', $content ) ); + break; + default: + // Add it to our grand headers array. + $headers[ trim( $name ) ] = trim( $content ); + break; + } + } + } + } + + // Empty out the values that may be set. + $phpmailer->clearAllRecipients(); + $phpmailer->clearAttachments(); + $phpmailer->clearCustomHeaders(); + $phpmailer->clearReplyTos(); + $phpmailer->Body = ''; + $phpmailer->AltBody = ''; + + // Set "From" name and email. + + // If we don't have a name from the input headers. + if ( ! isset( $from_name ) ) { + $from_name = 'WordPress'; + } + + /* + * If we don't have an email from the input headers, default to wordpress@$sitename + * Some hosts will block outgoing mail from this address if it doesn't exist, + * but there's no easy alternative. Defaulting to admin_email might appear to be + * another option, but some hosts may refuse to relay mail from an unknown domain. + * See https://core.trac.wordpress.org/ticket/5007. + */ + if ( ! isset( $from_email ) ) { + // Get the site domain and get rid of www. + $sitename = wp_parse_url( network_home_url(), PHP_URL_HOST ); + $from_email = 'wordpress@'; + + if ( null !== $sitename ) { + if ( 'www.' === substr( $sitename, 0, 4 ) ) { + $sitename = substr( $sitename, 4 ); + } + + $from_email .= $sitename; + } + } + + /** + * Filters the email address to send from. + * + * @param string $from_email Email address to send from. + * + * @since 2.2.0 + * + */ + $from_email = apply_filters( 'wp_mail_from', $from_email ); + + /** + * Filters the name to associate with the "from" email address. + * + * @param string $from_name Name associated with the "from" email address. + * + * @since 2.3.0 + * + */ + $from_name = apply_filters( 'wp_mail_from_name', $from_name ); + + try { + $phpmailer->setFrom( $from_email, $from_name, false ); + } catch ( PHPMailer\PHPMailer\Exception $e ) { + $mail_error_data = compact( 'to', 'subject', 'message', 'headers', 'attachments' ); + $mail_error_data['phpmailer_exception_code'] = $e->getCode(); + + /** This filter is documented in wp-includes/pluggable.php */ + do_action( 'wp_mail_failed', new WP_Error( 'wp_mail_failed', $e->getMessage(), $mail_error_data ) ); + + return false; + } + + // Set mail's subject and body. + $phpmailer->Subject = $subject; + $phpmailer->Body = $message; + + // Set destination addresses, using appropriate methods for handling addresses. + $address_headers = compact( 'to', 'cc', 'bcc', 'reply_to' ); + + foreach ( $address_headers as $address_header => $addresses ) { + if ( empty( $addresses ) ) { + continue; + } + + foreach ( (array) $addresses as $address ) { + try { + // Break $recipient into name and address parts if in the format "Foo ". + $recipient_name = ''; + + if ( preg_match( '/(.*)<(.+)>/', $address, $matches ) ) { + if ( count( $matches ) == 3 ) { + $recipient_name = $matches[1]; + $address = $matches[2]; + } + } + + switch ( $address_header ) { + case 'to': + $phpmailer->addAddress( $address, $recipient_name ); + break; + case 'cc': + $phpmailer->addCc( $address, $recipient_name ); + break; + case 'bcc': + $phpmailer->addBcc( $address, $recipient_name ); + break; + case 'reply_to': + $phpmailer->addReplyTo( $address, $recipient_name ); + break; + } + } catch ( PHPMailer\PHPMailer\Exception $e ) { + continue; + } + } + } + + // Set to use PHP's mail(). + $phpmailer->isMail(); + + // Set Content-Type and charset. + + // If we don't have a content-type from the input headers. + if ( ! isset( $content_type ) ) { + $content_type = 'text/plain'; + } + + /** + * Filters the wp_mail() content type. + * + * @param string $content_type Default wp_mail() content type. + * + * @since 2.3.0 + * + */ + $content_type = apply_filters( 'wp_mail_content_type', $content_type ); + + $phpmailer->ContentType = $content_type; + + // Set whether it's plaintext, depending on $content_type. + if ( 'text/html' === $content_type ) { + $phpmailer->isHTML( true ); + } + + // If we don't have a charset from the input headers. + if ( ! isset( $charset ) ) { + $charset = get_bloginfo( 'charset' ); + } + + /** + * Filters the default wp_mail() charset. + * + * @param string $charset Default email charset. + * + * @since 2.3.0 + * + */ + $phpmailer->CharSet = apply_filters( 'wp_mail_charset', $charset ); + + // Set custom headers. + if ( ! empty( $headers ) ) { + foreach ( (array) $headers as $name => $content ) { + // Only add custom headers not added automatically by PHPMailer. + if ( ! in_array( $name, array( 'MIME-Version', 'X-Mailer' ), true ) ) { + try { + $phpmailer->addCustomHeader( sprintf( '%1$s: %2$s', $name, $content ) ); + } catch ( PHPMailer\PHPMailer\Exception $e ) { + continue; + } + } + } + + if ( false !== stripos( $content_type, 'multipart' ) && ! empty( $boundary ) ) { + $phpmailer->addCustomHeader( sprintf( 'Content-Type: %s; boundary="%s"', $content_type, $boundary ) ); + } + } + + if ( ! empty( $attachments ) ) { + foreach ( $attachments as $attachment ) { + try { + $phpmailer->addAttachment( $attachment ); + } catch ( PHPMailer\PHPMailer\Exception $e ) { + continue; + } + } + } + + /** + * Fires after PHPMailer is initialized. + * + * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference). + * + * @since 2.2.0 + * + */ + do_action_ref_array( 'phpmailer_init', array( &$phpmailer ) ); + + $mail_data = compact( 'to', 'subject', 'message', 'headers', 'attachments' ); + + // Send! + try { + $send = $phpmailer->send(); + + /** + * Fires after PHPMailer has successfully sent an email. + * + * The firing of this action does not necessarily mean that the recipient(s) received the + * email successfully. It only means that the `send` method above was able to + * process the request without any errors. + * + * @param array $mail_data { + * An array containing the email recipient(s), subject, message, headers, and attachments. + * + * @type string[] $to Email addresses to send message. + * @type string $subject Email subject. + * @type string $message Message contents. + * @type string[] $headers Additional headers. + * @type string[] $attachments Paths to files to attach. + * } + * @since 5.9.0 + * + */ + do_action( 'wp_mail_succeeded', $mail_data ); + + return $send; + } catch ( PHPMailer\PHPMailer\Exception $e ) { + $mail_data['phpmailer_exception_code'] = $e->getCode(); + + /** + * Fires after a PHPMailer\PHPMailer\Exception is caught. + * + * @param WP_Error $error A WP_Error object with the PHPMailer\PHPMailer\Exception message, and an array + * containing the mail recipient, subject, message, headers, and attachments. + * + * @since 4.4.0 + * + */ + do_action( 'wp_mail_failed', new WP_Error( 'wp_mail_failed', $e->getMessage(), $mail_data ) ); + + return false; + } + } +endif; + +require_once ABSPATH . WPINC . '/PHPMailer/PHPMailer.php'; + +/** + * PHPMailer - PHP email creation and transport class. + * + * @author Marcus Bointon (Synchro/coolbru) + * @author Jim Jagielski (jimjag) + * @author Andy Prevost (codeworxtech) + * @author Brent R. Matzelle (original founder) + */ +class Infinite_Uploads_PHPMailer extends PHPMailer\PHPMailer\PHPMailer { + /** + * Check whether a file path is of a permitted type. + * Used to reject URLs and phar files from functions that access local file paths, + * such as addAttachment. + * + * @param string $path A relative or absolute path to a file + * + * @return bool + */ + protected static function isPermittedPath( $path ) { + + return true; + + //Matches scheme definition from https://tools.ietf.org/html/rfc3986#section-3.1 + return ! preg_match( '#^[a-z][a-z\d+.-]*://#i', $path ); + } + + /** + * Check whether a file path is safe, accessible, and readable. + * + * @param string $path A relative or absolute path to a file + * + * @return bool + */ + protected static function fileIsAccessible( $path ) { + + if ( ! static::isPermittedPath( $path ) ) { + return false; + } + $readable = is_file( $path ); + //If not a UNC path (expected to start with \\), check read permission, see #2069 + if ( strpos( $path, '\\\\' ) !== 0 ) { + $readable = $readable && is_readable( $path ); + } + + return $readable; + } +} diff --git a/inc/class-infinite-uploads.php b/inc/class-infinite-uploads.php index 3a0b012..b33c743 100644 --- a/inc/class-infinite-uploads.php +++ b/inc/class-infinite-uploads.php @@ -108,6 +108,7 @@ public function setup() { add_filter( 'infinite_uploads_s3_client_params', function ( $params ) use ( $api_data ) { $params['endpoint'] = $api_data->site->upload_endpoint; $params['use_path_style_endpoint'] = true; + $params['use_aws_shared_config_files'] = false; //$params['debug'] = [ // 'logfn' => 'error_log', // 'stream_size' => 0, @@ -174,6 +175,7 @@ public function setup() { $this->plugin_compatibility(); + if ( ( ! defined( 'INFINITE_UPLOADS_DISABLE_REPLACE_UPLOAD_URL' ) || ! INFINITE_UPLOADS_DISABLE_REPLACE_UPLOAD_URL ) && $api_data->site->cdn_enabled ) { //makes this work with pre 3.5 MU ms_files rewriting (ie domain.com/files/filename.jpg) $original_root_dirs = $this->get_original_upload_dir_root(); diff --git a/infinite-uploads.php b/infinite-uploads.php index efe5f6c..8f54dea 100644 --- a/infinite-uploads.php +++ b/infinite-uploads.php @@ -2,7 +2,7 @@ /* * Plugin Name: Infinite Uploads * Description: Infinitely scalable cloud storage and delivery for your videos and uploads made easy! Upload directly to cloud storage and manage your files right from the WordPress Media Library. - * Version: 2.0 + * Version: 2.0.1 * Author: Infinite Uploads * Author URI: https://infiniteuploads.com/?utm_source=iup_plugin&utm_medium=plugin&utm_campaign=iup_plugin&utm_content=meta * Text Domain: infinite-uploads @@ -17,12 +17,14 @@ * Copyright 2021 UglyRobot, LLC */ -define( 'INFINITE_UPLOADS_VERSION', '2.0' ); +define( 'INFINITE_UPLOADS_VERSION', '2.0.1' ); if ( defined( 'WP_CLI' ) && WP_CLI ) { require_once dirname( __FILE__ ) . '/inc/class-infinite-uploads-wp-cli-command.php'; } +//require_once 'inc/class-infinite-uploads-wp-mail.php'; + register_activation_hook( __FILE__, 'infinite_uploads_install' ); add_action( 'plugins_loaded', 'infinite_uploads_init' );