PageRenderTime 52ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/tests/phpunit/tests/http/base.php

https://gitlab.com/morganestes/wordpress-develop
PHP | 440 lines | 266 code | 66 blank | 108 comment | 15 complexity | 4edcb3c1072dc8c3085b95e765d158aa MD5 | raw file
  1. <?php
  2. /**
  3. * Note, When running these tests, remember that some things are done differently
  4. * based on safe_mode. You can run the test in safe_mode like such:
  5. *
  6. * phpunit -d safe_mode=on --group http
  7. *
  8. * You may also need `-d safe_mode_gid=1` to relax the safe_mode checks to allow
  9. * inclusion of PEAR.
  10. *
  11. * The WP_HTTP tests require a class-http.php file of r17550 or later.
  12. */
  13. abstract class WP_HTTP_UnitTestCase extends WP_UnitTestCase {
  14. // You can use your own version of data/WPHTTP-testcase-redirection-script.php here.
  15. var $redirection_script = 'http://api.wordpress.org/core/tests/1.0/redirection.php';
  16. var $fileStreamUrl = 'http://s.w.org/screenshots/3.9/dashboard.png';
  17. protected $http_request_args;
  18. /**
  19. * Mark test as skipped if the HTTP request times out
  20. */
  21. function skipTestOnTimeout( $response ) {
  22. if ( ! is_wp_error( $response ) ) {
  23. return;
  24. }
  25. if ( 'connect() timed out!' === $response->get_error_message() ) {
  26. $this->markTestSkipped( 'HTTP timeout' );
  27. }
  28. if ( 0 === strpos( $response->get_error_message(), 'Operation timed out after' ) ) {
  29. $this->markTestSkipped( 'HTTP timeout' );
  30. }
  31. if ( 0 === strpos( $response->get_error_message(), 'stream_socket_client(): unable to connect to tcp://s.w.org:80' ) ) {
  32. $this->markTestSkipped( 'HTTP timeout' );
  33. }
  34. }
  35. function setUp() {
  36. if ( is_callable( array( 'WP_Http', '_getTransport' ) ) ) {
  37. $this->markTestSkipped( 'The WP_Http tests require a class-http.php file of r17550 or later.' );
  38. return;
  39. }
  40. $class = 'WP_Http_' . ucfirst( $this->transport );
  41. if ( ! call_user_func( array( $class, 'test' ) ) ) {
  42. $this->markTestSkipped( sprintf( 'The transport %s is not supported on this system', $this->transport ) );
  43. }
  44. // Disable all transports aside from this one.
  45. foreach ( array( 'curl', 'streams', 'fsockopen' ) as $t ) {
  46. remove_filter( "use_{$t}_transport", '__return_false' ); // Just strip them all
  47. if ( $t != $this->transport ) {
  48. add_filter( "use_{$t}_transport", '__return_false' ); // and add it back if need be..
  49. }
  50. }
  51. }
  52. function tearDown() {
  53. foreach ( array( 'curl', 'streams', 'fsockopen' ) as $t ) {
  54. remove_filter( "use_{$t}_transport", '__return_false' );
  55. }
  56. parent::tearDown();
  57. }
  58. function filter_http_request_args( array $args ) {
  59. $this->http_request_args = $args;
  60. return $args;
  61. }
  62. function test_redirect_on_301() {
  63. // 5 : 5 & 301
  64. $res = wp_remote_request( $this->redirection_script . '?code=301&rt=' . 5, array( 'redirection' => 5 ) );
  65. $this->assertNotWPError( $res );
  66. $this->assertEquals( 200, (int) $res['response']['code'] );
  67. }
  68. function test_redirect_on_302() {
  69. // 5 : 5 & 302
  70. $res = wp_remote_request( $this->redirection_script . '?code=302&rt=' . 5, array( 'redirection' => 5 ) );
  71. $this->assertNotWPError( $res );
  72. $this->assertEquals( 200, (int) $res['response']['code'] );
  73. }
  74. /**
  75. * @ticket 16855
  76. */
  77. function test_redirect_on_301_no_redirect() {
  78. // 5 > 0 & 301
  79. $res = wp_remote_request( $this->redirection_script . '?code=301&rt=' . 5, array( 'redirection' => 0 ) );
  80. $this->assertNotWPError( $res );
  81. $this->assertEquals( 301, (int) $res['response']['code'] );
  82. }
  83. /**
  84. * @ticket 16855
  85. */
  86. function test_redirect_on_302_no_redirect() {
  87. // 5 > 0 & 302
  88. $res = wp_remote_request( $this->redirection_script . '?code=302&rt=' . 5, array( 'redirection' => 0 ) );
  89. $this->assertNotWPError( $res );
  90. $this->assertEquals( 302, (int) $res['response']['code'] );
  91. }
  92. function test_redirections_equal() {
  93. // 5 - 5
  94. $res = wp_remote_request( $this->redirection_script . '?rt=' . 5, array( 'redirection' => 5 ) );
  95. $this->assertNotWPError( $res );
  96. $this->assertEquals( 200, (int) $res['response']['code'] );
  97. }
  98. function test_no_head_redirections() {
  99. // No redirections on HEAD request:
  100. $res = wp_remote_request( $this->redirection_script . '?code=302&rt=' . 1, array( 'method' => 'HEAD' ) );
  101. $this->assertNotWPError( $res );
  102. $this->assertEquals( 302, (int) $res['response']['code'] );
  103. }
  104. /**
  105. * @ticket 16855
  106. */
  107. function test_redirect_on_head() {
  108. // Redirections on HEAD request when Requested
  109. $res = wp_remote_request(
  110. $this->redirection_script . '?rt=' . 5, array(
  111. 'redirection' => 5,
  112. 'method' => 'HEAD',
  113. )
  114. );
  115. $this->assertNotWPError( $res );
  116. $this->assertEquals( 200, (int) $res['response']['code'] );
  117. }
  118. function test_redirections_greater() {
  119. // 10 > 5
  120. $res = wp_remote_request( $this->redirection_script . '?rt=' . 10, array( 'redirection' => 5 ) );
  121. $this->assertWPError( $res );
  122. }
  123. function test_redirections_greater_edgecase() {
  124. // 6 > 5 (close edgecase)
  125. $res = wp_remote_request( $this->redirection_script . '?rt=' . 6, array( 'redirection' => 5 ) );
  126. $this->assertWPError( $res );
  127. }
  128. function test_redirections_less_edgecase() {
  129. // 4 < 5 (close edgecase)
  130. $res = wp_remote_request( $this->redirection_script . '?rt=' . 4, array( 'redirection' => 5 ) );
  131. $this->assertNotWPError( $res );
  132. }
  133. /**
  134. * @ticket 16855
  135. */
  136. function test_redirections_zero_redirections_specified() {
  137. // 0 redirections asked for, Should return the document?
  138. $res = wp_remote_request( $this->redirection_script . '?code=302&rt=' . 5, array( 'redirection' => 0 ) );
  139. $this->assertNotWPError( $res );
  140. $this->assertEquals( 302, (int) $res['response']['code'] );
  141. }
  142. /**
  143. * Do not redirect on non 3xx status codes
  144. *
  145. * @ticket 16889
  146. */
  147. function test_location_header_on_201() {
  148. // Prints PASS on initial load, FAIL if the client follows the specified redirection
  149. $res = wp_remote_request( $this->redirection_script . '?201-location=true' );
  150. $this->assertNotWPError( $res );
  151. $this->assertEquals( 'PASS', $res['body'] );
  152. }
  153. /**
  154. * Test handling of PUT requests on redirects
  155. *
  156. * @ticket 16889
  157. */
  158. function test_no_redirection_on_PUT() {
  159. $url = 'http://api.wordpress.org/core/tests/1.0/redirection.php?201-location=1';
  160. // Test 301 - POST to POST
  161. $res = wp_remote_request(
  162. $url, array(
  163. 'method' => 'PUT',
  164. 'timeout' => 30,
  165. )
  166. );
  167. $this->assertEquals( 'PASS', wp_remote_retrieve_body( $res ) );
  168. $this->assertTrue( ! empty( $res['headers']['location'] ) );
  169. }
  170. /**
  171. * @ticket 11888
  172. */
  173. function test_send_headers() {
  174. // Test that the headers sent are recieved by the server
  175. $headers = array(
  176. 'test1' => 'test',
  177. 'test2' => 0,
  178. 'test3' => '',
  179. );
  180. $res = wp_remote_request( $this->redirection_script . '?header-check', array( 'headers' => $headers ) );
  181. $this->assertNotWPError( $res );
  182. $headers = array();
  183. foreach ( explode( "\n", $res['body'] ) as $key => $value ) {
  184. if ( empty( $value ) ) {
  185. continue;
  186. }
  187. $parts = explode( ':', $value, 2 );
  188. unset( $headers[ $key ] );
  189. $headers[ $parts[0] ] = $parts[1];
  190. }
  191. $this->assertTrue( isset( $headers['test1'] ) && 'test' == $headers['test1'] );
  192. $this->assertTrue( isset( $headers['test2'] ) && '0' === $headers['test2'] );
  193. // cURL/HTTP Extension Note: Will never pass, cURL does not pass headers with an empty value.
  194. // Should it be that empty headers with empty values are NOT sent?
  195. //$this->assertTrue( isset($headers['test3']) && '' === $headers['test3'] );
  196. }
  197. function test_file_stream() {
  198. $url = $this->fileStreamUrl;
  199. $size = 153204;
  200. $res = wp_remote_request(
  201. $url, array(
  202. 'stream' => true,
  203. 'timeout' => 30,
  204. )
  205. ); //Auto generate the filename.
  206. // Cleanup before we assert, as it'll return early.
  207. if ( ! is_wp_error( $res ) ) {
  208. $filesize = filesize( $res['filename'] );
  209. unlink( $res['filename'] );
  210. }
  211. $this->skipTestOnTimeout( $res );
  212. $this->assertNotWPError( $res );
  213. $this->assertEquals( '', $res['body'] ); // The body should be empty.
  214. $this->assertEquals( $size, $res['headers']['content-length'] ); // Check the headers are returned (and the size is the same..)
  215. $this->assertEquals( $size, $filesize ); // Check that the file is written to disk correctly without any extra characters
  216. $this->assertStringStartsWith( get_temp_dir(), $res['filename'] ); // Check it's saving within the temp dir
  217. }
  218. /**
  219. * @ticket 26726
  220. */
  221. function test_file_stream_limited_size() {
  222. $url = $this->fileStreamUrl;
  223. $size = 10000;
  224. $res = wp_remote_request(
  225. $url, array(
  226. 'stream' => true,
  227. 'timeout' => 30,
  228. 'limit_response_size' => $size,
  229. )
  230. ); //Auto generate the filename.
  231. // Cleanup before we assert, as it'll return early.
  232. if ( ! is_wp_error( $res ) ) {
  233. $filesize = filesize( $res['filename'] );
  234. unlink( $res['filename'] );
  235. }
  236. $this->skipTestOnTimeout( $res );
  237. $this->assertNotWPError( $res );
  238. $this->assertEquals( $size, $filesize ); // Check that the file is written to disk correctly without any extra characters
  239. }
  240. /**
  241. * Tests Limiting the response size when returning strings
  242. *
  243. * @ticket 31172
  244. */
  245. function test_request_limited_size() {
  246. $url = $this->fileStreamUrl;
  247. $size = 10000;
  248. $res = wp_remote_request(
  249. $url, array(
  250. 'timeout' => 30,
  251. 'limit_response_size' => $size,
  252. )
  253. );
  254. $this->skipTestOnTimeout( $res );
  255. $this->assertNotWPError( $res );
  256. $this->assertEquals( $size, strlen( $res['body'] ) );
  257. }
  258. /**
  259. * Test POST redirection methods
  260. *
  261. * @dataProvider data_post_redirect_to_method_300
  262. *
  263. * @ticket 17588
  264. */
  265. function test_post_redirect_to_method_300( $response_code, $method ) {
  266. $url = 'http://api.wordpress.org/core/tests/1.0/redirection.php?post-redirect-to-method=1';
  267. $res = wp_remote_post( add_query_arg( 'response_code', $response_code, $url ), array( 'timeout' => 30 ) );
  268. $this->assertEquals( $method, wp_remote_retrieve_body( $res ) );
  269. }
  270. public function data_post_redirect_to_method_300() {
  271. return array(
  272. // Test 300 - POST to POST
  273. array(
  274. 300,
  275. 'POST',
  276. ),
  277. // Test 301 - POST to POST
  278. array(
  279. 301,
  280. 'POST',
  281. ),
  282. // Test 302 - POST to GET
  283. array(
  284. 302,
  285. 'GET',
  286. ),
  287. // Test 303 - POST to GET
  288. array(
  289. 303,
  290. 'GET',
  291. ),
  292. );
  293. }
  294. /**
  295. * Test HTTP Requests using an IP url, with a HOST header specified
  296. *
  297. * @ticket 24182
  298. */
  299. function test_ip_url_with_host_header() {
  300. $ip = gethostbyname( 'api.wordpress.org' );
  301. $url = 'http://' . $ip . '/core/tests/1.0/redirection.php?print-pass=1';
  302. $args = array(
  303. 'headers' => array(
  304. 'Host' => 'api.wordpress.org',
  305. ),
  306. 'timeout' => 30,
  307. 'redirection' => 0,
  308. );
  309. $res = wp_remote_get( $url, $args );
  310. $this->assertEquals( 'PASS', wp_remote_retrieve_body( $res ) );
  311. }
  312. /**
  313. * Test HTTP requests where SSL verification is disabled but the CA bundle is still populated
  314. *
  315. * @ticket 33978
  316. */
  317. function test_https_url_without_ssl_verification() {
  318. $url = 'https://wordpress.org/';
  319. $args = array(
  320. 'sslverify' => false,
  321. );
  322. add_filter( 'http_request_args', array( $this, 'filter_http_request_args' ) );
  323. $res = wp_remote_head( $url, $args );
  324. remove_filter( 'http_request_args', array( $this, 'filter_http_request_args' ) );
  325. $this->assertNotEmpty( $this->http_request_args['sslcertificates'] );
  326. $this->assertNotWPError( $res );
  327. }
  328. /**
  329. * Test HTTP Redirects with multiple Location headers specified
  330. *
  331. * @ticket 16890
  332. */
  333. function test_multiple_location_headers() {
  334. $url = 'http://api.wordpress.org/core/tests/1.0/redirection.php?multiple-location-headers=1';
  335. $res = wp_remote_head( $url, array( 'timeout' => 30 ) );
  336. $this->assertInternalType( 'array', wp_remote_retrieve_header( $res, 'location' ) );
  337. $this->assertCount( 2, wp_remote_retrieve_header( $res, 'location' ) );
  338. $res = wp_remote_get( $url, array( 'timeout' => 30 ) );
  339. $this->assertEquals( 'PASS', wp_remote_retrieve_body( $res ) );
  340. }
  341. /**
  342. * Test HTTP Cookie handling
  343. *
  344. * @ticket 21182
  345. */
  346. function test_cookie_handling() {
  347. $url = 'http://api.wordpress.org/core/tests/1.0/redirection.php?cookie-test=1';
  348. $res = wp_remote_get( $url );
  349. $this->assertEquals( 'PASS', wp_remote_retrieve_body( $res ) );
  350. }
  351. /**
  352. * Test if HTTPS support works
  353. *
  354. * @group ssl
  355. * @ticket 25007
  356. */
  357. function test_ssl() {
  358. if ( ! wp_http_supports( array( 'ssl' ) ) ) {
  359. $this->fail( 'This installation of PHP does not support SSL' );
  360. }
  361. $res = wp_remote_get( 'https://wordpress.org/' );
  362. $this->assertNotWPError( $res );
  363. }
  364. /**
  365. * @ticket 37733
  366. */
  367. function test_url_with_double_slashes_path() {
  368. $url = $this->redirection_script . '?rt=' . 0;
  369. $path = parse_url( $url, PHP_URL_PATH );
  370. $url = str_replace( $path, '/' . $path, $url );
  371. $res = wp_remote_request( $url );
  372. $this->assertNotWPError( $res );
  373. }
  374. }