public/wordpress/wp-content/plugins/backupbuddy/classes/remote_api.php
/* remoteCall()
	 *
	 * Send an API call to a remote server.
	 * @param	array 	$remoteAPI		Remote API state array including URL, etc. Stored in destination settings.
	 * @param	string	$verb			API verb to call on remote server.
	 * @param	array 	$moreParams		Optional: Additional parameters to append to those sent.  If needing to send a non-string this should be encoded in some manner and decoded on remote.
	 * @param	int		$timeout		Optional: How long we expect this can last before a server times out.  Typically the minimum of the local and remote timeouts.
	 * @param	string	$file			Optional: File we are sending. This is passed so that various CRC data can be calculated.
	 * @param	string	$fileData		Optional: Raw file contents to send (for this chunk if using chunking).
	 * @param	int		$seekTo			Optional: Location to fseek to in the file for writing.
	 * @param	bool	$isFileTest		Optional: When true the destination will auto-delete the file after testing.
	 * @param	bool	$isFileDone		Optional: Pass true when the last chunk (or only chunk) of the file is being sent so destination knows not to expect any other pieces.
	 * @param	int		$fileSize		Optional: Size of the file sending.
	 * @param	string	$filePath		Optional: Remote file path in relation to the root location where the file is being stored, based on file type (based on verb).
	 * @param	bool	$returnRaw		When true returns body raw text/data rather than decoding encoded data first.
	 *
	 */
remoteCall()
Send an API call to a remote server.
@param       array   $remoteAPI              Remote API state array including URL, etc. Stored in destination settings.
@param       string  $verb                   API verb to call on remote server.
@param       array   $moreParams             Optional: Additional parameters to append to those sent.  If needing to send a non-string this should be encoded in some manner and decoded on remote.
@param       int             $timeout                Optional: How long we expect this can last before a server times out.  Typically the minimum of the local and remote timeouts.
@param       string  $file                   Optional: File we are sending. This is passed so that various CRC data can be calculated.
@param       string  $fileData               Optional: Raw file contents to send (for this chunk if using chunking).
@param       int             $seekTo                 Optional: Location to fseek to in the file for writing.
@param       bool    $isFileTest             Optional: When true the destination will auto-delete the file after testing.
@param       bool    $isFileDone             Optional: Pass true when the last chunk (or only chunk) of the file is being sent so destination knows not to expect any other pieces.
@param       int             $fileSize               Optional: Size of the file sending.
@param       string  $filePath               Optional: Remote file path in relation to the root location where the file is being stored, based on file type (based on verb).
@param       bool    $returnRaw              When true returns body raw text/data rather than decoding encoded data first.
remoteCall () Send an API call to a remote server . @param array $remoteAPI Remote API state array including URL etc . Stored in destination settings . @param string $verb API verb to call on remote server . @param array $moreParams Optional : Additional parameters to append to those sent . If needing to send a non - string this should be encoded in some manner and decoded on remote . @param int $timeout Optional : How long we expect this can last before a server times out . Typically the minimum of the local and remote timeouts . @param string $file Optional : File we are sending . This is passed so that various CRC data can be calculated . @param string $fileData Optional : Raw file contents to send ( for this chunk if using chunking ) . @param int $seekTo Optional : Location to fseek to in the file for writing . @param bool $isFileTest Optional : When true the destination will auto - delete the file after testing . @param bool $isFileDone Optional : Pass true when the last chunk ( or only chunk ) of the file is being sent so destination knows not to expect any other pieces . @param int $fileSize Optional : Size of the file sending . @param string $filePath Optional : Remote file path in relation to the root location where the file is being stored based on file type ( based on verb ) . @param bool $returnRaw When true returns body raw text / data rather than decoding encoded data first .
public static function remoteCall( $remoteAPI, $verb, $moreParams = array(), $timeout, $files = array(), $returnRaw = false ) {
		pb_backupbuddy::status( 'details', 'Preparing remote API call verb `' . $verb . '`.' );
		$now = time();
		$body = array();
		if ( ! is_numeric( $timeout ) ) {
			$timeout = backupbuddy_constants::DEPLOYMENT_REMOTE_API_DEFAULT_TIMEOUT;
		}
		pb_backupbuddy::status( 'details', 'remoteCall() HTTP wait timeout: `' . $timeout . '` seconds.' );
		$defaultFile = array(
			'file'    => '',
			'size'    => '',
			'seekto'  => '',
			'done'    => false,
			'test'    => false,
			'encoded' => false,
			'datalen' => 0,
			'data'    => '',
		);
		foreach( $files as &$file ) {
			$file = array_merge( $defaultFile, $file );
		}
		$body['files'] = $files;
		if ( ! is_array( $moreParams ) ) {
			error_log( 'BackupBuddy Error #4893783447 remote_api.php; $moreParams must be passed as array.' );
		}
		$body = serialize( array_merge( $body, $moreParams ) );
		$signature = md5( $now . $verb . $remoteAPI['key_public'] . $remoteAPI['key_secret'] . $body );
		if ( defined( 'BACKUPBUDDY_DEV' ) && ( true === BACKUPBUDDY_DEV ) ) {
			error_log( 'BACKUPBUDDY_DEV-remote api http body SEND- ' . print_r( $body, true ) );
		}
		$response = wp_remote_post( $remoteAPI['siteurl'], array(
				'method' => 'POST',
				'timeout' => ( $timeout - 2 ),
				'redirection' => 5,
				'httpversion' => '1.0',
				'blocking' => true,
				'headers' => array(
						'Referer' => $remoteAPI['siteurl'],
						'Content-Type' => 'application/octet-stream', 
						'backupbuddy_api_key' => $remoteAPI['key_public'],
						'backupbuddy_version' => pb_backupbuddy::settings( 'version' ),
						'backupbuddy_verb' => $verb,
						'backupbuddy_now' => $now,
						'backupbuddy_signature' => $signature,
					), 
				'body' => $body, 
				'cookies' => array()
			)
		);
		if ( is_wp_error( $response ) ) {
			return self::_error( 'Error #9037: Unable to connect to remote server or unexpected response. Details: `' . $response->get_error_message() . '` - Site URL: `' . $remoteAPI['siteurl'] . '`, Home URL: `' . $remoteAPI['homeurl'] . '`.' );
		} else {
			if ( true === $returnRaw ) {
				return $response['body'];
			}
			if ( false !== stripos( $response['body'], 'Request Entity Too Large' ) ) {
				return self::_error( 'Error #8001b: Request Entity Too Large. The destination server says we sent too much data. Either change the Deployment Advanced Setting "Max Chunk Size" to a lower value or change the server configuration to accept a larger value. See the following webpage for the server solution for Apache, nginx, or IIS: https://craftcms.stackexchange.com/questions/2328/413-request-entity-too-large-error-with-uploading-a-file  ... Return data: `' . htmlentities( $response['body'] ) . '`.' );
			}
			if ( false === ( $return = @unserialize( $response['body'] ) ) ) {
				return self::_error( 'Error #8001: Unable to decode Deployment response. <b>Things to check:</b><br><ol><li>Verify both sites are running the latest BackupBuddy version (v8.2 introduced non-backward-compatible changes)</li><li> Check the remote site API URL is correct: ' . $remoteAPI['siteurl'] . '</li><li>If you changed the remote site API key you must update it into this site</li><li>Make sure the remote site has the API enabled in its wp-config.php by adding <i>define( \'BACKUPBUDDY_API_ENABLE\', true );</i> somewhere ABOVE the line "That\'s all, stop editing!".</li></ol>Return data: `' . $sanibody . '`.' );
			} else {
				if ( isset( $return['logs'] ) ) {
					pb_backupbuddy::status( 'details', '*** Begin External Log (Remote API Call Response)' );
					foreach( $return['logs'] as $log ) {
						pb_backupbuddy::status( 'details', '* ' . print_r( $log, true ) );
					}
					pb_backupbuddy::status( 'details', '*** End External Log (Remote API Call Response)' );
				}
				if ( ! isset( $return['success'] ) || ( true !== $return['success'] ) ) { 
					$error = '';
					if ( isset( $return['error'] ) ) {
						$error = $return['error'];
					} else {
						$error = 'Error #838438734: No error given. Full response: "' . $return . '".';
					}
					return self::_error( 'Error #3289379: API did not report success. Error details: `' . $error . '`.' );
				} else { 
					if ( isset( $return['message'] ) ) {
						pb_backupbuddy::status( 'details', 'Response message from API: ' . $return['message'] . '".' );
					}
					return $return;
				}
			}
		}
	}
public static function remoteCall ( $ remoteAPI , $ verb , $ moreParams = array ( ) , $ timeout , $ files = array ( ) , $ returnRaw = false ) { pb_backupbuddy :: status ( 'details' , 'Preparing remote API call verb `' . $ verb . '`.' ) ; $ now = time ( ) ; $ body = array ( ) ; if ( ! is_numeric ( $ timeout ) ) { $ timeout = backupbuddy_constants :: DEPLOYMENT_REMOTE_API_DEFAULT_TIMEOUT ; } pb_backupbuddy :: status ( 'details' , 'remoteCall() HTTP wait timeout: `' . $ timeout . '` seconds.' ) ; $ defaultFile = array ( 'file' => '' , 'size' => '' , 'seekto' => '' , 'done' => false , 'test' => false , 'encoded' => false , 'datalen' => 0 , 'data' => '' , ) ; foreach ( $ files as & $ file ) { $ file = array_merge ( $ defaultFile , $ file ) ; } $ body [ 'files' ] = $ files ; if ( ! is_array ( $ moreParams ) ) { error_log ( 'BackupBuddy Error #4893783447 remote_api.php; $moreParams must be passed as array.' ) ; } $ body = serialize ( array_merge ( $ body , $ moreParams ) ) ; $ signature = md5 ( $ now . $ verb . $ remoteAPI [ 'key_public' ] . $ remoteAPI [ 'key_secret' ] . $ body ) ; if ( defined ( 'BACKUPBUDDY_DEV' ) && ( true === BACKUPBUDDY_DEV ) ) { error_log ( 'BACKUPBUDDY_DEV-remote api http body SEND- ' . print_r ( $ body , true ) ) ; } $ response = wp_remote_post ( $ remoteAPI [ 'siteurl' ] , array ( 'method' => 'POST' , 'timeout' => ( $ timeout - 2 ) , 'redirection' => 5 , 'httpversion' => '1.0' , 'blocking' => true , 'headers' => array ( 'Referer' => $ remoteAPI [ 'siteurl' ] , 'Content-Type' => 'application/octet-stream' , 'backupbuddy_api_key' => $ remoteAPI [ 'key_public' ] , 'backupbuddy_version' => pb_backupbuddy :: settings ( 'version' ) , 'backupbuddy_verb' => $ verb , 'backupbuddy_now' => $ now , 'backupbuddy_signature' => $ signature , ) , 'body' => $ body , 'cookies' => array ( ) ) ) ; if ( is_wp_error ( $ response ) ) { return self :: _error ( 'Error #9037: Unable to connect to remote server or unexpected response. Details: `' . $ response -> get_error_message ( ) . '` - Site URL: `' . $ remoteAPI [ 'siteurl' ] . '`, Home URL: `' . $ remoteAPI [ 'homeurl' ] . '`.' ) ; } else { if ( true === $ returnRaw ) { return $ response [ 'body' ] ; } if ( false !== stripos ( $ response [ 'body' ] , 'Request Entity Too Large' ) ) { return self :: _error ( 'Error #8001b: Request Entity Too Large. The destination server says we sent too much data. Either change the Deployment Advanced Setting "Max Chunk Size" to a lower value or change the server configuration to accept a larger value. See the following webpage for the server solution for Apache, nginx, or IIS: https://craftcms.stackexchange.com/questions/2328/413-request-entity-too-large-error-with-uploading-a-file  ... Return data: `' . htmlentities ( $ response [ 'body' ] ) . '`.' ) ; } if ( false === ( $ return = @ unserialize ( $ response [ 'body' ] ) ) ) { return self :: _error ( 'Error #8001: Unable to decode Deployment response. <b>Things to check:</b><br><ol><li>Verify both sites are running the latest BackupBuddy version (v8.2 introduced non-backward-compatible changes)</li><li> Check the remote site API URL is correct: ' . $ remoteAPI [ 'siteurl' ] . '</li><li>If you changed the remote site API key you must update it into this site</li><li>Make sure the remote site has the API enabled in its wp-config.php by adding <i>define( \'BACKUPBUDDY_API_ENABLE\', true );</i> somewhere ABOVE the line "That\'s all, stop editing!".</li></ol>Return data: `' . $ sanibody . '`.' ) ; } else { if ( isset ( $ return [ 'logs' ] ) ) { pb_backupbuddy :: status ( 'details' , '*** Begin External Log (Remote API Call Response)' ) ; foreach ( $ return [ 'logs' ] as $ log ) { pb_backupbuddy :: status ( 'details' , '* ' . print_r ( $ log , true ) ) ; } pb_backupbuddy :: status ( 'details' , '*** End External Log (Remote API Call Response)' ) ; } if ( ! isset ( $ return [ 'success' ] ) || ( true !== $ return [ 'success' ] ) ) { $ error = '' ; if ( isset ( $ return [ 'error' ] ) ) { $ error = $ return [ 'error' ] ; } else { $ error = 'Error #838438734: No error given. Full response: "' . $ return . '".' ; } return self :: _error ( 'Error #3289379: API did not report success. Error details: `' . $ error . '`.' ) ; } else { if ( isset ( $ return [ 'message' ] ) ) { pb_backupbuddy :: status ( 'details' , 'Response message from API: ' . $ return [ 'message' ] . '".' ) ; } return $ return ; } } } }
remoteCall()
 Send an API call to a remote server.
remoteCall () Send an API call to a remote server .
// Apply defaults for each file. //print_r( $apiKey ); //error_log( 'connectTo: ' . $remoteAPI['siteurl'] ); // binary // Sending referer header helps prevent security blocks. // IMPORTANT: ALWAYS for security verify signature prior to ever unserializing any incoming data. //error_log( '3333Response: ' . $response['body'] ); // Fail. // Success.