All-in-One WP Migration - Version 4.13

Version Description

  • Add new mechanism for resolving HTTP requests
Download this release

Release Info

Developer bangelov
Plugin Icon 128x128 All-in-One WP Migration
Version 4.13
Comparing to
See all releases

Code changes from version 4.12 to 4.13

all-in-one-wp-migration.php CHANGED
@@ -5,7 +5,7 @@
5
  * Description: Migration tool for all your blog data. Import or Export your blog content with a single click.
6
  * Author: ServMask
7
  * Author URI: https://servmask.com/
8
- * Version: 4.12
9
  * Text Domain: all-in-one-wp-migration
10
  * Domain Path: /languages
11
  * Network: True
@@ -58,6 +58,9 @@ define( 'AI1WM_THEMES_PATH', get_theme_root() );
58
  // Include constants
59
  require_once dirname( __FILE__ ) . DIRECTORY_SEPARATOR . 'constants.php';
60
 
 
 
 
61
  // Include loader
62
  require_once dirname( __FILE__ ) . DIRECTORY_SEPARATOR . 'loader.php';
63
 
5
  * Description: Migration tool for all your blog data. Import or Export your blog content with a single click.
6
  * Author: ServMask
7
  * Author URI: https://servmask.com/
8
+ * Version: 4.13
9
  * Text Domain: all-in-one-wp-migration
10
  * Domain Path: /languages
11
  * Network: True
58
  // Include constants
59
  require_once dirname( __FILE__ ) . DIRECTORY_SEPARATOR . 'constants.php';
60
 
61
+ // Include functions
62
+ require_once dirname( __FILE__ ) . DIRECTORY_SEPARATOR . 'functions.php';
63
+
64
  // Include loader
65
  require_once dirname( __FILE__ ) . DIRECTORY_SEPARATOR . 'loader.php';
66
 
constants.php CHANGED
@@ -38,7 +38,7 @@ if ( function_exists( 'gethostname' ) && in_array( gethostname(), $local ) ) {
38
  // ==================
39
  // = Plugin Version =
40
  // ==================
41
- define( 'AI1WM_VERSION', '4.12' );
42
 
43
  // ===============
44
  // = Plugin Name =
@@ -165,6 +165,16 @@ define( 'AI1WM_EXCEPTION_HANDLER', 'ai1wm_exception_handler' );
165
  // ========================
166
  define( 'AI1WM_MAINTENANCE_MODE', 'ai1wm_maintenance_mode' );
167
 
 
 
 
 
 
 
 
 
 
 
168
  // ==============
169
  // = Secret Key =
170
  // ==============
38
  // ==================
39
  // = Plugin Version =
40
  // ==================
41
+ define( 'AI1WM_VERSION', '4.13' );
42
 
43
  // ===============
44
  // = Plugin Name =
165
  // ========================
166
  define( 'AI1WM_MAINTENANCE_MODE', 'ai1wm_maintenance_mode' );
167
 
168
+ // ==========
169
+ // = URL IP =
170
+ // ==========
171
+ define( 'AI1WM_URL_IP', 'ai1wm_url_ip' );
172
+
173
+ // =================
174
+ // = URL Transport =
175
+ // =================
176
+ define( 'AI1WM_URL_TRANSPORT', 'ai1wm_url_transport' );
177
+
178
  // ==============
179
  // = Secret Key =
180
  // ==============
functions.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (C) 2014 ServMask Inc.
4
+ *
5
+ * This program is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * This program is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ *
18
+ * ███████╗███████╗██████╗ ██╗ ██╗███╗ ███╗ █████╗ ███████╗██╗ ██╗
19
+ * ██╔════╝██╔════╝██╔══██╗██║ ██║████╗ ████║██╔══██╗██╔════╝██║ ██╔╝
20
+ * ███████╗█████╗ ██████╔╝██║ ██║██╔████╔██║███████║███████╗█████╔╝
21
+ * ╚════██║██╔══╝ ██╔══██╗╚██╗ ██╔╝██║╚██╔╝██║██╔══██║╚════██║██╔═██╗
22
+ * ███████║███████╗██║ ██║ ╚████╔╝ ██║ ╚═╝ ██║██║ ██║███████║██║ ██╗
23
+ * ╚══════╝╚══════╝╚═╝ ╚═╝ ╚═══╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝
24
+ */
25
+
26
+ /**
27
+ * URL encode
28
+ *
29
+ * @param mixed $value Value to encode
30
+ * @return mixed
31
+ */
32
+ function ai1wm_urlencode( $value ) {
33
+ return is_array( $value ) ? array_map( 'ai1wm_urlencode', $value ) : urlencode( $value );
34
+ }
35
+
36
+ /**
37
+ * URL decode
38
+ *
39
+ * @param mixed $value Value to decode
40
+ * @return mixed
41
+ */
42
+ function ai1wm_urldecode( $value ) {
43
+ return is_array( $value ) ? array_map( 'ai1wm_urldecode', $value ) : urldecode( stripslashes( $value ) );
44
+ }
lib/controller/class-ai1wm-export-controller.php CHANGED
@@ -42,7 +42,7 @@ class Ai1wm_Export_Controller {
42
 
43
  // Set arguments
44
  if ( empty( $args ) ) {
45
- $args = $_REQUEST;
46
  }
47
 
48
  // Set storage path
42
 
43
  // Set arguments
44
  if ( empty( $args ) ) {
45
+ $args = ai1wm_urldecode( $_REQUEST );
46
  }
47
 
48
  // Set storage path
lib/controller/class-ai1wm-import-controller.php CHANGED
@@ -33,7 +33,7 @@ class Ai1wm_Import_Controller {
33
 
34
  // Set arguments
35
  if ( empty( $args ) ) {
36
- $args = $_REQUEST;
37
  }
38
 
39
  // Set storage path
33
 
34
  // Set arguments
35
  if ( empty( $args ) ) {
36
+ $args = ai1wm_urldecode( $_REQUEST );
37
  }
38
 
39
  // Set storage path
lib/controller/class-ai1wm-main-controller.php CHANGED
@@ -256,6 +256,8 @@ class Ai1wm_Main_Controller {
256
  // Public
257
  add_action( 'wp_ajax_nopriv_ai1wm_export', 'Ai1wm_Export_Controller::export' );
258
  add_action( 'wp_ajax_nopriv_ai1wm_import', 'Ai1wm_Import_Controller::import' );
 
 
259
 
260
  // Private
261
  if ( ! current_user_can( 'export' ) || ! current_user_can( 'import' ) ) {
@@ -270,6 +272,8 @@ class Ai1wm_Main_Controller {
270
  add_action( 'wp_ajax_ai1wm_close_message', 'Ai1wm_Message_Controller::close_message' );
271
  add_action( 'wp_ajax_ai1wm_backup_delete', 'Ai1wm_Backup_Controller::delete' );
272
  add_action( 'wp_ajax_ai1wm_disable_maintenance', 'Ai1wm_Maintenance::disable' );
 
 
273
  }
274
 
275
  /**
256
  // Public
257
  add_action( 'wp_ajax_nopriv_ai1wm_export', 'Ai1wm_Export_Controller::export' );
258
  add_action( 'wp_ajax_nopriv_ai1wm_import', 'Ai1wm_Import_Controller::import' );
259
+ add_action( 'wp_ajax_nopriv_ai1wm_resolve', 'Ai1wm_Resolve_Controller::resolve' );
260
+
261
 
262
  // Private
263
  if ( ! current_user_can( 'export' ) || ! current_user_can( 'import' ) ) {
272
  add_action( 'wp_ajax_ai1wm_close_message', 'Ai1wm_Message_Controller::close_message' );
273
  add_action( 'wp_ajax_ai1wm_backup_delete', 'Ai1wm_Backup_Controller::delete' );
274
  add_action( 'wp_ajax_ai1wm_disable_maintenance', 'Ai1wm_Maintenance::disable' );
275
+ add_action( 'wp_ajax_ai1wm_resolve', 'Ai1wm_Resolve_Controller::resolve' );
276
+
277
  }
278
 
279
  /**
lib/controller/class-ai1wm-resolve-controller.php ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (C) 2014 ServMask Inc.
4
+ *
5
+ * This program is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * This program is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ *
18
+ * ███████╗███████╗██████╗ ██╗ ██╗███╗ ███╗ █████╗ ███████╗██╗ ██╗
19
+ * ██╔════╝██╔════╝██╔══██╗██║ ██║████╗ ████║██╔══██╗██╔════╝██║ ██╔╝
20
+ * ███████╗█████╗ ██████╔╝██║ ██║██╔████╔██║███████║███████╗█████╔╝
21
+ * ╚════██║██╔══╝ ██╔══██╗╚██╗ ██╔╝██║╚██╔╝██║██╔══██║╚════██║██╔═██╗
22
+ * ███████║███████╗██║ ██║ ╚████╔╝ ██║ ╚═╝ ██║██║ ██║███████║██║ ██╗
23
+ * ╚══════╝╚══════╝╚═╝ ╚═╝ ╚═══╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝
24
+ */
25
+
26
+ class Ai1wm_Resolve_Controller {
27
+
28
+ public static function resolve( $args = array() ) {
29
+
30
+ // Set arguments
31
+ if ( empty( $args ) ) {
32
+ $args = ai1wm_urldecode( $_REQUEST );
33
+ }
34
+
35
+ // Set secret key
36
+ $secret_key = null;
37
+ if ( isset( $args['secret_key'] ) ) {
38
+ $secret_key = $args['secret_key'];
39
+ }
40
+
41
+ // Verify secret key by using the value in the database, not in cache
42
+ if ( $secret_key !== get_site_option( AI1WM_SECRET_KEY, false, false ) ) {
43
+ Ai1wm_Status::set(
44
+ array(
45
+ 'type' => 'error',
46
+ 'title' => __( "Unable to resolve", AI1WM_PLUGIN_NAME ),
47
+ 'message' => __( "Unable to authenticate your request with secret_key = \"{$secret_key}\"", AI1WM_PLUGIN_NAME ),
48
+ )
49
+ );
50
+ exit;
51
+ }
52
+
53
+ // Set IP address
54
+ if ( isset( $args['url_ip'] ) && ( $ip = $args['url_ip' ] ) ) {
55
+ update_site_option( AI1WM_URL_IP, $ip );
56
+ }
57
+
58
+ // Set transport layer
59
+ if ( isset( $args['url_transport'] ) && ( $transport = $args['url_transport'] ) ) {
60
+ if ( $transport === 'curl' ) {
61
+ update_site_option( AI1WM_URL_TRANSPORT, array( 'curl', 'ai1wm' ) );
62
+ } else {
63
+ update_site_option( AI1WM_URL_TRANSPORT, array( 'ai1wm', 'curl' ) );
64
+ }
65
+ }
66
+ }
67
+ }
lib/exception/class-ai1wm-http-exception.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Copyright (C) 2014 ServMask Inc.
5
+ *
6
+ * This program is free software: you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License as published by
8
+ * the Free Software Foundation, either version 3 of the License, or
9
+ * (at your option) any later version.
10
+ *
11
+ * This program is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU General Public License
17
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18
+ *
19
+ * ███████╗███████╗██████╗ ██╗ ██╗███╗ ███╗ █████╗ ███████╗██╗ ██╗
20
+ * ██╔════╝██╔════╝██╔══██╗██║ ██║████╗ ████║██╔══██╗██╔════╝██║ ██╔╝
21
+ * ███████╗█████╗ ██████╔╝██║ ██║██╔████╔██║███████║███████╗█████╔╝
22
+ * ╚════██║██╔══╝ ██╔══██╗╚██╗ ██╔╝██║╚██╔╝██║██╔══██║╚════██║██╔═██╗
23
+ * ███████║███████╗██║ ██║ ╚████╔╝ ██║ ╚═╝ ██║██║ ██║███████║██║ ██╗
24
+ * ╚══════╝╚══════╝╚═╝ ╚═╝ ╚═══╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝
25
+ */
26
+ class Ai1wm_Http_Exception extends Exception {
27
+
28
+ }
lib/model/class-ai1wm-export-abstract.php CHANGED
@@ -31,6 +31,11 @@ abstract class Ai1wm_Export_Abstract {
31
 
32
  public function __construct( array $args = array() ) {
33
  $this->args = $args;
 
 
 
 
 
34
  }
35
 
36
  /**
@@ -391,61 +396,8 @@ abstract class Ai1wm_Export_Abstract {
391
  exit;
392
  }
393
 
394
- $headers = array();
395
-
396
- // HTTP authentication
397
- $auth_user = get_site_option( AI1WM_AUTH_USER, false, false );
398
- $auth_password = get_site_option( AI1WM_AUTH_PASSWORD, false, false );
399
- if ( ! empty( $auth_user ) && ! empty( $auth_password ) ) {
400
- $headers['Authorization'] = 'Basic ' . base64_encode( $auth_user . ':' . $auth_password );
401
- }
402
-
403
- // Resolve domain
404
- $url = add_query_arg( urlencode_deep( $this->args ), admin_url( 'admin-ajax.php?action=ai1wm_export' ) );
405
- $hostname = parse_url( $url, PHP_URL_HOST );
406
- $port = parse_url( $url, PHP_URL_PORT );
407
- $ip = gethostbyname( $hostname );
408
-
409
- // Could not resolve host
410
- if ( $hostname === $ip ) {
411
-
412
- // Get server IP address
413
- if ( ! empty( $_SERVER['SERVER_ADDR'] ) ) {
414
- $ip = $_SERVER['SERVER_ADDR'];
415
- } else if ( ! empty( $_SERVER['LOCAL_ADDR'] ) ) {
416
- $ip = $_SERVER['LOCAL_ADDR'];
417
- } else {
418
- $ip = $_SERVER['SERVER_NAME'];
419
- }
420
-
421
- // Add IPv6 support
422
- if ( filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) ) {
423
- $ip = "[$ip]";
424
- }
425
- }
426
-
427
- // Replace URL
428
- $url = preg_replace( sprintf( '/%s/', preg_quote( $hostname, '-' ) ), $ip, $url, 1 );
429
-
430
- // Set host header
431
- if ( ! empty( $port ) ) {
432
- $headers['Host'] = sprintf( '%s:%s', $hostname, $port );
433
- } else {
434
- $headers['Host'] = sprintf( '%s', $hostname );
435
- }
436
-
437
  // HTTP request
438
- remove_all_filters( 'http_request_args' );
439
- wp_remote_get(
440
- $url,
441
- array(
442
- 'timeout' => apply_filters( 'ai1wm_http_timeout', 5 ),
443
- 'blocking' => false,
444
- 'sslverify' => apply_filters( 'https_local_ssl_verify', false ),
445
- 'user-agent' => 'ai1wm',
446
- 'headers' => $headers,
447
- )
448
- );
449
  }
450
 
451
  /**
31
 
32
  public function __construct( array $args = array() ) {
33
  $this->args = $args;
34
+
35
+ // HTTP resolve
36
+ if ( $this->args['method'] === 'start' ) {
37
+ Ai1wm_Http::resolve( admin_url( 'admin-ajax.php?action=ai1wm_resolve' ) );
38
+ }
39
  }
40
 
41
  /**
396
  exit;
397
  }
398
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
399
  // HTTP request
400
+ Ai1wm_Http::get( admin_url( 'admin-ajax.php?action=ai1wm_export' ), $this->args );
 
 
 
 
 
 
 
 
 
 
401
  }
402
 
403
  /**
lib/model/class-ai1wm-http.php ADDED
@@ -0,0 +1,147 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright (C) 2014 ServMask Inc.
4
+ *
5
+ * This program is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * This program is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ *
18
+ * ███████╗███████╗██████╗ ██╗ ██╗███╗ ███╗ █████╗ ███████╗██╗ ██╗
19
+ * ██╔════╝██╔════╝██╔══██╗██║ ██║████╗ ████║██╔══██╗██╔════╝██║ ██╔╝
20
+ * ███████╗█████╗ ██████╔╝██║ ██║██╔████╔██║███████║███████╗█████╔╝
21
+ * ╚════██║██╔══╝ ██╔══██╗╚██╗ ██╔╝██║╚██╔╝██║██╔══██║╚════██║██╔═██╗
22
+ * ███████║███████╗██║ ██║ ╚████╔╝ ██║ ╚═╝ ██║██║ ██║███████║██║ ██╗
23
+ * ╚══════╝╚══════╝╚═╝ ╚═╝ ╚═══╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝
24
+ */
25
+
26
+ class Ai1wm_Http {
27
+
28
+ public static function get( $url, $params = array() ) {
29
+
30
+ // Get IP address
31
+ $ip = get_site_option( AI1WM_URL_IP, false, false );
32
+
33
+ // HTTP request
34
+ Ai1wm_Http::request( $url, $ip, $params );
35
+ }
36
+
37
+ public static function resolve( $url ) {
38
+
39
+ // Reset IP address and transport layer
40
+ delete_site_option( AI1WM_URL_IP );
41
+ delete_site_option( AI1WM_URL_TRANSPORT );
42
+
43
+ // Set secret
44
+ $secret_key = get_site_option( AI1WM_SECRET_KEY, false, false );
45
+
46
+ // Set scheme
47
+ $scheme = parse_url( $url, PHP_URL_SCHEME );
48
+
49
+ // Set host name
50
+ $host = parse_url( $url, PHP_URL_HOST );
51
+
52
+ // Set server IP address
53
+ if ( ! empty( $_SERVER['SERVER_ADDR'] ) ) {
54
+ $ip = $_SERVER['SERVER_ADDR'];
55
+ } else if ( ! empty( $_SERVER['LOCAL_ADDR'] ) ) {
56
+ $ip = $_SERVER['LOCAL_ADDR'];
57
+ } else {
58
+ $ip = '127.0.0.1';
59
+ }
60
+
61
+ // Set domain IP address
62
+ $domain = gethostbyname( $host );
63
+
64
+ // HTTP resolve
65
+ foreach ( array( 'ai1wm', 'curl' ) as $transport ) {
66
+ foreach ( array( $ip, $domain, $host ) as $ip ) {
67
+
68
+ // HTTP request
69
+ Ai1wm_Http::request( $url, $ip, array(
70
+ 'secret_key' => $secret_key,
71
+ 'url_ip' => $ip,
72
+ 'url_transport' => $transport
73
+ ) );
74
+
75
+ // HTTP response
76
+ for ( $i = 0; $i < 5; $i++, sleep( 1 ) ) {
77
+
78
+ // Clear WP options cache
79
+ wp_cache_flush();
80
+
81
+ // Is valid transport layer?
82
+ if ( get_site_option( AI1WM_URL_IP, false, false )
83
+ && get_site_option( AI1WM_URL_TRANSPORT, false, false ) ) {
84
+ return;
85
+ }
86
+ }
87
+ }
88
+ }
89
+
90
+ // No connection
91
+ throw new Ai1wm_Http_Exception( __(
92
+ 'There was a problem while reaching your server.<br />' .
93
+ 'Contact <a href="mailto:support@servmask.com">support@servmask.com</a> for assistance.',
94
+ AI1WM_PLUGIN_NAME
95
+ ) );
96
+ }
97
+
98
+ public static function request( $url, $ip, $params = array() ) {
99
+
100
+ // Set request order
101
+ add_filter( 'http_api_transports', 'Ai1wm_Http::transports', 100 );
102
+
103
+ // Set host name
104
+ $host = parse_url( $url, PHP_URL_HOST );
105
+
106
+ // Set accept header
107
+ $headers = array( 'Accept' => '*/*' );
108
+
109
+ // Add authorization header
110
+ if ( ( $user = get_site_option( AI1WM_AUTH_USER ) ) && ( $password = get_site_option( AI1WM_AUTH_PASSWORD ) ) ) {
111
+ $headers['Authorization'] = sprintf( 'Basic %s', base64_encode( "{$user}:{$password}" ) );
112
+ }
113
+
114
+ // Add host header
115
+ if ( ( $port = parse_url( $url, PHP_URL_PORT ) ) ) {
116
+ $headers['Host'] = sprintf( '%s:%s', $host, $port );
117
+ } else {
118
+ $headers['Host'] = sprintf( '%s', $host );
119
+ }
120
+
121
+ // Add IPv6 support
122
+ if ( filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) ) {
123
+ $ip = "[$ip]";
124
+ }
125
+
126
+ // Replace IP address
127
+ if ( ! empty( $ip ) ) {
128
+ $url = str_replace( "//{$host}", "//{$ip}", $url );
129
+ }
130
+
131
+ // HTTP request
132
+ remove_all_filters( 'http_request_args' );
133
+ wp_remote_get(
134
+ add_query_arg( ai1wm_urlencode( $params ), $url ),
135
+ array(
136
+ 'timeout' => apply_filters( 'ai1wm_http_timeout', 5 ),
137
+ 'blocking' => false,
138
+ 'sslverify' => false,
139
+ 'headers' => $headers,
140
+ )
141
+ );
142
+ }
143
+
144
+ public static function transports( $transports ) {
145
+ return get_site_option( AI1WM_URL_TRANSPORT, array( 'ai1wm', 'curl' ), false );
146
+ }
147
+ }
lib/model/class-ai1wm-import-abstract.php CHANGED
@@ -31,6 +31,11 @@ abstract class Ai1wm_Import_Abstract {
31
 
32
  public function __construct( array $args = array() ) {
33
  $this->args = $args;
 
 
 
 
 
34
  }
35
 
36
  /**
@@ -381,65 +386,12 @@ abstract class Ai1wm_Import_Abstract {
381
  $this->args['method'] = $method;
382
  $this->args['secret_key'] = get_site_option( AI1WM_SECRET_KEY, false, false );
383
 
384
- // Check the status of the import, maybe we need to stop it
385
  if ( ! is_file( $this->storage()->archive() ) ) {
386
  exit;
387
  }
388
 
389
- $headers = array();
390
-
391
- // HTTP authentication
392
- $auth_user = get_site_option( AI1WM_AUTH_USER, false, false );
393
- $auth_password = get_site_option( AI1WM_AUTH_PASSWORD, false, false );
394
- if ( ! empty( $auth_user ) && ! empty( $auth_password ) ) {
395
- $headers['Authorization'] = 'Basic ' . base64_encode( $auth_user . ':' . $auth_password );
396
- }
397
-
398
- // Resolve domain
399
- $url = add_query_arg( urlencode_deep( $this->args ), admin_url( 'admin-ajax.php?action=ai1wm_import' ) );
400
- $hostname = parse_url( $url, PHP_URL_HOST );
401
- $port = parse_url( $url, PHP_URL_PORT );
402
- $ip = gethostbyname( $hostname );
403
-
404
- // Could not resolve host
405
- if ( $hostname === $ip ) {
406
-
407
- // Get server IP address
408
- if ( ! empty( $_SERVER['SERVER_ADDR'] ) ) {
409
- $ip = $_SERVER['SERVER_ADDR'];
410
- } else if ( ! empty( $_SERVER['LOCAL_ADDR'] ) ) {
411
- $ip = $_SERVER['LOCAL_ADDR'];
412
- } else {
413
- $ip = $_SERVER['SERVER_NAME'];
414
- }
415
-
416
- // Add IPv6 support
417
- if ( filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) ) {
418
- $ip = "[$ip]";
419
- }
420
- }
421
-
422
- // Replace URL
423
- $url = preg_replace( sprintf( '/%s/', preg_quote( $hostname, '-' ) ), $ip, $url, 1 );
424
-
425
- // Set host header
426
- if ( ! empty( $port ) ) {
427
- $headers['Host'] = sprintf( '%s:%s', $hostname, $port );
428
- } else {
429
- $headers['Host'] = sprintf( '%s', $hostname );
430
- }
431
-
432
  // HTTP request
433
- remove_all_filters( 'http_request_args' );
434
- wp_remote_get(
435
- $url,
436
- array(
437
- 'timeout' => apply_filters( 'ai1wm_http_timeout', 5 ),
438
- 'blocking' => false,
439
- 'sslverify' => apply_filters( 'https_local_ssl_verify', false ),
440
- 'user-agent' => 'ai1wm',
441
- 'headers' => $headers,
442
- )
443
- );
444
  }
445
  }
31
 
32
  public function __construct( array $args = array() ) {
33
  $this->args = $args;
34
+
35
+ // HTTP resolve
36
+ if ( $this->args['method'] === 'import' ) {
37
+ Ai1wm_Http::resolve( admin_url( 'admin-ajax.php?action=ai1wm_resolve' ) );
38
+ }
39
  }
40
 
41
  /**
386
  $this->args['method'] = $method;
387
  $this->args['secret_key'] = get_site_option( AI1WM_SECRET_KEY, false, false );
388
 
389
+ // Check the status of the export, maybe we need to stop it
390
  if ( ! is_file( $this->storage()->archive() ) ) {
391
  exit;
392
  }
393
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
394
  // HTTP request
395
+ Ai1wm_Http::get( admin_url( 'admin-ajax.php?action=ai1wm_import' ), $this->args );
 
 
 
 
 
 
 
 
 
 
396
  }
397
  }
lib/model/class-ai1wm-streams.php ADDED
@@ -0,0 +1,418 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Simple and uniform HTTP request API.
4
+ *
5
+ * Standardizes the HTTP requests for WordPress. Handles cookies, gzip encoding and decoding, chunk
6
+ * decoding, if HTTP 1.1 and various other difficult HTTP protocol implementations.
7
+ *
8
+ * @link https://core.trac.wordpress.org/ticket/4779 HTTP API Proposal
9
+ *
10
+ * @package WordPress
11
+ * @subpackage HTTP
12
+ * @since 2.7.0
13
+ */
14
+
15
+ /**
16
+ * HTTP request method uses PHP Streams to retrieve the url.
17
+ *
18
+ * @since 2.7.0
19
+ * @since 3.7.0 Combined with the fsockopen transport and switched to stream_socket_client().
20
+ */
21
+ class WP_Http_Ai1wm {
22
+ /**
23
+ * Send a HTTP request to a URI using PHP Streams.
24
+ *
25
+ * @see WP_Http::request For default options descriptions.
26
+ *
27
+ * @since 2.7.0
28
+ * @since 3.7.0 Combined with the fsockopen transport and switched to stream_socket_client().
29
+ *
30
+ * @access public
31
+ * @param string $url The request URL.
32
+ * @param string|array $args Optional. Override the defaults.
33
+ * @return array|WP_Error Array containing 'headers', 'body', 'response', 'cookies', 'filename'. A WP_Error instance upon error
34
+ */
35
+ public function request($url, $args = array()) {
36
+ $defaults = array(
37
+ 'method' => 'GET', 'timeout' => 5,
38
+ 'redirection' => 5, 'httpversion' => '1.0',
39
+ 'blocking' => true,
40
+ 'headers' => array(), 'body' => null, 'cookies' => array()
41
+ );
42
+
43
+ $r = wp_parse_args( $args, $defaults );
44
+
45
+ if ( isset( $r['headers']['User-Agent'] ) ) {
46
+ $r['user-agent'] = $r['headers']['User-Agent'];
47
+ unset( $r['headers']['User-Agent'] );
48
+ } elseif ( isset( $r['headers']['user-agent'] ) ) {
49
+ $r['user-agent'] = $r['headers']['user-agent'];
50
+ unset( $r['headers']['user-agent'] );
51
+ }
52
+
53
+ // Construct Cookie: header if any cookies are set.
54
+ WP_Http::buildCookieHeader( $r );
55
+
56
+ $arrURL = parse_url($url);
57
+
58
+ $connect_host = $arrURL['host'];
59
+
60
+ $secure_transport = ( $arrURL['scheme'] == 'ssl' || $arrURL['scheme'] == 'https' );
61
+ if ( ! isset( $arrURL['port'] ) ) {
62
+ if ( $arrURL['scheme'] == 'ssl' || $arrURL['scheme'] == 'https' ) {
63
+ $arrURL['port'] = 443;
64
+ $secure_transport = true;
65
+ } else {
66
+ $arrURL['port'] = 80;
67
+ }
68
+ }
69
+
70
+ // Always pass a Path, defaulting to the root in cases such as http://example.com
71
+ if ( ! isset( $arrURL['path'] ) ) {
72
+ $arrURL['path'] = '/';
73
+ }
74
+
75
+ if ( isset( $r['headers']['Host'] ) || isset( $r['headers']['host'] ) ) {
76
+ if ( isset( $r['headers']['Host'] ) )
77
+ $arrURL['host'] = $r['headers']['Host'];
78
+ else
79
+ $arrURL['host'] = $r['headers']['host'];
80
+ unset( $r['headers']['Host'], $r['headers']['host'] );
81
+ }
82
+
83
+ /*
84
+ * Certain versions of PHP have issues with 'localhost' and IPv6, It attempts to connect
85
+ * to ::1, which fails when the server is not set up for it. For compatibility, always
86
+ * connect to the IPv4 address.
87
+ */
88
+ if ( 'localhost' == strtolower( $connect_host ) )
89
+ $connect_host = '127.0.0.1';
90
+
91
+ $connect_host = $secure_transport ? 'ssl://' . $connect_host : 'tcp://' . $connect_host;
92
+
93
+ $is_local = isset( $r['local'] ) && $r['local'];
94
+ $ssl_verify = isset( $r['sslverify'] ) && $r['sslverify'];
95
+ if ( $is_local ) {
96
+ /**
97
+ * Filter whether SSL should be verified for local requests.
98
+ *
99
+ * @since 2.8.0
100
+ *
101
+ * @param bool $ssl_verify Whether to verify the SSL connection. Default true.
102
+ */
103
+ $ssl_verify = apply_filters( 'https_local_ssl_verify', $ssl_verify );
104
+ } elseif ( ! $is_local ) {
105
+ /**
106
+ * Filter whether SSL should be verified for non-local requests.
107
+ *
108
+ * @since 2.8.0
109
+ *
110
+ * @param bool $ssl_verify Whether to verify the SSL connection. Default true.
111
+ */
112
+ $ssl_verify = apply_filters( 'https_ssl_verify', $ssl_verify );
113
+ }
114
+
115
+ $proxy = new WP_HTTP_Proxy();
116
+
117
+ $context = stream_context_create( array(
118
+ 'ssl' => array(
119
+ 'verify_peer' => $ssl_verify,
120
+ //'CN_match' => $arrURL['host'], // This is handled by self::verify_ssl_certificate()
121
+ 'capture_peer_cert' => $ssl_verify,
122
+ 'SNI_enabled' => true,
123
+ 'cafile' => $r['sslcertificates'],
124
+ 'allow_self_signed' => ! $ssl_verify,
125
+ )
126
+ ) );
127
+
128
+ $timeout = (int) floor( $r['timeout'] );
129
+ $utimeout = $timeout == $r['timeout'] ? 0 : 1000000 * $r['timeout'] % 1000000;
130
+ $connect_timeout = max( $timeout, 1 );
131
+
132
+ // Store error number.
133
+ $connection_error = null;
134
+
135
+ // Store error string.
136
+ $connection_error_str = null;
137
+
138
+ if ( !WP_DEBUG ) {
139
+ // In the event that the SSL connection fails, silence the many PHP Warnings.
140
+ if ( $secure_transport )
141
+ $error_reporting = error_reporting(0);
142
+
143
+ if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) )
144
+ $handle = @stream_socket_client( 'tcp://' . $proxy->host() . ':' . $proxy->port(), $connection_error, $connection_error_str, $connect_timeout, STREAM_CLIENT_CONNECT, $context );
145
+ else
146
+ $handle = @stream_socket_client( $connect_host . ':' . $arrURL['port'], $connection_error, $connection_error_str, $connect_timeout, STREAM_CLIENT_CONNECT, $context );
147
+
148
+ if ( $secure_transport )
149
+ error_reporting( $error_reporting );
150
+
151
+ } else {
152
+ if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) )
153
+ $handle = stream_socket_client( 'tcp://' . $proxy->host() . ':' . $proxy->port(), $connection_error, $connection_error_str, $connect_timeout, STREAM_CLIENT_CONNECT, $context );
154
+ else
155
+ $handle = stream_socket_client( $connect_host . ':' . $arrURL['port'], $connection_error, $connection_error_str, $connect_timeout, STREAM_CLIENT_CONNECT, $context );
156
+ }
157
+
158
+ if ( false === $handle ) {
159
+ // SSL connection failed due to expired/invalid cert, or, OpenSSL configuration is broken.
160
+ if ( $secure_transport && 0 === $connection_error && '' === $connection_error_str )
161
+ return new WP_Error( 'http_request_failed', __( 'The SSL certificate for the host could not be verified.' ) );
162
+
163
+ return new WP_Error('http_request_failed', $connection_error . ': ' . $connection_error_str );
164
+ }
165
+
166
+ // Verify that the SSL certificate is valid for this request.
167
+ if ( $secure_transport && $ssl_verify && ! $proxy->is_enabled() ) {
168
+ if ( ! self::verify_ssl_certificate( $handle, $arrURL['host'] ) )
169
+ return new WP_Error( 'http_request_failed', __( 'The SSL certificate for the host could not be verified.' ) );
170
+ }
171
+
172
+ stream_set_timeout( $handle, $timeout, $utimeout );
173
+
174
+ if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) //Some proxies require full URL in this field.
175
+ $requestPath = $url;
176
+ else
177
+ $requestPath = $arrURL['path'] . ( isset($arrURL['query']) ? '?' . $arrURL['query'] : '' );
178
+
179
+ $strHeaders = strtoupper($r['method']) . ' ' . $requestPath . ' HTTP/' . $r['httpversion'] . "\r\n";
180
+
181
+ $include_port_in_host_header = (
182
+ ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) ||
183
+ ( 'http' == $arrURL['scheme'] && 80 != $arrURL['port'] ) ||
184
+ ( 'https' == $arrURL['scheme'] && 443 != $arrURL['port'] )
185
+ );
186
+
187
+ if ( $include_port_in_host_header ) {
188
+ $strHeaders .= 'Host: ' . $arrURL['host'] . ':' . $arrURL['port'] . "\r\n";
189
+ } else {
190
+ $strHeaders .= 'Host: ' . $arrURL['host'] . "\r\n";
191
+ }
192
+
193
+ if ( isset($r['user-agent']) )
194
+ $strHeaders .= 'User-agent: ' . $r['user-agent'] . "\r\n";
195
+
196
+ if ( is_array($r['headers']) ) {
197
+ foreach ( (array) $r['headers'] as $header => $headerValue )
198
+ $strHeaders .= $header . ': ' . $headerValue . "\r\n";
199
+ } else {
200
+ $strHeaders .= $r['headers'];
201
+ }
202
+
203
+ if ( $proxy->use_authentication() )
204
+ $strHeaders .= $proxy->authentication_header() . "\r\n";
205
+
206
+ $strHeaders .= "\r\n";
207
+
208
+ if ( ! is_null($r['body']) )
209
+ $strHeaders .= $r['body'];
210
+
211
+ fwrite($handle, $strHeaders);
212
+
213
+ if ( ! $r['blocking'] ) {
214
+ usleep( 50000 );
215
+ stream_set_blocking( $handle, 0 );
216
+ fclose( $handle );
217
+ return array( 'headers' => array(), 'body' => '', 'response' => array('code' => false, 'message' => false), 'cookies' => array() );
218
+ }
219
+
220
+ $strResponse = '';
221
+ $bodyStarted = false;
222
+ $keep_reading = true;
223
+ $block_size = 4096;
224
+ if ( isset( $r['limit_response_size'] ) )
225
+ $block_size = min( $block_size, $r['limit_response_size'] );
226
+
227
+ // If streaming to a file setup the file handle.
228
+ if ( $r['stream'] ) {
229
+ if ( ! WP_DEBUG )
230
+ $stream_handle = @fopen( $r['filename'], 'w+' );
231
+ else
232
+ $stream_handle = fopen( $r['filename'], 'w+' );
233
+ if ( ! $stream_handle )
234
+ return new WP_Error( 'http_request_failed', sprintf( __( 'Could not open handle for fopen() to %s' ), $r['filename'] ) );
235
+
236
+ $bytes_written = 0;
237
+ while ( ! feof($handle) && $keep_reading ) {
238
+ $block = fread( $handle, $block_size );
239
+ if ( ! $bodyStarted ) {
240
+ $strResponse .= $block;
241
+ if ( strpos( $strResponse, "\r\n\r\n" ) ) {
242
+ $process = WP_Http::processResponse( $strResponse );
243
+ $bodyStarted = true;
244
+ $block = $process['body'];
245
+ unset( $strResponse );
246
+ $process['body'] = '';
247
+ }
248
+ }
249
+
250
+ $this_block_size = strlen( $block );
251
+
252
+ if ( isset( $r['limit_response_size'] ) && ( $bytes_written + $this_block_size ) > $r['limit_response_size'] ) {
253
+ $this_block_size = ( $r['limit_response_size'] - $bytes_written );
254
+ $block = substr( $block, 0, $this_block_size );
255
+ }
256
+
257
+ $bytes_written_to_file = fwrite( $stream_handle, $block );
258
+
259
+ if ( $bytes_written_to_file != $this_block_size ) {
260
+ fclose( $handle );
261
+ fclose( $stream_handle );
262
+ return new WP_Error( 'http_request_failed', __( 'Failed to write request to temporary file.' ) );
263
+ }
264
+
265
+ $bytes_written += $bytes_written_to_file;
266
+
267
+ $keep_reading = !isset( $r['limit_response_size'] ) || $bytes_written < $r['limit_response_size'];
268
+ }
269
+
270
+ fclose( $stream_handle );
271
+
272
+ } else {
273
+ $header_length = 0;
274
+ while ( ! feof( $handle ) && $keep_reading ) {
275
+ $block = fread( $handle, $block_size );
276
+ $strResponse .= $block;
277
+ if ( ! $bodyStarted && strpos( $strResponse, "\r\n\r\n" ) ) {
278
+ $header_length = strpos( $strResponse, "\r\n\r\n" ) + 4;
279
+ $bodyStarted = true;
280
+ }
281
+ $keep_reading = ( ! $bodyStarted || !isset( $r['limit_response_size'] ) || strlen( $strResponse ) < ( $header_length + $r['limit_response_size'] ) );
282
+ }
283
+
284
+ $process = WP_Http::processResponse( $strResponse );
285
+ unset( $strResponse );
286
+
287
+ }
288
+
289
+ fclose( $handle );
290
+
291
+ $arrHeaders = WP_Http::processHeaders( $process['headers'], $url );
292
+
293
+ $response = array(
294
+ 'headers' => $arrHeaders['headers'],
295
+ // Not yet processed.
296
+ 'body' => null,
297
+ 'response' => $arrHeaders['response'],
298
+ 'cookies' => $arrHeaders['cookies'],
299
+ 'filename' => $r['filename']
300
+ );
301
+
302
+ // Handle redirects.
303
+ if ( false !== ( $redirect_response = WP_HTTP::handle_redirects( $url, $r, $response ) ) )
304
+ return $redirect_response;
305
+
306
+ // If the body was chunk encoded, then decode it.
307
+ if ( ! empty( $process['body'] ) && isset( $arrHeaders['headers']['transfer-encoding'] ) && 'chunked' == $arrHeaders['headers']['transfer-encoding'] )
308
+ $process['body'] = WP_Http::chunkTransferDecode($process['body']);
309
+
310
+ if ( true === $r['decompress'] && true === WP_Http_Encoding::should_decode($arrHeaders['headers']) )
311
+ $process['body'] = WP_Http_Encoding::decompress( $process['body'] );
312
+
313
+ if ( isset( $r['limit_response_size'] ) && strlen( $process['body'] ) > $r['limit_response_size'] )
314
+ $process['body'] = substr( $process['body'], 0, $r['limit_response_size'] );
315
+
316
+ $response['body'] = $process['body'];
317
+
318
+ return $response;
319
+ }
320
+
321
+ /**
322
+ * Verifies the received SSL certificate against it's Common Names and subjectAltName fields
323
+ *
324
+ * PHP's SSL verifications only verify that it's a valid Certificate, it doesn't verify if
325
+ * the certificate is valid for the hostname which was requested.
326
+ * This function verifies the requested hostname against certificate's subjectAltName field,
327
+ * if that is empty, or contains no DNS entries, a fallback to the Common Name field is used.
328
+ *
329
+ * IP Address support is included if the request is being made to an IP address.
330
+ *
331
+ * @since 3.7.0
332
+ * @static
333
+ *
334
+ * @param stream $stream The PHP Stream which the SSL request is being made over
335
+ * @param string $host The hostname being requested
336
+ * @return bool If the cerficiate presented in $stream is valid for $host
337
+ */
338
+ public static function verify_ssl_certificate( $stream, $host ) {
339
+ $context_options = stream_context_get_options( $stream );
340
+
341
+ if ( empty( $context_options['ssl']['peer_certificate'] ) )
342
+ return false;
343
+
344
+ $cert = openssl_x509_parse( $context_options['ssl']['peer_certificate'] );
345
+ if ( ! $cert )
346
+ return false;
347
+
348
+ /*
349
+ * If the request is being made to an IP address, we'll validate against IP fields
350
+ * in the cert (if they exist)
351
+ */
352
+ $host_type = ( WP_HTTP::is_ip_address( $host ) ? 'ip' : 'dns' );
353
+
354
+ $certificate_hostnames = array();
355
+ if ( ! empty( $cert['extensions']['subjectAltName'] ) ) {
356
+ $match_against = preg_split( '/,\s*/', $cert['extensions']['subjectAltName'] );
357
+ foreach ( $match_against as $match ) {
358
+ list( $match_type, $match_host ) = explode( ':', $match );
359
+ if ( $host_type == strtolower( trim( $match_type ) ) ) // IP: or DNS:
360
+ $certificate_hostnames[] = strtolower( trim( $match_host ) );
361
+ }
362
+ } elseif ( !empty( $cert['subject']['CN'] ) ) {
363
+ // Only use the CN when the certificate includes no subjectAltName extension.
364
+ $certificate_hostnames[] = strtolower( $cert['subject']['CN'] );
365
+ }
366
+
367
+ // Exact hostname/IP matches.
368
+ if ( in_array( strtolower( $host ), $certificate_hostnames ) )
369
+ return true;
370
+
371
+ // IP's can't be wildcards, Stop processing.
372
+ if ( 'ip' == $host_type )
373
+ return false;
374
+
375
+ // Test to see if the domain is at least 2 deep for wildcard support.
376
+ if ( substr_count( $host, '.' ) < 2 )
377
+ return false;
378
+
379
+ // Wildcard subdomains certs (*.example.com) are valid for a.example.com but not a.b.example.com.
380
+ $wildcard_host = preg_replace( '/^[^.]+\./', '*.', $host );
381
+
382
+ return in_array( strtolower( $wildcard_host ), $certificate_hostnames );
383
+ }
384
+
385
+ /**
386
+ * Whether this class can be used for retrieving a URL.
387
+ *
388
+ * @static
389
+ * @access public
390
+ * @since 2.7.0
391
+ * @since 3.7.0 Combined with the fsockopen transport and switched to stream_socket_client().
392
+ *
393
+ * @return bool False means this class can not be used, true means it can.
394
+ */
395
+ public static function test( $args = array() ) {
396
+ if ( ! function_exists( 'stream_socket_client' ) )
397
+ return false;
398
+
399
+ $is_ssl = isset( $args['ssl'] ) && $args['ssl'];
400
+
401
+ if ( $is_ssl ) {
402
+ if ( ! extension_loaded( 'openssl' ) )
403
+ return false;
404
+ if ( ! function_exists( 'openssl_x509_parse' ) )
405
+ return false;
406
+ }
407
+
408
+ /**
409
+ * Filter whether streams can be used as a transport for retrieving a URL.
410
+ *
411
+ * @since 2.7.0
412
+ *
413
+ * @param bool $use_class Whether the class can be used. Default true.
414
+ * @param array $args Request arguments.
415
+ */
416
+ return apply_filters( 'use_streams_transport', true, $args );
417
+ }
418
+ }
loader.php CHANGED
@@ -120,6 +120,10 @@ require_once AI1WM_CONTROLLER_PATH .
120
  DIRECTORY_SEPARATOR .
121
  'class-ai1wm-export-controller.php';
122
 
 
 
 
 
123
  require_once AI1WM_CONTROLLER_PATH .
124
  DIRECTORY_SEPARATOR .
125
  'class-ai1wm-backup-controller.php';
@@ -136,6 +140,14 @@ require_once AI1WM_CONTROLLER_PATH .
136
  DIRECTORY_SEPARATOR .
137
  'class-ai1wm-message-controller.php';
138
 
 
 
 
 
 
 
 
 
139
  require_once AI1WM_MODEL_PATH .
140
  DIRECTORY_SEPARATOR .
141
  'class-ai1wm-backup.php';
@@ -208,6 +220,10 @@ require_once AI1WM_SERVICE_PATH .
208
  DIRECTORY_SEPARATOR .
209
  'class-ai1wm-service-package.php';
210
 
 
 
 
 
211
  require_once AI1WM_EXCEPTION_PATH .
212
  DIRECTORY_SEPARATOR .
213
  'class-ai1wm-backup-exception.php';
120
  DIRECTORY_SEPARATOR .
121
  'class-ai1wm-export-controller.php';
122
 
123
+ require_once AI1WM_CONTROLLER_PATH .
124
+ DIRECTORY_SEPARATOR .
125
+ 'class-ai1wm-resolve-controller.php';
126
+
127
  require_once AI1WM_CONTROLLER_PATH .
128
  DIRECTORY_SEPARATOR .
129
  'class-ai1wm-backup-controller.php';
140
  DIRECTORY_SEPARATOR .
141
  'class-ai1wm-message-controller.php';
142
 
143
+ require_once AI1WM_MODEL_PATH .
144
+ DIRECTORY_SEPARATOR .
145
+ 'class-ai1wm-streams.php';
146
+
147
+ require_once AI1WM_MODEL_PATH .
148
+ DIRECTORY_SEPARATOR .
149
+ 'class-ai1wm-http.php';
150
+
151
  require_once AI1WM_MODEL_PATH .
152
  DIRECTORY_SEPARATOR .
153
  'class-ai1wm-backup.php';
220
  DIRECTORY_SEPARATOR .
221
  'class-ai1wm-service-package.php';
222
 
223
+ require_once AI1WM_EXCEPTION_PATH .
224
+ DIRECTORY_SEPARATOR .
225
+ 'class-ai1wm-http-exception.php';
226
+
227
  require_once AI1WM_EXCEPTION_PATH .
228
  DIRECTORY_SEPARATOR .
229
  'class-ai1wm-backup-exception.php';
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: yani.iliev, bangelov, pimjitsawang
3
  Tags: db migration, migration, wordpress migration, db backup, db restore, website backup, website restore, website migration, website deploy, wordpress deploy, db backup, database export, database serialization, database find replace
4
  Requires at least: 3.3
5
  Tested up to: 4.3
6
- Stable tag: 4.12
7
  License: GPLv2 or later
8
 
9
  All-in-One WP Migration is the only tool that you will ever need to migrate a WordPress site.
@@ -60,6 +60,9 @@ All in One WP Plugin is the first plugin to offer true mobile experience on Word
60
  3. Plugin Menu
61
 
62
  == Changelog ==
 
 
 
63
  = 4.12 =
64
  * Fix an issue with Google Drive extension
65
 
3
  Tags: db migration, migration, wordpress migration, db backup, db restore, website backup, website restore, website migration, website deploy, wordpress deploy, db backup, database export, database serialization, database find replace
4
  Requires at least: 3.3
5
  Tested up to: 4.3
6
+ Stable tag: 4.13
7
  License: GPLv2 or later
8
 
9
  All-in-One WP Migration is the only tool that you will ever need to migrate a WordPress site.
60
  3. Plugin Menu
61
 
62
  == Changelog ==
63
+ = 4.13 =
64
+ * Add new mechanism for resolving HTTP requests
65
+
66
  = 4.12 =
67
  * Fix an issue with Google Drive extension
68
 
uninstall.php CHANGED
@@ -34,11 +34,15 @@ require_once dirname( __FILE__ ) .
34
  if ( defined( 'WP_UNINSTALL_PLUGIN' ) ) {
35
  global $wpdb, $wp_filesystem;
36
 
37
- // delete any options or other data stored in the database here
38
- delete_site_option( AI1WM_MAINTENANCE_MODE );
39
  delete_site_option( AI1WM_EXPORT_OPTIONS );
40
  delete_site_option( AI1WM_ERROR_HANDLER );
41
  delete_site_option( AI1WM_EXCEPTION_HANDLER );
42
- delete_site_option( AI1WM_MESSAGES );
 
 
43
  delete_site_option( AI1WM_SECRET_KEY );
 
 
 
44
  }
34
  if ( defined( 'WP_UNINSTALL_PLUGIN' ) ) {
35
  global $wpdb, $wp_filesystem;
36
 
37
+ // Delete any options or other data stored in the database here
 
38
  delete_site_option( AI1WM_EXPORT_OPTIONS );
39
  delete_site_option( AI1WM_ERROR_HANDLER );
40
  delete_site_option( AI1WM_EXCEPTION_HANDLER );
41
+ delete_site_option( AI1WM_MAINTENANCE_MODE );
42
+ delete_site_option( AI1WM_URL_IP );
43
+ delete_site_option( AI1WM_URL_TRANSPORT );
44
  delete_site_option( AI1WM_SECRET_KEY );
45
+ delete_site_option( AI1WM_AUTH_USER );
46
+ delete_site_option( AI1WM_AUTH_PASSWORD );
47
+ delete_site_option( AI1WM_MESSAGES );
48
  }