Revive Old Posts – Auto Post to Social Media - Version 8.3.1

Version Description

  • 2019-05-24
Download this release

Release Info

Developer codeinwp
Plugin Icon 128x128 Revive Old Posts – Auto Post to Social Media
Version 8.3.1
Comparing to
See all releases

Code changes from version 8.3.0 to 8.3.1

Files changed (116) hide show
  1. CHANGELOG.md +5 -0
  2. includes/admin/services/class-rop-facebook-service.php +19 -39
  3. includes/admin/services/class-rop-linkedin-service.php +5 -5
  4. includes/admin/services/class-rop-pinterest-service.php +1 -1
  5. includes/class-rop-activator.php +27 -25
  6. includes/class-rop-deactivator.php +6 -10
  7. includes/class-rop.php +1 -1
  8. readme.md +6 -0
  9. readme.txt +6 -0
  10. themeisle-hash.json +1 -1
  11. tweet-old-post.php +2 -2
  12. uninstall.php +1 -0
  13. vendor/autoload.php +1 -1
  14. vendor/composer/autoload_files.php +0 -4
  15. vendor/composer/autoload_psr4.php +0 -4
  16. vendor/composer/autoload_real.php +5 -5
  17. vendor/composer/installed.json +0 -283
  18. vendor/guzzlehttp/guzzle/CHANGELOG.md +0 -1287
  19. vendor/guzzlehttp/guzzle/LICENSE +0 -19
  20. vendor/guzzlehttp/guzzle/README.md +0 -91
  21. vendor/guzzlehttp/guzzle/UPGRADING.md +0 -1203
  22. vendor/guzzlehttp/guzzle/src/Client.php +0 -422
  23. vendor/guzzlehttp/guzzle/src/ClientInterface.php +0 -84
  24. vendor/guzzlehttp/guzzle/src/Cookie/CookieJar.php +0 -314
  25. vendor/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php +0 -84
  26. vendor/guzzlehttp/guzzle/src/Cookie/FileCookieJar.php +0 -90
  27. vendor/guzzlehttp/guzzle/src/Cookie/SessionCookieJar.php +0 -71
  28. vendor/guzzlehttp/guzzle/src/Cookie/SetCookie.php +0 -403
  29. vendor/guzzlehttp/guzzle/src/Exception/BadResponseException.php +0 -27
  30. vendor/guzzlehttp/guzzle/src/Exception/ClientException.php +0 -7
  31. vendor/guzzlehttp/guzzle/src/Exception/ConnectException.php +0 -37
  32. vendor/guzzlehttp/guzzle/src/Exception/GuzzleException.php +0 -13
  33. vendor/guzzlehttp/guzzle/src/Exception/RequestException.php +0 -217
  34. vendor/guzzlehttp/guzzle/src/Exception/SeekException.php +0 -27
  35. vendor/guzzlehttp/guzzle/src/Exception/ServerException.php +0 -7
  36. vendor/guzzlehttp/guzzle/src/Exception/TooManyRedirectsException.php +0 -4
  37. vendor/guzzlehttp/guzzle/src/Exception/TransferException.php +0 -4
  38. vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php +0 -565
  39. vendor/guzzlehttp/guzzle/src/Handler/CurlFactoryInterface.php +0 -27
  40. vendor/guzzlehttp/guzzle/src/Handler/CurlHandler.php +0 -45
  41. vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php +0 -199
  42. vendor/guzzlehttp/guzzle/src/Handler/EasyHandle.php +0 -92
  43. vendor/guzzlehttp/guzzle/src/Handler/MockHandler.php +0 -189
  44. vendor/guzzlehttp/guzzle/src/Handler/Proxy.php +0 -55
  45. vendor/guzzlehttp/guzzle/src/Handler/StreamHandler.php +0 -532
  46. vendor/guzzlehttp/guzzle/src/HandlerStack.php +0 -273
  47. vendor/guzzlehttp/guzzle/src/MessageFormatter.php +0 -180
  48. vendor/guzzlehttp/guzzle/src/Middleware.php +0 -255
  49. vendor/guzzlehttp/guzzle/src/Pool.php +0 -123
  50. vendor/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php +0 -106
  51. vendor/guzzlehttp/guzzle/src/RedirectMiddleware.php +0 -237
  52. vendor/guzzlehttp/guzzle/src/RequestOptions.php +0 -255
  53. vendor/guzzlehttp/guzzle/src/RetryMiddleware.php +0 -112
  54. vendor/guzzlehttp/guzzle/src/TransferStats.php +0 -126
  55. vendor/guzzlehttp/guzzle/src/UriTemplate.php +0 -237
  56. vendor/guzzlehttp/guzzle/src/functions.php +0 -333
  57. vendor/guzzlehttp/guzzle/src/functions_include.php +0 -6
  58. vendor/guzzlehttp/promises/CHANGELOG.md +0 -65
  59. vendor/guzzlehttp/promises/LICENSE +0 -19
  60. vendor/guzzlehttp/promises/Makefile +0 -13
  61. vendor/guzzlehttp/promises/README.md +0 -504
  62. vendor/guzzlehttp/promises/src/AggregateException.php +0 -16
  63. vendor/guzzlehttp/promises/src/CancellationException.php +0 -9
  64. vendor/guzzlehttp/promises/src/Coroutine.php +0 -151
  65. vendor/guzzlehttp/promises/src/EachPromise.php +0 -229
  66. vendor/guzzlehttp/promises/src/FulfilledPromise.php +0 -82
  67. vendor/guzzlehttp/promises/src/Promise.php +0 -280
  68. vendor/guzzlehttp/promises/src/PromiseInterface.php +0 -93
  69. vendor/guzzlehttp/promises/src/PromisorInterface.php +0 -15
  70. vendor/guzzlehttp/promises/src/RejectedPromise.php +0 -87
  71. vendor/guzzlehttp/promises/src/RejectionException.php +0 -47
  72. vendor/guzzlehttp/promises/src/TaskQueue.php +0 -66
  73. vendor/guzzlehttp/promises/src/TaskQueueInterface.php +0 -25
  74. vendor/guzzlehttp/promises/src/functions.php +0 -457
  75. vendor/guzzlehttp/promises/src/functions_include.php +0 -6
  76. vendor/guzzlehttp/psr7/CHANGELOG.md +0 -225
  77. vendor/guzzlehttp/psr7/LICENSE +0 -19
  78. vendor/guzzlehttp/psr7/README.md +0 -745
  79. vendor/guzzlehttp/psr7/src/AppendStream.php +0 -241
  80. vendor/guzzlehttp/psr7/src/BufferStream.php +0 -137
  81. vendor/guzzlehttp/psr7/src/CachingStream.php +0 -138
  82. vendor/guzzlehttp/psr7/src/DroppingStream.php +0 -42
  83. vendor/guzzlehttp/psr7/src/FnStream.php +0 -158
  84. vendor/guzzlehttp/psr7/src/InflateStream.php +0 -52
  85. vendor/guzzlehttp/psr7/src/LazyOpenStream.php +0 -39
  86. vendor/guzzlehttp/psr7/src/LimitStream.php +0 -155
  87. vendor/guzzlehttp/psr7/src/MessageTrait.php +0 -183
  88. vendor/guzzlehttp/psr7/src/MultipartStream.php +0 -153
  89. vendor/guzzlehttp/psr7/src/NoSeekStream.php +0 -22
  90. vendor/guzzlehttp/psr7/src/PumpStream.php +0 -165
  91. vendor/guzzlehttp/psr7/src/Request.php +0 -142
  92. vendor/guzzlehttp/psr7/src/Response.php +0 -136
  93. vendor/guzzlehttp/psr7/src/Rfc7230.php +0 -18
  94. vendor/guzzlehttp/psr7/src/ServerRequest.php +0 -376
  95. vendor/guzzlehttp/psr7/src/Stream.php +0 -270
  96. vendor/guzzlehttp/psr7/src/StreamDecoratorTrait.php +0 -149
  97. vendor/guzzlehttp/psr7/src/StreamWrapper.php +0 -161
  98. vendor/guzzlehttp/psr7/src/UploadedFile.php +0 -316
  99. vendor/guzzlehttp/psr7/src/Uri.php +0 -738
  100. vendor/guzzlehttp/psr7/src/UriNormalizer.php +0 -216
  101. vendor/guzzlehttp/psr7/src/UriResolver.php +0 -219
  102. vendor/guzzlehttp/psr7/src/functions.php +0 -898
  103. vendor/guzzlehttp/psr7/src/functions_include.php +0 -6
  104. vendor/psr/http-message/CHANGELOG.md +0 -36
  105. vendor/psr/http-message/LICENSE +0 -19
  106. vendor/psr/http-message/README.md +0 -13
  107. vendor/psr/http-message/src/MessageInterface.php +0 -187
  108. vendor/psr/http-message/src/RequestInterface.php +0 -129
  109. vendor/psr/http-message/src/ResponseInterface.php +0 -68
  110. vendor/psr/http-message/src/ServerRequestInterface.php +0 -261
  111. vendor/psr/http-message/src/StreamInterface.php +0 -158
  112. vendor/psr/http-message/src/UploadedFileInterface.php +0 -123
  113. vendor/psr/http-message/src/UriInterface.php +0 -323
  114. vendor/ralouphie/getallheaders/LICENSE +0 -21
  115. vendor/ralouphie/getallheaders/README.md +0 -19
  116. vendor/ralouphie/getallheaders/src/getallheaders.php +0 -46
CHANGELOG.md CHANGED
@@ -1,4 +1,9 @@
1
 
 
 
 
 
 
2
  ### v8.3.0 - 2019-05-24
3
  **Changes:**
4
  * New: Made connecting Facebook pages to plugin much simpler.
1
 
2
+ ### v8.3.1 - 2019-05-24
3
+ **Changes:**
4
+ * Fix: Use wp_remote_request functions in favor of guzzle which was causing issues on some websites
5
+ * Fix: Posting to Pinterest board names with commas
6
+
7
  ### v8.3.0 - 2019-05-24
8
  **Changes:**
9
  * New: Made connecting Facebook pages to plugin much simpler.
includes/admin/services/class-rop-facebook-service.php CHANGED
@@ -683,11 +683,6 @@ class Rop_Facebook_Service extends Rop_Services_Abstract {
683
  // Page was added using ROP application (new method)
684
  // Try post via Guzzle 6
685
 
686
- if ( ! class_exists( 'GuzzleHttp\Client' ) ) {
687
- $this->logger->alert_error( 'Error: Cannot find Guzzle' );
688
- return;
689
- }
690
-
691
  $post_data = $new_post;
692
  $post_data['access_token'] = $token;
693
 
@@ -697,42 +692,27 @@ class Rop_Facebook_Service extends Rop_Services_Abstract {
697
  $url = 'https://graph.facebook.com' . $path;
698
  }
699
 
700
- $client = new GuzzleHttp\Client( ['headers' => ['Content-Type' => 'application/x-www-form-urlencoded']] );
 
 
701
 
702
- try {
703
- $client->request(
704
- 'POST',
705
- $url,
706
- [
707
- 'form_params' => $post_data,
708
- ]
709
- );
710
- return true;
711
 
712
- } catch ( GuzzleHttp\Exception\GuzzleException $e ) {
713
- $errorCode = $e->getCode();
714
- $errorMsg = $e->getMessage();
715
- if ( $errorCode === 400 && strpos( $errorMsg, '(#100)' ) !== false && ! empty( $post_data['name'] ) ) {
716
- // retry without name
717
- unset( $post_data['name'] );
718
- try {
719
- $client->request(
720
- 'POST',
721
- $url,
722
- [
723
- 'form_params' => $post_data,
724
- ]
725
- );
726
- return true;
727
- } catch ( GuzzleHttp\Exception\GuzzleException $e ) {
728
- $errorMsg = $e->getMessage();
729
- $this->logger->alert_error( 'Unable to share post for facebook. ' . $errorMsg );
730
- $this->rop_get_error_docs( $errorMsg );
731
- }
732
- } else {
733
- $this->logger->alert_error( 'Unable to share post for facebook. ' . $errorMsg );
734
- $this->rop_get_error_docs( $errorMsg );
735
- }
736
  }
737
  }
738
  }
683
  // Page was added using ROP application (new method)
684
  // Try post via Guzzle 6
685
 
 
 
 
 
 
686
  $post_data = $new_post;
687
  $post_data['access_token'] = $token;
688
 
692
  $url = 'https://graph.facebook.com' . $path;
693
  }
694
 
695
+ $response = wp_remote_post(
696
+ $url,
697
+ array(
698
 
699
+ 'body' => $post_data,
700
+ 'headers' => array(
701
+ 'Content-Type' => 'application/x-www-form-urlencoded',
702
+ ),
 
 
 
 
 
703
 
704
+ )
705
+ );
706
+
707
+ $body = json_decode( wp_remote_retrieve_body( $response ), true );
708
+
709
+ // Facebook only returns id if successful
710
+ if ( ! empty( $body['id'] ) ) {
711
+ return true;
712
+ } else {
713
+ $this->logger->alert_error( 'Error Posting to Facebook: ' . $body['error']['message'] );
714
+ $this->rop_get_error_docs( $body['error']['message'] );
715
+ return false;
 
 
 
 
 
 
 
 
 
 
 
 
716
  }
717
  }
718
  }
includes/admin/services/class-rop-linkedin-service.php CHANGED
@@ -435,14 +435,16 @@ class Rop_Linkedin_Service extends Rop_Services_Abstract {
435
  if ( empty( $post_details['post_image'] ) ) {
436
  $new_post = $this->linkedin_article_post( $post_details, $args );
437
  } else {
438
- $new_post = $this->linkedin_image_post( $post_details, $args, $token, $api );
 
439
  }
440
  } elseif ( get_post_type( $post_details['post_id'] ) === 'attachment' ) {
441
  // Linkedin Api v2 doesn't support video upload. Share as article post
442
  if ( strpos( get_post_mime_type( $post_details['post_id'] ), 'video' ) !== false ) {
443
  $new_post = $this->linkedin_article_post( $post_details, $args );
444
  } else {
445
- $new_post = $this->linkedin_image_post( $post_details, $args, $token, $api );
 
446
  }
447
  }
448
 
@@ -484,8 +486,6 @@ class Rop_Linkedin_Service extends Rop_Services_Abstract {
484
  */
485
  private function linkedin_article_post( $post_details, $args ) {
486
 
487
- $video_post = strpos( get_post_mime_type( $post_details['post_id'] ), 'video' );
488
-
489
  $new_post = array (
490
  'author' => 'urn:li:person:' . $args['id'],
491
  'lifecycleState' => 'PUBLISHED',
@@ -507,7 +507,7 @@ class Rop_Linkedin_Service extends Rop_Services_Abstract {
507
  array (
508
  'text' => $this->strip_excess_blank_lines( $post_details['content'] ),
509
  ),
510
- 'originalUrl' => ( $video_post === false ) ? trim( $this->get_url( $post_details ) ) : get_permalink( $post_details['post_id'] ),
511
  'title' =>
512
  array (
513
  'text' => html_entity_decode( get_the_title( $post_details['post_id'] ) ),
435
  if ( empty( $post_details['post_image'] ) ) {
436
  $new_post = $this->linkedin_article_post( $post_details, $args );
437
  } else {
438
+ $new_post = $this->linkedin_article_post( $post_details, $args );
439
+ // $new_post = $this->linkedin_image_post( $post_details, $args, $token, $api );
440
  }
441
  } elseif ( get_post_type( $post_details['post_id'] ) === 'attachment' ) {
442
  // Linkedin Api v2 doesn't support video upload. Share as article post
443
  if ( strpos( get_post_mime_type( $post_details['post_id'] ), 'video' ) !== false ) {
444
  $new_post = $this->linkedin_article_post( $post_details, $args );
445
  } else {
446
+ $new_post = $this->linkedin_article_post( $post_details, $args );
447
+ // $new_post = $this->linkedin_image_post( $post_details, $args, $token, $api );
448
  }
449
  }
450
 
486
  */
487
  private function linkedin_article_post( $post_details, $args ) {
488
 
 
 
489
  $new_post = array (
490
  'author' => 'urn:li:person:' . $args['id'],
491
  'lifecycleState' => 'PUBLISHED',
507
  array (
508
  'text' => $this->strip_excess_blank_lines( $post_details['content'] ),
509
  ),
510
+ 'originalUrl' => trim( $this->get_url( $post_details ) ),
511
  'title' =>
512
  array (
513
  'text' => html_entity_decode( get_the_title( $post_details['post_id'] ) ),
includes/admin/services/class-rop-pinterest-service.php CHANGED
@@ -285,7 +285,7 @@ class Rop_Pinterest_Service extends Rop_Services_Abstract {
285
  )
286
  );
287
 
288
- $search = array( ' ', '.', '/', '!', '@', '&', '#', '%', '*', '(', ')', '{', '}', '[', ']', '|', '\\', '$' );
289
  $replace = array( '-', '' );
290
 
291
  foreach ( $boards as $board ) {
285
  )
286
  );
287
 
288
+ $search = array( ' ', '.', ',', '/', '!', '@', '&', '#', '%', '*', '(', ')', '{', '}', '[', ']', '|', '\\', '$' );
289
  $replace = array( '-', '' );
290
 
291
  foreach ( $boards as $board ) {
includes/class-rop-activator.php CHANGED
@@ -62,40 +62,42 @@ class Rop_Activator {
62
 
63
  $logger = new Rop_Logger();
64
 
65
- if ( ! class_exists( 'GuzzleHttp\Client' ) ) {
66
- $logger->alert_error( 'Error: Cannot find Guzzle' );
67
- return;
 
 
 
 
 
68
  }
69
 
70
- $client = new GuzzleHttp\Client();
71
-
72
- try {
73
- $app_url = ROP_AUTH_APP_URL . ROP_APP_ACTIVATION_PATH;
74
-
75
- if ( isset( $_SERVER['HTTPS'] ) && $_SERVER['HTTPS'] === 'on' ) {
76
- $protocol = 'https';
77
- } elseif ( ! empty( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https' ) {
78
- $protocol = 'https';
79
- } else {
80
- $protocol = 'http';
81
- }
82
-
83
  $current_url = $protocol . '://' . $_SERVER['HTTP_HOST'];
84
  $email = base64_encode( get_option( 'admin_email' ) );
85
 
86
- // Get unique token
87
- $response = $client->request( 'GET', $app_url . '?activate=true&url=' . $current_url . '&data=' . $email );
88
- $token = $response->getBody()->getContents();
 
 
 
 
 
 
 
 
 
 
 
89
 
90
- if ( ! get_option( ROP_APP_TOKEN_OPTION ) ) {
91
  $deprecated = ' ';
92
  $autoload = 'no';
93
  add_option( ROP_APP_TOKEN_OPTION, $token, $deprecated, $autoload );
94
- } else {
95
- update_option( ROP_APP_TOKEN_OPTION, $token );
96
- }
97
- } catch ( GuzzleHttp\Exception\GuzzleException $e ) {
98
- $logger->alert_error( 'Error ' . $e->getCode() . '. ' . $e->getMessage() . "\n" . $e->getTrace() );
99
  }
100
 
101
  }
62
 
63
  $logger = new Rop_Logger();
64
 
65
+ $app_url = ROP_AUTH_APP_URL . ROP_APP_ACTIVATION_PATH;
66
+
67
+ if ( isset( $_SERVER['HTTPS'] ) && $_SERVER['HTTPS'] === 'on' ) {
68
+ $protocol = 'https';
69
+ } elseif ( ! empty( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https' ) {
70
+ $protocol = 'https';
71
+ } else {
72
+ $protocol = 'http';
73
  }
74
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
  $current_url = $protocol . '://' . $_SERVER['HTTP_HOST'];
76
  $email = base64_encode( get_option( 'admin_email' ) );
77
 
78
+ // Get unique token
79
+ $response = wp_remote_get( $app_url . '?activate=true&url=' . $current_url . '&data=' . $email . '&time=' . time() );
80
+ $token = wp_remote_retrieve_body( $response );
81
+ if ( empty( $token ) ) {
82
+ $logger->alert_error( 'There was an error creating your install token. Please send us a support ticket. Error:' . print_r( $response, true ) );
83
+ }
84
+
85
+ if ( strpos( $token, 'Rate Limited' ) !== false ) {
86
+ $logger->alert_error( 'Rate limited, please wait a few minutes then deactivate and reactivate ROP to recieve your install token (Needed to log into Facebook). ' );
87
+ }
88
+
89
+ if ( is_wp_error( $response ) ) {
90
+ $logger->alert_error( 'There was an error creating your token. Please send us a support ticket: ' . $response->get_error_message() );
91
+ }
92
 
93
+ if ( empty( get_option( ROP_APP_TOKEN_OPTION ) ) ) {
94
  $deprecated = ' ';
95
  $autoload = 'no';
96
  add_option( ROP_APP_TOKEN_OPTION, $token, $deprecated, $autoload );
97
+ } else {
98
+ // delete old token incase plugin was installed/uninstalled dirty
99
+ wp_remote_get( $app_url . '?deactivate=true&token=' . get_option( ROP_APP_TOKEN_OPTION ) . '&time=' . time() );
100
+ update_option( ROP_APP_TOKEN_OPTION, $token );
 
101
  }
102
 
103
  }
includes/class-rop-deactivator.php CHANGED
@@ -41,18 +41,14 @@ class Rop_Deactivator {
41
  */
42
  $logger = new Rop_Logger();
43
 
44
- if ( ! class_exists( 'GuzzleHttp\Client' ) ) {
45
- $logger->alert_error( 'Error: Cannot find Guzzle' );
46
- return;
47
- }
48
-
49
- $client = new GuzzleHttp\Client();
50
 
51
- try {
52
- $response = $client->request( 'GET', ROP_AUTH_APP_URL . ROP_APP_ACTIVATION_PATH . '?deactivate=true&token=' . get_option( ROP_APP_TOKEN_OPTION ) );
53
- } catch ( GuzzleHttp\Exception\GuzzleException $e ) {
54
- $logger->alert_error( 'Error ' . $e->getCode() . '. ' . $e->getMessage() . "\n" . $e->getTrace() );
55
  }
 
56
  }
57
 
58
  }
41
  */
42
  $logger = new Rop_Logger();
43
 
44
+ $app_url = ROP_AUTH_APP_URL . ROP_APP_ACTIVATION_PATH;
45
+ $response = wp_remote_get( $app_url . '?deactivate=true&token=' . get_option( ROP_APP_TOKEN_OPTION ) . '&time=' . time() );
46
+ delete_option( ROP_APP_TOKEN_OPTION );
 
 
 
47
 
48
+ if ( is_wp_error( $response ) ) {
49
+ $logger->alert_error( 'There was an error deleting your token: ' . $response->get_error_message() );
 
 
50
  }
51
+
52
  }
53
 
54
  }
includes/class-rop.php CHANGED
@@ -68,7 +68,7 @@ class Rop {
68
  public function __construct() {
69
 
70
  $this->plugin_name = 'rop';
71
- $this->version = '8.3.0';
72
 
73
  $this->load_dependencies();
74
  $this->set_locale();
68
  public function __construct() {
69
 
70
  $this->plugin_name = 'rop';
71
+ $this->version = '8.3.1';
72
 
73
  $this->load_dependencies();
74
  $this->set_locale();
readme.md CHANGED
@@ -134,6 +134,12 @@ http://revive.social/plugins/revive-old-post
134
 
135
 
136
  ## Changelog ##
 
 
 
 
 
 
137
  ### 8.3.0 - 2019-05-24 ###
138
 
139
  * New: Made connecting Facebook pages to plugin much simpler.
134
 
135
 
136
  ## Changelog ##
137
+ ### 8.3.1 - 2019-05-24 ###
138
+
139
+ * Fix: Use wp_remote_request functions in favor of guzzle which was causing issues on some websites
140
+ * Fix: Posting to Pinterest board names with commas
141
+
142
+
143
  ### 8.3.0 - 2019-05-24 ###
144
 
145
  * New: Made connecting Facebook pages to plugin much simpler.
readme.txt CHANGED
@@ -134,6 +134,12 @@ http://revive.social/plugins/revive-old-post
134
 
135
 
136
  == Changelog ==
 
 
 
 
 
 
137
  = 8.3.0 - 2019-05-24 =
138
 
139
  * New: Made connecting Facebook pages to plugin much simpler.
134
 
135
 
136
  == Changelog ==
137
+ = 8.3.1 - 2019-05-24 =
138
+
139
+ * Fix: Use wp_remote_request functions in favor of guzzle which was causing issues on some websites
140
+ * Fix: Posting to Pinterest board names with commas
141
+
142
+
143
  = 8.3.0 - 2019-05-24 =
144
 
145
  * New: Made connecting Facebook pages to plugin much simpler.
themeisle-hash.json CHANGED
@@ -1 +1 @@
1
- {"class-rop-autoloader.php":"7bfbb1554230d0ace777adb2e42bebeb","index.php":"39ab8276fb0e4bd3fcab3270822c5977","tweet-old-post.php":"dade52911a61c76388d9a31c64219146","uninstall.php":"0a431fe452d74ecbd9736908f34c07f6"}
1
+ {"class-rop-autoloader.php":"7bfbb1554230d0ace777adb2e42bebeb","index.php":"39ab8276fb0e4bd3fcab3270822c5977","tweet-old-post.php":"7752322337330f9249e8f885d62e0e29","uninstall.php":"9fc5df63a7d12a224ae1c02f12e0e930"}
tweet-old-post.php CHANGED
@@ -16,7 +16,7 @@
16
  * Plugin Name: Revive Old Posts
17
  * Plugin URI: https://revive.social/
18
  * Description: WordPress plugin that helps you to keeps your old posts alive by sharing them and driving more traffic to them from twitter/facebook or linkedin. It also helps you to promote your content. You can set time and no of posts to share to drive more traffic.For questions, comments, or feature requests, <a href="http://revive.social/support/?utm_source=plugindesc&utm_medium=announce&utm_campaign=top">contact </a> us!
19
- * Version: 8.3.0
20
  * Author: revive.social
21
  * Author URI: https://revive.social/
22
  * Requires at least: 3.5
@@ -98,7 +98,7 @@ function run_rop() {
98
  }
99
 
100
  define( 'ROP_PRO_URL', 'http://revive.social/plugins/revive-old-post/' );
101
- define( 'ROP_LITE_VERSION', '8.3.0' );
102
  define( 'ROP_LITE_BASE_FILE', __FILE__ );
103
  define( 'ROP_DEBUG', false );
104
  define( 'ROP_LITE_PATH', plugin_dir_path( __FILE__ ) );
16
  * Plugin Name: Revive Old Posts
17
  * Plugin URI: https://revive.social/
18
  * Description: WordPress plugin that helps you to keeps your old posts alive by sharing them and driving more traffic to them from twitter/facebook or linkedin. It also helps you to promote your content. You can set time and no of posts to share to drive more traffic.For questions, comments, or feature requests, <a href="http://revive.social/support/?utm_source=plugindesc&utm_medium=announce&utm_campaign=top">contact </a> us!
19
+ * Version: 8.3.1
20
  * Author: revive.social
21
  * Author URI: https://revive.social/
22
  * Requires at least: 3.5
98
  }
99
 
100
  define( 'ROP_PRO_URL', 'http://revive.social/plugins/revive-old-post/' );
101
+ define( 'ROP_LITE_VERSION', '8.3.1' );
102
  define( 'ROP_LITE_BASE_FILE', __FILE__ );
103
  define( 'ROP_DEBUG', false );
104
  define( 'ROP_LITE_PATH', plugin_dir_path( __FILE__ ) );
uninstall.php CHANGED
@@ -60,6 +60,7 @@ if ( isset( $housekeeping ) && $housekeeping ) {
60
 
61
  delete_metadata( 'user', 0, 'rop_publish_now_notice_dismissed', '', true );
62
  delete_metadata( 'user', 0, 'rop-linkedin-api-notice-dismissed', '', true );
 
63
 
64
  global $wpdb;
65
  $post_meta = $wpdb->prefix . 'postmeta';
60
 
61
  delete_metadata( 'user', 0, 'rop_publish_now_notice_dismissed', '', true );
62
  delete_metadata( 'user', 0, 'rop-linkedin-api-notice-dismissed', '', true );
63
+ delete_metadata( 'user', 0, 'rop-wp-cron-notice-dismissed', '', true );
64
 
65
  global $wpdb;
66
  $post_meta = $wpdb->prefix . 'postmeta';
vendor/autoload.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once __DIR__ . '/composer' . '/autoload_real.php';
6
 
7
- return ComposerAutoloaderInit25417b904ec1d05f984cada22653a862::getLoader();
4
 
5
  require_once __DIR__ . '/composer' . '/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInitf56f4914d0c764f779fb9960719c4e6b::getLoader();
vendor/composer/autoload_files.php CHANGED
@@ -6,10 +6,6 @@ $vendorDir = dirname(dirname(__FILE__));
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
9
- '7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php',
10
- 'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php',
11
- 'a0edc8309cc5e1d60e3047b5df6b7052' => $vendorDir . '/guzzlehttp/psr7/src/functions_include.php',
12
- '37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php',
13
  'c65d09b6820da036953a371c8c73a9b1' => $vendorDir . '/facebook/graph-sdk/src/Facebook/polyfills.php',
14
  '36c24edf14e0462467180307deb4c41f' => $vendorDir . '/codeinwp/themeisle-sdk/load.php',
15
  );
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
 
 
 
 
9
  'c65d09b6820da036953a371c8c73a9b1' => $vendorDir . '/facebook/graph-sdk/src/Facebook/polyfills.php',
10
  '36c24edf14e0462467180307deb4c41f' => $vendorDir . '/codeinwp/themeisle-sdk/load.php',
11
  );
vendor/composer/autoload_psr4.php CHANGED
@@ -7,11 +7,7 @@ $baseDir = dirname($vendorDir);
7
 
8
  return array(
9
  'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
10
- 'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src'),
11
  'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'),
12
- 'GuzzleHttp\\Psr7\\' => array($vendorDir . '/guzzlehttp/psr7/src'),
13
- 'GuzzleHttp\\Promise\\' => array($vendorDir . '/guzzlehttp/promises/src'),
14
- 'GuzzleHttp\\' => array($vendorDir . '/guzzlehttp/guzzle/src'),
15
  'Facebook\\' => array($vendorDir . '/facebook/graph-sdk/src/Facebook'),
16
  'Abraham\\TwitterOAuth\\' => array($vendorDir . '/abraham/twitteroauth/src'),
17
  );
7
 
8
  return array(
9
  'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
 
10
  'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'),
 
 
 
11
  'Facebook\\' => array($vendorDir . '/facebook/graph-sdk/src/Facebook'),
12
  'Abraham\\TwitterOAuth\\' => array($vendorDir . '/abraham/twitteroauth/src'),
13
  );
vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInit25417b904ec1d05f984cada22653a862
6
  {
7
  private static $loader;
8
 
@@ -19,9 +19,9 @@ class ComposerAutoloaderInit25417b904ec1d05f984cada22653a862
19
  return self::$loader;
20
  }
21
 
22
- spl_autoload_register(array('ComposerAutoloaderInit25417b904ec1d05f984cada22653a862', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
- spl_autoload_unregister(array('ComposerAutoloaderInit25417b904ec1d05f984cada22653a862', 'loadClassLoader'));
25
 
26
  $map = require __DIR__ . '/autoload_namespaces.php';
27
  foreach ($map as $namespace => $path) {
@@ -42,14 +42,14 @@ class ComposerAutoloaderInit25417b904ec1d05f984cada22653a862
42
 
43
  $includeFiles = require __DIR__ . '/autoload_files.php';
44
  foreach ($includeFiles as $fileIdentifier => $file) {
45
- composerRequire25417b904ec1d05f984cada22653a862($fileIdentifier, $file);
46
  }
47
 
48
  return $loader;
49
  }
50
  }
51
 
52
- function composerRequire25417b904ec1d05f984cada22653a862($fileIdentifier, $file)
53
  {
54
  if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
55
  require $file;
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
+ class ComposerAutoloaderInitf56f4914d0c764f779fb9960719c4e6b
6
  {
7
  private static $loader;
8
 
19
  return self::$loader;
20
  }
21
 
22
+ spl_autoload_register(array('ComposerAutoloaderInitf56f4914d0c764f779fb9960719c4e6b', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInitf56f4914d0c764f779fb9960719c4e6b', 'loadClassLoader'));
25
 
26
  $map = require __DIR__ . '/autoload_namespaces.php';
27
  foreach ($map as $namespace => $path) {
42
 
43
  $includeFiles = require __DIR__ . '/autoload_files.php';
44
  foreach ($includeFiles as $fileIdentifier => $file) {
45
+ composerRequiref56f4914d0c764f779fb9960719c4e6b($fileIdentifier, $file);
46
  }
47
 
48
  return $loader;
49
  }
50
  }
51
 
52
+ function composerRequiref56f4914d0c764f779fb9960719c4e6b($fileIdentifier, $file)
53
  {
54
  if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
55
  require $file;
vendor/composer/installed.json CHANGED
@@ -115,289 +115,6 @@
115
  "sdk"
116
  ]
117
  },
118
- {
119
- "name": "guzzlehttp/promises",
120
- "version": "v1.3.1",
121
- "version_normalized": "1.3.1.0",
122
- "source": {
123
- "type": "git",
124
- "url": "https://github.com/guzzle/promises.git",
125
- "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646"
126
- },
127
- "dist": {
128
- "type": "zip",
129
- "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646",
130
- "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646",
131
- "shasum": ""
132
- },
133
- "require": {
134
- "php": ">=5.5.0"
135
- },
136
- "require-dev": {
137
- "phpunit/phpunit": "^4.0"
138
- },
139
- "time": "2016-12-20 10:07:11",
140
- "type": "library",
141
- "extra": {
142
- "branch-alias": {
143
- "dev-master": "1.4-dev"
144
- }
145
- },
146
- "installation-source": "dist",
147
- "autoload": {
148
- "psr-4": {
149
- "GuzzleHttp\\Promise\\": "src/"
150
- },
151
- "files": [
152
- "src/functions_include.php"
153
- ]
154
- },
155
- "notification-url": "https://packagist.org/downloads/",
156
- "license": [
157
- "MIT"
158
- ],
159
- "authors": [
160
- {
161
- "name": "Michael Dowling",
162
- "email": "mtdowling@gmail.com",
163
- "homepage": "https://github.com/mtdowling"
164
- }
165
- ],
166
- "description": "Guzzle promises library",
167
- "keywords": [
168
- "promise"
169
- ]
170
- },
171
- {
172
- "name": "ralouphie/getallheaders",
173
- "version": "2.0.5",
174
- "version_normalized": "2.0.5.0",
175
- "source": {
176
- "type": "git",
177
- "url": "https://github.com/ralouphie/getallheaders.git",
178
- "reference": "5601c8a83fbba7ef674a7369456d12f1e0d0eafa"
179
- },
180
- "dist": {
181
- "type": "zip",
182
- "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/5601c8a83fbba7ef674a7369456d12f1e0d0eafa",
183
- "reference": "5601c8a83fbba7ef674a7369456d12f1e0d0eafa",
184
- "shasum": ""
185
- },
186
- "require": {
187
- "php": ">=5.3"
188
- },
189
- "require-dev": {
190
- "phpunit/phpunit": "~3.7.0",
191
- "satooshi/php-coveralls": ">=1.0"
192
- },
193
- "time": "2016-02-11 07:05:27",
194
- "type": "library",
195
- "installation-source": "dist",
196
- "autoload": {
197
- "files": [
198
- "src/getallheaders.php"
199
- ]
200
- },
201
- "notification-url": "https://packagist.org/downloads/",
202
- "license": [
203
- "MIT"
204
- ],
205
- "authors": [
206
- {
207
- "name": "Ralph Khattar",
208
- "email": "ralph.khattar@gmail.com"
209
- }
210
- ],
211
- "description": "A polyfill for getallheaders."
212
- },
213
- {
214
- "name": "psr/http-message",
215
- "version": "1.0.1",
216
- "version_normalized": "1.0.1.0",
217
- "source": {
218
- "type": "git",
219
- "url": "https://github.com/php-fig/http-message.git",
220
- "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
221
- },
222
- "dist": {
223
- "type": "zip",
224
- "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
225
- "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
226
- "shasum": ""
227
- },
228
- "require": {
229
- "php": ">=5.3.0"
230
- },
231
- "time": "2016-08-06 14:39:51",
232
- "type": "library",
233
- "extra": {
234
- "branch-alias": {
235
- "dev-master": "1.0.x-dev"
236
- }
237
- },
238
- "installation-source": "dist",
239
- "autoload": {
240
- "psr-4": {
241
- "Psr\\Http\\Message\\": "src/"
242
- }
243
- },
244
- "notification-url": "https://packagist.org/downloads/",
245
- "license": [
246
- "MIT"
247
- ],
248
- "authors": [
249
- {
250
- "name": "PHP-FIG",
251
- "homepage": "http://www.php-fig.org/"
252
- }
253
- ],
254
- "description": "Common interface for HTTP messages",
255
- "homepage": "https://github.com/php-fig/http-message",
256
- "keywords": [
257
- "http",
258
- "http-message",
259
- "psr",
260
- "psr-7",
261
- "request",
262
- "response"
263
- ]
264
- },
265
- {
266
- "name": "guzzlehttp/psr7",
267
- "version": "1.5.2",
268
- "version_normalized": "1.5.2.0",
269
- "source": {
270
- "type": "git",
271
- "url": "https://github.com/guzzle/psr7.git",
272
- "reference": "9f83dded91781a01c63574e387eaa769be769115"
273
- },
274
- "dist": {
275
- "type": "zip",
276
- "url": "https://api.github.com/repos/guzzle/psr7/zipball/9f83dded91781a01c63574e387eaa769be769115",
277
- "reference": "9f83dded91781a01c63574e387eaa769be769115",
278
- "shasum": ""
279
- },
280
- "require": {
281
- "php": ">=5.4.0",
282
- "psr/http-message": "~1.0",
283
- "ralouphie/getallheaders": "^2.0.5"
284
- },
285
- "provide": {
286
- "psr/http-message-implementation": "1.0"
287
- },
288
- "require-dev": {
289
- "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8"
290
- },
291
- "time": "2018-12-04 20:46:45",
292
- "type": "library",
293
- "extra": {
294
- "branch-alias": {
295
- "dev-master": "1.5-dev"
296
- }
297
- },
298
- "installation-source": "dist",
299
- "autoload": {
300
- "psr-4": {
301
- "GuzzleHttp\\Psr7\\": "src/"
302
- },
303
- "files": [
304
- "src/functions_include.php"
305
- ]
306
- },
307
- "notification-url": "https://packagist.org/downloads/",
308
- "license": [
309
- "MIT"
310
- ],
311
- "authors": [
312
- {
313
- "name": "Michael Dowling",
314
- "email": "mtdowling@gmail.com",
315
- "homepage": "https://github.com/mtdowling"
316
- },
317
- {
318
- "name": "Tobias Schultze",
319
- "homepage": "https://github.com/Tobion"
320
- }
321
- ],
322
- "description": "PSR-7 message implementation that also provides common utility methods",
323
- "keywords": [
324
- "http",
325
- "message",
326
- "psr-7",
327
- "request",
328
- "response",
329
- "stream",
330
- "uri",
331
- "url"
332
- ]
333
- },
334
- {
335
- "name": "guzzlehttp/guzzle",
336
- "version": "6.3.3",
337
- "version_normalized": "6.3.3.0",
338
- "source": {
339
- "type": "git",
340
- "url": "https://github.com/guzzle/guzzle.git",
341
- "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba"
342
- },
343
- "dist": {
344
- "type": "zip",
345
- "url": "https://api.github.com/repos/guzzle/guzzle/zipball/407b0cb880ace85c9b63c5f9551db498cb2d50ba",
346
- "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba",
347
- "shasum": ""
348
- },
349
- "require": {
350
- "guzzlehttp/promises": "^1.0",
351
- "guzzlehttp/psr7": "^1.4",
352
- "php": ">=5.5"
353
- },
354
- "require-dev": {
355
- "ext-curl": "*",
356
- "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0",
357
- "psr/log": "^1.0"
358
- },
359
- "suggest": {
360
- "psr/log": "Required for using the Log middleware"
361
- },
362
- "time": "2018-04-22 15:46:56",
363
- "type": "library",
364
- "extra": {
365
- "branch-alias": {
366
- "dev-master": "6.3-dev"
367
- }
368
- },
369
- "installation-source": "dist",
370
- "autoload": {
371
- "files": [
372
- "src/functions_include.php"
373
- ],
374
- "psr-4": {
375
- "GuzzleHttp\\": "src/"
376
- }
377
- },
378
- "notification-url": "https://packagist.org/downloads/",
379
- "license": [
380
- "MIT"
381
- ],
382
- "authors": [
383
- {
384
- "name": "Michael Dowling",
385
- "email": "mtdowling@gmail.com",
386
- "homepage": "https://github.com/mtdowling"
387
- }
388
- ],
389
- "description": "Guzzle is a PHP HTTP client library",
390
- "homepage": "http://guzzlephp.org/",
391
- "keywords": [
392
- "client",
393
- "curl",
394
- "framework",
395
- "http",
396
- "http client",
397
- "rest",
398
- "web service"
399
- ]
400
- },
401
  {
402
  "name": "psr/log",
403
  "version": "1.1.0",
115
  "sdk"
116
  ]
117
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
  {
119
  "name": "psr/log",
120
  "version": "1.1.0",
vendor/guzzlehttp/guzzle/CHANGELOG.md DELETED
@@ -1,1287 +0,0 @@
1
- # Change Log
2
-
3
- ## 6.3.3 - 2018-04-22
4
-
5
- * Fix: Default headers when decode_content is specified
6
-
7
-
8
- ## 6.3.2 - 2018-03-26
9
-
10
- * Fix: Release process
11
-
12
-
13
- ## 6.3.1 - 2018-03-26
14
-
15
- * Bug fix: Parsing 0 epoch expiry times in cookies [#2014](https://github.com/guzzle/guzzle/pull/2014)
16
- * Improvement: Better ConnectException detection [#2012](https://github.com/guzzle/guzzle/pull/2012)
17
- * Bug fix: Malformed domain that contains a "/" [#1999](https://github.com/guzzle/guzzle/pull/1999)
18
- * Bug fix: Undefined offset when a cookie has no first key-value pair [#1998](https://github.com/guzzle/guzzle/pull/1998)
19
- * Improvement: Support PHPUnit 6 [#1953](https://github.com/guzzle/guzzle/pull/1953)
20
- * Bug fix: Support empty headers [#1915](https://github.com/guzzle/guzzle/pull/1915)
21
- * Bug fix: Ignore case during header modifications [#1916](https://github.com/guzzle/guzzle/pull/1916)
22
-
23
- + Minor code cleanups, documentation fixes and clarifications.
24
-
25
-
26
- ## 6.3.0 - 2017-06-22
27
-
28
- * Feature: force IP resolution (ipv4 or ipv6) [#1608](https://github.com/guzzle/guzzle/pull/1608), [#1659](https://github.com/guzzle/guzzle/pull/1659)
29
- * Improvement: Don't include summary in exception message when body is empty [#1621](https://github.com/guzzle/guzzle/pull/1621)
30
- * Improvement: Handle `on_headers` option in MockHandler [#1580](https://github.com/guzzle/guzzle/pull/1580)
31
- * Improvement: Added SUSE Linux CA path [#1609](https://github.com/guzzle/guzzle/issues/1609)
32
- * Improvement: Use class reference for getting the name of the class instead of using hardcoded strings [#1641](https://github.com/guzzle/guzzle/pull/1641)
33
- * Feature: Added `read_timeout` option [#1611](https://github.com/guzzle/guzzle/pull/1611)
34
- * Bug fix: PHP 7.x fixes [#1685](https://github.com/guzzle/guzzle/pull/1685), [#1686](https://github.com/guzzle/guzzle/pull/1686), [#1811](https://github.com/guzzle/guzzle/pull/1811)
35
- * Deprecation: BadResponseException instantiation without a response [#1642](https://github.com/guzzle/guzzle/pull/1642)
36
- * Feature: Added NTLM auth [#1569](https://github.com/guzzle/guzzle/pull/1569)
37
- * Feature: Track redirect HTTP status codes [#1711](https://github.com/guzzle/guzzle/pull/1711)
38
- * Improvement: Check handler type during construction [#1745](https://github.com/guzzle/guzzle/pull/1745)
39
- * Improvement: Always include the Content-Length if there's a body [#1721](https://github.com/guzzle/guzzle/pull/1721)
40
- * Feature: Added convenience method to access a cookie by name [#1318](https://github.com/guzzle/guzzle/pull/1318)
41
- * Bug fix: Fill `CURLOPT_CAPATH` and `CURLOPT_CAINFO` properly [#1684](https://github.com/guzzle/guzzle/pull/1684)
42
- * Improvement: Use `\GuzzleHttp\Promise\rejection_for` function instead of object init [#1827](https://github.com/guzzle/guzzle/pull/1827)
43
-
44
-
45
- + Minor code cleanups, documentation fixes and clarifications.
46
-
47
- ## 6.2.3 - 2017-02-28
48
-
49
- * Fix deprecations with guzzle/psr7 version 1.4
50
-
51
- ## 6.2.2 - 2016-10-08
52
-
53
- * Allow to pass nullable Response to delay callable
54
- * Only add scheme when host is present
55
- * Fix drain case where content-length is the literal string zero
56
- * Obfuscate in-URL credentials in exceptions
57
-
58
- ## 6.2.1 - 2016-07-18
59
-
60
- * Address HTTP_PROXY security vulnerability, CVE-2016-5385:
61
- https://httpoxy.org/
62
- * Fixing timeout bug with StreamHandler:
63
- https://github.com/guzzle/guzzle/pull/1488
64
- * Only read up to `Content-Length` in PHP StreamHandler to avoid timeouts when
65
- a server does not honor `Connection: close`.
66
- * Ignore URI fragment when sending requests.
67
-
68
- ## 6.2.0 - 2016-03-21
69
-
70
- * Feature: added `GuzzleHttp\json_encode` and `GuzzleHttp\json_decode`.
71
- https://github.com/guzzle/guzzle/pull/1389
72
- * Bug fix: Fix sleep calculation when waiting for delayed requests.
73
- https://github.com/guzzle/guzzle/pull/1324
74
- * Feature: More flexible history containers.
75
- https://github.com/guzzle/guzzle/pull/1373
76
- * Bug fix: defer sink stream opening in StreamHandler.
77
- https://github.com/guzzle/guzzle/pull/1377
78
- * Bug fix: do not attempt to escape cookie values.
79
- https://github.com/guzzle/guzzle/pull/1406
80
- * Feature: report original content encoding and length on decoded responses.
81
- https://github.com/guzzle/guzzle/pull/1409
82
- * Bug fix: rewind seekable request bodies before dispatching to cURL.
83
- https://github.com/guzzle/guzzle/pull/1422
84
- * Bug fix: provide an empty string to `http_build_query` for HHVM workaround.
85
- https://github.com/guzzle/guzzle/pull/1367
86
-
87
- ## 6.1.1 - 2015-11-22
88
-
89
- * Bug fix: Proxy::wrapSync() now correctly proxies to the appropriate handler
90
- https://github.com/guzzle/guzzle/commit/911bcbc8b434adce64e223a6d1d14e9a8f63e4e4
91
- * Feature: HandlerStack is now more generic.
92
- https://github.com/guzzle/guzzle/commit/f2102941331cda544745eedd97fc8fd46e1ee33e
93
- * Bug fix: setting verify to false in the StreamHandler now disables peer
94
- verification. https://github.com/guzzle/guzzle/issues/1256
95
- * Feature: Middleware now uses an exception factory, including more error
96
- context. https://github.com/guzzle/guzzle/pull/1282
97
- * Feature: better support for disabled functions.
98
- https://github.com/guzzle/guzzle/pull/1287
99
- * Bug fix: fixed regression where MockHandler was not using `sink`.
100
- https://github.com/guzzle/guzzle/pull/1292
101
-
102
- ## 6.1.0 - 2015-09-08
103
-
104
- * Feature: Added the `on_stats` request option to provide access to transfer
105
- statistics for requests. https://github.com/guzzle/guzzle/pull/1202
106
- * Feature: Added the ability to persist session cookies in CookieJars.
107
- https://github.com/guzzle/guzzle/pull/1195
108
- * Feature: Some compatibility updates for Google APP Engine
109
- https://github.com/guzzle/guzzle/pull/1216
110
- * Feature: Added support for NO_PROXY to prevent the use of a proxy based on
111
- a simple set of rules. https://github.com/guzzle/guzzle/pull/1197
112
- * Feature: Cookies can now contain square brackets.
113
- https://github.com/guzzle/guzzle/pull/1237
114
- * Bug fix: Now correctly parsing `=` inside of quotes in Cookies.
115
- https://github.com/guzzle/guzzle/pull/1232
116
- * Bug fix: Cusotm cURL options now correctly override curl options of the
117
- same name. https://github.com/guzzle/guzzle/pull/1221
118
- * Bug fix: Content-Type header is now added when using an explicitly provided
119
- multipart body. https://github.com/guzzle/guzzle/pull/1218
120
- * Bug fix: Now ignoring Set-Cookie headers that have no name.
121
- * Bug fix: Reason phrase is no longer cast to an int in some cases in the
122
- cURL handler. https://github.com/guzzle/guzzle/pull/1187
123
- * Bug fix: Remove the Authorization header when redirecting if the Host
124
- header changes. https://github.com/guzzle/guzzle/pull/1207
125
- * Bug fix: Cookie path matching fixes
126
- https://github.com/guzzle/guzzle/issues/1129
127
- * Bug fix: Fixing the cURL `body_as_string` setting
128
- https://github.com/guzzle/guzzle/pull/1201
129
- * Bug fix: quotes are no longer stripped when parsing cookies.
130
- https://github.com/guzzle/guzzle/issues/1172
131
- * Bug fix: `form_params` and `query` now always uses the `&` separator.
132
- https://github.com/guzzle/guzzle/pull/1163
133
- * Bug fix: Adding a Content-Length to PHP stream wrapper requests if not set.
134
- https://github.com/guzzle/guzzle/pull/1189
135
-
136
- ## 6.0.2 - 2015-07-04
137
-
138
- * Fixed a memory leak in the curl handlers in which references to callbacks
139
- were not being removed by `curl_reset`.
140
- * Cookies are now extracted properly before redirects.
141
- * Cookies now allow more character ranges.
142
- * Decoded Content-Encoding responses are now modified to correctly reflect
143
- their state if the encoding was automatically removed by a handler. This
144
- means that the `Content-Encoding` header may be removed an the
145
- `Content-Length` modified to reflect the message size after removing the
146
- encoding.
147
- * Added a more explicit error message when trying to use `form_params` and
148
- `multipart` in the same request.
149
- * Several fixes for HHVM support.
150
- * Functions are now conditionally required using an additional level of
151
- indirection to help with global Composer installations.
152
-
153
- ## 6.0.1 - 2015-05-27
154
-
155
- * Fixed a bug with serializing the `query` request option where the `&`
156
- separator was missing.
157
- * Added a better error message for when `body` is provided as an array. Please
158
- use `form_params` or `multipart` instead.
159
- * Various doc fixes.
160
-
161
- ## 6.0.0 - 2015-05-26
162
-
163
- * See the UPGRADING.md document for more information.
164
- * Added `multipart` and `form_params` request options.
165
- * Added `synchronous` request option.
166
- * Added the `on_headers` request option.
167
- * Fixed `expect` handling.
168
- * No longer adding default middlewares in the client ctor. These need to be
169
- present on the provided handler in order to work.
170
- * Requests are no longer initiated when sending async requests with the
171
- CurlMultiHandler. This prevents unexpected recursion from requests completing
172
- while ticking the cURL loop.
173
- * Removed the semantics of setting `default` to `true`. This is no longer
174
- required now that the cURL loop is not ticked for async requests.
175
- * Added request and response logging middleware.
176
- * No longer allowing self signed certificates when using the StreamHandler.
177
- * Ensuring that `sink` is valid if saving to a file.
178
- * Request exceptions now include a "handler context" which provides handler
179
- specific contextual information.
180
- * Added `GuzzleHttp\RequestOptions` to allow request options to be applied
181
- using constants.
182
- * `$maxHandles` has been removed from CurlMultiHandler.
183
- * `MultipartPostBody` is now part of the `guzzlehttp/psr7` package.
184
-
185
- ## 5.3.0 - 2015-05-19
186
-
187
- * Mock now supports `save_to`
188
- * Marked `AbstractRequestEvent::getTransaction()` as public.
189
- * Fixed a bug in which multiple headers using different casing would overwrite
190
- previous headers in the associative array.
191
- * Added `Utils::getDefaultHandler()`
192
- * Marked `GuzzleHttp\Client::getDefaultUserAgent` as deprecated.
193
- * URL scheme is now always lowercased.
194
-
195
- ## 6.0.0-beta.1
196
-
197
- * Requires PHP >= 5.5
198
- * Updated to use PSR-7
199
- * Requires immutable messages, which basically means an event based system
200
- owned by a request instance is no longer possible.
201
- * Utilizing the [Guzzle PSR-7 package](https://github.com/guzzle/psr7).
202
- * Removed the dependency on `guzzlehttp/streams`. These stream abstractions
203
- are available in the `guzzlehttp/psr7` package under the `GuzzleHttp\Psr7`
204
- namespace.
205
- * Added middleware and handler system
206
- * Replaced the Guzzle event and subscriber system with a middleware system.
207
- * No longer depends on RingPHP, but rather places the HTTP handlers directly
208
- in Guzzle, operating on PSR-7 messages.
209
- * Retry logic is now encapsulated in `GuzzleHttp\Middleware::retry`, which
210
- means the `guzzlehttp/retry-subscriber` is now obsolete.
211
- * Mocking responses is now handled using `GuzzleHttp\Handler\MockHandler`.
212
- * Asynchronous responses
213
- * No longer supports the `future` request option to send an async request.
214
- Instead, use one of the `*Async` methods of a client (e.g., `requestAsync`,
215
- `getAsync`, etc.).
216
- * Utilizing `GuzzleHttp\Promise` instead of React's promise library to avoid
217
- recursion required by chaining and forwarding react promises. See
218
- https://github.com/guzzle/promises
219
- * Added `requestAsync` and `sendAsync` to send request asynchronously.
220
- * Added magic methods for `getAsync()`, `postAsync()`, etc. to send requests
221
- asynchronously.
222
- * Request options
223
- * POST and form updates
224
- * Added the `form_fields` and `form_files` request options.
225
- * Removed the `GuzzleHttp\Post` namespace.
226
- * The `body` request option no longer accepts an array for POST requests.
227
- * The `exceptions` request option has been deprecated in favor of the
228
- `http_errors` request options.
229
- * The `save_to` request option has been deprecated in favor of `sink` request
230
- option.
231
- * Clients no longer accept an array of URI template string and variables for
232
- URI variables. You will need to expand URI templates before passing them
233
- into a client constructor or request method.
234
- * Client methods `get()`, `post()`, `put()`, `patch()`, `options()`, etc. are
235
- now magic methods that will send synchronous requests.
236
- * Replaced `Utils.php` with plain functions in `functions.php`.
237
- * Removed `GuzzleHttp\Collection`.
238
- * Removed `GuzzleHttp\BatchResults`. Batched pool results are now returned as
239
- an array.
240
- * Removed `GuzzleHttp\Query`. Query string handling is now handled using an
241
- associative array passed into the `query` request option. The query string
242
- is serialized using PHP's `http_build_query`. If you need more control, you
243
- can pass the query string in as a string.
244
- * `GuzzleHttp\QueryParser` has been replaced with the
245
- `GuzzleHttp\Psr7\parse_query`.
246
-
247
- ## 5.2.0 - 2015-01-27
248
-
249
- * Added `AppliesHeadersInterface` to make applying headers to a request based
250
- on the body more generic and not specific to `PostBodyInterface`.
251
- * Reduced the number of stack frames needed to send requests.
252
- * Nested futures are now resolved in the client rather than the RequestFsm
253
- * Finishing state transitions is now handled in the RequestFsm rather than the
254
- RingBridge.
255
- * Added a guard in the Pool class to not use recursion for request retries.
256
-
257
- ## 5.1.0 - 2014-12-19
258
-
259
- * Pool class no longer uses recursion when a request is intercepted.
260
- * The size of a Pool can now be dynamically adjusted using a callback.
261
- See https://github.com/guzzle/guzzle/pull/943.
262
- * Setting a request option to `null` when creating a request with a client will
263
- ensure that the option is not set. This allows you to overwrite default
264
- request options on a per-request basis.
265
- See https://github.com/guzzle/guzzle/pull/937.
266
- * Added the ability to limit which protocols are allowed for redirects by
267
- specifying a `protocols` array in the `allow_redirects` request option.
268
- * Nested futures due to retries are now resolved when waiting for synchronous
269
- responses. See https://github.com/guzzle/guzzle/pull/947.
270
- * `"0"` is now an allowed URI path. See
271
- https://github.com/guzzle/guzzle/pull/935.
272
- * `Query` no longer typehints on the `$query` argument in the constructor,
273
- allowing for strings and arrays.
274
- * Exceptions thrown in the `end` event are now correctly wrapped with Guzzle
275
- specific exceptions if necessary.
276
-
277
- ## 5.0.3 - 2014-11-03
278
-
279
- This change updates query strings so that they are treated as un-encoded values
280
- by default where the value represents an un-encoded value to send over the
281
- wire. A Query object then encodes the value before sending over the wire. This
282
- means that even value query string values (e.g., ":") are url encoded. This
283
- makes the Query class match PHP's http_build_query function. However, if you
284
- want to send requests over the wire using valid query string characters that do
285
- not need to be encoded, then you can provide a string to Url::setQuery() and
286
- pass true as the second argument to specify that the query string is a raw
287
- string that should not be parsed or encoded (unless a call to getQuery() is
288
- subsequently made, forcing the query-string to be converted into a Query
289
- object).
290
-
291
- ## 5.0.2 - 2014-10-30
292
-
293
- * Added a trailing `\r\n` to multipart/form-data payloads. See
294
- https://github.com/guzzle/guzzle/pull/871
295
- * Added a `GuzzleHttp\Pool::send()` convenience method to match the docs.
296
- * Status codes are now returned as integers. See
297
- https://github.com/guzzle/guzzle/issues/881
298
- * No longer overwriting an existing `application/x-www-form-urlencoded` header
299
- when sending POST requests, allowing for customized headers. See
300
- https://github.com/guzzle/guzzle/issues/877
301
- * Improved path URL serialization.
302
-
303
- * No longer double percent-encoding characters in the path or query string if
304
- they are already encoded.
305
- * Now properly encoding the supplied path to a URL object, instead of only
306
- encoding ' ' and '?'.
307
- * Note: This has been changed in 5.0.3 to now encode query string values by
308
- default unless the `rawString` argument is provided when setting the query
309
- string on a URL: Now allowing many more characters to be present in the
310
- query string without being percent encoded. See http://tools.ietf.org/html/rfc3986#appendix-A
311
-
312
- ## 5.0.1 - 2014-10-16
313
-
314
- Bugfix release.
315
-
316
- * Fixed an issue where connection errors still returned response object in
317
- error and end events event though the response is unusable. This has been
318
- corrected so that a response is not returned in the `getResponse` method of
319
- these events if the response did not complete. https://github.com/guzzle/guzzle/issues/867
320
- * Fixed an issue where transfer statistics were not being populated in the
321
- RingBridge. https://github.com/guzzle/guzzle/issues/866
322
-
323
- ## 5.0.0 - 2014-10-12
324
-
325
- Adding support for non-blocking responses and some minor API cleanup.
326
-
327
- ### New Features
328
-
329
- * Added support for non-blocking responses based on `guzzlehttp/guzzle-ring`.
330
- * Added a public API for creating a default HTTP adapter.
331
- * Updated the redirect plugin to be non-blocking so that redirects are sent
332
- concurrently. Other plugins like this can now be updated to be non-blocking.
333
- * Added a "progress" event so that you can get upload and download progress
334
- events.
335
- * Added `GuzzleHttp\Pool` which implements FutureInterface and transfers
336
- requests concurrently using a capped pool size as efficiently as possible.
337
- * Added `hasListeners()` to EmitterInterface.
338
- * Removed `GuzzleHttp\ClientInterface::sendAll` and marked
339
- `GuzzleHttp\Client::sendAll` as deprecated (it's still there, just not the
340
- recommended way).
341
-
342
- ### Breaking changes
343
-
344
- The breaking changes in this release are relatively minor. The biggest thing to
345
- look out for is that request and response objects no longer implement fluent
346
- interfaces.
347
-
348
- * Removed the fluent interfaces (i.e., `return $this`) from requests,
349
- responses, `GuzzleHttp\Collection`, `GuzzleHttp\Url`,
350
- `GuzzleHttp\Query`, `GuzzleHttp\Post\PostBody`, and
351
- `GuzzleHttp\Cookie\SetCookie`. This blog post provides a good outline of
352
- why I did this: http://ocramius.github.io/blog/fluent-interfaces-are-evil/.
353
- This also makes the Guzzle message interfaces compatible with the current
354
- PSR-7 message proposal.
355
- * Removed "functions.php", so that Guzzle is truly PSR-4 compliant. Except
356
- for the HTTP request functions from function.php, these functions are now
357
- implemented in `GuzzleHttp\Utils` using camelCase. `GuzzleHttp\json_decode`
358
- moved to `GuzzleHttp\Utils::jsonDecode`. `GuzzleHttp\get_path` moved to
359
- `GuzzleHttp\Utils::getPath`. `GuzzleHttp\set_path` moved to
360
- `GuzzleHttp\Utils::setPath`. `GuzzleHttp\batch` should now be
361
- `GuzzleHttp\Pool::batch`, which returns an `objectStorage`. Using functions.php
362
- caused problems for many users: they aren't PSR-4 compliant, require an
363
- explicit include, and needed an if-guard to ensure that the functions are not
364
- declared multiple times.
365
- * Rewrote adapter layer.
366
- * Removing all classes from `GuzzleHttp\Adapter`, these are now
367
- implemented as callables that are stored in `GuzzleHttp\Ring\Client`.
368
- * Removed the concept of "parallel adapters". Sending requests serially or
369
- concurrently is now handled using a single adapter.
370
- * Moved `GuzzleHttp\Adapter\Transaction` to `GuzzleHttp\Transaction`. The
371
- Transaction object now exposes the request, response, and client as public
372
- properties. The getters and setters have been removed.
373
- * Removed the "headers" event. This event was only useful for changing the
374
- body a response once the headers of the response were known. You can implement
375
- a similar behavior in a number of ways. One example might be to use a
376
- FnStream that has access to the transaction being sent. For example, when the
377
- first byte is written, you could check if the response headers match your
378
- expectations, and if so, change the actual stream body that is being
379
- written to.
380
- * Removed the `asArray` parameter from
381
- `GuzzleHttp\Message\MessageInterface::getHeader`. If you want to get a header
382
- value as an array, then use the newly added `getHeaderAsArray()` method of
383
- `MessageInterface`. This change makes the Guzzle interfaces compatible with
384
- the PSR-7 interfaces.
385
- * `GuzzleHttp\Message\MessageFactory` no longer allows subclasses to add
386
- custom request options using double-dispatch (this was an implementation
387
- detail). Instead, you should now provide an associative array to the
388
- constructor which is a mapping of the request option name mapping to a
389
- function that applies the option value to a request.
390
- * Removed the concept of "throwImmediately" from exceptions and error events.
391
- This control mechanism was used to stop a transfer of concurrent requests
392
- from completing. This can now be handled by throwing the exception or by
393
- cancelling a pool of requests or each outstanding future request individually.
394
- * Updated to "GuzzleHttp\Streams" 3.0.
395
- * `GuzzleHttp\Stream\StreamInterface::getContents()` no longer accepts a
396
- `maxLen` parameter. This update makes the Guzzle streams project
397
- compatible with the current PSR-7 proposal.
398
- * `GuzzleHttp\Stream\Stream::__construct`,
399
- `GuzzleHttp\Stream\Stream::factory`, and
400
- `GuzzleHttp\Stream\Utils::create` no longer accept a size in the second
401
- argument. They now accept an associative array of options, including the
402
- "size" key and "metadata" key which can be used to provide custom metadata.
403
-
404
- ## 4.2.2 - 2014-09-08
405
-
406
- * Fixed a memory leak in the CurlAdapter when reusing cURL handles.
407
- * No longer using `request_fulluri` in stream adapter proxies.
408
- * Relative redirects are now based on the last response, not the first response.
409
-
410
- ## 4.2.1 - 2014-08-19
411
-
412
- * Ensuring that the StreamAdapter does not always add a Content-Type header
413
- * Adding automated github releases with a phar and zip
414
-
415
- ## 4.2.0 - 2014-08-17
416
-
417
- * Now merging in default options using a case-insensitive comparison.
418
- Closes https://github.com/guzzle/guzzle/issues/767
419
- * Added the ability to automatically decode `Content-Encoding` response bodies
420
- using the `decode_content` request option. This is set to `true` by default
421
- to decode the response body if it comes over the wire with a
422
- `Content-Encoding`. Set this value to `false` to disable decoding the
423
- response content, and pass a string to provide a request `Accept-Encoding`
424
- header and turn on automatic response decoding. This feature now allows you
425
- to pass an `Accept-Encoding` header in the headers of a request but still
426
- disable automatic response decoding.
427
- Closes https://github.com/guzzle/guzzle/issues/764
428
- * Added the ability to throw an exception immediately when transferring
429
- requests in parallel. Closes https://github.com/guzzle/guzzle/issues/760
430
- * Updating guzzlehttp/streams dependency to ~2.1
431
- * No longer utilizing the now deprecated namespaced methods from the stream
432
- package.
433
-
434
- ## 4.1.8 - 2014-08-14
435
-
436
- * Fixed an issue in the CurlFactory that caused setting the `stream=false`
437
- request option to throw an exception.
438
- See: https://github.com/guzzle/guzzle/issues/769
439
- * TransactionIterator now calls rewind on the inner iterator.
440
- See: https://github.com/guzzle/guzzle/pull/765
441
- * You can now set the `Content-Type` header to `multipart/form-data`
442
- when creating POST requests to force multipart bodies.
443
- See https://github.com/guzzle/guzzle/issues/768
444
-
445
- ## 4.1.7 - 2014-08-07
446
-
447
- * Fixed an error in the HistoryPlugin that caused the same request and response
448
- to be logged multiple times when an HTTP protocol error occurs.
449
- * Ensuring that cURL does not add a default Content-Type when no Content-Type
450
- has been supplied by the user. This prevents the adapter layer from modifying
451
- the request that is sent over the wire after any listeners may have already
452
- put the request in a desired state (e.g., signed the request).
453
- * Throwing an exception when you attempt to send requests that have the
454
- "stream" set to true in parallel using the MultiAdapter.
455
- * Only calling curl_multi_select when there are active cURL handles. This was
456
- previously changed and caused performance problems on some systems due to PHP
457
- always selecting until the maximum select timeout.
458
- * Fixed a bug where multipart/form-data POST fields were not correctly
459
- aggregated (e.g., values with "&").
460
-
461
- ## 4.1.6 - 2014-08-03
462
-
463
- * Added helper methods to make it easier to represent messages as strings,
464
- including getting the start line and getting headers as a string.
465
-
466
- ## 4.1.5 - 2014-08-02
467
-
468
- * Automatically retrying cURL "Connection died, retrying a fresh connect"
469
- errors when possible.
470
- * cURL implementation cleanup
471
- * Allowing multiple event subscriber listeners to be registered per event by
472
- passing an array of arrays of listener configuration.
473
-
474
- ## 4.1.4 - 2014-07-22
475
-
476
- * Fixed a bug that caused multi-part POST requests with more than one field to
477
- serialize incorrectly.
478
- * Paths can now be set to "0"
479
- * `ResponseInterface::xml` now accepts a `libxml_options` option and added a
480
- missing default argument that was required when parsing XML response bodies.
481
- * A `save_to` stream is now created lazily, which means that files are not
482
- created on disk unless a request succeeds.
483
-
484
- ## 4.1.3 - 2014-07-15
485
-
486
- * Various fixes to multipart/form-data POST uploads
487
- * Wrapping function.php in an if-statement to ensure Guzzle can be used
488
- globally and in a Composer install
489
- * Fixed an issue with generating and merging in events to an event array
490
- * POST headers are only applied before sending a request to allow you to change
491
- the query aggregator used before uploading
492
- * Added much more robust query string parsing
493
- * Fixed various parsing and normalization issues with URLs
494
- * Fixing an issue where multi-valued headers were not being utilized correctly
495
- in the StreamAdapter
496
-
497
- ## 4.1.2 - 2014-06-18
498
-
499
- * Added support for sending payloads with GET requests
500
-
501
- ## 4.1.1 - 2014-06-08
502
-
503
- * Fixed an issue related to using custom message factory options in subclasses
504
- * Fixed an issue with nested form fields in a multi-part POST
505
- * Fixed an issue with using the `json` request option for POST requests
506
- * Added `ToArrayInterface` to `GuzzleHttp\Cookie\CookieJar`
507
-
508
- ## 4.1.0 - 2014-05-27
509
-
510
- * Added a `json` request option to easily serialize JSON payloads.
511
- * Added a `GuzzleHttp\json_decode()` wrapper to safely parse JSON.
512
- * Added `setPort()` and `getPort()` to `GuzzleHttp\Message\RequestInterface`.
513
- * Added the ability to provide an emitter to a client in the client constructor.
514
- * Added the ability to persist a cookie session using $_SESSION.
515
- * Added a trait that can be used to add event listeners to an iterator.
516
- * Removed request method constants from RequestInterface.
517
- * Fixed warning when invalid request start-lines are received.
518
- * Updated MessageFactory to work with custom request option methods.
519
- * Updated cacert bundle to latest build.
520
-
521
- 4.0.2 (2014-04-16)
522
- ------------------
523
-
524
- * Proxy requests using the StreamAdapter now properly use request_fulluri (#632)
525
- * Added the ability to set scalars as POST fields (#628)
526
-
527
- ## 4.0.1 - 2014-04-04
528
-
529
- * The HTTP status code of a response is now set as the exception code of
530
- RequestException objects.
531
- * 303 redirects will now correctly switch from POST to GET requests.
532
- * The default parallel adapter of a client now correctly uses the MultiAdapter.
533
- * HasDataTrait now initializes the internal data array as an empty array so
534
- that the toArray() method always returns an array.
535
-
536
- ## 4.0.0 - 2014-03-29
537
-
538
- * For more information on the 4.0 transition, see:
539
- http://mtdowling.com/blog/2014/03/15/guzzle-4-rc/
540
- * For information on changes and upgrading, see:
541
- https://github.com/guzzle/guzzle/blob/master/UPGRADING.md#3x-to-40
542
- * Added `GuzzleHttp\batch()` as a convenience function for sending requests in
543
- parallel without needing to write asynchronous code.
544
- * Restructured how events are added to `GuzzleHttp\ClientInterface::sendAll()`.
545
- You can now pass a callable or an array of associative arrays where each
546
- associative array contains the "fn", "priority", and "once" keys.
547
-
548
- ## 4.0.0.rc-2 - 2014-03-25
549
-
550
- * Removed `getConfig()` and `setConfig()` from clients to avoid confusion
551
- around whether things like base_url, message_factory, etc. should be able to
552
- be retrieved or modified.
553
- * Added `getDefaultOption()` and `setDefaultOption()` to ClientInterface
554
- * functions.php functions were renamed using snake_case to match PHP idioms
555
- * Added support for `HTTP_PROXY`, `HTTPS_PROXY`, and
556
- `GUZZLE_CURL_SELECT_TIMEOUT` environment variables
557
- * Added the ability to specify custom `sendAll()` event priorities
558
- * Added the ability to specify custom stream context options to the stream
559
- adapter.
560
- * Added a functions.php function for `get_path()` and `set_path()`
561
- * CurlAdapter and MultiAdapter now use a callable to generate curl resources
562
- * MockAdapter now properly reads a body and emits a `headers` event
563
- * Updated Url class to check if a scheme and host are set before adding ":"
564
- and "//". This allows empty Url (e.g., "") to be serialized as "".
565
- * Parsing invalid XML no longer emits warnings
566
- * Curl classes now properly throw AdapterExceptions
567
- * Various performance optimizations
568
- * Streams are created with the faster `Stream\create()` function
569
- * Marked deprecation_proxy() as internal
570
- * Test server is now a collection of static methods on a class
571
-
572
- ## 4.0.0-rc.1 - 2014-03-15
573
-
574
- * See https://github.com/guzzle/guzzle/blob/master/UPGRADING.md#3x-to-40
575
-
576
- ## 3.8.1 - 2014-01-28
577
-
578
- * Bug: Always using GET requests when redirecting from a 303 response
579
- * Bug: CURLOPT_SSL_VERIFYHOST is now correctly set to false when setting `$certificateAuthority` to false in
580
- `Guzzle\Http\ClientInterface::setSslVerification()`
581
- * Bug: RedirectPlugin now uses strict RFC 3986 compliance when combining a base URL with a relative URL
582
- * Bug: The body of a request can now be set to `"0"`
583
- * Sending PHP stream requests no longer forces `HTTP/1.0`
584
- * Adding more information to ExceptionCollection exceptions so that users have more context, including a stack trace of
585
- each sub-exception
586
- * Updated the `$ref` attribute in service descriptions to merge over any existing parameters of a schema (rather than
587
- clobbering everything).
588
- * Merging URLs will now use the query string object from the relative URL (thus allowing custom query aggregators)
589
- * Query strings are now parsed in a way that they do no convert empty keys with no value to have a dangling `=`.
590
- For example `foo&bar=baz` is now correctly parsed and recognized as `foo&bar=baz` rather than `foo=&bar=baz`.
591
- * Now properly escaping the regular expression delimiter when matching Cookie domains.
592
- * Network access is now disabled when loading XML documents
593
-
594
- ## 3.8.0 - 2013-12-05
595
-
596
- * Added the ability to define a POST name for a file
597
- * JSON response parsing now properly walks additionalProperties
598
- * cURL error code 18 is now retried automatically in the BackoffPlugin
599
- * Fixed a cURL error when URLs contain fragments
600
- * Fixed an issue in the BackoffPlugin retry event where it was trying to access all exceptions as if they were
601
- CurlExceptions
602
- * CURLOPT_PROGRESS function fix for PHP 5.5 (69fcc1e)
603
- * Added the ability for Guzzle to work with older versions of cURL that do not support `CURLOPT_TIMEOUT_MS`
604
- * Fixed a bug that was encountered when parsing empty header parameters
605
- * UriTemplate now has a `setRegex()` method to match the docs
606
- * The `debug` request parameter now checks if it is truthy rather than if it exists
607
- * Setting the `debug` request parameter to true shows verbose cURL output instead of using the LogPlugin
608
- * Added the ability to combine URLs using strict RFC 3986 compliance
609
- * Command objects can now return the validation errors encountered by the command
610
- * Various fixes to cache revalidation (#437 and 29797e5)
611
- * Various fixes to the AsyncPlugin
612
- * Cleaned up build scripts
613
-
614
- ## 3.7.4 - 2013-10-02
615
-
616
- * Bug fix: 0 is now an allowed value in a description parameter that has a default value (#430)
617
- * Bug fix: SchemaFormatter now returns an integer when formatting to a Unix timestamp
618
- (see https://github.com/aws/aws-sdk-php/issues/147)
619
- * Bug fix: Cleaned up and fixed URL dot segment removal to properly resolve internal dots
620
- * Minimum PHP version is now properly specified as 5.3.3 (up from 5.3.2) (#420)
621
- * Updated the bundled cacert.pem (#419)
622
- * OauthPlugin now supports adding authentication to headers or query string (#425)
623
-
624
- ## 3.7.3 - 2013-09-08
625
-
626
- * Added the ability to get the exception associated with a request/command when using `MultiTransferException` and
627
- `CommandTransferException`.
628
- * Setting `additionalParameters` of a response to false is now honored when parsing responses with a service description
629
- * Schemas are only injected into response models when explicitly configured.
630
- * No longer guessing Content-Type based on the path of a request. Content-Type is now only guessed based on the path of
631
- an EntityBody.
632
- * Bug fix: ChunkedIterator can now properly chunk a \Traversable as well as an \Iterator.
633
- * Bug fix: FilterIterator now relies on `\Iterator` instead of `\Traversable`.
634
- * Bug fix: Gracefully handling malformed responses in RequestMediator::writeResponseBody()
635
- * Bug fix: Replaced call to canCache with canCacheRequest in the CallbackCanCacheStrategy of the CachePlugin
636
- * Bug fix: Visiting XML attributes first before visiting XML children when serializing requests
637
- * Bug fix: Properly parsing headers that contain commas contained in quotes
638
- * Bug fix: mimetype guessing based on a filename is now case-insensitive
639
-
640
- ## 3.7.2 - 2013-08-02
641
-
642
- * Bug fix: Properly URL encoding paths when using the PHP-only version of the UriTemplate expander
643
- See https://github.com/guzzle/guzzle/issues/371
644
- * Bug fix: Cookie domains are now matched correctly according to RFC 6265
645
- See https://github.com/guzzle/guzzle/issues/377
646
- * Bug fix: GET parameters are now used when calculating an OAuth signature
647
- * Bug fix: Fixed an issue with cache revalidation where the If-None-Match header was being double quoted
648
- * `Guzzle\Common\AbstractHasDispatcher::dispatch()` now returns the event that was dispatched
649
- * `Guzzle\Http\QueryString::factory()` now guesses the most appropriate query aggregator to used based on the input.
650
- See https://github.com/guzzle/guzzle/issues/379
651
- * Added a way to add custom domain objects to service description parsing using the `operation.parse_class` event. See
652
- https://github.com/guzzle/guzzle/pull/380
653
- * cURL multi cleanup and optimizations
654
-
655
- ## 3.7.1 - 2013-07-05
656
-
657
- * Bug fix: Setting default options on a client now works
658
- * Bug fix: Setting options on HEAD requests now works. See #352
659
- * Bug fix: Moving stream factory before send event to before building the stream. See #353
660
- * Bug fix: Cookies no longer match on IP addresses per RFC 6265
661
- * Bug fix: Correctly parsing header parameters that are in `<>` and quotes
662
- * Added `cert` and `ssl_key` as request options
663
- * `Host` header can now diverge from the host part of a URL if the header is set manually
664
- * `Guzzle\Service\Command\LocationVisitor\Request\XmlVisitor` was rewritten to change from using SimpleXML to XMLWriter
665
- * OAuth parameters are only added via the plugin if they aren't already set
666
- * Exceptions are now thrown when a URL cannot be parsed
667
- * Returning `false` if `Guzzle\Http\EntityBody::getContentMd5()` fails
668
- * Not setting a `Content-MD5` on a command if calculating the Content-MD5 fails via the CommandContentMd5Plugin
669
-
670
- ## 3.7.0 - 2013-06-10
671
-
672
- * See UPGRADING.md for more information on how to upgrade.
673
- * Requests now support the ability to specify an array of $options when creating a request to more easily modify a
674
- request. You can pass a 'request.options' configuration setting to a client to apply default request options to
675
- every request created by a client (e.g. default query string variables, headers, curl options, etc.).
676
- * Added a static facade class that allows you to use Guzzle with static methods and mount the class to `\Guzzle`.
677
- See `Guzzle\Http\StaticClient::mount`.
678
- * Added `command.request_options` to `Guzzle\Service\Command\AbstractCommand` to pass request options to requests
679
- created by a command (e.g. custom headers, query string variables, timeout settings, etc.).
680
- * Stream size in `Guzzle\Stream\PhpStreamRequestFactory` will now be set if Content-Length is returned in the
681
- headers of a response
682
- * Added `Guzzle\Common\Collection::setPath($path, $value)` to set a value into an array using a nested key
683
- (e.g. `$collection->setPath('foo/baz/bar', 'test'); echo $collection['foo']['bar']['bar'];`)
684
- * ServiceBuilders now support storing and retrieving arbitrary data
685
- * CachePlugin can now purge all resources for a given URI
686
- * CachePlugin can automatically purge matching cached items when a non-idempotent request is sent to a resource
687
- * CachePlugin now uses the Vary header to determine if a resource is a cache hit
688
- * `Guzzle\Http\Message\Response` now implements `\Serializable`
689
- * Added `Guzzle\Cache\CacheAdapterFactory::fromCache()` to more easily create cache adapters
690
- * `Guzzle\Service\ClientInterface::execute()` now accepts an array, single command, or Traversable
691
- * Fixed a bug in `Guzzle\Http\Message\Header\Link::addLink()`
692
- * Better handling of calculating the size of a stream in `Guzzle\Stream\Stream` using fstat() and caching the size
693
- * `Guzzle\Common\Exception\ExceptionCollection` now creates a more readable exception message
694
- * Fixing BC break: Added back the MonologLogAdapter implementation rather than extending from PsrLog so that older
695
- Symfony users can still use the old version of Monolog.
696
- * Fixing BC break: Added the implementation back in for `Guzzle\Http\Message\AbstractMessage::getTokenizedHeader()`.
697
- Now triggering an E_USER_DEPRECATED warning when used. Use `$message->getHeader()->parseParams()`.
698
- * Several performance improvements to `Guzzle\Common\Collection`
699
- * Added an `$options` argument to the end of the following methods of `Guzzle\Http\ClientInterface`:
700
- createRequest, head, delete, put, patch, post, options, prepareRequest
701
- * Added an `$options` argument to the end of `Guzzle\Http\Message\Request\RequestFactoryInterface::createRequest()`
702
- * Added an `applyOptions()` method to `Guzzle\Http\Message\Request\RequestFactoryInterface`
703
- * Changed `Guzzle\Http\ClientInterface::get($uri = null, $headers = null, $body = null)` to
704
- `Guzzle\Http\ClientInterface::get($uri = null, $headers = null, $options = array())`. You can still pass in a
705
- resource, string, or EntityBody into the $options parameter to specify the download location of the response.
706
- * Changed `Guzzle\Common\Collection::__construct($data)` to no longer accepts a null value for `$data` but a
707
- default `array()`
708
- * Added `Guzzle\Stream\StreamInterface::isRepeatable`
709
- * Removed `Guzzle\Http\ClientInterface::setDefaultHeaders(). Use
710
- $client->getConfig()->setPath('request.options/headers/{header_name}', 'value')`. or
711
- $client->getConfig()->setPath('request.options/headers', array('header_name' => 'value'))`.
712
- * Removed `Guzzle\Http\ClientInterface::getDefaultHeaders(). Use $client->getConfig()->getPath('request.options/headers')`.
713
- * Removed `Guzzle\Http\ClientInterface::expandTemplate()`
714
- * Removed `Guzzle\Http\ClientInterface::setRequestFactory()`
715
- * Removed `Guzzle\Http\ClientInterface::getCurlMulti()`
716
- * Removed `Guzzle\Http\Message\RequestInterface::canCache`
717
- * Removed `Guzzle\Http\Message\RequestInterface::setIsRedirect`
718
- * Removed `Guzzle\Http\Message\RequestInterface::isRedirect`
719
- * Made `Guzzle\Http\Client::expandTemplate` and `getUriTemplate` protected methods.
720
- * You can now enable E_USER_DEPRECATED warnings to see if you are using a deprecated method by setting
721
- `Guzzle\Common\Version::$emitWarnings` to true.
722
- * Marked `Guzzle\Http\Message\Request::isResponseBodyRepeatable()` as deprecated. Use
723
- `$request->getResponseBody()->isRepeatable()` instead.
724
- * Marked `Guzzle\Http\Message\Request::canCache()` as deprecated. Use
725
- `Guzzle\Plugin\Cache\DefaultCanCacheStrategy->canCacheRequest()` instead.
726
- * Marked `Guzzle\Http\Message\Request::canCache()` as deprecated. Use
727
- `Guzzle\Plugin\Cache\DefaultCanCacheStrategy->canCacheRequest()` instead.
728
- * Marked `Guzzle\Http\Message\Request::setIsRedirect()` as deprecated. Use the HistoryPlugin instead.
729
- * Marked `Guzzle\Http\Message\Request::isRedirect()` as deprecated. Use the HistoryPlugin instead.
730
- * Marked `Guzzle\Cache\CacheAdapterFactory::factory()` as deprecated
731
- * Marked 'command.headers', 'command.response_body' and 'command.on_complete' as deprecated for AbstractCommand.
732
- These will work through Guzzle 4.0
733
- * Marked 'request.params' for `Guzzle\Http\Client` as deprecated. Use [request.options][params].
734
- * Marked `Guzzle\Service\Client::enableMagicMethods()` as deprecated. Magic methods can no longer be disabled on a Guzzle\Service\Client.
735
- * Marked `Guzzle\Service\Client::getDefaultHeaders()` as deprecated. Use $client->getConfig()->getPath('request.options/headers')`.
736
- * Marked `Guzzle\Service\Client::setDefaultHeaders()` as deprecated. Use $client->getConfig()->setPath('request.options/headers/{header_name}', 'value')`.
737
- * Marked `Guzzle\Parser\Url\UrlParser` as deprecated. Just use PHP's `parse_url()` and percent encode your UTF-8.
738
- * Marked `Guzzle\Common\Collection::inject()` as deprecated.
739
- * Marked `Guzzle\Plugin\CurlAuth\CurlAuthPlugin` as deprecated. Use `$client->getConfig()->setPath('request.options/auth', array('user', 'pass', 'Basic|Digest');`
740
- * CacheKeyProviderInterface and DefaultCacheKeyProvider are no longer used. All of this logic is handled in a
741
- CacheStorageInterface. These two objects and interface will be removed in a future version.
742
- * Always setting X-cache headers on cached responses
743
- * Default cache TTLs are now handled by the CacheStorageInterface of a CachePlugin
744
- * `CacheStorageInterface::cache($key, Response $response, $ttl = null)` has changed to `cache(RequestInterface
745
- $request, Response $response);`
746
- * `CacheStorageInterface::fetch($key)` has changed to `fetch(RequestInterface $request);`
747
- * `CacheStorageInterface::delete($key)` has changed to `delete(RequestInterface $request);`
748
- * Added `CacheStorageInterface::purge($url)`
749
- * `DefaultRevalidation::__construct(CacheKeyProviderInterface $cacheKey, CacheStorageInterface $cache, CachePlugin
750
- $plugin)` has changed to `DefaultRevalidation::__construct(CacheStorageInterface $cache,
751
- CanCacheStrategyInterface $canCache = null)`
752
- * Added `RevalidationInterface::shouldRevalidate(RequestInterface $request, Response $response)`
753
-
754
- ## 3.6.0 - 2013-05-29
755
-
756
- * ServiceDescription now implements ToArrayInterface
757
- * Added command.hidden_params to blacklist certain headers from being treated as additionalParameters
758
- * Guzzle can now correctly parse incomplete URLs
759
- * Mixed casing of headers are now forced to be a single consistent casing across all values for that header.
760
- * Messages internally use a HeaderCollection object to delegate handling case-insensitive header resolution
761
- * Removed the whole changedHeader() function system of messages because all header changes now go through addHeader().
762
- * Specific header implementations can be created for complex headers. When a message creates a header, it uses a
763
- HeaderFactory which can map specific headers to specific header classes. There is now a Link header and
764
- CacheControl header implementation.
765
- * Removed from interface: Guzzle\Http\ClientInterface::setUriTemplate
766
- * Removed from interface: Guzzle\Http\ClientInterface::setCurlMulti()
767
- * Removed Guzzle\Http\Message\Request::receivedRequestHeader() and implemented this functionality in
768
- Guzzle\Http\Curl\RequestMediator
769
- * Removed the optional $asString parameter from MessageInterface::getHeader(). Just cast the header to a string.
770
- * Removed the optional $tryChunkedTransfer option from Guzzle\Http\Message\EntityEnclosingRequestInterface
771
- * Removed the $asObjects argument from Guzzle\Http\Message\MessageInterface::getHeaders()
772
- * Removed Guzzle\Parser\ParserRegister::get(). Use getParser()
773
- * Removed Guzzle\Parser\ParserRegister::set(). Use registerParser().
774
- * All response header helper functions return a string rather than mixing Header objects and strings inconsistently
775
- * Removed cURL blacklist support. This is no longer necessary now that Expect, Accept, etc. are managed by Guzzle
776
- directly via interfaces
777
- * Removed the injecting of a request object onto a response object. The methods to get and set a request still exist
778
- but are a no-op until removed.
779
- * Most classes that used to require a `Guzzle\Service\Command\CommandInterface` typehint now request a
780
- `Guzzle\Service\Command\ArrayCommandInterface`.
781
- * Added `Guzzle\Http\Message\RequestInterface::startResponse()` to the RequestInterface to handle injecting a response
782
- on a request while the request is still being transferred
783
- * The ability to case-insensitively search for header values
784
- * Guzzle\Http\Message\Header::hasExactHeader
785
- * Guzzle\Http\Message\Header::raw. Use getAll()
786
- * Deprecated cache control specific methods on Guzzle\Http\Message\AbstractMessage. Use the CacheControl header object
787
- instead.
788
- * `Guzzle\Service\Command\CommandInterface` now extends from ToArrayInterface and ArrayAccess
789
- * Added the ability to cast Model objects to a string to view debug information.
790
-
791
- ## 3.5.0 - 2013-05-13
792
-
793
- * Bug: Fixed a regression so that request responses are parsed only once per oncomplete event rather than multiple times
794
- * Bug: Better cleanup of one-time events across the board (when an event is meant to fire once, it will now remove
795
- itself from the EventDispatcher)
796
- * Bug: `Guzzle\Log\MessageFormatter` now properly writes "total_time" and "connect_time" values
797
- * Bug: Cloning an EntityEnclosingRequest now clones the EntityBody too
798
- * Bug: Fixed an undefined index error when parsing nested JSON responses with a sentAs parameter that reference a
799
- non-existent key
800
- * Bug: All __call() method arguments are now required (helps with mocking frameworks)
801
- * Deprecating Response::getRequest() and now using a shallow clone of a request object to remove a circular reference
802
- to help with refcount based garbage collection of resources created by sending a request
803
- * Deprecating ZF1 cache and log adapters. These will be removed in the next major version.
804
- * Deprecating `Response::getPreviousResponse()` (method signature still exists, but it's deprecated). Use the
805
- HistoryPlugin for a history.
806
- * Added a `responseBody` alias for the `response_body` location
807
- * Refactored internals to no longer rely on Response::getRequest()
808
- * HistoryPlugin can now be cast to a string
809
- * HistoryPlugin now logs transactions rather than requests and responses to more accurately keep track of the requests
810
- and responses that are sent over the wire
811
- * Added `getEffectiveUrl()` and `getRedirectCount()` to Response objects
812
-
813
- ## 3.4.3 - 2013-04-30
814
-
815
- * Bug fix: Fixing bug introduced in 3.4.2 where redirect responses are duplicated on the final redirected response
816
- * Added a check to re-extract the temp cacert bundle from the phar before sending each request
817
-
818
- ## 3.4.2 - 2013-04-29
819
-
820
- * Bug fix: Stream objects now work correctly with "a" and "a+" modes
821
- * Bug fix: Removing `Transfer-Encoding: chunked` header when a Content-Length is present
822
- * Bug fix: AsyncPlugin no longer forces HEAD requests
823
- * Bug fix: DateTime timezones are now properly handled when using the service description schema formatter
824
- * Bug fix: CachePlugin now properly handles stale-if-error directives when a request to the origin server fails
825
- * Setting a response on a request will write to the custom request body from the response body if one is specified
826
- * LogPlugin now writes to php://output when STDERR is undefined
827
- * Added the ability to set multiple POST files for the same key in a single call
828
- * application/x-www-form-urlencoded POSTs now use the utf-8 charset by default
829
- * Added the ability to queue CurlExceptions to the MockPlugin
830
- * Cleaned up how manual responses are queued on requests (removed "queued_response" and now using request.before_send)
831
- * Configuration loading now allows remote files
832
-
833
- ## 3.4.1 - 2013-04-16
834
-
835
- * Large refactoring to how CurlMulti handles work. There is now a proxy that sits in front of a pool of CurlMulti
836
- handles. This greatly simplifies the implementation, fixes a couple bugs, and provides a small performance boost.
837
- * Exceptions are now properly grouped when sending requests in parallel
838
- * Redirects are now properly aggregated when a multi transaction fails
839
- * Redirects now set the response on the original object even in the event of a failure
840
- * Bug fix: Model names are now properly set even when using $refs
841
- * Added support for PHP 5.5's CurlFile to prevent warnings with the deprecated @ syntax
842
- * Added support for oauth_callback in OAuth signatures
843
- * Added support for oauth_verifier in OAuth signatures
844
- * Added support to attempt to retrieve a command first literally, then ucfirst, the with inflection
845
-
846
- ## 3.4.0 - 2013-04-11
847
-
848
- * Bug fix: URLs are now resolved correctly based on http://tools.ietf.org/html/rfc3986#section-5.2. #289
849
- * Bug fix: Absolute URLs with a path in a service description will now properly override the base URL. #289
850
- * Bug fix: Parsing a query string with a single PHP array value will now result in an array. #263
851
- * Bug fix: Better normalization of the User-Agent header to prevent duplicate headers. #264.
852
- * Bug fix: Added `number` type to service descriptions.
853
- * Bug fix: empty parameters are removed from an OAuth signature
854
- * Bug fix: Revalidating a cache entry prefers the Last-Modified over the Date header
855
- * Bug fix: Fixed "array to string" error when validating a union of types in a service description
856
- * Bug fix: Removed code that attempted to determine the size of a stream when data is written to the stream
857
- * Bug fix: Not including an `oauth_token` if the value is null in the OauthPlugin.
858
- * Bug fix: Now correctly aggregating successful requests and failed requests in CurlMulti when a redirect occurs.
859
- * The new default CURLOPT_TIMEOUT setting has been increased to 150 seconds so that Guzzle works on poor connections.
860
- * Added a feature to EntityEnclosingRequest::setBody() that will automatically set the Content-Type of the request if
861
- the Content-Type can be determined based on the entity body or the path of the request.
862
- * Added the ability to overwrite configuration settings in a client when grabbing a throwaway client from a builder.
863
- * Added support for a PSR-3 LogAdapter.
864
- * Added a `command.after_prepare` event
865
- * Added `oauth_callback` parameter to the OauthPlugin
866
- * Added the ability to create a custom stream class when using a stream factory
867
- * Added a CachingEntityBody decorator
868
- * Added support for `additionalParameters` in service descriptions to define how custom parameters are serialized.
869
- * The bundled SSL certificate is now provided in the phar file and extracted when running Guzzle from a phar.
870
- * You can now send any EntityEnclosingRequest with POST fields or POST files and cURL will handle creating bodies
871
- * POST requests using a custom entity body are now treated exactly like PUT requests but with a custom cURL method. This
872
- means that the redirect behavior of POST requests with custom bodies will not be the same as POST requests that use
873
- POST fields or files (the latter is only used when emulating a form POST in the browser).
874
- * Lots of cleanup to CurlHandle::factory and RequestFactory::createRequest
875
-
876
- ## 3.3.1 - 2013-03-10
877
-
878
- * Added the ability to create PHP streaming responses from HTTP requests
879
- * Bug fix: Running any filters when parsing response headers with service descriptions
880
- * Bug fix: OauthPlugin fixes to allow for multi-dimensional array signing, and sorting parameters before signing
881
- * Bug fix: Removed the adding of default empty arrays and false Booleans to responses in order to be consistent across
882
- response location visitors.
883
- * Bug fix: Removed the possibility of creating configuration files with circular dependencies
884
- * RequestFactory::create() now uses the key of a POST file when setting the POST file name
885
- * Added xmlAllowEmpty to serialize an XML body even if no XML specific parameters are set
886
-
887
- ## 3.3.0 - 2013-03-03
888
-
889
- * A large number of performance optimizations have been made
890
- * Bug fix: Added 'wb' as a valid write mode for streams
891
- * Bug fix: `Guzzle\Http\Message\Response::json()` now allows scalar values to be returned
892
- * Bug fix: Fixed bug in `Guzzle\Http\Message\Response` where wrapping quotes were stripped from `getEtag()`
893
- * BC: Removed `Guzzle\Http\Utils` class
894
- * BC: Setting a service description on a client will no longer modify the client's command factories.
895
- * BC: Emitting IO events from a RequestMediator is now a parameter that must be set in a request's curl options using
896
- the 'emit_io' key. This was previously set under a request's parameters using 'curl.emit_io'
897
- * BC: `Guzzle\Stream\Stream::getWrapper()` and `Guzzle\Stream\Stream::getSteamType()` are no longer converted to
898
- lowercase
899
- * Operation parameter objects are now lazy loaded internally
900
- * Added ErrorResponsePlugin that can throw errors for responses defined in service description operations' errorResponses
901
- * Added support for instantiating responseType=class responseClass classes. Classes must implement
902
- `Guzzle\Service\Command\ResponseClassInterface`
903
- * Added support for additionalProperties for top-level parameters in responseType=model responseClasses. These
904
- additional properties also support locations and can be used to parse JSON responses where the outermost part of the
905
- JSON is an array
906
- * Added support for nested renaming of JSON models (rename sentAs to name)
907
- * CachePlugin
908
- * Added support for stale-if-error so that the CachePlugin can now serve stale content from the cache on error
909
- * Debug headers can now added to cached response in the CachePlugin
910
-
911
- ## 3.2.0 - 2013-02-14
912
-
913
- * CurlMulti is no longer reused globally. A new multi object is created per-client. This helps to isolate clients.
914
- * URLs with no path no longer contain a "/" by default
915
- * Guzzle\Http\QueryString does no longer manages the leading "?". This is now handled in Guzzle\Http\Url.
916
- * BadResponseException no longer includes the full request and response message
917
- * Adding setData() to Guzzle\Service\Description\ServiceDescriptionInterface
918
- * Adding getResponseBody() to Guzzle\Http\Message\RequestInterface
919
- * Various updates to classes to use ServiceDescriptionInterface type hints rather than ServiceDescription
920
- * Header values can now be normalized into distinct values when multiple headers are combined with a comma separated list
921
- * xmlEncoding can now be customized for the XML declaration of a XML service description operation
922
- * Guzzle\Http\QueryString now uses Guzzle\Http\QueryAggregator\QueryAggregatorInterface objects to add custom value
923
- aggregation and no longer uses callbacks
924
- * The URL encoding implementation of Guzzle\Http\QueryString can now be customized
925
- * Bug fix: Filters were not always invoked for array service description parameters
926
- * Bug fix: Redirects now use a target response body rather than a temporary response body
927
- * Bug fix: The default exponential backoff BackoffPlugin was not giving when the request threshold was exceeded
928
- * Bug fix: Guzzle now takes the first found value when grabbing Cache-Control directives
929
-
930
- ## 3.1.2 - 2013-01-27
931
-
932
- * Refactored how operation responses are parsed. Visitors now include a before() method responsible for parsing the
933
- response body. For example, the XmlVisitor now parses the XML response into an array in the before() method.
934
- * Fixed an issue where cURL would not automatically decompress responses when the Accept-Encoding header was sent
935
- * CURLOPT_SSL_VERIFYHOST is never set to 1 because it is deprecated (see 5e0ff2ef20f839e19d1eeb298f90ba3598784444)
936
- * Fixed a bug where redirect responses were not chained correctly using getPreviousResponse()
937
- * Setting default headers on a client after setting the user-agent will not erase the user-agent setting
938
-
939
- ## 3.1.1 - 2013-01-20
940
-
941
- * Adding wildcard support to Guzzle\Common\Collection::getPath()
942
- * Adding alias support to ServiceBuilder configs
943
- * Adding Guzzle\Service\Resource\CompositeResourceIteratorFactory and cleaning up factory interface
944
-
945
- ## 3.1.0 - 2013-01-12
946
-
947
- * BC: CurlException now extends from RequestException rather than BadResponseException
948
- * BC: Renamed Guzzle\Plugin\Cache\CanCacheStrategyInterface::canCache() to canCacheRequest() and added CanCacheResponse()
949
- * Added getData to ServiceDescriptionInterface
950
- * Added context array to RequestInterface::setState()
951
- * Bug: Removing hard dependency on the BackoffPlugin from Guzzle\Http
952
- * Bug: Adding required content-type when JSON request visitor adds JSON to a command
953
- * Bug: Fixing the serialization of a service description with custom data
954
- * Made it easier to deal with exceptions thrown when transferring commands or requests in parallel by providing
955
- an array of successful and failed responses
956
- * Moved getPath from Guzzle\Service\Resource\Model to Guzzle\Common\Collection
957
- * Added Guzzle\Http\IoEmittingEntityBody
958
- * Moved command filtration from validators to location visitors
959
- * Added `extends` attributes to service description parameters
960
- * Added getModels to ServiceDescriptionInterface
961
-
962
- ## 3.0.7 - 2012-12-19
963
-
964
- * Fixing phar detection when forcing a cacert to system if null or true
965
- * Allowing filename to be passed to `Guzzle\Http\Message\Request::setResponseBody()`
966
- * Cleaning up `Guzzle\Common\Collection::inject` method
967
- * Adding a response_body location to service descriptions
968
-
969
- ## 3.0.6 - 2012-12-09
970
-
971
- * CurlMulti performance improvements
972
- * Adding setErrorResponses() to Operation
973
- * composer.json tweaks
974
-
975
- ## 3.0.5 - 2012-11-18
976
-
977
- * Bug: Fixing an infinite recursion bug caused from revalidating with the CachePlugin
978
- * Bug: Response body can now be a string containing "0"
979
- * Bug: Using Guzzle inside of a phar uses system by default but now allows for a custom cacert
980
- * Bug: QueryString::fromString now properly parses query string parameters that contain equal signs
981
- * Added support for XML attributes in service description responses
982
- * DefaultRequestSerializer now supports array URI parameter values for URI template expansion
983
- * Added better mimetype guessing to requests and post files
984
-
985
- ## 3.0.4 - 2012-11-11
986
-
987
- * Bug: Fixed a bug when adding multiple cookies to a request to use the correct glue value
988
- * Bug: Cookies can now be added that have a name, domain, or value set to "0"
989
- * Bug: Using the system cacert bundle when using the Phar
990
- * Added json and xml methods to Response to make it easier to parse JSON and XML response data into data structures
991
- * Enhanced cookie jar de-duplication
992
- * Added the ability to enable strict cookie jars that throw exceptions when invalid cookies are added
993
- * Added setStream to StreamInterface to actually make it possible to implement custom rewind behavior for entity bodies
994
- * Added the ability to create any sort of hash for a stream rather than just an MD5 hash
995
-
996
- ## 3.0.3 - 2012-11-04
997
-
998
- * Implementing redirects in PHP rather than cURL
999
- * Added PECL URI template extension and using as default parser if available
1000
- * Bug: Fixed Content-Length parsing of Response factory
1001
- * Adding rewind() method to entity bodies and streams. Allows for custom rewinding of non-repeatable streams.
1002
- * Adding ToArrayInterface throughout library
1003
- * Fixing OauthPlugin to create unique nonce values per request
1004
-
1005
- ## 3.0.2 - 2012-10-25
1006
-
1007
- * Magic methods are enabled by default on clients
1008
- * Magic methods return the result of a command
1009
- * Service clients no longer require a base_url option in the factory
1010
- * Bug: Fixed an issue with URI templates where null template variables were being expanded
1011
-
1012
- ## 3.0.1 - 2012-10-22
1013
-
1014
- * Models can now be used like regular collection objects by calling filter, map, etc.
1015
- * Models no longer require a Parameter structure or initial data in the constructor
1016
- * Added a custom AppendIterator to get around a PHP bug with the `\AppendIterator`
1017
-
1018
- ## 3.0.0 - 2012-10-15
1019
-
1020
- * Rewrote service description format to be based on Swagger
1021
- * Now based on JSON schema
1022
- * Added nested input structures and nested response models
1023
- * Support for JSON and XML input and output models
1024
- * Renamed `commands` to `operations`
1025
- * Removed dot class notation
1026
- * Removed custom types
1027
- * Broke the project into smaller top-level namespaces to be more component friendly
1028
- * Removed support for XML configs and descriptions. Use arrays or JSON files.
1029
- * Removed the Validation component and Inspector
1030
- * Moved all cookie code to Guzzle\Plugin\Cookie
1031
- * Magic methods on a Guzzle\Service\Client now return the command un-executed.
1032
- * Calling getResult() or getResponse() on a command will lazily execute the command if needed.
1033
- * Now shipping with cURL's CA certs and using it by default
1034
- * Added previousResponse() method to response objects
1035
- * No longer sending Accept and Accept-Encoding headers on every request
1036
- * Only sending an Expect header by default when a payload is greater than 1MB
1037
- * Added/moved client options:
1038
- * curl.blacklist to curl.option.blacklist
1039
- * Added ssl.certificate_authority
1040
- * Added a Guzzle\Iterator component
1041
- * Moved plugins from Guzzle\Http\Plugin to Guzzle\Plugin
1042
- * Added a more robust backoff retry strategy (replaced the ExponentialBackoffPlugin)
1043
- * Added a more robust caching plugin
1044
- * Added setBody to response objects
1045
- * Updating LogPlugin to use a more flexible MessageFormatter
1046
- * Added a completely revamped build process
1047
- * Cleaning up Collection class and removing default values from the get method
1048
- * Fixed ZF2 cache adapters
1049
-
1050
- ## 2.8.8 - 2012-10-15
1051
-
1052
- * Bug: Fixed a cookie issue that caused dot prefixed domains to not match where popular browsers did
1053
-
1054
- ## 2.8.7 - 2012-09-30
1055
-
1056
- * Bug: Fixed config file aliases for JSON includes
1057
- * Bug: Fixed cookie bug on a request object by using CookieParser to parse cookies on requests
1058
- * Bug: Removing the path to a file when sending a Content-Disposition header on a POST upload
1059
- * Bug: Hardening request and response parsing to account for missing parts
1060
- * Bug: Fixed PEAR packaging
1061
- * Bug: Fixed Request::getInfo
1062
- * Bug: Fixed cases where CURLM_CALL_MULTI_PERFORM return codes were causing curl transactions to fail
1063
- * Adding the ability for the namespace Iterator factory to look in multiple directories
1064
- * Added more getters/setters/removers from service descriptions
1065
- * Added the ability to remove POST fields from OAuth signatures
1066
- * OAuth plugin now supports 2-legged OAuth
1067
-
1068
- ## 2.8.6 - 2012-09-05
1069
-
1070
- * Added the ability to modify and build service descriptions
1071
- * Added the use of visitors to apply parameters to locations in service descriptions using the dynamic command
1072
- * Added a `json` parameter location
1073
- * Now allowing dot notation for classes in the CacheAdapterFactory
1074
- * Using the union of two arrays rather than an array_merge when extending service builder services and service params
1075
- * Ensuring that a service is a string before doing strpos() checks on it when substituting services for references
1076
- in service builder config files.
1077
- * Services defined in two different config files that include one another will by default replace the previously
1078
- defined service, but you can now create services that extend themselves and merge their settings over the previous
1079
- * The JsonLoader now supports aliasing filenames with different filenames. This allows you to alias something like
1080
- '_default' with a default JSON configuration file.
1081
-
1082
- ## 2.8.5 - 2012-08-29
1083
-
1084
- * Bug: Suppressed empty arrays from URI templates
1085
- * Bug: Added the missing $options argument from ServiceDescription::factory to enable caching
1086
- * Added support for HTTP responses that do not contain a reason phrase in the start-line
1087
- * AbstractCommand commands are now invokable
1088
- * Added a way to get the data used when signing an Oauth request before a request is sent
1089
-
1090
- ## 2.8.4 - 2012-08-15
1091
-
1092
- * Bug: Custom delay time calculations are no longer ignored in the ExponentialBackoffPlugin
1093
- * Added the ability to transfer entity bodies as a string rather than streamed. This gets around curl error 65. Set `body_as_string` in a request's curl options to enable.
1094
- * Added a StreamInterface, EntityBodyInterface, and added ftell() to Guzzle\Common\Stream
1095
- * Added an AbstractEntityBodyDecorator and a ReadLimitEntityBody decorator to transfer only a subset of a decorated stream
1096
- * Stream and EntityBody objects will now return the file position to the previous position after a read required operation (e.g. getContentMd5())
1097
- * Added additional response status codes
1098
- * Removed SSL information from the default User-Agent header
1099
- * DELETE requests can now send an entity body
1100
- * Added an EventDispatcher to the ExponentialBackoffPlugin and added an ExponentialBackoffLogger to log backoff retries
1101
- * Added the ability of the MockPlugin to consume mocked request bodies
1102
- * LogPlugin now exposes request and response objects in the extras array
1103
-
1104
- ## 2.8.3 - 2012-07-30
1105
-
1106
- * Bug: Fixed a case where empty POST requests were sent as GET requests
1107
- * Bug: Fixed a bug in ExponentialBackoffPlugin that caused fatal errors when retrying an EntityEnclosingRequest that does not have a body
1108
- * Bug: Setting the response body of a request to null after completing a request, not when setting the state of a request to new
1109
- * Added multiple inheritance to service description commands
1110
- * Added an ApiCommandInterface and added `getParamNames()` and `hasParam()`
1111
- * Removed the default 2mb size cutoff from the Md5ValidatorPlugin so that it now defaults to validating everything
1112
- * Changed CurlMulti::perform to pass a smaller timeout to CurlMulti::executeHandles
1113
-
1114
- ## 2.8.2 - 2012-07-24
1115
-
1116
- * Bug: Query string values set to 0 are no longer dropped from the query string
1117
- * Bug: A Collection object is no longer created each time a call is made to `Guzzle\Service\Command\AbstractCommand::getRequestHeaders()`
1118
- * Bug: `+` is now treated as an encoded space when parsing query strings
1119
- * QueryString and Collection performance improvements
1120
- * Allowing dot notation for class paths in filters attribute of a service descriptions
1121
-
1122
- ## 2.8.1 - 2012-07-16
1123
-
1124
- * Loosening Event Dispatcher dependency
1125
- * POST redirects can now be customized using CURLOPT_POSTREDIR
1126
-
1127
- ## 2.8.0 - 2012-07-15
1128
-
1129
- * BC: Guzzle\Http\Query
1130
- * Query strings with empty variables will always show an equal sign unless the variable is set to QueryString::BLANK (e.g. ?acl= vs ?acl)
1131
- * Changed isEncodingValues() and isEncodingFields() to isUrlEncoding()
1132
- * Changed setEncodeValues(bool) and setEncodeFields(bool) to useUrlEncoding(bool)
1133
- * Changed the aggregation functions of QueryString to be static methods
1134
- * Can now use fromString() with querystrings that have a leading ?
1135
- * cURL configuration values can be specified in service descriptions using `curl.` prefixed parameters
1136
- * Content-Length is set to 0 before emitting the request.before_send event when sending an empty request body
1137
- * Cookies are no longer URL decoded by default
1138
- * Bug: URI template variables set to null are no longer expanded
1139
-
1140
- ## 2.7.2 - 2012-07-02
1141
-
1142
- * BC: Moving things to get ready for subtree splits. Moving Inflection into Common. Moving Guzzle\Http\Parser to Guzzle\Parser.
1143
- * BC: Removing Guzzle\Common\Batch\Batch::count() and replacing it with isEmpty()
1144
- * CachePlugin now allows for a custom request parameter function to check if a request can be cached
1145
- * Bug fix: CachePlugin now only caches GET and HEAD requests by default
1146
- * Bug fix: Using header glue when transferring headers over the wire
1147
- * Allowing deeply nested arrays for composite variables in URI templates
1148
- * Batch divisors can now return iterators or arrays
1149
-
1150
- ## 2.7.1 - 2012-06-26
1151
-
1152
- * Minor patch to update version number in UA string
1153
- * Updating build process
1154
-
1155
- ## 2.7.0 - 2012-06-25
1156
-
1157
- * BC: Inflection classes moved to Guzzle\Inflection. No longer static methods. Can now inject custom inflectors into classes.
1158
- * BC: Removed magic setX methods from commands
1159
- * BC: Magic methods mapped to service description commands are now inflected in the command factory rather than the client __call() method
1160
- * Verbose cURL options are no longer enabled by default. Set curl.debug to true on a client to enable.
1161
- * Bug: Now allowing colons in a response start-line (e.g. HTTP/1.1 503 Service Unavailable: Back-end server is at capacity)
1162
- * Guzzle\Service\Resource\ResourceIteratorApplyBatched now internally uses the Guzzle\Common\Batch namespace
1163
- * Added Guzzle\Service\Plugin namespace and a PluginCollectionPlugin
1164
- * Added the ability to set POST fields and files in a service description
1165
- * Guzzle\Http\EntityBody::factory() now accepts objects with a __toString() method
1166
- * Adding a command.before_prepare event to clients
1167
- * Added BatchClosureTransfer and BatchClosureDivisor
1168
- * BatchTransferException now includes references to the batch divisor and transfer strategies
1169
- * Fixed some tests so that they pass more reliably
1170
- * Added Guzzle\Common\Log\ArrayLogAdapter
1171
-
1172
- ## 2.6.6 - 2012-06-10
1173
-
1174
- * BC: Removing Guzzle\Http\Plugin\BatchQueuePlugin
1175
- * BC: Removing Guzzle\Service\Command\CommandSet
1176
- * Adding generic batching system (replaces the batch queue plugin and command set)
1177
- * Updating ZF cache and log adapters and now using ZF's composer repository
1178
- * Bug: Setting the name of each ApiParam when creating through an ApiCommand
1179
- * Adding result_type, result_doc, deprecated, and doc_url to service descriptions
1180
- * Bug: Changed the default cookie header casing back to 'Cookie'
1181
-
1182
- ## 2.6.5 - 2012-06-03
1183
-
1184
- * BC: Renaming Guzzle\Http\Message\RequestInterface::getResourceUri() to getResource()
1185
- * BC: Removing unused AUTH_BASIC and AUTH_DIGEST constants from
1186
- * BC: Guzzle\Http\Cookie is now used to manage Set-Cookie data, not Cookie data
1187
- * BC: Renaming methods in the CookieJarInterface
1188
- * Moving almost all cookie logic out of the CookiePlugin and into the Cookie or CookieJar implementations
1189
- * Making the default glue for HTTP headers ';' instead of ','
1190
- * Adding a removeValue to Guzzle\Http\Message\Header
1191
- * Adding getCookies() to request interface.
1192
- * Making it easier to add event subscribers to HasDispatcherInterface classes. Can now directly call addSubscriber()
1193
-
1194
- ## 2.6.4 - 2012-05-30
1195
-
1196
- * BC: Cleaning up how POST files are stored in EntityEnclosingRequest objects. Adding PostFile class.
1197
- * BC: Moving ApiCommand specific functionality from the Inspector and on to the ApiCommand
1198
- * Bug: Fixing magic method command calls on clients
1199
- * Bug: Email constraint only validates strings
1200
- * Bug: Aggregate POST fields when POST files are present in curl handle
1201
- * Bug: Fixing default User-Agent header
1202
- * Bug: Only appending or prepending parameters in commands if they are specified
1203
- * Bug: Not requiring response reason phrases or status codes to match a predefined list of codes
1204
- * Allowing the use of dot notation for class namespaces when using instance_of constraint
1205
- * Added any_match validation constraint
1206
- * Added an AsyncPlugin
1207
- * Passing request object to the calculateWait method of the ExponentialBackoffPlugin
1208
- * Allowing the result of a command object to be changed
1209
- * Parsing location and type sub values when instantiating a service description rather than over and over at runtime
1210
-
1211
- ## 2.6.3 - 2012-05-23
1212
-
1213
- * [BC] Guzzle\Common\FromConfigInterface no longer requires any config options.
1214
- * [BC] Refactoring how POST files are stored on an EntityEnclosingRequest. They are now separate from POST fields.
1215
- * You can now use an array of data when creating PUT request bodies in the request factory.
1216
- * Removing the requirement that HTTPS requests needed a Cache-Control: public directive to be cacheable.
1217
- * [Http] Adding support for Content-Type in multipart POST uploads per upload
1218
- * [Http] Added support for uploading multiple files using the same name (foo[0], foo[1])
1219
- * Adding more POST data operations for easier manipulation of POST data.
1220
- * You can now set empty POST fields.
1221
- * The body of a request is only shown on EntityEnclosingRequest objects that do not use POST files.
1222
- * Split the Guzzle\Service\Inspector::validateConfig method into two methods. One to initialize when a command is created, and one to validate.
1223
- * CS updates
1224
-
1225
- ## 2.6.2 - 2012-05-19
1226
-
1227
- * [Http] Better handling of nested scope requests in CurlMulti. Requests are now always prepares in the send() method rather than the addRequest() method.
1228
-
1229
- ## 2.6.1 - 2012-05-19
1230
-
1231
- * [BC] Removing 'path' support in service descriptions. Use 'uri'.
1232
- * [BC] Guzzle\Service\Inspector::parseDocBlock is now protected. Adding getApiParamsForClass() with cache.
1233
- * [BC] Removing Guzzle\Common\NullObject. Use https://github.com/mtdowling/NullObject if you need it.
1234
- * [BC] Removing Guzzle\Common\XmlElement.
1235
- * All commands, both dynamic and concrete, have ApiCommand objects.
1236
- * Adding a fix for CurlMulti so that if all of the connections encounter some sort of curl error, then the loop exits.
1237
- * Adding checks to EntityEnclosingRequest so that empty POST files and fields are ignored.
1238
- * Making the method signature of Guzzle\Service\Builder\ServiceBuilder::factory more flexible.
1239
-
1240
- ## 2.6.0 - 2012-05-15
1241
-
1242
- * [BC] Moving Guzzle\Service\Builder to Guzzle\Service\Builder\ServiceBuilder
1243
- * [BC] Executing a Command returns the result of the command rather than the command
1244
- * [BC] Moving all HTTP parsing logic to Guzzle\Http\Parsers. Allows for faster C implementations if needed.
1245
- * [BC] Changing the Guzzle\Http\Message\Response::setProtocol() method to accept a protocol and version in separate args.
1246
- * [BC] Moving ResourceIterator* to Guzzle\Service\Resource
1247
- * [BC] Completely refactored ResourceIterators to iterate over a cloned command object
1248
- * [BC] Moved Guzzle\Http\UriTemplate to Guzzle\Http\Parser\UriTemplate\UriTemplate
1249
- * [BC] Guzzle\Guzzle is now deprecated
1250
- * Moving Guzzle\Common\Guzzle::inject to Guzzle\Common\Collection::inject
1251
- * Adding Guzzle\Version class to give version information about Guzzle
1252
- * Adding Guzzle\Http\Utils class to provide getDefaultUserAgent() and getHttpDate()
1253
- * Adding Guzzle\Curl\CurlVersion to manage caching curl_version() data
1254
- * ServiceDescription and ServiceBuilder are now cacheable using similar configs
1255
- * Changing the format of XML and JSON service builder configs. Backwards compatible.
1256
- * Cleaned up Cookie parsing
1257
- * Trimming the default Guzzle User-Agent header
1258
- * Adding a setOnComplete() method to Commands that is called when a command completes
1259
- * Keeping track of requests that were mocked in the MockPlugin
1260
- * Fixed a caching bug in the CacheAdapterFactory
1261
- * Inspector objects can be injected into a Command object
1262
- * Refactoring a lot of code and tests to be case insensitive when dealing with headers
1263
- * Adding Guzzle\Http\Message\HeaderComparison for easy comparison of HTTP headers using a DSL
1264
- * Adding the ability to set global option overrides to service builder configs
1265
- * Adding the ability to include other service builder config files from within XML and JSON files
1266
- * Moving the parseQuery method out of Url and on to QueryString::fromString() as a static factory method.
1267
-
1268
- ## 2.5.0 - 2012-05-08
1269
-
1270
- * Major performance improvements
1271
- * [BC] Simplifying Guzzle\Common\Collection. Please check to see if you are using features that are now deprecated.
1272
- * [BC] Using a custom validation system that allows a flyweight implementation for much faster validation. No longer using Symfony2 Validation component.
1273
- * [BC] No longer supporting "{{ }}" for injecting into command or UriTemplates. Use "{}"
1274
- * Added the ability to passed parameters to all requests created by a client
1275
- * Added callback functionality to the ExponentialBackoffPlugin
1276
- * Using microtime in ExponentialBackoffPlugin to allow more granular backoff strategies.
1277
- * Rewinding request stream bodies when retrying requests
1278
- * Exception is thrown when JSON response body cannot be decoded
1279
- * Added configurable magic method calls to clients and commands. This is off by default.
1280
- * Fixed a defect that added a hash to every parsed URL part
1281
- * Fixed duplicate none generation for OauthPlugin.
1282
- * Emitting an event each time a client is generated by a ServiceBuilder
1283
- * Using an ApiParams object instead of a Collection for parameters of an ApiCommand
1284
- * cache.* request parameters should be renamed to params.cache.*
1285
- * Added the ability to set arbitrary curl options on requests (disable_wire, progress, etc.). See CurlHandle.
1286
- * Added the ability to disable type validation of service descriptions
1287
- * ServiceDescriptions and ServiceBuilders are now Serializable
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/guzzle/LICENSE DELETED
@@ -1,19 +0,0 @@
1
- Copyright (c) 2011-2018 Michael Dowling, https://github.com/mtdowling <mtdowling@gmail.com>
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining a copy
4
- of this software and associated documentation files (the "Software"), to deal
5
- in the Software without restriction, including without limitation the rights
6
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
- copies of the Software, and to permit persons to whom the Software is
8
- furnished to do so, subject to the following conditions:
9
-
10
- The above copyright notice and this permission notice shall be included in
11
- all copies or substantial portions of the Software.
12
-
13
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
- THE SOFTWARE.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/guzzle/README.md DELETED
@@ -1,91 +0,0 @@
1
- Guzzle, PHP HTTP client
2
- =======================
3
-
4
- [![Latest Version](https://img.shields.io/github/release/guzzle/guzzle.svg?style=flat-square)](https://github.com/guzzle/guzzle/releases)
5
- [![Build Status](https://img.shields.io/travis/guzzle/guzzle.svg?style=flat-square)](https://travis-ci.org/guzzle/guzzle)
6
- [![Total Downloads](https://img.shields.io/packagist/dt/guzzlehttp/guzzle.svg?style=flat-square)](https://packagist.org/packages/guzzlehttp/guzzle)
7
-
8
- Guzzle is a PHP HTTP client that makes it easy to send HTTP requests and
9
- trivial to integrate with web services.
10
-
11
- - Simple interface for building query strings, POST requests, streaming large
12
- uploads, streaming large downloads, using HTTP cookies, uploading JSON data,
13
- etc...
14
- - Can send both synchronous and asynchronous requests using the same interface.
15
- - Uses PSR-7 interfaces for requests, responses, and streams. This allows you
16
- to utilize other PSR-7 compatible libraries with Guzzle.
17
- - Abstracts away the underlying HTTP transport, allowing you to write
18
- environment and transport agnostic code; i.e., no hard dependency on cURL,
19
- PHP streams, sockets, or non-blocking event loops.
20
- - Middleware system allows you to augment and compose client behavior.
21
-
22
- ```php
23
- $client = new \GuzzleHttp\Client();
24
- $res = $client->request('GET', 'https://api.github.com/repos/guzzle/guzzle');
25
- echo $res->getStatusCode();
26
- // 200
27
- echo $res->getHeaderLine('content-type');
28
- // 'application/json; charset=utf8'
29
- echo $res->getBody();
30
- // '{"id": 1420053, "name": "guzzle", ...}'
31
-
32
- // Send an asynchronous request.
33
- $request = new \GuzzleHttp\Psr7\Request('GET', 'http://httpbin.org');
34
- $promise = $client->sendAsync($request)->then(function ($response) {
35
- echo 'I completed! ' . $response->getBody();
36
- });
37
- $promise->wait();
38
- ```
39
-
40
- ## Help and docs
41
-
42
- - [Documentation](http://guzzlephp.org/)
43
- - [Stack Overflow](http://stackoverflow.com/questions/tagged/guzzle)
44
- - [Gitter](https://gitter.im/guzzle/guzzle)
45
-
46
-
47
- ## Installing Guzzle
48
-
49
- The recommended way to install Guzzle is through
50
- [Composer](http://getcomposer.org).
51
-
52
- ```bash
53
- # Install Composer
54
- curl -sS https://getcomposer.org/installer | php
55
- ```
56
-
57
- Next, run the Composer command to install the latest stable version of Guzzle:
58
-
59
- ```bash
60
- php composer.phar require guzzlehttp/guzzle
61
- ```
62
-
63
- After installing, you need to require Composer's autoloader:
64
-
65
- ```php
66
- require 'vendor/autoload.php';
67
- ```
68
-
69
- You can then later update Guzzle using composer:
70
-
71
- ```bash
72
- composer.phar update
73
- ```
74
-
75
-
76
- ## Version Guidance
77
-
78
- | Version | Status | Packagist | Namespace | Repo | Docs | PSR-7 | PHP Version |
79
- |---------|------------|---------------------|--------------|---------------------|---------------------|-------|-------------|
80
- | 3.x | EOL | `guzzle/guzzle` | `Guzzle` | [v3][guzzle-3-repo] | [v3][guzzle-3-docs] | No | >= 5.3.3 |
81
- | 4.x | EOL | `guzzlehttp/guzzle` | `GuzzleHttp` | [v4][guzzle-4-repo] | N/A | No | >= 5.4 |
82
- | 5.x | Maintained | `guzzlehttp/guzzle` | `GuzzleHttp` | [v5][guzzle-5-repo] | [v5][guzzle-5-docs] | No | >= 5.4 |
83
- | 6.x | Latest | `guzzlehttp/guzzle` | `GuzzleHttp` | [v6][guzzle-6-repo] | [v6][guzzle-6-docs] | Yes | >= 5.5 |
84
-
85
- [guzzle-3-repo]: https://github.com/guzzle/guzzle3
86
- [guzzle-4-repo]: https://github.com/guzzle/guzzle/tree/4.x
87
- [guzzle-5-repo]: https://github.com/guzzle/guzzle/tree/5.3
88
- [guzzle-6-repo]: https://github.com/guzzle/guzzle
89
- [guzzle-3-docs]: http://guzzle3.readthedocs.org/en/latest/
90
- [guzzle-5-docs]: http://guzzle.readthedocs.org/en/5.3/
91
- [guzzle-6-docs]: http://guzzle.readthedocs.org/en/latest/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/guzzle/UPGRADING.md DELETED
@@ -1,1203 +0,0 @@
1
- Guzzle Upgrade Guide
2
- ====================
3
-
4
- 5.0 to 6.0
5
- ----------
6
-
7
- Guzzle now uses [PSR-7](http://www.php-fig.org/psr/psr-7/) for HTTP messages.
8
- Due to the fact that these messages are immutable, this prompted a refactoring
9
- of Guzzle to use a middleware based system rather than an event system. Any
10
- HTTP message interaction (e.g., `GuzzleHttp\Message\Request`) need to be
11
- updated to work with the new immutable PSR-7 request and response objects. Any
12
- event listeners or subscribers need to be updated to become middleware
13
- functions that wrap handlers (or are injected into a
14
- `GuzzleHttp\HandlerStack`).
15
-
16
- - Removed `GuzzleHttp\BatchResults`
17
- - Removed `GuzzleHttp\Collection`
18
- - Removed `GuzzleHttp\HasDataTrait`
19
- - Removed `GuzzleHttp\ToArrayInterface`
20
- - The `guzzlehttp/streams` dependency has been removed. Stream functionality
21
- is now present in the `GuzzleHttp\Psr7` namespace provided by the
22
- `guzzlehttp/psr7` package.
23
- - Guzzle no longer uses ReactPHP promises and now uses the
24
- `guzzlehttp/promises` library. We use a custom promise library for three
25
- significant reasons:
26
- 1. React promises (at the time of writing this) are recursive. Promise
27
- chaining and promise resolution will eventually blow the stack. Guzzle
28
- promises are not recursive as they use a sort of trampolining technique.
29
- Note: there has been movement in the React project to modify promises to
30
- no longer utilize recursion.
31
- 2. Guzzle needs to have the ability to synchronously block on a promise to
32
- wait for a result. Guzzle promises allows this functionality (and does
33
- not require the use of recursion).
34
- 3. Because we need to be able to wait on a result, doing so using React
35
- promises requires wrapping react promises with RingPHP futures. This
36
- overhead is no longer needed, reducing stack sizes, reducing complexity,
37
- and improving performance.
38
- - `GuzzleHttp\Mimetypes` has been moved to a function in
39
- `GuzzleHttp\Psr7\mimetype_from_extension` and
40
- `GuzzleHttp\Psr7\mimetype_from_filename`.
41
- - `GuzzleHttp\Query` and `GuzzleHttp\QueryParser` have been removed. Query
42
- strings must now be passed into request objects as strings, or provided to
43
- the `query` request option when creating requests with clients. The `query`
44
- option uses PHP's `http_build_query` to convert an array to a string. If you
45
- need a different serialization technique, you will need to pass the query
46
- string in as a string. There are a couple helper functions that will make
47
- working with query strings easier: `GuzzleHttp\Psr7\parse_query` and
48
- `GuzzleHttp\Psr7\build_query`.
49
- - Guzzle no longer has a dependency on RingPHP. Due to the use of a middleware
50
- system based on PSR-7, using RingPHP and it's middleware system as well adds
51
- more complexity than the benefits it provides. All HTTP handlers that were
52
- present in RingPHP have been modified to work directly with PSR-7 messages
53
- and placed in the `GuzzleHttp\Handler` namespace. This significantly reduces
54
- complexity in Guzzle, removes a dependency, and improves performance. RingPHP
55
- will be maintained for Guzzle 5 support, but will no longer be a part of
56
- Guzzle 6.
57
- - As Guzzle now uses a middleware based systems the event system and RingPHP
58
- integration has been removed. Note: while the event system has been removed,
59
- it is possible to add your own type of event system that is powered by the
60
- middleware system.
61
- - Removed the `Event` namespace.
62
- - Removed the `Subscriber` namespace.
63
- - Removed `Transaction` class
64
- - Removed `RequestFsm`
65
- - Removed `RingBridge`
66
- - `GuzzleHttp\Subscriber\Cookie` is now provided by
67
- `GuzzleHttp\Middleware::cookies`
68
- - `GuzzleHttp\Subscriber\HttpError` is now provided by
69
- `GuzzleHttp\Middleware::httpError`
70
- - `GuzzleHttp\Subscriber\History` is now provided by
71
- `GuzzleHttp\Middleware::history`
72
- - `GuzzleHttp\Subscriber\Mock` is now provided by
73
- `GuzzleHttp\Handler\MockHandler`
74
- - `GuzzleHttp\Subscriber\Prepare` is now provided by
75
- `GuzzleHttp\PrepareBodyMiddleware`
76
- - `GuzzleHttp\Subscriber\Redirect` is now provided by
77
- `GuzzleHttp\RedirectMiddleware`
78
- - Guzzle now uses `Psr\Http\Message\UriInterface` (implements in
79
- `GuzzleHttp\Psr7\Uri`) for URI support. `GuzzleHttp\Url` is now gone.
80
- - Static functions in `GuzzleHttp\Utils` have been moved to namespaced
81
- functions under the `GuzzleHttp` namespace. This requires either a Composer
82
- based autoloader or you to include functions.php.
83
- - `GuzzleHttp\ClientInterface::getDefaultOption` has been renamed to
84
- `GuzzleHttp\ClientInterface::getConfig`.
85
- - `GuzzleHttp\ClientInterface::setDefaultOption` has been removed.
86
- - The `json` and `xml` methods of response objects has been removed. With the
87
- migration to strictly adhering to PSR-7 as the interface for Guzzle messages,
88
- adding methods to message interfaces would actually require Guzzle messages
89
- to extend from PSR-7 messages rather then work with them directly.
90
-
91
- ## Migrating to middleware
92
-
93
- The change to PSR-7 unfortunately required significant refactoring to Guzzle
94
- due to the fact that PSR-7 messages are immutable. Guzzle 5 relied on an event
95
- system from plugins. The event system relied on mutability of HTTP messages and
96
- side effects in order to work. With immutable messages, you have to change your
97
- workflow to become more about either returning a value (e.g., functional
98
- middlewares) or setting a value on an object. Guzzle v6 has chosen the
99
- functional middleware approach.
100
-
101
- Instead of using the event system to listen for things like the `before` event,
102
- you now create a stack based middleware function that intercepts a request on
103
- the way in and the promise of the response on the way out. This is a much
104
- simpler and more predictable approach than the event system and works nicely
105
- with PSR-7 middleware. Due to the use of promises, the middleware system is
106
- also asynchronous.
107
-
108
- v5:
109
-
110
- ```php
111
- use GuzzleHttp\Event\BeforeEvent;
112
- $client = new GuzzleHttp\Client();
113
- // Get the emitter and listen to the before event.
114
- $client->getEmitter()->on('before', function (BeforeEvent $e) {
115
- // Guzzle v5 events relied on mutation
116
- $e->getRequest()->setHeader('X-Foo', 'Bar');
117
- });
118
- ```
119
-
120
- v6:
121
-
122
- In v6, you can modify the request before it is sent using the `mapRequest`
123
- middleware. The idiomatic way in v6 to modify the request/response lifecycle is
124
- to setup a handler middleware stack up front and inject the handler into a
125
- client.
126
-
127
- ```php
128
- use GuzzleHttp\Middleware;
129
- // Create a handler stack that has all of the default middlewares attached
130
- $handler = GuzzleHttp\HandlerStack::create();
131
- // Push the handler onto the handler stack
132
- $handler->push(Middleware::mapRequest(function (RequestInterface $request) {
133
- // Notice that we have to return a request object
134
- return $request->withHeader('X-Foo', 'Bar');
135
- }));
136
- // Inject the handler into the client
137
- $client = new GuzzleHttp\Client(['handler' => $handler]);
138
- ```
139
-
140
- ## POST Requests
141
-
142
- This version added the [`form_params`](http://guzzle.readthedocs.org/en/latest/request-options.html#form_params)
143
- and `multipart` request options. `form_params` is an associative array of
144
- strings or array of strings and is used to serialize an
145
- `application/x-www-form-urlencoded` POST request. The
146
- [`multipart`](http://guzzle.readthedocs.org/en/latest/request-options.html#multipart)
147
- option is now used to send a multipart/form-data POST request.
148
-
149
- `GuzzleHttp\Post\PostFile` has been removed. Use the `multipart` option to add
150
- POST files to a multipart/form-data request.
151
-
152
- The `body` option no longer accepts an array to send POST requests. Please use
153
- `multipart` or `form_params` instead.
154
-
155
- The `base_url` option has been renamed to `base_uri`.
156
-
157
- 4.x to 5.0
158
- ----------
159
-
160
- ## Rewritten Adapter Layer
161
-
162
- Guzzle now uses [RingPHP](http://ringphp.readthedocs.org/en/latest) to send
163
- HTTP requests. The `adapter` option in a `GuzzleHttp\Client` constructor
164
- is still supported, but it has now been renamed to `handler`. Instead of
165
- passing a `GuzzleHttp\Adapter\AdapterInterface`, you must now pass a PHP
166
- `callable` that follows the RingPHP specification.
167
-
168
- ## Removed Fluent Interfaces
169
-
170
- [Fluent interfaces were removed](http://ocramius.github.io/blog/fluent-interfaces-are-evil)
171
- from the following classes:
172
-
173
- - `GuzzleHttp\Collection`
174
- - `GuzzleHttp\Url`
175
- - `GuzzleHttp\Query`
176
- - `GuzzleHttp\Post\PostBody`
177
- - `GuzzleHttp\Cookie\SetCookie`
178
-
179
- ## Removed functions.php
180
-
181
- Removed "functions.php", so that Guzzle is truly PSR-4 compliant. The following
182
- functions can be used as replacements.
183
-
184
- - `GuzzleHttp\json_decode` -> `GuzzleHttp\Utils::jsonDecode`
185
- - `GuzzleHttp\get_path` -> `GuzzleHttp\Utils::getPath`
186
- - `GuzzleHttp\Utils::setPath` -> `GuzzleHttp\set_path`
187
- - `GuzzleHttp\Pool::batch` -> `GuzzleHttp\batch`. This function is, however,
188
- deprecated in favor of using `GuzzleHttp\Pool::batch()`.
189
-
190
- The "procedural" global client has been removed with no replacement (e.g.,
191
- `GuzzleHttp\get()`, `GuzzleHttp\post()`, etc.). Use a `GuzzleHttp\Client`
192
- object as a replacement.
193
-
194
- ## `throwImmediately` has been removed
195
-
196
- The concept of "throwImmediately" has been removed from exceptions and error
197
- events. This control mechanism was used to stop a transfer of concurrent
198
- requests from completing. This can now be handled by throwing the exception or
199
- by cancelling a pool of requests or each outstanding future request
200
- individually.
201
-
202
- ## headers event has been removed
203
-
204
- Removed the "headers" event. This event was only useful for changing the
205
- body a response once the headers of the response were known. You can implement
206
- a similar behavior in a number of ways. One example might be to use a
207
- FnStream that has access to the transaction being sent. For example, when the
208
- first byte is written, you could check if the response headers match your
209
- expectations, and if so, change the actual stream body that is being
210
- written to.
211
-
212
- ## Updates to HTTP Messages
213
-
214
- Removed the `asArray` parameter from
215
- `GuzzleHttp\Message\MessageInterface::getHeader`. If you want to get a header
216
- value as an array, then use the newly added `getHeaderAsArray()` method of
217
- `MessageInterface`. This change makes the Guzzle interfaces compatible with
218
- the PSR-7 interfaces.
219
-
220
- 3.x to 4.0
221
- ----------
222
-
223
- ## Overarching changes:
224
-
225
- - Now requires PHP 5.4 or greater.
226
- - No longer requires cURL to send requests.
227
- - Guzzle no longer wraps every exception it throws. Only exceptions that are
228
- recoverable are now wrapped by Guzzle.
229
- - Various namespaces have been removed or renamed.
230
- - No longer requiring the Symfony EventDispatcher. A custom event dispatcher
231
- based on the Symfony EventDispatcher is
232
- now utilized in `GuzzleHttp\Event\EmitterInterface` (resulting in significant
233
- speed and functionality improvements).
234
-
235
- Changes per Guzzle 3.x namespace are described below.
236
-
237
- ## Batch
238
-
239
- The `Guzzle\Batch` namespace has been removed. This is best left to
240
- third-parties to implement on top of Guzzle's core HTTP library.
241
-
242
- ## Cache
243
-
244
- The `Guzzle\Cache` namespace has been removed. (Todo: No suitable replacement
245
- has been implemented yet, but hoping to utilize a PSR cache interface).
246
-
247
- ## Common
248
-
249
- - Removed all of the wrapped exceptions. It's better to use the standard PHP
250
- library for unrecoverable exceptions.
251
- - `FromConfigInterface` has been removed.
252
- - `Guzzle\Common\Version` has been removed. The VERSION constant can be found
253
- at `GuzzleHttp\ClientInterface::VERSION`.
254
-
255
- ### Collection
256
-
257
- - `getAll` has been removed. Use `toArray` to convert a collection to an array.
258
- - `inject` has been removed.
259
- - `keySearch` has been removed.
260
- - `getPath` no longer supports wildcard expressions. Use something better like
261
- JMESPath for this.
262
- - `setPath` now supports appending to an existing array via the `[]` notation.
263
-
264
- ### Events
265
-
266
- Guzzle no longer requires Symfony's EventDispatcher component. Guzzle now uses
267
- `GuzzleHttp\Event\Emitter`.
268
-
269
- - `Symfony\Component\EventDispatcher\EventDispatcherInterface` is replaced by
270
- `GuzzleHttp\Event\EmitterInterface`.
271
- - `Symfony\Component\EventDispatcher\EventDispatcher` is replaced by
272
- `GuzzleHttp\Event\Emitter`.
273
- - `Symfony\Component\EventDispatcher\Event` is replaced by
274
- `GuzzleHttp\Event\Event`, and Guzzle now has an EventInterface in
275
- `GuzzleHttp\Event\EventInterface`.
276
- - `AbstractHasDispatcher` has moved to a trait, `HasEmitterTrait`, and
277
- `HasDispatcherInterface` has moved to `HasEmitterInterface`. Retrieving the
278
- event emitter of a request, client, etc. now uses the `getEmitter` method
279
- rather than the `getDispatcher` method.
280
-
281
- #### Emitter
282
-
283
- - Use the `once()` method to add a listener that automatically removes itself
284
- the first time it is invoked.
285
- - Use the `listeners()` method to retrieve a list of event listeners rather than
286
- the `getListeners()` method.
287
- - Use `emit()` instead of `dispatch()` to emit an event from an emitter.
288
- - Use `attach()` instead of `addSubscriber()` and `detach()` instead of
289
- `removeSubscriber()`.
290
-
291
- ```php
292
- $mock = new Mock();
293
- // 3.x
294
- $request->getEventDispatcher()->addSubscriber($mock);
295
- $request->getEventDispatcher()->removeSubscriber($mock);
296
- // 4.x
297
- $request->getEmitter()->attach($mock);
298
- $request->getEmitter()->detach($mock);
299
- ```
300
-
301
- Use the `on()` method to add a listener rather than the `addListener()` method.
302
-
303
- ```php
304
- // 3.x
305
- $request->getEventDispatcher()->addListener('foo', function (Event $event) { /* ... */ } );
306
- // 4.x
307
- $request->getEmitter()->on('foo', function (Event $event, $name) { /* ... */ } );
308
- ```
309
-
310
- ## Http
311
-
312
- ### General changes
313
-
314
- - The cacert.pem certificate has been moved to `src/cacert.pem`.
315
- - Added the concept of adapters that are used to transfer requests over the
316
- wire.
317
- - Simplified the event system.
318
- - Sending requests in parallel is still possible, but batching is no longer a
319
- concept of the HTTP layer. Instead, you must use the `complete` and `error`
320
- events to asynchronously manage parallel request transfers.
321
- - `Guzzle\Http\Url` has moved to `GuzzleHttp\Url`.
322
- - `Guzzle\Http\QueryString` has moved to `GuzzleHttp\Query`.
323
- - QueryAggregators have been rewritten so that they are simply callable
324
- functions.
325
- - `GuzzleHttp\StaticClient` has been removed. Use the functions provided in
326
- `functions.php` for an easy to use static client instance.
327
- - Exceptions in `GuzzleHttp\Exception` have been updated to all extend from
328
- `GuzzleHttp\Exception\TransferException`.
329
-
330
- ### Client
331
-
332
- Calling methods like `get()`, `post()`, `head()`, etc. no longer create and
333
- return a request, but rather creates a request, sends the request, and returns
334
- the response.
335
-
336
- ```php
337
- // 3.0
338
- $request = $client->get('/');
339
- $response = $request->send();
340
-
341
- // 4.0
342
- $response = $client->get('/');
343
-
344
- // or, to mirror the previous behavior
345
- $request = $client->createRequest('GET', '/');
346
- $response = $client->send($request);
347
- ```
348
-
349
- `GuzzleHttp\ClientInterface` has changed.
350
-
351
- - The `send` method no longer accepts more than one request. Use `sendAll` to
352
- send multiple requests in parallel.
353
- - `setUserAgent()` has been removed. Use a default request option instead. You
354
- could, for example, do something like:
355
- `$client->setConfig('defaults/headers/User-Agent', 'Foo/Bar ' . $client::getDefaultUserAgent())`.
356
- - `setSslVerification()` has been removed. Use default request options instead,
357
- like `$client->setConfig('defaults/verify', true)`.
358
-
359
- `GuzzleHttp\Client` has changed.
360
-
361
- - The constructor now accepts only an associative array. You can include a
362
- `base_url` string or array to use a URI template as the base URL of a client.
363
- You can also specify a `defaults` key that is an associative array of default
364
- request options. You can pass an `adapter` to use a custom adapter,
365
- `batch_adapter` to use a custom adapter for sending requests in parallel, or
366
- a `message_factory` to change the factory used to create HTTP requests and
367
- responses.
368
- - The client no longer emits a `client.create_request` event.
369
- - Creating requests with a client no longer automatically utilize a URI
370
- template. You must pass an array into a creational method (e.g.,
371
- `createRequest`, `get`, `put`, etc.) in order to expand a URI template.
372
-
373
- ### Messages
374
-
375
- Messages no longer have references to their counterparts (i.e., a request no
376
- longer has a reference to it's response, and a response no loger has a
377
- reference to its request). This association is now managed through a
378
- `GuzzleHttp\Adapter\TransactionInterface` object. You can get references to
379
- these transaction objects using request events that are emitted over the
380
- lifecycle of a request.
381
-
382
- #### Requests with a body
383
-
384
- - `GuzzleHttp\Message\EntityEnclosingRequest` and
385
- `GuzzleHttp\Message\EntityEnclosingRequestInterface` have been removed. The
386
- separation between requests that contain a body and requests that do not
387
- contain a body has been removed, and now `GuzzleHttp\Message\RequestInterface`
388
- handles both use cases.
389
- - Any method that previously accepts a `GuzzleHttp\Response` object now accept a
390
- `GuzzleHttp\Message\ResponseInterface`.
391
- - `GuzzleHttp\Message\RequestFactoryInterface` has been renamed to
392
- `GuzzleHttp\Message\MessageFactoryInterface`. This interface is used to create
393
- both requests and responses and is implemented in
394
- `GuzzleHttp\Message\MessageFactory`.
395
- - POST field and file methods have been removed from the request object. You
396
- must now use the methods made available to `GuzzleHttp\Post\PostBodyInterface`
397
- to control the format of a POST body. Requests that are created using a
398
- standard `GuzzleHttp\Message\MessageFactoryInterface` will automatically use
399
- a `GuzzleHttp\Post\PostBody` body if the body was passed as an array or if
400
- the method is POST and no body is provided.
401
-
402
- ```php
403
- $request = $client->createRequest('POST', '/');
404
- $request->getBody()->setField('foo', 'bar');
405
- $request->getBody()->addFile(new PostFile('file_key', fopen('/path/to/content', 'r')));
406
- ```
407
-
408
- #### Headers
409
-
410
- - `GuzzleHttp\Message\Header` has been removed. Header values are now simply
411
- represented by an array of values or as a string. Header values are returned
412
- as a string by default when retrieving a header value from a message. You can
413
- pass an optional argument of `true` to retrieve a header value as an array
414
- of strings instead of a single concatenated string.
415
- - `GuzzleHttp\PostFile` and `GuzzleHttp\PostFileInterface` have been moved to
416
- `GuzzleHttp\Post`. This interface has been simplified and now allows the
417
- addition of arbitrary headers.
418
- - Custom headers like `GuzzleHttp\Message\Header\Link` have been removed. Most
419
- of the custom headers are now handled separately in specific
420
- subscribers/plugins, and `GuzzleHttp\Message\HeaderValues::parseParams()` has
421
- been updated to properly handle headers that contain parameters (like the
422
- `Link` header).
423
-
424
- #### Responses
425
-
426
- - `GuzzleHttp\Message\Response::getInfo()` and
427
- `GuzzleHttp\Message\Response::setInfo()` have been removed. Use the event
428
- system to retrieve this type of information.
429
- - `GuzzleHttp\Message\Response::getRawHeaders()` has been removed.
430
- - `GuzzleHttp\Message\Response::getMessage()` has been removed.
431
- - `GuzzleHttp\Message\Response::calculateAge()` and other cache specific
432
- methods have moved to the CacheSubscriber.
433
- - Header specific helper functions like `getContentMd5()` have been removed.
434
- Just use `getHeader('Content-MD5')` instead.
435
- - `GuzzleHttp\Message\Response::setRequest()` and
436
- `GuzzleHttp\Message\Response::getRequest()` have been removed. Use the event
437
- system to work with request and response objects as a transaction.
438
- - `GuzzleHttp\Message\Response::getRedirectCount()` has been removed. Use the
439
- Redirect subscriber instead.
440
- - `GuzzleHttp\Message\Response::isSuccessful()` and other related methods have
441
- been removed. Use `getStatusCode()` instead.
442
-
443
- #### Streaming responses
444
-
445
- Streaming requests can now be created by a client directly, returning a
446
- `GuzzleHttp\Message\ResponseInterface` object that contains a body stream
447
- referencing an open PHP HTTP stream.
448
-
449
- ```php
450
- // 3.0
451
- use Guzzle\Stream\PhpStreamRequestFactory;
452
- $request = $client->get('/');
453
- $factory = new PhpStreamRequestFactory();
454
- $stream = $factory->fromRequest($request);
455
- $data = $stream->read(1024);
456
-
457
- // 4.0
458
- $response = $client->get('/', ['stream' => true]);
459
- // Read some data off of the stream in the response body
460
- $data = $response->getBody()->read(1024);
461
- ```
462
-
463
- #### Redirects
464
-
465
- The `configureRedirects()` method has been removed in favor of a
466
- `allow_redirects` request option.
467
-
468
- ```php
469
- // Standard redirects with a default of a max of 5 redirects
470
- $request = $client->createRequest('GET', '/', ['allow_redirects' => true]);
471
-
472
- // Strict redirects with a custom number of redirects
473
- $request = $client->createRequest('GET', '/', [
474
- 'allow_redirects' => ['max' => 5, 'strict' => true]
475
- ]);
476
- ```
477
-
478
- #### EntityBody
479
-
480
- EntityBody interfaces and classes have been removed or moved to
481
- `GuzzleHttp\Stream`. All classes and interfaces that once required
482
- `GuzzleHttp\EntityBodyInterface` now require
483
- `GuzzleHttp\Stream\StreamInterface`. Creating a new body for a request no
484
- longer uses `GuzzleHttp\EntityBody::factory` but now uses
485
- `GuzzleHttp\Stream\Stream::factory` or even better:
486
- `GuzzleHttp\Stream\create()`.
487
-
488
- - `Guzzle\Http\EntityBodyInterface` is now `GuzzleHttp\Stream\StreamInterface`
489
- - `Guzzle\Http\EntityBody` is now `GuzzleHttp\Stream\Stream`
490
- - `Guzzle\Http\CachingEntityBody` is now `GuzzleHttp\Stream\CachingStream`
491
- - `Guzzle\Http\ReadLimitEntityBody` is now `GuzzleHttp\Stream\LimitStream`
492
- - `Guzzle\Http\IoEmittyinEntityBody` has been removed.
493
-
494
- #### Request lifecycle events
495
-
496
- Requests previously submitted a large number of requests. The number of events
497
- emitted over the lifecycle of a request has been significantly reduced to make
498
- it easier to understand how to extend the behavior of a request. All events
499
- emitted during the lifecycle of a request now emit a custom
500
- `GuzzleHttp\Event\EventInterface` object that contains context providing
501
- methods and a way in which to modify the transaction at that specific point in
502
- time (e.g., intercept the request and set a response on the transaction).
503
-
504
- - `request.before_send` has been renamed to `before` and now emits a
505
- `GuzzleHttp\Event\BeforeEvent`
506
- - `request.complete` has been renamed to `complete` and now emits a
507
- `GuzzleHttp\Event\CompleteEvent`.
508
- - `request.sent` has been removed. Use `complete`.
509
- - `request.success` has been removed. Use `complete`.
510
- - `error` is now an event that emits a `GuzzleHttp\Event\ErrorEvent`.
511
- - `request.exception` has been removed. Use `error`.
512
- - `request.receive.status_line` has been removed.
513
- - `curl.callback.progress` has been removed. Use a custom `StreamInterface` to
514
- maintain a status update.
515
- - `curl.callback.write` has been removed. Use a custom `StreamInterface` to
516
- intercept writes.
517
- - `curl.callback.read` has been removed. Use a custom `StreamInterface` to
518
- intercept reads.
519
-
520
- `headers` is a new event that is emitted after the response headers of a
521
- request have been received before the body of the response is downloaded. This
522
- event emits a `GuzzleHttp\Event\HeadersEvent`.
523
-
524
- You can intercept a request and inject a response using the `intercept()` event
525
- of a `GuzzleHttp\Event\BeforeEvent`, `GuzzleHttp\Event\CompleteEvent`, and
526
- `GuzzleHttp\Event\ErrorEvent` event.
527
-
528
- See: http://docs.guzzlephp.org/en/latest/events.html
529
-
530
- ## Inflection
531
-
532
- The `Guzzle\Inflection` namespace has been removed. This is not a core concern
533
- of Guzzle.
534
-
535
- ## Iterator
536
-
537
- The `Guzzle\Iterator` namespace has been removed.
538
-
539
- - `Guzzle\Iterator\AppendIterator`, `Guzzle\Iterator\ChunkedIterator`, and
540
- `Guzzle\Iterator\MethodProxyIterator` are nice, but not a core requirement of
541
- Guzzle itself.
542
- - `Guzzle\Iterator\FilterIterator` is no longer needed because an equivalent
543
- class is shipped with PHP 5.4.
544
- - `Guzzle\Iterator\MapIterator` is not really needed when using PHP 5.5 because
545
- it's easier to just wrap an iterator in a generator that maps values.
546
-
547
- For a replacement of these iterators, see https://github.com/nikic/iter
548
-
549
- ## Log
550
-
551
- The LogPlugin has moved to https://github.com/guzzle/log-subscriber. The
552
- `Guzzle\Log` namespace has been removed. Guzzle now relies on
553
- `Psr\Log\LoggerInterface` for all logging. The MessageFormatter class has been
554
- moved to `GuzzleHttp\Subscriber\Log\Formatter`.
555
-
556
- ## Parser
557
-
558
- The `Guzzle\Parser` namespace has been removed. This was previously used to
559
- make it possible to plug in custom parsers for cookies, messages, URI
560
- templates, and URLs; however, this level of complexity is not needed in Guzzle
561
- so it has been removed.
562
-
563
- - Cookie: Cookie parsing logic has been moved to
564
- `GuzzleHttp\Cookie\SetCookie::fromString`.
565
- - Message: Message parsing logic for both requests and responses has been moved
566
- to `GuzzleHttp\Message\MessageFactory::fromMessage`. Message parsing is only
567
- used in debugging or deserializing messages, so it doesn't make sense for
568
- Guzzle as a library to add this level of complexity to parsing messages.
569
- - UriTemplate: URI template parsing has been moved to
570
- `GuzzleHttp\UriTemplate`. The Guzzle library will automatically use the PECL
571
- URI template library if it is installed.
572
- - Url: URL parsing is now performed in `GuzzleHttp\Url::fromString` (previously
573
- it was `Guzzle\Http\Url::factory()`). If custom URL parsing is necessary,
574
- then developers are free to subclass `GuzzleHttp\Url`.
575
-
576
- ## Plugin
577
-
578
- The `Guzzle\Plugin` namespace has been renamed to `GuzzleHttp\Subscriber`.
579
- Several plugins are shipping with the core Guzzle library under this namespace.
580
-
581
- - `GuzzleHttp\Subscriber\Cookie`: Replaces the old CookiePlugin. Cookie jar
582
- code has moved to `GuzzleHttp\Cookie`.
583
- - `GuzzleHttp\Subscriber\History`: Replaces the old HistoryPlugin.
584
- - `GuzzleHttp\Subscriber\HttpError`: Throws errors when a bad HTTP response is
585
- received.
586
- - `GuzzleHttp\Subscriber\Mock`: Replaces the old MockPlugin.
587
- - `GuzzleHttp\Subscriber\Prepare`: Prepares the body of a request just before
588
- sending. This subscriber is attached to all requests by default.
589
- - `GuzzleHttp\Subscriber\Redirect`: Replaces the RedirectPlugin.
590
-
591
- The following plugins have been removed (third-parties are free to re-implement
592
- these if needed):
593
-
594
- - `GuzzleHttp\Plugin\Async` has been removed.
595
- - `GuzzleHttp\Plugin\CurlAuth` has been removed.
596
- - `GuzzleHttp\Plugin\ErrorResponse\ErrorResponsePlugin` has been removed. This
597
- functionality should instead be implemented with event listeners that occur
598
- after normal response parsing occurs in the guzzle/command package.
599
-
600
- The following plugins are not part of the core Guzzle package, but are provided
601
- in separate repositories:
602
-
603
- - `Guzzle\Http\Plugin\BackoffPlugin` has been rewritten to be much simpler
604
- to build custom retry policies using simple functions rather than various
605
- chained classes. See: https://github.com/guzzle/retry-subscriber
606
- - `Guzzle\Http\Plugin\Cache\CachePlugin` has moved to
607
- https://github.com/guzzle/cache-subscriber
608
- - `Guzzle\Http\Plugin\Log\LogPlugin` has moved to
609
- https://github.com/guzzle/log-subscriber
610
- - `Guzzle\Http\Plugin\Md5\Md5Plugin` has moved to
611
- https://github.com/guzzle/message-integrity-subscriber
612
- - `Guzzle\Http\Plugin\Mock\MockPlugin` has moved to
613
- `GuzzleHttp\Subscriber\MockSubscriber`.
614
- - `Guzzle\Http\Plugin\Oauth\OauthPlugin` has moved to
615
- https://github.com/guzzle/oauth-subscriber
616
-
617
- ## Service
618
-
619
- The service description layer of Guzzle has moved into two separate packages:
620
-
621
- - http://github.com/guzzle/command Provides a high level abstraction over web
622
- services by representing web service operations using commands.
623
- - http://github.com/guzzle/guzzle-services Provides an implementation of
624
- guzzle/command that provides request serialization and response parsing using
625
- Guzzle service descriptions.
626
-
627
- ## Stream
628
-
629
- Stream have moved to a separate package available at
630
- https://github.com/guzzle/streams.
631
-
632
- `Guzzle\Stream\StreamInterface` has been given a large update to cleanly take
633
- on the responsibilities of `Guzzle\Http\EntityBody` and
634
- `Guzzle\Http\EntityBodyInterface` now that they have been removed. The number
635
- of methods implemented by the `StreamInterface` has been drastically reduced to
636
- allow developers to more easily extend and decorate stream behavior.
637
-
638
- ## Removed methods from StreamInterface
639
-
640
- - `getStream` and `setStream` have been removed to better encapsulate streams.
641
- - `getMetadata` and `setMetadata` have been removed in favor of
642
- `GuzzleHttp\Stream\MetadataStreamInterface`.
643
- - `getWrapper`, `getWrapperData`, `getStreamType`, and `getUri` have all been
644
- removed. This data is accessible when
645
- using streams that implement `GuzzleHttp\Stream\MetadataStreamInterface`.
646
- - `rewind` has been removed. Use `seek(0)` for a similar behavior.
647
-
648
- ## Renamed methods
649
-
650
- - `detachStream` has been renamed to `detach`.
651
- - `feof` has been renamed to `eof`.
652
- - `ftell` has been renamed to `tell`.
653
- - `readLine` has moved from an instance method to a static class method of
654
- `GuzzleHttp\Stream\Stream`.
655
-
656
- ## Metadata streams
657
-
658
- `GuzzleHttp\Stream\MetadataStreamInterface` has been added to denote streams
659
- that contain additional metadata accessible via `getMetadata()`.
660
- `GuzzleHttp\Stream\StreamInterface::getMetadata` and
661
- `GuzzleHttp\Stream\StreamInterface::setMetadata` have been removed.
662
-
663
- ## StreamRequestFactory
664
-
665
- The entire concept of the StreamRequestFactory has been removed. The way this
666
- was used in Guzzle 3 broke the actual interface of sending streaming requests
667
- (instead of getting back a Response, you got a StreamInterface). Streaming
668
- PHP requests are now implemented through the `GuzzleHttp\Adapter\StreamAdapter`.
669
-
670
- 3.6 to 3.7
671
- ----------
672
-
673
- ### Deprecations
674
-
675
- - You can now enable E_USER_DEPRECATED warnings to see if you are using any deprecated methods.:
676
-
677
- ```php
678
- \Guzzle\Common\Version::$emitWarnings = true;
679
- ```
680
-
681
- The following APIs and options have been marked as deprecated:
682
-
683
- - Marked `Guzzle\Http\Message\Request::isResponseBodyRepeatable()` as deprecated. Use `$request->getResponseBody()->isRepeatable()` instead.
684
- - Marked `Guzzle\Http\Message\Request::canCache()` as deprecated. Use `Guzzle\Plugin\Cache\DefaultCanCacheStrategy->canCacheRequest()` instead.
685
- - Marked `Guzzle\Http\Message\Request::canCache()` as deprecated. Use `Guzzle\Plugin\Cache\DefaultCanCacheStrategy->canCacheRequest()` instead.
686
- - Marked `Guzzle\Http\Message\Request::setIsRedirect()` as deprecated. Use the HistoryPlugin instead.
687
- - Marked `Guzzle\Http\Message\Request::isRedirect()` as deprecated. Use the HistoryPlugin instead.
688
- - Marked `Guzzle\Cache\CacheAdapterFactory::factory()` as deprecated
689
- - Marked `Guzzle\Service\Client::enableMagicMethods()` as deprecated. Magic methods can no longer be disabled on a Guzzle\Service\Client.
690
- - Marked `Guzzle\Parser\Url\UrlParser` as deprecated. Just use PHP's `parse_url()` and percent encode your UTF-8.
691
- - Marked `Guzzle\Common\Collection::inject()` as deprecated.
692
- - Marked `Guzzle\Plugin\CurlAuth\CurlAuthPlugin` as deprecated. Use
693
- `$client->getConfig()->setPath('request.options/auth', array('user', 'pass', 'Basic|Digest|NTLM|Any'));` or
694
- `$client->setDefaultOption('auth', array('user', 'pass', 'Basic|Digest|NTLM|Any'));`
695
-
696
- 3.7 introduces `request.options` as a parameter for a client configuration and as an optional argument to all creational
697
- request methods. When paired with a client's configuration settings, these options allow you to specify default settings
698
- for various aspects of a request. Because these options make other previous configuration options redundant, several
699
- configuration options and methods of a client and AbstractCommand have been deprecated.
700
-
701
- - Marked `Guzzle\Service\Client::getDefaultHeaders()` as deprecated. Use `$client->getDefaultOption('headers')`.
702
- - Marked `Guzzle\Service\Client::setDefaultHeaders()` as deprecated. Use `$client->setDefaultOption('headers/{header_name}', 'value')`.
703
- - Marked 'request.params' for `Guzzle\Http\Client` as deprecated. Use `$client->setDefaultOption('params/{param_name}', 'value')`
704
- - Marked 'command.headers', 'command.response_body' and 'command.on_complete' as deprecated for AbstractCommand. These will work through Guzzle 4.0
705
-
706
- $command = $client->getCommand('foo', array(
707
- 'command.headers' => array('Test' => '123'),
708
- 'command.response_body' => '/path/to/file'
709
- ));
710
-
711
- // Should be changed to:
712
-
713
- $command = $client->getCommand('foo', array(
714
- 'command.request_options' => array(
715
- 'headers' => array('Test' => '123'),
716
- 'save_as' => '/path/to/file'
717
- )
718
- ));
719
-
720
- ### Interface changes
721
-
722
- Additions and changes (you will need to update any implementations or subclasses you may have created):
723
-
724
- - Added an `$options` argument to the end of the following methods of `Guzzle\Http\ClientInterface`:
725
- createRequest, head, delete, put, patch, post, options, prepareRequest
726
- - Added an `$options` argument to the end of `Guzzle\Http\Message\Request\RequestFactoryInterface::createRequest()`
727
- - Added an `applyOptions()` method to `Guzzle\Http\Message\Request\RequestFactoryInterface`
728
- - Changed `Guzzle\Http\ClientInterface::get($uri = null, $headers = null, $body = null)` to
729
- `Guzzle\Http\ClientInterface::get($uri = null, $headers = null, $options = array())`. You can still pass in a
730
- resource, string, or EntityBody into the $options parameter to specify the download location of the response.
731
- - Changed `Guzzle\Common\Collection::__construct($data)` to no longer accepts a null value for `$data` but a
732
- default `array()`
733
- - Added `Guzzle\Stream\StreamInterface::isRepeatable`
734
- - Made `Guzzle\Http\Client::expandTemplate` and `getUriTemplate` protected methods.
735
-
736
- The following methods were removed from interfaces. All of these methods are still available in the concrete classes
737
- that implement them, but you should update your code to use alternative methods:
738
-
739
- - Removed `Guzzle\Http\ClientInterface::setDefaultHeaders(). Use
740
- `$client->getConfig()->setPath('request.options/headers/{header_name}', 'value')`. or
741
- `$client->getConfig()->setPath('request.options/headers', array('header_name' => 'value'))` or
742
- `$client->setDefaultOption('headers/{header_name}', 'value')`. or
743
- `$client->setDefaultOption('headers', array('header_name' => 'value'))`.
744
- - Removed `Guzzle\Http\ClientInterface::getDefaultHeaders(). Use `$client->getConfig()->getPath('request.options/headers')`.
745
- - Removed `Guzzle\Http\ClientInterface::expandTemplate()`. This is an implementation detail.
746
- - Removed `Guzzle\Http\ClientInterface::setRequestFactory()`. This is an implementation detail.
747
- - Removed `Guzzle\Http\ClientInterface::getCurlMulti()`. This is a very specific implementation detail.
748
- - Removed `Guzzle\Http\Message\RequestInterface::canCache`. Use the CachePlugin.
749
- - Removed `Guzzle\Http\Message\RequestInterface::setIsRedirect`. Use the HistoryPlugin.
750
- - Removed `Guzzle\Http\Message\RequestInterface::isRedirect`. Use the HistoryPlugin.
751
-
752
- ### Cache plugin breaking changes
753
-
754
- - CacheKeyProviderInterface and DefaultCacheKeyProvider are no longer used. All of this logic is handled in a
755
- CacheStorageInterface. These two objects and interface will be removed in a future version.
756
- - Always setting X-cache headers on cached responses
757
- - Default cache TTLs are now handled by the CacheStorageInterface of a CachePlugin
758
- - `CacheStorageInterface::cache($key, Response $response, $ttl = null)` has changed to `cache(RequestInterface
759
- $request, Response $response);`
760
- - `CacheStorageInterface::fetch($key)` has changed to `fetch(RequestInterface $request);`
761
- - `CacheStorageInterface::delete($key)` has changed to `delete(RequestInterface $request);`
762
- - Added `CacheStorageInterface::purge($url)`
763
- - `DefaultRevalidation::__construct(CacheKeyProviderInterface $cacheKey, CacheStorageInterface $cache, CachePlugin
764
- $plugin)` has changed to `DefaultRevalidation::__construct(CacheStorageInterface $cache,
765
- CanCacheStrategyInterface $canCache = null)`
766
- - Added `RevalidationInterface::shouldRevalidate(RequestInterface $request, Response $response)`
767
-
768
- 3.5 to 3.6
769
- ----------
770
-
771
- * Mixed casing of headers are now forced to be a single consistent casing across all values for that header.
772
- * Messages internally use a HeaderCollection object to delegate handling case-insensitive header resolution
773
- * Removed the whole changedHeader() function system of messages because all header changes now go through addHeader().
774
- For example, setHeader() first removes the header using unset on a HeaderCollection and then calls addHeader().
775
- Keeping the Host header and URL host in sync is now handled by overriding the addHeader method in Request.
776
- * Specific header implementations can be created for complex headers. When a message creates a header, it uses a
777
- HeaderFactory which can map specific headers to specific header classes. There is now a Link header and
778
- CacheControl header implementation.
779
- * Moved getLinks() from Response to just be used on a Link header object.
780
-
781
- If you previously relied on Guzzle\Http\Message\Header::raw(), then you will need to update your code to use the
782
- HeaderInterface (e.g. toArray(), getAll(), etc.).
783
-
784
- ### Interface changes
785
-
786
- * Removed from interface: Guzzle\Http\ClientInterface::setUriTemplate
787
- * Removed from interface: Guzzle\Http\ClientInterface::setCurlMulti()
788
- * Removed Guzzle\Http\Message\Request::receivedRequestHeader() and implemented this functionality in
789
- Guzzle\Http\Curl\RequestMediator
790
- * Removed the optional $asString parameter from MessageInterface::getHeader(). Just cast the header to a string.
791
- * Removed the optional $tryChunkedTransfer option from Guzzle\Http\Message\EntityEnclosingRequestInterface
792
- * Removed the $asObjects argument from Guzzle\Http\Message\MessageInterface::getHeaders()
793
-
794
- ### Removed deprecated functions
795
-
796
- * Removed Guzzle\Parser\ParserRegister::get(). Use getParser()
797
- * Removed Guzzle\Parser\ParserRegister::set(). Use registerParser().
798
-
799
- ### Deprecations
800
-
801
- * The ability to case-insensitively search for header values
802
- * Guzzle\Http\Message\Header::hasExactHeader
803
- * Guzzle\Http\Message\Header::raw. Use getAll()
804
- * Deprecated cache control specific methods on Guzzle\Http\Message\AbstractMessage. Use the CacheControl header object
805
- instead.
806
-
807
- ### Other changes
808
-
809
- * All response header helper functions return a string rather than mixing Header objects and strings inconsistently
810
- * Removed cURL blacklist support. This is no longer necessary now that Expect, Accept, etc. are managed by Guzzle
811
- directly via interfaces
812
- * Removed the injecting of a request object onto a response object. The methods to get and set a request still exist
813
- but are a no-op until removed.
814
- * Most classes that used to require a `Guzzle\Service\Command\CommandInterface` typehint now request a
815
- `Guzzle\Service\Command\ArrayCommandInterface`.
816
- * Added `Guzzle\Http\Message\RequestInterface::startResponse()` to the RequestInterface to handle injecting a response
817
- on a request while the request is still being transferred
818
- * `Guzzle\Service\Command\CommandInterface` now extends from ToArrayInterface and ArrayAccess
819
-
820
- 3.3 to 3.4
821
- ----------
822
-
823
- Base URLs of a client now follow the rules of http://tools.ietf.org/html/rfc3986#section-5.2.2 when merging URLs.
824
-
825
- 3.2 to 3.3
826
- ----------
827
-
828
- ### Response::getEtag() quote stripping removed
829
-
830
- `Guzzle\Http\Message\Response::getEtag()` no longer strips quotes around the ETag response header
831
-
832
- ### Removed `Guzzle\Http\Utils`
833
-
834
- The `Guzzle\Http\Utils` class was removed. This class was only used for testing.
835
-
836
- ### Stream wrapper and type
837
-
838
- `Guzzle\Stream\Stream::getWrapper()` and `Guzzle\Stream\Stream::getStreamType()` are no longer converted to lowercase.
839
-
840
- ### curl.emit_io became emit_io
841
-
842
- Emitting IO events from a RequestMediator is now a parameter that must be set in a request's curl options using the
843
- 'emit_io' key. This was previously set under a request's parameters using 'curl.emit_io'
844
-
845
- 3.1 to 3.2
846
- ----------
847
-
848
- ### CurlMulti is no longer reused globally
849
-
850
- Before 3.2, the same CurlMulti object was reused globally for each client. This can cause issue where plugins added
851
- to a single client can pollute requests dispatched from other clients.
852
-
853
- If you still wish to reuse the same CurlMulti object with each client, then you can add a listener to the
854
- ServiceBuilder's `service_builder.create_client` event to inject a custom CurlMulti object into each client as it is
855
- created.
856
-
857
- ```php
858
- $multi = new Guzzle\Http\Curl\CurlMulti();
859
- $builder = Guzzle\Service\Builder\ServiceBuilder::factory('/path/to/config.json');
860
- $builder->addListener('service_builder.create_client', function ($event) use ($multi) {
861
- $event['client']->setCurlMulti($multi);
862
- }
863
- });
864
- ```
865
-
866
- ### No default path
867
-
868
- URLs no longer have a default path value of '/' if no path was specified.
869
-
870
- Before:
871
-
872
- ```php
873
- $request = $client->get('http://www.foo.com');
874
- echo $request->getUrl();
875
- // >> http://www.foo.com/
876
- ```
877
-
878
- After:
879
-
880
- ```php
881
- $request = $client->get('http://www.foo.com');
882
- echo $request->getUrl();
883
- // >> http://www.foo.com
884
- ```
885
-
886
- ### Less verbose BadResponseException
887
-
888
- The exception message for `Guzzle\Http\Exception\BadResponseException` no longer contains the full HTTP request and
889
- response information. You can, however, get access to the request and response object by calling `getRequest()` or
890
- `getResponse()` on the exception object.
891
-
892
- ### Query parameter aggregation
893
-
894
- Multi-valued query parameters are no longer aggregated using a callback function. `Guzzle\Http\Query` now has a
895
- setAggregator() method that accepts a `Guzzle\Http\QueryAggregator\QueryAggregatorInterface` object. This object is
896
- responsible for handling the aggregation of multi-valued query string variables into a flattened hash.
897
-
898
- 2.8 to 3.x
899
- ----------
900
-
901
- ### Guzzle\Service\Inspector
902
-
903
- Change `\Guzzle\Service\Inspector::fromConfig` to `\Guzzle\Common\Collection::fromConfig`
904
-
905
- **Before**
906
-
907
- ```php
908
- use Guzzle\Service\Inspector;
909
-
910
- class YourClient extends \Guzzle\Service\Client
911
- {
912
- public static function factory($config = array())
913
- {
914
- $default = array();
915
- $required = array('base_url', 'username', 'api_key');
916
- $config = Inspector::fromConfig($config, $default, $required);
917
-
918
- $client = new self(
919
- $config->get('base_url'),
920
- $config->get('username'),
921
- $config->get('api_key')
922
- );
923
- $client->setConfig($config);
924
-
925
- $client->setDescription(ServiceDescription::factory(__DIR__ . DIRECTORY_SEPARATOR . 'client.json'));
926
-
927
- return $client;
928
- }
929
- ```
930
-
931
- **After**
932
-
933
- ```php
934
- use Guzzle\Common\Collection;
935
-
936
- class YourClient extends \Guzzle\Service\Client
937
- {
938
- public static function factory($config = array())
939
- {
940
- $default = array();
941
- $required = array('base_url', 'username', 'api_key');
942
- $config = Collection::fromConfig($config, $default, $required);
943
-
944
- $client = new self(
945
- $config->get('base_url'),
946
- $config->get('username'),
947
- $config->get('api_key')
948
- );
949
- $client->setConfig($config);
950
-
951
- $client->setDescription(ServiceDescription::factory(__DIR__ . DIRECTORY_SEPARATOR . 'client.json'));
952
-
953
- return $client;
954
- }
955
- ```
956
-
957
- ### Convert XML Service Descriptions to JSON
958
-
959
- **Before**
960
-
961
- ```xml
962
- <?xml version="1.0" encoding="UTF-8"?>
963
- <client>
964
- <commands>
965
- <!-- Groups -->
966
- <command name="list_groups" method="GET" uri="groups.json">
967
- <doc>Get a list of groups</doc>
968
- </command>
969
- <command name="search_groups" method="GET" uri='search.json?query="{{query}} type:group"'>
970
- <doc>Uses a search query to get a list of groups</doc>
971
- <param name="query" type="string" required="true" />
972
- </command>
973
- <command name="create_group" method="POST" uri="groups.json">
974
- <doc>Create a group</doc>
975
- <param name="data" type="array" location="body" filters="json_encode" doc="Group JSON"/>
976
- <param name="Content-Type" location="header" static="application/json"/>
977
- </command>
978
- <command name="delete_group" method="DELETE" uri="groups/{{id}}.json">
979
- <doc>Delete a group by ID</doc>
980
- <param name="id" type="integer" required="true"/>
981
- </command>
982
- <command name="get_group" method="GET" uri="groups/{{id}}.json">
983
- <param name="id" type="integer" required="true"/>
984
- </command>
985
- <command name="update_group" method="PUT" uri="groups/{{id}}.json">
986
- <doc>Update a group</doc>
987
- <param name="id" type="integer" required="true"/>
988
- <param name="data" type="array" location="body" filters="json_encode" doc="Group JSON"/>
989
- <param name="Content-Type" location="header" static="application/json"/>
990
- </command>
991
- </commands>
992
- </client>
993
- ```
994
-
995
- **After**
996
-
997
- ```json
998
- {
999
- "name": "Zendesk REST API v2",
1000
- "apiVersion": "2012-12-31",
1001
- "description":"Provides access to Zendesk views, groups, tickets, ticket fields, and users",
1002
- "operations": {
1003
- "list_groups": {
1004
- "httpMethod":"GET",
1005
- "uri": "groups.json",
1006
- "summary": "Get a list of groups"
1007
- },
1008
- "search_groups":{
1009
- "httpMethod":"GET",
1010
- "uri": "search.json?query=\"{query} type:group\"",
1011
- "summary": "Uses a search query to get a list of groups",
1012
- "parameters":{
1013
- "query":{
1014
- "location": "uri",
1015
- "description":"Zendesk Search Query",
1016
- "type": "string",
1017
- "required": true
1018
- }
1019
- }
1020
- },
1021
- "create_group": {
1022
- "httpMethod":"POST",
1023
- "uri": "groups.json",
1024
- "summary": "Create a group",
1025
- "parameters":{
1026
- "data": {
1027
- "type": "array",
1028
- "location": "body",
1029
- "description":"Group JSON",
1030
- "filters": "json_encode",
1031
- "required": true
1032
- },
1033
- "Content-Type":{
1034
- "type": "string",
1035
- "location":"header",
1036
- "static": "application/json"
1037
- }
1038
- }
1039
- },
1040
- "delete_group": {
1041
- "httpMethod":"DELETE",
1042
- "uri": "groups/{id}.json",
1043
- "summary": "Delete a group",
1044
- "parameters":{
1045
- "id":{
1046
- "location": "uri",
1047
- "description":"Group to delete by ID",
1048
- "type": "integer",
1049
- "required": true
1050
- }
1051
- }
1052
- },
1053
- "get_group": {
1054
- "httpMethod":"GET",
1055
- "uri": "groups/{id}.json",
1056
- "summary": "Get a ticket",
1057
- "parameters":{
1058
- "id":{
1059
- "location": "uri",
1060
- "description":"Group to get by ID",
1061
- "type": "integer",
1062
- "required": true
1063
- }
1064
- }
1065
- },
1066
- "update_group": {
1067
- "httpMethod":"PUT",
1068
- "uri": "groups/{id}.json",
1069
- "summary": "Update a group",
1070
- "parameters":{
1071
- "id": {
1072
- "location": "uri",
1073
- "description":"Group to update by ID",
1074
- "type": "integer",
1075
- "required": true
1076
- },
1077
- "data": {
1078
- "type": "array",
1079
- "location": "body",
1080
- "description":"Group JSON",
1081
- "filters": "json_encode",
1082
- "required": true
1083
- },
1084
- "Content-Type":{
1085
- "type": "string",
1086
- "location":"header",
1087
- "static": "application/json"
1088
- }
1089
- }
1090
- }
1091
- }
1092
- ```
1093
-
1094
- ### Guzzle\Service\Description\ServiceDescription
1095
-
1096
- Commands are now called Operations
1097
-
1098
- **Before**
1099
-
1100
- ```php
1101
- use Guzzle\Service\Description\ServiceDescription;
1102
-
1103
- $sd = new ServiceDescription();
1104
- $sd->getCommands(); // @returns ApiCommandInterface[]
1105
- $sd->hasCommand($name);
1106
- $sd->getCommand($name); // @returns ApiCommandInterface|null
1107
- $sd->addCommand($command); // @param ApiCommandInterface $command
1108
- ```
1109
-
1110
- **After**
1111
-
1112
- ```php
1113
- use Guzzle\Service\Description\ServiceDescription;
1114
-
1115
- $sd = new ServiceDescription();
1116
- $sd->getOperations(); // @returns OperationInterface[]
1117
- $sd->hasOperation($name);
1118
- $sd->getOperation($name); // @returns OperationInterface|null
1119
- $sd->addOperation($operation); // @param OperationInterface $operation
1120
- ```
1121
-
1122
- ### Guzzle\Common\Inflection\Inflector
1123
-
1124
- Namespace is now `Guzzle\Inflection\Inflector`
1125
-
1126
- ### Guzzle\Http\Plugin
1127
-
1128
- Namespace is now `Guzzle\Plugin`. Many other changes occur within this namespace and are detailed in their own sections below.
1129
-
1130
- ### Guzzle\Http\Plugin\LogPlugin and Guzzle\Common\Log
1131
-
1132
- Now `Guzzle\Plugin\Log\LogPlugin` and `Guzzle\Log` respectively.
1133
-
1134
- **Before**
1135
-
1136
- ```php
1137
- use Guzzle\Common\Log\ClosureLogAdapter;
1138
- use Guzzle\Http\Plugin\LogPlugin;
1139
-
1140
- /** @var \Guzzle\Http\Client */
1141
- $client;
1142
-
1143
- // $verbosity is an integer indicating desired message verbosity level
1144
- $client->addSubscriber(new LogPlugin(new ClosureLogAdapter(function($m) { echo $m; }, $verbosity = LogPlugin::LOG_VERBOSE);
1145
- ```
1146
-
1147
- **After**
1148
-
1149
- ```php
1150
- use Guzzle\Log\ClosureLogAdapter;
1151
- use Guzzle\Log\MessageFormatter;
1152
- use Guzzle\Plugin\Log\LogPlugin;
1153
-
1154
- /** @var \Guzzle\Http\Client */
1155
- $client;
1156
-
1157
- // $format is a string indicating desired message format -- @see MessageFormatter
1158
- $client->addSubscriber(new LogPlugin(new ClosureLogAdapter(function($m) { echo $m; }, $format = MessageFormatter::DEBUG_FORMAT);
1159
- ```
1160
-
1161
- ### Guzzle\Http\Plugin\CurlAuthPlugin
1162
-
1163
- Now `Guzzle\Plugin\CurlAuth\CurlAuthPlugin`.
1164
-
1165
- ### Guzzle\Http\Plugin\ExponentialBackoffPlugin
1166
-
1167
- Now `Guzzle\Plugin\Backoff\BackoffPlugin`, and other changes.
1168
-
1169
- **Before**
1170
-
1171
- ```php
1172
- use Guzzle\Http\Plugin\ExponentialBackoffPlugin;
1173
-
1174
- $backoffPlugin = new ExponentialBackoffPlugin($maxRetries, array_merge(
1175
- ExponentialBackoffPlugin::getDefaultFailureCodes(), array(429)
1176
- ));
1177
-
1178
- $client->addSubscriber($backoffPlugin);
1179
- ```
1180
-
1181
- **After**
1182
-
1183
- ```php
1184
- use Guzzle\Plugin\Backoff\BackoffPlugin;
1185
- use Guzzle\Plugin\Backoff\HttpBackoffStrategy;
1186
-
1187
- // Use convenient factory method instead -- see implementation for ideas of what
1188
- // you can do with chaining backoff strategies
1189
- $backoffPlugin = BackoffPlugin::getExponentialBackoff($maxRetries, array_merge(
1190
- HttpBackoffStrategy::getDefaultFailureCodes(), array(429)
1191
- ));
1192
- $client->addSubscriber($backoffPlugin);
1193
- ```
1194
-
1195
- ### Known Issues
1196
-
1197
- #### [BUG] Accept-Encoding header behavior changed unintentionally.
1198
-
1199
- (See #217) (Fixed in 09daeb8c666fb44499a0646d655a8ae36456575e)
1200
-
1201
- In version 2.8 setting the `Accept-Encoding` header would set the CURLOPT_ENCODING option, which permitted cURL to
1202
- properly handle gzip/deflate compressed responses from the server. In versions affected by this bug this does not happen.
1203
- See issue #217 for a workaround, or use a version containing the fix.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/guzzle/src/Client.php DELETED
@@ -1,422 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp;
3
-
4
- use GuzzleHttp\Cookie\CookieJar;
5
- use GuzzleHttp\Promise;
6
- use GuzzleHttp\Psr7;
7
- use Psr\Http\Message\UriInterface;
8
- use Psr\Http\Message\RequestInterface;
9
- use Psr\Http\Message\ResponseInterface;
10
-
11
- /**
12
- * @method ResponseInterface get(string|UriInterface $uri, array $options = [])
13
- * @method ResponseInterface head(string|UriInterface $uri, array $options = [])
14
- * @method ResponseInterface put(string|UriInterface $uri, array $options = [])
15
- * @method ResponseInterface post(string|UriInterface $uri, array $options = [])
16
- * @method ResponseInterface patch(string|UriInterface $uri, array $options = [])
17
- * @method ResponseInterface delete(string|UriInterface $uri, array $options = [])
18
- * @method Promise\PromiseInterface getAsync(string|UriInterface $uri, array $options = [])
19
- * @method Promise\PromiseInterface headAsync(string|UriInterface $uri, array $options = [])
20
- * @method Promise\PromiseInterface putAsync(string|UriInterface $uri, array $options = [])
21
- * @method Promise\PromiseInterface postAsync(string|UriInterface $uri, array $options = [])
22
- * @method Promise\PromiseInterface patchAsync(string|UriInterface $uri, array $options = [])
23
- * @method Promise\PromiseInterface deleteAsync(string|UriInterface $uri, array $options = [])
24
- */
25
- class Client implements ClientInterface
26
- {
27
- /** @var array Default request options */
28
- private $config;
29
-
30
- /**
31
- * Clients accept an array of constructor parameters.
32
- *
33
- * Here's an example of creating a client using a base_uri and an array of
34
- * default request options to apply to each request:
35
- *
36
- * $client = new Client([
37
- * 'base_uri' => 'http://www.foo.com/1.0/',
38
- * 'timeout' => 0,
39
- * 'allow_redirects' => false,
40
- * 'proxy' => '192.168.16.1:10'
41
- * ]);
42
- *
43
- * Client configuration settings include the following options:
44
- *
45
- * - handler: (callable) Function that transfers HTTP requests over the
46
- * wire. The function is called with a Psr7\Http\Message\RequestInterface
47
- * and array of transfer options, and must return a
48
- * GuzzleHttp\Promise\PromiseInterface that is fulfilled with a
49
- * Psr7\Http\Message\ResponseInterface on success. "handler" is a
50
- * constructor only option that cannot be overridden in per/request
51
- * options. If no handler is provided, a default handler will be created
52
- * that enables all of the request options below by attaching all of the
53
- * default middleware to the handler.
54
- * - base_uri: (string|UriInterface) Base URI of the client that is merged
55
- * into relative URIs. Can be a string or instance of UriInterface.
56
- * - **: any request option
57
- *
58
- * @param array $config Client configuration settings.
59
- *
60
- * @see \GuzzleHttp\RequestOptions for a list of available request options.
61
- */
62
- public function __construct(array $config = [])
63
- {
64
- if (!isset($config['handler'])) {
65
- $config['handler'] = HandlerStack::create();
66
- } elseif (!is_callable($config['handler'])) {
67
- throw new \InvalidArgumentException('handler must be a callable');
68
- }
69
-
70
- // Convert the base_uri to a UriInterface
71
- if (isset($config['base_uri'])) {
72
- $config['base_uri'] = Psr7\uri_for($config['base_uri']);
73
- }
74
-
75
- $this->configureDefaults($config);
76
- }
77
-
78
- public function __call($method, $args)
79
- {
80
- if (count($args) < 1) {
81
- throw new \InvalidArgumentException('Magic request methods require a URI and optional options array');
82
- }
83
-
84
- $uri = $args[0];
85
- $opts = isset($args[1]) ? $args[1] : [];
86
-
87
- return substr($method, -5) === 'Async'
88
- ? $this->requestAsync(substr($method, 0, -5), $uri, $opts)
89
- : $this->request($method, $uri, $opts);
90
- }
91
-
92
- public function sendAsync(RequestInterface $request, array $options = [])
93
- {
94
- // Merge the base URI into the request URI if needed.
95
- $options = $this->prepareDefaults($options);
96
-
97
- return $this->transfer(
98
- $request->withUri($this->buildUri($request->getUri(), $options), $request->hasHeader('Host')),
99
- $options
100
- );
101
- }
102
-
103
- public function send(RequestInterface $request, array $options = [])
104
- {
105
- $options[RequestOptions::SYNCHRONOUS] = true;
106
- return $this->sendAsync($request, $options)->wait();
107
- }
108
-
109
- public function requestAsync($method, $uri = '', array $options = [])
110
- {
111
- $options = $this->prepareDefaults($options);
112
- // Remove request modifying parameter because it can be done up-front.
113
- $headers = isset($options['headers']) ? $options['headers'] : [];
114
- $body = isset($options['body']) ? $options['body'] : null;
115
- $version = isset($options['version']) ? $options['version'] : '1.1';
116
- // Merge the URI into the base URI.
117
- $uri = $this->buildUri($uri, $options);
118
- if (is_array($body)) {
119
- $this->invalidBody();
120
- }
121
- $request = new Psr7\Request($method, $uri, $headers, $body, $version);
122
- // Remove the option so that they are not doubly-applied.
123
- unset($options['headers'], $options['body'], $options['version']);
124
-
125
- return $this->transfer($request, $options);
126
- }
127
-
128
- public function request($method, $uri = '', array $options = [])
129
- {
130
- $options[RequestOptions::SYNCHRONOUS] = true;
131
- return $this->requestAsync($method, $uri, $options)->wait();
132
- }
133
-
134
- public function getConfig($option = null)
135
- {
136
- return $option === null
137
- ? $this->config
138
- : (isset($this->config[$option]) ? $this->config[$option] : null);
139
- }
140
-
141
- private function buildUri($uri, array $config)
142
- {
143
- // for BC we accept null which would otherwise fail in uri_for
144
- $uri = Psr7\uri_for($uri === null ? '' : $uri);
145
-
146
- if (isset($config['base_uri'])) {
147
- $uri = Psr7\UriResolver::resolve(Psr7\uri_for($config['base_uri']), $uri);
148
- }
149
-
150
- return $uri->getScheme() === '' && $uri->getHost() !== '' ? $uri->withScheme('http') : $uri;
151
- }
152
-
153
- /**
154
- * Configures the default options for a client.
155
- *
156
- * @param array $config
157
- */
158
- private function configureDefaults(array $config)
159
- {
160
- $defaults = [
161
- 'allow_redirects' => RedirectMiddleware::$defaultSettings,
162
- 'http_errors' => true,
163
- 'decode_content' => true,
164
- 'verify' => true,
165
- 'cookies' => false
166
- ];
167
-
168
- // Use the standard Linux HTTP_PROXY and HTTPS_PROXY if set.
169
-
170
- // We can only trust the HTTP_PROXY environment variable in a CLI
171
- // process due to the fact that PHP has no reliable mechanism to
172
- // get environment variables that start with "HTTP_".
173
- if (php_sapi_name() == 'cli' && getenv('HTTP_PROXY')) {
174
- $defaults['proxy']['http'] = getenv('HTTP_PROXY');
175
- }
176
-
177
- if ($proxy = getenv('HTTPS_PROXY')) {
178
- $defaults['proxy']['https'] = $proxy;
179
- }
180
-
181
- if ($noProxy = getenv('NO_PROXY')) {
182
- $cleanedNoProxy = str_replace(' ', '', $noProxy);
183
- $defaults['proxy']['no'] = explode(',', $cleanedNoProxy);
184
- }
185
-
186
- $this->config = $config + $defaults;
187
-
188
- if (!empty($config['cookies']) && $config['cookies'] === true) {
189
- $this->config['cookies'] = new CookieJar();
190
- }
191
-
192
- // Add the default user-agent header.
193
- if (!isset($this->config['headers'])) {
194
- $this->config['headers'] = ['User-Agent' => default_user_agent()];
195
- } else {
196
- // Add the User-Agent header if one was not already set.
197
- foreach (array_keys($this->config['headers']) as $name) {
198
- if (strtolower($name) === 'user-agent') {
199
- return;
200
- }
201
- }
202
- $this->config['headers']['User-Agent'] = default_user_agent();
203
- }
204
- }
205
-
206
- /**
207
- * Merges default options into the array.
208
- *
209
- * @param array $options Options to modify by reference
210
- *
211
- * @return array
212
- */
213
- private function prepareDefaults($options)
214
- {
215
- $defaults = $this->config;
216
-
217
- if (!empty($defaults['headers'])) {
218
- // Default headers are only added if they are not present.
219
- $defaults['_conditional'] = $defaults['headers'];
220
- unset($defaults['headers']);
221
- }
222
-
223
- // Special handling for headers is required as they are added as
224
- // conditional headers and as headers passed to a request ctor.
225
- if (array_key_exists('headers', $options)) {
226
- // Allows default headers to be unset.
227
- if ($options['headers'] === null) {
228
- $defaults['_conditional'] = null;
229
- unset($options['headers']);
230
- } elseif (!is_array($options['headers'])) {
231
- throw new \InvalidArgumentException('headers must be an array');
232
- }
233
- }
234
-
235
- // Shallow merge defaults underneath options.
236
- $result = $options + $defaults;
237
-
238
- // Remove null values.
239
- foreach ($result as $k => $v) {
240
- if ($v === null) {
241
- unset($result[$k]);
242
- }
243
- }
244
-
245
- return $result;
246
- }
247
-
248
- /**
249
- * Transfers the given request and applies request options.
250
- *
251
- * The URI of the request is not modified and the request options are used
252
- * as-is without merging in default options.
253
- *
254
- * @param RequestInterface $request
255
- * @param array $options
256
- *
257
- * @return Promise\PromiseInterface
258
- */
259
- private function transfer(RequestInterface $request, array $options)
260
- {
261
- // save_to -> sink
262
- if (isset($options['save_to'])) {
263
- $options['sink'] = $options['save_to'];
264
- unset($options['save_to']);
265
- }
266
-
267
- // exceptions -> http_errors
268
- if (isset($options['exceptions'])) {
269
- $options['http_errors'] = $options['exceptions'];
270
- unset($options['exceptions']);
271
- }
272
-
273
- $request = $this->applyOptions($request, $options);
274
- $handler = $options['handler'];
275
-
276
- try {
277
- return Promise\promise_for($handler($request, $options));
278
- } catch (\Exception $e) {
279
- return Promise\rejection_for($e);
280
- }
281
- }
282
-
283
- /**
284
- * Applies the array of request options to a request.
285
- *
286
- * @param RequestInterface $request
287
- * @param array $options
288
- *
289
- * @return RequestInterface
290
- */
291
- private function applyOptions(RequestInterface $request, array &$options)
292
- {
293
- $modify = [
294
- 'set_headers' => [],
295
- ];
296
-
297
- if (isset($options['headers'])) {
298
- $modify['set_headers'] = $options['headers'];
299
- unset($options['headers']);
300
- }
301
-
302
- if (isset($options['form_params'])) {
303
- if (isset($options['multipart'])) {
304
- throw new \InvalidArgumentException('You cannot use '
305
- . 'form_params and multipart at the same time. Use the '
306
- . 'form_params option if you want to send application/'
307
- . 'x-www-form-urlencoded requests, and the multipart '
308
- . 'option to send multipart/form-data requests.');
309
- }
310
- $options['body'] = http_build_query($options['form_params'], '', '&');
311
- unset($options['form_params']);
312
- // Ensure that we don't have the header in different case and set the new value.
313
- $options['_conditional'] = Psr7\_caseless_remove(['Content-Type'], $options['_conditional']);
314
- $options['_conditional']['Content-Type'] = 'application/x-www-form-urlencoded';
315
- }
316
-
317
- if (isset($options['multipart'])) {
318
- $options['body'] = new Psr7\MultipartStream($options['multipart']);
319
- unset($options['multipart']);
320
- }
321
-
322
- if (isset($options['json'])) {
323
- $options['body'] = \GuzzleHttp\json_encode($options['json']);
324
- unset($options['json']);
325
- // Ensure that we don't have the header in different case and set the new value.
326
- $options['_conditional'] = Psr7\_caseless_remove(['Content-Type'], $options['_conditional']);
327
- $options['_conditional']['Content-Type'] = 'application/json';
328
- }
329
-
330
- if (!empty($options['decode_content'])
331
- && $options['decode_content'] !== true
332
- ) {
333
- // Ensure that we don't have the header in different case and set the new value.
334
- $options['_conditional'] = Psr7\_caseless_remove(['Accept-Encoding'], $options['_conditional']);
335
- $modify['set_headers']['Accept-Encoding'] = $options['decode_content'];
336
- }
337
-
338
- if (isset($options['body'])) {
339
- if (is_array($options['body'])) {
340
- $this->invalidBody();
341
- }
342
- $modify['body'] = Psr7\stream_for($options['body']);
343
- unset($options['body']);
344
- }
345
-
346
- if (!empty($options['auth']) && is_array($options['auth'])) {
347
- $value = $options['auth'];
348
- $type = isset($value[2]) ? strtolower($value[2]) : 'basic';
349
- switch ($type) {
350
- case 'basic':
351
- // Ensure that we don't have the header in different case and set the new value.
352
- $modify['set_headers'] = Psr7\_caseless_remove(['Authorization'], $modify['set_headers']);
353
- $modify['set_headers']['Authorization'] = 'Basic '
354
- . base64_encode("$value[0]:$value[1]");
355
- break;
356
- case 'digest':
357
- // @todo: Do not rely on curl
358
- $options['curl'][CURLOPT_HTTPAUTH] = CURLAUTH_DIGEST;
359
- $options['curl'][CURLOPT_USERPWD] = "$value[0]:$value[1]";
360
- break;
361
- case 'ntlm':
362
- $options['curl'][CURLOPT_HTTPAUTH] = CURLAUTH_NTLM;
363
- $options['curl'][CURLOPT_USERPWD] = "$value[0]:$value[1]";
364
- break;
365
- }
366
- }
367
-
368
- if (isset($options['query'])) {
369
- $value = $options['query'];
370
- if (is_array($value)) {
371
- $value = http_build_query($value, null, '&', PHP_QUERY_RFC3986);
372
- }
373
- if (!is_string($value)) {
374
- throw new \InvalidArgumentException('query must be a string or array');
375
- }
376
- $modify['query'] = $value;
377
- unset($options['query']);
378
- }
379
-
380
- // Ensure that sink is not an invalid value.
381
- if (isset($options['sink'])) {
382
- // TODO: Add more sink validation?
383
- if (is_bool($options['sink'])) {
384
- throw new \InvalidArgumentException('sink must not be a boolean');
385
- }
386
- }
387
-
388
- $request = Psr7\modify_request($request, $modify);
389
- if ($request->getBody() instanceof Psr7\MultipartStream) {
390
- // Use a multipart/form-data POST if a Content-Type is not set.
391
- // Ensure that we don't have the header in different case and set the new value.
392
- $options['_conditional'] = Psr7\_caseless_remove(['Content-Type'], $options['_conditional']);
393
- $options['_conditional']['Content-Type'] = 'multipart/form-data; boundary='
394
- . $request->getBody()->getBoundary();
395
- }
396
-
397
- // Merge in conditional headers if they are not present.
398
- if (isset($options['_conditional'])) {
399
- // Build up the changes so it's in a single clone of the message.
400
- $modify = [];
401
- foreach ($options['_conditional'] as $k => $v) {
402
- if (!$request->hasHeader($k)) {
403
- $modify['set_headers'][$k] = $v;
404
- }
405
- }
406
- $request = Psr7\modify_request($request, $modify);
407
- // Don't pass this internal value along to middleware/handlers.
408
- unset($options['_conditional']);
409
- }
410
-
411
- return $request;
412
- }
413
-
414
- private function invalidBody()
415
- {
416
- throw new \InvalidArgumentException('Passing in the "body" request '
417
- . 'option as an array to send a POST request has been deprecated. '
418
- . 'Please use the "form_params" request option to send a '
419
- . 'application/x-www-form-urlencoded request, or the "multipart" '
420
- . 'request option to send a multipart/form-data request.');
421
- }
422
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/guzzle/src/ClientInterface.php DELETED
@@ -1,84 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp;
3
-
4
- use GuzzleHttp\Promise\PromiseInterface;
5
- use GuzzleHttp\Exception\GuzzleException;
6
- use Psr\Http\Message\RequestInterface;
7
- use Psr\Http\Message\ResponseInterface;
8
- use Psr\Http\Message\UriInterface;
9
-
10
- /**
11
- * Client interface for sending HTTP requests.
12
- */
13
- interface ClientInterface
14
- {
15
- const VERSION = '6.3.3';
16
-
17
- /**
18
- * Send an HTTP request.
19
- *
20
- * @param RequestInterface $request Request to send
21
- * @param array $options Request options to apply to the given
22
- * request and to the transfer.
23
- *
24
- * @return ResponseInterface
25
- * @throws GuzzleException
26
- */
27
- public function send(RequestInterface $request, array $options = []);
28
-
29
- /**
30
- * Asynchronously send an HTTP request.
31
- *
32
- * @param RequestInterface $request Request to send
33
- * @param array $options Request options to apply to the given
34
- * request and to the transfer.
35
- *
36
- * @return PromiseInterface
37
- */
38
- public function sendAsync(RequestInterface $request, array $options = []);
39
-
40
- /**
41
- * Create and send an HTTP request.
42
- *
43
- * Use an absolute path to override the base path of the client, or a
44
- * relative path to append to the base path of the client. The URL can
45
- * contain the query string as well.
46
- *
47
- * @param string $method HTTP method.
48
- * @param string|UriInterface $uri URI object or string.
49
- * @param array $options Request options to apply.
50
- *
51
- * @return ResponseInterface
52
- * @throws GuzzleException
53
- */
54
- public function request($method, $uri, array $options = []);
55
-
56
- /**
57
- * Create and send an asynchronous HTTP request.
58
- *
59
- * Use an absolute path to override the base path of the client, or a
60
- * relative path to append to the base path of the client. The URL can
61
- * contain the query string as well. Use an array to provide a URL
62
- * template and additional variables to use in the URL template expansion.
63
- *
64
- * @param string $method HTTP method
65
- * @param string|UriInterface $uri URI object or string.
66
- * @param array $options Request options to apply.
67
- *
68
- * @return PromiseInterface
69
- */
70
- public function requestAsync($method, $uri, array $options = []);
71
-
72
- /**
73
- * Get a client configuration option.
74
- *
75
- * These options include default request options of the client, a "handler"
76
- * (if utilized by the concrete client), and a "base_uri" if utilized by
77
- * the concrete client.
78
- *
79
- * @param string|null $option The config option to retrieve.
80
- *
81
- * @return mixed
82
- */
83
- public function getConfig($option = null);
84
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/guzzle/src/Cookie/CookieJar.php DELETED
@@ -1,314 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Cookie;
3
-
4
- use Psr\Http\Message\RequestInterface;
5
- use Psr\Http\Message\ResponseInterface;
6
-
7
- /**
8
- * Cookie jar that stores cookies as an array
9
- */
10
- class CookieJar implements CookieJarInterface
11
- {
12
- /** @var SetCookie[] Loaded cookie data */
13
- private $cookies = [];
14
-
15
- /** @var bool */
16
- private $strictMode;
17
-
18
- /**
19
- * @param bool $strictMode Set to true to throw exceptions when invalid
20
- * cookies are added to the cookie jar.
21
- * @param array $cookieArray Array of SetCookie objects or a hash of
22
- * arrays that can be used with the SetCookie
23
- * constructor
24
- */
25
- public function __construct($strictMode = false, $cookieArray = [])
26
- {
27
- $this->strictMode = $strictMode;
28
-
29
- foreach ($cookieArray as $cookie) {
30
- if (!($cookie instanceof SetCookie)) {
31
- $cookie = new SetCookie($cookie);
32
- }
33
- $this->setCookie($cookie);
34
- }
35
- }
36
-
37
- /**
38
- * Create a new Cookie jar from an associative array and domain.
39
- *
40
- * @param array $cookies Cookies to create the jar from
41
- * @param string $domain Domain to set the cookies to
42
- *
43
- * @return self
44
- */
45
- public static function fromArray(array $cookies, $domain)
46
- {
47
- $cookieJar = new self();
48
- foreach ($cookies as $name => $value) {
49
- $cookieJar->setCookie(new SetCookie([
50
- 'Domain' => $domain,
51
- 'Name' => $name,
52
- 'Value' => $value,
53
- 'Discard' => true
54
- ]));
55
- }
56
-
57
- return $cookieJar;
58
- }
59
-
60
- /**
61
- * @deprecated
62
- */
63
- public static function getCookieValue($value)
64
- {
65
- return $value;
66
- }
67
-
68
- /**
69
- * Evaluate if this cookie should be persisted to storage
70
- * that survives between requests.
71
- *
72
- * @param SetCookie $cookie Being evaluated.
73
- * @param bool $allowSessionCookies If we should persist session cookies
74
- * @return bool
75
- */
76
- public static function shouldPersist(
77
- SetCookie $cookie,
78
- $allowSessionCookies = false
79
- ) {
80
- if ($cookie->getExpires() || $allowSessionCookies) {
81
- if (!$cookie->getDiscard()) {
82
- return true;
83
- }
84
- }
85
-
86
- return false;
87
- }
88
-
89
- /**
90
- * Finds and returns the cookie based on the name
91
- *
92
- * @param string $name cookie name to search for
93
- * @return SetCookie|null cookie that was found or null if not found
94
- */
95
- public function getCookieByName($name)
96
- {
97
- // don't allow a null name
98
- if ($name === null) {
99
- return null;
100
- }
101
- foreach ($this->cookies as $cookie) {
102
- if ($cookie->getName() !== null && strcasecmp($cookie->getName(), $name) === 0) {
103
- return $cookie;
104
- }
105
- }
106
- }
107
-
108
- public function toArray()
109
- {
110
- return array_map(function (SetCookie $cookie) {
111
- return $cookie->toArray();
112
- }, $this->getIterator()->getArrayCopy());
113
- }
114
-
115
- public function clear($domain = null, $path = null, $name = null)
116
- {
117
- if (!$domain) {
118
- $this->cookies = [];
119
- return;
120
- } elseif (!$path) {
121
- $this->cookies = array_filter(
122
- $this->cookies,
123
- function (SetCookie $cookie) use ($path, $domain) {
124
- return !$cookie->matchesDomain($domain);
125
- }
126
- );
127
- } elseif (!$name) {
128
- $this->cookies = array_filter(
129
- $this->cookies,
130
- function (SetCookie $cookie) use ($path, $domain) {
131
- return !($cookie->matchesPath($path) &&
132
- $cookie->matchesDomain($domain));
133
- }
134
- );
135
- } else {
136
- $this->cookies = array_filter(
137
- $this->cookies,
138
- function (SetCookie $cookie) use ($path, $domain, $name) {
139
- return !($cookie->getName() == $name &&
140
- $cookie->matchesPath($path) &&
141
- $cookie->matchesDomain($domain));
142
- }
143
- );
144
- }
145
- }
146
-
147
- public function clearSessionCookies()
148
- {
149
- $this->cookies = array_filter(
150
- $this->cookies,
151
- function (SetCookie $cookie) {
152
- return !$cookie->getDiscard() && $cookie->getExpires();
153
- }
154
- );
155
- }
156
-
157
- public function setCookie(SetCookie $cookie)
158
- {
159
- // If the name string is empty (but not 0), ignore the set-cookie
160
- // string entirely.
161
- $name = $cookie->getName();
162
- if (!$name && $name !== '0') {
163
- return false;
164
- }
165
-
166
- // Only allow cookies with set and valid domain, name, value
167
- $result = $cookie->validate();
168
- if ($result !== true) {
169
- if ($this->strictMode) {
170
- throw new \RuntimeException('Invalid cookie: ' . $result);
171
- } else {
172
- $this->removeCookieIfEmpty($cookie);
173
- return false;
174
- }
175
- }
176
-
177
- // Resolve conflicts with previously set cookies
178
- foreach ($this->cookies as $i => $c) {
179
-
180
- // Two cookies are identical, when their path, and domain are
181
- // identical.
182
- if ($c->getPath() != $cookie->getPath() ||
183
- $c->getDomain() != $cookie->getDomain() ||
184
- $c->getName() != $cookie->getName()
185
- ) {
186
- continue;
187
- }
188
-
189
- // The previously set cookie is a discard cookie and this one is
190
- // not so allow the new cookie to be set
191
- if (!$cookie->getDiscard() && $c->getDiscard()) {
192
- unset($this->cookies[$i]);
193
- continue;
194
- }
195
-
196
- // If the new cookie's expiration is further into the future, then
197
- // replace the old cookie
198
- if ($cookie->getExpires() > $c->getExpires()) {
199
- unset($this->cookies[$i]);
200
- continue;
201
- }
202
-
203
- // If the value has changed, we better change it
204
- if ($cookie->getValue() !== $c->getValue()) {
205
- unset($this->cookies[$i]);
206
- continue;
207
- }
208
-
209
- // The cookie exists, so no need to continue
210
- return false;
211
- }
212
-
213
- $this->cookies[] = $cookie;
214
-
215
- return true;
216
- }
217
-
218
- public function count()
219
- {
220
- return count($this->cookies);
221
- }
222
-
223
- public function getIterator()
224
- {
225
- return new \ArrayIterator(array_values($this->cookies));
226
- }
227
-
228
- public function extractCookies(
229
- RequestInterface $request,
230
- ResponseInterface $response
231
- ) {
232
- if ($cookieHeader = $response->getHeader('Set-Cookie')) {
233
- foreach ($cookieHeader as $cookie) {
234
- $sc = SetCookie::fromString($cookie);
235
- if (!$sc->getDomain()) {
236
- $sc->setDomain($request->getUri()->getHost());
237
- }
238
- if (0 !== strpos($sc->getPath(), '/')) {
239
- $sc->setPath($this->getCookiePathFromRequest($request));
240
- }
241
- $this->setCookie($sc);
242
- }
243
- }
244
- }
245
-
246
- /**
247
- * Computes cookie path following RFC 6265 section 5.1.4
248
- *
249
- * @link https://tools.ietf.org/html/rfc6265#section-5.1.4
250
- *
251
- * @param RequestInterface $request
252
- * @return string
253
- */
254
- private function getCookiePathFromRequest(RequestInterface $request)
255
- {
256
- $uriPath = $request->getUri()->getPath();
257
- if ('' === $uriPath) {
258
- return '/';
259
- }
260
- if (0 !== strpos($uriPath, '/')) {
261
- return '/';
262
- }
263
- if ('/' === $uriPath) {
264
- return '/';
265
- }
266
- if (0 === $lastSlashPos = strrpos($uriPath, '/')) {
267
- return '/';
268
- }
269
-
270
- return substr($uriPath, 0, $lastSlashPos);
271
- }
272
-
273
- public function withCookieHeader(RequestInterface $request)
274
- {
275
- $values = [];
276
- $uri = $request->getUri();
277
- $scheme = $uri->getScheme();
278
- $host = $uri->getHost();
279
- $path = $uri->getPath() ?: '/';
280
-
281
- foreach ($this->cookies as $cookie) {
282
- if ($cookie->matchesPath($path) &&
283
- $cookie->matchesDomain($host) &&
284
- !$cookie->isExpired() &&
285
- (!$cookie->getSecure() || $scheme === 'https')
286
- ) {
287
- $values[] = $cookie->getName() . '='
288
- . $cookie->getValue();
289
- }
290
- }
291
-
292
- return $values
293
- ? $request->withHeader('Cookie', implode('; ', $values))
294
- : $request;
295
- }
296
-
297
- /**
298
- * If a cookie already exists and the server asks to set it again with a
299
- * null value, the cookie must be deleted.
300
- *
301
- * @param SetCookie $cookie
302
- */
303
- private function removeCookieIfEmpty(SetCookie $cookie)
304
- {
305
- $cookieValue = $cookie->getValue();
306
- if ($cookieValue === null || $cookieValue === '') {
307
- $this->clear(
308
- $cookie->getDomain(),
309
- $cookie->getPath(),
310
- $cookie->getName()
311
- );
312
- }
313
- }
314
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php DELETED
@@ -1,84 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Cookie;
3
-
4
- use Psr\Http\Message\RequestInterface;
5
- use Psr\Http\Message\ResponseInterface;
6
-
7
- /**
8
- * Stores HTTP cookies.
9
- *
10
- * It extracts cookies from HTTP requests, and returns them in HTTP responses.
11
- * CookieJarInterface instances automatically expire contained cookies when
12
- * necessary. Subclasses are also responsible for storing and retrieving
13
- * cookies from a file, database, etc.
14
- *
15
- * @link http://docs.python.org/2/library/cookielib.html Inspiration
16
- */
17
- interface CookieJarInterface extends \Countable, \IteratorAggregate
18
- {
19
- /**
20
- * Create a request with added cookie headers.
21
- *
22
- * If no matching cookies are found in the cookie jar, then no Cookie
23
- * header is added to the request and the same request is returned.
24
- *
25
- * @param RequestInterface $request Request object to modify.
26
- *
27
- * @return RequestInterface returns the modified request.
28
- */
29
- public function withCookieHeader(RequestInterface $request);
30
-
31
- /**
32
- * Extract cookies from an HTTP response and store them in the CookieJar.
33
- *
34
- * @param RequestInterface $request Request that was sent
35
- * @param ResponseInterface $response Response that was received
36
- */
37
- public function extractCookies(
38
- RequestInterface $request,
39
- ResponseInterface $response
40
- );
41
-
42
- /**
43
- * Sets a cookie in the cookie jar.
44
- *
45
- * @param SetCookie $cookie Cookie to set.
46
- *
47
- * @return bool Returns true on success or false on failure
48
- */
49
- public function setCookie(SetCookie $cookie);
50
-
51
- /**
52
- * Remove cookies currently held in the cookie jar.
53
- *
54
- * Invoking this method without arguments will empty the whole cookie jar.
55
- * If given a $domain argument only cookies belonging to that domain will
56
- * be removed. If given a $domain and $path argument, cookies belonging to
57
- * the specified path within that domain are removed. If given all three
58
- * arguments, then the cookie with the specified name, path and domain is
59
- * removed.
60
- *
61
- * @param string $domain Clears cookies matching a domain
62
- * @param string $path Clears cookies matching a domain and path
63
- * @param string $name Clears cookies matching a domain, path, and name
64
- *
65
- * @return CookieJarInterface
66
- */
67
- public function clear($domain = null, $path = null, $name = null);
68
-
69
- /**
70
- * Discard all sessions cookies.
71
- *
72
- * Removes cookies that don't have an expire field or a have a discard
73
- * field set to true. To be called when the user agent shuts down according
74
- * to RFC 2965.
75
- */
76
- public function clearSessionCookies();
77
-
78
- /**
79
- * Converts the cookie jar to an array.
80
- *
81
- * @return array
82
- */
83
- public function toArray();
84
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/guzzle/src/Cookie/FileCookieJar.php DELETED
@@ -1,90 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Cookie;
3
-
4
- /**
5
- * Persists non-session cookies using a JSON formatted file
6
- */
7
- class FileCookieJar extends CookieJar
8
- {
9
- /** @var string filename */
10
- private $filename;
11
-
12
- /** @var bool Control whether to persist session cookies or not. */
13
- private $storeSessionCookies;
14
-
15
- /**
16
- * Create a new FileCookieJar object
17
- *
18
- * @param string $cookieFile File to store the cookie data
19
- * @param bool $storeSessionCookies Set to true to store session cookies
20
- * in the cookie jar.
21
- *
22
- * @throws \RuntimeException if the file cannot be found or created
23
- */
24
- public function __construct($cookieFile, $storeSessionCookies = false)
25
- {
26
- $this->filename = $cookieFile;
27
- $this->storeSessionCookies = $storeSessionCookies;
28
-
29
- if (file_exists($cookieFile)) {
30
- $this->load($cookieFile);
31
- }
32
- }
33
-
34
- /**
35
- * Saves the file when shutting down
36
- */
37
- public function __destruct()
38
- {
39
- $this->save($this->filename);
40
- }
41
-
42
- /**
43
- * Saves the cookies to a file.
44
- *
45
- * @param string $filename File to save
46
- * @throws \RuntimeException if the file cannot be found or created
47
- */
48
- public function save($filename)
49
- {
50
- $json = [];
51
- foreach ($this as $cookie) {
52
- /** @var SetCookie $cookie */
53
- if (CookieJar::shouldPersist($cookie, $this->storeSessionCookies)) {
54
- $json[] = $cookie->toArray();
55
- }
56
- }
57
-
58
- $jsonStr = \GuzzleHttp\json_encode($json);
59
- if (false === file_put_contents($filename, $jsonStr)) {
60
- throw new \RuntimeException("Unable to save file {$filename}");
61
- }
62
- }
63
-
64
- /**
65
- * Load cookies from a JSON formatted file.
66
- *
67
- * Old cookies are kept unless overwritten by newly loaded ones.
68
- *
69
- * @param string $filename Cookie file to load.
70
- * @throws \RuntimeException if the file cannot be loaded.
71
- */
72
- public function load($filename)
73
- {
74
- $json = file_get_contents($filename);
75
- if (false === $json) {
76
- throw new \RuntimeException("Unable to load file {$filename}");
77
- } elseif ($json === '') {
78
- return;
79
- }
80
-
81
- $data = \GuzzleHttp\json_decode($json, true);
82
- if (is_array($data)) {
83
- foreach (json_decode($json, true) as $cookie) {
84
- $this->setCookie(new SetCookie($cookie));
85
- }
86
- } elseif (strlen($data)) {
87
- throw new \RuntimeException("Invalid cookie file: {$filename}");
88
- }
89
- }
90
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/guzzle/src/Cookie/SessionCookieJar.php DELETED
@@ -1,71 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Cookie;
3
-
4
- /**
5
- * Persists cookies in the client session
6
- */
7
- class SessionCookieJar extends CookieJar
8
- {
9
- /** @var string session key */
10
- private $sessionKey;
11
-
12
- /** @var bool Control whether to persist session cookies or not. */
13
- private $storeSessionCookies;
14
-
15
- /**
16
- * Create a new SessionCookieJar object
17
- *
18
- * @param string $sessionKey Session key name to store the cookie
19
- * data in session
20
- * @param bool $storeSessionCookies Set to true to store session cookies
21
- * in the cookie jar.
22
- */
23
- public function __construct($sessionKey, $storeSessionCookies = false)
24
- {
25
- $this->sessionKey = $sessionKey;
26
- $this->storeSessionCookies = $storeSessionCookies;
27
- $this->load();
28
- }
29
-
30
- /**
31
- * Saves cookies to session when shutting down
32
- */
33
- public function __destruct()
34
- {
35
- $this->save();
36
- }
37
-
38
- /**
39
- * Save cookies to the client session
40
- */
41
- public function save()
42
- {
43
- $json = [];
44
- foreach ($this as $cookie) {
45
- /** @var SetCookie $cookie */
46
- if (CookieJar::shouldPersist($cookie, $this->storeSessionCookies)) {
47
- $json[] = $cookie->toArray();
48
- }
49
- }
50
-
51
- $_SESSION[$this->sessionKey] = json_encode($json);
52
- }
53
-
54
- /**
55
- * Load the contents of the client session into the data array
56
- */
57
- protected function load()
58
- {
59
- if (!isset($_SESSION[$this->sessionKey])) {
60
- return;
61
- }
62
- $data = json_decode($_SESSION[$this->sessionKey], true);
63
- if (is_array($data)) {
64
- foreach ($data as $cookie) {
65
- $this->setCookie(new SetCookie($cookie));
66
- }
67
- } elseif (strlen($data)) {
68
- throw new \RuntimeException("Invalid cookie data");
69
- }
70
- }
71
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/guzzle/src/Cookie/SetCookie.php DELETED
@@ -1,403 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Cookie;
3
-
4
- /**
5
- * Set-Cookie object
6
- */
7
- class SetCookie
8
- {
9
- /** @var array */
10
- private static $defaults = [
11
- 'Name' => null,
12
- 'Value' => null,
13
- 'Domain' => null,
14
- 'Path' => '/',
15
- 'Max-Age' => null,
16
- 'Expires' => null,
17
- 'Secure' => false,
18
- 'Discard' => false,
19
- 'HttpOnly' => false
20
- ];
21
-
22
- /** @var array Cookie data */
23
- private $data;
24
-
25
- /**
26
- * Create a new SetCookie object from a string
27
- *
28
- * @param string $cookie Set-Cookie header string
29
- *
30
- * @return self
31
- */
32
- public static function fromString($cookie)
33
- {
34
- // Create the default return array
35
- $data = self::$defaults;
36
- // Explode the cookie string using a series of semicolons
37
- $pieces = array_filter(array_map('trim', explode(';', $cookie)));
38
- // The name of the cookie (first kvp) must exist and include an equal sign.
39
- if (empty($pieces[0]) || !strpos($pieces[0], '=')) {
40
- return new self($data);
41
- }
42
-
43
- // Add the cookie pieces into the parsed data array
44
- foreach ($pieces as $part) {
45
- $cookieParts = explode('=', $part, 2);
46
- $key = trim($cookieParts[0]);
47
- $value = isset($cookieParts[1])
48
- ? trim($cookieParts[1], " \n\r\t\0\x0B")
49
- : true;
50
-
51
- // Only check for non-cookies when cookies have been found
52
- if (empty($data['Name'])) {
53
- $data['Name'] = $key;
54
- $data['Value'] = $value;
55
- } else {
56
- foreach (array_keys(self::$defaults) as $search) {
57
- if (!strcasecmp($search, $key)) {
58
- $data[$search] = $value;
59
- continue 2;
60
- }
61
- }
62
- $data[$key] = $value;
63
- }
64
- }
65
-
66
- return new self($data);
67
- }
68
-
69
- /**
70
- * @param array $data Array of cookie data provided by a Cookie parser
71
- */
72
- public function __construct(array $data = [])
73
- {
74
- $this->data = array_replace(self::$defaults, $data);
75
- // Extract the Expires value and turn it into a UNIX timestamp if needed
76
- if (!$this->getExpires() && $this->getMaxAge()) {
77
- // Calculate the Expires date
78
- $this->setExpires(time() + $this->getMaxAge());
79
- } elseif ($this->getExpires() && !is_numeric($this->getExpires())) {
80
- $this->setExpires($this->getExpires());
81
- }
82
- }
83
-
84
- public function __toString()
85
- {
86
- $str = $this->data['Name'] . '=' . $this->data['Value'] . '; ';
87
- foreach ($this->data as $k => $v) {
88
- if ($k !== 'Name' && $k !== 'Value' && $v !== null && $v !== false) {
89
- if ($k === 'Expires') {
90
- $str .= 'Expires=' . gmdate('D, d M Y H:i:s \G\M\T', $v) . '; ';
91
- } else {
92
- $str .= ($v === true ? $k : "{$k}={$v}") . '; ';
93
- }
94
- }
95
- }
96
-
97
- return rtrim($str, '; ');
98
- }
99
-
100
- public function toArray()
101
- {
102
- return $this->data;
103
- }
104
-
105
- /**
106
- * Get the cookie name
107
- *
108
- * @return string
109
- */
110
- public function getName()
111
- {
112
- return $this->data['Name'];
113
- }
114
-
115
- /**
116
- * Set the cookie name
117
- *
118
- * @param string $name Cookie name
119
- */
120
- public function setName($name)
121
- {
122
- $this->data['Name'] = $name;
123
- }
124
-
125
- /**
126
- * Get the cookie value
127
- *
128
- * @return string
129
- */
130
- public function getValue()
131
- {
132
- return $this->data['Value'];
133
- }
134
-
135
- /**
136
- * Set the cookie value
137
- *
138
- * @param string $value Cookie value
139
- */
140
- public function setValue($value)
141
- {
142
- $this->data['Value'] = $value;
143
- }
144
-
145
- /**
146
- * Get the domain
147
- *
148
- * @return string|null
149
- */
150
- public function getDomain()
151
- {
152
- return $this->data['Domain'];
153
- }
154
-
155
- /**
156
- * Set the domain of the cookie
157
- *
158
- * @param string $domain
159
- */
160
- public function setDomain($domain)
161
- {
162
- $this->data['Domain'] = $domain;
163
- }
164
-
165
- /**
166
- * Get the path
167
- *
168
- * @return string
169
- */
170
- public function getPath()
171
- {
172
- return $this->data['Path'];
173
- }
174
-
175
- /**
176
- * Set the path of the cookie
177
- *
178
- * @param string $path Path of the cookie
179
- */
180
- public function setPath($path)
181
- {
182
- $this->data['Path'] = $path;
183
- }
184
-
185
- /**
186
- * Maximum lifetime of the cookie in seconds
187
- *
188
- * @return int|null
189
- */
190
- public function getMaxAge()
191
- {
192
- return $this->data['Max-Age'];
193
- }
194
-
195
- /**
196
- * Set the max-age of the cookie
197
- *
198
- * @param int $maxAge Max age of the cookie in seconds
199
- */
200
- public function setMaxAge($maxAge)
201
- {
202
- $this->data['Max-Age'] = $maxAge;
203
- }
204
-
205
- /**
206
- * The UNIX timestamp when the cookie Expires
207
- *
208
- * @return mixed
209
- */
210
- public function getExpires()
211
- {
212
- return $this->data['Expires'];
213
- }
214
-
215
- /**
216
- * Set the unix timestamp for which the cookie will expire
217
- *
218
- * @param int $timestamp Unix timestamp
219
- */
220
- public function setExpires($timestamp)
221
- {
222
- $this->data['Expires'] = is_numeric($timestamp)
223
- ? (int) $timestamp
224
- : strtotime($timestamp);
225
- }
226
-
227
- /**
228
- * Get whether or not this is a secure cookie
229
- *
230
- * @return null|bool
231
- */
232
- public function getSecure()
233
- {
234
- return $this->data['Secure'];
235
- }
236
-
237
- /**
238
- * Set whether or not the cookie is secure
239
- *
240
- * @param bool $secure Set to true or false if secure
241
- */
242
- public function setSecure($secure)
243
- {
244
- $this->data['Secure'] = $secure;
245
- }
246
-
247
- /**
248
- * Get whether or not this is a session cookie
249
- *
250
- * @return null|bool
251
- */
252
- public function getDiscard()
253
- {
254
- return $this->data['Discard'];
255
- }
256
-
257
- /**
258
- * Set whether or not this is a session cookie
259
- *
260
- * @param bool $discard Set to true or false if this is a session cookie
261
- */
262
- public function setDiscard($discard)
263
- {
264
- $this->data['Discard'] = $discard;
265
- }
266
-
267
- /**
268
- * Get whether or not this is an HTTP only cookie
269
- *
270
- * @return bool
271
- */
272
- public function getHttpOnly()
273
- {
274
- return $this->data['HttpOnly'];
275
- }
276
-
277
- /**
278
- * Set whether or not this is an HTTP only cookie
279
- *
280
- * @param bool $httpOnly Set to true or false if this is HTTP only
281
- */
282
- public function setHttpOnly($httpOnly)
283
- {
284
- $this->data['HttpOnly'] = $httpOnly;
285
- }
286
-
287
- /**
288
- * Check if the cookie matches a path value.
289
- *
290
- * A request-path path-matches a given cookie-path if at least one of
291
- * the following conditions holds:
292
- *
293
- * - The cookie-path and the request-path are identical.
294
- * - The cookie-path is a prefix of the request-path, and the last
295
- * character of the cookie-path is %x2F ("/").
296
- * - The cookie-path is a prefix of the request-path, and the first
297
- * character of the request-path that is not included in the cookie-
298
- * path is a %x2F ("/") character.
299
- *
300
- * @param string $requestPath Path to check against
301
- *
302
- * @return bool
303
- */
304
- public function matchesPath($requestPath)
305
- {
306
- $cookiePath = $this->getPath();
307
-
308
- // Match on exact matches or when path is the default empty "/"
309
- if ($cookiePath === '/' || $cookiePath == $requestPath) {
310
- return true;
311
- }
312
-
313
- // Ensure that the cookie-path is a prefix of the request path.
314
- if (0 !== strpos($requestPath, $cookiePath)) {
315
- return false;
316
- }
317
-
318
- // Match if the last character of the cookie-path is "/"
319
- if (substr($cookiePath, -1, 1) === '/') {
320
- return true;
321
- }
322
-
323
- // Match if the first character not included in cookie path is "/"
324
- return substr($requestPath, strlen($cookiePath), 1) === '/';
325
- }
326
-
327
- /**
328
- * Check if the cookie matches a domain value
329
- *
330
- * @param string $domain Domain to check against
331
- *
332
- * @return bool
333
- */
334
- public function matchesDomain($domain)
335
- {
336
- // Remove the leading '.' as per spec in RFC 6265.
337
- // http://tools.ietf.org/html/rfc6265#section-5.2.3
338
- $cookieDomain = ltrim($this->getDomain(), '.');
339
-
340
- // Domain not set or exact match.
341
- if (!$cookieDomain || !strcasecmp($domain, $cookieDomain)) {
342
- return true;
343
- }
344
-
345
- // Matching the subdomain according to RFC 6265.
346
- // http://tools.ietf.org/html/rfc6265#section-5.1.3
347
- if (filter_var($domain, FILTER_VALIDATE_IP)) {
348
- return false;
349
- }
350
-
351
- return (bool) preg_match('/\.' . preg_quote($cookieDomain, '/') . '$/', $domain);
352
- }
353
-
354
- /**
355
- * Check if the cookie is expired
356
- *
357
- * @return bool
358
- */
359
- public function isExpired()
360
- {
361
- return $this->getExpires() !== null && time() > $this->getExpires();
362
- }
363
-
364
- /**
365
- * Check if the cookie is valid according to RFC 6265
366
- *
367
- * @return bool|string Returns true if valid or an error message if invalid
368
- */
369
- public function validate()
370
- {
371
- // Names must not be empty, but can be 0
372
- $name = $this->getName();
373
- if (empty($name) && !is_numeric($name)) {
374
- return 'The cookie name must not be empty';
375
- }
376
-
377
- // Check if any of the invalid characters are present in the cookie name
378
- if (preg_match(
379
- '/[\x00-\x20\x22\x28-\x29\x2c\x2f\x3a-\x40\x5c\x7b\x7d\x7f]/',
380
- $name
381
- )) {
382
- return 'Cookie name must not contain invalid characters: ASCII '
383
- . 'Control characters (0-31;127), space, tab and the '
384
- . 'following characters: ()<>@,;:\"/?={}';
385
- }
386
-
387
- // Value must not be empty, but can be 0
388
- $value = $this->getValue();
389
- if (empty($value) && !is_numeric($value)) {
390
- return 'The cookie value must not be empty';
391
- }
392
-
393
- // Domains must not be empty, but can be 0
394
- // A "0" is not a valid internet domain, but may be used as server name
395
- // in a private network.
396
- $domain = $this->getDomain();
397
- if (empty($domain) && !is_numeric($domain)) {
398
- return 'The cookie domain must not be empty';
399
- }
400
-
401
- return true;
402
- }
403
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/guzzle/src/Exception/BadResponseException.php DELETED
@@ -1,27 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Exception;
3
-
4
- use Psr\Http\Message\RequestInterface;
5
- use Psr\Http\Message\ResponseInterface;
6
-
7
- /**
8
- * Exception when an HTTP error occurs (4xx or 5xx error)
9
- */
10
- class BadResponseException extends RequestException
11
- {
12
- public function __construct(
13
- $message,
14
- RequestInterface $request,
15
- ResponseInterface $response = null,
16
- \Exception $previous = null,
17
- array $handlerContext = []
18
- ) {
19
- if (null === $response) {
20
- @trigger_error(
21
- 'Instantiating the ' . __CLASS__ . ' class without a Response is deprecated since version 6.3 and will be removed in 7.0.',
22
- E_USER_DEPRECATED
23
- );
24
- }
25
- parent::__construct($message, $request, $response, $previous, $handlerContext);
26
- }
27
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/guzzle/src/Exception/ClientException.php DELETED
@@ -1,7 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Exception;
3
-
4
- /**
5
- * Exception when a client error is encountered (4xx codes)
6
- */
7
- class ClientException extends BadResponseException {}
 
 
 
 
 
 
 
vendor/guzzlehttp/guzzle/src/Exception/ConnectException.php DELETED
@@ -1,37 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Exception;
3
-
4
- use Psr\Http\Message\RequestInterface;
5
-
6
- /**
7
- * Exception thrown when a connection cannot be established.
8
- *
9
- * Note that no response is present for a ConnectException
10
- */
11
- class ConnectException extends RequestException
12
- {
13
- public function __construct(
14
- $message,
15
- RequestInterface $request,
16
- \Exception $previous = null,
17
- array $handlerContext = []
18
- ) {
19
- parent::__construct($message, $request, null, $previous, $handlerContext);
20
- }
21
-
22
- /**
23
- * @return null
24
- */
25
- public function getResponse()
26
- {
27
- return null;
28
- }
29
-
30
- /**
31
- * @return bool
32
- */
33
- public function hasResponse()
34
- {
35
- return false;
36
- }
37
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/guzzle/src/Exception/GuzzleException.php DELETED
@@ -1,13 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Exception;
3
-
4
- /**
5
- * @method string getMessage()
6
- * @method \Throwable|null getPrevious()
7
- * @method mixed getCode()
8
- * @method string getFile()
9
- * @method int getLine()
10
- * @method array getTrace()
11
- * @method string getTraceAsString()
12
- */
13
- interface GuzzleException {}
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/guzzle/src/Exception/RequestException.php DELETED
@@ -1,217 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Exception;
3
-
4
- use Psr\Http\Message\RequestInterface;
5
- use Psr\Http\Message\ResponseInterface;
6
- use GuzzleHttp\Promise\PromiseInterface;
7
- use Psr\Http\Message\UriInterface;
8
-
9
- /**
10
- * HTTP Request exception
11
- */
12
- class RequestException extends TransferException
13
- {
14
- /** @var RequestInterface */
15
- private $request;
16
-
17
- /** @var ResponseInterface */
18
- private $response;
19
-
20
- /** @var array */
21
- private $handlerContext;
22
-
23
- public function __construct(
24
- $message,
25
- RequestInterface $request,
26
- ResponseInterface $response = null,
27
- \Exception $previous = null,
28
- array $handlerContext = []
29
- ) {
30
- // Set the code of the exception if the response is set and not future.
31
- $code = $response && !($response instanceof PromiseInterface)
32
- ? $response->getStatusCode()
33
- : 0;
34
- parent::__construct($message, $code, $previous);
35
- $this->request = $request;
36
- $this->response = $response;
37
- $this->handlerContext = $handlerContext;
38
- }
39
-
40
- /**
41
- * Wrap non-RequestExceptions with a RequestException
42
- *
43
- * @param RequestInterface $request
44
- * @param \Exception $e
45
- *
46
- * @return RequestException
47
- */
48
- public static function wrapException(RequestInterface $request, \Exception $e)
49
- {
50
- return $e instanceof RequestException
51
- ? $e
52
- : new RequestException($e->getMessage(), $request, null, $e);
53
- }
54
-
55
- /**
56
- * Factory method to create a new exception with a normalized error message
57
- *
58
- * @param RequestInterface $request Request
59
- * @param ResponseInterface $response Response received
60
- * @param \Exception $previous Previous exception
61
- * @param array $ctx Optional handler context.
62
- *
63
- * @return self
64
- */
65
- public static function create(
66
- RequestInterface $request,
67
- ResponseInterface $response = null,
68
- \Exception $previous = null,
69
- array $ctx = []
70
- ) {
71
- if (!$response) {
72
- return new self(
73
- 'Error completing request',
74
- $request,
75
- null,
76
- $previous,
77
- $ctx
78
- );
79
- }
80
-
81
- $level = (int) floor($response->getStatusCode() / 100);
82
- if ($level === 4) {
83
- $label = 'Client error';
84
- $className = ClientException::class;
85
- } elseif ($level === 5) {
86
- $label = 'Server error';
87
- $className = ServerException::class;
88
- } else {
89
- $label = 'Unsuccessful request';
90
- $className = __CLASS__;
91
- }
92
-
93
- $uri = $request->getUri();
94
- $uri = static::obfuscateUri($uri);
95
-
96
- // Client Error: `GET /` resulted in a `404 Not Found` response:
97
- // <html> ... (truncated)
98
- $message = sprintf(
99
- '%s: `%s %s` resulted in a `%s %s` response',
100
- $label,
101
- $request->getMethod(),
102
- $uri,
103
- $response->getStatusCode(),
104
- $response->getReasonPhrase()
105
- );
106
-
107
- $summary = static::getResponseBodySummary($response);
108
-
109
- if ($summary !== null) {
110
- $message .= ":\n{$summary}\n";
111
- }
112
-
113
- return new $className($message, $request, $response, $previous, $ctx);
114
- }
115
-
116
- /**
117
- * Get a short summary of the response
118
- *
119
- * Will return `null` if the response is not printable.
120
- *
121
- * @param ResponseInterface $response
122
- *
123
- * @return string|null
124
- */
125
- public static function getResponseBodySummary(ResponseInterface $response)
126
- {
127
- $body = $response->getBody();
128
-
129
- if (!$body->isSeekable()) {
130
- return null;
131
- }
132
-
133
- $size = $body->getSize();
134
-
135
- if ($size === 0) {
136
- return null;
137
- }
138
-
139
- $summary = $body->read(120);
140
- $body->rewind();
141
-
142
- if ($size > 120) {
143
- $summary .= ' (truncated...)';
144
- }
145
-
146
- // Matches any printable character, including unicode characters:
147
- // letters, marks, numbers, punctuation, spacing, and separators.
148
- if (preg_match('/[^\pL\pM\pN\pP\pS\pZ\n\r\t]/', $summary)) {
149
- return null;
150
- }
151
-
152
- return $summary;
153
- }
154
-
155
- /**
156
- * Obfuscates URI if there is an username and a password present
157
- *
158
- * @param UriInterface $uri
159
- *
160
- * @return UriInterface
161
- */
162
- private static function obfuscateUri($uri)
163
- {
164
- $userInfo = $uri->getUserInfo();
165
-
166
- if (false !== ($pos = strpos($userInfo, ':'))) {
167
- return $uri->withUserInfo(substr($userInfo, 0, $pos), '***');
168
- }
169
-
170
- return $uri;
171
- }
172
-
173
- /**
174
- * Get the request that caused the exception
175
- *
176
- * @return RequestInterface
177
- */
178
- public function getRequest()
179
- {
180
- return $this->request;
181
- }
182
-
183
- /**
184
- * Get the associated response
185
- *
186
- * @return ResponseInterface|null
187
- */
188
- public function getResponse()
189
- {
190
- return $this->response;
191
- }
192
-
193
- /**
194
- * Check if a response was received
195
- *
196
- * @return bool
197
- */
198
- public function hasResponse()
199
- {
200
- return $this->response !== null;
201
- }
202
-
203
- /**
204
- * Get contextual information about the error from the underlying handler.
205
- *
206
- * The contents of this array will vary depending on which handler you are
207
- * using. It may also be just an empty array. Relying on this data will
208
- * couple you to a specific handler, but can give more debug information
209
- * when needed.
210
- *
211
- * @return array
212
- */
213
- public function getHandlerContext()
214
- {
215
- return $this->handlerContext;
216
- }
217
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/guzzle/src/Exception/SeekException.php DELETED
@@ -1,27 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Exception;
3
-
4
- use Psr\Http\Message\StreamInterface;
5
-
6
- /**
7
- * Exception thrown when a seek fails on a stream.
8
- */
9
- class SeekException extends \RuntimeException implements GuzzleException
10
- {
11
- private $stream;
12
-
13
- public function __construct(StreamInterface $stream, $pos = 0, $msg = '')
14
- {
15
- $this->stream = $stream;
16
- $msg = $msg ?: 'Could not seek the stream to position ' . $pos;
17
- parent::__construct($msg);
18
- }
19
-
20
- /**
21
- * @return StreamInterface
22
- */
23
- public function getStream()
24
- {
25
- return $this->stream;
26
- }
27
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/guzzle/src/Exception/ServerException.php DELETED
@@ -1,7 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Exception;
3
-
4
- /**
5
- * Exception when a server error is encountered (5xx codes)
6
- */
7
- class ServerException extends BadResponseException {}
 
 
 
 
 
 
 
vendor/guzzlehttp/guzzle/src/Exception/TooManyRedirectsException.php DELETED
@@ -1,4 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Exception;
3
-
4
- class TooManyRedirectsException extends RequestException {}
 
 
 
 
vendor/guzzlehttp/guzzle/src/Exception/TransferException.php DELETED
@@ -1,4 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Exception;
3
-
4
- class TransferException extends \RuntimeException implements GuzzleException {}
 
 
 
 
vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php DELETED
@@ -1,565 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Handler;
3
-
4
- use GuzzleHttp\Exception\RequestException;
5
- use GuzzleHttp\Exception\ConnectException;
6
- use GuzzleHttp\Promise\FulfilledPromise;
7
- use GuzzleHttp\Psr7;
8
- use GuzzleHttp\Psr7\LazyOpenStream;
9
- use GuzzleHttp\TransferStats;
10
- use Psr\Http\Message\RequestInterface;
11
-
12
- /**
13
- * Creates curl resources from a request
14
- */
15
- class CurlFactory implements CurlFactoryInterface
16
- {
17
- /** @var array */
18
- private $handles = [];
19
-
20
- /** @var int Total number of idle handles to keep in cache */
21
- private $maxHandles;
22
-
23
- /**
24
- * @param int $maxHandles Maximum number of idle handles.
25
- */
26
- public function __construct($maxHandles)
27
- {
28
- $this->maxHandles = $maxHandles;
29
- }
30
-
31
- public function create(RequestInterface $request, array $options)
32
- {
33
- if (isset($options['curl']['body_as_string'])) {
34
- $options['_body_as_string'] = $options['curl']['body_as_string'];
35
- unset($options['curl']['body_as_string']);
36
- }
37
-
38
- $easy = new EasyHandle;
39
- $easy->request = $request;
40
- $easy->options = $options;
41
- $conf = $this->getDefaultConf($easy);
42
- $this->applyMethod($easy, $conf);
43
- $this->applyHandlerOptions($easy, $conf);
44
- $this->applyHeaders($easy, $conf);
45
- unset($conf['_headers']);
46
-
47
- // Add handler options from the request configuration options
48
- if (isset($options['curl'])) {
49
- $conf = array_replace($conf, $options['curl']);
50
- }
51
-
52
- $conf[CURLOPT_HEADERFUNCTION] = $this->createHeaderFn($easy);
53
- $easy->handle = $this->handles
54
- ? array_pop($this->handles)
55
- : curl_init();
56
- curl_setopt_array($easy->handle, $conf);
57
-
58
- return $easy;
59
- }
60
-
61
- public function release(EasyHandle $easy)
62
- {
63
- $resource = $easy->handle;
64
- unset($easy->handle);
65
-
66
- if (count($this->handles) >= $this->maxHandles) {
67
- curl_close($resource);
68
- } else {
69
- // Remove all callback functions as they can hold onto references
70
- // and are not cleaned up by curl_reset. Using curl_setopt_array
71
- // does not work for some reason, so removing each one
72
- // individually.
73
- curl_setopt($resource, CURLOPT_HEADERFUNCTION, null);
74
- curl_setopt($resource, CURLOPT_READFUNCTION, null);
75
- curl_setopt($resource, CURLOPT_WRITEFUNCTION, null);
76
- curl_setopt($resource, CURLOPT_PROGRESSFUNCTION, null);
77
- curl_reset($resource);
78
- $this->handles[] = $resource;
79
- }
80
- }
81
-
82
- /**
83
- * Completes a cURL transaction, either returning a response promise or a
84
- * rejected promise.
85
- *
86
- * @param callable $handler
87
- * @param EasyHandle $easy
88
- * @param CurlFactoryInterface $factory Dictates how the handle is released
89
- *
90
- * @return \GuzzleHttp\Promise\PromiseInterface
91
- */
92
- public static function finish(
93
- callable $handler,
94
- EasyHandle $easy,
95
- CurlFactoryInterface $factory
96
- ) {
97
- if (isset($easy->options['on_stats'])) {
98
- self::invokeStats($easy);
99
- }
100
-
101
- if (!$easy->response || $easy->errno) {
102
- return self::finishError($handler, $easy, $factory);
103
- }
104
-
105
- // Return the response if it is present and there is no error.
106
- $factory->release($easy);
107
-
108
- // Rewind the body of the response if possible.
109
- $body = $easy->response->getBody();
110
- if ($body->isSeekable()) {
111
- $body->rewind();
112
- }
113
-
114
- return new FulfilledPromise($easy->response);
115
- }
116
-
117
- private static function invokeStats(EasyHandle $easy)
118
- {
119
- $curlStats = curl_getinfo($easy->handle);
120
- $stats = new TransferStats(
121
- $easy->request,
122
- $easy->response,
123
- $curlStats['total_time'],
124
- $easy->errno,
125
- $curlStats
126
- );
127
- call_user_func($easy->options['on_stats'], $stats);
128
- }
129
-
130
- private static function finishError(
131
- callable $handler,
132
- EasyHandle $easy,
133
- CurlFactoryInterface $factory
134
- ) {
135
- // Get error information and release the handle to the factory.
136
- $ctx = [
137
- 'errno' => $easy->errno,
138
- 'error' => curl_error($easy->handle),
139
- ] + curl_getinfo($easy->handle);
140
- $factory->release($easy);
141
-
142
- // Retry when nothing is present or when curl failed to rewind.
143
- if (empty($easy->options['_err_message'])
144
- && (!$easy->errno || $easy->errno == 65)
145
- ) {
146
- return self::retryFailedRewind($handler, $easy, $ctx);
147
- }
148
-
149
- return self::createRejection($easy, $ctx);
150
- }
151
-
152
- private static function createRejection(EasyHandle $easy, array $ctx)
153
- {
154
- static $connectionErrors = [
155
- CURLE_OPERATION_TIMEOUTED => true,
156
- CURLE_COULDNT_RESOLVE_HOST => true,
157
- CURLE_COULDNT_CONNECT => true,
158
- CURLE_SSL_CONNECT_ERROR => true,
159
- CURLE_GOT_NOTHING => true,
160
- ];
161
-
162
- // If an exception was encountered during the onHeaders event, then
163
- // return a rejected promise that wraps that exception.
164
- if ($easy->onHeadersException) {
165
- return \GuzzleHttp\Promise\rejection_for(
166
- new RequestException(
167
- 'An error was encountered during the on_headers event',
168
- $easy->request,
169
- $easy->response,
170
- $easy->onHeadersException,
171
- $ctx
172
- )
173
- );
174
- }
175
-
176
- $message = sprintf(
177
- 'cURL error %s: %s (%s)',
178
- $ctx['errno'],
179
- $ctx['error'],
180
- 'see http://curl.haxx.se/libcurl/c/libcurl-errors.html'
181
- );
182
-
183
- // Create a connection exception if it was a specific error code.
184
- $error = isset($connectionErrors[$easy->errno])
185
- ? new ConnectException($message, $easy->request, null, $ctx)
186
- : new RequestException($message, $easy->request, $easy->response, null, $ctx);
187
-
188
- return \GuzzleHttp\Promise\rejection_for($error);
189
- }
190
-
191
- private function getDefaultConf(EasyHandle $easy)
192
- {
193
- $conf = [
194
- '_headers' => $easy->request->getHeaders(),
195
- CURLOPT_CUSTOMREQUEST => $easy->request->getMethod(),
196
- CURLOPT_URL => (string) $easy->request->getUri()->withFragment(''),
197
- CURLOPT_RETURNTRANSFER => false,
198
- CURLOPT_HEADER => false,
199
- CURLOPT_CONNECTTIMEOUT => 150,
200
- ];
201
-
202
- if (defined('CURLOPT_PROTOCOLS')) {
203
- $conf[CURLOPT_PROTOCOLS] = CURLPROTO_HTTP | CURLPROTO_HTTPS;
204
- }
205
-
206
- $version = $easy->request->getProtocolVersion();
207
- if ($version == 1.1) {
208
- $conf[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_1_1;
209
- } elseif ($version == 2.0) {
210
- $conf[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_2_0;
211
- } else {
212
- $conf[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_1_0;
213
- }
214
-
215
- return $conf;
216
- }
217
-
218
- private function applyMethod(EasyHandle $easy, array &$conf)
219
- {
220
- $body = $easy->request->getBody();
221
- $size = $body->getSize();
222
-
223
- if ($size === null || $size > 0) {
224
- $this->applyBody($easy->request, $easy->options, $conf);
225
- return;
226
- }
227
-
228
- $method = $easy->request->getMethod();
229
- if ($method === 'PUT' || $method === 'POST') {
230
- // See http://tools.ietf.org/html/rfc7230#section-3.3.2
231
- if (!$easy->request->hasHeader('Content-Length')) {
232
- $conf[CURLOPT_HTTPHEADER][] = 'Content-Length: 0';
233
- }
234
- } elseif ($method === 'HEAD') {
235
- $conf[CURLOPT_NOBODY] = true;
236
- unset(
237
- $conf[CURLOPT_WRITEFUNCTION],
238
- $conf[CURLOPT_READFUNCTION],
239
- $conf[CURLOPT_FILE],
240
- $conf[CURLOPT_INFILE]
241
- );
242
- }
243
- }
244
-
245
- private function applyBody(RequestInterface $request, array $options, array &$conf)
246
- {
247
- $size = $request->hasHeader('Content-Length')
248
- ? (int) $request->getHeaderLine('Content-Length')
249
- : null;
250
-
251
- // Send the body as a string if the size is less than 1MB OR if the
252
- // [curl][body_as_string] request value is set.
253
- if (($size !== null && $size < 1000000) ||
254
- !empty($options['_body_as_string'])
255
- ) {
256
- $conf[CURLOPT_POSTFIELDS] = (string) $request->getBody();
257
- // Don't duplicate the Content-Length header
258
- $this->removeHeader('Content-Length', $conf);
259
- $this->removeHeader('Transfer-Encoding', $conf);
260
- } else {
261
- $conf[CURLOPT_UPLOAD] = true;
262
- if ($size !== null) {
263
- $conf[CURLOPT_INFILESIZE] = $size;
264
- $this->removeHeader('Content-Length', $conf);
265
- }
266
- $body = $request->getBody();
267
- if ($body->isSeekable()) {
268
- $body->rewind();
269
- }
270
- $conf[CURLOPT_READFUNCTION] = function ($ch, $fd, $length) use ($body) {
271
- return $body->read($length);
272
- };
273
- }
274
-
275
- // If the Expect header is not present, prevent curl from adding it
276
- if (!$request->hasHeader('Expect')) {
277
- $conf[CURLOPT_HTTPHEADER][] = 'Expect:';
278
- }
279
-
280
- // cURL sometimes adds a content-type by default. Prevent this.
281
- if (!$request->hasHeader('Content-Type')) {
282
- $conf[CURLOPT_HTTPHEADER][] = 'Content-Type:';
283
- }
284
- }
285
-
286
- private function applyHeaders(EasyHandle $easy, array &$conf)
287
- {
288
- foreach ($conf['_headers'] as $name => $values) {
289
- foreach ($values as $value) {
290
- $value = (string) $value;
291
- if ($value === '') {
292
- // cURL requires a special format for empty headers.
293
- // See https://github.com/guzzle/guzzle/issues/1882 for more details.
294
- $conf[CURLOPT_HTTPHEADER][] = "$name;";
295
- } else {
296
- $conf[CURLOPT_HTTPHEADER][] = "$name: $value";
297
- }
298
- }
299
- }
300
-
301
- // Remove the Accept header if one was not set
302
- if (!$easy->request->hasHeader('Accept')) {
303
- $conf[CURLOPT_HTTPHEADER][] = 'Accept:';
304
- }
305
- }
306
-
307
- /**
308
- * Remove a header from the options array.
309
- *
310
- * @param string $name Case-insensitive header to remove
311
- * @param array $options Array of options to modify
312
- */
313
- private function removeHeader($name, array &$options)
314
- {
315
- foreach (array_keys($options['_headers']) as $key) {
316
- if (!strcasecmp($key, $name)) {
317
- unset($options['_headers'][$key]);
318
- return;
319
- }
320
- }
321
- }
322
-
323
- private function applyHandlerOptions(EasyHandle $easy, array &$conf)
324
- {
325
- $options = $easy->options;
326
- if (isset($options['verify'])) {
327
- if ($options['verify'] === false) {
328
- unset($conf[CURLOPT_CAINFO]);
329
- $conf[CURLOPT_SSL_VERIFYHOST] = 0;
330
- $conf[CURLOPT_SSL_VERIFYPEER] = false;
331
- } else {
332
- $conf[CURLOPT_SSL_VERIFYHOST] = 2;
333
- $conf[CURLOPT_SSL_VERIFYPEER] = true;
334
- if (is_string($options['verify'])) {
335
- // Throw an error if the file/folder/link path is not valid or doesn't exist.
336
- if (!file_exists($options['verify'])) {
337
- throw new \InvalidArgumentException(
338
- "SSL CA bundle not found: {$options['verify']}"
339
- );
340
- }
341
- // If it's a directory or a link to a directory use CURLOPT_CAPATH.
342
- // If not, it's probably a file, or a link to a file, so use CURLOPT_CAINFO.
343
- if (is_dir($options['verify']) ||
344
- (is_link($options['verify']) && is_dir(readlink($options['verify'])))) {
345
- $conf[CURLOPT_CAPATH] = $options['verify'];
346
- } else {
347
- $conf[CURLOPT_CAINFO] = $options['verify'];
348
- }
349
- }
350
- }
351
- }
352
-
353
- if (!empty($options['decode_content'])) {
354
- $accept = $easy->request->getHeaderLine('Accept-Encoding');
355
- if ($accept) {
356
- $conf[CURLOPT_ENCODING] = $accept;
357
- } else {
358
- $conf[CURLOPT_ENCODING] = '';
359
- // Don't let curl send the header over the wire
360
- $conf[CURLOPT_HTTPHEADER][] = 'Accept-Encoding:';
361
- }
362
- }
363
-
364
- if (isset($options['sink'])) {
365
- $sink = $options['sink'];
366
- if (!is_string($sink)) {
367
- $sink = \GuzzleHttp\Psr7\stream_for($sink);
368
- } elseif (!is_dir(dirname($sink))) {
369
- // Ensure that the directory exists before failing in curl.
370
- throw new \RuntimeException(sprintf(
371
- 'Directory %s does not exist for sink value of %s',
372
- dirname($sink),
373
- $sink
374
- ));
375
- } else {
376
- $sink = new LazyOpenStream($sink, 'w+');
377
- }
378
- $easy->sink = $sink;
379
- $conf[CURLOPT_WRITEFUNCTION] = function ($ch, $write) use ($sink) {
380
- return $sink->write($write);
381
- };
382
- } else {
383
- // Use a default temp stream if no sink was set.
384
- $conf[CURLOPT_FILE] = fopen('php://temp', 'w+');
385
- $easy->sink = Psr7\stream_for($conf[CURLOPT_FILE]);
386
- }
387
- $timeoutRequiresNoSignal = false;
388
- if (isset($options['timeout'])) {
389
- $timeoutRequiresNoSignal |= $options['timeout'] < 1;
390
- $conf[CURLOPT_TIMEOUT_MS] = $options['timeout'] * 1000;
391
- }
392
-
393
- // CURL default value is CURL_IPRESOLVE_WHATEVER
394
- if (isset($options['force_ip_resolve'])) {
395
- if ('v4' === $options['force_ip_resolve']) {
396
- $conf[CURLOPT_IPRESOLVE] = CURL_IPRESOLVE_V4;
397
- } elseif ('v6' === $options['force_ip_resolve']) {
398
- $conf[CURLOPT_IPRESOLVE] = CURL_IPRESOLVE_V6;
399
- }
400
- }
401
-
402
- if (isset($options['connect_timeout'])) {
403
- $timeoutRequiresNoSignal |= $options['connect_timeout'] < 1;
404
- $conf[CURLOPT_CONNECTTIMEOUT_MS] = $options['connect_timeout'] * 1000;
405
- }
406
-
407
- if ($timeoutRequiresNoSignal && strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') {
408
- $conf[CURLOPT_NOSIGNAL] = true;
409
- }
410
-
411
- if (isset($options['proxy'])) {
412
- if (!is_array($options['proxy'])) {
413
- $conf[CURLOPT_PROXY] = $options['proxy'];
414
- } else {
415
- $scheme = $easy->request->getUri()->getScheme();
416
- if (isset($options['proxy'][$scheme])) {
417
- $host = $easy->request->getUri()->getHost();
418
- if (!isset($options['proxy']['no']) ||
419
- !\GuzzleHttp\is_host_in_noproxy($host, $options['proxy']['no'])
420
- ) {
421
- $conf[CURLOPT_PROXY] = $options['proxy'][$scheme];
422
- }
423
- }
424
- }
425
- }
426
-
427
- if (isset($options['cert'])) {
428
- $cert = $options['cert'];
429
- if (is_array($cert)) {
430
- $conf[CURLOPT_SSLCERTPASSWD] = $cert[1];
431
- $cert = $cert[0];
432
- }
433
- if (!file_exists($cert)) {
434
- throw new \InvalidArgumentException(
435
- "SSL certificate not found: {$cert}"
436
- );
437
- }
438
- $conf[CURLOPT_SSLCERT] = $cert;
439
- }
440
-
441
- if (isset($options['ssl_key'])) {
442
- $sslKey = $options['ssl_key'];
443
- if (is_array($sslKey)) {
444
- $conf[CURLOPT_SSLKEYPASSWD] = $sslKey[1];
445
- $sslKey = $sslKey[0];
446
- }
447
- if (!file_exists($sslKey)) {
448
- throw new \InvalidArgumentException(
449
- "SSL private key not found: {$sslKey}"
450
- );
451
- }
452
- $conf[CURLOPT_SSLKEY] = $sslKey;
453
- }
454
-
455
- if (isset($options['progress'])) {
456
- $progress = $options['progress'];
457
- if (!is_callable($progress)) {
458
- throw new \InvalidArgumentException(
459
- 'progress client option must be callable'
460
- );
461
- }
462
- $conf[CURLOPT_NOPROGRESS] = false;
463
- $conf[CURLOPT_PROGRESSFUNCTION] = function () use ($progress) {
464
- $args = func_get_args();
465
- // PHP 5.5 pushed the handle onto the start of the args
466
- if (is_resource($args[0])) {
467
- array_shift($args);
468
- }
469
- call_user_func_array($progress, $args);
470
- };
471
- }
472
-
473
- if (!empty($options['debug'])) {
474
- $conf[CURLOPT_STDERR] = \GuzzleHttp\debug_resource($options['debug']);
475
- $conf[CURLOPT_VERBOSE] = true;
476
- }
477
- }
478
-
479
- /**
480
- * This function ensures that a response was set on a transaction. If one
481
- * was not set, then the request is retried if possible. This error
482
- * typically means you are sending a payload, curl encountered a
483
- * "Connection died, retrying a fresh connect" error, tried to rewind the
484
- * stream, and then encountered a "necessary data rewind wasn't possible"
485
- * error, causing the request to be sent through curl_multi_info_read()
486
- * without an error status.
487
- */
488
- private static function retryFailedRewind(
489
- callable $handler,
490
- EasyHandle $easy,
491
- array $ctx
492
- ) {
493
- try {
494
- // Only rewind if the body has been read from.
495
- $body = $easy->request->getBody();
496
- if ($body->tell() > 0) {
497
- $body->rewind();
498
- }
499
- } catch (\RuntimeException $e) {
500
- $ctx['error'] = 'The connection unexpectedly failed without '
501
- . 'providing an error. The request would have been retried, '
502
- . 'but attempting to rewind the request body failed. '
503
- . 'Exception: ' . $e;
504
- return self::createRejection($easy, $ctx);
505
- }
506
-
507
- // Retry no more than 3 times before giving up.
508
- if (!isset($easy->options['_curl_retries'])) {
509
- $easy->options['_curl_retries'] = 1;
510
- } elseif ($easy->options['_curl_retries'] == 2) {
511
- $ctx['error'] = 'The cURL request was retried 3 times '
512
- . 'and did not succeed. The most likely reason for the failure '
513
- . 'is that cURL was unable to rewind the body of the request '
514
- . 'and subsequent retries resulted in the same error. Turn on '
515
- . 'the debug option to see what went wrong. See '
516
- . 'https://bugs.php.net/bug.php?id=47204 for more information.';
517
- return self::createRejection($easy, $ctx);
518
- } else {
519
- $easy->options['_curl_retries']++;
520
- }
521
-
522
- return $handler($easy->request, $easy->options);
523
- }
524
-
525
- private function createHeaderFn(EasyHandle $easy)
526
- {
527
- if (isset($easy->options['on_headers'])) {
528
- $onHeaders = $easy->options['on_headers'];
529
-
530
- if (!is_callable($onHeaders)) {
531
- throw new \InvalidArgumentException('on_headers must be callable');
532
- }
533
- } else {
534
- $onHeaders = null;
535
- }
536
-
537
- return function ($ch, $h) use (
538
- $onHeaders,
539
- $easy,
540
- &$startingResponse
541
- ) {
542
- $value = trim($h);
543
- if ($value === '') {
544
- $startingResponse = true;
545
- $easy->createResponse();
546
- if ($onHeaders !== null) {
547
- try {
548
- $onHeaders($easy->response);
549
- } catch (\Exception $e) {
550
- // Associate the exception with the handle and trigger
551
- // a curl header write error by returning 0.
552
- $easy->onHeadersException = $e;
553
- return -1;
554
- }
555
- }
556
- } elseif ($startingResponse) {
557
- $startingResponse = false;
558
- $easy->headers = [$value];
559
- } else {
560
- $easy->headers[] = $value;
561
- }
562
- return strlen($h);
563
- };
564
- }
565
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/guzzle/src/Handler/CurlFactoryInterface.php DELETED
@@ -1,27 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Handler;
3
-
4
- use Psr\Http\Message\RequestInterface;
5
-
6
- interface CurlFactoryInterface
7
- {
8
- /**
9
- * Creates a cURL handle resource.
10
- *
11
- * @param RequestInterface $request Request
12
- * @param array $options Transfer options
13
- *
14
- * @return EasyHandle
15
- * @throws \RuntimeException when an option cannot be applied
16
- */
17
- public function create(RequestInterface $request, array $options);
18
-
19
- /**
20
- * Release an easy handle, allowing it to be reused or closed.
21
- *
22
- * This function must call unset on the easy handle's "handle" property.
23
- *
24
- * @param EasyHandle $easy
25
- */
26
- public function release(EasyHandle $easy);
27
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/guzzle/src/Handler/CurlHandler.php DELETED
@@ -1,45 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Handler;
3
-
4
- use GuzzleHttp\Psr7;
5
- use Psr\Http\Message\RequestInterface;
6
-
7
- /**
8
- * HTTP handler that uses cURL easy handles as a transport layer.
9
- *
10
- * When using the CurlHandler, custom curl options can be specified as an
11
- * associative array of curl option constants mapping to values in the
12
- * **curl** key of the "client" key of the request.
13
- */
14
- class CurlHandler
15
- {
16
- /** @var CurlFactoryInterface */
17
- private $factory;
18
-
19
- /**
20
- * Accepts an associative array of options:
21
- *
22
- * - factory: Optional curl factory used to create cURL handles.
23
- *
24
- * @param array $options Array of options to use with the handler
25
- */
26
- public function __construct(array $options = [])
27
- {
28
- $this->factory = isset($options['handle_factory'])
29
- ? $options['handle_factory']
30
- : new CurlFactory(3);
31
- }
32
-
33
- public function __invoke(RequestInterface $request, array $options)
34
- {
35
- if (isset($options['delay'])) {
36
- usleep($options['delay'] * 1000);
37
- }
38
-
39
- $easy = $this->factory->create($request, $options);
40
- curl_exec($easy->handle);
41
- $easy->errno = curl_errno($easy->handle);
42
-
43
- return CurlFactory::finish($this, $easy, $this->factory);
44
- }
45
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php DELETED
@@ -1,199 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Handler;
3
-
4
- use GuzzleHttp\Promise as P;
5
- use GuzzleHttp\Promise\Promise;
6
- use GuzzleHttp\Psr7;
7
- use Psr\Http\Message\RequestInterface;
8
-
9
- /**
10
- * Returns an asynchronous response using curl_multi_* functions.
11
- *
12
- * When using the CurlMultiHandler, custom curl options can be specified as an
13
- * associative array of curl option constants mapping to values in the
14
- * **curl** key of the provided request options.
15
- *
16
- * @property resource $_mh Internal use only. Lazy loaded multi-handle.
17
- */
18
- class CurlMultiHandler
19
- {
20
- /** @var CurlFactoryInterface */
21
- private $factory;
22
- private $selectTimeout;
23
- private $active;
24
- private $handles = [];
25
- private $delays = [];
26
-
27
- /**
28
- * This handler accepts the following options:
29
- *
30
- * - handle_factory: An optional factory used to create curl handles
31
- * - select_timeout: Optional timeout (in seconds) to block before timing
32
- * out while selecting curl handles. Defaults to 1 second.
33
- *
34
- * @param array $options
35
- */
36
- public function __construct(array $options = [])
37
- {
38
- $this->factory = isset($options['handle_factory'])
39
- ? $options['handle_factory'] : new CurlFactory(50);
40
- $this->selectTimeout = isset($options['select_timeout'])
41
- ? $options['select_timeout'] : 1;
42
- }
43
-
44
- public function __get($name)
45
- {
46
- if ($name === '_mh') {
47
- return $this->_mh = curl_multi_init();
48
- }
49
-
50
- throw new \BadMethodCallException();
51
- }
52
-
53
- public function __destruct()
54
- {
55
- if (isset($this->_mh)) {
56
- curl_multi_close($this->_mh);
57
- unset($this->_mh);
58
- }
59
- }
60
-
61
- public function __invoke(RequestInterface $request, array $options)
62
- {
63
- $easy = $this->factory->create($request, $options);
64
- $id = (int) $easy->handle;
65
-
66
- $promise = new Promise(
67
- [$this, 'execute'],
68
- function () use ($id) {
69
- return $this->cancel($id);
70
- }
71
- );
72
-
73
- $this->addRequest(['easy' => $easy, 'deferred' => $promise]);
74
-
75
- return $promise;
76
- }
77
-
78
- /**
79
- * Ticks the curl event loop.
80
- */
81
- public function tick()
82
- {
83
- // Add any delayed handles if needed.
84
- if ($this->delays) {
85
- $currentTime = microtime(true);
86
- foreach ($this->delays as $id => $delay) {
87
- if ($currentTime >= $delay) {
88
- unset($this->delays[$id]);
89
- curl_multi_add_handle(
90
- $this->_mh,
91
- $this->handles[$id]['easy']->handle
92
- );
93
- }
94
- }
95
- }
96
-
97
- // Step through the task queue which may add additional requests.
98
- P\queue()->run();
99
-
100
- if ($this->active &&
101
- curl_multi_select($this->_mh, $this->selectTimeout) === -1
102
- ) {
103
- // Perform a usleep if a select returns -1.
104
- // See: https://bugs.php.net/bug.php?id=61141
105
- usleep(250);
106
- }
107
-
108
- while (curl_multi_exec($this->_mh, $this->active) === CURLM_CALL_MULTI_PERFORM);
109
-
110
- $this->processMessages();
111
- }
112
-
113
- /**
114
- * Runs until all outstanding connections have completed.
115
- */
116
- public function execute()
117
- {
118
- $queue = P\queue();
119
-
120
- while ($this->handles || !$queue->isEmpty()) {
121
- // If there are no transfers, then sleep for the next delay
122
- if (!$this->active && $this->delays) {
123
- usleep($this->timeToNext());
124
- }
125
- $this->tick();
126
- }
127
- }
128
-
129
- private function addRequest(array $entry)
130
- {
131
- $easy = $entry['easy'];
132
- $id = (int) $easy->handle;
133
- $this->handles[$id] = $entry;
134
- if (empty($easy->options['delay'])) {
135
- curl_multi_add_handle($this->_mh, $easy->handle);
136
- } else {
137
- $this->delays[$id] = microtime(true) + ($easy->options['delay'] / 1000);
138
- }
139
- }
140
-
141
- /**
142
- * Cancels a handle from sending and removes references to it.
143
- *
144
- * @param int $id Handle ID to cancel and remove.
145
- *
146
- * @return bool True on success, false on failure.
147
- */
148
- private function cancel($id)
149
- {
150
- // Cannot cancel if it has been processed.
151
- if (!isset($this->handles[$id])) {
152
- return false;
153
- }
154
-
155
- $handle = $this->handles[$id]['easy']->handle;
156
- unset($this->delays[$id], $this->handles[$id]);
157
- curl_multi_remove_handle($this->_mh, $handle);
158
- curl_close($handle);
159
-
160
- return true;
161
- }
162
-
163
- private function processMessages()
164
- {
165
- while ($done = curl_multi_info_read($this->_mh)) {
166
- $id = (int) $done['handle'];
167
- curl_multi_remove_handle($this->_mh, $done['handle']);
168
-
169
- if (!isset($this->handles[$id])) {
170
- // Probably was cancelled.
171
- continue;
172
- }
173
-
174
- $entry = $this->handles[$id];
175
- unset($this->handles[$id], $this->delays[$id]);
176
- $entry['easy']->errno = $done['result'];
177
- $entry['deferred']->resolve(
178
- CurlFactory::finish(
179
- $this,
180
- $entry['easy'],
181
- $this->factory
182
- )
183
- );
184
- }
185
- }
186
-
187
- private function timeToNext()
188
- {
189
- $currentTime = microtime(true);
190
- $nextTime = PHP_INT_MAX;
191
- foreach ($this->delays as $time) {
192
- if ($time < $nextTime) {
193
- $nextTime = $time;
194
- }
195
- }
196
-
197
- return max(0, $nextTime - $currentTime) * 1000000;
198
- }
199
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/guzzle/src/Handler/EasyHandle.php DELETED
@@ -1,92 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Handler;
3
-
4
- use GuzzleHttp\Psr7\Response;
5
- use Psr\Http\Message\RequestInterface;
6
- use Psr\Http\Message\ResponseInterface;
7
- use Psr\Http\Message\StreamInterface;
8
-
9
- /**
10
- * Represents a cURL easy handle and the data it populates.
11
- *
12
- * @internal
13
- */
14
- final class EasyHandle
15
- {
16
- /** @var resource cURL resource */
17
- public $handle;
18
-
19
- /** @var StreamInterface Where data is being written */
20
- public $sink;
21
-
22
- /** @var array Received HTTP headers so far */
23
- public $headers = [];
24
-
25
- /** @var ResponseInterface Received response (if any) */
26
- public $response;
27
-
28
- /** @var RequestInterface Request being sent */
29
- public $request;
30
-
31
- /** @var array Request options */
32
- public $options = [];
33
-
34
- /** @var int cURL error number (if any) */
35
- public $errno = 0;
36
-
37
- /** @var \Exception Exception during on_headers (if any) */
38
- public $onHeadersException;
39
-
40
- /**
41
- * Attach a response to the easy handle based on the received headers.
42
- *
43
- * @throws \RuntimeException if no headers have been received.
44
- */
45
- public function createResponse()
46
- {
47
- if (empty($this->headers)) {
48
- throw new \RuntimeException('No headers have been received');
49
- }
50
-
51
- // HTTP-version SP status-code SP reason-phrase
52
- $startLine = explode(' ', array_shift($this->headers), 3);
53
- $headers = \GuzzleHttp\headers_from_lines($this->headers);
54
- $normalizedKeys = \GuzzleHttp\normalize_header_keys($headers);
55
-
56
- if (!empty($this->options['decode_content'])
57
- && isset($normalizedKeys['content-encoding'])
58
- ) {
59
- $headers['x-encoded-content-encoding']
60
- = $headers[$normalizedKeys['content-encoding']];
61
- unset($headers[$normalizedKeys['content-encoding']]);
62
- if (isset($normalizedKeys['content-length'])) {
63
- $headers['x-encoded-content-length']
64
- = $headers[$normalizedKeys['content-length']];
65
-
66
- $bodyLength = (int) $this->sink->getSize();
67
- if ($bodyLength) {
68
- $headers[$normalizedKeys['content-length']] = $bodyLength;
69
- } else {
70
- unset($headers[$normalizedKeys['content-length']]);
71
- }
72
- }
73
- }
74
-
75
- // Attach a response to the easy handle with the parsed headers.
76
- $this->response = new Response(
77
- $startLine[1],
78
- $headers,
79
- $this->sink,
80
- substr($startLine[0], 5),
81
- isset($startLine[2]) ? (string) $startLine[2] : null
82
- );
83
- }
84
-
85
- public function __get($name)
86
- {
87
- $msg = $name === 'handle'
88
- ? 'The EasyHandle has been released'
89
- : 'Invalid property: ' . $name;
90
- throw new \BadMethodCallException($msg);
91
- }
92
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/guzzle/src/Handler/MockHandler.php DELETED
@@ -1,189 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Handler;
3
-
4
- use GuzzleHttp\Exception\RequestException;
5
- use GuzzleHttp\HandlerStack;
6
- use GuzzleHttp\Promise\PromiseInterface;
7
- use GuzzleHttp\Promise\RejectedPromise;
8
- use GuzzleHttp\TransferStats;
9
- use Psr\Http\Message\RequestInterface;
10
- use Psr\Http\Message\ResponseInterface;
11
-
12
- /**
13
- * Handler that returns responses or throw exceptions from a queue.
14
- */
15
- class MockHandler implements \Countable
16
- {
17
- private $queue = [];
18
- private $lastRequest;
19
- private $lastOptions;
20
- private $onFulfilled;
21
- private $onRejected;
22
-
23
- /**
24
- * Creates a new MockHandler that uses the default handler stack list of
25
- * middlewares.
26
- *
27
- * @param array $queue Array of responses, callables, or exceptions.
28
- * @param callable $onFulfilled Callback to invoke when the return value is fulfilled.
29
- * @param callable $onRejected Callback to invoke when the return value is rejected.
30
- *
31
- * @return HandlerStack
32
- */
33
- public static function createWithMiddleware(
34
- array $queue = null,
35
- callable $onFulfilled = null,
36
- callable $onRejected = null
37
- ) {
38
- return HandlerStack::create(new self($queue, $onFulfilled, $onRejected));
39
- }
40
-
41
- /**
42
- * The passed in value must be an array of
43
- * {@see Psr7\Http\Message\ResponseInterface} objects, Exceptions,
44
- * callables, or Promises.
45
- *
46
- * @param array $queue
47
- * @param callable $onFulfilled Callback to invoke when the return value is fulfilled.
48
- * @param callable $onRejected Callback to invoke when the return value is rejected.
49
- */
50
- public function __construct(
51
- array $queue = null,
52
- callable $onFulfilled = null,
53
- callable $onRejected = null
54
- ) {
55
- $this->onFulfilled = $onFulfilled;
56
- $this->onRejected = $onRejected;
57
-
58
- if ($queue) {
59
- call_user_func_array([$this, 'append'], $queue);
60
- }
61
- }
62
-
63
- public function __invoke(RequestInterface $request, array $options)
64
- {
65
- if (!$this->queue) {
66
- throw new \OutOfBoundsException('Mock queue is empty');
67
- }
68
-
69
- if (isset($options['delay'])) {
70
- usleep($options['delay'] * 1000);
71
- }
72
-
73
- $this->lastRequest = $request;
74
- $this->lastOptions = $options;
75
- $response = array_shift($this->queue);
76
-
77
- if (isset($options['on_headers'])) {
78
- if (!is_callable($options['on_headers'])) {
79
- throw new \InvalidArgumentException('on_headers must be callable');
80
- }
81
- try {
82
- $options['on_headers']($response);
83
- } catch (\Exception $e) {
84
- $msg = 'An error was encountered during the on_headers event';
85
- $response = new RequestException($msg, $request, $response, $e);
86
- }
87
- }
88
-
89
- if (is_callable($response)) {
90
- $response = call_user_func($response, $request, $options);
91
- }
92
-
93
- $response = $response instanceof \Exception
94
- ? \GuzzleHttp\Promise\rejection_for($response)
95
- : \GuzzleHttp\Promise\promise_for($response);
96
-
97
- return $response->then(
98
- function ($value) use ($request, $options) {
99
- $this->invokeStats($request, $options, $value);
100
- if ($this->onFulfilled) {
101
- call_user_func($this->onFulfilled, $value);
102
- }
103
- if (isset($options['sink'])) {
104
- $contents = (string) $value->getBody();
105
- $sink = $options['sink'];
106
-
107
- if (is_resource($sink)) {
108
- fwrite($sink, $contents);
109
- } elseif (is_string($sink)) {
110
- file_put_contents($sink, $contents);
111
- } elseif ($sink instanceof \Psr\Http\Message\StreamInterface) {
112
- $sink->write($contents);
113
- }
114
- }
115
-
116
- return $value;
117
- },
118
- function ($reason) use ($request, $options) {
119
- $this->invokeStats($request, $options, null, $reason);
120
- if ($this->onRejected) {
121
- call_user_func($this->onRejected, $reason);
122
- }
123
- return \GuzzleHttp\Promise\rejection_for($reason);
124
- }
125
- );
126
- }
127
-
128
- /**
129
- * Adds one or more variadic requests, exceptions, callables, or promises
130
- * to the queue.
131
- */
132
- public function append()
133
- {
134
- foreach (func_get_args() as $value) {
135
- if ($value instanceof ResponseInterface
136
- || $value instanceof \Exception
137
- || $value instanceof PromiseInterface
138
- || is_callable($value)
139
- ) {
140
- $this->queue[] = $value;
141
- } else {
142
- throw new \InvalidArgumentException('Expected a response or '
143
- . 'exception. Found ' . \GuzzleHttp\describe_type($value));
144
- }
145
- }
146
- }
147
-
148
- /**
149
- * Get the last received request.
150
- *
151
- * @return RequestInterface
152
- */
153
- public function getLastRequest()
154
- {
155
- return $this->lastRequest;
156
- }
157
-
158
- /**
159
- * Get the last received request options.
160
- *
161
- * @return array
162
- */
163
- public function getLastOptions()
164
- {
165
- return $this->lastOptions;
166
- }
167
-
168
- /**
169
- * Returns the number of remaining items in the queue.
170
- *
171
- * @return int
172
- */
173
- public function count()
174
- {
175
- return count($this->queue);
176
- }
177
-
178
- private function invokeStats(
179
- RequestInterface $request,
180
- array $options,
181
- ResponseInterface $response = null,
182
- $reason = null
183
- ) {
184
- if (isset($options['on_stats'])) {
185
- $stats = new TransferStats($request, $response, 0, $reason);
186
- call_user_func($options['on_stats'], $stats);
187
- }
188
- }
189
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/guzzle/src/Handler/Proxy.php DELETED
@@ -1,55 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Handler;
3
-
4
- use GuzzleHttp\RequestOptions;
5
- use Psr\Http\Message\RequestInterface;
6
-
7
- /**
8
- * Provides basic proxies for handlers.
9
- */
10
- class Proxy
11
- {
12
- /**
13
- * Sends synchronous requests to a specific handler while sending all other
14
- * requests to another handler.
15
- *
16
- * @param callable $default Handler used for normal responses
17
- * @param callable $sync Handler used for synchronous responses.
18
- *
19
- * @return callable Returns the composed handler.
20
- */
21
- public static function wrapSync(
22
- callable $default,
23
- callable $sync
24
- ) {
25
- return function (RequestInterface $request, array $options) use ($default, $sync) {
26
- return empty($options[RequestOptions::SYNCHRONOUS])
27
- ? $default($request, $options)
28
- : $sync($request, $options);
29
- };
30
- }
31
-
32
- /**
33
- * Sends streaming requests to a streaming compatible handler while sending
34
- * all other requests to a default handler.
35
- *
36
- * This, for example, could be useful for taking advantage of the
37
- * performance benefits of curl while still supporting true streaming
38
- * through the StreamHandler.
39
- *
40
- * @param callable $default Handler used for non-streaming responses
41
- * @param callable $streaming Handler used for streaming responses
42
- *
43
- * @return callable Returns the composed handler.
44
- */
45
- public static function wrapStreaming(
46
- callable $default,
47
- callable $streaming
48
- ) {
49
- return function (RequestInterface $request, array $options) use ($default, $streaming) {
50
- return empty($options['stream'])
51
- ? $default($request, $options)
52
- : $streaming($request, $options);
53
- };
54
- }
55
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/guzzle/src/Handler/StreamHandler.php DELETED
@@ -1,532 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Handler;
3
-
4
- use GuzzleHttp\Exception\RequestException;
5
- use GuzzleHttp\Exception\ConnectException;
6
- use GuzzleHttp\Promise\FulfilledPromise;
7
- use GuzzleHttp\Promise\PromiseInterface;
8
- use GuzzleHttp\Psr7;
9
- use GuzzleHttp\TransferStats;
10
- use Psr\Http\Message\RequestInterface;
11
- use Psr\Http\Message\ResponseInterface;
12
- use Psr\Http\Message\StreamInterface;
13
-
14
- /**
15
- * HTTP handler that uses PHP's HTTP stream wrapper.
16
- */
17
- class StreamHandler
18
- {
19
- private $lastHeaders = [];
20
-
21
- /**
22
- * Sends an HTTP request.
23
- *
24
- * @param RequestInterface $request Request to send.
25
- * @param array $options Request transfer options.
26
- *
27
- * @return PromiseInterface
28
- */
29
- public function __invoke(RequestInterface $request, array $options)
30
- {
31
- // Sleep if there is a delay specified.
32
- if (isset($options['delay'])) {
33
- usleep($options['delay'] * 1000);
34
- }
35
-
36
- $startTime = isset($options['on_stats']) ? microtime(true) : null;
37
-
38
- try {
39
- // Does not support the expect header.
40
- $request = $request->withoutHeader('Expect');
41
-
42
- // Append a content-length header if body size is zero to match
43
- // cURL's behavior.
44
- if (0 === $request->getBody()->getSize()) {
45
- $request = $request->withHeader('Content-Length', 0);
46
- }
47
-
48
- return $this->createResponse(
49
- $request,
50
- $options,
51
- $this->createStream($request, $options),
52
- $startTime
53
- );
54
- } catch (\InvalidArgumentException $e) {
55
- throw $e;
56
- } catch (\Exception $e) {
57
- // Determine if the error was a networking error.
58
- $message = $e->getMessage();
59
- // This list can probably get more comprehensive.
60
- if (strpos($message, 'getaddrinfo') // DNS lookup failed
61
- || strpos($message, 'Connection refused')
62
- || strpos($message, "couldn't connect to host") // error on HHVM
63
- || strpos($message, "connection attempt failed")
64
- ) {
65
- $e = new ConnectException($e->getMessage(), $request, $e);
66
- }
67
- $e = RequestException::wrapException($request, $e);
68
- $this->invokeStats($options, $request, $startTime, null, $e);
69
-
70
- return \GuzzleHttp\Promise\rejection_for($e);
71
- }
72
- }
73
-
74
- private function invokeStats(
75
- array $options,
76
- RequestInterface $request,
77
- $startTime,
78
- ResponseInterface $response = null,
79
- $error = null
80
- ) {
81
- if (isset($options['on_stats'])) {
82
- $stats = new TransferStats(
83
- $request,
84
- $response,
85
- microtime(true) - $startTime,
86
- $error,
87
- []
88
- );
89
- call_user_func($options['on_stats'], $stats);
90
- }
91
- }
92
-
93
- private function createResponse(
94
- RequestInterface $request,
95
- array $options,
96
- $stream,
97
- $startTime
98
- ) {
99
- $hdrs = $this->lastHeaders;
100
- $this->lastHeaders = [];
101
- $parts = explode(' ', array_shift($hdrs), 3);
102
- $ver = explode('/', $parts[0])[1];
103
- $status = $parts[1];
104
- $reason = isset($parts[2]) ? $parts[2] : null;
105
- $headers = \GuzzleHttp\headers_from_lines($hdrs);
106
- list($stream, $headers) = $this->checkDecode($options, $headers, $stream);
107
- $stream = Psr7\stream_for($stream);
108
- $sink = $stream;
109
-
110
- if (strcasecmp('HEAD', $request->getMethod())) {
111
- $sink = $this->createSink($stream, $options);
112
- }
113
-
114
- $response = new Psr7\Response($status, $headers, $sink, $ver, $reason);
115
-
116
- if (isset($options['on_headers'])) {
117
- try {
118
- $options['on_headers']($response);
119
- } catch (\Exception $e) {
120
- $msg = 'An error was encountered during the on_headers event';
121
- $ex = new RequestException($msg, $request, $response, $e);
122
- return \GuzzleHttp\Promise\rejection_for($ex);
123
- }
124
- }
125
-
126
- // Do not drain when the request is a HEAD request because they have
127
- // no body.
128
- if ($sink !== $stream) {
129
- $this->drain(
130
- $stream,
131
- $sink,
132
- $response->getHeaderLine('Content-Length')
133
- );
134
- }
135
-
136
- $this->invokeStats($options, $request, $startTime, $response, null);
137
-
138
- return new FulfilledPromise($response);
139
- }
140
-
141
- private function createSink(StreamInterface $stream, array $options)
142
- {
143
- if (!empty($options['stream'])) {
144
- return $stream;
145
- }
146
-
147
- $sink = isset($options['sink'])
148
- ? $options['sink']
149
- : fopen('php://temp', 'r+');
150
-
151
- return is_string($sink)
152
- ? new Psr7\LazyOpenStream($sink, 'w+')
153
- : Psr7\stream_for($sink);
154
- }
155
-
156
- private function checkDecode(array $options, array $headers, $stream)
157
- {
158
- // Automatically decode responses when instructed.
159
- if (!empty($options['decode_content'])) {
160
- $normalizedKeys = \GuzzleHttp\normalize_header_keys($headers);
161
- if (isset($normalizedKeys['content-encoding'])) {
162
- $encoding = $headers[$normalizedKeys['content-encoding']];
163
- if ($encoding[0] === 'gzip' || $encoding[0] === 'deflate') {
164
- $stream = new Psr7\InflateStream(
165
- Psr7\stream_for($stream)
166
- );
167
- $headers['x-encoded-content-encoding']
168
- = $headers[$normalizedKeys['content-encoding']];
169
- // Remove content-encoding header
170
- unset($headers[$normalizedKeys['content-encoding']]);
171
- // Fix content-length header
172
- if (isset($normalizedKeys['content-length'])) {
173
- $headers['x-encoded-content-length']
174
- = $headers[$normalizedKeys['content-length']];
175
-
176
- $length = (int) $stream->getSize();
177
- if ($length === 0) {
178
- unset($headers[$normalizedKeys['content-length']]);
179
- } else {
180
- $headers[$normalizedKeys['content-length']] = [$length];
181
- }
182
- }
183
- }
184
- }
185
- }
186
-
187
- return [$stream, $headers];
188
- }
189
-
190
- /**
191
- * Drains the source stream into the "sink" client option.
192
- *
193
- * @param StreamInterface $source
194
- * @param StreamInterface $sink
195
- * @param string $contentLength Header specifying the amount of
196
- * data to read.
197
- *
198
- * @return StreamInterface
199
- * @throws \RuntimeException when the sink option is invalid.
200
- */
201
- private function drain(
202
- StreamInterface $source,
203
- StreamInterface $sink,
204
- $contentLength
205
- ) {
206
- // If a content-length header is provided, then stop reading once
207
- // that number of bytes has been read. This can prevent infinitely
208
- // reading from a stream when dealing with servers that do not honor
209
- // Connection: Close headers.
210
- Psr7\copy_to_stream(
211
- $source,
212
- $sink,
213
- (strlen($contentLength) > 0 && (int) $contentLength > 0) ? (int) $contentLength : -1
214
- );
215
-
216
- $sink->seek(0);
217
- $source->close();
218
-
219
- return $sink;
220
- }
221
-
222
- /**
223
- * Create a resource and check to ensure it was created successfully
224
- *
225
- * @param callable $callback Callable that returns stream resource
226
- *
227
- * @return resource
228
- * @throws \RuntimeException on error
229
- */
230
- private function createResource(callable $callback)
231
- {
232
- $errors = null;
233
- set_error_handler(function ($_, $msg, $file, $line) use (&$errors) {
234
- $errors[] = [
235
- 'message' => $msg,
236
- 'file' => $file,
237
- 'line' => $line
238
- ];
239
- return true;
240
- });
241
-
242
- $resource = $callback();
243
- restore_error_handler();
244
-
245
- if (!$resource) {
246
- $message = 'Error creating resource: ';
247
- foreach ($errors as $err) {
248
- foreach ($err as $key => $value) {
249
- $message .= "[$key] $value" . PHP_EOL;
250
- }
251
- }
252
- throw new \RuntimeException(trim($message));
253
- }
254
-
255
- return $resource;
256
- }
257
-
258
- private function createStream(RequestInterface $request, array $options)
259
- {
260
- static $methods;
261
- if (!$methods) {
262
- $methods = array_flip(get_class_methods(__CLASS__));
263
- }
264
-
265
- // HTTP/1.1 streams using the PHP stream wrapper require a
266
- // Connection: close header
267
- if ($request->getProtocolVersion() == '1.1'
268
- && !$request->hasHeader('Connection')
269
- ) {
270
- $request = $request->withHeader('Connection', 'close');
271
- }
272
-
273
- // Ensure SSL is verified by default
274
- if (!isset($options['verify'])) {
275
- $options['verify'] = true;
276
- }
277
-
278
- $params = [];
279
- $context = $this->getDefaultContext($request);
280
-
281
- if (isset($options['on_headers']) && !is_callable($options['on_headers'])) {
282
- throw new \InvalidArgumentException('on_headers must be callable');
283
- }
284
-
285
- if (!empty($options)) {
286
- foreach ($options as $key => $value) {
287
- $method = "add_{$key}";
288
- if (isset($methods[$method])) {
289
- $this->{$method}($request, $context, $value, $params);
290
- }
291
- }
292
- }
293
-
294
- if (isset($options['stream_context'])) {
295
- if (!is_array($options['stream_context'])) {
296
- throw new \InvalidArgumentException('stream_context must be an array');
297
- }
298
- $context = array_replace_recursive(
299
- $context,
300
- $options['stream_context']
301
- );
302
- }
303
-
304
- // Microsoft NTLM authentication only supported with curl handler
305
- if (isset($options['auth'])
306
- && is_array($options['auth'])
307
- && isset($options['auth'][2])
308
- && 'ntlm' == $options['auth'][2]
309
- ) {
310
- throw new \InvalidArgumentException('Microsoft NTLM authentication only supported with curl handler');
311
- }
312
-
313
- $uri = $this->resolveHost($request, $options);
314
-
315
- $context = $this->createResource(
316
- function () use ($context, $params) {
317
- return stream_context_create($context, $params);
318
- }
319
- );
320
-
321
- return $this->createResource(
322
- function () use ($uri, &$http_response_header, $context, $options) {
323
- $resource = fopen((string) $uri, 'r', null, $context);
324
- $this->lastHeaders = $http_response_header;
325
-
326
- if (isset($options['read_timeout'])) {
327
- $readTimeout = $options['read_timeout'];
328
- $sec = (int) $readTimeout;
329
- $usec = ($readTimeout - $sec) * 100000;
330
- stream_set_timeout($resource, $sec, $usec);
331
- }
332
-
333
- return $resource;
334
- }
335
- );
336
- }
337
-
338
- private function resolveHost(RequestInterface $request, array $options)
339
- {
340
- $uri = $request->getUri();
341
-
342
- if (isset($options['force_ip_resolve']) && !filter_var($uri->getHost(), FILTER_VALIDATE_IP)) {
343
- if ('v4' === $options['force_ip_resolve']) {
344
- $records = dns_get_record($uri->getHost(), DNS_A);
345
- if (!isset($records[0]['ip'])) {
346
- throw new ConnectException(sprintf("Could not resolve IPv4 address for host '%s'", $uri->getHost()), $request);
347
- }
348
- $uri = $uri->withHost($records[0]['ip']);
349
- } elseif ('v6' === $options['force_ip_resolve']) {
350
- $records = dns_get_record($uri->getHost(), DNS_AAAA);
351
- if (!isset($records[0]['ipv6'])) {
352
- throw new ConnectException(sprintf("Could not resolve IPv6 address for host '%s'", $uri->getHost()), $request);
353
- }
354
- $uri = $uri->withHost('[' . $records[0]['ipv6'] . ']');
355
- }
356
- }
357
-
358
- return $uri;
359
- }
360
-
361
- private function getDefaultContext(RequestInterface $request)
362
- {
363
- $headers = '';
364
- foreach ($request->getHeaders() as $name => $value) {
365
- foreach ($value as $val) {
366
- $headers .= "$name: $val\r\n";
367
- }
368
- }
369
-
370
- $context = [
371
- 'http' => [
372
- 'method' => $request->getMethod(),
373
- 'header' => $headers,
374
- 'protocol_version' => $request->getProtocolVersion(),
375
- 'ignore_errors' => true,
376
- 'follow_location' => 0,
377
- ],
378
- ];
379
-
380
- $body = (string) $request->getBody();
381
-
382
- if (!empty($body)) {
383
- $context['http']['content'] = $body;
384
- // Prevent the HTTP handler from adding a Content-Type header.
385
- if (!$request->hasHeader('Content-Type')) {
386
- $context['http']['header'] .= "Content-Type:\r\n";
387
- }
388
- }
389
-
390
- $context['http']['header'] = rtrim($context['http']['header']);
391
-
392
- return $context;
393
- }
394
-
395
- private function add_proxy(RequestInterface $request, &$options, $value, &$params)
396
- {
397
- if (!is_array($value)) {
398
- $options['http']['proxy'] = $value;
399
- } else {
400
- $scheme = $request->getUri()->getScheme();
401
- if (isset($value[$scheme])) {
402
- if (!isset($value['no'])
403
- || !\GuzzleHttp\is_host_in_noproxy(
404
- $request->getUri()->getHost(),
405
- $value['no']
406
- )
407
- ) {
408
- $options['http']['proxy'] = $value[$scheme];
409
- }
410
- }
411
- }
412
- }
413
-
414
- private function add_timeout(RequestInterface $request, &$options, $value, &$params)
415
- {
416
- if ($value > 0) {
417
- $options['http']['timeout'] = $value;
418
- }
419
- }
420
-
421
- private function add_verify(RequestInterface $request, &$options, $value, &$params)
422
- {
423
- if ($value === true) {
424
- // PHP 5.6 or greater will find the system cert by default. When
425
- // < 5.6, use the Guzzle bundled cacert.
426
- if (PHP_VERSION_ID < 50600) {
427
- $options['ssl']['cafile'] = \GuzzleHttp\default_ca_bundle();
428
- }
429
- } elseif (is_string($value)) {
430
- $options['ssl']['cafile'] = $value;
431
- if (!file_exists($value)) {
432
- throw new \RuntimeException("SSL CA bundle not found: $value");
433
- }
434
- } elseif ($value === false) {
435
- $options['ssl']['verify_peer'] = false;
436
- $options['ssl']['verify_peer_name'] = false;
437
- return;
438
- } else {
439
- throw new \InvalidArgumentException('Invalid verify request option');
440
- }
441
-
442
- $options['ssl']['verify_peer'] = true;
443
- $options['ssl']['verify_peer_name'] = true;
444
- $options['ssl']['allow_self_signed'] = false;
445
- }
446
-
447
- private function add_cert(RequestInterface $request, &$options, $value, &$params)
448
- {
449
- if (is_array($value)) {
450
- $options['ssl']['passphrase'] = $value[1];
451
- $value = $value[0];
452
- }
453
-
454
- if (!file_exists($value)) {
455
- throw new \RuntimeException("SSL certificate not found: {$value}");
456
- }
457
-
458
- $options['ssl']['local_cert'] = $value;
459
- }
460
-
461
- private function add_progress(RequestInterface $request, &$options, $value, &$params)
462
- {
463
- $this->addNotification(
464
- $params,
465
- function ($code, $a, $b, $c, $transferred, $total) use ($value) {
466
- if ($code == STREAM_NOTIFY_PROGRESS) {
467
- $value($total, $transferred, null, null);
468
- }
469
- }
470
- );
471
- }
472
-
473
- private function add_debug(RequestInterface $request, &$options, $value, &$params)
474
- {
475
- if ($value === false) {
476
- return;
477
- }
478
-
479
- static $map = [
480
- STREAM_NOTIFY_CONNECT => 'CONNECT',
481
- STREAM_NOTIFY_AUTH_REQUIRED => 'AUTH_REQUIRED',
482
- STREAM_NOTIFY_AUTH_RESULT => 'AUTH_RESULT',
483
- STREAM_NOTIFY_MIME_TYPE_IS => 'MIME_TYPE_IS',
484
- STREAM_NOTIFY_FILE_SIZE_IS => 'FILE_SIZE_IS',
485
- STREAM_NOTIFY_REDIRECTED => 'REDIRECTED',
486
- STREAM_NOTIFY_PROGRESS => 'PROGRESS',
487
- STREAM_NOTIFY_FAILURE => 'FAILURE',
488
- STREAM_NOTIFY_COMPLETED => 'COMPLETED',
489
- STREAM_NOTIFY_RESOLVE => 'RESOLVE',
490
- ];
491
- static $args = ['severity', 'message', 'message_code',
492
- 'bytes_transferred', 'bytes_max'];
493
-
494
- $value = \GuzzleHttp\debug_resource($value);
495
- $ident = $request->getMethod() . ' ' . $request->getUri()->withFragment('');
496
- $this->addNotification(
497
- $params,
498
- function () use ($ident, $value, $map, $args) {
499
- $passed = func_get_args();
500
- $code = array_shift($passed);
501
- fprintf($value, '<%s> [%s] ', $ident, $map[$code]);
502
- foreach (array_filter($passed) as $i => $v) {
503
- fwrite($value, $args[$i] . ': "' . $v . '" ');
504
- }
505
- fwrite($value, "\n");
506
- }
507
- );
508
- }
509
-
510
- private function addNotification(array &$params, callable $notify)
511
- {
512
- // Wrap the existing function if needed.
513
- if (!isset($params['notification'])) {
514
- $params['notification'] = $notify;
515
- } else {
516
- $params['notification'] = $this->callArray([
517
- $params['notification'],
518
- $notify
519
- ]);
520
- }
521
- }
522
-
523
- private function callArray(array $functions)
524
- {
525
- return function () use ($functions) {
526
- $args = func_get_args();
527
- foreach ($functions as $fn) {
528
- call_user_func_array($fn, $args);
529
- }
530
- };
531
- }
532
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/guzzle/src/HandlerStack.php DELETED
@@ -1,273 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp;
3
-
4
- use Psr\Http\Message\RequestInterface;
5
-
6
- /**
7
- * Creates a composed Guzzle handler function by stacking middlewares on top of
8
- * an HTTP handler function.
9
- */
10
- class HandlerStack
11
- {
12
- /** @var callable */
13
- private $handler;
14
-
15
- /** @var array */
16
- private $stack = [];
17
-
18
- /** @var callable|null */
19
- private $cached;
20
-
21
- /**
22
- * Creates a default handler stack that can be used by clients.
23
- *
24
- * The returned handler will wrap the provided handler or use the most
25
- * appropriate default handler for your system. The returned HandlerStack has
26
- * support for cookies, redirects, HTTP error exceptions, and preparing a body
27
- * before sending.
28
- *
29
- * The returned handler stack can be passed to a client in the "handler"
30
- * option.
31
- *
32
- * @param callable $handler HTTP handler function to use with the stack. If no
33
- * handler is provided, the best handler for your
34
- * system will be utilized.
35
- *
36
- * @return HandlerStack
37
- */
38
- public static function create(callable $handler = null)
39
- {
40
- $stack = new self($handler ?: choose_handler());
41
- $stack->push(Middleware::httpErrors(), 'http_errors');
42
- $stack->push(Middleware::redirect(), 'allow_redirects');
43
- $stack->push(Middleware::cookies(), 'cookies');
44
- $stack->push(Middleware::prepareBody(), 'prepare_body');
45
-
46
- return $stack;
47
- }
48
-
49
- /**
50
- * @param callable $handler Underlying HTTP handler.
51
- */
52
- public function __construct(callable $handler = null)
53
- {
54
- $this->handler = $handler;
55
- }
56
-
57
- /**
58
- * Invokes the handler stack as a composed handler
59
- *
60
- * @param RequestInterface $request
61
- * @param array $options
62
- */
63
- public function __invoke(RequestInterface $request, array $options)
64
- {
65
- $handler = $this->resolve();
66
-
67
- return $handler($request, $options);
68
- }
69
-
70
- /**
71
- * Dumps a string representation of the stack.
72
- *
73
- * @return string
74
- */
75
- public function __toString()
76
- {
77
- $depth = 0;
78
- $stack = [];
79
- if ($this->handler) {
80
- $stack[] = "0) Handler: " . $this->debugCallable($this->handler);
81
- }
82
-
83
- $result = '';
84
- foreach (array_reverse($this->stack) as $tuple) {
85
- $depth++;
86
- $str = "{$depth}) Name: '{$tuple[1]}', ";
87
- $str .= "Function: " . $this->debugCallable($tuple[0]);
88
- $result = "> {$str}\n{$result}";
89
- $stack[] = $str;
90
- }
91
-
92
- foreach (array_keys($stack) as $k) {
93
- $result .= "< {$stack[$k]}\n";
94
- }
95
-
96
- return $result;
97
- }
98
-
99
- /**
100
- * Set the HTTP handler that actually returns a promise.
101
- *
102
- * @param callable $handler Accepts a request and array of options and
103
- * returns a Promise.
104
- */
105
- public function setHandler(callable $handler)
106
- {
107
- $this->handler = $handler;
108
- $this->cached = null;
109
- }
110
-
111
- /**
112
- * Returns true if the builder has a handler.
113
- *
114
- * @return bool
115
- */
116
- public function hasHandler()
117
- {
118
- return (bool) $this->handler;
119
- }
120
-
121
- /**
122
- * Unshift a middleware to the bottom of the stack.
123
- *
124
- * @param callable $middleware Middleware function
125
- * @param string $name Name to register for this middleware.
126
- */
127
- public function unshift(callable $middleware, $name = null)
128
- {
129
- array_unshift($this->stack, [$middleware, $name]);
130
- $this->cached = null;
131
- }
132
-
133
- /**
134
- * Push a middleware to the top of the stack.
135
- *
136
- * @param callable $middleware Middleware function
137
- * @param string $name Name to register for this middleware.
138
- */
139
- public function push(callable $middleware, $name = '')
140
- {
141
- $this->stack[] = [$middleware, $name];
142
- $this->cached = null;
143
- }
144
-
145
- /**
146
- * Add a middleware before another middleware by name.
147
- *
148
- * @param string $findName Middleware to find
149
- * @param callable $middleware Middleware function
150
- * @param string $withName Name to register for this middleware.
151
- */
152
- public function before($findName, callable $middleware, $withName = '')
153
- {
154
- $this->splice($findName, $withName, $middleware, true);
155
- }
156
-
157
- /**
158
- * Add a middleware after another middleware by name.
159
- *
160
- * @param string $findName Middleware to find
161
- * @param callable $middleware Middleware function
162
- * @param string $withName Name to register for this middleware.
163
- */
164
- public function after($findName, callable $middleware, $withName = '')
165
- {
166
- $this->splice($findName, $withName, $middleware, false);
167
- }
168
-
169
- /**
170
- * Remove a middleware by instance or name from the stack.
171
- *
172
- * @param callable|string $remove Middleware to remove by instance or name.
173
- */
174
- public function remove($remove)
175
- {
176
- $this->cached = null;
177
- $idx = is_callable($remove) ? 0 : 1;
178
- $this->stack = array_values(array_filter(
179
- $this->stack,
180
- function ($tuple) use ($idx, $remove) {
181
- return $tuple[$idx] !== $remove;
182
- }
183
- ));
184
- }
185
-
186
- /**
187
- * Compose the middleware and handler into a single callable function.
188
- *
189
- * @return callable
190
- */
191
- public function resolve()
192
- {
193
- if (!$this->cached) {
194
- if (!($prev = $this->handler)) {
195
- throw new \LogicException('No handler has been specified');
196
- }
197
-
198
- foreach (array_reverse($this->stack) as $fn) {
199
- $prev = $fn[0]($prev);
200
- }
201
-
202
- $this->cached = $prev;
203
- }
204
-
205
- return $this->cached;
206
- }
207
-
208
- /**
209
- * @param $name
210
- * @return int
211
- */
212
- private function findByName($name)
213
- {
214
- foreach ($this->stack as $k => $v) {
215
- if ($v[1] === $name) {
216
- return $k;
217
- }
218
- }
219
-
220
- throw new \InvalidArgumentException("Middleware not found: $name");
221
- }
222
-
223
- /**
224
- * Splices a function into the middleware list at a specific position.
225
- *
226
- * @param $findName
227
- * @param $withName
228
- * @param callable $middleware
229
- * @param $before
230
- */
231
- private function splice($findName, $withName, callable $middleware, $before)
232
- {
233
- $this->cached = null;
234
- $idx = $this->findByName($findName);
235
- $tuple = [$middleware, $withName];
236
-
237
- if ($before) {
238
- if ($idx === 0) {
239
- array_unshift($this->stack, $tuple);
240
- } else {
241
- $replacement = [$tuple, $this->stack[$idx]];
242
- array_splice($this->stack, $idx, 1, $replacement);
243
- }
244
- } elseif ($idx === count($this->stack) - 1) {
245
- $this->stack[] = $tuple;
246
- } else {
247
- $replacement = [$this->stack[$idx], $tuple];
248
- array_splice($this->stack, $idx, 1, $replacement);
249
- }
250
- }
251
-
252
- /**
253
- * Provides a debug string for a given callable.
254
- *
255
- * @param array|callable $fn Function to write as a string.
256
- *
257
- * @return string
258
- */
259
- private function debugCallable($fn)
260
- {
261
- if (is_string($fn)) {
262
- return "callable({$fn})";
263
- }
264
-
265
- if (is_array($fn)) {
266
- return is_string($fn[0])
267
- ? "callable({$fn[0]}::{$fn[1]})"
268
- : "callable(['" . get_class($fn[0]) . "', '{$fn[1]}'])";
269
- }
270
-
271
- return 'callable(' . spl_object_hash($fn) . ')';
272
- }
273
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/guzzle/src/MessageFormatter.php DELETED
@@ -1,180 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp;
3
-
4
- use Psr\Http\Message\MessageInterface;
5
- use Psr\Http\Message\RequestInterface;
6
- use Psr\Http\Message\ResponseInterface;
7
-
8
- /**
9
- * Formats log messages using variable substitutions for requests, responses,
10
- * and other transactional data.
11
- *
12
- * The following variable substitutions are supported:
13
- *
14
- * - {request}: Full HTTP request message
15
- * - {response}: Full HTTP response message
16
- * - {ts}: ISO 8601 date in GMT
17
- * - {date_iso_8601} ISO 8601 date in GMT
18
- * - {date_common_log} Apache common log date using the configured timezone.
19
- * - {host}: Host of the request
20
- * - {method}: Method of the request
21
- * - {uri}: URI of the request
22
- * - {version}: Protocol version
23
- * - {target}: Request target of the request (path + query + fragment)
24
- * - {hostname}: Hostname of the machine that sent the request
25
- * - {code}: Status code of the response (if available)
26
- * - {phrase}: Reason phrase of the response (if available)
27
- * - {error}: Any error messages (if available)
28
- * - {req_header_*}: Replace `*` with the lowercased name of a request header to add to the message
29
- * - {res_header_*}: Replace `*` with the lowercased name of a response header to add to the message
30
- * - {req_headers}: Request headers
31
- * - {res_headers}: Response headers
32
- * - {req_body}: Request body
33
- * - {res_body}: Response body
34
- */
35
- class MessageFormatter
36
- {
37
- /**
38
- * Apache Common Log Format.
39
- * @link http://httpd.apache.org/docs/2.4/logs.html#common
40
- * @var string
41
- */
42
- const CLF = "{hostname} {req_header_User-Agent} - [{date_common_log}] \"{method} {target} HTTP/{version}\" {code} {res_header_Content-Length}";
43
- const DEBUG = ">>>>>>>>\n{request}\n<<<<<<<<\n{response}\n--------\n{error}";
44
- const SHORT = '[{ts}] "{method} {target} HTTP/{version}" {code}';
45
-
46
- /** @var string Template used to format log messages */
47
- private $template;
48
-
49
- /**
50
- * @param string $template Log message template
51
- */
52
- public function __construct($template = self::CLF)
53
- {
54
- $this->template = $template ?: self::CLF;
55
- }
56
-
57
- /**
58
- * Returns a formatted message string.
59
- *
60
- * @param RequestInterface $request Request that was sent
61
- * @param ResponseInterface $response Response that was received
62
- * @param \Exception $error Exception that was received
63
- *
64
- * @return string
65
- */
66
- public function format(
67
- RequestInterface $request,
68
- ResponseInterface $response = null,
69
- \Exception $error = null
70
- ) {
71
- $cache = [];
72
-
73
- return preg_replace_callback(
74
- '/{\s*([A-Za-z_\-\.0-9]+)\s*}/',
75
- function (array $matches) use ($request, $response, $error, &$cache) {
76
- if (isset($cache[$matches[1]])) {
77
- return $cache[$matches[1]];
78
- }
79
-
80
- $result = '';
81
- switch ($matches[1]) {
82
- case 'request':
83
- $result = Psr7\str($request);
84
- break;
85
- case 'response':
86
- $result = $response ? Psr7\str($response) : '';
87
- break;
88
- case 'req_headers':
89
- $result = trim($request->getMethod()
90
- . ' ' . $request->getRequestTarget())
91
- . ' HTTP/' . $request->getProtocolVersion() . "\r\n"
92
- . $this->headers($request);
93
- break;
94
- case 'res_headers':
95
- $result = $response ?
96
- sprintf(
97
- 'HTTP/%s %d %s',
98
- $response->getProtocolVersion(),
99
- $response->getStatusCode(),
100
- $response->getReasonPhrase()
101
- ) . "\r\n" . $this->headers($response)
102
- : 'NULL';
103
- break;
104
- case 'req_body':
105
- $result = $request->getBody();
106
- break;
107
- case 'res_body':
108
- $result = $response ? $response->getBody() : 'NULL';
109
- break;
110
- case 'ts':
111
- case 'date_iso_8601':
112
- $result = gmdate('c');
113
- break;
114
- case 'date_common_log':
115
- $result = date('d/M/Y:H:i:s O');
116
- break;
117
- case 'method':
118
- $result = $request->getMethod();
119
- break;
120
- case 'version':
121
- $result = $request->getProtocolVersion();
122
- break;
123
- case 'uri':
124
- case 'url':
125
- $result = $request->getUri();
126
- break;
127
- case 'target':
128
- $result = $request->getRequestTarget();
129
- break;
130
- case 'req_version':
131
- $result = $request->getProtocolVersion();
132
- break;
133
- case 'res_version':
134
- $result = $response
135
- ? $response->getProtocolVersion()
136
- : 'NULL';
137
- break;
138
- case 'host':
139
- $result = $request->getHeaderLine('Host');
140
- break;
141
- case 'hostname':
142
- $result = gethostname();
143
- break;
144
- case 'code':
145
- $result = $response ? $response->getStatusCode() : 'NULL';
146
- break;
147
- case 'phrase':
148
- $result = $response ? $response->getReasonPhrase() : 'NULL';
149
- break;
150
- case 'error':
151
- $result = $error ? $error->getMessage() : 'NULL';
152
- break;
153
- default:
154
- // handle prefixed dynamic headers
155
- if (strpos($matches[1], 'req_header_') === 0) {
156
- $result = $request->getHeaderLine(substr($matches[1], 11));
157
- } elseif (strpos($matches[1], 'res_header_') === 0) {
158
- $result = $response
159
- ? $response->getHeaderLine(substr($matches[1], 11))
160
- : 'NULL';
161
- }
162
- }
163
-
164
- $cache[$matches[1]] = $result;
165
- return $result;
166
- },
167
- $this->template
168
- );
169
- }
170
-
171
- private function headers(MessageInterface $message)
172
- {
173
- $result = '';
174
- foreach ($message->getHeaders() as $name => $values) {
175
- $result .= $name . ': ' . implode(', ', $values) . "\r\n";
176
- }
177
-
178
- return trim($result);
179
- }
180
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/guzzle/src/Middleware.php DELETED
@@ -1,255 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp;
3
-
4
- use GuzzleHttp\Cookie\CookieJarInterface;
5
- use GuzzleHttp\Exception\RequestException;
6
- use GuzzleHttp\Promise\RejectedPromise;
7
- use GuzzleHttp\Psr7;
8
- use Psr\Http\Message\ResponseInterface;
9
- use Psr\Log\LoggerInterface;
10
- use Psr\Log\LogLevel;
11
-
12
- /**
13
- * Functions used to create and wrap handlers with handler middleware.
14
- */
15
- final class Middleware
16
- {
17
- /**
18
- * Middleware that adds cookies to requests.
19
- *
20
- * The options array must be set to a CookieJarInterface in order to use
21
- * cookies. This is typically handled for you by a client.
22
- *
23
- * @return callable Returns a function that accepts the next handler.
24
- */
25
- public static function cookies()
26
- {
27
- return function (callable $handler) {
28
- return function ($request, array $options) use ($handler) {
29
- if (empty($options['cookies'])) {
30
- return $handler($request, $options);
31
- } elseif (!($options['cookies'] instanceof CookieJarInterface)) {
32
- throw new \InvalidArgumentException('cookies must be an instance of GuzzleHttp\Cookie\CookieJarInterface');
33
- }
34
- $cookieJar = $options['cookies'];
35
- $request = $cookieJar->withCookieHeader($request);
36
- return $handler($request, $options)
37
- ->then(
38
- function ($response) use ($cookieJar, $request) {
39
- $cookieJar->extractCookies($request, $response);
40
- return $response;
41
- }
42
- );
43
- };
44
- };
45
- }
46
-
47
- /**
48
- * Middleware that throws exceptions for 4xx or 5xx responses when the
49
- * "http_error" request option is set to true.
50
- *
51
- * @return callable Returns a function that accepts the next handler.
52
- */
53
- public static function httpErrors()
54
- {
55
- return function (callable $handler) {
56
- return function ($request, array $options) use ($handler) {
57
- if (empty($options['http_errors'])) {
58
- return $handler($request, $options);
59
- }
60
- return $handler($request, $options)->then(
61
- function (ResponseInterface $response) use ($request, $handler) {
62
- $code = $response->getStatusCode();
63
- if ($code < 400) {
64
- return $response;
65
- }
66
- throw RequestException::create($request, $response);
67
- }
68
- );
69
- };
70
- };
71
- }
72
-
73
- /**
74
- * Middleware that pushes history data to an ArrayAccess container.
75
- *
76
- * @param array|\ArrayAccess $container Container to hold the history (by reference).
77
- *
78
- * @return callable Returns a function that accepts the next handler.
79
- * @throws \InvalidArgumentException if container is not an array or ArrayAccess.
80
- */
81
- public static function history(&$container)
82
- {
83
- if (!is_array($container) && !$container instanceof \ArrayAccess) {
84
- throw new \InvalidArgumentException('history container must be an array or object implementing ArrayAccess');
85
- }
86
-
87
- return function (callable $handler) use (&$container) {
88
- return function ($request, array $options) use ($handler, &$container) {
89
- return $handler($request, $options)->then(
90
- function ($value) use ($request, &$container, $options) {
91
- $container[] = [
92
- 'request' => $request,
93
- 'response' => $value,
94
- 'error' => null,
95
- 'options' => $options
96
- ];
97
- return $value;
98
- },
99
- function ($reason) use ($request, &$container, $options) {
100
- $container[] = [
101
- 'request' => $request,
102
- 'response' => null,
103
- 'error' => $reason,
104
- 'options' => $options
105
- ];
106
- return \GuzzleHttp\Promise\rejection_for($reason);
107
- }
108
- );
109
- };
110
- };
111
- }
112
-
113
- /**
114
- * Middleware that invokes a callback before and after sending a request.
115
- *
116
- * The provided listener cannot modify or alter the response. It simply
117
- * "taps" into the chain to be notified before returning the promise. The
118
- * before listener accepts a request and options array, and the after
119
- * listener accepts a request, options array, and response promise.
120
- *
121
- * @param callable $before Function to invoke before forwarding the request.
122
- * @param callable $after Function invoked after forwarding.
123
- *
124
- * @return callable Returns a function that accepts the next handler.
125
- */
126
- public static function tap(callable $before = null, callable $after = null)
127
- {
128
- return function (callable $handler) use ($before, $after) {
129
- return function ($request, array $options) use ($handler, $before, $after) {
130
- if ($before) {
131
- $before($request, $options);
132
- }
133
- $response = $handler($request, $options);
134
- if ($after) {
135
- $after($request, $options, $response);
136
- }
137
- return $response;
138
- };
139
- };
140
- }
141
-
142
- /**
143
- * Middleware that handles request redirects.
144
- *
145
- * @return callable Returns a function that accepts the next handler.
146
- */
147
- public static function redirect()
148
- {
149
- return function (callable $handler) {
150
- return new RedirectMiddleware($handler);
151
- };
152
- }
153
-
154
- /**
155
- * Middleware that retries requests based on the boolean result of
156
- * invoking the provided "decider" function.
157
- *
158
- * If no delay function is provided, a simple implementation of exponential
159
- * backoff will be utilized.
160
- *
161
- * @param callable $decider Function that accepts the number of retries,
162
- * a request, [response], and [exception] and
163
- * returns true if the request is to be retried.
164
- * @param callable $delay Function that accepts the number of retries and
165
- * returns the number of milliseconds to delay.
166
- *
167
- * @return callable Returns a function that accepts the next handler.
168
- */
169
- public static function retry(callable $decider, callable $delay = null)
170
- {
171
- return function (callable $handler) use ($decider, $delay) {
172
- return new RetryMiddleware($decider, $handler, $delay);
173
- };
174
- }
175
-
176
- /**
177
- * Middleware that logs requests, responses, and errors using a message
178
- * formatter.
179
- *
180
- * @param LoggerInterface $logger Logs messages.
181
- * @param MessageFormatter $formatter Formatter used to create message strings.
182
- * @param string $logLevel Level at which to log requests.
183
- *
184
- * @return callable Returns a function that accepts the next handler.
185
- */
186
- public static function log(LoggerInterface $logger, MessageFormatter $formatter, $logLevel = LogLevel::INFO)
187
- {
188
- return function (callable $handler) use ($logger, $formatter, $logLevel) {
189
- return function ($request, array $options) use ($handler, $logger, $formatter, $logLevel) {
190
- return $handler($request, $options)->then(
191
- function ($response) use ($logger, $request, $formatter, $logLevel) {
192
- $message = $formatter->format($request, $response);
193
- $logger->log($logLevel, $message);
194
- return $response;
195
- },
196
- function ($reason) use ($logger, $request, $formatter) {
197
- $response = $reason instanceof RequestException
198
- ? $reason->getResponse()
199
- : null;
200
- $message = $formatter->format($request, $response, $reason);
201
- $logger->notice($message);
202
- return \GuzzleHttp\Promise\rejection_for($reason);
203
- }
204
- );
205
- };
206
- };
207
- }
208
-
209
- /**
210
- * This middleware adds a default content-type if possible, a default
211
- * content-length or transfer-encoding header, and the expect header.
212
- *
213
- * @return callable
214
- */
215
- public static function prepareBody()
216
- {
217
- return function (callable $handler) {
218
- return new PrepareBodyMiddleware($handler);
219
- };
220
- }
221
-
222
- /**
223
- * Middleware that applies a map function to the request before passing to
224
- * the next handler.
225
- *
226
- * @param callable $fn Function that accepts a RequestInterface and returns
227
- * a RequestInterface.
228
- * @return callable
229
- */
230
- public static function mapRequest(callable $fn)
231
- {
232
- return function (callable $handler) use ($fn) {
233
- return function ($request, array $options) use ($handler, $fn) {
234
- return $handler($fn($request), $options);
235
- };
236
- };
237
- }
238
-
239
- /**
240
- * Middleware that applies a map function to the resolved promise's
241
- * response.
242
- *
243
- * @param callable $fn Function that accepts a ResponseInterface and
244
- * returns a ResponseInterface.
245
- * @return callable
246
- */
247
- public static function mapResponse(callable $fn)
248
- {
249
- return function (callable $handler) use ($fn) {
250
- return function ($request, array $options) use ($handler, $fn) {
251
- return $handler($request, $options)->then($fn);
252
- };
253
- };
254
- }
255
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/guzzle/src/Pool.php DELETED
@@ -1,123 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp;
3
-
4
- use GuzzleHttp\Promise\PromisorInterface;
5
- use Psr\Http\Message\RequestInterface;
6
- use GuzzleHttp\Promise\EachPromise;
7
-
8
- /**
9
- * Sends and iterator of requests concurrently using a capped pool size.
10
- *
11
- * The pool will read from an iterator until it is cancelled or until the
12
- * iterator is consumed. When a request is yielded, the request is sent after
13
- * applying the "request_options" request options (if provided in the ctor).
14
- *
15
- * When a function is yielded by the iterator, the function is provided the
16
- * "request_options" array that should be merged on top of any existing
17
- * options, and the function MUST then return a wait-able promise.
18
- */
19
- class Pool implements PromisorInterface
20
- {
21
- /** @var EachPromise */
22
- private $each;
23
-
24
- /**
25
- * @param ClientInterface $client Client used to send the requests.
26
- * @param array|\Iterator $requests Requests or functions that return
27
- * requests to send concurrently.
28
- * @param array $config Associative array of options
29
- * - concurrency: (int) Maximum number of requests to send concurrently
30
- * - options: Array of request options to apply to each request.
31
- * - fulfilled: (callable) Function to invoke when a request completes.
32
- * - rejected: (callable) Function to invoke when a request is rejected.
33
- */
34
- public function __construct(
35
- ClientInterface $client,
36
- $requests,
37
- array $config = []
38
- ) {
39
- // Backwards compatibility.
40
- if (isset($config['pool_size'])) {
41
- $config['concurrency'] = $config['pool_size'];
42
- } elseif (!isset($config['concurrency'])) {
43
- $config['concurrency'] = 25;
44
- }
45
-
46
- if (isset($config['options'])) {
47
- $opts = $config['options'];
48
- unset($config['options']);
49
- } else {
50
- $opts = [];
51
- }
52
-
53
- $iterable = \GuzzleHttp\Promise\iter_for($requests);
54
- $requests = function () use ($iterable, $client, $opts) {
55
- foreach ($iterable as $key => $rfn) {
56
- if ($rfn instanceof RequestInterface) {
57
- yield $key => $client->sendAsync($rfn, $opts);
58
- } elseif (is_callable($rfn)) {
59
- yield $key => $rfn($opts);
60
- } else {
61
- throw new \InvalidArgumentException('Each value yielded by '
62
- . 'the iterator must be a Psr7\Http\Message\RequestInterface '
63
- . 'or a callable that returns a promise that fulfills '
64
- . 'with a Psr7\Message\Http\ResponseInterface object.');
65
- }
66
- }
67
- };
68
-
69
- $this->each = new EachPromise($requests(), $config);
70
- }
71
-
72
- public function promise()
73
- {
74
- return $this->each->promise();
75
- }
76
-
77
- /**
78
- * Sends multiple requests concurrently and returns an array of responses
79
- * and exceptions that uses the same ordering as the provided requests.
80
- *
81
- * IMPORTANT: This method keeps every request and response in memory, and
82
- * as such, is NOT recommended when sending a large number or an
83
- * indeterminate number of requests concurrently.
84
- *
85
- * @param ClientInterface $client Client used to send the requests
86
- * @param array|\Iterator $requests Requests to send concurrently.
87
- * @param array $options Passes through the options available in
88
- * {@see GuzzleHttp\Pool::__construct}
89
- *
90
- * @return array Returns an array containing the response or an exception
91
- * in the same order that the requests were sent.
92
- * @throws \InvalidArgumentException if the event format is incorrect.
93
- */
94
- public static function batch(
95
- ClientInterface $client,
96
- $requests,
97
- array $options = []
98
- ) {
99
- $res = [];
100
- self::cmpCallback($options, 'fulfilled', $res);
101
- self::cmpCallback($options, 'rejected', $res);
102
- $pool = new static($client, $requests, $options);
103
- $pool->promise()->wait();
104
- ksort($res);
105
-
106
- return $res;
107
- }
108
-
109
- private static function cmpCallback(array &$options, $name, array &$results)
110
- {
111
- if (!isset($options[$name])) {
112
- $options[$name] = function ($v, $k) use (&$results) {
113
- $results[$k] = $v;
114
- };
115
- } else {
116
- $currentFn = $options[$name];
117
- $options[$name] = function ($v, $k) use (&$results, $currentFn) {
118
- $currentFn($v, $k);
119
- $results[$k] = $v;
120
- };
121
- }
122
- }
123
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php DELETED
@@ -1,106 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp;
3
-
4
- use GuzzleHttp\Promise\PromiseInterface;
5
- use GuzzleHttp\Psr7;
6
- use Psr\Http\Message\RequestInterface;
7
-
8
- /**
9
- * Prepares requests that contain a body, adding the Content-Length,
10
- * Content-Type, and Expect headers.
11
- */
12
- class PrepareBodyMiddleware
13
- {
14
- /** @var callable */
15
- private $nextHandler;
16
-
17
- /**
18
- * @param callable $nextHandler Next handler to invoke.
19
- */
20
- public function __construct(callable $nextHandler)
21
- {
22
- $this->nextHandler = $nextHandler;
23
- }
24
-
25
- /**
26
- * @param RequestInterface $request
27
- * @param array $options
28
- *
29
- * @return PromiseInterface
30
- */
31
- public function __invoke(RequestInterface $request, array $options)
32
- {
33
- $fn = $this->nextHandler;
34
-
35
- // Don't do anything if the request has no body.
36
- if ($request->getBody()->getSize() === 0) {
37
- return $fn($request, $options);
38
- }
39
-
40
- $modify = [];
41
-
42
- // Add a default content-type if possible.
43
- if (!$request->hasHeader('Content-Type')) {
44
- if ($uri = $request->getBody()->getMetadata('uri')) {
45
- if ($type = Psr7\mimetype_from_filename($uri)) {
46
- $modify['set_headers']['Content-Type'] = $type;
47
- }
48
- }
49
- }
50
-
51
- // Add a default content-length or transfer-encoding header.
52
- if (!$request->hasHeader('Content-Length')
53
- && !$request->hasHeader('Transfer-Encoding')
54
- ) {
55
- $size = $request->getBody()->getSize();
56
- if ($size !== null) {
57
- $modify['set_headers']['Content-Length'] = $size;
58
- } else {
59
- $modify['set_headers']['Transfer-Encoding'] = 'chunked';
60
- }
61
- }
62
-
63
- // Add the expect header if needed.
64
- $this->addExpectHeader($request, $options, $modify);
65
-
66
- return $fn(Psr7\modify_request($request, $modify), $options);
67
- }
68
-
69
- private function addExpectHeader(
70
- RequestInterface $request,
71
- array $options,
72
- array &$modify
73
- ) {
74
- // Determine if the Expect header should be used
75
- if ($request->hasHeader('Expect')) {
76
- return;
77
- }
78
-
79
- $expect = isset($options['expect']) ? $options['expect'] : null;
80
-
81
- // Return if disabled or if you're not using HTTP/1.1 or HTTP/2.0
82
- if ($expect === false || $request->getProtocolVersion() < 1.1) {
83
- return;
84
- }
85
-
86
- // The expect header is unconditionally enabled
87
- if ($expect === true) {
88
- $modify['set_headers']['Expect'] = '100-Continue';
89
- return;
90
- }
91
-
92
- // By default, send the expect header when the payload is > 1mb
93
- if ($expect === null) {
94
- $expect = 1048576;
95
- }
96
-
97
- // Always add if the body cannot be rewound, the size cannot be
98
- // determined, or the size is greater than the cutoff threshold
99
- $body = $request->getBody();
100
- $size = $body->getSize();
101
-
102
- if ($size === null || $size >= (int) $expect || !$body->isSeekable()) {
103
- $modify['set_headers']['Expect'] = '100-Continue';
104
- }
105
- }
106
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/guzzle/src/RedirectMiddleware.php DELETED
@@ -1,237 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp;
3
-
4
- use GuzzleHttp\Exception\BadResponseException;
5
- use GuzzleHttp\Exception\TooManyRedirectsException;
6
- use GuzzleHttp\Promise\PromiseInterface;
7
- use GuzzleHttp\Psr7;
8
- use Psr\Http\Message\RequestInterface;
9
- use Psr\Http\Message\ResponseInterface;
10
- use Psr\Http\Message\UriInterface;
11
-
12
- /**
13
- * Request redirect middleware.
14
- *
15
- * Apply this middleware like other middleware using
16
- * {@see GuzzleHttp\Middleware::redirect()}.
17
- */
18
- class RedirectMiddleware
19
- {
20
- const HISTORY_HEADER = 'X-Guzzle-Redirect-History';
21
-
22
- const STATUS_HISTORY_HEADER = 'X-Guzzle-Redirect-Status-History';
23
-
24
- public static $defaultSettings = [
25
- 'max' => 5,
26
- 'protocols' => ['http', 'https'],
27
- 'strict' => false,
28
- 'referer' => false,
29
- 'track_redirects' => false,
30
- ];
31
-
32
- /** @var callable */
33
- private $nextHandler;
34
-
35
- /**
36
- * @param callable $nextHandler Next handler to invoke.
37
- */
38
- public function __construct(callable $nextHandler)
39
- {
40
- $this->nextHandler = $nextHandler;
41
- }
42
-
43
- /**
44
- * @param RequestInterface $request
45
- * @param array $options
46
- *
47
- * @return PromiseInterface
48
- */
49
- public function __invoke(RequestInterface $request, array $options)
50
- {
51
- $fn = $this->nextHandler;
52
-
53
- if (empty($options['allow_redirects'])) {
54
- return $fn($request, $options);
55
- }
56
-
57
- if ($options['allow_redirects'] === true) {
58
- $options['allow_redirects'] = self::$defaultSettings;
59
- } elseif (!is_array($options['allow_redirects'])) {
60
- throw new \InvalidArgumentException('allow_redirects must be true, false, or array');
61
- } else {
62
- // Merge the default settings with the provided settings
63
- $options['allow_redirects'] += self::$defaultSettings;
64
- }
65
-
66
- if (empty($options['allow_redirects']['max'])) {
67
- return $fn($request, $options);
68
- }
69
-
70
- return $fn($request, $options)
71
- ->then(function (ResponseInterface $response) use ($request, $options) {
72
- return $this->checkRedirect($request, $options, $response);
73
- });
74
- }
75
-
76
- /**
77
- * @param RequestInterface $request
78
- * @param array $options
79
- * @param ResponseInterface|PromiseInterface $response
80
- *
81
- * @return ResponseInterface|PromiseInterface
82
- */
83
- public function checkRedirect(
84
- RequestInterface $request,
85
- array $options,
86
- ResponseInterface $response
87
- ) {
88
- if (substr($response->getStatusCode(), 0, 1) != '3'
89
- || !$response->hasHeader('Location')
90
- ) {
91
- return $response;
92
- }
93
-
94
- $this->guardMax($request, $options);
95
- $nextRequest = $this->modifyRequest($request, $options, $response);
96
-
97
- if (isset($options['allow_redirects']['on_redirect'])) {
98
- call_user_func(
99
- $options['allow_redirects']['on_redirect'],
100
- $request,
101
- $response,
102
- $nextRequest->getUri()
103
- );
104
- }
105
-
106
- /** @var PromiseInterface|ResponseInterface $promise */
107
- $promise = $this($nextRequest, $options);
108
-
109
- // Add headers to be able to track history of redirects.
110
- if (!empty($options['allow_redirects']['track_redirects'])) {
111
- return $this->withTracking(
112
- $promise,
113
- (string) $nextRequest->getUri(),
114
- $response->getStatusCode()
115
- );
116
- }
117
-
118
- return $promise;
119
- }
120
-
121
- private function withTracking(PromiseInterface $promise, $uri, $statusCode)
122
- {
123
- return $promise->then(
124
- function (ResponseInterface $response) use ($uri, $statusCode) {
125
- // Note that we are pushing to the front of the list as this
126
- // would be an earlier response than what is currently present
127
- // in the history header.
128
- $historyHeader = $response->getHeader(self::HISTORY_HEADER);
129
- $statusHeader = $response->getHeader(self::STATUS_HISTORY_HEADER);
130
- array_unshift($historyHeader, $uri);
131
- array_unshift($statusHeader, $statusCode);
132
- return $response->withHeader(self::HISTORY_HEADER, $historyHeader)
133
- ->withHeader(self::STATUS_HISTORY_HEADER, $statusHeader);
134
- }
135
- );
136
- }
137
-
138
- private function guardMax(RequestInterface $request, array &$options)
139
- {
140
- $current = isset($options['__redirect_count'])
141
- ? $options['__redirect_count']
142
- : 0;
143
- $options['__redirect_count'] = $current + 1;
144
- $max = $options['allow_redirects']['max'];
145
-
146
- if ($options['__redirect_count'] > $max) {
147
- throw new TooManyRedirectsException(
148
- "Will not follow more than {$max} redirects",
149
- $request
150
- );
151
- }
152
- }
153
-
154
- /**
155
- * @param RequestInterface $request
156
- * @param array $options
157
- * @param ResponseInterface $response
158
- *
159
- * @return RequestInterface
160
- */
161
- public function modifyRequest(
162
- RequestInterface $request,
163
- array $options,
164
- ResponseInterface $response
165
- ) {
166
- // Request modifications to apply.
167
- $modify = [];
168
- $protocols = $options['allow_redirects']['protocols'];
169
-
170
- // Use a GET request if this is an entity enclosing request and we are
171
- // not forcing RFC compliance, but rather emulating what all browsers
172
- // would do.
173
- $statusCode = $response->getStatusCode();
174
- if ($statusCode == 303 ||
175
- ($statusCode <= 302 && $request->getBody() && !$options['allow_redirects']['strict'])
176
- ) {
177
- $modify['method'] = 'GET';
178
- $modify['body'] = '';
179
- }
180
-
181
- $modify['uri'] = $this->redirectUri($request, $response, $protocols);
182
- Psr7\rewind_body($request);
183
-
184
- // Add the Referer header if it is told to do so and only
185
- // add the header if we are not redirecting from https to http.
186
- if ($options['allow_redirects']['referer']
187
- && $modify['uri']->getScheme() === $request->getUri()->getScheme()
188
- ) {
189
- $uri = $request->getUri()->withUserInfo('', '');
190
- $modify['set_headers']['Referer'] = (string) $uri;
191
- } else {
192
- $modify['remove_headers'][] = 'Referer';
193
- }
194
-
195
- // Remove Authorization header if host is different.
196
- if ($request->getUri()->getHost() !== $modify['uri']->getHost()) {
197
- $modify['remove_headers'][] = 'Authorization';
198
- }
199
-
200
- return Psr7\modify_request($request, $modify);
201
- }
202
-
203
- /**
204
- * Set the appropriate URL on the request based on the location header
205
- *
206
- * @param RequestInterface $request
207
- * @param ResponseInterface $response
208
- * @param array $protocols
209
- *
210
- * @return UriInterface
211
- */
212
- private function redirectUri(
213
- RequestInterface $request,
214
- ResponseInterface $response,
215
- array $protocols
216
- ) {
217
- $location = Psr7\UriResolver::resolve(
218
- $request->getUri(),
219
- new Psr7\Uri($response->getHeaderLine('Location'))
220
- );
221
-
222
- // Ensure that the redirect URI is allowed based on the protocols.
223
- if (!in_array($location->getScheme(), $protocols)) {
224
- throw new BadResponseException(
225
- sprintf(
226
- 'Redirect URI, %s, does not use one of the allowed redirect protocols: %s',
227
- $location,
228
- implode(', ', $protocols)
229
- ),
230
- $request,
231
- $response
232
- );
233
- }
234
-
235
- return $location;
236
- }
237
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/guzzle/src/RequestOptions.php DELETED
@@ -1,255 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp;
3
-
4
- /**
5
- * This class contains a list of built-in Guzzle request options.
6
- *
7
- * More documentation for each option can be found at http://guzzlephp.org/.
8
- *
9
- * @link http://docs.guzzlephp.org/en/v6/request-options.html
10
- */
11
- final class RequestOptions
12
- {
13
- /**
14
- * allow_redirects: (bool|array) Controls redirect behavior. Pass false
15
- * to disable redirects, pass true to enable redirects, pass an
16
- * associative to provide custom redirect settings. Defaults to "false".
17
- * This option only works if your handler has the RedirectMiddleware. When
18
- * passing an associative array, you can provide the following key value
19
- * pairs:
20
- *
21
- * - max: (int, default=5) maximum number of allowed redirects.
22
- * - strict: (bool, default=false) Set to true to use strict redirects
23
- * meaning redirect POST requests with POST requests vs. doing what most
24
- * browsers do which is redirect POST requests with GET requests
25
- * - referer: (bool, default=true) Set to false to disable the Referer
26
- * header.
27
- * - protocols: (array, default=['http', 'https']) Allowed redirect
28
- * protocols.
29
- * - on_redirect: (callable) PHP callable that is invoked when a redirect
30
- * is encountered. The callable is invoked with the request, the redirect
31
- * response that was received, and the effective URI. Any return value
32
- * from the on_redirect function is ignored.
33
- */
34
- const ALLOW_REDIRECTS = 'allow_redirects';
35
-
36
- /**
37
- * auth: (array) Pass an array of HTTP authentication parameters to use
38
- * with the request. The array must contain the username in index [0],
39
- * the password in index [1], and you can optionally provide a built-in
40
- * authentication type in index [2]. Pass null to disable authentication
41
- * for a request.
42
- */
43
- const AUTH = 'auth';
44
-
45
- /**
46
- * body: (resource|string|null|int|float|StreamInterface|callable|\Iterator)
47
- * Body to send in the request.
48
- */
49
- const BODY = 'body';
50
-
51
- /**
52
- * cert: (string|array) Set to a string to specify the path to a file
53
- * containing a PEM formatted SSL client side certificate. If a password
54
- * is required, then set cert to an array containing the path to the PEM
55
- * file in the first array element followed by the certificate password
56
- * in the second array element.
57
- */
58
- const CERT = 'cert';
59
-
60
- /**
61
- * cookies: (bool|GuzzleHttp\Cookie\CookieJarInterface, default=false)
62
- * Specifies whether or not cookies are used in a request or what cookie
63
- * jar to use or what cookies to send. This option only works if your
64
- * handler has the `cookie` middleware. Valid values are `false` and
65
- * an instance of {@see GuzzleHttp\Cookie\CookieJarInterface}.
66
- */
67
- const COOKIES = 'cookies';
68
-
69
- /**
70
- * connect_timeout: (float, default=0) Float describing the number of
71
- * seconds to wait while trying to connect to a server. Use 0 to wait
72
- * indefinitely (the default behavior).
73
- */
74
- const CONNECT_TIMEOUT = 'connect_timeout';
75
-
76
- /**
77
- * debug: (bool|resource) Set to true or set to a PHP stream returned by
78
- * fopen() enable debug output with the HTTP handler used to send a
79
- * request.
80
- */
81
- const DEBUG = 'debug';
82
-
83
- /**
84
- * decode_content: (bool, default=true) Specify whether or not
85
- * Content-Encoding responses (gzip, deflate, etc.) are automatically
86
- * decoded.
87
- */
88
- const DECODE_CONTENT = 'decode_content';
89
-
90
- /**
91
- * delay: (int) The amount of time to delay before sending in milliseconds.
92
- */
93
- const DELAY = 'delay';
94
-
95
- /**
96
- * expect: (bool|integer) Controls the behavior of the
97
- * "Expect: 100-Continue" header.
98
- *
99
- * Set to `true` to enable the "Expect: 100-Continue" header for all
100
- * requests that sends a body. Set to `false` to disable the
101
- * "Expect: 100-Continue" header for all requests. Set to a number so that
102
- * the size of the payload must be greater than the number in order to send
103
- * the Expect header. Setting to a number will send the Expect header for
104
- * all requests in which the size of the payload cannot be determined or
105
- * where the body is not rewindable.
106
- *
107
- * By default, Guzzle will add the "Expect: 100-Continue" header when the
108
- * size of the body of a request is greater than 1 MB and a request is
109
- * using HTTP/1.1.
110
- */
111
- const EXPECT = 'expect';
112
-
113
- /**
114
- * form_params: (array) Associative array of form field names to values
115
- * where each value is a string or array of strings. Sets the Content-Type
116
- * header to application/x-www-form-urlencoded when no Content-Type header
117
- * is already present.
118
- */
119
- const FORM_PARAMS = 'form_params';
120
-
121
- /**
122
- * headers: (array) Associative array of HTTP headers. Each value MUST be
123
- * a string or array of strings.
124
- */
125
- const HEADERS = 'headers';
126
-
127
- /**
128
- * http_errors: (bool, default=true) Set to false to disable exceptions
129
- * when a non- successful HTTP response is received. By default,
130
- * exceptions will be thrown for 4xx and 5xx responses. This option only
131
- * works if your handler has the `httpErrors` middleware.
132
- */
133
- const HTTP_ERRORS = 'http_errors';
134
-
135
- /**
136
- * json: (mixed) Adds JSON data to a request. The provided value is JSON
137
- * encoded and a Content-Type header of application/json will be added to
138
- * the request if no Content-Type header is already present.
139
- */
140
- const JSON = 'json';
141
-
142
- /**
143
- * multipart: (array) Array of associative arrays, each containing a
144
- * required "name" key mapping to the form field, name, a required
145
- * "contents" key mapping to a StreamInterface|resource|string, an
146
- * optional "headers" associative array of custom headers, and an
147
- * optional "filename" key mapping to a string to send as the filename in
148
- * the part. If no "filename" key is present, then no "filename" attribute
149
- * will be added to the part.
150
- */
151
- const MULTIPART = 'multipart';
152
-
153
- /**
154
- * on_headers: (callable) A callable that is invoked when the HTTP headers
155
- * of the response have been received but the body has not yet begun to
156
- * download.
157
- */
158
- const ON_HEADERS = 'on_headers';
159
-
160
- /**
161
- * on_stats: (callable) allows you to get access to transfer statistics of
162
- * a request and access the lower level transfer details of the handler
163
- * associated with your client. ``on_stats`` is a callable that is invoked
164
- * when a handler has finished sending a request. The callback is invoked
165
- * with transfer statistics about the request, the response received, or
166
- * the error encountered. Included in the data is the total amount of time
167
- * taken to send the request.
168
- */
169
- const ON_STATS = 'on_stats';
170
-
171
- /**
172
- * progress: (callable) Defines a function to invoke when transfer
173
- * progress is made. The function accepts the following positional
174
- * arguments: the total number of bytes expected to be downloaded, the
175
- * number of bytes downloaded so far, the number of bytes expected to be
176
- * uploaded, the number of bytes uploaded so far.
177
- */
178
- const PROGRESS = 'progress';
179
-
180
- /**
181
- * proxy: (string|array) Pass a string to specify an HTTP proxy, or an
182
- * array to specify different proxies for different protocols (where the
183
- * key is the protocol and the value is a proxy string).
184
- */
185
- const PROXY = 'proxy';
186
-
187
- /**
188
- * query: (array|string) Associative array of query string values to add
189
- * to the request. This option uses PHP's http_build_query() to create
190
- * the string representation. Pass a string value if you need more
191
- * control than what this method provides
192
- */
193
- const QUERY = 'query';
194
-
195
- /**
196
- * sink: (resource|string|StreamInterface) Where the data of the
197
- * response is written to. Defaults to a PHP temp stream. Providing a
198
- * string will write data to a file by the given name.
199
- */
200
- const SINK = 'sink';
201
-
202
- /**
203
- * synchronous: (bool) Set to true to inform HTTP handlers that you intend
204
- * on waiting on the response. This can be useful for optimizations. Note
205
- * that a promise is still returned if you are using one of the async
206
- * client methods.
207
- */
208
- const SYNCHRONOUS = 'synchronous';
209
-
210
- /**
211
- * ssl_key: (array|string) Specify the path to a file containing a private
212
- * SSL key in PEM format. If a password is required, then set to an array
213
- * containing the path to the SSL key in the first array element followed
214
- * by the password required for the certificate in the second element.
215
- */
216
- const SSL_KEY = 'ssl_key';
217
-
218
- /**
219
- * stream: Set to true to attempt to stream a response rather than
220
- * download it all up-front.
221
- */
222
- const STREAM = 'stream';
223
-
224
- /**
225
- * verify: (bool|string, default=true) Describes the SSL certificate
226
- * verification behavior of a request. Set to true to enable SSL
227
- * certificate verification using the system CA bundle when available
228
- * (the default). Set to false to disable certificate verification (this
229
- * is insecure!). Set to a string to provide the path to a CA bundle on
230
- * disk to enable verification using a custom certificate.
231
- */
232
- const VERIFY = 'verify';
233
-
234
- /**
235
- * timeout: (float, default=0) Float describing the timeout of the
236
- * request in seconds. Use 0 to wait indefinitely (the default behavior).
237
- */
238
- const TIMEOUT = 'timeout';
239
-
240
- /**
241
- * read_timeout: (float, default=default_socket_timeout ini setting) Float describing
242
- * the body read timeout, for stream requests.
243
- */
244
- const READ_TIMEOUT = 'read_timeout';
245
-
246
- /**
247
- * version: (float) Specifies the HTTP protocol version to attempt to use.
248
- */
249
- const VERSION = 'version';
250
-
251
- /**
252
- * force_ip_resolve: (bool) Force client to use only ipv4 or ipv6 protocol
253
- */
254
- const FORCE_IP_RESOLVE = 'force_ip_resolve';
255
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/guzzle/src/RetryMiddleware.php DELETED
@@ -1,112 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp;
3
-
4
- use GuzzleHttp\Promise\PromiseInterface;
5
- use GuzzleHttp\Promise\RejectedPromise;
6
- use GuzzleHttp\Psr7;
7
- use Psr\Http\Message\RequestInterface;
8
- use Psr\Http\Message\ResponseInterface;
9
-
10
- /**
11
- * Middleware that retries requests based on the boolean result of
12
- * invoking the provided "decider" function.
13
- */
14
- class RetryMiddleware
15
- {
16
- /** @var callable */
17
- private $nextHandler;
18
-
19
- /** @var callable */
20
- private $decider;
21
-
22
- /**
23
- * @param callable $decider Function that accepts the number of retries,
24
- * a request, [response], and [exception] and
25
- * returns true if the request is to be
26
- * retried.
27
- * @param callable $nextHandler Next handler to invoke.
28
- * @param callable $delay Function that accepts the number of retries
29
- * and [response] and returns the number of
30
- * milliseconds to delay.
31
- */
32
- public function __construct(
33
- callable $decider,
34
- callable $nextHandler,
35
- callable $delay = null
36
- ) {
37
- $this->decider = $decider;
38
- $this->nextHandler = $nextHandler;
39
- $this->delay = $delay ?: __CLASS__ . '::exponentialDelay';
40
- }
41
-
42
- /**
43
- * Default exponential backoff delay function.
44
- *
45
- * @param $retries
46
- *
47
- * @return int
48
- */
49
- public static function exponentialDelay($retries)
50
- {
51
- return (int) pow(2, $retries - 1);
52
- }
53
-
54
- /**
55
- * @param RequestInterface $request
56
- * @param array $options
57
- *
58
- * @return PromiseInterface
59
- */
60
- public function __invoke(RequestInterface $request, array $options)
61
- {
62
- if (!isset($options['retries'])) {
63
- $options['retries'] = 0;
64
- }
65
-
66
- $fn = $this->nextHandler;
67
- return $fn($request, $options)
68
- ->then(
69
- $this->onFulfilled($request, $options),
70
- $this->onRejected($request, $options)
71
- );
72
- }
73
-
74
- private function onFulfilled(RequestInterface $req, array $options)
75
- {
76
- return function ($value) use ($req, $options) {
77
- if (!call_user_func(
78
- $this->decider,
79
- $options['retries'],
80
- $req,
81
- $value,
82
- null
83
- )) {
84
- return $value;
85
- }
86
- return $this->doRetry($req, $options, $value);
87
- };
88
- }
89
-
90
- private function onRejected(RequestInterface $req, array $options)
91
- {
92
- return function ($reason) use ($req, $options) {
93
- if (!call_user_func(
94
- $this->decider,
95
- $options['retries'],
96
- $req,
97
- null,
98
- $reason
99
- )) {
100
- return \GuzzleHttp\Promise\rejection_for($reason);
101
- }
102
- return $this->doRetry($req, $options);
103
- };
104
- }
105
-
106
- private function doRetry(RequestInterface $request, array $options, ResponseInterface $response = null)
107
- {
108
- $options['delay'] = call_user_func($this->delay, ++$options['retries'], $response);
109
-
110
- return $this($request, $options);
111
- }
112
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/guzzle/src/TransferStats.php DELETED
@@ -1,126 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp;
3
-
4
- use Psr\Http\Message\RequestInterface;
5
- use Psr\Http\Message\ResponseInterface;
6
- use Psr\Http\Message\UriInterface;
7
-
8
- /**
9
- * Represents data at the point after it was transferred either successfully
10
- * or after a network error.
11
- */
12
- final class TransferStats
13
- {
14
- private $request;
15
- private $response;
16
- private $transferTime;
17
- private $handlerStats;
18
- private $handlerErrorData;
19
-
20
- /**
21
- * @param RequestInterface $request Request that was sent.
22
- * @param ResponseInterface $response Response received (if any)
23
- * @param null $transferTime Total handler transfer time.
24
- * @param mixed $handlerErrorData Handler error data.
25
- * @param array $handlerStats Handler specific stats.
26
- */
27
- public function __construct(
28
- RequestInterface $request,
29
- ResponseInterface $response = null,
30
- $transferTime = null,
31
- $handlerErrorData = null,
32
- $handlerStats = []
33
- ) {
34
- $this->request = $request;
35
- $this->response = $response;
36
- $this->transferTime = $transferTime;
37
- $this->handlerErrorData = $handlerErrorData;
38
- $this->handlerStats = $handlerStats;
39
- }
40
-
41
- /**
42
- * @return RequestInterface
43
- */
44
- public function getRequest()
45
- {
46
- return $this->request;
47
- }
48
-
49
- /**
50
- * Returns the response that was received (if any).
51
- *
52
- * @return ResponseInterface|null
53
- */
54
- public function getResponse()
55
- {
56
- return $this->response;
57
- }
58
-
59
- /**
60
- * Returns true if a response was received.
61
- *
62
- * @return bool
63
- */
64
- public function hasResponse()
65
- {
66
- return $this->response !== null;
67
- }
68
-
69
- /**
70
- * Gets handler specific error data.
71
- *
72
- * This might be an exception, a integer representing an error code, or
73
- * anything else. Relying on this value assumes that you know what handler
74
- * you are using.
75
- *
76
- * @return mixed
77
- */
78
- public function getHandlerErrorData()
79
- {
80
- return $this->handlerErrorData;
81
- }
82
-
83
- /**
84
- * Get the effective URI the request was sent to.
85
- *
86
- * @return UriInterface
87
- */
88
- public function getEffectiveUri()
89
- {
90
- return $this->request->getUri();
91
- }
92
-
93
- /**
94
- * Get the estimated time the request was being transferred by the handler.
95
- *
96
- * @return float Time in seconds.
97
- */
98
- public function getTransferTime()
99
- {
100
- return $this->transferTime;
101
- }
102
-
103
- /**
104
- * Gets an array of all of the handler specific transfer data.
105
- *
106
- * @return array
107
- */
108
- public function getHandlerStats()
109
- {
110
- return $this->handlerStats;
111
- }
112
-
113
- /**
114
- * Get a specific handler statistic from the handler by name.
115
- *
116
- * @param string $stat Handler specific transfer stat to retrieve.
117
- *
118
- * @return mixed|null
119
- */
120
- public function getHandlerStat($stat)
121
- {
122
- return isset($this->handlerStats[$stat])
123
- ? $this->handlerStats[$stat]
124
- : null;
125
- }
126
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/guzzle/src/UriTemplate.php DELETED
@@ -1,237 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp;
3
-
4
- /**
5
- * Expands URI templates. Userland implementation of PECL uri_template.
6
- *
7
- * @link http://tools.ietf.org/html/rfc6570
8
- */
9
- class UriTemplate
10
- {
11
- /** @var string URI template */
12
- private $template;
13
-
14
- /** @var array Variables to use in the template expansion */
15
- private $variables;
16
-
17
- /** @var array Hash for quick operator lookups */
18
- private static $operatorHash = [
19
- '' => ['prefix' => '', 'joiner' => ',', 'query' => false],
20
- '+' => ['prefix' => '', 'joiner' => ',', 'query' => false],
21
- '#' => ['prefix' => '#', 'joiner' => ',', 'query' => false],
22
- '.' => ['prefix' => '.', 'joiner' => '.', 'query' => false],
23
- '/' => ['prefix' => '/', 'joiner' => '/', 'query' => false],
24
- ';' => ['prefix' => ';', 'joiner' => ';', 'query' => true],
25
- '?' => ['prefix' => '?', 'joiner' => '&', 'query' => true],
26
- '&' => ['prefix' => '&', 'joiner' => '&', 'query' => true]
27
- ];
28
-
29
- /** @var array Delimiters */
30
- private static $delims = [':', '/', '?', '#', '[', ']', '@', '!', '$',
31
- '&', '\'', '(', ')', '*', '+', ',', ';', '='];
32
-
33
- /** @var array Percent encoded delimiters */
34
- private static $delimsPct = ['%3A', '%2F', '%3F', '%23', '%5B', '%5D',
35
- '%40', '%21', '%24', '%26', '%27', '%28', '%29', '%2A', '%2B', '%2C',
36
- '%3B', '%3D'];
37
-
38
- public function expand($template, array $variables)
39
- {
40
- if (false === strpos($template, '{')) {
41
- return $template;
42
- }
43
-
44
- $this->template = $template;
45
- $this->variables = $variables;
46
-
47
- return preg_replace_callback(
48
- '/\{([^\}]+)\}/',
49
- [$this, 'expandMatch'],
50
- $this->template
51
- );
52
- }
53
-
54
- /**
55
- * Parse an expression into parts
56
- *
57
- * @param string $expression Expression to parse
58
- *
59
- * @return array Returns an associative array of parts
60
- */
61
- private function parseExpression($expression)
62
- {
63
- $result = [];
64
-
65
- if (isset(self::$operatorHash[$expression[0]])) {
66
- $result['operator'] = $expression[0];
67
- $expression = substr($expression, 1);
68
- } else {
69
- $result['operator'] = '';
70
- }
71
-
72
- foreach (explode(',', $expression) as $value) {
73
- $value = trim($value);
74
- $varspec = [];
75
- if ($colonPos = strpos($value, ':')) {
76
- $varspec['value'] = substr($value, 0, $colonPos);
77
- $varspec['modifier'] = ':';
78
- $varspec['position'] = (int) substr($value, $colonPos + 1);
79
- } elseif (substr($value, -1) === '*') {
80
- $varspec['modifier'] = '*';
81
- $varspec['value'] = substr($value, 0, -1);
82
- } else {
83
- $varspec['value'] = (string) $value;
84
- $varspec['modifier'] = '';
85
- }
86
- $result['values'][] = $varspec;
87
- }
88
-
89
- return $result;
90
- }
91
-
92
- /**
93
- * Process an expansion
94
- *
95
- * @param array $matches Matches met in the preg_replace_callback
96
- *
97
- * @return string Returns the replacement string
98
- */
99
- private function expandMatch(array $matches)
100
- {
101
- static $rfc1738to3986 = ['+' => '%20', '%7e' => '~'];
102
-
103
- $replacements = [];
104
- $parsed = self::parseExpression($matches[1]);
105
- $prefix = self::$operatorHash[$parsed['operator']]['prefix'];
106
- $joiner = self::$operatorHash[$parsed['operator']]['joiner'];
107
- $useQuery = self::$operatorHash[$parsed['operator']]['query'];
108
-
109
- foreach ($parsed['values'] as $value) {
110
- if (!isset($this->variables[$value['value']])) {
111
- continue;
112
- }
113
-
114
- $variable = $this->variables[$value['value']];
115
- $actuallyUseQuery = $useQuery;
116
- $expanded = '';
117
-
118
- if (is_array($variable)) {
119
- $isAssoc = $this->isAssoc($variable);
120
- $kvp = [];
121
- foreach ($variable as $key => $var) {
122
- if ($isAssoc) {
123
- $key = rawurlencode($key);
124
- $isNestedArray = is_array($var);
125
- } else {
126
- $isNestedArray = false;
127
- }
128
-
129
- if (!$isNestedArray) {
130
- $var = rawurlencode($var);
131
- if ($parsed['operator'] === '+' ||
132
- $parsed['operator'] === '#'
133
- ) {
134
- $var = $this->decodeReserved($var);
135
- }
136
- }
137
-
138
- if ($value['modifier'] === '*') {
139
- if ($isAssoc) {
140
- if ($isNestedArray) {
141
- // Nested arrays must allow for deeply nested
142
- // structures.
143
- $var = strtr(
144
- http_build_query([$key => $var]),
145
- $rfc1738to3986
146
- );
147
- } else {
148
- $var = $key . '=' . $var;
149
- }
150
- } elseif ($key > 0 && $actuallyUseQuery) {
151
- $var = $value['value'] . '=' . $var;
152
- }
153
- }
154
-
155
- $kvp[$key] = $var;
156
- }
157
-
158
- if (empty($variable)) {
159
- $actuallyUseQuery = false;
160
- } elseif ($value['modifier'] === '*') {
161
- $expanded = implode($joiner, $kvp);
162
- if ($isAssoc) {
163
- // Don't prepend the value name when using the explode
164
- // modifier with an associative array.
165
- $actuallyUseQuery = false;
166
- }
167
- } else {
168
- if ($isAssoc) {
169
- // When an associative array is encountered and the
170
- // explode modifier is not set, then the result must be
171
- // a comma separated list of keys followed by their
172
- // respective values.
173
- foreach ($kvp as $k => &$v) {
174
- $v = $k . ',' . $v;
175
- }
176
- }
177
- $expanded = implode(',', $kvp);
178
- }
179
- } else {
180
- if ($value['modifier'] === ':') {
181
- $variable = substr($variable, 0, $value['position']);
182
- }
183
- $expanded = rawurlencode($variable);
184
- if ($parsed['operator'] === '+' || $parsed['operator'] === '#') {
185
- $expanded = $this->decodeReserved($expanded);
186
- }
187
- }
188
-
189
- if ($actuallyUseQuery) {
190
- if (!$expanded && $joiner !== '&') {
191
- $expanded = $value['value'];
192
- } else {
193
- $expanded = $value['value'] . '=' . $expanded;
194
- }
195
- }
196
-
197
- $replacements[] = $expanded;
198
- }
199
-
200
- $ret = implode($joiner, $replacements);
201
- if ($ret && $prefix) {
202
- return $prefix . $ret;
203
- }
204
-
205
- return $ret;
206
- }
207
-
208
- /**
209
- * Determines if an array is associative.
210
- *
211
- * This makes the assumption that input arrays are sequences or hashes.
212
- * This assumption is a tradeoff for accuracy in favor of speed, but it
213
- * should work in almost every case where input is supplied for a URI
214
- * template.
215
- *
216
- * @param array $array Array to check
217
- *
218
- * @return bool
219
- */
220
- private function isAssoc(array $array)
221
- {
222
- return $array && array_keys($array)[0] !== 0;
223
- }
224
-
225
- /**
226
- * Removes percent encoding on reserved characters (used with + and #
227
- * modifiers).
228
- *
229
- * @param string $string String to fix
230
- *
231
- * @return string
232
- */
233
- private function decodeReserved($string)
234
- {
235
- return str_replace(self::$delimsPct, self::$delims, $string);
236
- }
237
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/guzzle/src/functions.php DELETED
@@ -1,333 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp;
3
-
4
- use GuzzleHttp\Handler\CurlHandler;
5
- use GuzzleHttp\Handler\CurlMultiHandler;
6
- use GuzzleHttp\Handler\Proxy;
7
- use GuzzleHttp\Handler\StreamHandler;
8
-
9
- /**
10
- * Expands a URI template
11
- *
12
- * @param string $template URI template
13
- * @param array $variables Template variables
14
- *
15
- * @return string
16
- */
17
- function uri_template($template, array $variables)
18
- {
19
- if (extension_loaded('uri_template')) {
20
- // @codeCoverageIgnoreStart
21
- return \uri_template($template, $variables);
22
- // @codeCoverageIgnoreEnd
23
- }
24
-
25
- static $uriTemplate;
26
- if (!$uriTemplate) {
27
- $uriTemplate = new UriTemplate();
28
- }
29
-
30
- return $uriTemplate->expand($template, $variables);
31
- }
32
-
33
- /**
34
- * Debug function used to describe the provided value type and class.
35
- *
36
- * @param mixed $input
37
- *
38
- * @return string Returns a string containing the type of the variable and
39
- * if a class is provided, the class name.
40
- */
41
- function describe_type($input)
42
- {
43
- switch (gettype($input)) {
44
- case 'object':
45
- return 'object(' . get_class($input) . ')';
46
- case 'array':
47
- return 'array(' . count($input) . ')';
48
- default:
49
- ob_start();
50
- var_dump($input);
51
- // normalize float vs double
52
- return str_replace('double(', 'float(', rtrim(ob_get_clean()));
53
- }
54
- }
55
-
56
- /**
57
- * Parses an array of header lines into an associative array of headers.
58
- *
59
- * @param array $lines Header lines array of strings in the following
60
- * format: "Name: Value"
61
- * @return array
62
- */
63
- function headers_from_lines($lines)
64
- {
65
- $headers = [];
66
-
67
- foreach ($lines as $line) {
68
- $parts = explode(':', $line, 2);
69
- $headers[trim($parts[0])][] = isset($parts[1])
70
- ? trim($parts[1])
71
- : null;
72
- }
73
-
74
- return $headers;
75
- }
76
-
77
- /**
78
- * Returns a debug stream based on the provided variable.
79
- *
80
- * @param mixed $value Optional value
81
- *
82
- * @return resource
83
- */
84
- function debug_resource($value = null)
85
- {
86
- if (is_resource($value)) {
87
- return $value;
88
- } elseif (defined('STDOUT')) {
89
- return STDOUT;
90
- }
91
-
92
- return fopen('php://output', 'w');
93
- }
94
-
95
- /**
96
- * Chooses and creates a default handler to use based on the environment.
97
- *
98
- * The returned handler is not wrapped by any default middlewares.
99
- *
100
- * @throws \RuntimeException if no viable Handler is available.
101
- * @return callable Returns the best handler for the given system.
102
- */
103
- function choose_handler()
104
- {
105
- $handler = null;
106
- if (function_exists('curl_multi_exec') && function_exists('curl_exec')) {
107
- $handler = Proxy::wrapSync(new CurlMultiHandler(), new CurlHandler());
108
- } elseif (function_exists('curl_exec')) {
109
- $handler = new CurlHandler();
110
- } elseif (function_exists('curl_multi_exec')) {
111
- $handler = new CurlMultiHandler();
112
- }
113
-
114
- if (ini_get('allow_url_fopen')) {
115
- $handler = $handler
116
- ? Proxy::wrapStreaming($handler, new StreamHandler())
117
- : new StreamHandler();
118
- } elseif (!$handler) {
119
- throw new \RuntimeException('GuzzleHttp requires cURL, the '
120
- . 'allow_url_fopen ini setting, or a custom HTTP handler.');
121
- }
122
-
123
- return $handler;
124
- }
125
-
126
- /**
127
- * Get the default User-Agent string to use with Guzzle
128
- *
129
- * @return string
130
- */
131
- function default_user_agent()
132
- {
133
- static $defaultAgent = '';
134
-
135
- if (!$defaultAgent) {
136
- $defaultAgent = 'GuzzleHttp/' . Client::VERSION;
137
- if (extension_loaded('curl') && function_exists('curl_version')) {
138
- $defaultAgent .= ' curl/' . \curl_version()['version'];
139
- }
140
- $defaultAgent .= ' PHP/' . PHP_VERSION;
141
- }
142
-
143
- return $defaultAgent;
144
- }
145
-
146
- /**
147
- * Returns the default cacert bundle for the current system.
148
- *
149
- * First, the openssl.cafile and curl.cainfo php.ini settings are checked.
150
- * If those settings are not configured, then the common locations for
151
- * bundles found on Red Hat, CentOS, Fedora, Ubuntu, Debian, FreeBSD, OS X
152
- * and Windows are checked. If any of these file locations are found on
153
- * disk, they will be utilized.
154
- *
155
- * Note: the result of this function is cached for subsequent calls.
156
- *
157
- * @return string
158
- * @throws \RuntimeException if no bundle can be found.
159
- */
160
- function default_ca_bundle()
161
- {
162
- static $cached = null;
163
- static $cafiles = [
164
- // Red Hat, CentOS, Fedora (provided by the ca-certificates package)
165
- '/etc/pki/tls/certs/ca-bundle.crt',
166
- // Ubuntu, Debian (provided by the ca-certificates package)
167
- '/etc/ssl/certs/ca-certificates.crt',
168
- // FreeBSD (provided by the ca_root_nss package)
169
- '/usr/local/share/certs/ca-root-nss.crt',
170
- // SLES 12 (provided by the ca-certificates package)
171
- '/var/lib/ca-certificates/ca-bundle.pem',
172
- // OS X provided by homebrew (using the default path)
173
- '/usr/local/etc/openssl/cert.pem',
174
- // Google app engine
175
- '/etc/ca-certificates.crt',
176
- // Windows?
177
- 'C:\\windows\\system32\\curl-ca-bundle.crt',
178
- 'C:\\windows\\curl-ca-bundle.crt',
179
- ];
180
-
181
- if ($cached) {
182
- return $cached;
183
- }
184
-
185
- if ($ca = ini_get('openssl.cafile')) {
186
- return $cached = $ca;
187
- }
188
-
189
- if ($ca = ini_get('curl.cainfo')) {
190
- return $cached = $ca;
191
- }
192
-
193
- foreach ($cafiles as $filename) {
194
- if (file_exists($filename)) {
195
- return $cached = $filename;
196
- }
197
- }
198
-
199
- throw new \RuntimeException(<<< EOT
200
- No system CA bundle could be found in any of the the common system locations.
201
- PHP versions earlier than 5.6 are not properly configured to use the system's
202
- CA bundle by default. In order to verify peer certificates, you will need to
203
- supply the path on disk to a certificate bundle to the 'verify' request
204
- option: http://docs.guzzlephp.org/en/latest/clients.html#verify. If you do not
205
- need a specific certificate bundle, then Mozilla provides a commonly used CA
206
- bundle which can be downloaded here (provided by the maintainer of cURL):
207
- https://raw.githubusercontent.com/bagder/ca-bundle/master/ca-bundle.crt. Once
208
- you have a CA bundle available on disk, you can set the 'openssl.cafile' PHP
209
- ini setting to point to the path to the file, allowing you to omit the 'verify'
210
- request option. See http://curl.haxx.se/docs/sslcerts.html for more
211
- information.
212
- EOT
213
- );
214
- }
215
-
216
- /**
217
- * Creates an associative array of lowercase header names to the actual
218
- * header casing.
219
- *
220
- * @param array $headers
221
- *
222
- * @return array
223
- */
224
- function normalize_header_keys(array $headers)
225
- {
226
- $result = [];
227
- foreach (array_keys($headers) as $key) {
228
- $result[strtolower($key)] = $key;
229
- }
230
-
231
- return $result;
232
- }
233
-
234
- /**
235
- * Returns true if the provided host matches any of the no proxy areas.
236
- *
237
- * This method will strip a port from the host if it is present. Each pattern
238
- * can be matched with an exact match (e.g., "foo.com" == "foo.com") or a
239
- * partial match: (e.g., "foo.com" == "baz.foo.com" and ".foo.com" ==
240
- * "baz.foo.com", but ".foo.com" != "foo.com").
241
- *
242
- * Areas are matched in the following cases:
243
- * 1. "*" (without quotes) always matches any hosts.
244
- * 2. An exact match.
245
- * 3. The area starts with "." and the area is the last part of the host. e.g.
246
- * '.mit.edu' will match any host that ends with '.mit.edu'.
247
- *
248
- * @param string $host Host to check against the patterns.
249
- * @param array $noProxyArray An array of host patterns.
250
- *
251
- * @return bool
252
- */
253
- function is_host_in_noproxy($host, array $noProxyArray)
254
- {
255
- if (strlen($host) === 0) {
256
- throw new \InvalidArgumentException('Empty host provided');
257
- }
258
-
259
- // Strip port if present.
260
- if (strpos($host, ':')) {
261
- $host = explode($host, ':', 2)[0];
262
- }
263
-
264
- foreach ($noProxyArray as $area) {
265
- // Always match on wildcards.
266
- if ($area === '*') {
267
- return true;
268
- } elseif (empty($area)) {
269
- // Don't match on empty values.
270
- continue;
271
- } elseif ($area === $host) {
272
- // Exact matches.
273
- return true;
274
- } else {
275
- // Special match if the area when prefixed with ".". Remove any
276
- // existing leading "." and add a new leading ".".
277
- $area = '.' . ltrim($area, '.');
278
- if (substr($host, -(strlen($area))) === $area) {
279
- return true;
280
- }
281
- }
282
- }
283
-
284
- return false;
285
- }
286
-
287
- /**
288
- * Wrapper for json_decode that throws when an error occurs.
289
- *
290
- * @param string $json JSON data to parse
291
- * @param bool $assoc When true, returned objects will be converted
292
- * into associative arrays.
293
- * @param int $depth User specified recursion depth.
294
- * @param int $options Bitmask of JSON decode options.
295
- *
296
- * @return mixed
297
- * @throws \InvalidArgumentException if the JSON cannot be decoded.
298
- * @link http://www.php.net/manual/en/function.json-decode.php
299
- */
300
- function json_decode($json, $assoc = false, $depth = 512, $options = 0)
301
- {
302
- $data = \json_decode($json, $assoc, $depth, $options);
303
- if (JSON_ERROR_NONE !== json_last_error()) {
304
- throw new \InvalidArgumentException(
305
- 'json_decode error: ' . json_last_error_msg()
306
- );
307
- }
308
-
309
- return $data;
310
- }
311
-
312
- /**
313
- * Wrapper for JSON encoding that throws when an error occurs.
314
- *
315
- * @param mixed $value The value being encoded
316
- * @param int $options JSON encode option bitmask
317
- * @param int $depth Set the maximum depth. Must be greater than zero.
318
- *
319
- * @return string
320
- * @throws \InvalidArgumentException if the JSON cannot be encoded.
321
- * @link http://www.php.net/manual/en/function.json-encode.php
322
- */
323
- function json_encode($value, $options = 0, $depth = 512)
324
- {
325
- $json = \json_encode($value, $options, $depth);
326
- if (JSON_ERROR_NONE !== json_last_error()) {
327
- throw new \InvalidArgumentException(
328
- 'json_encode error: ' . json_last_error_msg()
329
- );
330
- }
331
-
332
- return $json;
333
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/guzzle/src/functions_include.php DELETED
@@ -1,6 +0,0 @@
1
- <?php
2
-
3
- // Don't redefine the functions if included multiple times.
4
- if (!function_exists('GuzzleHttp\uri_template')) {
5
- require __DIR__ . '/functions.php';
6
- }
 
 
 
 
 
 
vendor/guzzlehttp/promises/CHANGELOG.md DELETED
@@ -1,65 +0,0 @@
1
- # CHANGELOG
2
-
3
-
4
- ## 1.3.1 - 2016-12-20
5
-
6
- ### Fixed
7
-
8
- - `wait()` foreign promise compatibility
9
-
10
-
11
- ## 1.3.0 - 2016-11-18
12
-
13
- ### Added
14
-
15
- - Adds support for custom task queues.
16
-
17
- ### Fixed
18
-
19
- - Fixed coroutine promise memory leak.
20
-
21
-
22
- ## 1.2.0 - 2016-05-18
23
-
24
- ### Changed
25
-
26
- - Update to now catch `\Throwable` on PHP 7+
27
-
28
-
29
- ## 1.1.0 - 2016-03-07
30
-
31
- ### Changed
32
-
33
- - Update EachPromise to prevent recurring on a iterator when advancing, as this
34
- could trigger fatal generator errors.
35
- - Update Promise to allow recursive waiting without unwrapping exceptions.
36
-
37
-
38
- ## 1.0.3 - 2015-10-15
39
-
40
- ### Changed
41
-
42
- - Update EachPromise to immediately resolve when the underlying promise iterator
43
- is empty. Previously, such a promise would throw an exception when its `wait`
44
- function was called.
45
-
46
-
47
- ## 1.0.2 - 2015-05-15
48
-
49
- ### Changed
50
-
51
- - Conditionally require functions.php.
52
-
53
-
54
- ## 1.0.1 - 2015-06-24
55
-
56
- ### Changed
57
-
58
- - Updating EachPromise to call next on the underlying promise iterator as late
59
- as possible to ensure that generators that generate new requests based on
60
- callbacks are not iterated until after callbacks are invoked.
61
-
62
-
63
- ## 1.0.0 - 2015-05-12
64
-
65
- - Initial release
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/promises/LICENSE DELETED
@@ -1,19 +0,0 @@
1
- Copyright (c) 2015-2016 Michael Dowling, https://github.com/mtdowling <mtdowling@gmail.com>
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining a copy
4
- of this software and associated documentation files (the "Software"), to deal
5
- in the Software without restriction, including without limitation the rights
6
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
- copies of the Software, and to permit persons to whom the Software is
8
- furnished to do so, subject to the following conditions:
9
-
10
- The above copyright notice and this permission notice shall be included in
11
- all copies or substantial portions of the Software.
12
-
13
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
- THE SOFTWARE.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/promises/Makefile DELETED
@@ -1,13 +0,0 @@
1
- all: clean test
2
-
3
- test:
4
- vendor/bin/phpunit
5
-
6
- coverage:
7
- vendor/bin/phpunit --coverage-html=artifacts/coverage
8
-
9
- view-coverage:
10
- open artifacts/coverage/index.html
11
-
12
- clean:
13
- rm -rf artifacts/*
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/promises/README.md DELETED
@@ -1,504 +0,0 @@
1
- # Guzzle Promises
2
-
3
- [Promises/A+](https://promisesaplus.com/) implementation that handles promise
4
- chaining and resolution iteratively, allowing for "infinite" promise chaining
5
- while keeping the stack size constant. Read [this blog post](https://blog.domenic.me/youre-missing-the-point-of-promises/)
6
- for a general introduction to promises.
7
-
8
- - [Features](#features)
9
- - [Quick start](#quick-start)
10
- - [Synchronous wait](#synchronous-wait)
11
- - [Cancellation](#cancellation)
12
- - [API](#api)
13
- - [Promise](#promise)
14
- - [FulfilledPromise](#fulfilledpromise)
15
- - [RejectedPromise](#rejectedpromise)
16
- - [Promise interop](#promise-interop)
17
- - [Implementation notes](#implementation-notes)
18
-
19
-
20
- # Features
21
-
22
- - [Promises/A+](https://promisesaplus.com/) implementation.
23
- - Promise resolution and chaining is handled iteratively, allowing for
24
- "infinite" promise chaining.
25
- - Promises have a synchronous `wait` method.
26
- - Promises can be cancelled.
27
- - Works with any object that has a `then` function.
28
- - C# style async/await coroutine promises using
29
- `GuzzleHttp\Promise\coroutine()`.
30
-
31
-
32
- # Quick start
33
-
34
- A *promise* represents the eventual result of an asynchronous operation. The
35
- primary way of interacting with a promise is through its `then` method, which
36
- registers callbacks to receive either a promise's eventual value or the reason
37
- why the promise cannot be fulfilled.
38
-
39
-
40
- ## Callbacks
41
-
42
- Callbacks are registered with the `then` method by providing an optional
43
- `$onFulfilled` followed by an optional `$onRejected` function.
44
-
45
-
46
- ```php
47
- use GuzzleHttp\Promise\Promise;
48
-
49
- $promise = new Promise();
50
- $promise->then(
51
- // $onFulfilled
52
- function ($value) {
53
- echo 'The promise was fulfilled.';
54
- },
55
- // $onRejected
56
- function ($reason) {
57
- echo 'The promise was rejected.';
58
- }
59
- );
60
- ```
61
-
62
- *Resolving* a promise means that you either fulfill a promise with a *value* or
63
- reject a promise with a *reason*. Resolving a promises triggers callbacks
64
- registered with the promises's `then` method. These callbacks are triggered
65
- only once and in the order in which they were added.
66
-
67
-
68
- ## Resolving a promise
69
-
70
- Promises are fulfilled using the `resolve($value)` method. Resolving a promise
71
- with any value other than a `GuzzleHttp\Promise\RejectedPromise` will trigger
72
- all of the onFulfilled callbacks (resolving a promise with a rejected promise
73
- will reject the promise and trigger the `$onRejected` callbacks).
74
-
75
- ```php
76
- use GuzzleHttp\Promise\Promise;
77
-
78
- $promise = new Promise();
79
- $promise
80
- ->then(function ($value) {
81
- // Return a value and don't break the chain
82
- return "Hello, " . $value;
83
- })
84
- // This then is executed after the first then and receives the value
85
- // returned from the first then.
86
- ->then(function ($value) {
87
- echo $value;
88
- });
89
-
90
- // Resolving the promise triggers the $onFulfilled callbacks and outputs
91
- // "Hello, reader".
92
- $promise->resolve('reader.');
93
- ```
94
-
95
-
96
- ## Promise forwarding
97
-
98
- Promises can be chained one after the other. Each then in the chain is a new
99
- promise. The return value of a promise is what's forwarded to the next
100
- promise in the chain. Returning a promise in a `then` callback will cause the
101
- subsequent promises in the chain to only be fulfilled when the returned promise
102
- has been fulfilled. The next promise in the chain will be invoked with the
103
- resolved value of the promise.
104
-
105
- ```php
106
- use GuzzleHttp\Promise\Promise;
107
-
108
- $promise = new Promise();
109
- $nextPromise = new Promise();
110
-
111
- $promise
112
- ->then(function ($value) use ($nextPromise) {
113
- echo $value;
114
- return $nextPromise;
115
- })
116
- ->then(function ($value) {
117
- echo $value;
118
- });
119
-
120
- // Triggers the first callback and outputs "A"
121
- $promise->resolve('A');
122
- // Triggers the second callback and outputs "B"
123
- $nextPromise->resolve('B');
124
- ```
125
-
126
- ## Promise rejection
127
-
128
- When a promise is rejected, the `$onRejected` callbacks are invoked with the
129
- rejection reason.
130
-
131
- ```php
132
- use GuzzleHttp\Promise\Promise;
133
-
134
- $promise = new Promise();
135
- $promise->then(null, function ($reason) {
136
- echo $reason;
137
- });
138
-
139
- $promise->reject('Error!');
140
- // Outputs "Error!"
141
- ```
142
-
143
- ## Rejection forwarding
144
-
145
- If an exception is thrown in an `$onRejected` callback, subsequent
146
- `$onRejected` callbacks are invoked with the thrown exception as the reason.
147
-
148
- ```php
149
- use GuzzleHttp\Promise\Promise;
150
-
151
- $promise = new Promise();
152
- $promise->then(null, function ($reason) {
153
- throw new \Exception($reason);
154
- })->then(null, function ($reason) {
155
- assert($reason->getMessage() === 'Error!');
156
- });
157
-
158
- $promise->reject('Error!');
159
- ```
160
-
161
- You can also forward a rejection down the promise chain by returning a
162
- `GuzzleHttp\Promise\RejectedPromise` in either an `$onFulfilled` or
163
- `$onRejected` callback.
164
-
165
- ```php
166
- use GuzzleHttp\Promise\Promise;
167
- use GuzzleHttp\Promise\RejectedPromise;
168
-
169
- $promise = new Promise();
170
- $promise->then(null, function ($reason) {
171
- return new RejectedPromise($reason);
172
- })->then(null, function ($reason) {
173
- assert($reason === 'Error!');
174
- });
175
-
176
- $promise->reject('Error!');
177
- ```
178
-
179
- If an exception is not thrown in a `$onRejected` callback and the callback
180
- does not return a rejected promise, downstream `$onFulfilled` callbacks are
181
- invoked using the value returned from the `$onRejected` callback.
182
-
183
- ```php
184
- use GuzzleHttp\Promise\Promise;
185
- use GuzzleHttp\Promise\RejectedPromise;
186
-
187
- $promise = new Promise();
188
- $promise
189
- ->then(null, function ($reason) {
190
- return "It's ok";
191
- })
192
- ->then(function ($value) {
193
- assert($value === "It's ok");
194
- });
195
-
196
- $promise->reject('Error!');
197
- ```
198
-
199
- # Synchronous wait
200
-
201
- You can synchronously force promises to complete using a promise's `wait`
202
- method. When creating a promise, you can provide a wait function that is used
203
- to synchronously force a promise to complete. When a wait function is invoked
204
- it is expected to deliver a value to the promise or reject the promise. If the
205
- wait function does not deliver a value, then an exception is thrown. The wait
206
- function provided to a promise constructor is invoked when the `wait` function
207
- of the promise is called.
208
-
209
- ```php
210
- $promise = new Promise(function () use (&$promise) {
211
- $promise->resolve('foo');
212
- });
213
-
214
- // Calling wait will return the value of the promise.
215
- echo $promise->wait(); // outputs "foo"
216
- ```
217
-
218
- If an exception is encountered while invoking the wait function of a promise,
219
- the promise is rejected with the exception and the exception is thrown.
220
-
221
- ```php
222
- $promise = new Promise(function () use (&$promise) {
223
- throw new \Exception('foo');
224
- });
225
-
226
- $promise->wait(); // throws the exception.
227
- ```
228
-
229
- Calling `wait` on a promise that has been fulfilled will not trigger the wait
230
- function. It will simply return the previously resolved value.
231
-
232
- ```php
233
- $promise = new Promise(function () { die('this is not called!'); });
234
- $promise->resolve('foo');
235
- echo $promise->wait(); // outputs "foo"
236
- ```
237
-
238
- Calling `wait` on a promise that has been rejected will throw an exception. If
239
- the rejection reason is an instance of `\Exception` the reason is thrown.
240
- Otherwise, a `GuzzleHttp\Promise\RejectionException` is thrown and the reason
241
- can be obtained by calling the `getReason` method of the exception.
242
-
243
- ```php
244
- $promise = new Promise();
245
- $promise->reject('foo');
246
- $promise->wait();
247
- ```
248
-
249
- > PHP Fatal error: Uncaught exception 'GuzzleHttp\Promise\RejectionException' with message 'The promise was rejected with value: foo'
250
-
251
-
252
- ## Unwrapping a promise
253
-
254
- When synchronously waiting on a promise, you are joining the state of the
255
- promise into the current state of execution (i.e., return the value of the
256
- promise if it was fulfilled or throw an exception if it was rejected). This is
257
- called "unwrapping" the promise. Waiting on a promise will by default unwrap
258
- the promise state.
259
-
260
- You can force a promise to resolve and *not* unwrap the state of the promise
261
- by passing `false` to the first argument of the `wait` function:
262
-
263
- ```php
264
- $promise = new Promise();
265
- $promise->reject('foo');
266
- // This will not throw an exception. It simply ensures the promise has
267
- // been resolved.
268
- $promise->wait(false);
269
- ```
270
-
271
- When unwrapping a promise, the resolved value of the promise will be waited
272
- upon until the unwrapped value is not a promise. This means that if you resolve
273
- promise A with a promise B and unwrap promise A, the value returned by the
274
- wait function will be the value delivered to promise B.
275
-
276
- **Note**: when you do not unwrap the promise, no value is returned.
277
-
278
-
279
- # Cancellation
280
-
281
- You can cancel a promise that has not yet been fulfilled using the `cancel()`
282
- method of a promise. When creating a promise you can provide an optional
283
- cancel function that when invoked cancels the action of computing a resolution
284
- of the promise.
285
-
286
-
287
- # API
288
-
289
-
290
- ## Promise
291
-
292
- When creating a promise object, you can provide an optional `$waitFn` and
293
- `$cancelFn`. `$waitFn` is a function that is invoked with no arguments and is
294
- expected to resolve the promise. `$cancelFn` is a function with no arguments
295
- that is expected to cancel the computation of a promise. It is invoked when the
296
- `cancel()` method of a promise is called.
297
-
298
- ```php
299
- use GuzzleHttp\Promise\Promise;
300
-
301
- $promise = new Promise(
302
- function () use (&$promise) {
303
- $promise->resolve('waited');
304
- },
305
- function () {
306
- // do something that will cancel the promise computation (e.g., close
307
- // a socket, cancel a database query, etc...)
308
- }
309
- );
310
-
311
- assert('waited' === $promise->wait());
312
- ```
313
-
314
- A promise has the following methods:
315
-
316
- - `then(callable $onFulfilled, callable $onRejected) : PromiseInterface`
317
-
318
- Appends fulfillment and rejection handlers to the promise, and returns a new promise resolving to the return value of the called handler.
319
-
320
- - `otherwise(callable $onRejected) : PromiseInterface`
321
-
322
- Appends a rejection handler callback to the promise, and returns a new promise resolving to the return value of the callback if it is called, or to its original fulfillment value if the promise is instead fulfilled.
323
-
324
- - `wait($unwrap = true) : mixed`
325
-
326
- Synchronously waits on the promise to complete.
327
-
328
- `$unwrap` controls whether or not the value of the promise is returned for a
329
- fulfilled promise or if an exception is thrown if the promise is rejected.
330
- This is set to `true` by default.
331
-
332
- - `cancel()`
333
-
334
- Attempts to cancel the promise if possible. The promise being cancelled and
335
- the parent most ancestor that has not yet been resolved will also be
336
- cancelled. Any promises waiting on the cancelled promise to resolve will also
337
- be cancelled.
338
-
339
- - `getState() : string`
340
-
341
- Returns the state of the promise. One of `pending`, `fulfilled`, or
342
- `rejected`.
343
-
344
- - `resolve($value)`
345
-
346
- Fulfills the promise with the given `$value`.
347
-
348
- - `reject($reason)`
349
-
350
- Rejects the promise with the given `$reason`.
351
-
352
-
353
- ## FulfilledPromise
354
-
355
- A fulfilled promise can be created to represent a promise that has been
356
- fulfilled.
357
-
358
- ```php
359
- use GuzzleHttp\Promise\FulfilledPromise;
360
-
361
- $promise = new FulfilledPromise('value');
362
-
363
- // Fulfilled callbacks are immediately invoked.
364
- $promise->then(function ($value) {
365
- echo $value;
366
- });
367
- ```
368
-
369
-
370
- ## RejectedPromise
371
-
372
- A rejected promise can be created to represent a promise that has been
373
- rejected.
374
-
375
- ```php
376
- use GuzzleHttp\Promise\RejectedPromise;
377
-
378
- $promise = new RejectedPromise('Error');
379
-
380
- // Rejected callbacks are immediately invoked.
381
- $promise->then(null, function ($reason) {
382
- echo $reason;
383
- });
384
- ```
385
-
386
-
387
- # Promise interop
388
-
389
- This library works with foreign promises that have a `then` method. This means
390
- you can use Guzzle promises with [React promises](https://github.com/reactphp/promise)
391
- for example. When a foreign promise is returned inside of a then method
392
- callback, promise resolution will occur recursively.
393
-
394
- ```php
395
- // Create a React promise
396
- $deferred = new React\Promise\Deferred();
397
- $reactPromise = $deferred->promise();
398
-
399
- // Create a Guzzle promise that is fulfilled with a React promise.
400
- $guzzlePromise = new \GuzzleHttp\Promise\Promise();
401
- $guzzlePromise->then(function ($value) use ($reactPromise) {
402
- // Do something something with the value...
403
- // Return the React promise
404
- return $reactPromise;
405
- });
406
- ```
407
-
408
- Please note that wait and cancel chaining is no longer possible when forwarding
409
- a foreign promise. You will need to wrap a third-party promise with a Guzzle
410
- promise in order to utilize wait and cancel functions with foreign promises.
411
-
412
-
413
- ## Event Loop Integration
414
-
415
- In order to keep the stack size constant, Guzzle promises are resolved
416
- asynchronously using a task queue. When waiting on promises synchronously, the
417
- task queue will be automatically run to ensure that the blocking promise and
418
- any forwarded promises are resolved. When using promises asynchronously in an
419
- event loop, you will need to run the task queue on each tick of the loop. If
420
- you do not run the task queue, then promises will not be resolved.
421
-
422
- You can run the task queue using the `run()` method of the global task queue
423
- instance.
424
-
425
- ```php
426
- // Get the global task queue
427
- $queue = \GuzzleHttp\Promise\queue();
428
- $queue->run();
429
- ```
430
-
431
- For example, you could use Guzzle promises with React using a periodic timer:
432
-
433
- ```php
434
- $loop = React\EventLoop\Factory::create();
435
- $loop->addPeriodicTimer(0, [$queue, 'run']);
436
- ```
437
-
438
- *TODO*: Perhaps adding a `futureTick()` on each tick would be faster?
439
-
440
-
441
- # Implementation notes
442
-
443
-
444
- ## Promise resolution and chaining is handled iteratively
445
-
446
- By shuffling pending handlers from one owner to another, promises are
447
- resolved iteratively, allowing for "infinite" then chaining.
448
-
449
- ```php
450
- <?php
451
- require 'vendor/autoload.php';
452
-
453
- use GuzzleHttp\Promise\Promise;
454
-
455
- $parent = new Promise();
456
- $p = $parent;
457
-
458
- for ($i = 0; $i < 1000; $i++) {
459
- $p = $p->then(function ($v) {
460
- // The stack size remains constant (a good thing)
461
- echo xdebug_get_stack_depth() . ', ';
462
- return $v + 1;
463
- });
464
- }
465
-
466
- $parent->resolve(0);
467
- var_dump($p->wait()); // int(1000)
468
-
469
- ```
470
-
471
- When a promise is fulfilled or rejected with a non-promise value, the promise
472
- then takes ownership of the handlers of each child promise and delivers values
473
- down the chain without using recursion.
474
-
475
- When a promise is resolved with another promise, the original promise transfers
476
- all of its pending handlers to the new promise. When the new promise is
477
- eventually resolved, all of the pending handlers are delivered the forwarded
478
- value.
479
-
480
-
481
- ## A promise is the deferred.
482
-
483
- Some promise libraries implement promises using a deferred object to represent
484
- a computation and a promise object to represent the delivery of the result of
485
- the computation. This is a nice separation of computation and delivery because
486
- consumers of the promise cannot modify the value that will be eventually
487
- delivered.
488
-
489
- One side effect of being able to implement promise resolution and chaining
490
- iteratively is that you need to be able for one promise to reach into the state
491
- of another promise to shuffle around ownership of handlers. In order to achieve
492
- this without making the handlers of a promise publicly mutable, a promise is
493
- also the deferred value, allowing promises of the same parent class to reach
494
- into and modify the private properties of promises of the same type. While this
495
- does allow consumers of the value to modify the resolution or rejection of the
496
- deferred, it is a small price to pay for keeping the stack size constant.
497
-
498
- ```php
499
- $promise = new Promise();
500
- $promise->then(function ($value) { echo $value; });
501
- // The promise is the deferred value, so you can deliver a value to it.
502
- $promise->resolve('foo');
503
- // prints "foo"
504
- ```
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/promises/src/AggregateException.php DELETED
@@ -1,16 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Promise;
3
-
4
- /**
5
- * Exception thrown when too many errors occur in the some() or any() methods.
6
- */
7
- class AggregateException extends RejectionException
8
- {
9
- public function __construct($msg, array $reasons)
10
- {
11
- parent::__construct(
12
- $reasons,
13
- sprintf('%s; %d rejected promises', $msg, count($reasons))
14
- );
15
- }
16
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/promises/src/CancellationException.php DELETED
@@ -1,9 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Promise;
3
-
4
- /**
5
- * Exception that is set as the reason for a promise that has been cancelled.
6
- */
7
- class CancellationException extends RejectionException
8
- {
9
- }
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/promises/src/Coroutine.php DELETED
@@ -1,151 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Promise;
3
-
4
- use Exception;
5
- use Generator;
6
- use Throwable;
7
-
8
- /**
9
- * Creates a promise that is resolved using a generator that yields values or
10
- * promises (somewhat similar to C#'s async keyword).
11
- *
12
- * When called, the coroutine function will start an instance of the generator
13
- * and returns a promise that is fulfilled with its final yielded value.
14
- *
15
- * Control is returned back to the generator when the yielded promise settles.
16
- * This can lead to less verbose code when doing lots of sequential async calls
17
- * with minimal processing in between.
18
- *
19
- * use GuzzleHttp\Promise;
20
- *
21
- * function createPromise($value) {
22
- * return new Promise\FulfilledPromise($value);
23
- * }
24
- *
25
- * $promise = Promise\coroutine(function () {
26
- * $value = (yield createPromise('a'));
27
- * try {
28
- * $value = (yield createPromise($value . 'b'));
29
- * } catch (\Exception $e) {
30
- * // The promise was rejected.
31
- * }
32
- * yield $value . 'c';
33
- * });
34
- *
35
- * // Outputs "abc"
36
- * $promise->then(function ($v) { echo $v; });
37
- *
38
- * @param callable $generatorFn Generator function to wrap into a promise.
39
- *
40
- * @return Promise
41
- * @link https://github.com/petkaantonov/bluebird/blob/master/API.md#generators inspiration
42
- */
43
- final class Coroutine implements PromiseInterface
44
- {
45
- /**
46
- * @var PromiseInterface|null
47
- */
48
- private $currentPromise;
49
-
50
- /**
51
- * @var Generator
52
- */
53
- private $generator;
54
-
55
- /**
56
- * @var Promise
57
- */
58
- private $result;
59
-
60
- public function __construct(callable $generatorFn)
61
- {
62
- $this->generator = $generatorFn();
63
- $this->result = new Promise(function () {
64
- while (isset($this->currentPromise)) {
65
- $this->currentPromise->wait();
66
- }
67
- });
68
- $this->nextCoroutine($this->generator->current());
69
- }
70
-
71
- public function then(
72
- callable $onFulfilled = null,
73
- callable $onRejected = null
74
- ) {
75
- return $this->result->then($onFulfilled, $onRejected);
76
- }
77
-
78
- public function otherwise(callable $onRejected)
79
- {
80
- return $this->result->otherwise($onRejected);
81
- }
82
-
83
- public function wait($unwrap = true)
84
- {
85
- return $this->result->wait($unwrap);
86
- }
87
-
88
- public function getState()
89
- {
90
- return $this->result->getState();
91
- }
92
-
93
- public function resolve($value)
94
- {
95
- $this->result->resolve($value);
96
- }
97
-
98
- public function reject($reason)
99
- {
100
- $this->result->reject($reason);
101
- }
102
-
103
- public function cancel()
104
- {
105
- $this->currentPromise->cancel();
106
- $this->result->cancel();
107
- }
108
-
109
- private function nextCoroutine($yielded)
110
- {
111
- $this->currentPromise = promise_for($yielded)
112
- ->then([$this, '_handleSuccess'], [$this, '_handleFailure']);
113
- }
114
-
115
- /**
116
- * @internal
117
- */
118
- public function _handleSuccess($value)
119
- {
120
- unset($this->currentPromise);
121
- try {
122
- $next = $this->generator->send($value);
123
- if ($this->generator->valid()) {
124
- $this->nextCoroutine($next);
125
- } else {
126
- $this->result->resolve($value);
127
- }
128
- } catch (Exception $exception) {
129
- $this->result->reject($exception);
130
- } catch (Throwable $throwable) {
131
- $this->result->reject($throwable);
132
- }
133
- }
134
-
135
- /**
136
- * @internal
137
- */
138
- public function _handleFailure($reason)
139
- {
140
- unset($this->currentPromise);
141
- try {
142
- $nextYield = $this->generator->throw(exception_for($reason));
143
- // The throw was caught, so keep iterating on the coroutine
144
- $this->nextCoroutine($nextYield);
145
- } catch (Exception $exception) {
146
- $this->result->reject($exception);
147
- } catch (Throwable $throwable) {
148
- $this->result->reject($throwable);
149
- }
150
- }
151
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/promises/src/EachPromise.php DELETED
@@ -1,229 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Promise;
3
-
4
- /**
5
- * Represents a promise that iterates over many promises and invokes
6
- * side-effect functions in the process.
7
- */
8
- class EachPromise implements PromisorInterface
9
- {
10
- private $pending = [];
11
-
12
- /** @var \Iterator */
13
- private $iterable;
14
-
15
- /** @var callable|int */
16
- private $concurrency;
17
-
18
- /** @var callable */
19
- private $onFulfilled;
20
-
21
- /** @var callable */
22
- private $onRejected;
23
-
24
- /** @var Promise */
25
- private $aggregate;
26
-
27
- /** @var bool */
28
- private $mutex;
29
-
30
- /**
31
- * Configuration hash can include the following key value pairs:
32
- *
33
- * - fulfilled: (callable) Invoked when a promise fulfills. The function
34
- * is invoked with three arguments: the fulfillment value, the index
35
- * position from the iterable list of the promise, and the aggregate
36
- * promise that manages all of the promises. The aggregate promise may
37
- * be resolved from within the callback to short-circuit the promise.
38
- * - rejected: (callable) Invoked when a promise is rejected. The
39
- * function is invoked with three arguments: the rejection reason, the
40
- * index position from the iterable list of the promise, and the
41
- * aggregate promise that manages all of the promises. The aggregate
42
- * promise may be resolved from within the callback to short-circuit
43
- * the promise.
44
- * - concurrency: (integer) Pass this configuration option to limit the
45
- * allowed number of outstanding concurrently executing promises,
46
- * creating a capped pool of promises. There is no limit by default.
47
- *
48
- * @param mixed $iterable Promises or values to iterate.
49
- * @param array $config Configuration options
50
- */
51
- public function __construct($iterable, array $config = [])
52
- {
53
- $this->iterable = iter_for($iterable);
54
-
55
- if (isset($config['concurrency'])) {
56
- $this->concurrency = $config['concurrency'];
57
- }
58
-
59
- if (isset($config['fulfilled'])) {
60
- $this->onFulfilled = $config['fulfilled'];
61
- }
62
-
63
- if (isset($config['rejected'])) {
64
- $this->onRejected = $config['rejected'];
65
- }
66
- }
67
-
68
- public function promise()
69
- {
70
- if ($this->aggregate) {
71
- return $this->aggregate;
72
- }
73
-
74
- try {
75
- $this->createPromise();
76
- $this->iterable->rewind();
77
- $this->refillPending();
78
- } catch (\Throwable $e) {
79
- $this->aggregate->reject($e);
80
- } catch (\Exception $e) {
81
- $this->aggregate->reject($e);
82
- }
83
-
84
- return $this->aggregate;
85
- }
86
-
87
- private function createPromise()
88
- {
89
- $this->mutex = false;
90
- $this->aggregate = new Promise(function () {
91
- reset($this->pending);
92
- if (empty($this->pending) && !$this->iterable->valid()) {
93
- $this->aggregate->resolve(null);
94
- return;
95
- }
96
-
97
- // Consume a potentially fluctuating list of promises while
98
- // ensuring that indexes are maintained (precluding array_shift).
99
- while ($promise = current($this->pending)) {
100
- next($this->pending);
101
- $promise->wait();
102
- if ($this->aggregate->getState() !== PromiseInterface::PENDING) {
103
- return;
104
- }
105
- }
106
- });
107
-
108
- // Clear the references when the promise is resolved.
109
- $clearFn = function () {
110
- $this->iterable = $this->concurrency = $this->pending = null;
111
- $this->onFulfilled = $this->onRejected = null;
112
- };
113
-
114
- $this->aggregate->then($clearFn, $clearFn);
115
- }
116
-
117
- private function refillPending()
118
- {
119
- if (!$this->concurrency) {
120
- // Add all pending promises.
121
- while ($this->addPending() && $this->advanceIterator());
122
- return;
123
- }
124
-
125
- // Add only up to N pending promises.
126
- $concurrency = is_callable($this->concurrency)
127
- ? call_user_func($this->concurrency, count($this->pending))
128
- : $this->concurrency;
129
- $concurrency = max($concurrency - count($this->pending), 0);
130
- // Concurrency may be set to 0 to disallow new promises.
131
- if (!$concurrency) {
132
- return;
133
- }
134
- // Add the first pending promise.
135
- $this->addPending();
136
- // Note this is special handling for concurrency=1 so that we do
137
- // not advance the iterator after adding the first promise. This
138
- // helps work around issues with generators that might not have the
139
- // next value to yield until promise callbacks are called.
140
- while (--$concurrency
141
- && $this->advanceIterator()
142
- && $this->addPending());
143
- }
144
-
145
- private function addPending()
146
- {
147
- if (!$this->iterable || !$this->iterable->valid()) {
148
- return false;
149
- }
150
-
151
- $promise = promise_for($this->iterable->current());
152
- $idx = $this->iterable->key();
153
-
154
- $this->pending[$idx] = $promise->then(
155
- function ($value) use ($idx) {
156
- if ($this->onFulfilled) {
157
- call_user_func(
158
- $this->onFulfilled, $value, $idx, $this->aggregate
159
- );
160
- }
161
- $this->step($idx);
162
- },
163
- function ($reason) use ($idx) {
164
- if ($this->onRejected) {
165
- call_user_func(
166
- $this->onRejected, $reason, $idx, $this->aggregate
167
- );
168
- }
169
- $this->step($idx);
170
- }
171
- );
172
-
173
- return true;
174
- }
175
-
176
- private function advanceIterator()
177
- {
178
- // Place a lock on the iterator so that we ensure to not recurse,
179
- // preventing fatal generator errors.
180
- if ($this->mutex) {
181
- return false;
182
- }
183
-
184
- $this->mutex = true;
185
-
186
- try {
187
- $this->iterable->next();
188
- $this->mutex = false;
189
- return true;
190
- } catch (\Throwable $e) {
191
- $this->aggregate->reject($e);
192
- $this->mutex = false;
193
- return false;
194
- } catch (\Exception $e) {
195
- $this->aggregate->reject($e);
196
- $this->mutex = false;
197
- return false;
198
- }
199
- }
200
-
201
- private function step($idx)
202
- {
203
- // If the promise was already resolved, then ignore this step.
204
- if ($this->aggregate->getState() !== PromiseInterface::PENDING) {
205
- return;
206
- }
207
-
208
- unset($this->pending[$idx]);
209
-
210
- // Only refill pending promises if we are not locked, preventing the
211
- // EachPromise to recursively invoke the provided iterator, which
212
- // cause a fatal error: "Cannot resume an already running generator"
213
- if ($this->advanceIterator() && !$this->checkIfFinished()) {
214
- // Add more pending promises if possible.
215
- $this->refillPending();
216
- }
217
- }
218
-
219
- private function checkIfFinished()
220
- {
221
- if (!$this->pending && !$this->iterable->valid()) {
222
- // Resolve the promise if there's nothing left to do.
223
- $this->aggregate->resolve(null);
224
- return true;
225
- }
226
-
227
- return false;
228
- }
229
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/promises/src/FulfilledPromise.php DELETED
@@ -1,82 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Promise;
3
-
4
- /**
5
- * A promise that has been fulfilled.
6
- *
7
- * Thenning off of this promise will invoke the onFulfilled callback
8
- * immediately and ignore other callbacks.
9
- */
10
- class FulfilledPromise implements PromiseInterface
11
- {
12
- private $value;
13
-
14
- public function __construct($value)
15
- {
16
- if (method_exists($value, 'then')) {
17
- throw new \InvalidArgumentException(
18
- 'You cannot create a FulfilledPromise with a promise.');
19
- }
20
-
21
- $this->value = $value;
22
- }
23
-
24
- public function then(
25
- callable $onFulfilled = null,
26
- callable $onRejected = null
27
- ) {
28
- // Return itself if there is no onFulfilled function.
29
- if (!$onFulfilled) {
30
- return $this;
31
- }
32
-
33
- $queue = queue();
34
- $p = new Promise([$queue, 'run']);
35
- $value = $this->value;
36
- $queue->add(static function () use ($p, $value, $onFulfilled) {
37
- if ($p->getState() === self::PENDING) {
38
- try {
39
- $p->resolve($onFulfilled($value));
40
- } catch (\Throwable $e) {
41
- $p->reject($e);
42
- } catch (\Exception $e) {
43
- $p->reject($e);
44
- }
45
- }
46
- });
47
-
48
- return $p;
49
- }
50
-
51
- public function otherwise(callable $onRejected)
52
- {
53
- return $this->then(null, $onRejected);
54
- }
55
-
56
- public function wait($unwrap = true, $defaultDelivery = null)
57
- {
58
- return $unwrap ? $this->value : null;
59
- }
60
-
61
- public function getState()
62
- {
63
- return self::FULFILLED;
64
- }
65
-
66
- public function resolve($value)
67
- {
68
- if ($value !== $this->value) {
69
- throw new \LogicException("Cannot resolve a fulfilled promise");
70
- }
71
- }
72
-
73
- public function reject($reason)
74
- {
75
- throw new \LogicException("Cannot reject a fulfilled promise");
76
- }
77
-
78
- public function cancel()
79
- {
80
- // pass
81
- }
82
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/promises/src/Promise.php DELETED
@@ -1,280 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Promise;
3
-
4
- /**
5
- * Promises/A+ implementation that avoids recursion when possible.
6
- *
7
- * @link https://promisesaplus.com/
8
- */
9
- class Promise implements PromiseInterface
10
- {
11
- private $state = self::PENDING;
12
- private $result;
13
- private $cancelFn;
14
- private $waitFn;
15
- private $waitList;
16
- private $handlers = [];
17
-
18
- /**
19
- * @param callable $waitFn Fn that when invoked resolves the promise.
20
- * @param callable $cancelFn Fn that when invoked cancels the promise.
21
- */
22
- public function __construct(
23
- callable $waitFn = null,
24
- callable $cancelFn = null
25
- ) {
26
- $this->waitFn = $waitFn;
27
- $this->cancelFn = $cancelFn;
28
- }
29
-
30
- public function then(
31
- callable $onFulfilled = null,
32
- callable $onRejected = null
33
- ) {
34
- if ($this->state === self::PENDING) {
35
- $p = new Promise(null, [$this, 'cancel']);
36
- $this->handlers[] = [$p, $onFulfilled, $onRejected];
37
- $p->waitList = $this->waitList;
38
- $p->waitList[] = $this;
39
- return $p;
40
- }
41
-
42
- // Return a fulfilled promise and immediately invoke any callbacks.
43
- if ($this->state === self::FULFILLED) {
44
- return $onFulfilled
45
- ? promise_for($this->result)->then($onFulfilled)
46
- : promise_for($this->result);
47
- }
48
-
49
- // It's either cancelled or rejected, so return a rejected promise
50
- // and immediately invoke any callbacks.
51
- $rejection = rejection_for($this->result);
52
- return $onRejected ? $rejection->then(null, $onRejected) : $rejection;
53
- }
54
-
55
- public function otherwise(callable $onRejected)
56
- {
57
- return $this->then(null, $onRejected);
58
- }
59
-
60
- public function wait($unwrap = true)
61
- {
62
- $this->waitIfPending();
63
-
64
- $inner = $this->result instanceof PromiseInterface
65
- ? $this->result->wait($unwrap)
66
- : $this->result;
67
-
68
- if ($unwrap) {
69
- if ($this->result instanceof PromiseInterface
70
- || $this->state === self::FULFILLED
71
- ) {
72
- return $inner;
73
- } else {
74
- // It's rejected so "unwrap" and throw an exception.
75
- throw exception_for($inner);
76
- }
77
- }
78
- }
79
-
80
- public function getState()
81
- {
82
- return $this->state;
83
- }
84
-
85
- public function cancel()
86
- {
87
- if ($this->state !== self::PENDING) {
88
- return;
89
- }
90
-
91
- $this->waitFn = $this->waitList = null;
92
-
93
- if ($this->cancelFn) {
94
- $fn = $this->cancelFn;
95
- $this->cancelFn = null;
96
- try {
97
- $fn();
98
- } catch (\Throwable $e) {
99
- $this->reject($e);
100
- } catch (\Exception $e) {
101
- $this->reject($e);
102
- }
103
- }
104
-
105
- // Reject the promise only if it wasn't rejected in a then callback.
106
- if ($this->state === self::PENDING) {
107
- $this->reject(new CancellationException('Promise has been cancelled'));
108
- }
109
- }
110
-
111
- public function resolve($value)
112
- {
113
- $this->settle(self::FULFILLED, $value);
114
- }
115
-
116
- public function reject($reason)
117
- {
118
- $this->settle(self::REJECTED, $reason);
119
- }
120
-
121
- private function settle($state, $value)
122
- {
123
- if ($this->state !== self::PENDING) {
124
- // Ignore calls with the same resolution.
125
- if ($state === $this->state && $value === $this->result) {
126
- return;
127
- }
128
- throw $this->state === $state
129
- ? new \LogicException("The promise is already {$state}.")
130
- : new \LogicException("Cannot change a {$this->state} promise to {$state}");
131
- }
132
-
133
- if ($value === $this) {
134
- throw new \LogicException('Cannot fulfill or reject a promise with itself');
135
- }
136
-
137
- // Clear out the state of the promise but stash the handlers.
138
- $this->state = $state;
139
- $this->result = $value;
140
- $handlers = $this->handlers;
141
- $this->handlers = null;
142
- $this->waitList = $this->waitFn = null;
143
- $this->cancelFn = null;
144
-
145
- if (!$handlers) {
146
- return;
147
- }
148
-
149
- // If the value was not a settled promise or a thenable, then resolve
150
- // it in the task queue using the correct ID.
151
- if (!method_exists($value, 'then')) {
152
- $id = $state === self::FULFILLED ? 1 : 2;
153
- // It's a success, so resolve the handlers in the queue.
154
- queue()->add(static function () use ($id, $value, $handlers) {
155
- foreach ($handlers as $handler) {
156
- self::callHandler($id, $value, $handler);
157
- }
158
- });
159
- } elseif ($value instanceof Promise
160
- && $value->getState() === self::PENDING
161
- ) {
162
- // We can just merge our handlers onto the next promise.
163
- $value->handlers = array_merge($value->handlers, $handlers);
164
- } else {
165
- // Resolve the handlers when the forwarded promise is resolved.
166
- $value->then(
167
- static function ($value) use ($handlers) {
168
- foreach ($handlers as $handler) {
169
- self::callHandler(1, $value, $handler);
170
- }
171
- },
172
- static function ($reason) use ($handlers) {
173
- foreach ($handlers as $handler) {
174
- self::callHandler(2, $reason, $handler);
175
- }
176
- }
177
- );
178
- }
179
- }
180
-
181
- /**
182
- * Call a stack of handlers using a specific callback index and value.
183
- *
184
- * @param int $index 1 (resolve) or 2 (reject).
185
- * @param mixed $value Value to pass to the callback.
186
- * @param array $handler Array of handler data (promise and callbacks).
187
- *
188
- * @return array Returns the next group to resolve.
189
- */
190
- private static function callHandler($index, $value, array $handler)
191
- {
192
- /** @var PromiseInterface $promise */
193
- $promise = $handler[0];
194
-
195
- // The promise may have been cancelled or resolved before placing
196
- // this thunk in the queue.
197
- if ($promise->getState() !== self::PENDING) {
198
- return;
199
- }
200
-
201
- try {
202
- if (isset($handler[$index])) {
203
- $promise->resolve($handler[$index]($value));
204
- } elseif ($index === 1) {
205
- // Forward resolution values as-is.
206
- $promise->resolve($value);
207
- } else {
208
- // Forward rejections down the chain.
209
- $promise->reject($value);
210
- }
211
- } catch (\Throwable $reason) {
212
- $promise->reject($reason);
213
- } catch (\Exception $reason) {
214
- $promise->reject($reason);
215
- }
216
- }
217
-
218
- private function waitIfPending()
219
- {
220
- if ($this->state !== self::PENDING) {
221
- return;
222
- } elseif ($this->waitFn) {
223
- $this->invokeWaitFn();
224
- } elseif ($this->waitList) {
225
- $this->invokeWaitList();
226
- } else {
227
- // If there's not wait function, then reject the promise.
228
- $this->reject('Cannot wait on a promise that has '
229
- . 'no internal wait function. You must provide a wait '
230
- . 'function when constructing the promise to be able to '
231
- . 'wait on a promise.');
232
- }
233
-
234
- queue()->run();
235
-
236
- if ($this->state === self::PENDING) {
237
- $this->reject('Invoking the wait callback did not resolve the promise');
238
- }
239
- }
240
-
241
- private function invokeWaitFn()
242
- {
243
- try {
244
- $wfn = $this->waitFn;
245
- $this->waitFn = null;
246
- $wfn(true);
247
- } catch (\Exception $reason) {
248
- if ($this->state === self::PENDING) {
249
- // The promise has not been resolved yet, so reject the promise
250
- // with the exception.
251
- $this->reject($reason);
252
- } else {
253
- // The promise was already resolved, so there's a problem in
254
- // the application.
255
- throw $reason;
256
- }
257
- }
258
- }
259
-
260
- private function invokeWaitList()
261
- {
262
- $waitList = $this->waitList;
263
- $this->waitList = null;
264
-
265
- foreach ($waitList as $result) {
266
- while (true) {
267
- $result->waitIfPending();
268
-
269
- if ($result->result instanceof Promise) {
270
- $result = $result->result;
271
- } else {
272
- if ($result->result instanceof PromiseInterface) {
273
- $result->result->wait(false);
274
- }
275
- break;
276
- }
277
- }
278
- }
279
- }
280
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/promises/src/PromiseInterface.php DELETED
@@ -1,93 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Promise;
3
-
4
- /**
5
- * A promise represents the eventual result of an asynchronous operation.
6
- *
7
- * The primary way of interacting with a promise is through its then method,
8
- * which registers callbacks to receive either a promise’s eventual value or
9
- * the reason why the promise cannot be fulfilled.
10
- *
11
- * @link https://promisesaplus.com/
12
- */
13
- interface PromiseInterface
14
- {
15
- const PENDING = 'pending';
16
- const FULFILLED = 'fulfilled';
17
- const REJECTED = 'rejected';
18
-
19
- /**
20
- * Appends fulfillment and rejection handlers to the promise, and returns
21
- * a new promise resolving to the return value of the called handler.
22
- *
23
- * @param callable $onFulfilled Invoked when the promise fulfills.
24
- * @param callable $onRejected Invoked when the promise is rejected.
25
- *
26
- * @return PromiseInterface
27
- */
28
- public function then(
29
- callable $onFulfilled = null,
30
- callable $onRejected = null
31
- );
32
-
33
- /**
34
- * Appends a rejection handler callback to the promise, and returns a new
35
- * promise resolving to the return value of the callback if it is called,
36
- * or to its original fulfillment value if the promise is instead
37
- * fulfilled.
38
- *
39
- * @param callable $onRejected Invoked when the promise is rejected.
40
- *
41
- * @return PromiseInterface
42
- */
43
- public function otherwise(callable $onRejected);
44
-
45
- /**
46
- * Get the state of the promise ("pending", "rejected", or "fulfilled").
47
- *
48
- * The three states can be checked against the constants defined on
49
- * PromiseInterface: PENDING, FULFILLED, and REJECTED.
50
- *
51
- * @return string
52
- */
53
- public function getState();
54
-
55
- /**
56
- * Resolve the promise with the given value.
57
- *
58
- * @param mixed $value
59
- * @throws \RuntimeException if the promise is already resolved.
60
- */
61
- public function resolve($value);
62
-
63
- /**
64
- * Reject the promise with the given reason.
65
- *
66
- * @param mixed $reason
67
- * @throws \RuntimeException if the promise is already resolved.
68
- */
69
- public function reject($reason);
70
-
71
- /**
72
- * Cancels the promise if possible.
73
- *
74
- * @link https://github.com/promises-aplus/cancellation-spec/issues/7
75
- */
76
- public function cancel();
77
-
78
- /**
79
- * Waits until the promise completes if possible.
80
- *
81
- * Pass $unwrap as true to unwrap the result of the promise, either
82
- * returning the resolved value or throwing the rejected exception.
83
- *
84
- * If the promise cannot be waited on, then the promise will be rejected.
85
- *
86
- * @param bool $unwrap
87
- *
88
- * @return mixed
89
- * @throws \LogicException if the promise has no wait function or if the
90
- * promise does not settle after waiting.
91
- */
92
- public function wait($unwrap = true);
93
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/promises/src/PromisorInterface.php DELETED
@@ -1,15 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Promise;
3
-
4
- /**
5
- * Interface used with classes that return a promise.
6
- */
7
- interface PromisorInterface
8
- {
9
- /**
10
- * Returns a promise.
11
- *
12
- * @return PromiseInterface
13
- */
14
- public function promise();
15
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/promises/src/RejectedPromise.php DELETED
@@ -1,87 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Promise;
3
-
4
- /**
5
- * A promise that has been rejected.
6
- *
7
- * Thenning off of this promise will invoke the onRejected callback
8
- * immediately and ignore other callbacks.
9
- */
10
- class RejectedPromise implements PromiseInterface
11
- {
12
- private $reason;
13
-
14
- public function __construct($reason)
15
- {
16
- if (method_exists($reason, 'then')) {
17
- throw new \InvalidArgumentException(
18
- 'You cannot create a RejectedPromise with a promise.');
19
- }
20
-
21
- $this->reason = $reason;
22
- }
23
-
24
- public function then(
25
- callable $onFulfilled = null,
26
- callable $onRejected = null
27
- ) {
28
- // If there's no onRejected callback then just return self.
29
- if (!$onRejected) {
30
- return $this;
31
- }
32
-
33
- $queue = queue();
34
- $reason = $this->reason;
35
- $p = new Promise([$queue, 'run']);
36
- $queue->add(static function () use ($p, $reason, $onRejected) {
37
- if ($p->getState() === self::PENDING) {
38
- try {
39
- // Return a resolved promise if onRejected does not throw.
40
- $p->resolve($onRejected($reason));
41
- } catch (\Throwable $e) {
42
- // onRejected threw, so return a rejected promise.
43
- $p->reject($e);
44
- } catch (\Exception $e) {
45
- // onRejected threw, so return a rejected promise.
46
- $p->reject($e);
47
- }
48
- }
49
- });
50
-
51
- return $p;
52
- }
53
-
54
- public function otherwise(callable $onRejected)
55
- {
56
- return $this->then(null, $onRejected);
57
- }
58
-
59
- public function wait($unwrap = true, $defaultDelivery = null)
60
- {
61
- if ($unwrap) {
62
- throw exception_for($this->reason);
63
- }
64
- }
65
-
66
- public function getState()
67
- {
68
- return self::REJECTED;
69
- }
70
-
71
- public function resolve($value)
72
- {
73
- throw new \LogicException("Cannot resolve a rejected promise");
74
- }
75
-
76
- public function reject($reason)
77
- {
78
- if ($reason !== $this->reason) {
79
- throw new \LogicException("Cannot reject a rejected promise");
80
- }
81
- }
82
-
83
- public function cancel()
84
- {
85
- // pass
86
- }
87
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/promises/src/RejectionException.php DELETED
@@ -1,47 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Promise;
3
-
4
- /**
5
- * A special exception that is thrown when waiting on a rejected promise.
6
- *
7
- * The reason value is available via the getReason() method.
8
- */
9
- class RejectionException extends \RuntimeException
10
- {
11
- /** @var mixed Rejection reason. */
12
- private $reason;
13
-
14
- /**
15
- * @param mixed $reason Rejection reason.
16
- * @param string $description Optional description
17
- */
18
- public function __construct($reason, $description = null)
19
- {
20
- $this->reason = $reason;
21
-
22
- $message = 'The promise was rejected';
23
-
24
- if ($description) {
25
- $message .= ' with reason: ' . $description;
26
- } elseif (is_string($reason)
27
- || (is_object($reason) && method_exists($reason, '__toString'))
28
- ) {
29
- $message .= ' with reason: ' . $this->reason;
30
- } elseif ($reason instanceof \JsonSerializable) {
31
- $message .= ' with reason: '
32
- . json_encode($this->reason, JSON_PRETTY_PRINT);
33
- }
34
-
35
- parent::__construct($message);
36
- }
37
-
38
- /**
39
- * Returns the rejection reason.
40
- *
41
- * @return mixed
42
- */
43
- public function getReason()
44
- {
45
- return $this->reason;
46
- }
47
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/promises/src/TaskQueue.php DELETED
@@ -1,66 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Promise;
3
-
4
- /**
5
- * A task queue that executes tasks in a FIFO order.
6
- *
7
- * This task queue class is used to settle promises asynchronously and
8
- * maintains a constant stack size. You can use the task queue asynchronously
9
- * by calling the `run()` function of the global task queue in an event loop.
10
- *
11
- * GuzzleHttp\Promise\queue()->run();
12
- */
13
- class TaskQueue implements TaskQueueInterface
14
- {
15
- private $enableShutdown = true;
16
- private $queue = [];
17
-
18
- public function __construct($withShutdown = true)
19
- {
20
- if ($withShutdown) {
21
- register_shutdown_function(function () {
22
- if ($this->enableShutdown) {
23
- // Only run the tasks if an E_ERROR didn't occur.
24
- $err = error_get_last();
25
- if (!$err || ($err['type'] ^ E_ERROR)) {
26
- $this->run();
27
- }
28
- }
29
- });
30
- }
31
- }
32
-
33
- public function isEmpty()
34
- {
35
- return !$this->queue;
36
- }
37
-
38
- public function add(callable $task)
39
- {
40
- $this->queue[] = $task;
41
- }
42
-
43
- public function run()
44
- {
45
- /** @var callable $task */
46
- while ($task = array_shift($this->queue)) {
47
- $task();
48
- }
49
- }
50
-
51
- /**
52
- * The task queue will be run and exhausted by default when the process
53
- * exits IFF the exit is not the result of a PHP E_ERROR error.
54
- *
55
- * You can disable running the automatic shutdown of the queue by calling
56
- * this function. If you disable the task queue shutdown process, then you
57
- * MUST either run the task queue (as a result of running your event loop
58
- * or manually using the run() method) or wait on each outstanding promise.
59
- *
60
- * Note: This shutdown will occur before any destructors are triggered.
61
- */
62
- public function disableShutdown()
63
- {
64
- $this->enableShutdown = false;
65
- }
66
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/promises/src/TaskQueueInterface.php DELETED
@@ -1,25 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Promise;
3
-
4
- interface TaskQueueInterface
5
- {
6
- /**
7
- * Returns true if the queue is empty.
8
- *
9
- * @return bool
10
- */
11
- public function isEmpty();
12
-
13
- /**
14
- * Adds a task to the queue that will be executed the next time run is
15
- * called.
16
- *
17
- * @param callable $task
18
- */
19
- public function add(callable $task);
20
-
21
- /**
22
- * Execute all of the pending task in the queue.
23
- */
24
- public function run();
25
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/promises/src/functions.php DELETED
@@ -1,457 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Promise;
3
-
4
- /**
5
- * Get the global task queue used for promise resolution.
6
- *
7
- * This task queue MUST be run in an event loop in order for promises to be
8
- * settled asynchronously. It will be automatically run when synchronously
9
- * waiting on a promise.
10
- *
11
- * <code>
12
- * while ($eventLoop->isRunning()) {
13
- * GuzzleHttp\Promise\queue()->run();
14
- * }
15
- * </code>
16
- *
17
- * @param TaskQueueInterface $assign Optionally specify a new queue instance.
18
- *
19
- * @return TaskQueueInterface
20
- */
21
- function queue(TaskQueueInterface $assign = null)
22
- {
23
- static $queue;
24
-
25
- if ($assign) {
26
- $queue = $assign;
27
- } elseif (!$queue) {
28
- $queue = new TaskQueue();
29
- }
30
-
31
- return $queue;
32
- }
33
-
34
- /**
35
- * Adds a function to run in the task queue when it is next `run()` and returns
36
- * a promise that is fulfilled or rejected with the result.
37
- *
38
- * @param callable $task Task function to run.
39
- *
40
- * @return PromiseInterface
41
- */
42
- function task(callable $task)
43
- {
44
- $queue = queue();
45
- $promise = new Promise([$queue, 'run']);
46
- $queue->add(function () use ($task, $promise) {
47
- try {
48
- $promise->resolve($task());
49
- } catch (\Throwable $e) {
50
- $promise->reject($e);
51
- } catch (\Exception $e) {
52
- $promise->reject($e);
53
- }
54
- });
55
-
56
- return $promise;
57
- }
58
-
59
- /**
60
- * Creates a promise for a value if the value is not a promise.
61
- *
62
- * @param mixed $value Promise or value.
63
- *
64
- * @return PromiseInterface
65
- */
66
- function promise_for($value)
67
- {
68
- if ($value instanceof PromiseInterface) {
69
- return $value;
70
- }
71
-
72
- // Return a Guzzle promise that shadows the given promise.
73
- if (method_exists($value, 'then')) {
74
- $wfn = method_exists($value, 'wait') ? [$value, 'wait'] : null;
75
- $cfn = method_exists($value, 'cancel') ? [$value, 'cancel'] : null;
76
- $promise = new Promise($wfn, $cfn);
77
- $value->then([$promise, 'resolve'], [$promise, 'reject']);
78
- return $promise;
79
- }
80
-
81
- return new FulfilledPromise($value);
82
- }
83
-
84
- /**
85
- * Creates a rejected promise for a reason if the reason is not a promise. If
86
- * the provided reason is a promise, then it is returned as-is.
87
- *
88
- * @param mixed $reason Promise or reason.
89
- *
90
- * @return PromiseInterface
91
- */
92
- function rejection_for($reason)
93
- {
94
- if ($reason instanceof PromiseInterface) {
95
- return $reason;
96
- }
97
-
98
- return new RejectedPromise($reason);
99
- }
100
-
101
- /**
102
- * Create an exception for a rejected promise value.
103
- *
104
- * @param mixed $reason
105
- *
106
- * @return \Exception|\Throwable
107
- */
108
- function exception_for($reason)
109
- {
110
- return $reason instanceof \Exception || $reason instanceof \Throwable
111
- ? $reason
112
- : new RejectionException($reason);
113
- }
114
-
115
- /**
116
- * Returns an iterator for the given value.
117
- *
118
- * @param mixed $value
119
- *
120
- * @return \Iterator
121
- */
122
- function iter_for($value)
123
- {
124
- if ($value instanceof \Iterator) {
125
- return $value;
126
- } elseif (is_array($value)) {
127
- return new \ArrayIterator($value);
128
- } else {
129
- return new \ArrayIterator([$value]);
130
- }
131
- }
132
-
133
- /**
134
- * Synchronously waits on a promise to resolve and returns an inspection state
135
- * array.
136
- *
137
- * Returns a state associative array containing a "state" key mapping to a
138
- * valid promise state. If the state of the promise is "fulfilled", the array
139
- * will contain a "value" key mapping to the fulfilled value of the promise. If
140
- * the promise is rejected, the array will contain a "reason" key mapping to
141
- * the rejection reason of the promise.
142
- *
143
- * @param PromiseInterface $promise Promise or value.
144
- *
145
- * @return array
146
- */
147
- function inspect(PromiseInterface $promise)
148
- {
149
- try {
150
- return [
151
- 'state' => PromiseInterface::FULFILLED,
152
- 'value' => $promise->wait()
153
- ];
154
- } catch (RejectionException $e) {
155
- return ['state' => PromiseInterface::REJECTED, 'reason' => $e->getReason()];
156
- } catch (\Throwable $e) {
157
- return ['state' => PromiseInterface::REJECTED, 'reason' => $e];
158
- } catch (\Exception $e) {
159
- return ['state' => PromiseInterface::REJECTED, 'reason' => $e];
160
- }
161
- }
162
-
163
- /**
164
- * Waits on all of the provided promises, but does not unwrap rejected promises
165
- * as thrown exception.
166
- *
167
- * Returns an array of inspection state arrays.
168
- *
169
- * @param PromiseInterface[] $promises Traversable of promises to wait upon.
170
- *
171
- * @return array
172
- * @see GuzzleHttp\Promise\inspect for the inspection state array format.
173
- */
174
- function inspect_all($promises)
175
- {
176
- $results = [];
177
- foreach ($promises as $key => $promise) {
178
- $results[$key] = inspect($promise);
179
- }
180
-
181
- return $results;
182
- }
183
-
184
- /**
185
- * Waits on all of the provided promises and returns the fulfilled values.
186
- *
187
- * Returns an array that contains the value of each promise (in the same order
188
- * the promises were provided). An exception is thrown if any of the promises
189
- * are rejected.
190
- *
191
- * @param mixed $promises Iterable of PromiseInterface objects to wait on.
192
- *
193
- * @return array
194
- * @throws \Exception on error
195
- * @throws \Throwable on error in PHP >=7
196
- */
197
- function unwrap($promises)
198
- {
199
- $results = [];
200
- foreach ($promises as $key => $promise) {
201
- $results[$key] = $promise->wait();
202
- }
203
-
204
- return $results;
205
- }
206
-
207
- /**
208
- * Given an array of promises, return a promise that is fulfilled when all the
209
- * items in the array are fulfilled.
210
- *
211
- * The promise's fulfillment value is an array with fulfillment values at
212
- * respective positions to the original array. If any promise in the array
213
- * rejects, the returned promise is rejected with the rejection reason.
214
- *
215
- * @param mixed $promises Promises or values.
216
- *
217
- * @return PromiseInterface
218
- */
219
- function all($promises)
220
- {
221
- $results = [];
222
- return each(
223
- $promises,
224
- function ($value, $idx) use (&$results) {
225
- $results[$idx] = $value;
226
- },
227
- function ($reason, $idx, Promise $aggregate) {
228
- $aggregate->reject($reason);
229
- }
230
- )->then(function () use (&$results) {
231
- ksort($results);
232
- return $results;
233
- });
234
- }
235
-
236
- /**
237
- * Initiate a competitive race between multiple promises or values (values will
238
- * become immediately fulfilled promises).
239
- *
240
- * When count amount of promises have been fulfilled, the returned promise is
241
- * fulfilled with an array that contains the fulfillment values of the winners
242
- * in order of resolution.
243
- *
244
- * This prommise is rejected with a {@see GuzzleHttp\Promise\AggregateException}
245
- * if the number of fulfilled promises is less than the desired $count.
246
- *
247
- * @param int $count Total number of promises.
248
- * @param mixed $promises Promises or values.
249
- *
250
- * @return PromiseInterface
251
- */
252
- function some($count, $promises)
253
- {
254
- $results = [];
255
- $rejections = [];
256
-
257
- return each(
258
- $promises,
259
- function ($value, $idx, PromiseInterface $p) use (&$results, $count) {
260
- if ($p->getState() !== PromiseInterface::PENDING) {
261
- return;
262
- }
263
- $results[$idx] = $value;
264
- if (count($results) >= $count) {
265
- $p->resolve(null);
266
- }
267
- },
268
- function ($reason) use (&$rejections) {
269
- $rejections[] = $reason;
270
- }
271
- )->then(
272
- function () use (&$results, &$rejections, $count) {
273
- if (count($results) !== $count) {
274
- throw new AggregateException(
275
- 'Not enough promises to fulfill count',
276
- $rejections
277
- );
278
- }
279
- ksort($results);
280
- return array_values($results);
281
- }
282
- );
283
- }
284
-
285
- /**
286
- * Like some(), with 1 as count. However, if the promise fulfills, the
287
- * fulfillment value is not an array of 1 but the value directly.
288
- *
289
- * @param mixed $promises Promises or values.
290
- *
291
- * @return PromiseInterface
292
- */
293
- function any($promises)
294
- {
295
- return some(1, $promises)->then(function ($values) { return $values[0]; });
296
- }
297
-
298
- /**
299
- * Returns a promise that is fulfilled when all of the provided promises have
300
- * been fulfilled or rejected.
301
- *
302
- * The returned promise is fulfilled with an array of inspection state arrays.
303
- *
304
- * @param mixed $promises Promises or values.
305
- *
306
- * @return PromiseInterface
307
- * @see GuzzleHttp\Promise\inspect for the inspection state array format.
308
- */
309
- function settle($promises)
310
- {
311
- $results = [];
312
-
313
- return each(
314
- $promises,
315
- function ($value, $idx) use (&$results) {
316
- $results[$idx] = ['state' => PromiseInterface::FULFILLED, 'value' => $value];
317
- },
318
- function ($reason, $idx) use (&$results) {
319
- $results[$idx] = ['state' => PromiseInterface::REJECTED, 'reason' => $reason];
320
- }
321
- )->then(function () use (&$results) {
322
- ksort($results);
323
- return $results;
324
- });
325
- }
326
-
327
- /**
328
- * Given an iterator that yields promises or values, returns a promise that is
329
- * fulfilled with a null value when the iterator has been consumed or the
330
- * aggregate promise has been fulfilled or rejected.
331
- *
332
- * $onFulfilled is a function that accepts the fulfilled value, iterator
333
- * index, and the aggregate promise. The callback can invoke any necessary side
334
- * effects and choose to resolve or reject the aggregate promise if needed.
335
- *
336
- * $onRejected is a function that accepts the rejection reason, iterator
337
- * index, and the aggregate promise. The callback can invoke any necessary side
338
- * effects and choose to resolve or reject the aggregate promise if needed.
339
- *
340
- * @param mixed $iterable Iterator or array to iterate over.
341
- * @param callable $onFulfilled
342
- * @param callable $onRejected
343
- *
344
- * @return PromiseInterface
345
- */
346
- function each(
347
- $iterable,
348
- callable $onFulfilled = null,
349
- callable $onRejected = null
350
- ) {
351
- return (new EachPromise($iterable, [
352
- 'fulfilled' => $onFulfilled,
353
- 'rejected' => $onRejected
354
- ]))->promise();
355
- }
356
-
357
- /**
358
- * Like each, but only allows a certain number of outstanding promises at any
359
- * given time.
360
- *
361
- * $concurrency may be an integer or a function that accepts the number of
362
- * pending promises and returns a numeric concurrency limit value to allow for
363
- * dynamic a concurrency size.
364
- *
365
- * @param mixed $iterable
366
- * @param int|callable $concurrency
367
- * @param callable $onFulfilled
368
- * @param callable $onRejected
369
- *
370
- * @return PromiseInterface
371
- */
372
- function each_limit(
373
- $iterable,
374
- $concurrency,
375
- callable $onFulfilled = null,
376
- callable $onRejected = null
377
- ) {
378
- return (new EachPromise($iterable, [
379
- 'fulfilled' => $onFulfilled,
380
- 'rejected' => $onRejected,
381
- 'concurrency' => $concurrency
382
- ]))->promise();
383
- }
384
-
385
- /**
386
- * Like each_limit, but ensures that no promise in the given $iterable argument
387
- * is rejected. If any promise is rejected, then the aggregate promise is
388
- * rejected with the encountered rejection.
389
- *
390
- * @param mixed $iterable
391
- * @param int|callable $concurrency
392
- * @param callable $onFulfilled
393
- *
394
- * @return PromiseInterface
395
- */
396
- function each_limit_all(
397
- $iterable,
398
- $concurrency,
399
- callable $onFulfilled = null
400
- ) {
401
- return each_limit(
402
- $iterable,
403
- $concurrency,
404
- $onFulfilled,
405
- function ($reason, $idx, PromiseInterface $aggregate) {
406
- $aggregate->reject($reason);
407
- }
408
- );
409
- }
410
-
411
- /**
412
- * Returns true if a promise is fulfilled.
413
- *
414
- * @param PromiseInterface $promise
415
- *
416
- * @return bool
417
- */
418
- function is_fulfilled(PromiseInterface $promise)
419
- {
420
- return $promise->getState() === PromiseInterface::FULFILLED;
421
- }
422
-
423
- /**
424
- * Returns true if a promise is rejected.
425
- *
426
- * @param PromiseInterface $promise
427
- *
428
- * @return bool
429
- */
430
- function is_rejected(PromiseInterface $promise)
431
- {
432
- return $promise->getState() === PromiseInterface::REJECTED;
433
- }
434
-
435
- /**
436
- * Returns true if a promise is fulfilled or rejected.
437
- *
438
- * @param PromiseInterface $promise
439
- *
440
- * @return bool
441
- */
442
- function is_settled(PromiseInterface $promise)
443
- {
444
- return $promise->getState() !== PromiseInterface::PENDING;
445
- }
446
-
447
- /**
448
- * @see Coroutine
449
- *
450
- * @param callable $generatorFn
451
- *
452
- * @return PromiseInterface
453
- */
454
- function coroutine(callable $generatorFn)
455
- {
456
- return new Coroutine($generatorFn);
457
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/promises/src/functions_include.php DELETED
@@ -1,6 +0,0 @@
1
- <?php
2
-
3
- // Don't redefine the functions if included multiple times.
4
- if (!function_exists('GuzzleHttp\Promise\promise_for')) {
5
- require __DIR__ . '/functions.php';
6
- }
 
 
 
 
 
 
vendor/guzzlehttp/psr7/CHANGELOG.md DELETED
@@ -1,225 +0,0 @@
1
- # Change Log
2
-
3
-
4
- All notable changes to this project will be documented in this file.
5
-
6
- The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
7
- and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
8
-
9
-
10
- ## [Unreleased]
11
-
12
-
13
- ## [1.5.2] - 2018-12-04
14
-
15
- ### Fixed
16
-
17
- - Check body size when getting the message summary
18
-
19
-
20
- ## [1.5.1] - 2018-12-04
21
-
22
- ### Fixed
23
-
24
- - Get the summary of a body only if it is readable
25
-
26
-
27
- ## [1.5.0] - 2018-12-03
28
-
29
- ### Added
30
-
31
- - Response first-line to response string exception (fixes #145)
32
- - A test for #129 behavior
33
- - `get_message_body_summary` function in order to get the message summary
34
- - `3gp` and `mkv` mime types
35
-
36
- ### Changed
37
-
38
- - Clarify exception message when stream is detached
39
-
40
- ### Deprecated
41
-
42
- - Deprecated parsing folded header lines as per RFC 7230
43
-
44
- ### Fixed
45
-
46
- - Fix `AppendStream::detach` to not close streams
47
- - `InflateStream` preserves `isSeekable` attribute of the underlying stream
48
- - `ServerRequest::getUriFromGlobals` to support URLs in query parameters
49
-
50
-
51
- Several other fixes and improvements.
52
-
53
-
54
- ## [1.4.2] - 2017-03-20
55
-
56
- ### Fixed
57
-
58
- - Reverted BC break to `Uri::resolve` and `Uri::removeDotSegments` by removing
59
- calls to `trigger_error` when deprecated methods are invoked.
60
-
61
-
62
- ## [1.4.1] - 2017-02-27
63
-
64
- ### Added
65
-
66
- - Rriggering of silenced deprecation warnings.
67
-
68
- ### Fixed
69
-
70
- - Reverted BC break by reintroducing behavior to automagically fix a URI with a
71
- relative path and an authority by adding a leading slash to the path. It's only
72
- deprecated now.
73
-
74
-
75
- ## [1.4.0] - 2017-02-21
76
-
77
- ### Added
78
-
79
- - Added common URI utility methods based on RFC 3986 (see documentation in the readme):
80
- - `Uri::isDefaultPort`
81
- - `Uri::isAbsolute`
82
- - `Uri::isNetworkPathReference`
83
- - `Uri::isAbsolutePathReference`
84
- - `Uri::isRelativePathReference`
85
- - `Uri::isSameDocumentReference`
86
- - `Uri::composeComponents`
87
- - `UriNormalizer::normalize`
88
- - `UriNormalizer::isEquivalent`
89
- - `UriResolver::relativize`
90
-
91
- ### Changed
92
-
93
- - Ensure `ServerRequest::getUriFromGlobals` returns a URI in absolute form.
94
- - Allow `parse_response` to parse a response without delimiting space and reason.
95
- - Ensure each URI modification results in a valid URI according to PSR-7 discussions.
96
- Invalid modifications will throw an exception instead of returning a wrong URI or
97
- doing some magic.
98
- - `(new Uri)->withPath('foo')->withHost('example.com')` will throw an exception
99
- because the path of a URI with an authority must start with a slash "/" or be empty
100
- - `(new Uri())->withScheme('http')` will return `'http://localhost'`
101
-
102
- ### Deprecated
103
-
104
- - `Uri::resolve` in favor of `UriResolver::resolve`
105
- - `Uri::removeDotSegments` in favor of `UriResolver::removeDotSegments`
106
-
107
- ### Fixed
108
-
109
- - `Stream::read` when length parameter <= 0.
110
- - `copy_to_stream` reads bytes in chunks instead of `maxLen` into memory.
111
- - `ServerRequest::getUriFromGlobals` when `Host` header contains port.
112
- - Compatibility of URIs with `file` scheme and empty host.
113
-
114
-
115
- ## [1.3.1] - 2016-06-25
116
-
117
- ### Fixed
118
-
119
- - `Uri::__toString` for network path references, e.g. `//example.org`.
120
- - Missing lowercase normalization for host.
121
- - Handling of URI components in case they are `'0'` in a lot of places,
122
- e.g. as a user info password.
123
- - `Uri::withAddedHeader` to correctly merge headers with different case.
124
- - Trimming of header values in `Uri::withAddedHeader`. Header values may
125
- be surrounded by whitespace which should be ignored according to RFC 7230
126
- Section 3.2.4. This does not apply to header names.
127
- - `Uri::withAddedHeader` with an array of header values.
128
- - `Uri::resolve` when base path has no slash and handling of fragment.
129
- - Handling of encoding in `Uri::with(out)QueryValue` so one can pass the
130
- key/value both in encoded as well as decoded form to those methods. This is
131
- consistent with withPath, withQuery etc.
132
- - `ServerRequest::withoutAttribute` when attribute value is null.
133
-
134
-
135
- ## [1.3.0] - 2016-04-13
136
-
137
- ### Added
138
-
139
- - Remaining interfaces needed for full PSR7 compatibility
140
- (ServerRequestInterface, UploadedFileInterface, etc.).
141
- - Support for stream_for from scalars.
142
-
143
- ### Changed
144
-
145
- - Can now extend Uri.
146
-
147
- ### Fixed
148
- - A bug in validating request methods by making it more permissive.
149
-
150
-
151
- ## [1.2.3] - 2016-02-18
152
-
153
- ### Fixed
154
-
155
- - Support in `GuzzleHttp\Psr7\CachingStream` for seeking forward on remote
156
- streams, which can sometimes return fewer bytes than requested with `fread`.
157
- - Handling of gzipped responses with FNAME headers.
158
-
159
-
160
- ## [1.2.2] - 2016-01-22
161
-
162
- ### Added
163
-
164
- - Support for URIs without any authority.
165
- - Support for HTTP 451 'Unavailable For Legal Reasons.'
166
- - Support for using '0' as a filename.
167
- - Support for including non-standard ports in Host headers.
168
-
169
-
170
- ## [1.2.1] - 2015-11-02
171
-
172
- ### Changes
173
-
174
- - Now supporting negative offsets when seeking to SEEK_END.
175
-
176
-
177
- ## [1.2.0] - 2015-08-15
178
-
179
- ### Changed
180
-
181
- - Body as `"0"` is now properly added to a response.
182
- - Now allowing forward seeking in CachingStream.
183
- - Now properly parsing HTTP requests that contain proxy targets in
184
- `parse_request`.
185
- - functions.php is now conditionally required.
186
- - user-info is no longer dropped when resolving URIs.
187
-
188
-
189
- ## [1.1.0] - 2015-06-24
190
-
191
- ### Changed
192
-
193
- - URIs can now be relative.
194
- - `multipart/form-data` headers are now overridden case-insensitively.
195
- - URI paths no longer encode the following characters because they are allowed
196
- in URIs: "(", ")", "*", "!", "'"
197
- - A port is no longer added to a URI when the scheme is missing and no port is
198
- present.
199
-
200
-
201
- ## 1.0.0 - 2015-05-19
202
-
203
- Initial release.
204
-
205
- Currently unsupported:
206
-
207
- - `Psr\Http\Message\ServerRequestInterface`
208
- - `Psr\Http\Message\UploadedFileInterface`
209
-
210
-
211
-
212
- [Unreleased]: https://github.com/guzzle/psr7/compare/1.5.2...HEAD
213
- [1.5.2]: https://github.com/guzzle/psr7/compare/1.5.1...1.5.2
214
- [1.5.1]: https://github.com/guzzle/psr7/compare/1.5.0...1.5.1
215
- [1.5.0]: https://github.com/guzzle/psr7/compare/1.4.2...1.5.0
216
- [1.4.2]: https://github.com/guzzle/psr7/compare/1.4.1...1.4.2
217
- [1.4.1]: https://github.com/guzzle/psr7/compare/1.4.0...1.4.1
218
- [1.4.0]: https://github.com/guzzle/psr7/compare/1.3.1...1.4.0
219
- [1.3.1]: https://github.com/guzzle/psr7/compare/1.3.0...1.3.1
220
- [1.3.0]: https://github.com/guzzle/psr7/compare/1.2.3...1.3.0
221
- [1.2.3]: https://github.com/guzzle/psr7/compare/1.2.2...1.2.3
222
- [1.2.2]: https://github.com/guzzle/psr7/compare/1.2.1...1.2.2
223
- [1.2.1]: https://github.com/guzzle/psr7/compare/1.2.0...1.2.1
224
- [1.2.0]: https://github.com/guzzle/psr7/compare/1.1.0...1.2.0
225
- [1.1.0]: https://github.com/guzzle/psr7/compare/1.0.0...1.1.0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/psr7/LICENSE DELETED
@@ -1,19 +0,0 @@
1
- Copyright (c) 2015 Michael Dowling, https://github.com/mtdowling <mtdowling@gmail.com>
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining a copy
4
- of this software and associated documentation files (the "Software"), to deal
5
- in the Software without restriction, including without limitation the rights
6
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
- copies of the Software, and to permit persons to whom the Software is
8
- furnished to do so, subject to the following conditions:
9
-
10
- The above copyright notice and this permission notice shall be included in
11
- all copies or substantial portions of the Software.
12
-
13
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
- THE SOFTWARE.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/psr7/README.md DELETED
@@ -1,745 +0,0 @@
1
- # PSR-7 Message Implementation
2
-
3
- This repository contains a full [PSR-7](http://www.php-fig.org/psr/psr-7/)
4
- message implementation, several stream decorators, and some helpful
5
- functionality like query string parsing.
6
-
7
-
8
- [![Build Status](https://travis-ci.org/guzzle/psr7.svg?branch=master)](https://travis-ci.org/guzzle/psr7)
9
-
10
-
11
- # Stream implementation
12
-
13
- This package comes with a number of stream implementations and stream
14
- decorators.
15
-
16
-
17
- ## AppendStream
18
-
19
- `GuzzleHttp\Psr7\AppendStream`
20
-
21
- Reads from multiple streams, one after the other.
22
-
23
- ```php
24
- use GuzzleHttp\Psr7;
25
-
26
- $a = Psr7\stream_for('abc, ');
27
- $b = Psr7\stream_for('123.');
28
- $composed = new Psr7\AppendStream([$a, $b]);
29
-
30
- $composed->addStream(Psr7\stream_for(' Above all listen to me'));
31
-
32
- echo $composed; // abc, 123. Above all listen to me.
33
- ```
34
-
35
-
36
- ## BufferStream
37
-
38
- `GuzzleHttp\Psr7\BufferStream`
39
-
40
- Provides a buffer stream that can be written to fill a buffer, and read
41
- from to remove bytes from the buffer.
42
-
43
- This stream returns a "hwm" metadata value that tells upstream consumers
44
- what the configured high water mark of the stream is, or the maximum
45
- preferred size of the buffer.
46
-
47
- ```php
48
- use GuzzleHttp\Psr7;
49
-
50
- // When more than 1024 bytes are in the buffer, it will begin returning
51
- // false to writes. This is an indication that writers should slow down.
52
- $buffer = new Psr7\BufferStream(1024);
53
- ```
54
-
55
-
56
- ## CachingStream
57
-
58
- The CachingStream is used to allow seeking over previously read bytes on
59
- non-seekable streams. This can be useful when transferring a non-seekable
60
- entity body fails due to needing to rewind the stream (for example, resulting
61
- from a redirect). Data that is read from the remote stream will be buffered in
62
- a PHP temp stream so that previously read bytes are cached first in memory,
63
- then on disk.
64
-
65
- ```php
66
- use GuzzleHttp\Psr7;
67
-
68
- $original = Psr7\stream_for(fopen('http://www.google.com', 'r'));
69
- $stream = new Psr7\CachingStream($original);
70
-
71
- $stream->read(1024);
72
- echo $stream->tell();
73
- // 1024
74
-
75
- $stream->seek(0);
76
- echo $stream->tell();
77
- // 0
78
- ```
79
-
80
-
81
- ## DroppingStream
82
-
83
- `GuzzleHttp\Psr7\DroppingStream`
84
-
85
- Stream decorator that begins dropping data once the size of the underlying
86
- stream becomes too full.
87
-
88
- ```php
89
- use GuzzleHttp\Psr7;
90
-
91
- // Create an empty stream
92
- $stream = Psr7\stream_for();
93
-
94
- // Start dropping data when the stream has more than 10 bytes
95
- $dropping = new Psr7\DroppingStream($stream, 10);
96
-
97
- $dropping->write('01234567890123456789');
98
- echo $stream; // 0123456789
99
- ```
100
-
101
-
102
- ## FnStream
103
-
104
- `GuzzleHttp\Psr7\FnStream`
105
-
106
- Compose stream implementations based on a hash of functions.
107
-
108
- Allows for easy testing and extension of a provided stream without needing
109
- to create a concrete class for a simple extension point.
110
-
111
- ```php
112
-
113
- use GuzzleHttp\Psr7;
114
-
115
- $stream = Psr7\stream_for('hi');
116
- $fnStream = Psr7\FnStream::decorate($stream, [
117
- 'rewind' => function () use ($stream) {
118
- echo 'About to rewind - ';
119
- $stream->rewind();
120
- echo 'rewound!';
121
- }
122
- ]);
123
-
124
- $fnStream->rewind();
125
- // Outputs: About to rewind - rewound!
126
- ```
127
-
128
-
129
- ## InflateStream
130
-
131
- `GuzzleHttp\Psr7\InflateStream`
132
-
133
- Uses PHP's zlib.inflate filter to inflate deflate or gzipped content.
134
-
135
- This stream decorator skips the first 10 bytes of the given stream to remove
136
- the gzip header, converts the provided stream to a PHP stream resource,
137
- then appends the zlib.inflate filter. The stream is then converted back
138
- to a Guzzle stream resource to be used as a Guzzle stream.
139
-
140
-
141
- ## LazyOpenStream
142
-
143
- `GuzzleHttp\Psr7\LazyOpenStream`
144
-
145
- Lazily reads or writes to a file that is opened only after an IO operation
146
- take place on the stream.
147
-
148
- ```php
149
- use GuzzleHttp\Psr7;
150
-
151
- $stream = new Psr7\LazyOpenStream('/path/to/file', 'r');
152
- // The file has not yet been opened...
153
-
154
- echo $stream->read(10);
155
- // The file is opened and read from only when needed.
156
- ```
157
-
158
-
159
- ## LimitStream
160
-
161
- `GuzzleHttp\Psr7\LimitStream`
162
-
163
- LimitStream can be used to read a subset or slice of an existing stream object.
164
- This can be useful for breaking a large file into smaller pieces to be sent in
165
- chunks (e.g. Amazon S3's multipart upload API).
166
-
167
- ```php
168
- use GuzzleHttp\Psr7;
169
-
170
- $original = Psr7\stream_for(fopen('/tmp/test.txt', 'r+'));
171
- echo $original->getSize();
172
- // >>> 1048576
173
-
174
- // Limit the size of the body to 1024 bytes and start reading from byte 2048
175
- $stream = new Psr7\LimitStream($original, 1024, 2048);
176
- echo $stream->getSize();
177
- // >>> 1024
178
- echo $stream->tell();
179
- // >>> 0
180
- ```
181
-
182
-
183
- ## MultipartStream
184
-
185
- `GuzzleHttp\Psr7\MultipartStream`
186
-
187
- Stream that when read returns bytes for a streaming multipart or
188
- multipart/form-data stream.
189
-
190
-
191
- ## NoSeekStream
192
-
193
- `GuzzleHttp\Psr7\NoSeekStream`
194
-
195
- NoSeekStream wraps a stream and does not allow seeking.
196
-
197
- ```php
198
- use GuzzleHttp\Psr7;
199
-
200
- $original = Psr7\stream_for('foo');
201
- $noSeek = new Psr7\NoSeekStream($original);
202
-
203
- echo $noSeek->read(3);
204
- // foo
205
- var_export($noSeek->isSeekable());
206
- // false
207
- $noSeek->seek(0);
208
- var_export($noSeek->read(3));
209
- // NULL
210
- ```
211
-
212
-
213
- ## PumpStream
214
-
215
- `GuzzleHttp\Psr7\PumpStream`
216
-
217
- Provides a read only stream that pumps data from a PHP callable.
218
-
219
- When invoking the provided callable, the PumpStream will pass the amount of
220
- data requested to read to the callable. The callable can choose to ignore
221
- this value and return fewer or more bytes than requested. Any extra data
222
- returned by the provided callable is buffered internally until drained using
223
- the read() function of the PumpStream. The provided callable MUST return
224
- false when there is no more data to read.
225
-
226
-
227
- ## Implementing stream decorators
228
-
229
- Creating a stream decorator is very easy thanks to the
230
- `GuzzleHttp\Psr7\StreamDecoratorTrait`. This trait provides methods that
231
- implement `Psr\Http\Message\StreamInterface` by proxying to an underlying
232
- stream. Just `use` the `StreamDecoratorTrait` and implement your custom
233
- methods.
234
-
235
- For example, let's say we wanted to call a specific function each time the last
236
- byte is read from a stream. This could be implemented by overriding the
237
- `read()` method.
238
-
239
- ```php
240
- use Psr\Http\Message\StreamInterface;
241
- use GuzzleHttp\Psr7\StreamDecoratorTrait;
242
-
243
- class EofCallbackStream implements StreamInterface
244
- {
245
- use StreamDecoratorTrait;
246
-
247
- private $callback;
248
-
249
- public function __construct(StreamInterface $stream, callable $cb)
250
- {
251
- $this->stream = $stream;
252
- $this->callback = $cb;
253
- }
254
-
255
- public function read($length)
256
- {
257
- $result = $this->stream->read($length);
258
-
259
- // Invoke the callback when EOF is hit.
260
- if ($this->eof()) {
261
- call_user_func($this->callback);
262
- }
263
-
264
- return $result;
265
- }
266
- }
267
- ```
268
-
269
- This decorator could be added to any existing stream and used like so:
270
-
271
- ```php
272
- use GuzzleHttp\Psr7;
273
-
274
- $original = Psr7\stream_for('foo');
275
-
276
- $eofStream = new EofCallbackStream($original, function () {
277
- echo 'EOF!';
278
- });
279
-
280
- $eofStream->read(2);
281
- $eofStream->read(1);
282
- // echoes "EOF!"
283
- $eofStream->seek(0);
284
- $eofStream->read(3);
285
- // echoes "EOF!"
286
- ```
287
-
288
-
289
- ## PHP StreamWrapper
290
-
291
- You can use the `GuzzleHttp\Psr7\StreamWrapper` class if you need to use a
292
- PSR-7 stream as a PHP stream resource.
293
-
294
- Use the `GuzzleHttp\Psr7\StreamWrapper::getResource()` method to create a PHP
295
- stream from a PSR-7 stream.
296
-
297
- ```php
298
- use GuzzleHttp\Psr7\StreamWrapper;
299
-
300
- $stream = GuzzleHttp\Psr7\stream_for('hello!');
301
- $resource = StreamWrapper::getResource($stream);
302
- echo fread($resource, 6); // outputs hello!
303
- ```
304
-
305
-
306
- # Function API
307
-
308
- There are various functions available under the `GuzzleHttp\Psr7` namespace.
309
-
310
-
311
- ## `function str`
312
-
313
- `function str(MessageInterface $message)`
314
-
315
- Returns the string representation of an HTTP message.
316
-
317
- ```php
318
- $request = new GuzzleHttp\Psr7\Request('GET', 'http://example.com');
319
- echo GuzzleHttp\Psr7\str($request);
320
- ```
321
-
322
-
323
- ## `function uri_for`
324
-
325
- `function uri_for($uri)`
326
-
327
- This function accepts a string or `Psr\Http\Message\UriInterface` and returns a
328
- UriInterface for the given value. If the value is already a `UriInterface`, it
329
- is returned as-is.
330
-
331
- ```php
332
- $uri = GuzzleHttp\Psr7\uri_for('http://example.com');
333
- assert($uri === GuzzleHttp\Psr7\uri_for($uri));
334
- ```
335
-
336
-
337
- ## `function stream_for`
338
-
339
- `function stream_for($resource = '', array $options = [])`
340
-
341
- Create a new stream based on the input type.
342
-
343
- Options is an associative array that can contain the following keys:
344
-
345
- * - metadata: Array of custom metadata.
346
- * - size: Size of the stream.
347
-
348
- This method accepts the following `$resource` types:
349
-
350
- - `Psr\Http\Message\StreamInterface`: Returns the value as-is.
351
- - `string`: Creates a stream object that uses the given string as the contents.
352
- - `resource`: Creates a stream object that wraps the given PHP stream resource.
353
- - `Iterator`: If the provided value implements `Iterator`, then a read-only
354
- stream object will be created that wraps the given iterable. Each time the
355
- stream is read from, data from the iterator will fill a buffer and will be
356
- continuously called until the buffer is equal to the requested read size.
357
- Subsequent read calls will first read from the buffer and then call `next`
358
- on the underlying iterator until it is exhausted.
359
- - `object` with `__toString()`: If the object has the `__toString()` method,
360
- the object will be cast to a string and then a stream will be returned that
361
- uses the string value.
362
- - `NULL`: When `null` is passed, an empty stream object is returned.
363
- - `callable` When a callable is passed, a read-only stream object will be
364
- created that invokes the given callable. The callable is invoked with the
365
- number of suggested bytes to read. The callable can return any number of
366
- bytes, but MUST return `false` when there is no more data to return. The
367
- stream object that wraps the callable will invoke the callable until the
368
- number of requested bytes are available. Any additional bytes will be
369
- buffered and used in subsequent reads.
370
-
371
- ```php
372
- $stream = GuzzleHttp\Psr7\stream_for('foo');
373
- $stream = GuzzleHttp\Psr7\stream_for(fopen('/path/to/file', 'r'));
374
-
375
- $generator = function ($bytes) {
376
- for ($i = 0; $i < $bytes; $i++) {
377
- yield ' ';
378
- }
379
- }
380
-
381
- $stream = GuzzleHttp\Psr7\stream_for($generator(100));
382
- ```
383
-
384
-
385
- ## `function parse_header`
386
-
387
- `function parse_header($header)`
388
-
389
- Parse an array of header values containing ";" separated data into an array of
390
- associative arrays representing the header key value pair data of the header.
391
- When a parameter does not contain a value, but just contains a key, this
392
- function will inject a key with a '' string value.
393
-
394
-
395
- ## `function normalize_header`
396
-
397
- `function normalize_header($header)`
398
-
399
- Converts an array of header values that may contain comma separated headers
400
- into an array of headers with no comma separated values.
401
-
402
-
403
- ## `function modify_request`
404
-
405
- `function modify_request(RequestInterface $request, array $changes)`
406
-
407
- Clone and modify a request with the given changes. This method is useful for
408
- reducing the number of clones needed to mutate a message.
409
-
410
- The changes can be one of:
411
-
412
- - method: (string) Changes the HTTP method.
413
- - set_headers: (array) Sets the given headers.
414
- - remove_headers: (array) Remove the given headers.
415
- - body: (mixed) Sets the given body.
416
- - uri: (UriInterface) Set the URI.
417
- - query: (string) Set the query string value of the URI.
418
- - version: (string) Set the protocol version.
419
-
420
-
421
- ## `function rewind_body`
422
-
423
- `function rewind_body(MessageInterface $message)`
424
-
425
- Attempts to rewind a message body and throws an exception on failure. The body
426
- of the message will only be rewound if a call to `tell()` returns a value other
427
- than `0`.
428
-
429
-
430
- ## `function try_fopen`
431
-
432
- `function try_fopen($filename, $mode)`
433
-
434
- Safely opens a PHP stream resource using a filename.
435
-
436
- When fopen fails, PHP normally raises a warning. This function adds an error
437
- handler that checks for errors and throws an exception instead.
438
-
439
-
440
- ## `function copy_to_string`
441
-
442
- `function copy_to_string(StreamInterface $stream, $maxLen = -1)`
443
-
444
- Copy the contents of a stream into a string until the given number of bytes
445
- have been read.
446
-
447
-
448
- ## `function copy_to_stream`
449
-
450
- `function copy_to_stream(StreamInterface $source, StreamInterface $dest, $maxLen = -1)`
451
-
452
- Copy the contents of a stream into another stream until the given number of
453
- bytes have been read.
454
-
455
-
456
- ## `function hash`
457
-
458
- `function hash(StreamInterface $stream, $algo, $rawOutput = false)`
459
-
460
- Calculate a hash of a Stream. This method reads the entire stream to calculate
461
- a rolling hash (based on PHP's hash_init functions).
462
-
463
-
464
- ## `function readline`
465
-
466
- `function readline(StreamInterface $stream, $maxLength = null)`
467
-
468
- Read a line from the stream up to the maximum allowed buffer length.
469
-
470
-
471
- ## `function parse_request`
472
-
473
- `function parse_request($message)`
474
-
475
- Parses a request message string into a request object.
476
-
477
-
478
- ## `function parse_response`
479
-
480
- `function parse_response($message)`
481
-
482
- Parses a response message string into a response object.
483
-
484
-
485
- ## `function parse_query`
486
-
487
- `function parse_query($str, $urlEncoding = true)`
488
-
489
- Parse a query string into an associative array.
490
-
491
- If multiple values are found for the same key, the value of that key value pair
492
- will become an array. This function does not parse nested PHP style arrays into
493
- an associative array (e.g., `foo[a]=1&foo[b]=2` will be parsed into
494
- `['foo[a]' => '1', 'foo[b]' => '2']`).
495
-
496
-
497
- ## `function build_query`
498
-
499
- `function build_query(array $params, $encoding = PHP_QUERY_RFC3986)`
500
-
501
- Build a query string from an array of key value pairs.
502
-
503
- This function can use the return value of parse_query() to build a query string.
504
- This function does not modify the provided keys when an array is encountered
505
- (like http_build_query would).
506
-
507
-
508
- ## `function mimetype_from_filename`
509
-
510
- `function mimetype_from_filename($filename)`
511
-
512
- Determines the mimetype of a file by looking at its extension.
513
-
514
-
515
- ## `function mimetype_from_extension`
516
-
517
- `function mimetype_from_extension($extension)`
518
-
519
- Maps a file extensions to a mimetype.
520
-
521
-
522
- # Additional URI Methods
523
-
524
- Aside from the standard `Psr\Http\Message\UriInterface` implementation in form of the `GuzzleHttp\Psr7\Uri` class,
525
- this library also provides additional functionality when working with URIs as static methods.
526
-
527
- ## URI Types
528
-
529
- An instance of `Psr\Http\Message\UriInterface` can either be an absolute URI or a relative reference.
530
- An absolute URI has a scheme. A relative reference is used to express a URI relative to another URI,
531
- the base URI. Relative references can be divided into several forms according to
532
- [RFC 3986 Section 4.2](https://tools.ietf.org/html/rfc3986#section-4.2):
533
-
534
- - network-path references, e.g. `//example.com/path`
535
- - absolute-path references, e.g. `/path`
536
- - relative-path references, e.g. `subpath`
537
-
538
- The following methods can be used to identify the type of the URI.
539
-
540
- ### `GuzzleHttp\Psr7\Uri::isAbsolute`
541
-
542
- `public static function isAbsolute(UriInterface $uri): bool`
543
-
544
- Whether the URI is absolute, i.e. it has a scheme.
545
-
546
- ### `GuzzleHttp\Psr7\Uri::isNetworkPathReference`
547
-
548
- `public static function isNetworkPathReference(UriInterface $uri): bool`
549
-
550
- Whether the URI is a network-path reference. A relative reference that begins with two slash characters is
551
- termed an network-path reference.
552
-
553
- ### `GuzzleHttp\Psr7\Uri::isAbsolutePathReference`
554
-
555
- `public static function isAbsolutePathReference(UriInterface $uri): bool`
556
-
557
- Whether the URI is a absolute-path reference. A relative reference that begins with a single slash character is
558
- termed an absolute-path reference.
559
-
560
- ### `GuzzleHttp\Psr7\Uri::isRelativePathReference`
561
-
562
- `public static function isRelativePathReference(UriInterface $uri): bool`
563
-
564
- Whether the URI is a relative-path reference. A relative reference that does not begin with a slash character is
565
- termed a relative-path reference.
566
-
567
- ### `GuzzleHttp\Psr7\Uri::isSameDocumentReference`
568
-
569
- `public static function isSameDocumentReference(UriInterface $uri, UriInterface $base = null): bool`
570
-
571
- Whether the URI is a same-document reference. A same-document reference refers to a URI that is, aside from its
572
- fragment component, identical to the base URI. When no base URI is given, only an empty URI reference
573
- (apart from its fragment) is considered a same-document reference.
574
-
575
- ## URI Components
576
-
577
- Additional methods to work with URI components.
578
-
579
- ### `GuzzleHttp\Psr7\Uri::isDefaultPort`
580
-
581
- `public static function isDefaultPort(UriInterface $uri): bool`
582
-
583
- Whether the URI has the default port of the current scheme. `Psr\Http\Message\UriInterface::getPort` may return null
584
- or the standard port. This method can be used independently of the implementation.
585
-
586
- ### `GuzzleHttp\Psr7\Uri::composeComponents`
587
-
588
- `public static function composeComponents($scheme, $authority, $path, $query, $fragment): string`
589
-
590
- Composes a URI reference string from its various components according to
591
- [RFC 3986 Section 5.3](https://tools.ietf.org/html/rfc3986#section-5.3). Usually this method does not need to be called
592
- manually but instead is used indirectly via `Psr\Http\Message\UriInterface::__toString`.
593
-
594
- ### `GuzzleHttp\Psr7\Uri::fromParts`
595
-
596
- `public static function fromParts(array $parts): UriInterface`
597
-
598
- Creates a URI from a hash of [`parse_url`](http://php.net/manual/en/function.parse-url.php) components.
599
-
600
-
601
- ### `GuzzleHttp\Psr7\Uri::withQueryValue`
602
-
603
- `public static function withQueryValue(UriInterface $uri, $key, $value): UriInterface`
604
-
605
- Creates a new URI with a specific query string value. Any existing query string values that exactly match the
606
- provided key are removed and replaced with the given key value pair. A value of null will set the query string
607
- key without a value, e.g. "key" instead of "key=value".
608
-
609
- ### `GuzzleHttp\Psr7\Uri::withQueryValues`
610
-
611
- `public static function withQueryValues(UriInterface $uri, array $keyValueArray): UriInterface`
612
-
613
- Creates a new URI with multiple query string values. It has the same behavior as `withQueryValue()` but for an
614
- associative array of key => value.
615
-
616
- ### `GuzzleHttp\Psr7\Uri::withoutQueryValue`
617
-
618
- `public static function withoutQueryValue(UriInterface $uri, $key): UriInterface`
619
-
620
- Creates a new URI with a specific query string value removed. Any existing query string values that exactly match the
621
- provided key are removed.
622
-
623
- ## Reference Resolution
624
-
625
- `GuzzleHttp\Psr7\UriResolver` provides methods to resolve a URI reference in the context of a base URI according
626
- to [RFC 3986 Section 5](https://tools.ietf.org/html/rfc3986#section-5). This is for example also what web browsers
627
- do when resolving a link in a website based on the current request URI.
628
-
629
- ### `GuzzleHttp\Psr7\UriResolver::resolve`
630
-
631
- `public static function resolve(UriInterface $base, UriInterface $rel): UriInterface`
632
-
633
- Converts the relative URI into a new URI that is resolved against the base URI.
634
-
635
- ### `GuzzleHttp\Psr7\UriResolver::removeDotSegments`
636
-
637
- `public static function removeDotSegments(string $path): string`
638
-
639
- Removes dot segments from a path and returns the new path according to
640
- [RFC 3986 Section 5.2.4](https://tools.ietf.org/html/rfc3986#section-5.2.4).
641
-
642
- ### `GuzzleHttp\Psr7\UriResolver::relativize`
643
-
644
- `public static function relativize(UriInterface $base, UriInterface $target): UriInterface`
645
-
646
- Returns the target URI as a relative reference from the base URI. This method is the counterpart to resolve():
647
-
648
- ```php
649
- (string) $target === (string) UriResolver::resolve($base, UriResolver::relativize($base, $target))
650
- ```
651
-
652
- One use-case is to use the current request URI as base URI and then generate relative links in your documents
653
- to reduce the document size or offer self-contained downloadable document archives.
654
-
655
- ```php
656
- $base = new Uri('http://example.com/a/b/');
657
- echo UriResolver::relativize($base, new Uri('http://example.com/a/b/c')); // prints 'c'.
658
- echo UriResolver::relativize($base, new Uri('http://example.com/a/x/y')); // prints '../x/y'.
659
- echo UriResolver::relativize($base, new Uri('http://example.com/a/b/?q')); // prints '?q'.
660
- echo UriResolver::relativize($base, new Uri('http://example.org/a/b/')); // prints '//example.org/a/b/'.
661
- ```
662
-
663
- ## Normalization and Comparison
664
-
665
- `GuzzleHttp\Psr7\UriNormalizer` provides methods to normalize and compare URIs according to
666
- [RFC 3986 Section 6](https://tools.ietf.org/html/rfc3986#section-6).
667
-
668
- ### `GuzzleHttp\Psr7\UriNormalizer::normalize`
669
-
670
- `public static function normalize(UriInterface $uri, $flags = self::PRESERVING_NORMALIZATIONS): UriInterface`
671
-
672
- Returns a normalized URI. The scheme and host component are already normalized to lowercase per PSR-7 UriInterface.
673
- This methods adds additional normalizations that can be configured with the `$flags` parameter which is a bitmask
674
- of normalizations to apply. The following normalizations are available:
675
-
676
- - `UriNormalizer::PRESERVING_NORMALIZATIONS`
677
-
678
- Default normalizations which only include the ones that preserve semantics.
679
-
680
- - `UriNormalizer::CAPITALIZE_PERCENT_ENCODING`
681
-
682
- All letters within a percent-encoding triplet (e.g., "%3A") are case-insensitive, and should be capitalized.
683
-
684
- Example: `http://example.org/a%c2%b1b` → `http://example.org/a%C2%B1b`
685
-
686
- - `UriNormalizer::DECODE_UNRESERVED_CHARACTERS`
687
-
688
- Decodes percent-encoded octets of unreserved characters. For consistency, percent-encoded octets in the ranges of
689
- ALPHA (%41–%5A and %61–%7A), DIGIT (%30–%39), hyphen (%2D), period (%2E), underscore (%5F), or tilde (%7E) should
690
- not be created by URI producers and, when found in a URI, should be decoded to their corresponding unreserved
691
- characters by URI normalizers.
692
-
693
- Example: `http://example.org/%7Eusern%61me/` → `http://example.org/~username/`
694
-
695
- - `UriNormalizer::CONVERT_EMPTY_PATH`
696
-
697
- Converts the empty path to "/" for http and https URIs.
698
-
699
- Example: `http://example.org` → `http://example.org/`
700
-
701
- - `UriNormalizer::REMOVE_DEFAULT_HOST`
702
-
703
- Removes the default host of the given URI scheme from the URI. Only the "file" scheme defines the default host
704
- "localhost". All of `file:/myfile`, `file:///myfile`, and `file://localhost/myfile` are equivalent according to
705
- RFC 3986.
706
-
707
- Example: `file://localhost/myfile` → `file:///myfile`
708
-
709
- - `UriNormalizer::REMOVE_DEFAULT_PORT`
710
-
711
- Removes the default port of the given URI scheme from the URI.
712
-
713
- Example: `http://example.org:80/` → `http://example.org/`
714
-
715
- - `UriNormalizer::REMOVE_DOT_SEGMENTS`
716
-
717
- Removes unnecessary dot-segments. Dot-segments in relative-path references are not removed as it would
718
- change the semantics of the URI reference.
719
-
720
- Example: `http://example.org/../a/b/../c/./d.html` → `http://example.org/a/c/d.html`
721
-
722
- - `UriNormalizer::REMOVE_DUPLICATE_SLASHES`
723
-
724
- Paths which include two or more adjacent slashes are converted to one. Webservers usually ignore duplicate slashes
725
- and treat those URIs equivalent. But in theory those URIs do not need to be equivalent. So this normalization
726
- may change the semantics. Encoded slashes (%2F) are not removed.
727
-
728
- Example: `http://example.org//foo///bar.html` → `http://example.org/foo/bar.html`
729
-
730
- - `UriNormalizer::SORT_QUERY_PARAMETERS`
731
-
732
- Sort query parameters with their values in alphabetical order. However, the order of parameters in a URI may be
733
- significant (this is not defined by the standard). So this normalization is not safe and may change the semantics
734
- of the URI.
735
-
736
- Example: `?lang=en&article=fred` → `?article=fred&lang=en`
737
-
738
- ### `GuzzleHttp\Psr7\UriNormalizer::isEquivalent`
739
-
740
- `public static function isEquivalent(UriInterface $uri1, UriInterface $uri2, $normalizations = self::PRESERVING_NORMALIZATIONS): bool`
741
-
742
- Whether two URIs can be considered equivalent. Both URIs are normalized automatically before comparison with the given
743
- `$normalizations` bitmask. The method also accepts relative URI references and returns true when they are equivalent.
744
- This of course assumes they will be resolved against the same base URI. If this is not the case, determination of
745
- equivalence or difference of relative references does not mean anything.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/psr7/src/AppendStream.php DELETED
@@ -1,241 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Psr7;
3
-
4
- use Psr\Http\Message\StreamInterface;
5
-
6
- /**
7
- * Reads from multiple streams, one after the other.
8
- *
9
- * This is a read-only stream decorator.
10
- */
11
- class AppendStream implements StreamInterface
12
- {
13
- /** @var StreamInterface[] Streams being decorated */
14
- private $streams = [];
15
-
16
- private $seekable = true;
17
- private $current = 0;
18
- private $pos = 0;
19
-
20
- /**
21
- * @param StreamInterface[] $streams Streams to decorate. Each stream must
22
- * be readable.
23
- */
24
- public function __construct(array $streams = [])
25
- {
26
- foreach ($streams as $stream) {
27
- $this->addStream($stream);
28
- }
29
- }
30
-
31
- public function __toString()
32
- {
33
- try {
34
- $this->rewind();
35
- return $this->getContents();
36
- } catch (\Exception $e) {
37
- return '';
38
- }
39
- }
40
-
41
- /**
42
- * Add a stream to the AppendStream
43
- *
44
- * @param StreamInterface $stream Stream to append. Must be readable.
45
- *
46
- * @throws \InvalidArgumentException if the stream is not readable
47
- */
48
- public function addStream(StreamInterface $stream)
49
- {
50
- if (!$stream->isReadable()) {
51
- throw new \InvalidArgumentException('Each stream must be readable');
52
- }
53
-
54
- // The stream is only seekable if all streams are seekable
55
- if (!$stream->isSeekable()) {
56
- $this->seekable = false;
57
- }
58
-
59
- $this->streams[] = $stream;
60
- }
61
-
62
- public function getContents()
63
- {
64
- return copy_to_string($this);
65
- }
66
-
67
- /**
68
- * Closes each attached stream.
69
- *
70
- * {@inheritdoc}
71
- */
72
- public function close()
73
- {
74
- $this->pos = $this->current = 0;
75
- $this->seekable = true;
76
-
77
- foreach ($this->streams as $stream) {
78
- $stream->close();
79
- }
80
-
81
- $this->streams = [];
82
- }
83
-
84
- /**
85
- * Detaches each attached stream.
86
- *
87
- * Returns null as it's not clear which underlying stream resource to return.
88
- *
89
- * {@inheritdoc}
90
- */
91
- public function detach()
92
- {
93
- $this->pos = $this->current = 0;
94
- $this->seekable = true;
95
-
96
- foreach ($this->streams as $stream) {
97
- $stream->detach();
98
- }
99
-
100
- $this->streams = [];
101
- }
102
-
103
- public function tell()
104
- {
105
- return $this->pos;
106
- }
107
-
108
- /**
109
- * Tries to calculate the size by adding the size of each stream.
110
- *
111
- * If any of the streams do not return a valid number, then the size of the
112
- * append stream cannot be determined and null is returned.
113
- *
114
- * {@inheritdoc}
115
- */
116
- public function getSize()
117
- {
118
- $size = 0;
119
-
120
- foreach ($this->streams as $stream) {
121
- $s = $stream->getSize();
122
- if ($s === null) {
123
- return null;
124
- }
125
- $size += $s;
126
- }
127
-
128
- return $size;
129
- }
130
-
131
- public function eof()
132
- {
133
- return !$this->streams ||
134
- ($this->current >= count($this->streams) - 1 &&
135
- $this->streams[$this->current]->eof());
136
- }
137
-
138
- public function rewind()
139
- {
140
- $this->seek(0);
141
- }
142
-
143
- /**
144
- * Attempts to seek to the given position. Only supports SEEK_SET.
145
- *
146
- * {@inheritdoc}
147
- */
148
- public function seek($offset, $whence = SEEK_SET)
149
- {
150
- if (!$this->seekable) {
151
- throw new \RuntimeException('This AppendStream is not seekable');
152
- } elseif ($whence !== SEEK_SET) {
153
- throw new \RuntimeException('The AppendStream can only seek with SEEK_SET');
154
- }
155
-
156
- $this->pos = $this->current = 0;
157
-
158
- // Rewind each stream
159
- foreach ($this->streams as $i => $stream) {
160
- try {
161
- $stream->rewind();
162
- } catch (\Exception $e) {
163
- throw new \RuntimeException('Unable to seek stream '
164
- . $i . ' of the AppendStream', 0, $e);
165
- }
166
- }
167
-
168
- // Seek to the actual position by reading from each stream
169
- while ($this->pos < $offset && !$this->eof()) {
170
- $result = $this->read(min(8096, $offset - $this->pos));
171
- if ($result === '') {
172
- break;
173
- }
174
- }
175
- }
176
-
177
- /**
178
- * Reads from all of the appended streams until the length is met or EOF.
179
- *
180
- * {@inheritdoc}
181
- */
182
- public function read($length)
183
- {
184
- $buffer = '';
185
- $total = count($this->streams) - 1;
186
- $remaining = $length;
187
- $progressToNext = false;
188
-
189
- while ($remaining > 0) {
190
-
191
- // Progress to the next stream if needed.
192
- if ($progressToNext || $this->streams[$this->current]->eof()) {
193
- $progressToNext = false;
194
- if ($this->current === $total) {
195
- break;
196
- }
197
- $this->current++;
198
- }
199
-
200
- $result = $this->streams[$this->current]->read($remaining);
201
-
202
- // Using a loose comparison here to match on '', false, and null
203
- if ($result == null) {
204
- $progressToNext = true;
205
- continue;
206
- }
207
-
208
- $buffer .= $result;
209
- $remaining = $length - strlen($buffer);
210
- }
211
-
212
- $this->pos += strlen($buffer);
213
-
214
- return $buffer;
215
- }
216
-
217
- public function isReadable()
218
- {
219
- return true;
220
- }
221
-
222
- public function isWritable()
223
- {
224
- return false;
225
- }
226
-
227
- public function isSeekable()
228
- {
229
- return $this->seekable;
230
- }
231
-
232
- public function write($string)
233
- {
234
- throw new \RuntimeException('Cannot write to an AppendStream');
235
- }
236
-
237
- public function getMetadata($key = null)
238
- {
239
- return $key ? null : [];
240
- }
241
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/psr7/src/BufferStream.php DELETED
@@ -1,137 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Psr7;
3
-
4
- use Psr\Http\Message\StreamInterface;
5
-
6
- /**
7
- * Provides a buffer stream that can be written to to fill a buffer, and read
8
- * from to remove bytes from the buffer.
9
- *
10
- * This stream returns a "hwm" metadata value that tells upstream consumers
11
- * what the configured high water mark of the stream is, or the maximum
12
- * preferred size of the buffer.
13
- */
14
- class BufferStream implements StreamInterface
15
- {
16
- private $hwm;
17
- private $buffer = '';
18
-
19
- /**
20
- * @param int $hwm High water mark, representing the preferred maximum
21
- * buffer size. If the size of the buffer exceeds the high
22
- * water mark, then calls to write will continue to succeed
23
- * but will return false to inform writers to slow down
24
- * until the buffer has been drained by reading from it.
25
- */
26
- public function __construct($hwm = 16384)
27
- {
28
- $this->hwm = $hwm;
29
- }
30
-
31
- public function __toString()
32
- {
33
- return $this->getContents();
34
- }
35
-
36
- public function getContents()
37
- {
38
- $buffer = $this->buffer;
39
- $this->buffer = '';
40
-
41
- return $buffer;
42
- }
43
-
44
- public function close()
45
- {
46
- $this->buffer = '';
47
- }
48
-
49
- public function detach()
50
- {
51
- $this->close();
52
- }
53
-
54
- public function getSize()
55
- {
56
- return strlen($this->buffer);
57
- }
58
-
59
- public function isReadable()
60
- {
61
- return true;
62
- }
63
-
64
- public function isWritable()
65
- {
66
- return true;
67
- }
68
-
69
- public function isSeekable()
70
- {
71
- return false;
72
- }
73
-
74
- public function rewind()
75
- {
76
- $this->seek(0);
77
- }
78
-
79
- public function seek($offset, $whence = SEEK_SET)
80
- {
81
- throw new \RuntimeException('Cannot seek a BufferStream');
82
- }
83
-
84
- public function eof()
85
- {
86
- return strlen($this->buffer) === 0;
87
- }
88
-
89
- public function tell()
90
- {
91
- throw new \RuntimeException('Cannot determine the position of a BufferStream');
92
- }
93
-
94
- /**
95
- * Reads data from the buffer.
96
- */
97
- public function read($length)
98
- {
99
- $currentLength = strlen($this->buffer);
100
-
101
- if ($length >= $currentLength) {
102
- // No need to slice the buffer because we don't have enough data.
103
- $result = $this->buffer;
104
- $this->buffer = '';
105
- } else {
106
- // Slice up the result to provide a subset of the buffer.
107
- $result = substr($this->buffer, 0, $length);
108
- $this->buffer = substr($this->buffer, $length);
109
- }
110
-
111
- return $result;
112
- }
113
-
114
- /**
115
- * Writes data to the buffer.
116
- */
117
- public function write($string)
118
- {
119
- $this->buffer .= $string;
120
-
121
- // TODO: What should happen here?
122
- if (strlen($this->buffer) >= $this->hwm) {
123
- return false;
124
- }
125
-
126
- return strlen($string);
127
- }
128
-
129
- public function getMetadata($key = null)
130
- {
131
- if ($key == 'hwm') {
132
- return $this->hwm;
133
- }
134
-
135
- return $key ? null : [];
136
- }
137
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/psr7/src/CachingStream.php DELETED
@@ -1,138 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Psr7;
3
-
4
- use Psr\Http\Message\StreamInterface;
5
-
6
- /**
7
- * Stream decorator that can cache previously read bytes from a sequentially
8
- * read stream.
9
- */
10
- class CachingStream implements StreamInterface
11
- {
12
- use StreamDecoratorTrait;
13
-
14
- /** @var StreamInterface Stream being wrapped */
15
- private $remoteStream;
16
-
17
- /** @var int Number of bytes to skip reading due to a write on the buffer */
18
- private $skipReadBytes = 0;
19
-
20
- /**
21
- * We will treat the buffer object as the body of the stream
22
- *
23
- * @param StreamInterface $stream Stream to cache
24
- * @param StreamInterface $target Optionally specify where data is cached
25
- */
26
- public function __construct(
27
- StreamInterface $stream,
28
- StreamInterface $target = null
29
- ) {
30
- $this->remoteStream = $stream;
31
- $this->stream = $target ?: new Stream(fopen('php://temp', 'r+'));
32
- }
33
-
34
- public function getSize()
35
- {
36
- return max($this->stream->getSize(), $this->remoteStream->getSize());
37
- }
38
-
39
- public function rewind()
40
- {
41
- $this->seek(0);
42
- }
43
-
44
- public function seek($offset, $whence = SEEK_SET)
45
- {
46
- if ($whence == SEEK_SET) {
47
- $byte = $offset;
48
- } elseif ($whence == SEEK_CUR) {
49
- $byte = $offset + $this->tell();
50
- } elseif ($whence == SEEK_END) {
51
- $size = $this->remoteStream->getSize();
52
- if ($size === null) {
53
- $size = $this->cacheEntireStream();
54
- }
55
- $byte = $size + $offset;
56
- } else {
57
- throw new \InvalidArgumentException('Invalid whence');
58
- }
59
-
60
- $diff = $byte - $this->stream->getSize();
61
-
62
- if ($diff > 0) {
63
- // Read the remoteStream until we have read in at least the amount
64
- // of bytes requested, or we reach the end of the file.
65
- while ($diff > 0 && !$this->remoteStream->eof()) {
66
- $this->read($diff);
67
- $diff = $byte - $this->stream->getSize();
68
- }
69
- } else {
70
- // We can just do a normal seek since we've already seen this byte.
71
- $this->stream->seek($byte);
72
- }
73
- }
74
-
75
- public function read($length)
76
- {
77
- // Perform a regular read on any previously read data from the buffer
78
- $data = $this->stream->read($length);
79
- $remaining = $length - strlen($data);
80
-
81
- // More data was requested so read from the remote stream
82
- if ($remaining) {
83
- // If data was written to the buffer in a position that would have
84
- // been filled from the remote stream, then we must skip bytes on
85
- // the remote stream to emulate overwriting bytes from that
86
- // position. This mimics the behavior of other PHP stream wrappers.
87
- $remoteData = $this->remoteStream->read(
88
- $remaining + $this->skipReadBytes
89
- );
90
-
91
- if ($this->skipReadBytes) {
92
- $len = strlen($remoteData);
93
- $remoteData = substr($remoteData, $this->skipReadBytes);
94
- $this->skipReadBytes = max(0, $this->skipReadBytes - $len);
95
- }
96
-
97
- $data .= $remoteData;
98
- $this->stream->write($remoteData);
99
- }
100
-
101
- return $data;
102
- }
103
-
104
- public function write($string)
105
- {
106
- // When appending to the end of the currently read stream, you'll want
107
- // to skip bytes from being read from the remote stream to emulate
108
- // other stream wrappers. Basically replacing bytes of data of a fixed
109
- // length.
110
- $overflow = (strlen($string) + $this->tell()) - $this->remoteStream->tell();
111
- if ($overflow > 0) {
112
- $this->skipReadBytes += $overflow;
113
- }
114
-
115
- return $this->stream->write($string);
116
- }
117
-
118
- public function eof()
119
- {
120
- return $this->stream->eof() && $this->remoteStream->eof();
121
- }
122
-
123
- /**
124
- * Close both the remote stream and buffer stream
125
- */
126
- public function close()
127
- {
128
- $this->remoteStream->close() && $this->stream->close();
129
- }
130
-
131
- private function cacheEntireStream()
132
- {
133
- $target = new FnStream(['write' => 'strlen']);
134
- copy_to_stream($this, $target);
135
-
136
- return $this->tell();
137
- }
138
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/psr7/src/DroppingStream.php DELETED
@@ -1,42 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Psr7;
3
-
4
- use Psr\Http\Message\StreamInterface;
5
-
6
- /**
7
- * Stream decorator that begins dropping data once the size of the underlying
8
- * stream becomes too full.
9
- */
10
- class DroppingStream implements StreamInterface
11
- {
12
- use StreamDecoratorTrait;
13
-
14
- private $maxLength;
15
-
16
- /**
17
- * @param StreamInterface $stream Underlying stream to decorate.
18
- * @param int $maxLength Maximum size before dropping data.
19
- */
20
- public function __construct(StreamInterface $stream, $maxLength)
21
- {
22
- $this->stream = $stream;
23
- $this->maxLength = $maxLength;
24
- }
25
-
26
- public function write($string)
27
- {
28
- $diff = $this->maxLength - $this->stream->getSize();
29
-
30
- // Begin returning 0 when the underlying stream is too large.
31
- if ($diff <= 0) {
32
- return 0;
33
- }
34
-
35
- // Write the stream or a subset of the stream if needed.
36
- if (strlen($string) < $diff) {
37
- return $this->stream->write($string);
38
- }
39
-
40
- return $this->stream->write(substr($string, 0, $diff));
41
- }
42
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/psr7/src/FnStream.php DELETED
@@ -1,158 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Psr7;
3
-
4
- use Psr\Http\Message\StreamInterface;
5
-
6
- /**
7
- * Compose stream implementations based on a hash of functions.
8
- *
9
- * Allows for easy testing and extension of a provided stream without needing
10
- * to create a concrete class for a simple extension point.
11
- */
12
- class FnStream implements StreamInterface
13
- {
14
- /** @var array */
15
- private $methods;
16
-
17
- /** @var array Methods that must be implemented in the given array */
18
- private static $slots = ['__toString', 'close', 'detach', 'rewind',
19
- 'getSize', 'tell', 'eof', 'isSeekable', 'seek', 'isWritable', 'write',
20
- 'isReadable', 'read', 'getContents', 'getMetadata'];
21
-
22
- /**
23
- * @param array $methods Hash of method name to a callable.
24
- */
25
- public function __construct(array $methods)
26
- {
27
- $this->methods = $methods;
28
-
29
- // Create the functions on the class
30
- foreach ($methods as $name => $fn) {
31
- $this->{'_fn_' . $name} = $fn;
32
- }
33
- }
34
-
35
- /**
36
- * Lazily determine which methods are not implemented.
37
- * @throws \BadMethodCallException
38
- */
39
- public function __get($name)
40
- {
41
- throw new \BadMethodCallException(str_replace('_fn_', '', $name)
42
- . '() is not implemented in the FnStream');
43
- }
44
-
45
- /**
46
- * The close method is called on the underlying stream only if possible.
47
- */
48
- public function __destruct()
49
- {
50
- if (isset($this->_fn_close)) {
51
- call_user_func($this->_fn_close);
52
- }
53
- }
54
-
55
- /**
56
- * An unserialize would allow the __destruct to run when the unserialized value goes out of scope.
57
- * @throws \LogicException
58
- */
59
- public function __wakeup()
60
- {
61
- throw new \LogicException('FnStream should never be unserialized');
62
- }
63
-
64
- /**
65
- * Adds custom functionality to an underlying stream by intercepting
66
- * specific method calls.
67
- *
68
- * @param StreamInterface $stream Stream to decorate
69
- * @param array $methods Hash of method name to a closure
70
- *
71
- * @return FnStream
72
- */
73
- public static function decorate(StreamInterface $stream, array $methods)
74
- {
75
- // If any of the required methods were not provided, then simply
76
- // proxy to the decorated stream.
77
- foreach (array_diff(self::$slots, array_keys($methods)) as $diff) {
78
- $methods[$diff] = [$stream, $diff];
79
- }
80
-
81
- return new self($methods);
82
- }
83
-
84
- public function __toString()
85
- {
86
- return call_user_func($this->_fn___toString);
87
- }
88
-
89
- public function close()
90
- {
91
- return call_user_func($this->_fn_close);
92
- }
93
-
94
- public function detach()
95
- {
96
- return call_user_func($this->_fn_detach);
97
- }
98
-
99
- public function getSize()
100
- {
101
- return call_user_func($this->_fn_getSize);
102
- }
103
-
104
- public function tell()
105
- {
106
- return call_user_func($this->_fn_tell);
107
- }
108
-
109
- public function eof()
110
- {
111
- return call_user_func($this->_fn_eof);
112
- }
113
-
114
- public function isSeekable()
115
- {
116
- return call_user_func($this->_fn_isSeekable);
117
- }
118
-
119
- public function rewind()
120
- {
121
- call_user_func($this->_fn_rewind);
122
- }
123
-
124
- public function seek($offset, $whence = SEEK_SET)
125
- {
126
- call_user_func($this->_fn_seek, $offset, $whence);
127
- }
128
-
129
- public function isWritable()
130
- {
131
- return call_user_func($this->_fn_isWritable);
132
- }
133
-
134
- public function write($string)
135
- {
136
- return call_user_func($this->_fn_write, $string);
137
- }
138
-
139
- public function isReadable()
140
- {
141
- return call_user_func($this->_fn_isReadable);
142
- }
143
-
144
- public function read($length)
145
- {
146
- return call_user_func($this->_fn_read, $length);
147
- }
148
-
149
- public function getContents()
150
- {
151
- return call_user_func($this->_fn_getContents);
152
- }
153
-
154
- public function getMetadata($key = null)
155
- {
156
- return call_user_func($this->_fn_getMetadata, $key);
157
- }
158
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/psr7/src/InflateStream.php DELETED
@@ -1,52 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Psr7;
3
-
4
- use Psr\Http\Message\StreamInterface;
5
-
6
- /**
7
- * Uses PHP's zlib.inflate filter to inflate deflate or gzipped content.
8
- *
9
- * This stream decorator skips the first 10 bytes of the given stream to remove
10
- * the gzip header, converts the provided stream to a PHP stream resource,
11
- * then appends the zlib.inflate filter. The stream is then converted back
12
- * to a Guzzle stream resource to be used as a Guzzle stream.
13
- *
14
- * @link http://tools.ietf.org/html/rfc1952
15
- * @link http://php.net/manual/en/filters.compression.php
16
- */
17
- class InflateStream implements StreamInterface
18
- {
19
- use StreamDecoratorTrait;
20
-
21
- public function __construct(StreamInterface $stream)
22
- {
23
- // read the first 10 bytes, ie. gzip header
24
- $header = $stream->read(10);
25
- $filenameHeaderLength = $this->getLengthOfPossibleFilenameHeader($stream, $header);
26
- // Skip the header, that is 10 + length of filename + 1 (nil) bytes
27
- $stream = new LimitStream($stream, -1, 10 + $filenameHeaderLength);
28
- $resource = StreamWrapper::getResource($stream);
29
- stream_filter_append($resource, 'zlib.inflate', STREAM_FILTER_READ);
30
- $this->stream = $stream->isSeekable() ? new Stream($resource) : new NoSeekStream(new Stream($resource));
31
- }
32
-
33
- /**
34
- * @param StreamInterface $stream
35
- * @param $header
36
- * @return int
37
- */
38
- private function getLengthOfPossibleFilenameHeader(StreamInterface $stream, $header)
39
- {
40
- $filename_header_length = 0;
41
-
42
- if (substr(bin2hex($header), 6, 2) === '08') {
43
- // we have a filename, read until nil
44
- $filename_header_length = 1;
45
- while ($stream->read(1) !== chr(0)) {
46
- $filename_header_length++;
47
- }
48
- }
49
-
50
- return $filename_header_length;
51
- }
52
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/psr7/src/LazyOpenStream.php DELETED
@@ -1,39 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Psr7;
3
-
4
- use Psr\Http\Message\StreamInterface;
5
-
6
- /**
7
- * Lazily reads or writes to a file that is opened only after an IO operation
8
- * take place on the stream.
9
- */
10
- class LazyOpenStream implements StreamInterface
11
- {
12
- use StreamDecoratorTrait;
13
-
14
- /** @var string File to open */
15
- private $filename;
16
-
17
- /** @var string $mode */
18
- private $mode;
19
-
20
- /**
21
- * @param string $filename File to lazily open
22
- * @param string $mode fopen mode to use when opening the stream
23
- */
24
- public function __construct($filename, $mode)
25
- {
26
- $this->filename = $filename;
27
- $this->mode = $mode;
28
- }
29
-
30
- /**
31
- * Creates the underlying stream lazily when required.
32
- *
33
- * @return StreamInterface
34
- */
35
- protected function createStream()
36
- {
37
- return stream_for(try_fopen($this->filename, $this->mode));
38
- }
39
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/psr7/src/LimitStream.php DELETED
@@ -1,155 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Psr7;
3
-
4
- use Psr\Http\Message\StreamInterface;
5
-
6
-
7
- /**
8
- * Decorator used to return only a subset of a stream
9
- */
10
- class LimitStream implements StreamInterface
11
- {
12
- use StreamDecoratorTrait;
13
-
14
- /** @var int Offset to start reading from */
15
- private $offset;
16
-
17
- /** @var int Limit the number of bytes that can be read */
18
- private $limit;
19
-
20
- /**
21
- * @param StreamInterface $stream Stream to wrap
22
- * @param int $limit Total number of bytes to allow to be read
23
- * from the stream. Pass -1 for no limit.
24
- * @param int $offset Position to seek to before reading (only
25
- * works on seekable streams).
26
- */
27
- public function __construct(
28
- StreamInterface $stream,
29
- $limit = -1,
30
- $offset = 0
31
- ) {
32
- $this->stream = $stream;
33
- $this->setLimit($limit);
34
- $this->setOffset($offset);
35
- }
36
-
37
- public function eof()
38
- {
39
- // Always return true if the underlying stream is EOF
40
- if ($this->stream->eof()) {
41
- return true;
42
- }
43
-
44
- // No limit and the underlying stream is not at EOF
45
- if ($this->limit == -1) {
46
- return false;
47
- }
48
-
49
- return $this->stream->tell() >= $this->offset + $this->limit;
50
- }
51
-
52
- /**
53
- * Returns the size of the limited subset of data
54
- * {@inheritdoc}
55
- */
56
- public function getSize()
57
- {
58
- if (null === ($length = $this->stream->getSize())) {
59
- return null;
60
- } elseif ($this->limit == -1) {
61
- return $length - $this->offset;
62
- } else {
63
- return min($this->limit, $length - $this->offset);
64
- }
65
- }
66
-
67
- /**
68
- * Allow for a bounded seek on the read limited stream
69
- * {@inheritdoc}
70
- */
71
- public function seek($offset, $whence = SEEK_SET)
72
- {
73
- if ($whence !== SEEK_SET || $offset < 0) {
74
- throw new \RuntimeException(sprintf(
75
- 'Cannot seek to offset % with whence %s',
76
- $offset,
77
- $whence
78
- ));
79
- }
80
-
81
- $offset += $this->offset;
82
-
83
- if ($this->limit !== -1) {
84
- if ($offset > $this->offset + $this->limit) {
85
- $offset = $this->offset + $this->limit;
86
- }
87
- }
88
-
89
- $this->stream->seek($offset);
90
- }
91
-
92
- /**
93
- * Give a relative tell()
94
- * {@inheritdoc}
95
- */
96
- public function tell()
97
- {
98
- return $this->stream->tell() - $this->offset;
99
- }
100
-
101
- /**
102
- * Set the offset to start limiting from
103
- *
104
- * @param int $offset Offset to seek to and begin byte limiting from
105
- *
106
- * @throws \RuntimeException if the stream cannot be seeked.
107
- */
108
- public function setOffset($offset)
109
- {
110
- $current = $this->stream->tell();
111
-
112
- if ($current !== $offset) {
113
- // If the stream cannot seek to the offset position, then read to it
114
- if ($this->stream->isSeekable()) {
115
- $this->stream->seek($offset);
116
- } elseif ($current > $offset) {
117
- throw new \RuntimeException("Could not seek to stream offset $offset");
118
- } else {
119
- $this->stream->read($offset - $current);
120
- }
121
- }
122
-
123
- $this->offset = $offset;
124
- }
125
-
126
- /**
127
- * Set the limit of bytes that the decorator allows to be read from the
128
- * stream.
129
- *
130
- * @param int $limit Number of bytes to allow to be read from the stream.
131
- * Use -1 for no limit.
132
- */
133
- public function setLimit($limit)
134
- {
135
- $this->limit = $limit;
136
- }
137
-
138
- public function read($length)
139
- {
140
- if ($this->limit == -1) {
141
- return $this->stream->read($length);
142
- }
143
-
144
- // Check if the current position is less than the total allowed
145
- // bytes + original offset
146
- $remaining = ($this->offset + $this->limit) - $this->stream->tell();
147
- if ($remaining > 0) {
148
- // Only return the amount of requested data, ensuring that the byte
149
- // limit is not exceeded
150
- return $this->stream->read(min($remaining, $length));
151
- }
152
-
153
- return '';
154
- }
155
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/psr7/src/MessageTrait.php DELETED
@@ -1,183 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Psr7;
3
-
4
- use Psr\Http\Message\StreamInterface;
5
-
6
- /**
7
- * Trait implementing functionality common to requests and responses.
8
- */
9
- trait MessageTrait
10
- {
11
- /** @var array Map of all registered headers, as original name => array of values */
12
- private $headers = [];
13
-
14
- /** @var array Map of lowercase header name => original name at registration */
15
- private $headerNames = [];
16
-
17
- /** @var string */
18
- private $protocol = '1.1';
19
-
20
- /** @var StreamInterface */
21
- private $stream;
22
-
23
- public function getProtocolVersion()
24
- {
25
- return $this->protocol;
26
- }
27
-
28
- public function withProtocolVersion($version)
29
- {
30
- if ($this->protocol === $version) {
31
- return $this;
32
- }
33
-
34
- $new = clone $this;
35
- $new->protocol = $version;
36
- return $new;
37
- }
38
-
39
- public function getHeaders()
40
- {
41
- return $this->headers;
42
- }
43
-
44
- public function hasHeader($header)
45
- {
46
- return isset($this->headerNames[strtolower($header)]);
47
- }
48
-
49
- public function getHeader($header)
50
- {
51
- $header = strtolower($header);
52
-
53
- if (!isset($this->headerNames[$header])) {
54
- return [];
55
- }
56
-
57
- $header = $this->headerNames[$header];
58
-
59
- return $this->headers[$header];
60
- }
61
-
62
- public function getHeaderLine($header)
63
- {
64
- return implode(', ', $this->getHeader($header));
65
- }
66
-
67
- public function withHeader($header, $value)
68
- {
69
- if (!is_array($value)) {
70
- $value = [$value];
71
- }
72
-
73
- $value = $this->trimHeaderValues($value);
74
- $normalized = strtolower($header);
75
-
76
- $new = clone $this;
77
- if (isset($new->headerNames[$normalized])) {
78
- unset($new->headers[$new->headerNames[$normalized]]);
79
- }
80
- $new->headerNames[$normalized] = $header;
81
- $new->headers[$header] = $value;
82
-
83
- return $new;
84
- }
85
-
86
- public function withAddedHeader($header, $value)
87
- {
88
- if (!is_array($value)) {
89
- $value = [$value];
90
- }
91
-
92
- $value = $this->trimHeaderValues($value);
93
- $normalized = strtolower($header);
94
-
95
- $new = clone $this;
96
- if (isset($new->headerNames[$normalized])) {
97
- $header = $this->headerNames[$normalized];
98
- $new->headers[$header] = array_merge($this->headers[$header], $value);
99
- } else {
100
- $new->headerNames[$normalized] = $header;
101
- $new->headers[$header] = $value;
102
- }
103
-
104
- return $new;
105
- }
106
-
107
- public function withoutHeader($header)
108
- {
109
- $normalized = strtolower($header);
110
-
111
- if (!isset($this->headerNames[$normalized])) {
112
- return $this;
113
- }
114
-
115
- $header = $this->headerNames[$normalized];
116
-
117
- $new = clone $this;
118
- unset($new->headers[$header], $new->headerNames[$normalized]);
119
-
120
- return $new;
121
- }
122
-
123
- public function getBody()
124
- {
125
- if (!$this->stream) {
126
- $this->stream = stream_for('');
127
- }
128
-
129
- return $this->stream;
130
- }
131
-
132
- public function withBody(StreamInterface $body)
133
- {
134
- if ($body === $this->stream) {
135
- return $this;
136
- }
137
-
138
- $new = clone $this;
139
- $new->stream = $body;
140
- return $new;
141
- }
142
-
143
- private function setHeaders(array $headers)
144
- {
145
- $this->headerNames = $this->headers = [];
146
- foreach ($headers as $header => $value) {
147
- if (!is_array($value)) {
148
- $value = [$value];
149
- }
150
-
151
- $value = $this->trimHeaderValues($value);
152
- $normalized = strtolower($header);
153
- if (isset($this->headerNames[$normalized])) {
154
- $header = $this->headerNames[$normalized];
155
- $this->headers[$header] = array_merge($this->headers[$header], $value);
156
- } else {
157
- $this->headerNames[$normalized] = $header;
158
- $this->headers[$header] = $value;
159
- }
160
- }
161
- }
162
-
163
- /**
164
- * Trims whitespace from the header values.
165
- *
166
- * Spaces and tabs ought to be excluded by parsers when extracting the field value from a header field.
167
- *
168
- * header-field = field-name ":" OWS field-value OWS
169
- * OWS = *( SP / HTAB )
170
- *
171
- * @param string[] $values Header values
172
- *
173
- * @return string[] Trimmed header values
174
- *
175
- * @see https://tools.ietf.org/html/rfc7230#section-3.2.4
176
- */
177
- private function trimHeaderValues(array $values)
178
- {
179
- return array_map(function ($value) {
180
- return trim($value, " \t");
181
- }, $values);
182
- }
183
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/psr7/src/MultipartStream.php DELETED
@@ -1,153 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Psr7;
3
-
4
- use Psr\Http\Message\StreamInterface;
5
-
6
- /**
7
- * Stream that when read returns bytes for a streaming multipart or
8
- * multipart/form-data stream.
9
- */
10
- class MultipartStream implements StreamInterface
11
- {
12
- use StreamDecoratorTrait;
13
-
14
- private $boundary;
15
-
16
- /**
17
- * @param array $elements Array of associative arrays, each containing a
18
- * required "name" key mapping to the form field,
19
- * name, a required "contents" key mapping to a
20
- * StreamInterface/resource/string, an optional
21
- * "headers" associative array of custom headers,
22
- * and an optional "filename" key mapping to a
23
- * string to send as the filename in the part.
24
- * @param string $boundary You can optionally provide a specific boundary
25
- *
26
- * @throws \InvalidArgumentException
27
- */
28
- public function __construct(array $elements = [], $boundary = null)
29
- {
30
- $this->boundary = $boundary ?: sha1(uniqid('', true));
31
- $this->stream = $this->createStream($elements);
32
- }
33
-
34
- /**
35
- * Get the boundary
36
- *
37
- * @return string
38
- */
39
- public function getBoundary()
40
- {
41
- return $this->boundary;
42
- }
43
-
44
- public function isWritable()
45
- {
46
- return false;
47
- }
48
-
49
- /**
50
- * Get the headers needed before transferring the content of a POST file
51
- */
52
- private function getHeaders(array $headers)
53
- {
54
- $str = '';
55
- foreach ($headers as $key => $value) {
56
- $str .= "{$key}: {$value}\r\n";
57
- }
58
-
59
- return "--{$this->boundary}\r\n" . trim($str) . "\r\n\r\n";
60
- }
61
-
62
- /**
63
- * Create the aggregate stream that will be used to upload the POST data
64
- */
65
- protected function createStream(array $elements)
66
- {
67
- $stream = new AppendStream();
68
-
69
- foreach ($elements as $element) {
70
- $this->addElement($stream, $element);
71
- }
72
-
73
- // Add the trailing boundary with CRLF
74
- $stream->addStream(stream_for("--{$this->boundary}--\r\n"));
75
-
76
- return $stream;
77
- }
78
-
79
- private function addElement(AppendStream $stream, array $element)
80
- {
81
- foreach (['contents', 'name'] as $key) {
82
- if (!array_key_exists($key, $element)) {
83
- throw new \InvalidArgumentException("A '{$key}' key is required");
84
- }
85
- }
86
-
87
- $element['contents'] = stream_for($element['contents']);
88
-
89
- if (empty($element['filename'])) {
90
- $uri = $element['contents']->getMetadata('uri');
91
- if (substr($uri, 0, 6) !== 'php://') {
92
- $element['filename'] = $uri;
93
- }
94
- }
95
-
96
- list($body, $headers) = $this->createElement(
97
- $element['name'],
98
- $element['contents'],
99
- isset($element['filename']) ? $element['filename'] : null,
100
- isset($element['headers']) ? $element['headers'] : []
101
- );
102
-
103
- $stream->addStream(stream_for($this->getHeaders($headers)));
104
- $stream->addStream($body);
105
- $stream->addStream(stream_for("\r\n"));
106
- }
107
-
108
- /**
109
- * @return array
110
- */
111
- private function createElement($name, StreamInterface $stream, $filename, array $headers)
112
- {
113
- // Set a default content-disposition header if one was no provided
114
- $disposition = $this->getHeader($headers, 'content-disposition');
115
- if (!$disposition) {
116
- $headers['Content-Disposition'] = ($filename === '0' || $filename)
117
- ? sprintf('form-data; name="%s"; filename="%s"',
118
- $name,
119
- basename($filename))
120
- : "form-data; name=\"{$name}\"";
121
- }
122
-
123
- // Set a default content-length header if one was no provided
124
- $length = $this->getHeader($headers, 'content-length');
125
- if (!$length) {
126
- if ($length = $stream->getSize()) {
127
- $headers['Content-Length'] = (string) $length;
128
- }
129
- }
130
-
131
- // Set a default Content-Type if one was not supplied
132
- $type = $this->getHeader($headers, 'content-type');
133
- if (!$type && ($filename === '0' || $filename)) {
134
- if ($type = mimetype_from_filename($filename)) {
135
- $headers['Content-Type'] = $type;
136
- }
137
- }
138
-
139
- return [$stream, $headers];
140
- }
141
-
142
- private function getHeader(array $headers, $key)
143
- {
144
- $lowercaseHeader = strtolower($key);
145
- foreach ($headers as $k => $v) {
146
- if (strtolower($k) === $lowercaseHeader) {
147
- return $v;
148
- }
149
- }
150
-
151
- return null;
152
- }
153
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/psr7/src/NoSeekStream.php DELETED
@@ -1,22 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Psr7;
3
-
4
- use Psr\Http\Message\StreamInterface;
5
-
6
- /**
7
- * Stream decorator that prevents a stream from being seeked
8
- */
9
- class NoSeekStream implements StreamInterface
10
- {
11
- use StreamDecoratorTrait;
12
-
13
- public function seek($offset, $whence = SEEK_SET)
14
- {
15
- throw new \RuntimeException('Cannot seek a NoSeekStream');
16
- }
17
-
18
- public function isSeekable()
19
- {
20
- return false;
21
- }
22
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/psr7/src/PumpStream.php DELETED
@@ -1,165 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Psr7;
3
-
4
- use Psr\Http\Message\StreamInterface;
5
-
6
- /**
7
- * Provides a read only stream that pumps data from a PHP callable.
8
- *
9
- * When invoking the provided callable, the PumpStream will pass the amount of
10
- * data requested to read to the callable. The callable can choose to ignore
11
- * this value and return fewer or more bytes than requested. Any extra data
12
- * returned by the provided callable is buffered internally until drained using
13
- * the read() function of the PumpStream. The provided callable MUST return
14
- * false when there is no more data to read.
15
- */
16
- class PumpStream implements StreamInterface
17
- {
18
- /** @var callable */
19
- private $source;
20
-
21
- /** @var int */
22
- private $size;
23
-
24
- /** @var int */
25
- private $tellPos = 0;
26
-
27
- /** @var array */
28
- private $metadata;
29
-
30
- /** @var BufferStream */
31
- private $buffer;
32
-
33
- /**
34
- * @param callable $source Source of the stream data. The callable MAY
35
- * accept an integer argument used to control the
36
- * amount of data to return. The callable MUST
37
- * return a string when called, or false on error
38
- * or EOF.
39
- * @param array $options Stream options:
40
- * - metadata: Hash of metadata to use with stream.
41
- * - size: Size of the stream, if known.
42
- */
43
- public function __construct(callable $source, array $options = [])
44
- {
45
- $this->source = $source;
46
- $this->size = isset($options['size']) ? $options['size'] : null;
47
- $this->metadata = isset($options['metadata']) ? $options['metadata'] : [];
48
- $this->buffer = new BufferStream();
49
- }
50
-
51
- public function __toString()
52
- {
53
- try {
54
- return copy_to_string($this);
55
- } catch (\Exception $e) {
56
- return '';
57
- }
58
- }
59
-
60
- public function close()
61
- {
62
- $this->detach();
63
- }
64
-
65
- public function detach()
66
- {
67
- $this->tellPos = false;
68
- $this->source = null;
69
- }
70
-
71
- public function getSize()
72
- {
73
- return $this->size;
74
- }
75
-
76
- public function tell()
77
- {
78
- return $this->tellPos;
79
- }
80
-
81
- public function eof()
82
- {
83
- return !$this->source;
84
- }
85
-
86
- public function isSeekable()
87
- {
88
- return false;
89
- }
90
-
91
- public function rewind()
92
- {
93
- $this->seek(0);
94
- }
95
-
96
- public function seek($offset, $whence = SEEK_SET)
97
- {
98
- throw new \RuntimeException('Cannot seek a PumpStream');
99
- }
100
-
101
- public function isWritable()
102
- {
103
- return false;
104
- }
105
-
106
- public function write($string)
107
- {
108
- throw new \RuntimeException('Cannot write to a PumpStream');
109
- }
110
-
111
- public function isReadable()
112
- {
113
- return true;
114
- }
115
-
116
- public function read($length)
117
- {
118
- $data = $this->buffer->read($length);
119
- $readLen = strlen($data);
120
- $this->tellPos += $readLen;
121
- $remaining = $length - $readLen;
122
-
123
- if ($remaining) {
124
- $this->pump($remaining);
125
- $data .= $this->buffer->read($remaining);
126
- $this->tellPos += strlen($data) - $readLen;
127
- }
128
-
129
- return $data;
130
- }
131
-
132
- public function getContents()
133
- {
134
- $result = '';
135
- while (!$this->eof()) {
136
- $result .= $this->read(1000000);
137
- }
138
-
139
- return $result;
140
- }
141
-
142
- public function getMetadata($key = null)
143
- {
144
- if (!$key) {
145
- return $this->metadata;
146
- }
147
-
148
- return isset($this->metadata[$key]) ? $this->metadata[$key] : null;
149
- }
150
-
151
- private function pump($length)
152
- {
153
- if ($this->source) {
154
- do {
155
- $data = call_user_func($this->source, $length);
156
- if ($data === false || $data === null) {
157
- $this->source = null;
158
- return;
159
- }
160
- $this->buffer->write($data);
161
- $length -= strlen($data);
162
- } while ($length > 0);
163
- }
164
- }
165
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/psr7/src/Request.php DELETED
@@ -1,142 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Psr7;
3
-
4
- use InvalidArgumentException;
5
- use Psr\Http\Message\RequestInterface;
6
- use Psr\Http\Message\StreamInterface;
7
- use Psr\Http\Message\UriInterface;
8
-
9
- /**
10
- * PSR-7 request implementation.
11
- */
12
- class Request implements RequestInterface
13
- {
14
- use MessageTrait;
15
-
16
- /** @var string */
17
- private $method;
18
-
19
- /** @var null|string */
20
- private $requestTarget;
21
-
22
- /** @var UriInterface */
23
- private $uri;
24
-
25
- /**
26
- * @param string $method HTTP method
27
- * @param string|UriInterface $uri URI
28
- * @param array $headers Request headers
29
- * @param string|null|resource|StreamInterface $body Request body
30
- * @param string $version Protocol version
31
- */
32
- public function __construct(
33
- $method,
34
- $uri,
35
- array $headers = [],
36
- $body = null,
37
- $version = '1.1'
38
- ) {
39
- if (!($uri instanceof UriInterface)) {
40
- $uri = new Uri($uri);
41
- }
42
-
43
- $this->method = strtoupper($method);
44
- $this->uri = $uri;
45
- $this->setHeaders($headers);
46
- $this->protocol = $version;
47
-
48
- if (!isset($this->headerNames['host'])) {
49
- $this->updateHostFromUri();
50
- }
51
-
52
- if ($body !== '' && $body !== null) {
53
- $this->stream = stream_for($body);
54
- }
55
- }
56
-
57
- public function getRequestTarget()
58
- {
59
- if ($this->requestTarget !== null) {
60
- return $this->requestTarget;
61
- }
62
-
63
- $target = $this->uri->getPath();
64
- if ($target == '') {
65
- $target = '/';
66
- }
67
- if ($this->uri->getQuery() != '') {
68
- $target .= '?' . $this->uri->getQuery();
69
- }
70
-
71
- return $target;
72
- }
73
-
74
- public function withRequestTarget($requestTarget)
75
- {
76
- if (preg_match('#\s#', $requestTarget)) {
77
- throw new InvalidArgumentException(
78
- 'Invalid request target provided; cannot contain whitespace'
79
- );
80
- }
81
-
82
- $new = clone $this;
83
- $new->requestTarget = $requestTarget;
84
- return $new;
85
- }
86
-
87
- public function getMethod()
88
- {
89
- return $this->method;
90
- }
91
-
92
- public function withMethod($method)
93
- {
94
- $new = clone $this;
95
- $new->method = strtoupper($method);
96
- return $new;
97
- }
98
-
99
- public function getUri()
100
- {
101
- return $this->uri;
102
- }
103
-
104
- public function withUri(UriInterface $uri, $preserveHost = false)
105
- {
106
- if ($uri === $this->uri) {
107
- return $this;
108
- }
109
-
110
- $new = clone $this;
111
- $new->uri = $uri;
112
-
113
- if (!$preserveHost || !isset($this->headerNames['host'])) {
114
- $new->updateHostFromUri();
115
- }
116
-
117
- return $new;
118
- }
119
-
120
- private function updateHostFromUri()
121
- {
122
- $host = $this->uri->getHost();
123
-
124
- if ($host == '') {
125
- return;
126
- }
127
-
128
- if (($port = $this->uri->getPort()) !== null) {
129
- $host .= ':' . $port;
130
- }
131
-
132
- if (isset($this->headerNames['host'])) {
133
- $header = $this->headerNames['host'];
134
- } else {
135
- $header = 'Host';
136
- $this->headerNames['host'] = 'Host';
137
- }
138
- // Ensure Host is the first header.
139
- // See: http://tools.ietf.org/html/rfc7230#section-5.4
140
- $this->headers = [$header => [$host]] + $this->headers;
141
- }
142
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/psr7/src/Response.php DELETED
@@ -1,136 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Psr7;
3
-
4
- use Psr\Http\Message\ResponseInterface;
5
- use Psr\Http\Message\StreamInterface;
6
-
7
- /**
8
- * PSR-7 response implementation.
9
- */
10
- class Response implements ResponseInterface
11
- {
12
- use MessageTrait;
13
-
14
- /** @var array Map of standard HTTP status code/reason phrases */
15
- private static $phrases = [
16
- 100 => 'Continue',
17
- 101 => 'Switching Protocols',
18
- 102 => 'Processing',
19
- 200 => 'OK',
20
- 201 => 'Created',
21
- 202 => 'Accepted',
22
- 203 => 'Non-Authoritative Information',
23
- 204 => 'No Content',
24
- 205 => 'Reset Content',
25
- 206 => 'Partial Content',
26
- 207 => 'Multi-status',
27
- 208 => 'Already Reported',
28
- 300 => 'Multiple Choices',
29
- 301 => 'Moved Permanently',
30
- 302 => 'Found',
31
- 303 => 'See Other',
32
- 304 => 'Not Modified',
33
- 305 => 'Use Proxy',
34
- 306 => 'Switch Proxy',
35
- 307 => 'Temporary Redirect',
36
- 400 => 'Bad Request',
37
- 401 => 'Unauthorized',
38
- 402 => 'Payment Required',
39
- 403 => 'Forbidden',
40
- 404 => 'Not Found',
41
- 405 => 'Method Not Allowed',
42
- 406 => 'Not Acceptable',
43
- 407 => 'Proxy Authentication Required',
44
- 408 => 'Request Time-out',
45
- 409 => 'Conflict',
46
- 410 => 'Gone',
47
- 411 => 'Length Required',
48
- 412 => 'Precondition Failed',
49
- 413 => 'Request Entity Too Large',
50
- 414 => 'Request-URI Too Large',
51
- 415 => 'Unsupported Media Type',
52
- 416 => 'Requested range not satisfiable',
53
- 417 => 'Expectation Failed',
54
- 418 => 'I\'m a teapot',
55
- 422 => 'Unprocessable Entity',
56
- 423 => 'Locked',
57
- 424 => 'Failed Dependency',
58
- 425 => 'Unordered Collection',
59
- 426 => 'Upgrade Required',
60
- 428 => 'Precondition Required',
61
- 429 => 'Too Many Requests',
62
- 431 => 'Request Header Fields Too Large',
63
- 451 => 'Unavailable For Legal Reasons',
64
- 500 => 'Internal Server Error',
65
- 501 => 'Not Implemented',
66
- 502 => 'Bad Gateway',
67
- 503 => 'Service Unavailable',
68
- 504 => 'Gateway Time-out',
69
- 505 => 'HTTP Version not supported',
70
- 506 => 'Variant Also Negotiates',
71
- 507 => 'Insufficient Storage',
72
- 508 => 'Loop Detected',
73
- 511 => 'Network Authentication Required',
74
- ];
75
-
76
- /** @var string */
77
- private $reasonPhrase = '';
78
-
79
- /** @var int */
80
- private $statusCode = 200;
81
-
82
- /**
83
- * @param int $status Status code
84
- * @param array $headers Response headers
85
- * @param string|null|resource|StreamInterface $body Response body
86
- * @param string $version Protocol version
87
- * @param string|null $reason Reason phrase (when empty a default will be used based on the status code)
88
- */
89
- public function __construct(
90
- $status = 200,
91
- array $headers = [],
92
- $body = null,
93
- $version = '1.1',
94
- $reason = null
95
- ) {
96
- if (filter_var($status, FILTER_VALIDATE_INT) === false) {
97
- throw new \InvalidArgumentException('Status code must be an integer value.');
98
- }
99
-
100
- $this->statusCode = (int) $status;
101
-
102
- if ($body !== '' && $body !== null) {
103
- $this->stream = stream_for($body);
104
- }
105
-
106
- $this->setHeaders($headers);
107
- if ($reason == '' && isset(self::$phrases[$this->statusCode])) {
108
- $this->reasonPhrase = self::$phrases[$this->statusCode];
109
- } else {
110
- $this->reasonPhrase = (string) $reason;
111
- }
112
-
113
- $this->protocol = $version;
114
- }
115
-
116
- public function getStatusCode()
117
- {
118
- return $this->statusCode;
119
- }
120
-
121
- public function getReasonPhrase()
122
- {
123
- return $this->reasonPhrase;
124
- }
125
-
126
- public function withStatus($code, $reasonPhrase = '')
127
- {
128
- $new = clone $this;
129
- $new->statusCode = (int) $code;
130
- if ($reasonPhrase == '' && isset(self::$phrases[$new->statusCode])) {
131
- $reasonPhrase = self::$phrases[$new->statusCode];
132
- }
133
- $new->reasonPhrase = $reasonPhrase;
134
- return $new;
135
- }
136
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/psr7/src/Rfc7230.php DELETED
@@ -1,18 +0,0 @@
1
- <?php
2
-
3
- namespace GuzzleHttp\Psr7;
4
-
5
- final class Rfc7230
6
- {
7
- /**
8
- * Header related regular expressions (copied from amphp/http package)
9
- * (Note: once we require PHP 7.x we could just depend on the upstream package)
10
- *
11
- * Note: header delimiter (\r\n) is modified to \r?\n to accept line feed only delimiters for BC reasons.
12
- *
13
- * @link https://github.com/amphp/http/blob/v1.0.1/src/Rfc7230.php#L12-L15
14
- * @license https://github.com/amphp/http/blob/v1.0.1/LICENSE
15
- */
16
- const HEADER_REGEX = "(^([^()<>@,;:\\\"/[\]?={}\x01-\x20\x7F]++):[ \t]*+((?:[ \t]*+[\x21-\x7E\x80-\xFF]++)*+)[ \t]*+\r?\n)m";
17
- const HEADER_FOLD_REGEX = "(\r?\n[ \t]++)";
18
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/psr7/src/ServerRequest.php DELETED
@@ -1,376 +0,0 @@
1
- <?php
2
-
3
- namespace GuzzleHttp\Psr7;
4
-
5
- use InvalidArgumentException;
6
- use Psr\Http\Message\ServerRequestInterface;
7
- use Psr\Http\Message\UriInterface;
8
- use Psr\Http\Message\StreamInterface;
9
- use Psr\Http\Message\UploadedFileInterface;
10
-
11
- /**
12
- * Server-side HTTP request
13
- *
14
- * Extends the Request definition to add methods for accessing incoming data,
15
- * specifically server parameters, cookies, matched path parameters, query
16
- * string arguments, body parameters, and upload file information.
17
- *
18
- * "Attributes" are discovered via decomposing the request (and usually
19
- * specifically the URI path), and typically will be injected by the application.
20
- *
21
- * Requests are considered immutable; all methods that might change state are
22
- * implemented such that they retain the internal state of the current
23
- * message and return a new instance that contains the changed state.
24
- */
25
- class ServerRequest extends Request implements ServerRequestInterface
26
- {
27
- /**
28
- * @var array
29
- */
30
- private $attributes = [];
31
-
32
- /**
33
- * @var array
34
- */
35
- private $cookieParams = [];
36
-
37
- /**
38
- * @var null|array|object
39
- */
40
- private $parsedBody;
41
-
42
- /**
43
- * @var array
44
- */
45
- private $queryParams = [];
46
-
47
- /**
48
- * @var array
49
- */
50
- private $serverParams;
51
-
52
- /**
53
- * @var array
54
- */
55
- private $uploadedFiles = [];
56
-
57
- /**
58
- * @param string $method HTTP method
59
- * @param string|UriInterface $uri URI
60
- * @param array $headers Request headers
61
- * @param string|null|resource|StreamInterface $body Request body
62
- * @param string $version Protocol version
63
- * @param array $serverParams Typically the $_SERVER superglobal
64
- */
65
- public function __construct(
66
- $method,
67
- $uri,
68
- array $headers = [],
69
- $body = null,
70
- $version = '1.1',
71
- array $serverParams = []
72
- ) {
73
- $this->serverParams = $serverParams;
74
-
75
- parent::__construct($method, $uri, $headers, $body, $version);
76
- }
77
-
78
- /**
79
- * Return an UploadedFile instance array.
80
- *
81
- * @param array $files A array which respect $_FILES structure
82
- * @throws InvalidArgumentException for unrecognized values
83
- * @return array
84
- */
85
- public static function normalizeFiles(array $files)
86
- {
87
- $normalized = [];
88
-
89
- foreach ($files as $key => $value) {
90
- if ($value instanceof UploadedFileInterface) {
91
- $normalized[$key] = $value;
92
- } elseif (is_array($value) && isset($value['tmp_name'])) {
93
- $normalized[$key] = self::createUploadedFileFromSpec($value);
94
- } elseif (is_array($value)) {
95
- $normalized[$key] = self::normalizeFiles($value);
96
- continue;
97
- } else {
98
- throw new InvalidArgumentException('Invalid value in files specification');
99
- }
100
- }
101
-
102
- return $normalized;
103
- }
104
-
105
- /**
106
- * Create and return an UploadedFile instance from a $_FILES specification.
107
- *
108
- * If the specification represents an array of values, this method will
109
- * delegate to normalizeNestedFileSpec() and return that return value.
110
- *
111
- * @param array $value $_FILES struct
112
- * @return array|UploadedFileInterface
113
- */
114
- private static function createUploadedFileFromSpec(array $value)
115
- {
116
- if (is_array($value['tmp_name'])) {
117
- return self::normalizeNestedFileSpec($value);
118
- }
119
-
120
- return new UploadedFile(
121
- $value['tmp_name'],
122
- (int) $value['size'],
123
- (int) $value['error'],
124
- $value['name'],
125
- $value['type']
126
- );
127
- }
128
-
129
- /**
130
- * Normalize an array of file specifications.
131
- *
132
- * Loops through all nested files and returns a normalized array of
133
- * UploadedFileInterface instances.
134
- *
135
- * @param array $files
136
- * @return UploadedFileInterface[]
137
- */
138
- private static function normalizeNestedFileSpec(array $files = [])
139
- {
140
- $normalizedFiles = [];
141
-
142
- foreach (array_keys($files['tmp_name']) as $key) {
143
- $spec = [
144
- 'tmp_name' => $files['tmp_name'][$key],
145
- 'size' => $files['size'][$key],
146
- 'error' => $files['error'][$key],
147
- 'name' => $files['name'][$key],
148
- 'type' => $files['type'][$key],
149
- ];
150
- $normalizedFiles[$key] = self::createUploadedFileFromSpec($spec);
151
- }
152
-
153
- return $normalizedFiles;
154
- }
155
-
156
- /**
157
- * Return a ServerRequest populated with superglobals:
158
- * $_GET
159
- * $_POST
160
- * $_COOKIE
161
- * $_FILES
162
- * $_SERVER
163
- *
164
- * @return ServerRequestInterface
165
- */
166
- public static function fromGlobals()
167
- {
168
- $method = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : 'GET';
169
- $headers = getallheaders();
170
- $uri = self::getUriFromGlobals();
171
- $body = new LazyOpenStream('php://input', 'r+');
172
- $protocol = isset($_SERVER['SERVER_PROTOCOL']) ? str_replace('HTTP/', '', $_SERVER['SERVER_PROTOCOL']) : '1.1';
173
-
174
- $serverRequest = new ServerRequest($method, $uri, $headers, $body, $protocol, $_SERVER);
175
-
176
- return $serverRequest
177
- ->withCookieParams($_COOKIE)
178
- ->withQueryParams($_GET)
179
- ->withParsedBody($_POST)
180
- ->withUploadedFiles(self::normalizeFiles($_FILES));
181
- }
182
-
183
- private static function extractHostAndPortFromAuthority($authority)
184
- {
185
- $uri = 'http://'.$authority;
186
- $parts = parse_url($uri);
187
- if (false === $parts) {
188
- return [null, null];
189
- }
190
-
191
- $host = isset($parts['host']) ? $parts['host'] : null;
192
- $port = isset($parts['port']) ? $parts['port'] : null;
193
-
194
- return [$host, $port];
195
- }
196
-
197
- /**
198
- * Get a Uri populated with values from $_SERVER.
199
- *
200
- * @return UriInterface
201
- */
202
- public static function getUriFromGlobals()
203
- {
204
- $uri = new Uri('');
205
-
206
- $uri = $uri->withScheme(!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' ? 'https' : 'http');
207
-
208
- $hasPort = false;
209
- if (isset($_SERVER['HTTP_HOST'])) {
210
- list($host, $port) = self::extractHostAndPortFromAuthority($_SERVER['HTTP_HOST']);
211
- if ($host !== null) {
212
- $uri = $uri->withHost($host);
213
- }
214
-
215
- if ($port !== null) {
216
- $hasPort = true;
217
- $uri = $uri->withPort($port);
218
- }
219
- } elseif (isset($_SERVER['SERVER_NAME'])) {
220
- $uri = $uri->withHost($_SERVER['SERVER_NAME']);
221
- } elseif (isset($_SERVER['SERVER_ADDR'])) {
222
- $uri = $uri->withHost($_SERVER['SERVER_ADDR']);
223
- }
224
-
225
- if (!$hasPort && isset($_SERVER['SERVER_PORT'])) {
226
- $uri = $uri->withPort($_SERVER['SERVER_PORT']);
227
- }
228
-
229
- $hasQuery = false;
230
- if (isset($_SERVER['REQUEST_URI'])) {
231
- $requestUriParts = explode('?', $_SERVER['REQUEST_URI'], 2);
232
- $uri = $uri->withPath($requestUriParts[0]);
233
- if (isset($requestUriParts[1])) {
234
- $hasQuery = true;
235
- $uri = $uri->withQuery($requestUriParts[1]);
236
- }
237
- }
238
-
239
- if (!$hasQuery && isset($_SERVER['QUERY_STRING'])) {
240
- $uri = $uri->withQuery($_SERVER['QUERY_STRING']);
241
- }
242
-
243
- return $uri;
244
- }
245
-
246
-
247
- /**
248
- * {@inheritdoc}
249
- */
250
- public function getServerParams()
251
- {
252
- return $this->serverParams;
253
- }
254
-
255
- /**
256
- * {@inheritdoc}
257
- */
258
- public function getUploadedFiles()
259
- {
260
- return $this->uploadedFiles;
261
- }
262
-
263
- /**
264
- * {@inheritdoc}
265
- */
266
- public function withUploadedFiles(array $uploadedFiles)
267
- {
268
- $new = clone $this;
269
- $new->uploadedFiles = $uploadedFiles;
270
-
271
- return $new;
272
- }
273
-
274
- /**
275
- * {@inheritdoc}
276
- */
277
- public function getCookieParams()
278
- {
279
- return $this->cookieParams;
280
- }
281
-
282
- /**
283
- * {@inheritdoc}
284
- */
285
- public function withCookieParams(array $cookies)
286
- {
287
- $new = clone $this;
288
- $new->cookieParams = $cookies;
289
-
290
- return $new;
291
- }
292
-
293
- /**
294
- * {@inheritdoc}
295
- */
296
- public function getQueryParams()
297
- {
298
- return $this->queryParams;
299
- }
300
-
301
- /**
302
- * {@inheritdoc}
303
- */
304
- public function withQueryParams(array $query)
305
- {
306
- $new = clone $this;
307
- $new->queryParams = $query;
308
-
309
- return $new;
310
- }
311
-
312
- /**
313
- * {@inheritdoc}
314
- */
315
- public function getParsedBody()
316
- {
317
- return $this->parsedBody;
318
- }
319
-
320
- /**
321
- * {@inheritdoc}
322
- */
323
- public function withParsedBody($data)
324
- {
325
- $new = clone $this;
326
- $new->parsedBody = $data;
327
-
328
- return $new;
329
- }
330
-
331
- /**
332
- * {@inheritdoc}
333
- */
334
- public function getAttributes()
335
- {
336
- return $this->attributes;
337
- }
338
-
339
- /**
340
- * {@inheritdoc}
341
- */
342
- public function getAttribute($attribute, $default = null)
343
- {
344
- if (false === array_key_exists($attribute, $this->attributes)) {
345
- return $default;
346
- }
347
-
348
- return $this->attributes[$attribute];
349
- }
350
-
351
- /**
352
- * {@inheritdoc}
353
- */
354
- public function withAttribute($attribute, $value)
355
- {
356
- $new = clone $this;
357
- $new->attributes[$attribute] = $value;
358
-
359
- return $new;
360
- }
361
-
362
- /**
363
- * {@inheritdoc}
364
- */
365
- public function withoutAttribute($attribute)
366
- {
367
- if (false === array_key_exists($attribute, $this->attributes)) {
368
- return $this;
369
- }
370
-
371
- $new = clone $this;
372
- unset($new->attributes[$attribute]);
373
-
374
- return $new;
375
- }
376
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/psr7/src/Stream.php DELETED
@@ -1,270 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Psr7;
3
-
4
- use Psr\Http\Message\StreamInterface;
5
-
6
- /**
7
- * PHP stream implementation.
8
- *
9
- * @var $stream
10
- */
11
- class Stream implements StreamInterface
12
- {
13
- private $stream;
14
- private $size;
15
- private $seekable;
16
- private $readable;
17
- private $writable;
18
- private $uri;
19
- private $customMetadata;
20
-
21
- /** @var array Hash of readable and writable stream types */
22
- private static $readWriteHash = [
23
- 'read' => [
24
- 'r' => true, 'w+' => true, 'r+' => true, 'x+' => true, 'c+' => true,
25
- 'rb' => true, 'w+b' => true, 'r+b' => true, 'x+b' => true,
26
- 'c+b' => true, 'rt' => true, 'w+t' => true, 'r+t' => true,
27
- 'x+t' => true, 'c+t' => true, 'a+' => true, 'rb+' => true,
28
- ],
29
- 'write' => [
30
- 'w' => true, 'w+' => true, 'rw' => true, 'r+' => true, 'x+' => true,
31
- 'c+' => true, 'wb' => true, 'w+b' => true, 'r+b' => true, 'rb+' => true,
32
- 'x+b' => true, 'c+b' => true, 'w+t' => true, 'r+t' => true,
33
- 'x+t' => true, 'c+t' => true, 'a' => true, 'a+' => true
34
- ]
35
- ];
36
-
37
- /**
38
- * This constructor accepts an associative array of options.
39
- *
40
- * - size: (int) If a read stream would otherwise have an indeterminate
41
- * size, but the size is known due to foreknowledge, then you can
42
- * provide that size, in bytes.
43
- * - metadata: (array) Any additional metadata to return when the metadata
44
- * of the stream is accessed.
45
- *
46
- * @param resource $stream Stream resource to wrap.
47
- * @param array $options Associative array of options.
48
- *
49
- * @throws \InvalidArgumentException if the stream is not a stream resource
50
- */
51
- public function __construct($stream, $options = [])
52
- {
53
- if (!is_resource($stream)) {
54
- throw new \InvalidArgumentException('Stream must be a resource');
55
- }
56
-
57
- if (isset($options['size'])) {
58
- $this->size = $options['size'];
59
- }
60
-
61
- $this->customMetadata = isset($options['metadata'])
62
- ? $options['metadata']
63
- : [];
64
-
65
- $this->stream = $stream;
66
- $meta = stream_get_meta_data($this->stream);
67
- $this->seekable = $meta['seekable'];
68
- $this->readable = isset(self::$readWriteHash['read'][$meta['mode']]);
69
- $this->writable = isset(self::$readWriteHash['write'][$meta['mode']]);
70
- $this->uri = $this->getMetadata('uri');
71
- }
72
-
73
- /**
74
- * Closes the stream when the destructed
75
- */
76
- public function __destruct()
77
- {
78
- $this->close();
79
- }
80
-
81
- public function __toString()
82
- {
83
- try {
84
- $this->seek(0);
85
- return (string) stream_get_contents($this->stream);
86
- } catch (\Exception $e) {
87
- return '';
88
- }
89
- }
90
-
91
- public function getContents()
92
- {
93
- if (!isset($this->stream)) {
94
- throw new \RuntimeException('Stream is detached');
95
- }
96
-
97
- $contents = stream_get_contents($this->stream);
98
-
99
- if ($contents === false) {
100
- throw new \RuntimeException('Unable to read stream contents');
101
- }
102
-
103
- return $contents;
104
- }
105
-
106
- public function close()
107
- {
108
- if (isset($this->stream)) {
109
- if (is_resource($this->stream)) {
110
- fclose($this->stream);
111
- }
112
- $this->detach();
113
- }
114
- }
115
-
116
- public function detach()
117
- {
118
- if (!isset($this->stream)) {
119
- return null;
120
- }
121
-
122
- $result = $this->stream;
123
- unset($this->stream);
124
- $this->size = $this->uri = null;
125
- $this->readable = $this->writable = $this->seekable = false;
126
-
127
- return $result;
128
- }
129
-
130
- public function getSize()
131
- {
132
- if ($this->size !== null) {
133
- return $this->size;
134
- }
135
-
136
- if (!isset($this->stream)) {
137
- return null;
138
- }
139
-
140
- // Clear the stat cache if the stream has a URI
141
- if ($this->uri) {
142
- clearstatcache(true, $this->uri);
143
- }
144
-
145
- $stats = fstat($this->stream);
146
- if (isset($stats['size'])) {
147
- $this->size = $stats['size'];
148
- return $this->size;
149
- }
150
-
151
- return null;
152
- }
153
-
154
- public function isReadable()
155
- {
156
- return $this->readable;
157
- }
158
-
159
- public function isWritable()
160
- {
161
- return $this->writable;
162
- }
163
-
164
- public function isSeekable()
165
- {
166
- return $this->seekable;
167
- }
168
-
169
- public function eof()
170
- {
171
- if (!isset($this->stream)) {
172
- throw new \RuntimeException('Stream is detached');
173
- }
174
-
175
- return feof($this->stream);
176
- }
177
-
178
- public function tell()
179
- {
180
- if (!isset($this->stream)) {
181
- throw new \RuntimeException('Stream is detached');
182
- }
183
-
184
- $result = ftell($this->stream);
185
-
186
- if ($result === false) {
187
- throw new \RuntimeException('Unable to determine stream position');
188
- }
189
-
190
- return $result;
191
- }
192
-
193
- public function rewind()
194
- {
195
- $this->seek(0);
196
- }
197
-
198
- public function seek($offset, $whence = SEEK_SET)
199
- {
200
- if (!isset($this->stream)) {
201
- throw new \RuntimeException('Stream is detached');
202
- }
203
- if (!$this->seekable) {
204
- throw new \RuntimeException('Stream is not seekable');
205
- }
206
- if (fseek($this->stream, $offset, $whence) === -1) {
207
- throw new \RuntimeException('Unable to seek to stream position '
208
- . $offset . ' with whence ' . var_export($whence, true));
209
- }
210
- }
211
-
212
- public function read($length)
213
- {
214
- if (!isset($this->stream)) {
215
- throw new \RuntimeException('Stream is detached');
216
- }
217
- if (!$this->readable) {
218
- throw new \RuntimeException('Cannot read from non-readable stream');
219
- }
220
- if ($length < 0) {
221
- throw new \RuntimeException('Length parameter cannot be negative');
222
- }
223
-
224
- if (0 === $length) {
225
- return '';
226
- }
227
-
228
- $string = fread($this->stream, $length);
229
- if (false === $string) {
230
- throw new \RuntimeException('Unable to read from stream');
231
- }
232
-
233
- return $string;
234
- }
235
-
236
- public function write($string)
237
- {
238
- if (!isset($this->stream)) {
239
- throw new \RuntimeException('Stream is detached');
240
- }
241
- if (!$this->writable) {
242
- throw new \RuntimeException('Cannot write to a non-writable stream');
243
- }
244
-
245
- // We can't know the size after writing anything
246
- $this->size = null;
247
- $result = fwrite($this->stream, $string);
248
-
249
- if ($result === false) {
250
- throw new \RuntimeException('Unable to write to stream');
251
- }
252
-
253
- return $result;
254
- }
255
-
256
- public function getMetadata($key = null)
257
- {
258
- if (!isset($this->stream)) {
259
- return $key ? null : [];
260
- } elseif (!$key) {
261
- return $this->customMetadata + stream_get_meta_data($this->stream);
262
- } elseif (isset($this->customMetadata[$key])) {
263
- return $this->customMetadata[$key];
264
- }
265
-
266
- $meta = stream_get_meta_data($this->stream);
267
-
268
- return isset($meta[$key]) ? $meta[$key] : null;
269
- }
270
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/psr7/src/StreamDecoratorTrait.php DELETED
@@ -1,149 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Psr7;
3
-
4
- use Psr\Http\Message\StreamInterface;
5
-
6
- /**
7
- * Stream decorator trait
8
- * @property StreamInterface stream
9
- */
10
- trait StreamDecoratorTrait
11
- {
12
- /**
13
- * @param StreamInterface $stream Stream to decorate
14
- */
15
- public function __construct(StreamInterface $stream)
16
- {
17
- $this->stream = $stream;
18
- }
19
-
20
- /**
21
- * Magic method used to create a new stream if streams are not added in
22
- * the constructor of a decorator (e.g., LazyOpenStream).
23
- *
24
- * @param string $name Name of the property (allows "stream" only).
25
- *
26
- * @return StreamInterface
27
- */
28
- public function __get($name)
29
- {
30
- if ($name == 'stream') {
31
- $this->stream = $this->createStream();
32
- return $this->stream;
33
- }
34
-
35
- throw new \UnexpectedValueException("$name not found on class");
36
- }
37
-
38
- public function __toString()
39
- {
40
- try {
41
- if ($this->isSeekable()) {
42
- $this->seek(0);
43
- }
44
- return $this->getContents();
45
- } catch (\Exception $e) {
46
- // Really, PHP? https://bugs.php.net/bug.php?id=53648
47
- trigger_error('StreamDecorator::__toString exception: '
48
- . (string) $e, E_USER_ERROR);
49
- return '';
50
- }
51
- }
52
-
53
- public function getContents()
54
- {
55
- return copy_to_string($this);
56
- }
57
-
58
- /**
59
- * Allow decorators to implement custom methods
60
- *
61
- * @param string $method Missing method name
62
- * @param array $args Method arguments
63
- *
64
- * @return mixed
65
- */
66
- public function __call($method, array $args)
67
- {
68
- $result = call_user_func_array([$this->stream, $method], $args);
69
-
70
- // Always return the wrapped object if the result is a return $this
71
- return $result === $this->stream ? $this : $result;
72
- }
73
-
74
- public function close()
75
- {
76
- $this->stream->close();
77
- }
78
-
79
- public function getMetadata($key = null)
80
- {
81
- return $this->stream->getMetadata($key);
82
- }
83
-
84
- public function detach()
85
- {
86
- return $this->stream->detach();
87
- }
88
-
89
- public function getSize()
90
- {
91
- return $this->stream->getSize();
92
- }
93
-
94
- public function eof()
95
- {
96
- return $this->stream->eof();
97
- }
98
-
99
- public function tell()
100
- {
101
- return $this->stream->tell();
102
- }
103
-
104
- public function isReadable()
105
- {
106
- return $this->stream->isReadable();
107
- }
108
-
109
- public function isWritable()
110
- {
111
- return $this->stream->isWritable();
112
- }
113
-
114
- public function isSeekable()
115
- {
116
- return $this->stream->isSeekable();
117
- }
118
-
119
- public function rewind()
120
- {
121
- $this->seek(0);
122
- }
123
-
124
- public function seek($offset, $whence = SEEK_SET)
125
- {
126
- $this->stream->seek($offset, $whence);
127
- }
128
-
129
- public function read($length)
130
- {
131
- return $this->stream->read($length);
132
- }
133
-
134
- public function write($string)
135
- {
136
- return $this->stream->write($string);
137
- }
138
-
139
- /**
140
- * Implement in subclasses to dynamically create streams when requested.
141
- *
142
- * @return StreamInterface
143
- * @throws \BadMethodCallException
144
- */
145
- protected function createStream()
146
- {
147
- throw new \BadMethodCallException('Not implemented');
148
- }
149
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/psr7/src/StreamWrapper.php DELETED
@@ -1,161 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Psr7;
3
-
4
- use Psr\Http\Message\StreamInterface;
5
-
6
- /**
7
- * Converts Guzzle streams into PHP stream resources.
8
- */
9
- class StreamWrapper
10
- {
11
- /** @var resource */
12
- public $context;
13
-
14
- /** @var StreamInterface */
15
- private $stream;
16
-
17
- /** @var string r, r+, or w */
18
- private $mode;
19
-
20
- /**
21
- * Returns a resource representing the stream.
22
- *
23
- * @param StreamInterface $stream The stream to get a resource for
24
- *
25
- * @return resource
26
- * @throws \InvalidArgumentException if stream is not readable or writable
27
- */
28
- public static function getResource(StreamInterface $stream)
29
- {
30
- self::register();
31
-
32
- if ($stream->isReadable()) {
33
- $mode = $stream->isWritable() ? 'r+' : 'r';
34
- } elseif ($stream->isWritable()) {
35
- $mode = 'w';
36
- } else {
37
- throw new \InvalidArgumentException('The stream must be readable, '
38
- . 'writable, or both.');
39
- }
40
-
41
- return fopen('guzzle://stream', $mode, null, self::createStreamContext($stream));
42
- }
43
-
44
- /**
45
- * Creates a stream context that can be used to open a stream as a php stream resource.
46
- *
47
- * @param StreamInterface $stream
48
- *
49
- * @return resource
50
- */
51
- public static function createStreamContext(StreamInterface $stream)
52
- {
53
- return stream_context_create([
54
- 'guzzle' => ['stream' => $stream]
55
- ]);
56
- }
57
-
58
- /**
59
- * Registers the stream wrapper if needed
60
- */
61
- public static function register()
62
- {
63
- if (!in_array('guzzle', stream_get_wrappers())) {
64
- stream_wrapper_register('guzzle', __CLASS__);
65
- }
66
- }
67
-
68
- public function stream_open($path, $mode, $options, &$opened_path)
69
- {
70
- $options = stream_context_get_options($this->context);
71
-
72
- if (!isset($options['guzzle']['stream'])) {
73
- return false;
74
- }
75
-
76
- $this->mode = $mode;
77
- $this->stream = $options['guzzle']['stream'];
78
-
79
- return true;
80
- }
81
-
82
- public function stream_read($count)
83
- {
84
- return $this->stream->read($count);
85
- }
86
-
87
- public function stream_write($data)
88
- {
89
- return (int) $this->stream->write($data);
90
- }
91
-
92
- public function stream_tell()
93
- {
94
- return $this->stream->tell();
95
- }
96
-
97
- public function stream_eof()
98
- {
99
- return $this->stream->eof();
100
- }
101
-
102
- public function stream_seek($offset, $whence)
103
- {
104
- $this->stream->seek($offset, $whence);
105
-
106
- return true;
107
- }
108
-
109
- public function stream_cast($cast_as)
110
- {
111
- $stream = clone($this->stream);
112
-
113
- return $stream->detach();
114
- }
115
-
116
- public function stream_stat()
117
- {
118
- static $modeMap = [
119
- 'r' => 33060,
120
- 'rb' => 33060,
121
- 'r+' => 33206,
122
- 'w' => 33188,
123
- 'wb' => 33188
124
- ];
125
-
126
- return [
127
- 'dev' => 0,
128
- 'ino' => 0,
129
- 'mode' => $modeMap[$this->mode],
130
- 'nlink' => 0,
131
- 'uid' => 0,
132
- 'gid' => 0,
133
- 'rdev' => 0,
134
- 'size' => $this->stream->getSize() ?: 0,
135
- 'atime' => 0,
136
- 'mtime' => 0,
137
- 'ctime' => 0,
138
- 'blksize' => 0,
139
- 'blocks' => 0
140
- ];
141
- }
142
-
143
- public function url_stat($path, $flags)
144
- {
145
- return [
146
- 'dev' => 0,
147
- 'ino' => 0,
148
- 'mode' => 0,
149
- 'nlink' => 0,
150
- 'uid' => 0,
151
- 'gid' => 0,
152
- 'rdev' => 0,
153
- 'size' => 0,
154
- 'atime' => 0,
155
- 'mtime' => 0,
156
- 'ctime' => 0,
157
- 'blksize' => 0,
158
- 'blocks' => 0
159
- ];
160
- }
161
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/psr7/src/UploadedFile.php DELETED
@@ -1,316 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Psr7;
3
-
4
- use InvalidArgumentException;
5
- use Psr\Http\Message\StreamInterface;
6
- use Psr\Http\Message\UploadedFileInterface;
7
- use RuntimeException;
8
-
9
- class UploadedFile implements UploadedFileInterface
10
- {
11
- /**
12
- * @var int[]
13
- */
14
- private static $errors = [
15
- UPLOAD_ERR_OK,
16
- UPLOAD_ERR_INI_SIZE,
17
- UPLOAD_ERR_FORM_SIZE,
18
- UPLOAD_ERR_PARTIAL,
19
- UPLOAD_ERR_NO_FILE,
20
- UPLOAD_ERR_NO_TMP_DIR,
21
- UPLOAD_ERR_CANT_WRITE,
22
- UPLOAD_ERR_EXTENSION,
23
- ];
24
-
25
- /**
26
- * @var string
27
- */
28
- private $clientFilename;
29
-
30
- /**
31
- * @var string
32
- */
33
- private $clientMediaType;
34
-
35
- /**
36
- * @var int
37
- */
38
- private $error;
39
-
40
- /**
41
- * @var null|string
42
- */
43
- private $file;
44
-
45
- /**
46
- * @var bool
47
- */
48
- private $moved = false;
49
-
50
- /**
51
- * @var int
52
- */
53
- private $size;
54
-
55
- /**
56
- * @var StreamInterface|null
57
- */
58
- private $stream;
59
-
60
- /**
61
- * @param StreamInterface|string|resource $streamOrFile
62
- * @param int $size
63
- * @param int $errorStatus
64
- * @param string|null $clientFilename
65
- * @param string|null $clientMediaType
66
- */
67
- public function __construct(
68
- $streamOrFile,
69
- $size,
70
- $errorStatus,
71
- $clientFilename = null,
72
- $clientMediaType = null
73
- ) {
74
- $this->setError($errorStatus);
75
- $this->setSize($size);
76
- $this->setClientFilename($clientFilename);
77
- $this->setClientMediaType($clientMediaType);
78
-
79
- if ($this->isOk()) {
80
- $this->setStreamOrFile($streamOrFile);
81
- }
82
- }
83
-
84
- /**
85
- * Depending on the value set file or stream variable
86
- *
87
- * @param mixed $streamOrFile
88
- * @throws InvalidArgumentException
89
- */
90
- private function setStreamOrFile($streamOrFile)
91
- {
92
- if (is_string($streamOrFile)) {
93
- $this->file = $streamOrFile;
94
- } elseif (is_resource($streamOrFile)) {
95
- $this->stream = new Stream($streamOrFile);
96
- } elseif ($streamOrFile instanceof StreamInterface) {
97
- $this->stream = $streamOrFile;
98
- } else {
99
- throw new InvalidArgumentException(
100
- 'Invalid stream or file provided for UploadedFile'
101
- );
102
- }
103
- }
104
-
105
- /**
106
- * @param int $error
107
- * @throws InvalidArgumentException
108
- */
109
- private function setError($error)
110
- {
111
- if (false === is_int($error)) {
112
- throw new InvalidArgumentException(
113
- 'Upload file error status must be an integer'
114
- );
115
- }
116
-
117
- if (false === in_array($error, UploadedFile::$errors)) {
118
- throw new InvalidArgumentException(
119
- 'Invalid error status for UploadedFile'
120
- );
121
- }
122
-
123
- $this->error = $error;
124
- }
125
-
126
- /**
127
- * @param int $size
128
- * @throws InvalidArgumentException
129
- */
130
- private function setSize($size)
131
- {
132
- if (false === is_int($size)) {
133
- throw new InvalidArgumentException(
134
- 'Upload file size must be an integer'
135
- );
136
- }
137
-
138
- $this->size = $size;
139
- }
140
-
141
- /**
142
- * @param mixed $param
143
- * @return boolean
144
- */
145
- private function isStringOrNull($param)
146
- {
147
- return in_array(gettype($param), ['string', 'NULL']);
148
- }
149
-
150
- /**
151
- * @param mixed $param
152
- * @return boolean
153
- */
154
- private function isStringNotEmpty($param)
155
- {
156
- return is_string($param) && false === empty($param);
157
- }
158
-
159
- /**
160
- * @param string|null $clientFilename
161
- * @throws InvalidArgumentException
162
- */
163
- private function setClientFilename($clientFilename)
164
- {
165
- if (false === $this->isStringOrNull($clientFilename)) {
166
- throw new InvalidArgumentException(
167
- 'Upload file client filename must be a string or null'
168
- );
169
- }
170
-
171
- $this->clientFilename = $clientFilename;
172
- }
173
-
174
- /**
175
- * @param string|null $clientMediaType
176
- * @throws InvalidArgumentException
177
- */
178
- private function setClientMediaType($clientMediaType)
179
- {
180
- if (false === $this->isStringOrNull($clientMediaType)) {
181
- throw new InvalidArgumentException(
182
- 'Upload file client media type must be a string or null'
183
- );
184
- }
185
-
186
- $this->clientMediaType = $clientMediaType;
187
- }
188
-
189
- /**
190
- * Return true if there is no upload error
191
- *
192
- * @return boolean
193
- */
194
- private function isOk()
195
- {
196
- return $this->error === UPLOAD_ERR_OK;
197
- }
198
-
199
- /**
200
- * @return boolean
201
- */
202
- public function isMoved()
203
- {
204
- return $this->moved;
205
- }
206
-
207
- /**
208
- * @throws RuntimeException if is moved or not ok
209
- */
210
- private function validateActive()
211
- {
212
- if (false === $this->isOk()) {
213
- throw new RuntimeException('Cannot retrieve stream due to upload error');
214
- }
215
-
216
- if ($this->isMoved()) {
217
- throw new RuntimeException('Cannot retrieve stream after it has already been moved');
218
- }
219
- }
220
-
221
- /**
222
- * {@inheritdoc}
223
- * @throws RuntimeException if the upload was not successful.
224
- */
225
- public function getStream()
226
- {
227
- $this->validateActive();
228
-
229
- if ($this->stream instanceof StreamInterface) {
230
- return $this->stream;
231
- }
232
-
233
- return new LazyOpenStream($this->file, 'r+');
234
- }
235
-
236
- /**
237
- * {@inheritdoc}
238
- *
239
- * @see http://php.net/is_uploaded_file
240
- * @see http://php.net/move_uploaded_file
241
- * @param string $targetPath Path to which to move the uploaded file.
242
- * @throws RuntimeException if the upload was not successful.
243
- * @throws InvalidArgumentException if the $path specified is invalid.
244
- * @throws RuntimeException on any error during the move operation, or on
245
- * the second or subsequent call to the method.
246
- */
247
- public function moveTo($targetPath)
248
- {
249
- $this->validateActive();
250
-
251
- if (false === $this->isStringNotEmpty($targetPath)) {
252
- throw new InvalidArgumentException(
253
- 'Invalid path provided for move operation; must be a non-empty string'
254
- );
255
- }
256
-
257
- if ($this->file) {
258
- $this->moved = php_sapi_name() == 'cli'
259
- ? rename($this->file, $targetPath)
260
- : move_uploaded_file($this->file, $targetPath);
261
- } else {
262
- copy_to_stream(
263
- $this->getStream(),
264
- new LazyOpenStream($targetPath, 'w')
265
- );
266
-
267
- $this->moved = true;
268
- }
269
-
270
- if (false === $this->moved) {
271
- throw new RuntimeException(
272
- sprintf('Uploaded file could not be moved to %s', $targetPath)
273
- );
274
- }
275
- }
276
-
277
- /**
278
- * {@inheritdoc}
279
- *
280
- * @return int|null The file size in bytes or null if unknown.
281
- */
282
- public function getSize()
283
- {
284
- return $this->size;
285
- }
286
-
287
- /**
288
- * {@inheritdoc}
289
- *
290
- * @see http://php.net/manual/en/features.file-upload.errors.php
291
- * @return int One of PHP's UPLOAD_ERR_XXX constants.
292
- */
293
- public function getError()
294
- {
295
- return $this->error;
296
- }
297
-
298
- /**
299
- * {@inheritdoc}
300
- *
301
- * @return string|null The filename sent by the client or null if none
302
- * was provided.
303
- */
304
- public function getClientFilename()
305
- {
306
- return $this->clientFilename;
307
- }
308
-
309
- /**
310
- * {@inheritdoc}
311
- */
312
- public function getClientMediaType()
313
- {
314
- return $this->clientMediaType;
315
- }
316
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/psr7/src/Uri.php DELETED
@@ -1,738 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Psr7;
3
-
4
- use Psr\Http\Message\UriInterface;
5
-
6
- /**
7
- * PSR-7 URI implementation.
8
- *
9
- * @author Michael Dowling
10
- * @author Tobias Schultze
11
- * @author Matthew Weier O'Phinney
12
- */
13
- class Uri implements UriInterface
14
- {
15
- /**
16
- * Absolute http and https URIs require a host per RFC 7230 Section 2.7
17
- * but in generic URIs the host can be empty. So for http(s) URIs
18
- * we apply this default host when no host is given yet to form a
19
- * valid URI.
20
- */
21
- const HTTP_DEFAULT_HOST = 'localhost';
22
-
23
- private static $defaultPorts = [
24
- 'http' => 80,
25
- 'https' => 443,
26
- 'ftp' => 21,
27
- 'gopher' => 70,
28
- 'nntp' => 119,
29
- 'news' => 119,
30
- 'telnet' => 23,
31
- 'tn3270' => 23,
32
- 'imap' => 143,
33
- 'pop' => 110,
34
- 'ldap' => 389,
35
- ];
36
-
37
- private static $charUnreserved = 'a-zA-Z0-9_\-\.~';
38
- private static $charSubDelims = '!\$&\'\(\)\*\+,;=';
39
- private static $replaceQuery = ['=' => '%3D', '&' => '%26'];
40
-
41
- /** @var string Uri scheme. */
42
- private $scheme = '';
43
-
44
- /** @var string Uri user info. */
45
- private $userInfo = '';
46
-
47
- /** @var string Uri host. */
48
- private $host = '';
49
-
50
- /** @var int|null Uri port. */
51
- private $port;
52
-
53
- /** @var string Uri path. */
54
- private $path = '';
55
-
56
- /** @var string Uri query string. */
57
- private $query = '';
58
-
59
- /** @var string Uri fragment. */
60
- private $fragment = '';
61
-
62
- /**
63
- * @param string $uri URI to parse
64
- */
65
- public function __construct($uri = '')
66
- {
67
- // weak type check to also accept null until we can add scalar type hints
68
- if ($uri != '') {
69
- $parts = parse_url($uri);
70
- if ($parts === false) {
71
- throw new \InvalidArgumentException("Unable to parse URI: $uri");
72
- }
73
- $this->applyParts($parts);
74
- }
75
- }
76
-
77
- public function __toString()
78
- {
79
- return self::composeComponents(
80
- $this->scheme,
81
- $this->getAuthority(),
82
- $this->path,
83
- $this->query,
84
- $this->fragment
85
- );
86
- }
87
-
88
- /**
89
- * Composes a URI reference string from its various components.
90
- *
91
- * Usually this method does not need to be called manually but instead is used indirectly via
92
- * `Psr\Http\Message\UriInterface::__toString`.
93
- *
94
- * PSR-7 UriInterface treats an empty component the same as a missing component as
95
- * getQuery(), getFragment() etc. always return a string. This explains the slight
96
- * difference to RFC 3986 Section 5.3.
97
- *
98
- * Another adjustment is that the authority separator is added even when the authority is missing/empty
99
- * for the "file" scheme. This is because PHP stream functions like `file_get_contents` only work with
100
- * `file:///myfile` but not with `file:/myfile` although they are equivalent according to RFC 3986. But
101
- * `file:///` is the more common syntax for the file scheme anyway (Chrome for example redirects to
102
- * that format).
103
- *
104
- * @param string $scheme
105
- * @param string $authority
106
- * @param string $path
107
- * @param string $query
108
- * @param string $fragment
109
- *
110
- * @return string
111
- *
112
- * @link https://tools.ietf.org/html/rfc3986#section-5.3
113
- */
114
- public static function composeComponents($scheme, $authority, $path, $query, $fragment)
115
- {
116
- $uri = '';
117
-
118
- // weak type checks to also accept null until we can add scalar type hints
119
- if ($scheme != '') {
120
- $uri .= $scheme . ':';
121
- }
122
-
123
- if ($authority != ''|| $scheme === 'file') {
124
- $uri .= '//' . $authority;
125
- }
126
-
127
- $uri .= $path;
128
-
129
- if ($query != '') {
130
- $uri .= '?' . $query;
131
- }
132
-
133
- if ($fragment != '') {
134
- $uri .= '#' . $fragment;
135
- }
136
-
137
- return $uri;
138
- }
139
-
140
- /**
141
- * Whether the URI has the default port of the current scheme.
142
- *
143
- * `Psr\Http\Message\UriInterface::getPort` may return null or the standard port. This method can be used
144
- * independently of the implementation.
145
- *
146
- * @param UriInterface $uri
147
- *
148
- * @return bool
149
- */
150
- public static function isDefaultPort(UriInterface $uri)
151
- {
152
- return $uri->getPort() === null
153
- || (isset(self::$defaultPorts[$uri->getScheme()]) && $uri->getPort() === self::$defaultPorts[$uri->getScheme()]);
154
- }
155
-
156
- /**
157
- * Whether the URI is absolute, i.e. it has a scheme.
158
- *
159
- * An instance of UriInterface can either be an absolute URI or a relative reference. This method returns true
160
- * if it is the former. An absolute URI has a scheme. A relative reference is used to express a URI relative
161
- * to another URI, the base URI. Relative references can be divided into several forms:
162
- * - network-path references, e.g. '//example.com/path'
163
- * - absolute-path references, e.g. '/path'
164
- * - relative-path references, e.g. 'subpath'
165
- *
166
- * @param UriInterface $uri
167
- *
168
- * @return bool
169
- * @see Uri::isNetworkPathReference
170
- * @see Uri::isAbsolutePathReference
171
- * @see Uri::isRelativePathReference
172
- * @link https://tools.ietf.org/html/rfc3986#section-4
173
- */
174
- public static function isAbsolute(UriInterface $uri)
175
- {
176
- return $uri->getScheme() !== '';
177
- }
178
-
179
- /**
180
- * Whether the URI is a network-path reference.
181
- *
182
- * A relative reference that begins with two slash characters is termed an network-path reference.
183
- *
184
- * @param UriInterface $uri
185
- *
186
- * @return bool
187
- * @link https://tools.ietf.org/html/rfc3986#section-4.2
188
- */
189
- public static function isNetworkPathReference(UriInterface $uri)
190
- {
191
- return $uri->getScheme() === '' && $uri->getAuthority() !== '';
192
- }
193
-
194
- /**
195
- * Whether the URI is a absolute-path reference.
196
- *
197
- * A relative reference that begins with a single slash character is termed an absolute-path reference.
198
- *
199
- * @param UriInterface $uri
200
- *
201
- * @return bool
202
- * @link https://tools.ietf.org/html/rfc3986#section-4.2
203
- */
204
- public static function isAbsolutePathReference(UriInterface $uri)
205
- {
206
- return $uri->getScheme() === ''
207
- && $uri->getAuthority() === ''
208
- && isset($uri->getPath()[0])
209
- && $uri->getPath()[0] === '/';
210
- }
211
-
212
- /**
213
- * Whether the URI is a relative-path reference.
214
- *
215
- * A relative reference that does not begin with a slash character is termed a relative-path reference.
216
- *
217
- * @param UriInterface $uri
218
- *
219
- * @return bool
220
- * @link https://tools.ietf.org/html/rfc3986#section-4.2
221
- */
222
- public static function isRelativePathReference(UriInterface $uri)
223
- {
224
- return $uri->getScheme() === ''
225
- && $uri->getAuthority() === ''
226
- && (!isset($uri->getPath()[0]) || $uri->getPath()[0] !== '/');
227
- }
228
-
229
- /**
230
- * Whether the URI is a same-document reference.
231
- *
232
- * A same-document reference refers to a URI that is, aside from its fragment
233
- * component, identical to the base URI. When no base URI is given, only an empty
234
- * URI reference (apart from its fragment) is considered a same-document reference.
235
- *
236
- * @param UriInterface $uri The URI to check
237
- * @param UriInterface|null $base An optional base URI to compare against
238
- *
239
- * @return bool
240
- * @link https://tools.ietf.org/html/rfc3986#section-4.4
241
- */
242
- public static function isSameDocumentReference(UriInterface $uri, UriInterface $base = null)
243
- {
244
- if ($base !== null) {
245
- $uri = UriResolver::resolve($base, $uri);
246
-
247
- return ($uri->getScheme() === $base->getScheme())
248
- && ($uri->getAuthority() === $base->getAuthority())
249
- && ($uri->getPath() === $base->getPath())
250
- && ($uri->getQuery() === $base->getQuery());
251
- }
252
-
253
- return $uri->getScheme() === '' && $uri->getAuthority() === '' && $uri->getPath() === '' && $uri->getQuery() === '';
254
- }
255
-
256
- /**
257
- * Removes dot segments from a path and returns the new path.
258
- *
259
- * @param string $path
260
- *
261
- * @return string
262
- *
263
- * @deprecated since version 1.4. Use UriResolver::removeDotSegments instead.
264
- * @see UriResolver::removeDotSegments
265
- */
266
- public static function removeDotSegments($path)
267
- {
268
- return UriResolver::removeDotSegments($path);
269
- }
270
-
271
- /**
272
- * Converts the relative URI into a new URI that is resolved against the base URI.
273
- *
274
- * @param UriInterface $base Base URI
275
- * @param string|UriInterface $rel Relative URI
276
- *
277
- * @return UriInterface
278
- *
279
- * @deprecated since version 1.4. Use UriResolver::resolve instead.
280
- * @see UriResolver::resolve
281
- */
282
- public static function resolve(UriInterface $base, $rel)
283
- {
284
- if (!($rel instanceof UriInterface)) {
285
- $rel = new self($rel);
286
- }
287
-
288
- return UriResolver::resolve($base, $rel);
289
- }
290
-
291
- /**
292
- * Creates a new URI with a specific query string value removed.
293
- *
294
- * Any existing query string values that exactly match the provided key are
295
- * removed.
296
- *
297
- * @param UriInterface $uri URI to use as a base.
298
- * @param string $key Query string key to remove.
299
- *
300
- * @return UriInterface
301
- */
302
- public static function withoutQueryValue(UriInterface $uri, $key)
303
- {
304
- $result = self::getFilteredQueryString($uri, [$key]);
305
-
306
- return $uri->withQuery(implode('&', $result));
307
- }
308
-
309
- /**
310
- * Creates a new URI with a specific query string value.
311
- *
312
- * Any existing query string values that exactly match the provided key are
313
- * removed and replaced with the given key value pair.
314
- *
315
- * A value of null will set the query string key without a value, e.g. "key"
316
- * instead of "key=value".
317
- *
318
- * @param UriInterface $uri URI to use as a base.
319
- * @param string $key Key to set.
320
- * @param string|null $value Value to set
321
- *
322
- * @return UriInterface
323
- */
324
- public static function withQueryValue(UriInterface $uri, $key, $value)
325
- {
326
- $result = self::getFilteredQueryString($uri, [$key]);
327
-
328
- $result[] = self::generateQueryString($key, $value);
329
-
330
- return $uri->withQuery(implode('&', $result));
331
- }
332
-
333
- /**
334
- * Creates a new URI with multiple specific query string values.
335
- *
336
- * It has the same behavior as withQueryValue() but for an associative array of key => value.
337
- *
338
- * @param UriInterface $uri URI to use as a base.
339
- * @param array $keyValueArray Associative array of key and values
340
- *
341
- * @return UriInterface
342
- */
343
- public static function withQueryValues(UriInterface $uri, array $keyValueArray)
344
- {
345
- $result = self::getFilteredQueryString($uri, array_keys($keyValueArray));
346
-
347
- foreach ($keyValueArray as $key => $value) {
348
- $result[] = self::generateQueryString($key, $value);
349
- }
350
-
351
- return $uri->withQuery(implode('&', $result));
352
- }
353
-
354
- /**
355
- * Creates a URI from a hash of `parse_url` components.
356
- *
357
- * @param array $parts
358
- *
359
- * @return UriInterface
360
- * @link http://php.net/manual/en/function.parse-url.php
361
- *
362
- * @throws \InvalidArgumentException If the components do not form a valid URI.
363
- */
364
- public static function fromParts(array $parts)
365
- {
366
- $uri = new self();
367
- $uri->applyParts($parts);
368
- $uri->validateState();
369
-
370
- return $uri;
371
- }
372
-
373
- public function getScheme()
374
- {
375
- return $this->scheme;
376
- }
377
-
378
- public function getAuthority()
379
- {
380
- $authority = $this->host;
381
- if ($this->userInfo !== '') {
382
- $authority = $this->userInfo . '@' . $authority;
383
- }
384
-
385
- if ($this->port !== null) {
386
- $authority .= ':' . $this->port;
387
- }
388
-
389
- return $authority;
390
- }
391
-
392
- public function getUserInfo()
393
- {
394
- return $this->userInfo;
395
- }
396
-
397
- public function getHost()
398
- {
399
- return $this->host;
400
- }
401
-
402
- public function getPort()
403
- {
404
- return $this->port;
405
- }
406
-
407
- public function getPath()
408
- {
409
- return $this->path;
410
- }
411
-
412
- public function getQuery()
413
- {
414
- return $this->query;
415
- }
416
-
417
- public function getFragment()
418
- {
419
- return $this->fragment;
420
- }
421
-
422
- public function withScheme($scheme)
423
- {
424
- $scheme = $this->filterScheme($scheme);
425
-
426
- if ($this->scheme === $scheme) {
427
- return $this;
428
- }
429
-
430
- $new = clone $this;
431
- $new->scheme = $scheme;
432
- $new->removeDefaultPort();
433
- $new->validateState();
434
-
435
- return $new;
436
- }
437
-
438
- public function withUserInfo($user, $password = null)
439
- {
440
- $info = $user;
441
- if ($password != '') {
442
- $info .= ':' . $password;
443
- }
444
-
445
- if ($this->userInfo === $info) {
446
- return $this;
447
- }
448
-
449
- $new = clone $this;
450
- $new->userInfo = $info;
451
- $new->validateState();
452
-
453
- return $new;
454
- }
455
-
456
- public function withHost($host)
457
- {
458
- $host = $this->filterHost($host);
459
-
460
- if ($this->host === $host) {
461
- return $this;
462
- }
463
-
464
- $new = clone $this;
465
- $new->host = $host;
466
- $new->validateState();
467
-
468
- return $new;
469
- }
470
-
471
- public function withPort($port)
472
- {
473
- $port = $this->filterPort($port);
474
-
475
- if ($this->port === $port) {
476
- return $this;
477
- }
478
-
479
- $new = clone $this;
480
- $new->port = $port;
481
- $new->removeDefaultPort();
482
- $new->validateState();
483
-
484
- return $new;
485
- }
486
-
487
- public function withPath($path)
488
- {
489
- $path = $this->filterPath($path);
490
-
491
- if ($this->path === $path) {
492
- return $this;
493
- }
494
-
495
- $new = clone $this;
496
- $new->path = $path;
497
- $new->validateState();
498
-
499
- return $new;
500
- }
501
-
502
- public function withQuery($query)
503
- {
504
- $query = $this->filterQueryAndFragment($query);
505
-
506
- if ($this->query === $query) {
507
- return $this;
508
- }
509
-
510
- $new = clone $this;
511
- $new->query = $query;
512
-
513
- return $new;
514
- }
515
-
516
- public function withFragment($fragment)
517
- {
518
- $fragment = $this->filterQueryAndFragment($fragment);
519
-
520
- if ($this->fragment === $fragment) {
521
- return $this;
522
- }
523
-
524
- $new = clone $this;
525
- $new->fragment = $fragment;
526
-
527
- return $new;
528
- }
529
-
530
- /**
531
- * Apply parse_url parts to a URI.
532
- *
533
- * @param array $parts Array of parse_url parts to apply.
534
- */
535
- private function applyParts(array $parts)
536
- {
537
- $this->scheme = isset($parts['scheme'])
538
- ? $this->filterScheme($parts['scheme'])
539
- : '';
540
- $this->userInfo = isset($parts['user']) ? $parts['user'] : '';
541
- $this->host = isset($parts['host'])
542
- ? $this->filterHost($parts['host'])
543
- : '';
544
- $this->port = isset($parts['port'])
545
- ? $this->filterPort($parts['port'])
546
- : null;
547
- $this->path = isset($parts['path'])
548
- ? $this->filterPath($parts['path'])
549
- : '';
550
- $this->query = isset($parts['query'])
551
- ? $this->filterQueryAndFragment($parts['query'])
552
- : '';
553
- $this->fragment = isset($parts['fragment'])
554
- ? $this->filterQueryAndFragment($parts['fragment'])
555
- : '';
556
- if (isset($parts['pass'])) {
557
- $this->userInfo .= ':' . $parts['pass'];
558
- }
559
-
560
- $this->removeDefaultPort();
561
- }
562
-
563
- /**
564
- * @param string $scheme
565
- *
566
- * @return string
567
- *
568
- * @throws \InvalidArgumentException If the scheme is invalid.
569
- */
570
- private function filterScheme($scheme)
571
- {
572
- if (!is_string($scheme)) {
573
- throw new \InvalidArgumentException('Scheme must be a string');
574
- }
575
-
576
- return strtolower($scheme);
577
- }
578
-
579
- /**
580
- * @param string $host
581
- *
582
- * @return string
583
- *
584
- * @throws \InvalidArgumentException If the host is invalid.
585
- */
586
- private function filterHost($host)
587
- {
588
- if (!is_string($host)) {
589
- throw new \InvalidArgumentException('Host must be a string');
590
- }
591
-
592
- return strtolower($host);
593
- }
594
-
595
- /**
596
- * @param int|null $port
597
- *
598
- * @return int|null
599
- *
600
- * @throws \InvalidArgumentException If the port is invalid.
601
- */
602
- private function filterPort($port)
603
- {
604
- if ($port === null) {
605
- return null;
606
- }
607
-
608
- $port = (int) $port;
609
- if (1 > $port || 0xffff < $port) {
610
- throw new \InvalidArgumentException(
611
- sprintf('Invalid port: %d. Must be between 1 and 65535', $port)
612
- );
613
- }
614
-
615
- return $port;
616
- }
617
-
618
- /**
619
- * @param UriInterface $uri
620
- * @param array $keys
621
- *
622
- * @return array
623
- */
624
- private static function getFilteredQueryString(UriInterface $uri, array $keys)
625
- {
626
- $current = $uri->getQuery();
627
-
628
- if ($current === '') {
629
- return [];
630
- }
631
-
632
- $decodedKeys = array_map('rawurldecode', $keys);
633
-
634
- return array_filter(explode('&', $current), function ($part) use ($decodedKeys) {
635
- return !in_array(rawurldecode(explode('=', $part)[0]), $decodedKeys, true);
636
- });
637
- }
638
-
639
- /**
640
- * @param string $key
641
- * @param string|null $value
642
- *
643
- * @return string
644
- */
645
- private static function generateQueryString($key, $value)
646
- {
647
- // Query string separators ("=", "&") within the key or value need to be encoded
648
- // (while preventing double-encoding) before setting the query string. All other
649
- // chars that need percent-encoding will be encoded by withQuery().
650
- $queryString = strtr($key, self::$replaceQuery);
651
-
652
- if ($value !== null) {
653
- $queryString .= '=' . strtr($value, self::$replaceQuery);
654
- }
655
-
656
- return $queryString;
657
- }
658
-
659
- private function removeDefaultPort()
660
- {
661
- if ($this->port !== null && self::isDefaultPort($this)) {
662
- $this->port = null;
663
- }
664
- }
665
-
666
- /**
667
- * Filters the path of a URI
668
- *
669
- * @param string $path
670
- *
671
- * @return string
672
- *
673
- * @throws \InvalidArgumentException If the path is invalid.
674
- */
675
- private function filterPath($path)
676
- {
677
- if (!is_string($path)) {
678
- throw new \InvalidArgumentException('Path must be a string');
679
- }
680
-
681
- return preg_replace_callback(
682
- '/(?:[^' . self::$charUnreserved . self::$charSubDelims . '%:@\/]++|%(?![A-Fa-f0-9]{2}))/',
683
- [$this, 'rawurlencodeMatchZero'],
684
- $path
685
- );
686
- }
687
-
688
- /**
689
- * Filters the query string or fragment of a URI.
690
- *
691
- * @param string $str
692
- *
693
- * @return string
694
- *
695
- * @throws \InvalidArgumentException If the query or fragment is invalid.
696
- */
697
- private function filterQueryAndFragment($str)
698
- {
699
- if (!is_string($str)) {
700
- throw new \InvalidArgumentException('Query and fragment must be a string');
701
- }
702
-
703
- return preg_replace_callback(
704
- '/(?:[^' . self::$charUnreserved . self::$charSubDelims . '%:@\/\?]++|%(?![A-Fa-f0-9]{2}))/',
705
- [$this, 'rawurlencodeMatchZero'],
706
- $str
707
- );
708
- }
709
-
710
- private function rawurlencodeMatchZero(array $match)
711
- {
712
- return rawurlencode($match[0]);
713
- }
714
-
715
- private function validateState()
716
- {
717
- if ($this->host === '' && ($this->scheme === 'http' || $this->scheme === 'https')) {
718
- $this->host = self::HTTP_DEFAULT_HOST;
719
- }
720
-
721
- if ($this->getAuthority() === '') {
722
- if (0 === strpos($this->path, '//')) {
723
- throw new \InvalidArgumentException('The path of a URI without an authority must not start with two slashes "//"');
724
- }
725
- if ($this->scheme === '' && false !== strpos(explode('/', $this->path, 2)[0], ':')) {
726
- throw new \InvalidArgumentException('A relative URI must not have a path beginning with a segment containing a colon');
727
- }
728
- } elseif (isset($this->path[0]) && $this->path[0] !== '/') {
729
- @trigger_error(
730
- 'The path of a URI with an authority must start with a slash "/" or be empty. Automagically fixing the URI ' .
731
- 'by adding a leading slash to the path is deprecated since version 1.4 and will throw an exception instead.',
732
- E_USER_DEPRECATED
733
- );
734
- $this->path = '/'. $this->path;
735
- //throw new \InvalidArgumentException('The path of a URI with an authority must start with a slash "/" or be empty');
736
- }
737
- }
738
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/psr7/src/UriNormalizer.php DELETED
@@ -1,216 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Psr7;
3
-
4
- use Psr\Http\Message\UriInterface;
5
-
6
- /**
7
- * Provides methods to normalize and compare URIs.
8
- *
9
- * @author Tobias Schultze
10
- *
11
- * @link https://tools.ietf.org/html/rfc3986#section-6
12
- */
13
- final class UriNormalizer
14
- {
15
- /**
16
- * Default normalizations which only include the ones that preserve semantics.
17
- *
18
- * self::CAPITALIZE_PERCENT_ENCODING | self::DECODE_UNRESERVED_CHARACTERS | self::CONVERT_EMPTY_PATH |
19
- * self::REMOVE_DEFAULT_HOST | self::REMOVE_DEFAULT_PORT | self::REMOVE_DOT_SEGMENTS
20
- */
21
- const PRESERVING_NORMALIZATIONS = 63;
22
-
23
- /**
24
- * All letters within a percent-encoding triplet (e.g., "%3A") are case-insensitive, and should be capitalized.
25
- *
26
- * Example: http://example.org/a%c2%b1b → http://example.org/a%C2%B1b
27
- */
28
- const CAPITALIZE_PERCENT_ENCODING = 1;
29
-
30
- /**
31
- * Decodes percent-encoded octets of unreserved characters.
32
- *
33
- * For consistency, percent-encoded octets in the ranges of ALPHA (%41–%5A and %61–%7A), DIGIT (%30–%39),
34
- * hyphen (%2D), period (%2E), underscore (%5F), or tilde (%7E) should not be created by URI producers and,
35
- * when found in a URI, should be decoded to their corresponding unreserved characters by URI normalizers.
36
- *
37
- * Example: http://example.org/%7Eusern%61me/ → http://example.org/~username/
38
- */
39
- const DECODE_UNRESERVED_CHARACTERS = 2;
40
-
41
- /**
42
- * Converts the empty path to "/" for http and https URIs.
43
- *
44
- * Example: http://example.org → http://example.org/
45
- */
46
- const CONVERT_EMPTY_PATH = 4;
47
-
48
- /**
49
- * Removes the default host of the given URI scheme from the URI.
50
- *
51
- * Only the "file" scheme defines the default host "localhost".
52
- * All of `file:/myfile`, `file:///myfile`, and `file://localhost/myfile`
53
- * are equivalent according to RFC 3986. The first format is not accepted
54
- * by PHPs stream functions and thus already normalized implicitly to the
55
- * second format in the Uri class. See `GuzzleHttp\Psr7\Uri::composeComponents`.
56
- *
57
- * Example: file://localhost/myfile → file:///myfile
58
- */
59
- const REMOVE_DEFAULT_HOST = 8;
60
-
61
- /**
62
- * Removes the default port of the given URI scheme from the URI.
63
- *
64
- * Example: http://example.org:80/ → http://example.org/
65
- */
66
- const REMOVE_DEFAULT_PORT = 16;
67
-
68
- /**
69
- * Removes unnecessary dot-segments.
70
- *
71
- * Dot-segments in relative-path references are not removed as it would
72
- * change the semantics of the URI reference.
73
- *
74
- * Example: http://example.org/../a/b/../c/./d.html → http://example.org/a/c/d.html
75
- */
76
- const REMOVE_DOT_SEGMENTS = 32;
77
-
78
- /**
79
- * Paths which include two or more adjacent slashes are converted to one.
80
- *
81
- * Webservers usually ignore duplicate slashes and treat those URIs equivalent.
82
- * But in theory those URIs do not need to be equivalent. So this normalization
83
- * may change the semantics. Encoded slashes (%2F) are not removed.
84
- *
85
- * Example: http://example.org//foo///bar.html → http://example.org/foo/bar.html
86
- */
87
- const REMOVE_DUPLICATE_SLASHES = 64;
88
-
89
- /**
90
- * Sort query parameters with their values in alphabetical order.
91
- *
92
- * However, the order of parameters in a URI may be significant (this is not defined by the standard).
93
- * So this normalization is not safe and may change the semantics of the URI.
94
- *
95
- * Example: ?lang=en&article=fred → ?article=fred&lang=en
96
- *
97
- * Note: The sorting is neither locale nor Unicode aware (the URI query does not get decoded at all) as the
98
- * purpose is to be able to compare URIs in a reproducible way, not to have the params sorted perfectly.
99
- */
100
- const SORT_QUERY_PARAMETERS = 128;
101
-
102
- /**
103
- * Returns a normalized URI.
104
- *
105
- * The scheme and host component are already normalized to lowercase per PSR-7 UriInterface.
106
- * This methods adds additional normalizations that can be configured with the $flags parameter.
107
- *
108
- * PSR-7 UriInterface cannot distinguish between an empty component and a missing component as
109
- * getQuery(), getFragment() etc. always return a string. This means the URIs "/?#" and "/" are
110
- * treated equivalent which is not necessarily true according to RFC 3986. But that difference
111
- * is highly uncommon in reality. So this potential normalization is implied in PSR-7 as well.
112
- *
113
- * @param UriInterface $uri The URI to normalize
114
- * @param int $flags A bitmask of normalizations to apply, see constants
115
- *
116
- * @return UriInterface The normalized URI
117
- * @link https://tools.ietf.org/html/rfc3986#section-6.2
118
- */
119
- public static function normalize(UriInterface $uri, $flags = self::PRESERVING_NORMALIZATIONS)
120
- {
121
- if ($flags & self::CAPITALIZE_PERCENT_ENCODING) {
122
- $uri = self::capitalizePercentEncoding($uri);
123
- }
124
-
125
- if ($flags & self::DECODE_UNRESERVED_CHARACTERS) {
126
- $uri = self::decodeUnreservedCharacters($uri);
127
- }
128
-
129
- if ($flags & self::CONVERT_EMPTY_PATH && $uri->getPath() === '' &&
130
- ($uri->getScheme() === 'http' || $uri->getScheme() === 'https')
131
- ) {
132
- $uri = $uri->withPath('/');
133
- }
134
-
135
- if ($flags & self::REMOVE_DEFAULT_HOST && $uri->getScheme() === 'file' && $uri->getHost() === 'localhost') {
136
- $uri = $uri->withHost('');
137
- }
138
-
139
- if ($flags & self::REMOVE_DEFAULT_PORT && $uri->getPort() !== null && Uri::isDefaultPort($uri)) {
140
- $uri = $uri->withPort(null);
141
- }
142
-
143
- if ($flags & self::REMOVE_DOT_SEGMENTS && !Uri::isRelativePathReference($uri)) {
144
- $uri = $uri->withPath(UriResolver::removeDotSegments($uri->getPath()));
145
- }
146
-
147
- if ($flags & self::REMOVE_DUPLICATE_SLASHES) {
148
- $uri = $uri->withPath(preg_replace('#//++#', '/', $uri->getPath()));
149
- }
150
-
151
- if ($flags & self::SORT_QUERY_PARAMETERS && $uri->getQuery() !== '') {
152
- $queryKeyValues = explode('&', $uri->getQuery());
153
- sort($queryKeyValues);
154
- $uri = $uri->withQuery(implode('&', $queryKeyValues));
155
- }
156
-
157
- return $uri;
158
- }
159
-
160
- /**
161
- * Whether two URIs can be considered equivalent.
162
- *
163
- * Both URIs are normalized automatically before comparison with the given $normalizations bitmask. The method also
164
- * accepts relative URI references and returns true when they are equivalent. This of course assumes they will be
165
- * resolved against the same base URI. If this is not the case, determination of equivalence or difference of
166
- * relative references does not mean anything.
167
- *
168
- * @param UriInterface $uri1 An URI to compare
169
- * @param UriInterface $uri2 An URI to compare
170
- * @param int $normalizations A bitmask of normalizations to apply, see constants
171
- *
172
- * @return bool
173
- * @link https://tools.ietf.org/html/rfc3986#section-6.1
174
- */
175
- public static function isEquivalent(UriInterface $uri1, UriInterface $uri2, $normalizations = self::PRESERVING_NORMALIZATIONS)
176
- {
177
- return (string) self::normalize($uri1, $normalizations) === (string) self::normalize($uri2, $normalizations);
178
- }
179
-
180
- private static function capitalizePercentEncoding(UriInterface $uri)
181
- {
182
- $regex = '/(?:%[A-Fa-f0-9]{2})++/';
183
-
184
- $callback = function (array $match) {
185
- return strtoupper($match[0]);
186
- };
187
-
188
- return
189
- $uri->withPath(
190
- preg_replace_callback($regex, $callback, $uri->getPath())
191
- )->withQuery(
192
- preg_replace_callback($regex, $callback, $uri->getQuery())
193
- );
194
- }
195
-
196
- private static function decodeUnreservedCharacters(UriInterface $uri)
197
- {
198
- $regex = '/%(?:2D|2E|5F|7E|3[0-9]|[46][1-9A-F]|[57][0-9A])/i';
199
-
200
- $callback = function (array $match) {
201
- return rawurldecode($match[0]);
202
- };
203
-
204
- return
205
- $uri->withPath(
206
- preg_replace_callback($regex, $callback, $uri->getPath())
207
- )->withQuery(
208
- preg_replace_callback($regex, $callback, $uri->getQuery())
209
- );
210
- }
211
-
212
- private function __construct()
213
- {
214
- // cannot be instantiated
215
- }
216
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/psr7/src/UriResolver.php DELETED
@@ -1,219 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Psr7;
3
-
4
- use Psr\Http\Message\UriInterface;
5
-
6
- /**
7
- * Resolves a URI reference in the context of a base URI and the opposite way.
8
- *
9
- * @author Tobias Schultze
10
- *
11
- * @link https://tools.ietf.org/html/rfc3986#section-5
12
- */
13
- final class UriResolver
14
- {
15
- /**
16
- * Removes dot segments from a path and returns the new path.
17
- *
18
- * @param string $path
19
- *
20
- * @return string
21
- * @link http://tools.ietf.org/html/rfc3986#section-5.2.4
22
- */
23
- public static function removeDotSegments($path)
24
- {
25
- if ($path === '' || $path === '/') {
26
- return $path;
27
- }
28
-
29
- $results = [];
30
- $segments = explode('/', $path);
31
- foreach ($segments as $segment) {
32
- if ($segment === '..') {
33
- array_pop($results);
34
- } elseif ($segment !== '.') {
35
- $results[] = $segment;
36
- }
37
- }
38
-
39
- $newPath = implode('/', $results);
40
-
41
- if ($path[0] === '/' && (!isset($newPath[0]) || $newPath[0] !== '/')) {
42
- // Re-add the leading slash if necessary for cases like "/.."
43
- $newPath = '/' . $newPath;
44
- } elseif ($newPath !== '' && ($segment === '.' || $segment === '..')) {
45
- // Add the trailing slash if necessary
46
- // If newPath is not empty, then $segment must be set and is the last segment from the foreach
47
- $newPath .= '/';
48
- }
49
-
50
- return $newPath;
51
- }
52
-
53
- /**
54
- * Converts the relative URI into a new URI that is resolved against the base URI.
55
- *
56
- * @param UriInterface $base Base URI
57
- * @param UriInterface $rel Relative URI
58
- *
59
- * @return UriInterface
60
- * @link http://tools.ietf.org/html/rfc3986#section-5.2
61
- */
62
- public static function resolve(UriInterface $base, UriInterface $rel)
63
- {
64
- if ((string) $rel === '') {
65
- // we can simply return the same base URI instance for this same-document reference
66
- return $base;
67
- }
68
-
69
- if ($rel->getScheme() != '') {
70
- return $rel->withPath(self::removeDotSegments($rel->getPath()));
71
- }
72
-
73
- if ($rel->getAuthority() != '') {
74
- $targetAuthority = $rel->getAuthority();
75
- $targetPath = self::removeDotSegments($rel->getPath());
76
- $targetQuery = $rel->getQuery();
77
- } else {
78
- $targetAuthority = $base->getAuthority();
79
- if ($rel->getPath() === '') {
80
- $targetPath = $base->getPath();
81
- $targetQuery = $rel->getQuery() != '' ? $rel->getQuery() : $base->getQuery();
82
- } else {
83
- if ($rel->getPath()[0] === '/') {
84
- $targetPath = $rel->getPath();
85
- } else {
86
- if ($targetAuthority != '' && $base->getPath() === '') {
87
- $targetPath = '/' . $rel->getPath();
88
- } else {
89
- $lastSlashPos = strrpos($base->getPath(), '/');
90
- if ($lastSlashPos === false) {
91
- $targetPath = $rel->getPath();
92
- } else {
93
- $targetPath = substr($base->getPath(), 0, $lastSlashPos + 1) . $rel->getPath();
94
- }
95
- }
96
- }
97
- $targetPath = self::removeDotSegments($targetPath);
98
- $targetQuery = $rel->getQuery();
99
- }
100
- }
101
-
102
- return new Uri(Uri::composeComponents(
103
- $base->getScheme(),
104
- $targetAuthority,
105
- $targetPath,
106
- $targetQuery,
107
- $rel->getFragment()
108
- ));
109
- }
110
-
111
- /**
112
- * Returns the target URI as a relative reference from the base URI.
113
- *
114
- * This method is the counterpart to resolve():
115
- *
116
- * (string) $target === (string) UriResolver::resolve($base, UriResolver::relativize($base, $target))
117
- *
118
- * One use-case is to use the current request URI as base URI and then generate relative links in your documents
119
- * to reduce the document size or offer self-contained downloadable document archives.
120
- *
121
- * $base = new Uri('http://example.com/a/b/');
122
- * echo UriResolver::relativize($base, new Uri('http://example.com/a/b/c')); // prints 'c'.
123
- * echo UriResolver::relativize($base, new Uri('http://example.com/a/x/y')); // prints '../x/y'.
124
- * echo UriResolver::relativize($base, new Uri('http://example.com/a/b/?q')); // prints '?q'.
125
- * echo UriResolver::relativize($base, new Uri('http://example.org/a/b/')); // prints '//example.org/a/b/'.
126
- *
127
- * This method also accepts a target that is already relative and will try to relativize it further. Only a
128
- * relative-path reference will be returned as-is.
129
- *
130
- * echo UriResolver::relativize($base, new Uri('/a/b/c')); // prints 'c' as well
131
- *
132
- * @param UriInterface $base Base URI
133
- * @param UriInterface $target Target URI
134
- *
135
- * @return UriInterface The relative URI reference
136
- */
137
- public static function relativize(UriInterface $base, UriInterface $target)
138
- {
139
- if ($target->getScheme() !== '' &&
140
- ($base->getScheme() !== $target->getScheme() || $target->getAuthority() === '' && $base->getAuthority() !== '')
141
- ) {
142
- return $target;
143
- }
144
-
145
- if (Uri::isRelativePathReference($target)) {
146
- // As the target is already highly relative we return it as-is. It would be possible to resolve
147
- // the target with `$target = self::resolve($base, $target);` and then try make it more relative
148
- // by removing a duplicate query. But let's not do that automatically.
149
- return $target;
150
- }
151
-
152
- if ($target->getAuthority() !== '' && $base->getAuthority() !== $target->getAuthority()) {
153
- return $target->withScheme('');
154
- }
155
-
156
- // We must remove the path before removing the authority because if the path starts with two slashes, the URI
157
- // would turn invalid. And we also cannot set a relative path before removing the authority, as that is also
158
- // invalid.
159
- $emptyPathUri = $target->withScheme('')->withPath('')->withUserInfo('')->withPort(null)->withHost('');
160
-
161
- if ($base->getPath() !== $target->getPath()) {
162
- return $emptyPathUri->withPath(self::getRelativePath($base, $target));
163
- }
164
-
165
- if ($base->getQuery() === $target->getQuery()) {
166
- // Only the target fragment is left. And it must be returned even if base and target fragment are the same.
167
- return $emptyPathUri->withQuery('');
168
- }
169
-
170
- // If the base URI has a query but the target has none, we cannot return an empty path reference as it would
171
- // inherit the base query component when resolving.
172
- if ($target->getQuery() === '') {
173
- $segments = explode('/', $target->getPath());
174
- $lastSegment = end($segments);
175
-
176
- return $emptyPathUri->withPath($lastSegment === '' ? './' : $lastSegment);
177
- }
178
-
179
- return $emptyPathUri;
180
- }
181
-
182
- private static function getRelativePath(UriInterface $base, UriInterface $target)
183
- {
184
- $sourceSegments = explode('/', $base->getPath());
185
- $targetSegments = explode('/', $target->getPath());
186
- array_pop($sourceSegments);
187
- $targetLastSegment = array_pop($targetSegments);
188
- foreach ($sourceSegments as $i => $segment) {
189
- if (isset($targetSegments[$i]) && $segment === $targetSegments[$i]) {
190
- unset($sourceSegments[$i], $targetSegments[$i]);
191
- } else {
192
- break;
193
- }
194
- }
195
- $targetSegments[] = $targetLastSegment;
196
- $relativePath = str_repeat('../', count($sourceSegments)) . implode('/', $targetSegments);
197
-
198
- // A reference to am empty last segment or an empty first sub-segment must be prefixed with "./".
199
- // This also applies to a segment with a colon character (e.g., "file:colon") that cannot be used
200
- // as the first segment of a relative-path reference, as it would be mistaken for a scheme name.
201
- if ('' === $relativePath || false !== strpos(explode('/', $relativePath, 2)[0], ':')) {
202
- $relativePath = "./$relativePath";
203
- } elseif ('/' === $relativePath[0]) {
204
- if ($base->getAuthority() != '' && $base->getPath() === '') {
205
- // In this case an extra slash is added by resolve() automatically. So we must not add one here.
206
- $relativePath = ".$relativePath";
207
- } else {
208
- $relativePath = "./$relativePath";
209
- }
210
- }
211
-
212
- return $relativePath;
213
- }
214
-
215
- private function __construct()
216
- {
217
- // cannot be instantiated
218
- }
219
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/psr7/src/functions.php DELETED
@@ -1,898 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Psr7;
3
-
4
- use Psr\Http\Message\MessageInterface;
5
- use Psr\Http\Message\RequestInterface;
6
- use Psr\Http\Message\ResponseInterface;
7
- use Psr\Http\Message\ServerRequestInterface;
8
- use Psr\Http\Message\StreamInterface;
9
- use Psr\Http\Message\UriInterface;
10
-
11
- /**
12
- * Returns the string representation of an HTTP message.
13
- *
14
- * @param MessageInterface $message Message to convert to a string.
15
- *
16
- * @return string
17
- */
18
- function str(MessageInterface $message)
19
- {
20
- if ($message instanceof RequestInterface) {
21
- $msg = trim($message->getMethod() . ' '
22
- . $message->getRequestTarget())
23
- . ' HTTP/' . $message->getProtocolVersion();
24
- if (!$message->hasHeader('host')) {
25
- $msg .= "\r\nHost: " . $message->getUri()->getHost();
26
- }
27
- } elseif ($message instanceof ResponseInterface) {
28
- $msg = 'HTTP/' . $message->getProtocolVersion() . ' '
29
- . $message->getStatusCode() . ' '
30
- . $message->getReasonPhrase();
31
- } else {
32
- throw new \InvalidArgumentException('Unknown message type');
33
- }
34
-
35
- foreach ($message->getHeaders() as $name => $values) {
36
- $msg .= "\r\n{$name}: " . implode(', ', $values);
37
- }
38
-
39
- return "{$msg}\r\n\r\n" . $message->getBody();
40
- }
41
-
42
- /**
43
- * Returns a UriInterface for the given value.
44
- *
45
- * This function accepts a string or {@see Psr\Http\Message\UriInterface} and
46
- * returns a UriInterface for the given value. If the value is already a
47
- * `UriInterface`, it is returned as-is.
48
- *
49
- * @param string|UriInterface $uri
50
- *
51
- * @return UriInterface
52
- * @throws \InvalidArgumentException
53
- */
54
- function uri_for($uri)
55
- {
56
- if ($uri instanceof UriInterface) {
57
- return $uri;
58
- } elseif (is_string($uri)) {
59
- return new Uri($uri);
60
- }
61
-
62
- throw new \InvalidArgumentException('URI must be a string or UriInterface');
63
- }
64
-
65
- /**
66
- * Create a new stream based on the input type.
67
- *
68
- * Options is an associative array that can contain the following keys:
69
- * - metadata: Array of custom metadata.
70
- * - size: Size of the stream.
71
- *
72
- * @param resource|string|null|int|float|bool|StreamInterface|callable|\Iterator $resource Entity body data
73
- * @param array $options Additional options
74
- *
75
- * @return StreamInterface
76
- * @throws \InvalidArgumentException if the $resource arg is not valid.
77
- */
78
- function stream_for($resource = '', array $options = [])
79
- {
80
- if (is_scalar($resource)) {
81
- $stream = fopen('php://temp', 'r+');
82
- if ($resource !== '') {
83
- fwrite($stream, $resource);
84
- fseek($stream, 0);
85
- }
86
- return new Stream($stream, $options);
87
- }
88
-
89
- switch (gettype($resource)) {
90
- case 'resource':
91
- return new Stream($resource, $options);
92
- case 'object':
93
- if ($resource instanceof StreamInterface) {
94
- return $resource;
95
- } elseif ($resource instanceof \Iterator) {
96
- return new PumpStream(function () use ($resource) {
97
- if (!$resource->valid()) {
98
- return false;
99
- }
100
- $result = $resource->current();
101
- $resource->next();
102
- return $result;
103
- }, $options);
104
- } elseif (method_exists($resource, '__toString')) {
105
- return stream_for((string) $resource, $options);
106
- }
107
- break;
108
- case 'NULL':
109
- return new Stream(fopen('php://temp', 'r+'), $options);
110
- }
111
-
112
- if (is_callable($resource)) {
113
- return new PumpStream($resource, $options);
114
- }
115
-
116
- throw new \InvalidArgumentException('Invalid resource type: ' . gettype($resource));
117
- }
118
-
119
- /**
120
- * Parse an array of header values containing ";" separated data into an
121
- * array of associative arrays representing the header key value pair
122
- * data of the header. When a parameter does not contain a value, but just
123
- * contains a key, this function will inject a key with a '' string value.
124
- *
125
- * @param string|array $header Header to parse into components.
126
- *
127
- * @return array Returns the parsed header values.
128
- */
129
- function parse_header($header)
130
- {
131
- static $trimmed = "\"' \n\t\r";
132
- $params = $matches = [];
133
-
134
- foreach (normalize_header($header) as $val) {
135
- $part = [];
136
- foreach (preg_split('/;(?=([^"]*"[^"]*")*[^"]*$)/', $val) as $kvp) {
137
- if (preg_match_all('/<[^>]+>|[^=]+/', $kvp, $matches)) {
138
- $m = $matches[0];
139
- if (isset($m[1])) {
140
- $part[trim($m[0], $trimmed)] = trim($m[1], $trimmed);
141
- } else {
142
- $part[] = trim($m[0], $trimmed);
143
- }
144
- }
145
- }
146
- if ($part) {
147
- $params[] = $part;
148
- }
149
- }
150
-
151
- return $params;
152
- }
153
-
154
- /**
155
- * Converts an array of header values that may contain comma separated
156
- * headers into an array of headers with no comma separated values.
157
- *
158
- * @param string|array $header Header to normalize.
159
- *
160
- * @return array Returns the normalized header field values.
161
- */
162
- function normalize_header($header)
163
- {
164
- if (!is_array($header)) {
165
- return array_map('trim', explode(',', $header));
166
- }
167
-
168
- $result = [];
169
- foreach ($header as $value) {
170
- foreach ((array) $value as $v) {
171
- if (strpos($v, ',') === false) {
172
- $result[] = $v;
173
- continue;
174
- }
175
- foreach (preg_split('/,(?=([^"]*"[^"]*")*[^"]*$)/', $v) as $vv) {
176
- $result[] = trim($vv);
177
- }
178
- }
179
- }
180
-
181
- return $result;
182
- }
183
-
184
- /**
185
- * Clone and modify a request with the given changes.
186
- *
187
- * The changes can be one of:
188
- * - method: (string) Changes the HTTP method.
189
- * - set_headers: (array) Sets the given headers.
190
- * - remove_headers: (array) Remove the given headers.
191
- * - body: (mixed) Sets the given body.
192
- * - uri: (UriInterface) Set the URI.
193
- * - query: (string) Set the query string value of the URI.
194
- * - version: (string) Set the protocol version.
195
- *
196
- * @param RequestInterface $request Request to clone and modify.
197
- * @param array $changes Changes to apply.
198
- *
199
- * @return RequestInterface
200
- */
201
- function modify_request(RequestInterface $request, array $changes)
202
- {
203
- if (!$changes) {
204
- return $request;
205
- }
206
-
207
- $headers = $request->getHeaders();
208
-
209
- if (!isset($changes['uri'])) {
210
- $uri = $request->getUri();
211
- } else {
212
- // Remove the host header if one is on the URI
213
- if ($host = $changes['uri']->getHost()) {
214
- $changes['set_headers']['Host'] = $host;
215
-
216
- if ($port = $changes['uri']->getPort()) {
217
- $standardPorts = ['http' => 80, 'https' => 443];
218
- $scheme = $changes['uri']->getScheme();
219
- if (isset($standardPorts[$scheme]) && $port != $standardPorts[$scheme]) {
220
- $changes['set_headers']['Host'] .= ':'.$port;
221
- }
222
- }
223
- }
224
- $uri = $changes['uri'];
225
- }
226
-
227
- if (!empty($changes['remove_headers'])) {
228
- $headers = _caseless_remove($changes['remove_headers'], $headers);
229
- }
230
-
231
- if (!empty($changes['set_headers'])) {
232
- $headers = _caseless_remove(array_keys($changes['set_headers']), $headers);
233
- $headers = $changes['set_headers'] + $headers;
234
- }
235
-
236
- if (isset($changes['query'])) {
237
- $uri = $uri->withQuery($changes['query']);
238
- }
239
-
240
- if ($request instanceof ServerRequestInterface) {
241
- return (new ServerRequest(
242
- isset($changes['method']) ? $changes['method'] : $request->getMethod(),
243
- $uri,
244
- $headers,
245
- isset($changes['body']) ? $changes['body'] : $request->getBody(),
246
- isset($changes['version'])
247
- ? $changes['version']
248
- : $request->getProtocolVersion(),
249
- $request->getServerParams()
250
- ))
251
- ->withParsedBody($request->getParsedBody())
252
- ->withQueryParams($request->getQueryParams())
253
- ->withCookieParams($request->getCookieParams())
254
- ->withUploadedFiles($request->getUploadedFiles());
255
- }
256
-
257
- return new Request(
258
- isset($changes['method']) ? $changes['method'] : $request->getMethod(),
259
- $uri,
260
- $headers,
261
- isset($changes['body']) ? $changes['body'] : $request->getBody(),
262
- isset($changes['version'])
263
- ? $changes['version']
264
- : $request->getProtocolVersion()
265
- );
266
- }
267
-
268
- /**
269
- * Attempts to rewind a message body and throws an exception on failure.
270
- *
271
- * The body of the message will only be rewound if a call to `tell()` returns a
272
- * value other than `0`.
273
- *
274
- * @param MessageInterface $message Message to rewind
275
- *
276
- * @throws \RuntimeException
277
- */
278
- function rewind_body(MessageInterface $message)
279
- {
280
- $body = $message->getBody();
281
-
282
- if ($body->tell()) {
283
- $body->rewind();
284
- }
285
- }
286
-
287
- /**
288
- * Safely opens a PHP stream resource using a filename.
289
- *
290
- * When fopen fails, PHP normally raises a warning. This function adds an
291
- * error handler that checks for errors and throws an exception instead.
292
- *
293
- * @param string $filename File to open
294
- * @param string $mode Mode used to open the file
295
- *
296
- * @return resource
297
- * @throws \RuntimeException if the file cannot be opened
298
- */
299
- function try_fopen($filename, $mode)
300
- {
301
- $ex = null;
302
- set_error_handler(function () use ($filename, $mode, &$ex) {
303
- $ex = new \RuntimeException(sprintf(
304
- 'Unable to open %s using mode %s: %s',
305
- $filename,
306
- $mode,
307
- func_get_args()[1]
308
- ));
309
- });
310
-
311
- $handle = fopen($filename, $mode);
312
- restore_error_handler();
313
-
314
- if ($ex) {
315
- /** @var $ex \RuntimeException */
316
- throw $ex;
317
- }
318
-
319
- return $handle;
320
- }
321
-
322
- /**
323
- * Copy the contents of a stream into a string until the given number of
324
- * bytes have been read.
325
- *
326
- * @param StreamInterface $stream Stream to read
327
- * @param int $maxLen Maximum number of bytes to read. Pass -1
328
- * to read the entire stream.
329
- * @return string
330
- * @throws \RuntimeException on error.
331
- */
332
- function copy_to_string(StreamInterface $stream, $maxLen = -1)
333
- {
334
- $buffer = '';
335
-
336
- if ($maxLen === -1) {
337
- while (!$stream->eof()) {
338
- $buf = $stream->read(1048576);
339
- // Using a loose equality here to match on '' and false.
340
- if ($buf == null) {
341
- break;
342
- }
343
- $buffer .= $buf;
344
- }
345
- return $buffer;
346
- }
347
-
348
- $len = 0;
349
- while (!$stream->eof() && $len < $maxLen) {
350
- $buf = $stream->read($maxLen - $len);
351
- // Using a loose equality here to match on '' and false.
352
- if ($buf == null) {
353
- break;
354
- }
355
- $buffer .= $buf;
356
- $len = strlen($buffer);
357
- }
358
-
359
- return $buffer;
360
- }
361
-
362
- /**
363
- * Copy the contents of a stream into another stream until the given number
364
- * of bytes have been read.
365
- *
366
- * @param StreamInterface $source Stream to read from
367
- * @param StreamInterface $dest Stream to write to
368
- * @param int $maxLen Maximum number of bytes to read. Pass -1
369
- * to read the entire stream.
370
- *
371
- * @throws \RuntimeException on error.
372
- */
373
- function copy_to_stream(
374
- StreamInterface $source,
375
- StreamInterface $dest,
376
- $maxLen = -1
377
- ) {
378
- $bufferSize = 8192;
379
-
380
- if ($maxLen === -1) {
381
- while (!$source->eof()) {
382
- if (!$dest->write($source->read($bufferSize))) {
383
- break;
384
- }
385
- }
386
- } else {
387
- $remaining = $maxLen;
388
- while ($remaining > 0 && !$source->eof()) {
389
- $buf = $source->read(min($bufferSize, $remaining));
390
- $len = strlen($buf);
391
- if (!$len) {
392
- break;
393
- }
394
- $remaining -= $len;
395
- $dest->write($buf);
396
- }
397
- }
398
- }
399
-
400
- /**
401
- * Calculate a hash of a Stream
402
- *
403
- * @param StreamInterface $stream Stream to calculate the hash for
404
- * @param string $algo Hash algorithm (e.g. md5, crc32, etc)
405
- * @param bool $rawOutput Whether or not to use raw output
406
- *
407
- * @return string Returns the hash of the stream
408
- * @throws \RuntimeException on error.
409
- */
410
- function hash(
411
- StreamInterface $stream,
412
- $algo,
413
- $rawOutput = false
414
- ) {
415
- $pos = $stream->tell();
416
-
417
- if ($pos > 0) {
418
- $stream->rewind();
419
- }
420
-
421
- $ctx = hash_init($algo);
422
- while (!$stream->eof()) {
423
- hash_update($ctx, $stream->read(1048576));
424
- }
425
-
426
- $out = hash_final($ctx, (bool) $rawOutput);
427
- $stream->seek($pos);
428
-
429
- return $out;
430
- }
431
-
432
- /**
433
- * Read a line from the stream up to the maximum allowed buffer length
434
- *
435
- * @param StreamInterface $stream Stream to read from
436
- * @param int $maxLength Maximum buffer length
437
- *
438
- * @return string
439
- */
440
- function readline(StreamInterface $stream, $maxLength = null)
441
- {
442
- $buffer = '';
443
- $size = 0;
444
-
445
- while (!$stream->eof()) {
446
- // Using a loose equality here to match on '' and false.
447
- if (null == ($byte = $stream->read(1))) {
448
- return $buffer;
449
- }
450
- $buffer .= $byte;
451
- // Break when a new line is found or the max length - 1 is reached
452
- if ($byte === "\n" || ++$size === $maxLength - 1) {
453
- break;
454
- }
455
- }
456
-
457
- return $buffer;
458
- }
459
-
460
- /**
461
- * Parses a request message string into a request object.
462
- *
463
- * @param string $message Request message string.
464
- *
465
- * @return Request
466
- */
467
- function parse_request($message)
468
- {
469
- $data = _parse_message($message);
470
- $matches = [];
471
- if (!preg_match('/^[\S]+\s+([a-zA-Z]+:\/\/|\/).*/', $data['start-line'], $matches)) {
472
- throw new \InvalidArgumentException('Invalid request string');
473
- }
474
- $parts = explode(' ', $data['start-line'], 3);
475
- $version = isset($parts[2]) ? explode('/', $parts[2])[1] : '1.1';
476
-
477
- $request = new Request(
478
- $parts[0],
479
- $matches[1] === '/' ? _parse_request_uri($parts[1], $data['headers']) : $parts[1],
480
- $data['headers'],
481
- $data['body'],
482
- $version
483
- );
484
-
485
- return $matches[1] === '/' ? $request : $request->withRequestTarget($parts[1]);
486
- }
487
-
488
- /**
489
- * Parses a response message string into a response object.
490
- *
491
- * @param string $message Response message string.
492
- *
493
- * @return Response
494
- */
495
- function parse_response($message)
496
- {
497
- $data = _parse_message($message);
498
- // According to https://tools.ietf.org/html/rfc7230#section-3.1.2 the space
499
- // between status-code and reason-phrase is required. But browsers accept
500
- // responses without space and reason as well.
501
- if (!preg_match('/^HTTP\/.* [0-9]{3}( .*|$)/', $data['start-line'])) {
502
- throw new \InvalidArgumentException('Invalid response string: ' . $data['start-line']);
503
- }
504
- $parts = explode(' ', $data['start-line'], 3);
505
-
506
- return new Response(
507
- $parts[1],
508
- $data['headers'],
509
- $data['body'],
510
- explode('/', $parts[0])[1],
511
- isset($parts[2]) ? $parts[2] : null
512
- );
513
- }
514
-
515
- /**
516
- * Parse a query string into an associative array.
517
- *
518
- * If multiple values are found for the same key, the value of that key
519
- * value pair will become an array. This function does not parse nested
520
- * PHP style arrays into an associative array (e.g., foo[a]=1&foo[b]=2 will
521
- * be parsed into ['foo[a]' => '1', 'foo[b]' => '2']).
522
- *
523
- * @param string $str Query string to parse
524
- * @param int|bool $urlEncoding How the query string is encoded
525
- *
526
- * @return array
527
- */
528
- function parse_query($str, $urlEncoding = true)
529
- {
530
- $result = [];
531
-
532
- if ($str === '') {
533
- return $result;
534
- }
535
-
536
- if ($urlEncoding === true) {
537
- $decoder = function ($value) {
538
- return rawurldecode(str_replace('+', ' ', $value));
539
- };
540
- } elseif ($urlEncoding === PHP_QUERY_RFC3986) {
541
- $decoder = 'rawurldecode';
542
- } elseif ($urlEncoding === PHP_QUERY_RFC1738) {
543
- $decoder = 'urldecode';
544
- } else {
545
- $decoder = function ($str) { return $str; };
546
- }
547
-
548
- foreach (explode('&', $str) as $kvp) {
549
- $parts = explode('=', $kvp, 2);
550
- $key = $decoder($parts[0]);
551
- $value = isset($parts[1]) ? $decoder($parts[1]) : null;
552
- if (!isset($result[$key])) {
553
- $result[$key] = $value;
554
- } else {
555
- if (!is_array($result[$key])) {
556
- $result[$key] = [$result[$key]];
557
- }
558
- $result[$key][] = $value;
559
- }
560
- }
561
-
562
- return $result;
563
- }
564
-
565
- /**
566
- * Build a query string from an array of key value pairs.
567
- *
568
- * This function can use the return value of parse_query() to build a query
569
- * string. This function does not modify the provided keys when an array is
570
- * encountered (like http_build_query would).
571
- *
572
- * @param array $params Query string parameters.
573
- * @param int|false $encoding Set to false to not encode, PHP_QUERY_RFC3986
574
- * to encode using RFC3986, or PHP_QUERY_RFC1738
575
- * to encode using RFC1738.
576
- * @return string
577
- */
578
- function build_query(array $params, $encoding = PHP_QUERY_RFC3986)
579
- {
580
- if (!$params) {
581
- return '';
582
- }
583
-
584
- if ($encoding === false) {
585
- $encoder = function ($str) { return $str; };
586
- } elseif ($encoding === PHP_QUERY_RFC3986) {
587
- $encoder = 'rawurlencode';
588
- } elseif ($encoding === PHP_QUERY_RFC1738) {
589
- $encoder = 'urlencode';
590
- } else {
591
- throw new \InvalidArgumentException('Invalid type');
592
- }
593
-
594
- $qs = '';
595
- foreach ($params as $k => $v) {
596
- $k = $encoder($k);
597
- if (!is_array($v)) {
598
- $qs .= $k;
599
- if ($v !== null) {
600
- $qs .= '=' . $encoder($v);
601
- }
602
- $qs .= '&';
603
- } else {
604
- foreach ($v as $vv) {
605
- $qs .= $k;
606
- if ($vv !== null) {
607
- $qs .= '=' . $encoder($vv);
608
- }
609
- $qs .= '&';
610
- }
611
- }
612
- }
613
-
614
- return $qs ? (string) substr($qs, 0, -1) : '';
615
- }
616
-
617
- /**
618
- * Determines the mimetype of a file by looking at its extension.
619
- *
620
- * @param $filename
621
- *
622
- * @return null|string
623
- */
624
- function mimetype_from_filename($filename)
625
- {
626
- return mimetype_from_extension(pathinfo($filename, PATHINFO_EXTENSION));
627
- }
628
-
629
- /**
630
- * Maps a file extensions to a mimetype.
631
- *
632
- * @param $extension string The file extension.
633
- *
634
- * @return string|null
635
- * @link http://svn.apache.org/repos/asf/httpd/httpd/branches/1.3.x/conf/mime.types
636
- */
637
- function mimetype_from_extension($extension)
638
- {
639
- static $mimetypes = [
640
- '3gp' => 'video/3gpp',
641
- '7z' => 'application/x-7z-compressed',
642
- 'aac' => 'audio/x-aac',
643
- 'ai' => 'application/postscript',
644
- 'aif' => 'audio/x-aiff',
645
- 'asc' => 'text/plain',
646
- 'asf' => 'video/x-ms-asf',
647
- 'atom' => 'application/atom+xml',
648
- 'avi' => 'video/x-msvideo',
649
- 'bmp' => 'image/bmp',
650
- 'bz2' => 'application/x-bzip2',
651
- 'cer' => 'application/pkix-cert',
652
- 'crl' => 'application/pkix-crl',
653
- 'crt' => 'application/x-x509-ca-cert',
654
- 'css' => 'text/css',
655
- 'csv' => 'text/csv',
656
- 'cu' => 'application/cu-seeme',
657
- 'deb' => 'application/x-debian-package',
658
- 'doc' => 'application/msword',
659
- 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
660
- 'dvi' => 'application/x-dvi',
661
- 'eot' => 'application/vnd.ms-fontobject',
662
- 'eps' => 'application/postscript',
663
- 'epub' => 'application/epub+zip',
664
- 'etx' => 'text/x-setext',
665
- 'flac' => 'audio/flac',
666
- 'flv' => 'video/x-flv',
667
- 'gif' => 'image/gif',
668
- 'gz' => 'application/gzip',
669
- 'htm' => 'text/html',
670
- 'html' => 'text/html',
671
- 'ico' => 'image/x-icon',
672
- 'ics' => 'text/calendar',
673
- 'ini' => 'text/plain',
674
- 'iso' => 'application/x-iso9660-image',
675
- 'jar' => 'application/java-archive',
676
- 'jpe' => 'image/jpeg',
677
- 'jpeg' => 'image/jpeg',
678
- 'jpg' => 'image/jpeg',
679
- 'js' => 'text/javascript',
680
- 'json' => 'application/json',
681
- 'latex' => 'application/x-latex',
682
- 'log' => 'text/plain',
683
- 'm4a' => 'audio/mp4',
684
- 'm4v' => 'video/mp4',
685
- 'mid' => 'audio/midi',
686
- 'midi' => 'audio/midi',
687
- 'mov' => 'video/quicktime',
688
- 'mkv' => 'video/x-matroska',
689
- 'mp3' => 'audio/mpeg',
690
- 'mp4' => 'video/mp4',
691
- 'mp4a' => 'audio/mp4',
692
- 'mp4v' => 'video/mp4',
693
- 'mpe' => 'video/mpeg',
694
- 'mpeg' => 'video/mpeg',
695
- 'mpg' => 'video/mpeg',
696
- 'mpg4' => 'video/mp4',
697
- 'oga' => 'audio/ogg',
698
- 'ogg' => 'audio/ogg',
699
- 'ogv' => 'video/ogg',
700
- 'ogx' => 'application/ogg',
701
- 'pbm' => 'image/x-portable-bitmap',
702
- 'pdf' => 'application/pdf',
703
- 'pgm' => 'image/x-portable-graymap',
704
- 'png' => 'image/png',
705
- 'pnm' => 'image/x-portable-anymap',
706
- 'ppm' => 'image/x-portable-pixmap',
707
- 'ppt' => 'application/vnd.ms-powerpoint',
708
- 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
709
- 'ps' => 'application/postscript',
710
- 'qt' => 'video/quicktime',
711
- 'rar' => 'application/x-rar-compressed',
712
- 'ras' => 'image/x-cmu-raster',
713
- 'rss' => 'application/rss+xml',
714
- 'rtf' => 'application/rtf',
715
- 'sgm' => 'text/sgml',
716
- 'sgml' => 'text/sgml',
717
- 'svg' => 'image/svg+xml',
718
- 'swf' => 'application/x-shockwave-flash',
719
- 'tar' => 'application/x-tar',
720
- 'tif' => 'image/tiff',
721
- 'tiff' => 'image/tiff',
722
- 'torrent' => 'application/x-bittorrent',
723
- 'ttf' => 'application/x-font-ttf',
724
- 'txt' => 'text/plain',
725
- 'wav' => 'audio/x-wav',
726
- 'webm' => 'video/webm',
727
- 'wma' => 'audio/x-ms-wma',
728
- 'wmv' => 'video/x-ms-wmv',
729
- 'woff' => 'application/x-font-woff',
730
- 'wsdl' => 'application/wsdl+xml',
731
- 'xbm' => 'image/x-xbitmap',
732
- 'xls' => 'application/vnd.ms-excel',
733
- 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
734
- 'xml' => 'application/xml',
735
- 'xpm' => 'image/x-xpixmap',
736
- 'xwd' => 'image/x-xwindowdump',
737
- 'yaml' => 'text/yaml',
738
- 'yml' => 'text/yaml',
739
- 'zip' => 'application/zip',
740
- ];
741
-
742
- $extension = strtolower($extension);
743
-
744
- return isset($mimetypes[$extension])
745
- ? $mimetypes[$extension]
746
- : null;
747
- }
748
-
749
- /**
750
- * Parses an HTTP message into an associative array.
751
- *
752
- * The array contains the "start-line" key containing the start line of
753
- * the message, "headers" key containing an associative array of header
754
- * array values, and a "body" key containing the body of the message.
755
- *
756
- * @param string $message HTTP request or response to parse.
757
- *
758
- * @return array
759
- * @internal
760
- */
761
- function _parse_message($message)
762
- {
763
- if (!$message) {
764
- throw new \InvalidArgumentException('Invalid message');
765
- }
766
-
767
- $message = ltrim($message, "\r\n");
768
-
769
- $messageParts = preg_split("/\r?\n\r?\n/", $message, 2);
770
-
771
- if ($messageParts === false || count($messageParts) !== 2) {
772
- throw new \InvalidArgumentException('Invalid message: Missing header delimiter');
773
- }
774
-
775
- list($rawHeaders, $body) = $messageParts;
776
- $rawHeaders .= "\r\n"; // Put back the delimiter we split previously
777
- $headerParts = preg_split("/\r?\n/", $rawHeaders, 2);
778
-
779
- if ($headerParts === false || count($headerParts) !== 2) {
780
- throw new \InvalidArgumentException('Invalid message: Missing status line');
781
- }
782
-
783
- list($startLine, $rawHeaders) = $headerParts;
784
-
785
- if (preg_match("/(?:^HTTP\/|^[A-Z]+ \S+ HTTP\/)(\d+(?:\.\d+)?)/i", $startLine, $matches) && $matches[1] === '1.0') {
786
- // Header folding is deprecated for HTTP/1.1, but allowed in HTTP/1.0
787
- $rawHeaders = preg_replace(Rfc7230::HEADER_FOLD_REGEX, ' ', $rawHeaders);
788
- }
789
-
790
- /** @var array[] $headerLines */
791
- $count = preg_match_all(Rfc7230::HEADER_REGEX, $rawHeaders, $headerLines, PREG_SET_ORDER);
792
-
793
- // If these aren't the same, then one line didn't match and there's an invalid header.
794
- if ($count !== substr_count($rawHeaders, "\n")) {
795
- // Folding is deprecated, see https://tools.ietf.org/html/rfc7230#section-3.2.4
796
- if (preg_match(Rfc7230::HEADER_FOLD_REGEX, $rawHeaders)) {
797
- throw new \InvalidArgumentException('Invalid header syntax: Obsolete line folding');
798
- }
799
-
800
- throw new \InvalidArgumentException('Invalid header syntax');
801
- }
802
-
803
- $headers = [];
804
-
805
- foreach ($headerLines as $headerLine) {
806
- $headers[$headerLine[1]][] = $headerLine[2];
807
- }
808
-
809
- return [
810
- 'start-line' => $startLine,
811
- 'headers' => $headers,
812
- 'body' => $body,
813
- ];
814
- }
815
-
816
- /**
817
- * Constructs a URI for an HTTP request message.
818
- *
819
- * @param string $path Path from the start-line
820
- * @param array $headers Array of headers (each value an array).
821
- *
822
- * @return string
823
- * @internal
824
- */
825
- function _parse_request_uri($path, array $headers)
826
- {
827
- $hostKey = array_filter(array_keys($headers), function ($k) {
828
- return strtolower($k) === 'host';
829
- });
830
-
831
- // If no host is found, then a full URI cannot be constructed.
832
- if (!$hostKey) {
833
- return $path;
834
- }
835
-
836
- $host = $headers[reset($hostKey)][0];
837
- $scheme = substr($host, -4) === ':443' ? 'https' : 'http';
838
-
839
- return $scheme . '://' . $host . '/' . ltrim($path, '/');
840
- }
841
-
842
- /**
843
- * Get a short summary of the message body
844
- *
845
- * Will return `null` if the response is not printable.
846
- *
847
- * @param MessageInterface $message The message to get the body summary
848
- * @param int $truncateAt The maximum allowed size of the summary
849
- *
850
- * @return null|string
851
- */
852
- function get_message_body_summary(MessageInterface $message, $truncateAt = 120)
853
- {
854
- $body = $message->getBody();
855
-
856
- if (!$body->isSeekable() || !$body->isReadable()) {
857
- return null;
858
- }
859
-
860
- $size = $body->getSize();
861
-
862
- if ($size === 0) {
863
- return null;
864
- }
865
-
866
- $summary = $body->read($truncateAt);
867
- $body->rewind();
868
-
869
- if ($size > $truncateAt) {
870
- $summary .= ' (truncated...)';
871
- }
872
-
873
- // Matches any printable character, including unicode characters:
874
- // letters, marks, numbers, punctuation, spacing, and separators.
875
- if (preg_match('/[^\pL\pM\pN\pP\pS\pZ\n\r\t]/', $summary)) {
876
- return null;
877
- }
878
-
879
- return $summary;
880
- }
881
-
882
- /** @internal */
883
- function _caseless_remove($keys, array $data)
884
- {
885
- $result = [];
886
-
887
- foreach ($keys as &$key) {
888
- $key = strtolower($key);
889
- }
890
-
891
- foreach ($data as $k => $v) {
892
- if (!in_array(strtolower($k), $keys)) {
893
- $result[$k] = $v;
894
- }
895
- }
896
-
897
- return $result;
898
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/guzzlehttp/psr7/src/functions_include.php DELETED
@@ -1,6 +0,0 @@
1
- <?php
2
-
3
- // Don't redefine the functions if included multiple times.
4
- if (!function_exists('GuzzleHttp\Psr7\str')) {
5
- require __DIR__ . '/functions.php';
6
- }
 
 
 
 
 
 
vendor/psr/http-message/CHANGELOG.md DELETED
@@ -1,36 +0,0 @@
1
- # Changelog
2
-
3
- All notable changes to this project will be documented in this file, in reverse chronological order by release.
4
-
5
- ## 1.0.1 - 2016-08-06
6
-
7
- ### Added
8
-
9
- - Nothing.
10
-
11
- ### Deprecated
12
-
13
- - Nothing.
14
-
15
- ### Removed
16
-
17
- - Nothing.
18
-
19
- ### Fixed
20
-
21
- - Updated all `@return self` annotation references in interfaces to use
22
- `@return static`, which more closelly follows the semantics of the
23
- specification.
24
- - Updated the `MessageInterface::getHeaders()` return annotation to use the
25
- value `string[][]`, indicating the format is a nested array of strings.
26
- - Updated the `@link` annotation for `RequestInterface::withRequestTarget()`
27
- to point to the correct section of RFC 7230.
28
- - Updated the `ServerRequestInterface::withUploadedFiles()` parameter annotation
29
- to add the parameter name (`$uploadedFiles`).
30
- - Updated a `@throws` annotation for the `UploadedFileInterface::moveTo()`
31
- method to correctly reference the method parameter (it was referencing an
32
- incorrect parameter name previously).
33
-
34
- ## 1.0.0 - 2016-05-18
35
-
36
- Initial stable release; reflects accepted PSR-7 specification.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/psr/http-message/LICENSE DELETED
@@ -1,19 +0,0 @@
1
- Copyright (c) 2014 PHP Framework Interoperability Group
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining a copy
4
- of this software and associated documentation files (the "Software"), to deal
5
- in the Software without restriction, including without limitation the rights
6
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
- copies of the Software, and to permit persons to whom the Software is
8
- furnished to do so, subject to the following conditions:
9
-
10
- The above copyright notice and this permission notice shall be included in
11
- all copies or substantial portions of the Software.
12
-
13
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
- THE SOFTWARE.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/psr/http-message/README.md DELETED
@@ -1,13 +0,0 @@
1
- PSR Http Message
2
- ================
3
-
4
- This repository holds all interfaces/classes/traits related to
5
- [PSR-7](http://www.php-fig.org/psr/psr-7/).
6
-
7
- Note that this is not a HTTP message implementation of its own. It is merely an
8
- interface that describes a HTTP message. See the specification for more details.
9
-
10
- Usage
11
- -----
12
-
13
- We'll certainly need some stuff in here.
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/psr/http-message/src/MessageInterface.php DELETED
@@ -1,187 +0,0 @@
1
- <?php
2
-
3
- namespace Psr\Http\Message;
4
-
5
- /**
6
- * HTTP messages consist of requests from a client to a server and responses
7
- * from a server to a client. This interface defines the methods common to
8
- * each.
9
- *
10
- * Messages are considered immutable; all methods that might change state MUST
11
- * be implemented such that they retain the internal state of the current
12
- * message and return an instance that contains the changed state.
13
- *
14
- * @link http://www.ietf.org/rfc/rfc7230.txt
15
- * @link http://www.ietf.org/rfc/rfc7231.txt
16
- */
17
- interface MessageInterface
18
- {
19
- /**
20
- * Retrieves the HTTP protocol version as a string.
21
- *
22
- * The string MUST contain only the HTTP version number (e.g., "1.1", "1.0").
23
- *
24
- * @return string HTTP protocol version.
25
- */
26
- public function getProtocolVersion();
27
-
28
- /**
29
- * Return an instance with the specified HTTP protocol version.
30
- *
31
- * The version string MUST contain only the HTTP version number (e.g.,
32
- * "1.1", "1.0").
33
- *
34
- * This method MUST be implemented in such a way as to retain the
35
- * immutability of the message, and MUST return an instance that has the
36
- * new protocol version.
37
- *
38
- * @param string $version HTTP protocol version
39
- * @return static
40
- */
41
- public function withProtocolVersion($version);
42
-
43
- /**
44
- * Retrieves all message header values.
45
- *
46
- * The keys represent the header name as it will be sent over the wire, and
47
- * each value is an array of strings associated with the header.
48
- *
49
- * // Represent the headers as a string
50
- * foreach ($message->getHeaders() as $name => $values) {
51
- * echo $name . ": " . implode(", ", $values);
52
- * }
53
- *
54
- * // Emit headers iteratively:
55
- * foreach ($message->getHeaders() as $name => $values) {
56
- * foreach ($values as $value) {
57
- * header(sprintf('%s: %s', $name, $value), false);
58
- * }
59
- * }
60
- *
61
- * While header names are not case-sensitive, getHeaders() will preserve the
62
- * exact case in which headers were originally specified.
63
- *
64
- * @return string[][] Returns an associative array of the message's headers. Each
65
- * key MUST be a header name, and each value MUST be an array of strings
66
- * for that header.
67
- */
68
- public function getHeaders();
69
-
70
- /**
71
- * Checks if a header exists by the given case-insensitive name.
72
- *
73
- * @param string $name Case-insensitive header field name.
74
- * @return bool Returns true if any header names match the given header
75
- * name using a case-insensitive string comparison. Returns false if
76
- * no matching header name is found in the message.
77
- */
78
- public function hasHeader($name);
79
-
80
- /**
81
- * Retrieves a message header value by the given case-insensitive name.
82
- *
83
- * This method returns an array of all the header values of the given
84
- * case-insensitive header name.
85
- *
86
- * If the header does not appear in the message, this method MUST return an
87
- * empty array.
88
- *
89
- * @param string $name Case-insensitive header field name.
90
- * @return string[] An array of string values as provided for the given
91
- * header. If the header does not appear in the message, this method MUST
92
- * return an empty array.
93
- */
94
- public function getHeader($name);
95
-
96
- /**
97
- * Retrieves a comma-separated string of the values for a single header.
98
- *
99
- * This method returns all of the header values of the given
100
- * case-insensitive header name as a string concatenated together using
101
- * a comma.
102
- *
103
- * NOTE: Not all header values may be appropriately represented using
104
- * comma concatenation. For such headers, use getHeader() instead
105
- * and supply your own delimiter when concatenating.
106
- *
107
- * If the header does not appear in the message, this method MUST return
108
- * an empty string.
109
- *
110
- * @param string $name Case-insensitive header field name.
111
- * @return string A string of values as provided for the given header
112
- * concatenated together using a comma. If the header does not appear in
113
- * the message, this method MUST return an empty string.
114
- */
115
- public function getHeaderLine($name);
116
-
117
- /**
118
- * Return an instance with the provided value replacing the specified header.
119
- *
120
- * While header names are case-insensitive, the casing of the header will
121
- * be preserved by this function, and returned from getHeaders().
122
- *
123
- * This method MUST be implemented in such a way as to retain the
124
- * immutability of the message, and MUST return an instance that has the
125
- * new and/or updated header and value.
126
- *
127
- * @param string $name Case-insensitive header field name.
128
- * @param string|string[] $value Header value(s).
129
- * @return static
130
- * @throws \InvalidArgumentException for invalid header names or values.
131
- */
132
- public function withHeader($name, $value);
133
-
134
- /**
135
- * Return an instance with the specified header appended with the given value.
136
- *
137
- * Existing values for the specified header will be maintained. The new
138
- * value(s) will be appended to the existing list. If the header did not
139
- * exist previously, it will be added.
140
- *
141
- * This method MUST be implemented in such a way as to retain the
142
- * immutability of the message, and MUST return an instance that has the
143
- * new header and/or value.
144
- *
145
- * @param string $name Case-insensitive header field name to add.
146
- * @param string|string[] $value Header value(s).
147
- * @return static
148
- * @throws \InvalidArgumentException for invalid header names or values.
149
- */
150
- public function withAddedHeader($name, $value);
151
-
152
- /**
153
- * Return an instance without the specified header.
154
- *
155
- * Header resolution MUST be done without case-sensitivity.
156
- *
157
- * This method MUST be implemented in such a way as to retain the
158
- * immutability of the message, and MUST return an instance that removes
159
- * the named header.
160
- *
161
- * @param string $name Case-insensitive header field name to remove.
162
- * @return static
163
- */
164
- public function withoutHeader($name);
165
-
166
- /**
167
- * Gets the body of the message.
168
- *
169
- * @return StreamInterface Returns the body as a stream.
170
- */
171
- public function getBody();
172
-
173
- /**
174
- * Return an instance with the specified message body.
175
- *
176
- * The body MUST be a StreamInterface object.
177
- *
178
- * This method MUST be implemented in such a way as to retain the
179
- * immutability of the message, and MUST return a new instance that has the
180
- * new body stream.
181
- *
182
- * @param StreamInterface $body Body.
183
- * @return static
184
- * @throws \InvalidArgumentException When the body is not valid.
185
- */
186
- public function withBody(StreamInterface $body);
187
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/psr/http-message/src/RequestInterface.php DELETED
@@ -1,129 +0,0 @@
1
- <?php
2
-
3
- namespace Psr\Http\Message;
4
-
5
- /**
6
- * Representation of an outgoing, client-side request.
7
- *
8
- * Per the HTTP specification, this interface includes properties for
9
- * each of the following:
10
- *
11
- * - Protocol version
12
- * - HTTP method
13
- * - URI
14
- * - Headers
15
- * - Message body
16
- *
17
- * During construction, implementations MUST attempt to set the Host header from
18
- * a provided URI if no Host header is provided.
19
- *
20
- * Requests are considered immutable; all methods that might change state MUST
21
- * be implemented such that they retain the internal state of the current
22
- * message and return an instance that contains the changed state.
23
- */
24
- interface RequestInterface extends MessageInterface
25
- {
26
- /**
27
- * Retrieves the message's request target.
28
- *
29
- * Retrieves the message's request-target either as it will appear (for
30
- * clients), as it appeared at request (for servers), or as it was
31
- * specified for the instance (see withRequestTarget()).
32
- *
33
- * In most cases, this will be the origin-form of the composed URI,
34
- * unless a value was provided to the concrete implementation (see
35
- * withRequestTarget() below).
36
- *
37
- * If no URI is available, and no request-target has been specifically
38
- * provided, this method MUST return the string "/".
39
- *
40
- * @return string
41
- */
42
- public function getRequestTarget();
43
-
44
- /**
45
- * Return an instance with the specific request-target.
46
- *
47
- * If the request needs a non-origin-form request-target — e.g., for
48
- * specifying an absolute-form, authority-form, or asterisk-form —
49
- * this method may be used to create an instance with the specified
50
- * request-target, verbatim.
51
- *
52
- * This method MUST be implemented in such a way as to retain the
53
- * immutability of the message, and MUST return an instance that has the
54
- * changed request target.
55
- *
56
- * @link http://tools.ietf.org/html/rfc7230#section-5.3 (for the various
57
- * request-target forms allowed in request messages)
58
- * @param mixed $requestTarget
59
- * @return static
60
- */
61
- public function withRequestTarget($requestTarget);
62
-
63
- /**
64
- * Retrieves the HTTP method of the request.
65
- *
66
- * @return string Returns the request method.
67
- */
68
- public function getMethod();
69
-
70
- /**
71
- * Return an instance with the provided HTTP method.
72
- *
73
- * While HTTP method names are typically all uppercase characters, HTTP
74
- * method names are case-sensitive and thus implementations SHOULD NOT
75
- * modify the given string.
76
- *
77
- * This method MUST be implemented in such a way as to retain the
78
- * immutability of the message, and MUST return an instance that has the
79
- * changed request method.
80
- *
81
- * @param string $method Case-sensitive method.
82
- * @return static
83
- * @throws \InvalidArgumentException for invalid HTTP methods.
84
- */
85
- public function withMethod($method);
86
-
87
- /**
88
- * Retrieves the URI instance.
89
- *
90
- * This method MUST return a UriInterface instance.
91
- *
92
- * @link http://tools.ietf.org/html/rfc3986#section-4.3
93
- * @return UriInterface Returns a UriInterface instance
94
- * representing the URI of the request.
95
- */
96
- public function getUri();
97
-
98
- /**
99
- * Returns an instance with the provided URI.
100
- *
101
- * This method MUST update the Host header of the returned request by
102
- * default if the URI contains a host component. If the URI does not
103
- * contain a host component, any pre-existing Host header MUST be carried
104
- * over to the returned request.
105
- *
106
- * You can opt-in to preserving the original state of the Host header by
107
- * setting `$preserveHost` to `true`. When `$preserveHost` is set to
108
- * `true`, this method interacts with the Host header in the following ways:
109
- *
110
- * - If the Host header is missing or empty, and the new URI contains
111
- * a host component, this method MUST update the Host header in the returned
112
- * request.
113
- * - If the Host header is missing or empty, and the new URI does not contain a
114
- * host component, this method MUST NOT update the Host header in the returned
115
- * request.
116
- * - If a Host header is present and non-empty, this method MUST NOT update
117
- * the Host header in the returned request.
118
- *
119
- * This method MUST be implemented in such a way as to retain the
120
- * immutability of the message, and MUST return an instance that has the
121
- * new UriInterface instance.
122
- *
123
- * @link http://tools.ietf.org/html/rfc3986#section-4.3
124
- * @param UriInterface $uri New request URI to use.
125
- * @param bool $preserveHost Preserve the original state of the Host header.
126
- * @return static
127
- */
128
- public function withUri(UriInterface $uri, $preserveHost = false);
129
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/psr/http-message/src/ResponseInterface.php DELETED
@@ -1,68 +0,0 @@
1
- <?php
2
-
3
- namespace Psr\Http\Message;
4
-
5
- /**
6
- * Representation of an outgoing, server-side response.
7
- *
8
- * Per the HTTP specification, this interface includes properties for
9
- * each of the following:
10
- *
11
- * - Protocol version
12
- * - Status code and reason phrase
13
- * - Headers
14
- * - Message body
15
- *
16
- * Responses are considered immutable; all methods that might change state MUST
17
- * be implemented such that they retain the internal state of the current
18
- * message and return an instance that contains the changed state.
19
- */
20
- interface ResponseInterface extends MessageInterface
21
- {
22
- /**
23
- * Gets the response status code.
24
- *
25
- * The status code is a 3-digit integer result code of the server's attempt
26
- * to understand and satisfy the request.
27
- *
28
- * @return int Status code.
29
- */
30
- public function getStatusCode();
31
-
32
- /**
33
- * Return an instance with the specified status code and, optionally, reason phrase.
34
- *
35
- * If no reason phrase is specified, implementations MAY choose to default
36
- * to the RFC 7231 or IANA recommended reason phrase for the response's
37
- * status code.
38
- *
39
- * This method MUST be implemented in such a way as to retain the
40
- * immutability of the message, and MUST return an instance that has the
41
- * updated status and reason phrase.
42
- *
43
- * @link http://tools.ietf.org/html/rfc7231#section-6
44
- * @link http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
45
- * @param int $code The 3-digit integer result code to set.
46
- * @param string $reasonPhrase The reason phrase to use with the
47
- * provided status code; if none is provided, implementations MAY
48
- * use the defaults as suggested in the HTTP specification.
49
- * @return static
50
- * @throws \InvalidArgumentException For invalid status code arguments.
51
- */
52
- public function withStatus($code, $reasonPhrase = '');
53
-
54
- /**
55
- * Gets the response reason phrase associated with the status code.
56
- *
57
- * Because a reason phrase is not a required element in a response
58
- * status line, the reason phrase value MAY be null. Implementations MAY
59
- * choose to return the default RFC 7231 recommended reason phrase (or those
60
- * listed in the IANA HTTP Status Code Registry) for the response's
61
- * status code.
62
- *
63
- * @link http://tools.ietf.org/html/rfc7231#section-6
64
- * @link http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
65
- * @return string Reason phrase; must return an empty string if none present.
66
- */
67
- public function getReasonPhrase();
68
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/psr/http-message/src/ServerRequestInterface.php DELETED
@@ -1,261 +0,0 @@
1
- <?php
2
-
3
- namespace Psr\Http\Message;
4
-
5
- /**
6
- * Representation of an incoming, server-side HTTP request.
7
- *
8
- * Per the HTTP specification, this interface includes properties for
9
- * each of the following:
10
- *
11
- * - Protocol version
12
- * - HTTP method
13
- * - URI
14
- * - Headers
15
- * - Message body
16
- *
17
- * Additionally, it encapsulates all data as it has arrived to the
18
- * application from the CGI and/or PHP environment, including:
19
- *
20
- * - The values represented in $_SERVER.
21
- * - Any cookies provided (generally via $_COOKIE)
22
- * - Query string arguments (generally via $_GET, or as parsed via parse_str())
23
- * - Upload files, if any (as represented by $_FILES)
24
- * - Deserialized body parameters (generally from $_POST)
25
- *
26
- * $_SERVER values MUST be treated as immutable, as they represent application
27
- * state at the time of request; as such, no methods are provided to allow
28
- * modification of those values. The other values provide such methods, as they
29
- * can be restored from $_SERVER or the request body, and may need treatment
30
- * during the application (e.g., body parameters may be deserialized based on
31
- * content type).
32
- *
33
- * Additionally, this interface recognizes the utility of introspecting a
34
- * request to derive and match additional parameters (e.g., via URI path
35
- * matching, decrypting cookie values, deserializing non-form-encoded body
36
- * content, matching authorization headers to users, etc). These parameters
37
- * are stored in an "attributes" property.
38
- *
39
- * Requests are considered immutable; all methods that might change state MUST
40
- * be implemented such that they retain the internal state of the current
41
- * message and return an instance that contains the changed state.
42
- */
43
- interface ServerRequestInterface extends RequestInterface
44
- {
45
- /**
46
- * Retrieve server parameters.
47
- *
48
- * Retrieves data related to the incoming request environment,
49
- * typically derived from PHP's $_SERVER superglobal. The data IS NOT
50
- * REQUIRED to originate from $_SERVER.
51
- *
52
- * @return array
53
- */
54
- public function getServerParams();
55
-
56
- /**
57
- * Retrieve cookies.
58
- *
59
- * Retrieves cookies sent by the client to the server.
60
- *
61
- * The data MUST be compatible with the structure of the $_COOKIE
62
- * superglobal.
63
- *
64
- * @return array
65
- */
66
- public function getCookieParams();
67
-
68
- /**
69
- * Return an instance with the specified cookies.
70
- *
71
- * The data IS NOT REQUIRED to come from the $_COOKIE superglobal, but MUST
72
- * be compatible with the structure of $_COOKIE. Typically, this data will
73
- * be injected at instantiation.
74
- *
75
- * This method MUST NOT update the related Cookie header of the request
76
- * instance, nor related values in the server params.
77
- *
78
- * This method MUST be implemented in such a way as to retain the
79
- * immutability of the message, and MUST return an instance that has the
80
- * updated cookie values.
81
- *
82
- * @param array $cookies Array of key/value pairs representing cookies.
83
- * @return static
84
- */
85
- public function withCookieParams(array $cookies);
86
-
87
- /**
88
- * Retrieve query string arguments.
89
- *
90
- * Retrieves the deserialized query string arguments, if any.
91
- *
92
- * Note: the query params might not be in sync with the URI or server
93
- * params. If you need to ensure you are only getting the original
94
- * values, you may need to parse the query string from `getUri()->getQuery()`
95
- * or from the `QUERY_STRING` server param.
96
- *
97
- * @return array
98
- */
99
- public function getQueryParams();
100
-
101
- /**
102
- * Return an instance with the specified query string arguments.
103
- *
104
- * These values SHOULD remain immutable over the course of the incoming
105
- * request. They MAY be injected during instantiation, such as from PHP's
106
- * $_GET superglobal, or MAY be derived from some other value such as the
107
- * URI. In cases where the arguments are parsed from the URI, the data
108
- * MUST be compatible with what PHP's parse_str() would return for
109
- * purposes of how duplicate query parameters are handled, and how nested
110
- * sets are handled.
111
- *
112
- * Setting query string arguments MUST NOT change the URI stored by the
113
- * request, nor the values in the server params.
114
- *
115
- * This method MUST be implemented in such a way as to retain the
116
- * immutability of the message, and MUST return an instance that has the
117
- * updated query string arguments.
118
- *
119
- * @param array $query Array of query string arguments, typically from
120
- * $_GET.
121
- * @return static
122
- */
123
- public function withQueryParams(array $query);
124
-
125
- /**
126
- * Retrieve normalized file upload data.
127
- *
128
- * This method returns upload metadata in a normalized tree, with each leaf
129
- * an instance of Psr\Http\Message\UploadedFileInterface.
130
- *
131
- * These values MAY be prepared from $_FILES or the message body during
132
- * instantiation, or MAY be injected via withUploadedFiles().
133
- *
134
- * @return array An array tree of UploadedFileInterface instances; an empty
135
- * array MUST be returned if no data is present.
136
- */
137
- public function getUploadedFiles();
138
-
139
- /**
140
- * Create a new instance with the specified uploaded files.
141
- *
142
- * This method MUST be implemented in such a way as to retain the
143
- * immutability of the message, and MUST return an instance that has the
144
- * updated body parameters.
145
- *
146
- * @param array $uploadedFiles An array tree of UploadedFileInterface instances.
147
- * @return static
148
- * @throws \InvalidArgumentException if an invalid structure is provided.
149
- */
150
- public function withUploadedFiles(array $uploadedFiles);
151
-
152
- /**
153
- * Retrieve any parameters provided in the request body.
154
- *
155
- * If the request Content-Type is either application/x-www-form-urlencoded
156
- * or multipart/form-data, and the request method is POST, this method MUST
157
- * return the contents of $_POST.
158
- *
159
- * Otherwise, this method may return any results of deserializing
160
- * the request body content; as parsing returns structured content, the
161
- * potential types MUST be arrays or objects only. A null value indicates
162
- * the absence of body content.
163
- *
164
- * @return null|array|object The deserialized body parameters, if any.
165
- * These will typically be an array or object.
166
- */
167
- public function getParsedBody();
168
-
169
- /**
170
- * Return an instance with the specified body parameters.
171
- *
172
- * These MAY be injected during instantiation.
173
- *
174
- * If the request Content-Type is either application/x-www-form-urlencoded
175
- * or multipart/form-data, and the request method is POST, use this method
176
- * ONLY to inject the contents of $_POST.
177
- *
178
- * The data IS NOT REQUIRED to come from $_POST, but MUST be the results of
179
- * deserializing the request body content. Deserialization/parsing returns
180
- * structured data, and, as such, this method ONLY accepts arrays or objects,
181
- * or a null value if nothing was available to parse.
182
- *
183
- * As an example, if content negotiation determines that the request data
184
- * is a JSON payload, this method could be used to create a request
185
- * instance with the deserialized parameters.
186
- *
187
- * This method MUST be implemented in such a way as to retain the
188
- * immutability of the message, and MUST return an instance that has the
189
- * updated body parameters.
190
- *
191
- * @param null|array|object $data The deserialized body data. This will
192
- * typically be in an array or object.
193
- * @return static
194
- * @throws \InvalidArgumentException if an unsupported argument type is
195
- * provided.
196
- */
197
- public function withParsedBody($data);
198
-
199
- /**
200
- * Retrieve attributes derived from the request.
201
- *
202
- * The request "attributes" may be used to allow injection of any
203
- * parameters derived from the request: e.g., the results of path
204
- * match operations; the results of decrypting cookies; the results of
205
- * deserializing non-form-encoded message bodies; etc. Attributes
206
- * will be application and request specific, and CAN be mutable.
207
- *
208
- * @return array Attributes derived from the request.
209
- */
210
- public function getAttributes();
211
-
212
- /**
213
- * Retrieve a single derived request attribute.
214
- *
215
- * Retrieves a single derived request attribute as described in
216
- * getAttributes(). If the attribute has not been previously set, returns
217
- * the default value as provided.
218
- *
219
- * This method obviates the need for a hasAttribute() method, as it allows
220
- * specifying a default value to return if the attribute is not found.
221
- *
222
- * @see getAttributes()
223
- * @param string $name The attribute name.
224
- * @param mixed $default Default value to return if the attribute does not exist.
225
- * @return mixed
226
- */
227
- public function getAttribute($name, $default = null);
228
-
229
- /**
230
- * Return an instance with the specified derived request attribute.
231
- *
232
- * This method allows setting a single derived request attribute as
233
- * described in getAttributes().
234
- *
235
- * This method MUST be implemented in such a way as to retain the
236
- * immutability of the message, and MUST return an instance that has the
237
- * updated attribute.
238
- *
239
- * @see getAttributes()
240
- * @param string $name The attribute name.
241
- * @param mixed $value The value of the attribute.
242
- * @return static
243
- */
244
- public function withAttribute($name, $value);
245
-
246
- /**
247
- * Return an instance that removes the specified derived request attribute.
248
- *
249
- * This method allows removing a single derived request attribute as
250
- * described in getAttributes().
251
- *
252
- * This method MUST be implemented in such a way as to retain the
253
- * immutability of the message, and MUST return an instance that removes
254
- * the attribute.
255
- *
256
- * @see getAttributes()
257
- * @param string $name The attribute name.
258
- * @return static
259
- */
260
- public function withoutAttribute($name);
261
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/psr/http-message/src/StreamInterface.php DELETED
@@ -1,158 +0,0 @@
1
- <?php
2
-
3
- namespace Psr\Http\Message;
4
-
5
- /**
6
- * Describes a data stream.
7
- *
8
- * Typically, an instance will wrap a PHP stream; this interface provides
9
- * a wrapper around the most common operations, including serialization of
10
- * the entire stream to a string.
11
- */
12
- interface StreamInterface
13
- {
14
- /**
15
- * Reads all data from the stream into a string, from the beginning to end.
16
- *
17
- * This method MUST attempt to seek to the beginning of the stream before
18
- * reading data and read the stream until the end is reached.
19
- *
20
- * Warning: This could attempt to load a large amount of data into memory.
21
- *
22
- * This method MUST NOT raise an exception in order to conform with PHP's
23
- * string casting operations.
24
- *
25
- * @see http://php.net/manual/en/language.oop5.magic.php#object.tostring
26
- * @return string
27
- */
28
- public function __toString();
29
-
30
- /**
31
- * Closes the stream and any underlying resources.
32
- *
33
- * @return void
34
- */
35
- public function close();
36
-
37
- /**
38
- * Separates any underlying resources from the stream.
39
- *
40
- * After the stream has been detached, the stream is in an unusable state.
41
- *
42
- * @return resource|null Underlying PHP stream, if any
43
- */
44
- public function detach();
45
-
46
- /**
47
- * Get the size of the stream if known.
48
- *
49
- * @return int|null Returns the size in bytes if known, or null if unknown.
50
- */
51
- public function getSize();
52
-
53
- /**
54
- * Returns the current position of the file read/write pointer
55
- *
56
- * @return int Position of the file pointer
57
- * @throws \RuntimeException on error.
58
- */
59
- public function tell();
60
-
61
- /**
62
- * Returns true if the stream is at the end of the stream.
63
- *
64
- * @return bool
65
- */
66
- public function eof();
67
-
68
- /**
69
- * Returns whether or not the stream is seekable.
70
- *
71
- * @return bool
72
- */
73
- public function isSeekable();
74
-
75
- /**
76
- * Seek to a position in the stream.
77
- *
78
- * @link http://www.php.net/manual/en/function.fseek.php
79
- * @param int $offset Stream offset
80
- * @param int $whence Specifies how the cursor position will be calculated
81
- * based on the seek offset. Valid values are identical to the built-in
82
- * PHP $whence values for `fseek()`. SEEK_SET: Set position equal to
83
- * offset bytes SEEK_CUR: Set position to current location plus offset
84
- * SEEK_END: Set position to end-of-stream plus offset.
85
- * @throws \RuntimeException on failure.
86
- */
87
- public function seek($offset, $whence = SEEK_SET);
88
-
89
- /**
90
- * Seek to the beginning of the stream.
91
- *
92
- * If the stream is not seekable, this method will raise an exception;
93
- * otherwise, it will perform a seek(0).
94
- *
95
- * @see seek()
96
- * @link http://www.php.net/manual/en/function.fseek.php
97
- * @throws \RuntimeException on failure.
98
- */
99
- public function rewind();
100
-
101
- /**
102
- * Returns whether or not the stream is writable.
103
- *
104
- * @return bool
105
- */
106
- public function isWritable();
107
-
108
- /**
109
- * Write data to the stream.
110
- *
111
- * @param string $string The string that is to be written.
112
- * @return int Returns the number of bytes written to the stream.
113
- * @throws \RuntimeException on failure.
114
- */
115
- public function write($string);
116
-
117
- /**
118
- * Returns whether or not the stream is readable.
119
- *
120
- * @return bool
121
- */
122
- public function isReadable();
123
-
124
- /**
125
- * Read data from the stream.
126
- *
127
- * @param int $length Read up to $length bytes from the object and return
128
- * them. Fewer than $length bytes may be returned if underlying stream
129
- * call returns fewer bytes.
130
- * @return string Returns the data read from the stream, or an empty string
131
- * if no bytes are available.
132
- * @throws \RuntimeException if an error occurs.
133
- */
134
- public function read($length);
135
-
136
- /**
137
- * Returns the remaining contents in a string
138
- *
139
- * @return string
140
- * @throws \RuntimeException if unable to read or an error occurs while
141
- * reading.
142
- */
143
- public function getContents();
144
-
145
- /**
146
- * Get stream metadata as an associative array or retrieve a specific key.
147
- *
148
- * The keys returned are identical to the keys returned from PHP's
149
- * stream_get_meta_data() function.
150
- *
151
- * @link http://php.net/manual/en/function.stream-get-meta-data.php
152
- * @param string $key Specific metadata to retrieve.
153
- * @return array|mixed|null Returns an associative array if no key is
154
- * provided. Returns a specific key value if a key is provided and the
155
- * value is found, or null if the key is not found.
156
- */
157
- public function getMetadata($key = null);
158
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/psr/http-message/src/UploadedFileInterface.php DELETED
@@ -1,123 +0,0 @@
1
- <?php
2
-
3
- namespace Psr\Http\Message;
4
-
5
- /**
6
- * Value object representing a file uploaded through an HTTP request.
7
- *
8
- * Instances of this interface are considered immutable; all methods that
9
- * might change state MUST be implemented such that they retain the internal
10
- * state of the current instance and return an instance that contains the
11
- * changed state.
12
- */
13
- interface UploadedFileInterface
14
- {
15
- /**
16
- * Retrieve a stream representing the uploaded file.
17
- *
18
- * This method MUST return a StreamInterface instance, representing the
19
- * uploaded file. The purpose of this method is to allow utilizing native PHP
20
- * stream functionality to manipulate the file upload, such as
21
- * stream_copy_to_stream() (though the result will need to be decorated in a
22
- * native PHP stream wrapper to work with such functions).
23
- *
24
- * If the moveTo() method has been called previously, this method MUST raise
25
- * an exception.
26
- *
27
- * @return StreamInterface Stream representation of the uploaded file.
28
- * @throws \RuntimeException in cases when no stream is available or can be
29
- * created.
30
- */
31
- public function getStream();
32
-
33
- /**
34
- * Move the uploaded file to a new location.
35
- *
36
- * Use this method as an alternative to move_uploaded_file(). This method is
37
- * guaranteed to work in both SAPI and non-SAPI environments.
38
- * Implementations must determine which environment they are in, and use the
39
- * appropriate method (move_uploaded_file(), rename(), or a stream
40
- * operation) to perform the operation.
41
- *
42
- * $targetPath may be an absolute path, or a relative path. If it is a
43
- * relative path, resolution should be the same as used by PHP's rename()
44
- * function.
45
- *
46
- * The original file or stream MUST be removed on completion.
47
- *
48
- * If this method is called more than once, any subsequent calls MUST raise
49
- * an exception.
50
- *
51
- * When used in an SAPI environment where $_FILES is populated, when writing
52
- * files via moveTo(), is_uploaded_file() and move_uploaded_file() SHOULD be
53
- * used to ensure permissions and upload status are verified correctly.
54
- *
55
- * If you wish to move to a stream, use getStream(), as SAPI operations
56
- * cannot guarantee writing to stream destinations.
57
- *
58
- * @see http://php.net/is_uploaded_file
59
- * @see http://php.net/move_uploaded_file
60
- * @param string $targetPath Path to which to move the uploaded file.
61
- * @throws \InvalidArgumentException if the $targetPath specified is invalid.
62
- * @throws \RuntimeException on any error during the move operation, or on
63
- * the second or subsequent call to the method.
64
- */
65
- public function moveTo($targetPath);
66
-
67
- /**
68
- * Retrieve the file size.
69
- *
70
- * Implementations SHOULD return the value stored in the "size" key of
71
- * the file in the $_FILES array if available, as PHP calculates this based
72
- * on the actual size transmitted.
73
- *
74
- * @return int|null The file size in bytes or null if unknown.
75
- */
76
- public function getSize();
77
-
78
- /**
79
- * Retrieve the error associated with the uploaded file.
80
- *
81
- * The return value MUST be one of PHP's UPLOAD_ERR_XXX constants.
82
- *
83
- * If the file was uploaded successfully, this method MUST return
84
- * UPLOAD_ERR_OK.
85
- *
86
- * Implementations SHOULD return the value stored in the "error" key of
87
- * the file in the $_FILES array.
88
- *
89
- * @see http://php.net/manual/en/features.file-upload.errors.php
90
- * @return int One of PHP's UPLOAD_ERR_XXX constants.
91
- */
92
- public function getError();
93
-
94
- /**
95
- * Retrieve the filename sent by the client.
96
- *
97
- * Do not trust the value returned by this method. A client could send
98
- * a malicious filename with the intention to corrupt or hack your
99
- * application.
100
- *
101
- * Implementations SHOULD return the value stored in the "name" key of
102
- * the file in the $_FILES array.
103
- *
104
- * @return string|null The filename sent by the client or null if none
105
- * was provided.
106
- */
107
- public function getClientFilename();
108
-
109
- /**
110
- * Retrieve the media type sent by the client.
111
- *
112
- * Do not trust the value returned by this method. A client could send
113
- * a malicious media type with the intention to corrupt or hack your
114
- * application.
115
- *
116
- * Implementations SHOULD return the value stored in the "type" key of
117
- * the file in the $_FILES array.
118
- *
119
- * @return string|null The media type sent by the client or null if none
120
- * was provided.
121
- */
122
- public function getClientMediaType();
123
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/psr/http-message/src/UriInterface.php DELETED
@@ -1,323 +0,0 @@
1
- <?php
2
- namespace Psr\Http\Message;
3
-
4
- /**
5
- * Value object representing a URI.
6
- *
7
- * This interface is meant to represent URIs according to RFC 3986 and to
8
- * provide methods for most common operations. Additional functionality for
9
- * working with URIs can be provided on top of the interface or externally.
10
- * Its primary use is for HTTP requests, but may also be used in other
11
- * contexts.
12
- *
13
- * Instances of this interface are considered immutable; all methods that
14
- * might change state MUST be implemented such that they retain the internal
15
- * state of the current instance and return an instance that contains the
16
- * changed state.
17
- *
18
- * Typically the Host header will be also be present in the request message.
19
- * For server-side requests, the scheme will typically be discoverable in the
20
- * server parameters.
21
- *
22
- * @link http://tools.ietf.org/html/rfc3986 (the URI specification)
23
- */
24
- interface UriInterface
25
- {
26
- /**
27
- * Retrieve the scheme component of the URI.
28
- *
29
- * If no scheme is present, this method MUST return an empty string.
30
- *
31
- * The value returned MUST be normalized to lowercase, per RFC 3986
32
- * Section 3.1.
33
- *
34
- * The trailing ":" character is not part of the scheme and MUST NOT be
35
- * added.
36
- *
37
- * @see https://tools.ietf.org/html/rfc3986#section-3.1
38
- * @return string The URI scheme.
39
- */
40
- public function getScheme();
41
-
42
- /**
43
- * Retrieve the authority component of the URI.
44
- *
45
- * If no authority information is present, this method MUST return an empty
46
- * string.
47
- *
48
- * The authority syntax of the URI is:
49
- *
50
- * <pre>
51
- * [user-info@]host[:port]
52
- * </pre>
53
- *
54
- * If the port component is not set or is the standard port for the current
55
- * scheme, it SHOULD NOT be included.
56
- *
57
- * @see https://tools.ietf.org/html/rfc3986#section-3.2
58
- * @return string The URI authority, in "[user-info@]host[:port]" format.
59
- */
60
- public function getAuthority();
61
-
62
- /**
63
- * Retrieve the user information component of the URI.
64
- *
65
- * If no user information is present, this method MUST return an empty
66
- * string.
67
- *
68
- * If a user is present in the URI, this will return that value;
69
- * additionally, if the password is also present, it will be appended to the
70
- * user value, with a colon (":") separating the values.
71
- *
72
- * The trailing "@" character is not part of the user information and MUST
73
- * NOT be added.
74
- *
75
- * @return string The URI user information, in "username[:password]" format.
76
- */
77
- public function getUserInfo();
78
-
79
- /**
80
- * Retrieve the host component of the URI.
81
- *
82
- * If no host is present, this method MUST return an empty string.
83
- *
84
- * The value returned MUST be normalized to lowercase, per RFC 3986
85
- * Section 3.2.2.
86
- *
87
- * @see http://tools.ietf.org/html/rfc3986#section-3.2.2
88
- * @return string The URI host.
89
- */
90
- public function getHost();
91
-
92
- /**
93
- * Retrieve the port component of the URI.
94
- *
95
- * If a port is present, and it is non-standard for the current scheme,
96
- * this method MUST return it as an integer. If the port is the standard port
97
- * used with the current scheme, this method SHOULD return null.
98
- *
99
- * If no port is present, and no scheme is present, this method MUST return
100
- * a null value.
101
- *
102
- * If no port is present, but a scheme is present, this method MAY return
103
- * the standard port for that scheme, but SHOULD return null.
104
- *
105
- * @return null|int The URI port.
106
- */
107
- public function getPort();
108
-
109
- /**
110
- * Retrieve the path component of the URI.
111
- *
112
- * The path can either be empty or absolute (starting with a slash) or
113
- * rootless (not starting with a slash). Implementations MUST support all
114
- * three syntaxes.
115
- *
116
- * Normally, the empty path "" and absolute path "/" are considered equal as
117
- * defined in RFC 7230 Section 2.7.3. But this method MUST NOT automatically
118
- * do this normalization because in contexts with a trimmed base path, e.g.
119
- * the front controller, this difference becomes significant. It's the task
120
- * of the user to handle both "" and "/".
121
- *
122
- * The value returned MUST be percent-encoded, but MUST NOT double-encode
123
- * any characters. To determine what characters to encode, please refer to
124
- * RFC 3986, Sections 2 and 3.3.
125
- *
126
- * As an example, if the value should include a slash ("/") not intended as
127
- * delimiter between path segments, that value MUST be passed in encoded
128
- * form (e.g., "%2F") to the instance.
129
- *
130
- * @see https://tools.ietf.org/html/rfc3986#section-2
131
- * @see https://tools.ietf.org/html/rfc3986#section-3.3
132
- * @return string The URI path.
133
- */
134
- public function getPath();
135
-
136
- /**
137
- * Retrieve the query string of the URI.
138
- *
139
- * If no query string is present, this method MUST return an empty string.
140
- *
141
- * The leading "?" character is not part of the query and MUST NOT be
142
- * added.
143
- *
144
- * The value returned MUST be percent-encoded, but MUST NOT double-encode
145
- * any characters. To determine what characters to encode, please refer to
146
- * RFC 3986, Sections 2 and 3.4.
147
- *
148
- * As an example, if a value in a key/value pair of the query string should
149
- * include an ampersand ("&") not intended as a delimiter between values,
150
- * that value MUST be passed in encoded form (e.g., "%26") to the instance.
151
- *
152
- * @see https://tools.ietf.org/html/rfc3986#section-2
153
- * @see https://tools.ietf.org/html/rfc3986#section-3.4
154
- * @return string The URI query string.
155
- */
156
- public function getQuery();
157
-
158
- /**
159
- * Retrieve the fragment component of the URI.
160
- *
161
- * If no fragment is present, this method MUST return an empty string.
162
- *
163
- * The leading "#" character is not part of the fragment and MUST NOT be
164
- * added.
165
- *
166
- * The value returned MUST be percent-encoded, but MUST NOT double-encode
167
- * any characters. To determine what characters to encode, please refer to
168
- * RFC 3986, Sections 2 and 3.5.
169
- *
170
- * @see https://tools.ietf.org/html/rfc3986#section-2
171
- * @see https://tools.ietf.org/html/rfc3986#section-3.5
172
- * @return string The URI fragment.
173
- */
174
- public function getFragment();
175
-
176
- /**
177
- * Return an instance with the specified scheme.
178
- *
179
- * This method MUST retain the state of the current instance, and return
180
- * an instance that contains the specified scheme.
181
- *
182
- * Implementations MUST support the schemes "http" and "https" case
183
- * insensitively, and MAY accommodate other schemes if required.
184
- *
185
- * An empty scheme is equivalent to removing the scheme.
186
- *
187
- * @param string $scheme The scheme to use with the new instance.
188
- * @return static A new instance with the specified scheme.
189
- * @throws \InvalidArgumentException for invalid or unsupported schemes.
190
- */
191
- public function withScheme($scheme);
192
-
193
- /**
194
- * Return an instance with the specified user information.
195
- *
196
- * This method MUST retain the state of the current instance, and return
197
- * an instance that contains the specified user information.
198
- *
199
- * Password is optional, but the user information MUST include the
200
- * user; an empty string for the user is equivalent to removing user
201
- * information.
202
- *
203
- * @param string $user The user name to use for authority.
204
- * @param null|string $password The password associated with $user.
205
- * @return static A new instance with the specified user information.
206
- */
207
- public function withUserInfo($user, $password = null);
208
-
209
- /**
210
- * Return an instance with the specified host.
211
- *
212
- * This method MUST retain the state of the current instance, and return
213
- * an instance that contains the specified host.
214
- *
215
- * An empty host value is equivalent to removing the host.
216
- *
217
- * @param string $host The hostname to use with the new instance.
218
- * @return static A new instance with the specified host.
219
- * @throws \InvalidArgumentException for invalid hostnames.
220
- */
221
- public function withHost($host);
222
-
223
- /**
224
- * Return an instance with the specified port.
225
- *
226
- * This method MUST retain the state of the current instance, and return
227
- * an instance that contains the specified port.
228
- *
229
- * Implementations MUST raise an exception for ports outside the
230
- * established TCP and UDP port ranges.
231
- *
232
- * A null value provided for the port is equivalent to removing the port
233
- * information.
234
- *
235
- * @param null|int $port The port to use with the new instance; a null value
236
- * removes the port information.
237
- * @return static A new instance with the specified port.
238
- * @throws \InvalidArgumentException for invalid ports.
239
- */
240
- public function withPort($port);
241
-
242
- /**
243
- * Return an instance with the specified path.
244
- *
245
- * This method MUST retain the state of the current instance, and return
246
- * an instance that contains the specified path.
247
- *
248
- * The path can either be empty or absolute (starting with a slash) or
249
- * rootless (not starting with a slash). Implementations MUST support all
250
- * three syntaxes.
251
- *
252
- * If the path is intended to be domain-relative rather than path relative then
253
- * it must begin with a slash ("/"). Paths not starting with a slash ("/")
254
- * are assumed to be relative to some base path known to the application or
255
- * consumer.
256
- *
257
- * Users can provide both encoded and decoded path characters.
258
- * Implementations ensure the correct encoding as outlined in getPath().
259
- *
260
- * @param string $path The path to use with the new instance.
261
- * @return static A new instance with the specified path.
262
- * @throws \InvalidArgumentException for invalid paths.
263
- */
264
- public function withPath($path);
265
-
266
- /**
267
- * Return an instance with the specified query string.
268
- *
269
- * This method MUST retain the state of the current instance, and return
270
- * an instance that contains the specified query string.
271
- *
272
- * Users can provide both encoded and decoded query characters.
273
- * Implementations ensure the correct encoding as outlined in getQuery().
274
- *
275
- * An empty query string value is equivalent to removing the query string.
276
- *
277
- * @param string $query The query string to use with the new instance.
278
- * @return static A new instance with the specified query string.
279
- * @throws \InvalidArgumentException for invalid query strings.
280
- */
281
- public function withQuery($query);
282
-
283
- /**
284
- * Return an instance with the specified URI fragment.
285
- *
286
- * This method MUST retain the state of the current instance, and return
287
- * an instance that contains the specified URI fragment.
288
- *
289
- * Users can provide both encoded and decoded fragment characters.
290
- * Implementations ensure the correct encoding as outlined in getFragment().
291
- *
292
- * An empty fragment value is equivalent to removing the fragment.
293
- *
294
- * @param string $fragment The fragment to use with the new instance.
295
- * @return static A new instance with the specified fragment.
296
- */
297
- public function withFragment($fragment);
298
-
299
- /**
300
- * Return the string representation as a URI reference.
301
- *
302
- * Depending on which components of the URI are present, the resulting
303
- * string is either a full URI or relative reference according to RFC 3986,
304
- * Section 4.1. The method concatenates the various components of the URI,
305
- * using the appropriate delimiters:
306
- *
307
- * - If a scheme is present, it MUST be suffixed by ":".
308
- * - If an authority is present, it MUST be prefixed by "//".
309
- * - The path can be concatenated without delimiters. But there are two
310
- * cases where the path has to be adjusted to make the URI reference
311
- * valid as PHP does not allow to throw an exception in __toString():
312
- * - If the path is rootless and an authority is present, the path MUST
313
- * be prefixed by "/".
314
- * - If the path is starting with more than one "/" and no authority is
315
- * present, the starting slashes MUST be reduced to one.
316
- * - If a query is present, it MUST be prefixed by "?".
317
- * - If a fragment is present, it MUST be prefixed by "#".
318
- *
319
- * @see http://tools.ietf.org/html/rfc3986#section-4.1
320
- * @return string
321
- */
322
- public function __toString();
323
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/ralouphie/getallheaders/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- The MIT License (MIT)
2
-
3
- Copyright (c) 2014 Ralph Khattar
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/ralouphie/getallheaders/README.md DELETED
@@ -1,19 +0,0 @@
1
- getallheaders
2
- =============
3
-
4
- PHP `getallheaders()` polyfill. Compatible with PHP >= 5.3.
5
-
6
- [![Build Status](https://travis-ci.org/ralouphie/getallheaders.svg?branch=master)](https://travis-ci.org/ralouphie/getallheaders)
7
- [![Coverage Status](https://coveralls.io/repos/ralouphie/getallheaders/badge.png?branch=master)](https://coveralls.io/r/ralouphie/getallheaders?branch=master)
8
- [![Latest Stable Version](https://poser.pugx.org/ralouphie/getallheaders/v/stable.png)](https://packagist.org/packages/ralouphie/getallheaders)
9
- [![Latest Unstable Version](https://poser.pugx.org/ralouphie/getallheaders/v/unstable.png)](https://packagist.org/packages/ralouphie/getallheaders)
10
- [![License](https://poser.pugx.org/ralouphie/getallheaders/license.png)](https://packagist.org/packages/ralouphie/getallheaders)
11
-
12
-
13
- This is a simple polyfill for [`getallheaders()`](http://www.php.net/manual/en/function.getallheaders.php).
14
-
15
- ## Install
16
-
17
- ```
18
- composer require ralouphie/getallheaders
19
- ```
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/ralouphie/getallheaders/src/getallheaders.php DELETED
@@ -1,46 +0,0 @@
1
- <?php
2
-
3
- if (!function_exists('getallheaders')) {
4
-
5
- /**
6
- * Get all HTTP header key/values as an associative array for the current request.
7
- *
8
- * @return string[string] The HTTP header key/value pairs.
9
- */
10
- function getallheaders()
11
- {
12
- $headers = array();
13
-
14
- $copy_server = array(
15
- 'CONTENT_TYPE' => 'Content-Type',
16
- 'CONTENT_LENGTH' => 'Content-Length',
17
- 'CONTENT_MD5' => 'Content-Md5',
18
- );
19
-
20
- foreach ($_SERVER as $key => $value) {
21
- if (substr($key, 0, 5) === 'HTTP_') {
22
- $key = substr($key, 5);
23
- if (!isset($copy_server[$key]) || !isset($_SERVER[$key])) {
24
- $key = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', $key))));
25
- $headers[$key] = $value;
26
- }
27
- } elseif (isset($copy_server[$key])) {
28
- $headers[$copy_server[$key]] = $value;
29
- }
30
- }
31
-
32
- if (!isset($headers['Authorization'])) {
33
- if (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) {
34
- $headers['Authorization'] = $_SERVER['REDIRECT_HTTP_AUTHORIZATION'];
35
- } elseif (isset($_SERVER['PHP_AUTH_USER'])) {
36
- $basic_pass = isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : '';
37
- $headers['Authorization'] = 'Basic ' . base64_encode($_SERVER['PHP_AUTH_USER'] . ':' . $basic_pass);
38
- } elseif (isset($_SERVER['PHP_AUTH_DIGEST'])) {
39
- $headers['Authorization'] = $_SERVER['PHP_AUTH_DIGEST'];
40
- }
41
- }
42
-
43
- return $headers;
44
- }
45
-
46
- }