���� JFIF �� � ( %"1"%)+...383,7(-.-
![]() Server : Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips PHP/7.4.20 System : Linux st2.domain.com 3.10.0-1127.10.1.el7.x86_64 #1 SMP Wed Jun 3 14:28:03 UTC 2020 x86_64 User : apache ( 48) PHP Version : 7.4.20 Disable Function : NONE Directory : /var/www/html/vidoe.top/proxy/logs/curl/tests/PHPCurlClass/ |
<?php namespace CurlTest; use \Curl\Curl; use \Curl\CaseInsensitiveArray; use \Helper\Test; class CurlTest extends \PHPUnit\Framework\TestCase { public function testExtensionsLoaded() { $this->assertTrue(extension_loaded('curl')); $this->assertTrue(extension_loaded('gd')); } public function testArrayAssociative() { $this->assertTrue(\Curl\ArrayUtil::is_array_assoc(array( 'foo' => 'wibble', 'bar' => 'wubble', 'baz' => 'wobble', ))); } public function testArrayIndexed() { $this->assertFalse(\Curl\ArrayUtil::is_array_assoc(array( 'wibble', 'wubble', 'wobble', ))); } public function testCaseInsensitiveArrayGet() { $array = new CaseInsensitiveArray(); $this->assertTrue(is_object($array)); $this->assertCount(0, $array); $this->assertNull($array[(string)rand()]); $array['foo'] = 'bar'; $this->assertNotEmpty($array); $this->assertCount(1, $array); } public function testCaseInsensitiveArraySet() { $array = new CaseInsensitiveArray(); foreach (array('FOO', 'FOo', 'Foo', 'fOO', 'fOo', 'foO', 'foo') as $key) { $value = mt_rand(); $array[$key] = $value; $this->assertCount(1, $array); $this->assertEquals($value, $array['FOO']); $this->assertEquals($value, $array['FOo']); $this->assertEquals($value, $array['Foo']); $this->assertEquals($value, $array['fOO']); $this->assertEquals($value, $array['fOo']); $this->assertEquals($value, $array['foO']); $this->assertEquals($value, $array['foo']); } $array['baz'] = 'qux'; $this->assertCount(2, $array); } public function testBuildPostDataArgSeparator() { $data = array( 'foo' => 'Hello', 'bar' => 'World', ); foreach (array(false, '&', '&') as $arg_separator) { if ($arg_separator) { ini_set('arg_separator.output', $arg_separator); } $curl = new Curl(); $this->assertEquals('foo=Hello&bar=World', $curl->buildPostData($data)); } } public function testUserAgent() { $php_version = preg_replace('/([\.\+\?\*\(\)\[\]\^\$\/])/', '\\\\\1', 'PHP/' . PHP_VERSION); $curl_version = curl_version(); $curl_version = 'curl\/' . $curl_version['version']; $test = new Test(); $user_agent = $test->server('server', 'GET', array('key' => 'HTTP_USER_AGENT')); $this->assertRegExp('/' . $php_version . '/', $user_agent); $this->assertRegExp('/' . $curl_version . '/', $user_agent); } public function testGet() { $test = new Test(); $this->assertEquals('GET', $test->server('request_method', 'GET')); } public function testUrl() { $data = array('foo' => 'bar'); // curl -v --get --request GET "http://127.0.0.1:8000/" --data "foo=bar" $test = new Test(); $test->server('server', 'GET', $data); $this->assertEquals(Test::TEST_URL, $test->curl->baseUrl); $this->assertEquals(Test::TEST_URL . '?' . http_build_query($data), $test->curl->url); // curl -v --request POST "http://127.0.0.1:8000/" --data "foo=bar" $test = new Test(); $test->server('server', 'POST', $data); $this->assertEquals(Test::TEST_URL, $test->curl->baseUrl); $this->assertEquals(Test::TEST_URL, $test->curl->url); // curl -v --request PUT "http://127.0.0.1:8000/" --data "foo=bar" $test = new Test(); $test->server('server', 'PUT', $data); $this->assertEquals(Test::TEST_URL, $test->curl->baseUrl); $this->assertEquals(Test::TEST_URL, $test->curl->url); // curl -v --request PATCH "http://127.0.0.1:8000/" --data "foo=bar" $test = new Test(); $test->server('server', 'PATCH', $data); $this->assertEquals(Test::TEST_URL, $test->curl->baseUrl); $this->assertEquals(Test::TEST_URL, $test->curl->url); // curl -v --request DELETE "http://127.0.0.1:8000/?foo=bar" $test = new Test(); $test->server('server', 'DELETE', $data); $this->assertEquals(Test::TEST_URL, $test->curl->baseUrl); $this->assertEquals(Test::TEST_URL . '?' . http_build_query($data), $test->curl->url); // curl -v --get --request HEAD --head "http://127.0.0.1:8000/" --data "foo=bar" $test = new Test(); $test->server('server', 'HEAD', $data); $this->assertEquals(Test::TEST_URL, $test->curl->baseUrl); $this->assertEquals(Test::TEST_URL . '?' . http_build_query($data), $test->curl->url); // curl -v --get --request OPTIONS "http://127.0.0.1:8000/" --data "foo=bar" $test = new Test(); $test->server('server', 'OPTIONS', $data); $this->assertEquals(Test::TEST_URL, $test->curl->baseUrl); $this->assertEquals(Test::TEST_URL . '?' . http_build_query($data), $test->curl->url); } public function testSetUrlInConstructor() { $data = array('key' => 'value'); $curl = new Curl(Test::TEST_URL); $curl->setHeader('X-DEBUG-TEST', 'delete_with_body'); $curl->delete($data, array('wibble' => 'wubble')); $this->assertEquals(Test::TEST_URL, $curl->baseUrl); $this->assertEquals('{"get":{"key":"value"},"delete":{"wibble":"wubble"}}', $curl->rawResponse); $curl = new Curl(Test::TEST_URL); $curl->setHeader('X-DEBUG-TEST', 'get'); $curl->delete($data); $this->assertEquals(Test::TEST_URL, $curl->baseUrl); $this->assertEquals('key=value', $curl->response); $curl = new Curl(Test::TEST_URL); $curl->setHeader('X-DEBUG-TEST', 'get'); $curl->get($data); $this->assertEquals(Test::TEST_URL, $curl->baseUrl); $this->assertEquals('key=value', $curl->response); $curl = new Curl(Test::TEST_URL); $curl->setHeader('X-DEBUG-TEST', 'get'); $curl->head($data); $this->assertEquals(Test::TEST_URL, $curl->baseUrl); $this->assertEquals('HEAD /?key=value HTTP/1.1', $curl->requestHeaders['Request-Line']); $curl = new Curl(Test::TEST_URL); $curl->setHeader('X-DEBUG-TEST', 'get'); $curl->options($data); $this->assertEquals(Test::TEST_URL, $curl->baseUrl); $this->assertEquals('key=value', $curl->response); $curl = new Curl(Test::TEST_URL); $curl->setHeader('X-DEBUG-TEST', 'request_method'); $curl->patch($data); $this->assertEquals(Test::TEST_URL, $curl->baseUrl); $this->assertEquals('PATCH', $curl->response); $curl = new Curl(Test::TEST_URL); $curl->setHeader('X-DEBUG-TEST', 'post'); $curl->post($data); $this->assertEquals(Test::TEST_URL, $curl->baseUrl); $this->assertEquals('key=value', $curl->response); $curl = new Curl(Test::TEST_URL); $curl->setHeader('X-DEBUG-TEST', 'put'); $curl->put($data); $this->assertEquals(Test::TEST_URL, $curl->baseUrl); $this->assertEquals('key=value', $curl->response); } public function testSetUrl() { $data = array('key' => 'value'); $curl = new Curl(); $curl->setUrl(Test::TEST_URL); $curl->delete($data); $this->assertEquals('DELETE /?key=value HTTP/1.1', $curl->requestHeaders['Request-Line']); $this->assertEquals(Test::TEST_URL . '?key=value', $curl->effectiveUrl); $curl = new Curl(); $curl->setUrl(Test::TEST_URL); $curl->get($data); $this->assertEquals('GET /?key=value HTTP/1.1', $curl->requestHeaders['Request-Line']); $this->assertEquals(Test::TEST_URL . '?key=value', $curl->effectiveUrl); $curl = new Curl(); $curl->setUrl(Test::TEST_URL); $curl->head($data); $this->assertEquals('HEAD /?key=value HTTP/1.1', $curl->requestHeaders['Request-Line']); $this->assertEquals(Test::TEST_URL . '?key=value', $curl->effectiveUrl); $curl = new Curl(); $curl->setUrl(Test::TEST_URL); $curl->options($data); $this->assertEquals('OPTIONS /?key=value HTTP/1.1', $curl->requestHeaders['Request-Line']); $this->assertEquals(Test::TEST_URL . '?key=value', $curl->effectiveUrl); $curl = new Curl(); $curl->setUrl(Test::TEST_URL); $curl->patch($data); $this->assertEquals('PATCH / HTTP/1.1', $curl->requestHeaders['Request-Line']); $this->assertEquals(Test::TEST_URL, $curl->effectiveUrl); $curl = new Curl(); $curl->setUrl(Test::TEST_URL); $curl->post($data); $this->assertEquals('POST / HTTP/1.1', $curl->requestHeaders['Request-Line']); $this->assertEquals(Test::TEST_URL, $curl->effectiveUrl); $curl = new Curl(); $curl->setUrl(Test::TEST_URL); $curl->put($data); $this->assertEquals('PUT / HTTP/1.1', $curl->requestHeaders['Request-Line']); $this->assertEquals(Test::TEST_URL, $curl->effectiveUrl); } public function testEffectiveUrl() { $test = new Test(); $test->server('redirect', 'GET'); $this->assertEquals(Test::TEST_URL, $test->curl->effectiveUrl); $test = new Test(); $test->curl->setOpt(CURLOPT_FOLLOWLOCATION, true); $test->server('redirect', 'GET'); $this->assertEquals(Test::TEST_URL . '?redirect', $test->curl->effectiveUrl); } public function testPostRequestMethod() { $test = new Test(); $this->assertEquals('POST', $test->server('request_method', 'POST')); } public function testPostContinueResponseHeader() { // 100 Continue responses may contain additional optional headers per // RFC 2616, Section 10.1: // This class of status code indicates a provisional response, // consisting only of the Status-Line and optional headers, and is // terminated by an empty line. $response = 'HTTP/1.1 100 Continue' . "\r\n" . 'Date: Fri, 01 Jan 1990 00:00:00 GMT' . "\r\n" . 'Server: PHP-Curl-Class' . "\r\n" . "\r\n" . 'HTTP/1.1 200 OK' . "\r\n" . 'Date: Fri, 01 Jan 1990 00:00:00 GMT' . "\r\n" . 'Cache-Control: private' . "\r\n" . 'Vary: Accept-Encoding' . "\r\n" . 'Content-Length: 2' . "\r\n" . 'Content-Type: text/plain;charset=UTF-8' . "\r\n" . 'Server: PHP-Curl-Class' . "\r\n" . 'Connection: keep-alive' . "\r\n" . "\r\n"; $reflector = new \ReflectionClass('\Curl\Curl'); $reflection_method = $reflector->getMethod('parseResponseHeaders'); $reflection_method->setAccessible(true); $curl = new Curl(); $response_headers = $reflection_method->invoke($curl, $response); $this->assertEquals('HTTP/1.1 200 OK', $response_headers['Status-Line']); } public function testPostData() { $test = new Test(); $this->assertEquals('key=value', $test->server('post', 'POST', array( 'key' => 'value', ))); } public function testPostAssociativeArrayData() { $data = array( 'username' => 'myusername', 'password' => 'mypassword', 'more_data' => array( 'param1' => 'something', 'param2' => 'other thing', 'param3' => 123, 'param4' => 3.14, ), ); $test = new Test(); $test->curl->setDefaultJsonDecoder(true); $response = $test->server('post_multidimensional', 'POST', $data); $this->assertEquals($data, $response['post']); } public function testPostContentLength() { $test_data = array( array(false, 0), array('', 0), array(array(), 0), array(null, 0), ); foreach ($test_data as $data) { $test = new Test(); list($post_data, $expected_content_length) = $data; if ($post_data === false) { $test->server('post', 'POST'); } else { $test->server('post', 'POST', $post_data); } $this->assertEquals($expected_content_length, $test->curl->requestHeaders['Content-Length']); } } public function testPostMultidimensionalData() { $data = array( 'key' => 'file', 'file' => array( 'wibble', 'wubble', 'wobble', ), ); $this->assertEquals( 'key=file&file[0]=wibble&file[1]=wubble&file[2]=wobble', urldecode(http_build_query($data)) ); $test = new Test(); $test->curl->setDefaultJsonDecoder(true); $response = $test->server('post_multidimensional', 'POST', $data); $this->assertEquals($data, $response['post']); } public function testPostMultidimensionalDataWithFile() { $tests = array(); $file_path_1 = \Helper\get_png(); $tests[] = array( 'file_path' => $file_path_1, 'post_data_image' => '@' . $file_path_1, ); if (class_exists('CURLFile')) { $file_path_2 = \Helper\get_png(); $tests[] = array( 'file_path' => $file_path_2, 'post_data_image' => new \CURLFile($file_path_2), ); } foreach ($tests as $test_data) { $file_path = $test_data['file_path']; $post_data_image = $test_data['post_data_image']; $test = new Test(); // Return associative for comparison. $assoc = true; $test->curl->setDefaultJsonDecoder($assoc); // Keep POST data separate from FILES data for comparison. $post_data_without_file = array( 'key' => 'value', 'alpha' => array( 'a' => '1', 'b' => '2', 'c' => '3', ), ); $post_data = $post_data_without_file; $post_data['image'] = $post_data_image; $test->server('post_multidimensional_with_file', 'POST', $post_data); // Expect "Content-Type: multipart/form-data" in request headers. preg_match( '/^multipart\/form-data; boundary=/', $test->curl->requestHeaders['Content-Type'], $content_type ); $this->assertTrue(!empty($content_type)); // Expect received POST data to match POSTed data less the file. $this->assertEquals($post_data_without_file, $test->curl->response['post']); // Expect POSTed files is received as $_FILES. $this->assertTrue(isset($test->curl->response['files']['image']['tmp_name'])); $this->assertEquals(0, $test->curl->response['files']['image']['error']); unlink($file_path); $this->assertFalse(file_exists($file_path)); } } public function testPostFilePathUpload() { $file_path = \Helper\get_png(); $test = new Test(); $this->assertEquals('image/png', $test->server('post_file_path_upload', 'POST', array( 'key' => 'image', 'image' => '@' . $file_path, ))); unlink($file_path); $this->assertFalse(file_exists($file_path)); } public function testPostCurlFileUpload() { if (class_exists('CURLFile')) { $file_path = \Helper\get_png(); $test = new Test(); $this->assertEquals('image/png', $test->server('post_file_path_upload', 'POST', array( 'key' => 'image', 'image' => new \CURLFile($file_path), ))); unlink($file_path); $this->assertFalse(file_exists($file_path)); } } public function testPostNonFilePathUpload() { $test = new Test(); $test->server('post', 'POST', array( 'foo' => 'bar', 'file' => '@not-a-file', )); $this->assertFalse($test->curl->error); $this->assertEquals('foo=bar&file=%40not-a-file', $test->curl->response); } public function testPostRedirectGet() { // Follow 303 redirection with GET $test = new Test(); $test->curl->setOpt(CURLOPT_FOLLOWLOCATION, true); $this->assertEquals('Redirected: GET', $test->server('post_redirect_get', 'POST')); // Follow 303 redirection with POST $test = new Test(); $test->curl->setOpt(CURLOPT_FOLLOWLOCATION, true); $this->assertEquals('Redirected: POST', $test->server('post_redirect_get', 'POST', array(), true)); // On compatible PHP engines, ensure that it is possible to reuse an existing Curl object if ((version_compare(PHP_VERSION, '5.5.11') > 0) && !defined('HHVM_VERSION')) { $this->assertEquals('Redirected: GET', $test->server('post_redirect_get', 'POST')); } } public function testPostRedirectGetReuseObjectIncompatibleEngine() { if ((version_compare(PHP_VERSION, '5.5.11') > 0) && !defined('HHVM_VERSION')) { $this->markTestSkipped(); } try { // Follow 303 redirection with POST $test = new Test(); $test->curl->setOpt(CURLOPT_FOLLOWLOCATION, true); $test->server('post_redirect_get', 'POST', array(), true); // On incompatible PHP engines, reusing an existing Curl object to perform a // post-redirect-get request will trigger a PHP error $test->server('post_redirect_get', 'POST'); $this->assertTrue( false, 'Reusing an existing Curl object on incompatible PHP engines shall trigger an error.' ); } catch (\PHPUnit_Framework_Error $e) { $this->assertTrue(true); } } public function testPutRequestMethod() { $test = new Test(); $this->assertEquals('PUT', $test->server('request_method', 'PUT')); } public function testPutData() { $test = new Test(); $this->assertEquals('key=value', $test->server('put', 'PUT', array( 'key' => 'value', ))); $test = new Test(); $this->assertEquals('{"key":"value"}', $test->server('put', 'PUT', json_encode(array( 'key' => 'value', )))); } public function testPutFileHandle() { $png = \Helper\create_png(); $tmp_file = \Helper\create_tmp_file($png); $test = new Test(); $test->curl->setHeader('X-DEBUG-TEST', 'put_file_handle'); $test->curl->setOpt(CURLOPT_PUT, true); $test->curl->setOpt(CURLOPT_INFILE, $tmp_file); $test->curl->setOpt(CURLOPT_INFILESIZE, strlen($png)); $test->curl->put(Test::TEST_URL); fclose($tmp_file); $this->assertEquals('image/png', $test->curl->response); } public function testPatchRequestMethod() { $test = new Test(); $this->assertEquals('PATCH', $test->server('request_method', 'PATCH')); } public function testPatchData() { $test = new Test(); $this->assertEquals('key=value', $test->server('patch', 'PATCH', array( 'key' => 'value', ))); $test = new Test(); $this->assertEquals('{"key":"value"}', $test->server('patch', 'PATCH', json_encode(array( 'key' => 'value', )))); } public function testPatchRequestMethodWithMultidimArray() { $data = array( 'data' => array( 'foo' => 'bar', 'wibble' => 'wubble', ), ); $curl = new Curl(); $curl->setHeader('X-DEBUG-TEST', 'data_values'); $curl->patch(Test::TEST_URL, $data); $this->assertEquals('{"data":{"foo":"bar","wibble":"wubble"}}', $curl->rawResponse); $this->assertEquals(json_decode(json_encode($data), false), $curl->response); } public function testDeleteRequestMethod() { $test = new Test(); $this->assertEquals('DELETE', $test->server('request_method', 'DELETE')); } public function testDeleteRequestBody() { $test = new Test(); $test->server('delete_with_body', 'DELETE', array('foo' => 'bar'), array('wibble' => 'wubble')); $this->assertEquals('{"get":{"foo":"bar"},"delete":{"wibble":"wubble"}}', $test->curl->rawResponse); } public function testHeadRequestMethod() { $test = new Test(); $test->server('request_method', 'HEAD'); $this->assertEquals('HEAD', $test->curl->responseHeaders['X-REQUEST-METHOD']); $this->assertEmpty($test->curl->response); } public function testOptionsRequestMethod() { $test = new Test(); $test->server('request_method', 'OPTIONS'); $this->assertEquals('OPTIONS', $test->curl->responseHeaders['X-REQUEST-METHOD']); } public function testDownload() { // Create and upload a file. $upload_file_path = \Helper\get_png(); $uploaded_file_path = \Helper\upload_file_to_server($upload_file_path); // Download the file. $downloaded_file_path = tempnam('/tmp', 'php-curl-class.'); $download_test = new Test(); $download_test->curl->setHeader('X-DEBUG-TEST', 'download_response'); $this->assertTrue($download_test->curl->download(Test::TEST_URL . '?' . http_build_query(array( 'file_path' => $uploaded_file_path, )), $downloaded_file_path)); $this->assertNotEquals($uploaded_file_path, $downloaded_file_path); $this->assertEquals(filesize($upload_file_path), filesize($downloaded_file_path)); $this->assertEquals(md5_file($upload_file_path), md5_file($downloaded_file_path)); $this->assertEquals(md5_file($upload_file_path), $download_test->curl->responseHeaders['ETag']); // Ensure successive requests set the appropriate values. $this->assertEquals('GET', $download_test->server('request_method', 'GET')); $this->assertFalse(is_bool($download_test->curl->response)); $this->assertFalse(is_bool($download_test->curl->rawResponse)); // Remove server file. \Helper\remove_file_from_server($uploaded_file_path); unlink($upload_file_path); unlink($downloaded_file_path); $this->assertFalse(file_exists($upload_file_path)); $this->assertFalse(file_exists($downloaded_file_path)); } public function testDownloadCallback() { // Create and upload a file. $upload_file_path = \Helper\get_png(); $uploaded_file_path = \Helper\upload_file_to_server($upload_file_path); // Download the file. $callback_called = false; $curl = new Curl(); $curl->setHeader('X-DEBUG-TEST', 'download_response'); $curl->download(Test::TEST_URL . '?' . http_build_query(array( 'file_path' => $uploaded_file_path, )), function ($instance, $fh) use (&$callback_called) { \PHPUnit\Framework\Assert::assertFalse($callback_called); \PHPUnit\Framework\Assert::assertInstanceOf('Curl\Curl', $instance); \PHPUnit\Framework\Assert::assertTrue(is_resource($fh)); \PHPUnit\Framework\Assert::assertEquals('stream', get_resource_type($fh)); \PHPUnit\Framework\Assert::assertGreaterThan(0, strlen(stream_get_contents($fh))); \PHPUnit\Framework\Assert::assertEquals(0, strlen(stream_get_contents($fh))); \PHPUnit\Framework\Assert::assertTrue(fclose($fh)); $callback_called = true; }); $this->assertTrue($callback_called); // Remove server file. \Helper\remove_file_from_server($uploaded_file_path); unlink($upload_file_path); $this->assertFalse(file_exists($upload_file_path)); } public function testDownloadRange() { // Create and upload a file. $filename = \Helper\get_png(); $uploaded_file_path = \Helper\upload_file_to_server($filename); $filesize = filesize($filename); foreach (array( false, 0, 1, 2, 3, 5, 10, 25, 50, $filesize - 3, $filesize - 2, $filesize - 1, // A partial temporary file having the exact same file size as the complete source file should only // occur under certain circumstances (almost never). When the download successfully completed, the // temporary file should have been moved to the download destination save path. However, it is possible // that a larger file download was interrupted after which the source file was updated and now has the // exact same file size as the partial temporary. When resuming the download, the range is now // unsatisfiable as the first byte position exceeds the available range. The entire file should be // downloaded again. $filesize - 0, // A partial temporary file having a larger file size than the complete source file should only occur // under certain circumstances. This is possible when a download was interrupted after which the source // file was updated with a smaller file. When resuming the download, the range is now unsatisfiable as // the first byte position exceeds the the available range. The entire file should be downloaded again. $filesize + 1, $filesize + 2, $filesize + 3, ) as $length) { $source = Test::TEST_URL; $destination = \Helper\get_tmp_file_path(); // Start with no file. if ($length === false) { $this->assertFalse(file_exists($destination)); // Start with $length bytes of file. } else { // Simulate resuming partially downloaded temporary file. $partial_filename = $destination . '.pccdownload'; if ($length === 0) { $partial_content = ''; } else { $file = fopen($filename, 'rb'); $partial_content = fread($file, $length); fclose($file); } // Partial content size should be $length bytes large for testing resume download behavior. if ($length <= $filesize) { $this->assertEquals($length, strlen($partial_content)); // Partial content should not be larger than the original file size. } else { $this->assertEquals($filesize, strlen($partial_content)); } file_put_contents($partial_filename, $partial_content); $this->assertEquals(strlen($partial_content), strlen(file_get_contents($partial_filename))); } // Download (the remaining bytes of) the file. $curl = new Curl(); $curl->setHeader('X-DEBUG-TEST', 'download_file_range'); $curl->download($source . '?' . http_build_query(array( 'file_path' => $uploaded_file_path, )), $destination); clearstatcache(); $expected_bytes_downloaded = $filesize - min($length, $filesize); $bytes_downloaded = $curl->responseHeaders['content-length']; if ($length === false || $length === 0) { $expected_http_status_code = 200; // 200 OK $this->assertEquals($expected_bytes_downloaded, $bytes_downloaded); } elseif ($length >= $filesize) { $expected_http_status_code = 416; // 416 Requested Range Not Satisfiable } else { $expected_http_status_code = 206; // 206 Partial Content $this->assertEquals($expected_bytes_downloaded, $bytes_downloaded); } $this->assertEquals($expected_http_status_code, $curl->httpStatusCode); if (!$curl->error) { $this->assertEquals($filesize, filesize($destination)); unlink($destination); $this->assertFalse(file_exists($destination)); } } // Remove server file. \Helper\remove_file_from_server($uploaded_file_path); unlink($filename); $this->assertFalse(file_exists($filename)); } public function testMaxFilesize() { $tests = array( array( 'bytes' => 1, 'max_filesize' => false, 'expect_error' => false, ), array( 'bytes' => 1, 'max_filesize' => 1, 'expect_error' => false, ), array( 'bytes' => 1, 'max_filesize' => 2, 'expect_error' => false, ), array( 'bytes' => 1, 'max_filesize' => 0, 'expect_error' => true, ), array( 'bytes' => 2, 'max_filesize' => false, 'expect_error' => false, ), array( 'bytes' => 2, 'max_filesize' => 2, 'expect_error' => false, ), array( 'bytes' => 2, 'max_filesize' => 3, 'expect_error' => false, ), array( 'bytes' => 2, 'max_filesize' => 1, 'expect_error' => true, ), array( 'bytes' => 1000, 'max_filesize' => false, 'expect_error' => false, ), array( 'bytes' => 1000, 'max_filesize' => 1000, 'expect_error' => false, ), array( 'bytes' => 1000, 'max_filesize' => 1001, 'expect_error' => false, ), array( 'bytes' => 1000, 'max_filesize' => 999, 'expect_error' => true, ), array( 'bytes' => 1000, 'max_filesize' => 0, 'expect_error' => true, ), ); foreach ($tests as $test) { $bytes = $test['bytes']; $max_filesize = $test['max_filesize']; $expect_error = $test['expect_error']; $test = new Test(); if (!($max_filesize === false)) { $test->curl->setMaxFilesize($max_filesize); } $test->server('download_file_size', 'GET', array( 'bytes' => $bytes, )); // Ensure exceeding download limit aborts the transfer and sets a CURLE_ABORTED_BY_CALLBACK error. if ($expect_error) { $this->assertTrue($test->curl->error); $this->assertEquals(CURLE_ABORTED_BY_CALLBACK, $test->curl->errorCode); } else { $str = str_repeat('.', $bytes); $this->assertEquals(md5($str), $test->curl->responseHeaders['etag']); $this->assertEquals($str, $test->curl->response); } } } public function testBasicHttpAuth() { $test = new Test(); $this->assertEquals('canceled', $test->server('http_basic_auth', 'GET')); $username = 'myusername'; $password = 'mypassword'; $test = new Test(); $test->curl->setBasicAuthentication($username, $password); $test->server('http_basic_auth', 'GET'); $json = $test->curl->response; $this->assertEquals($username, $json->username); $this->assertEquals($password, $json->password); } public function testDigestHttpAuth() { // Skip Digest Access Authentication test on HHVM. // https://github.com/facebook/hhvm/issues/5201 if (defined('HHVM_VERSION')) { $this->markTestSkipped(); } $username = 'myusername'; $password = 'mypassword'; $invalid_password = 'anotherpassword'; $test = new Test(); $test->server('http_digest_auth', 'GET'); $this->assertEquals('canceled', $test->curl->response); $this->assertEquals(401, $test->curl->httpStatusCode); $test = new Test(); $test->curl->setDigestAuthentication($username, $invalid_password); $test->server('http_digest_auth', 'GET'); $this->assertEquals('invalid', $test->curl->response); $this->assertEquals(401, $test->curl->httpStatusCode); $test = new Test(); $test->curl->setDigestAuthentication($username, $password); $test->server('http_digest_auth', 'GET'); $this->assertEquals('valid', $test->curl->response); $this->assertEquals(200, $test->curl->httpStatusCode); } public function testReferrer() { $test = new Test(); $test->curl->setReferrer('myreferrer'); $this->assertEquals('myreferrer', $test->server('server', 'GET', array( 'key' => 'HTTP_REFERER', ))); $test = new Test(); $test->curl->setReferer('myreferer'); $this->assertEquals('myreferer', $test->server('server', 'GET', array( 'key' => 'HTTP_REFERER', ))); } public function testResponseBody() { foreach (array( 'GET' => 'OK', 'POST' => 'OK', 'PUT' => 'OK', 'PATCH' => 'OK', 'DELETE' => 'OK', 'HEAD' => '', 'OPTIONS' => 'OK', ) as $request_method => $expected_response) { $curl = new Curl(); $curl->setHeader('X-DEBUG-TEST', 'response_body'); $this->assertEquals($expected_response, $curl->$request_method(Test::TEST_URL)); } } public function testSetCookie() { $test = new Test(); $test->curl->setCookie('mycookie', 'yum'); $test->server('setcookie', 'GET'); $this->assertEquals('yum', $test->curl->responseCookies['mycookie']); } public function testSetCookies() { $cookies = array( 'mycookie' => 'yum', 'fruit' => 'apple', 'color' => 'red', ); $test = new Test(); $test->curl->setCookies($cookies); $test->server('setcookie', 'GET'); $this->assertEquals('yum', $test->curl->responseCookies['mycookie']); $this->assertEquals('apple', $test->curl->responseCookies['fruit']); $this->assertEquals('red', $test->curl->responseCookies['color']); } public function testSetCookieEncodingSpace() { $curl = new Curl(); $curl->setCookie('cookie', 'Om nom nom nom'); $this->assertEquals('cookie=Om%20nom%20nom%20nom', $curl->getOpt(CURLOPT_COOKIE)); } public function testSetMultipleCookies() { $curl = new Curl(); $curl->setCookie('cookie', 'Om nom nom nom'); $curl->setCookie('foo', 'bar'); $this->assertEquals('cookie=Om%20nom%20nom%20nom; foo=bar', $curl->getOpt(CURLOPT_COOKIE)); } public function testSetCookieEncodingColon() { $curl = new Curl(); $curl->setCookie('JSESSIONID', '0000wd-PcsB3bZ-KzYGAqm_rKlm:17925chrl'); $this->assertEquals('JSESSIONID=0000wd-PcsB3bZ-KzYGAqm_rKlm:17925chrl', $curl->getOpt(CURLOPT_COOKIE)); } public function testSetCookieString() { $cookie_string = 'fruit=apple; color=red'; $test = new Test(); $test->curl->setCookieString($cookie_string); $this->assertEquals($cookie_string, $test->curl->getOpt(CURLOPT_COOKIE)); $this->assertEquals('fruit=apple&color=red', $test->server('cookie', 'GET')); } public function testCookieFile() { $cookie_file = dirname(__FILE__) . '/cookiefile.txt'; $cookie_data = implode("\t", array( '127.0.0.1', // domain 'FALSE', // tailmatch '/', // path 'FALSE', // secure '0', // expires 'mycookie', // name 'yum', // value )) . "\n"; file_put_contents($cookie_file, $cookie_data); $test = new Test(); $test->curl->setCookieFile($cookie_file); $this->assertEquals($cookie_data, file_get_contents($test->curl->getOpt(CURLOPT_COOKIEFILE))); $this->assertEquals('yum', $test->server('cookie', 'GET', array( 'key' => 'mycookie', ))); unlink($cookie_file); $this->assertFalse(file_exists($cookie_file)); } public function testCookieJar() { $cookie_jar = dirname(__FILE__) . '/cookiejar.txt'; $test = new Test(); $test->curl->setCookieJar($cookie_jar); $test->server('cookiejar', 'GET'); $test->curl->close(); $this->assertTrue(!(strpos(file_get_contents($cookie_jar), "\t" . 'mycookie' . "\t" . 'yum') === false)); unlink($cookie_jar); $this->assertFalse(file_exists($cookie_jar)); } public function testMultipleCookieResponse() { $test = new Test(); $test->server('multiple_cookie', 'GET'); $this->assertEquals('cookie1=scrumptious,cookie2=mouthwatering', $test->curl->responseHeaders['Set-Cookie']); $this->assertEquals('scrumptious', $test->curl->responseCookies['cookie1']); $this->assertEquals('mouthwatering', $test->curl->responseCookies['cookie2']); } public function testDefaultTimeout() { $test = new Test(); $test->server('timeout', 'GET', array( 'seconds' => '31', )); $this->assertTrue($test->curl->error); $this->assertTrue($test->curl->curlError); $this->assertEquals(CURLE_OPERATION_TIMEOUTED, $test->curl->errorCode); $this->assertEquals(CURLE_OPERATION_TIMEOUTED, $test->curl->curlErrorCode); $this->assertFalse($test->curl->httpError); } public function testTimeoutError() { $test = new Test(); $test->curl->setTimeout(5); $test->server('timeout', 'GET', array( 'seconds' => '10', )); $this->assertTrue($test->curl->error); $this->assertTrue($test->curl->curlError); $this->assertEquals(CURLE_OPERATION_TIMEOUTED, $test->curl->errorCode); $this->assertEquals(CURLE_OPERATION_TIMEOUTED, $test->curl->curlErrorCode); $this->assertFalse($test->curl->httpError); } public function testTimeout() { $test = new Test(); $test->curl->setTimeout(10); $test->server('timeout', 'GET', array( 'seconds' => '5', )); $this->assertFalse($test->curl->error); $this->assertFalse($test->curl->curlError); $this->assertNotEquals(CURLE_OPERATION_TIMEOUTED, $test->curl->errorCode); $this->assertNotEquals(CURLE_OPERATION_TIMEOUTED, $test->curl->curlErrorCode); $this->assertFalse($test->curl->httpError); } public function testError() { $test = new Test(); $test->curl->setOpt(CURLOPT_CONNECTTIMEOUT_MS, 4000); $test->curl->get(Test::ERROR_URL); $this->assertTrue($test->curl->error); $this->assertTrue($test->curl->curlError); $this->assertEquals(CURLE_OPERATION_TIMEOUTED, $test->curl->errorCode); $this->assertEquals(CURLE_OPERATION_TIMEOUTED, $test->curl->curlErrorCode); } public function testErrorMessage() { $test = new Test(); $test->server('error_message', 'GET'); $this->assertEquals('HTTP/1.1 401 Unauthorized', $test->curl->errorMessage); } public function testRequestHeaderCaseSensitivity() { $content_type = 'application/json'; $curl = new Curl(); $curl->setHeader('Content-Type', $content_type); $reflector = new \ReflectionClass('\Curl\Curl'); $property = $reflector->getProperty('headers'); $property->setAccessible(true); $headers = $property->getValue($curl); $this->assertEquals($content_type, $headers['Content-Type']); $this->assertEquals($content_type, $headers['content-type']); $this->assertEquals($content_type, $headers['CONTENT-TYPE']); $this->assertEquals($content_type, $headers['cOnTeNt-TyPe']); } public function testResponseHeaders() { $test = new Test(); $test->curl->setHeader('Content-Type', 'application/json'); $test->curl->setHeader('X-Requested-With', 'XMLHttpRequest'); $test->curl->setHeader('Accept', 'application/json'); $this->assertEquals('application/json', $test->server('server', 'GET', array('key' => 'CONTENT_TYPE'))); $this->assertEquals('XMLHttpRequest', $test->server('server', 'GET', array('key' => 'HTTP_X_REQUESTED_WITH'))); $this->assertEquals('application/json', $test->server('server', 'GET', array('key' => 'HTTP_ACCEPT'))); } public function testResponseHeaderCaseSensitivity() { $content_type = 'application/json'; $test = new Test(); $test->curl->setHeader('Content-Type', $content_type); $test->server('response_header', 'GET'); $request_headers = $test->curl->requestHeaders; $response_headers = $test->curl->responseHeaders; $this->assertEquals($content_type, $request_headers['Content-Type']); $this->assertEquals($content_type, $request_headers['content-type']); $this->assertEquals($content_type, $request_headers['CONTENT-TYPE']); $this->assertEquals($content_type, $request_headers['cOnTeNt-TyPe']); $etag = $response_headers['ETag']; $this->assertEquals($etag, $response_headers['ETAG']); $this->assertEquals($etag, $response_headers['etag']); $this->assertEquals($etag, $response_headers['eTAG']); $this->assertEquals($etag, $response_headers['eTaG']); } public function testHeaderOutOptional() { // CURLINFO_HEADER_OUT is true by default. $test_1 = new Test(); $test_1->server('response_header', 'GET'); $this->assertNotEmpty($test_1->curl->requestHeaders); $this->assertNotEmpty($test_1->curl->requestHeaders['Request-Line']); // CURLINFO_HEADER_OUT is set to true. $test_2 = new Test(); $test_2->curl->setOpt(CURLINFO_HEADER_OUT, true); $test_2->server('response_header', 'GET'); $this->assertNotEmpty($test_2->curl->requestHeaders); $this->assertNotEmpty($test_2->curl->requestHeaders['Request-Line']); // CURLINFO_HEADER_OUT is set to false. $test_3 = new Test(); $test_3->curl->setOpt(CURLINFO_HEADER_OUT, false); $test_3->curl->verbose(); $test_3->server('response_header', 'GET'); $this->assertNull($test_3->curl->requestHeaders); } public function testHeaderRedirect() { $test = new Test(); $test->curl->setOpt(CURLOPT_FOLLOWLOCATION, true); $test->server('redirect', 'GET'); $this->assertEquals('OK', $test->curl->response); } public function testRequestUrl() { $test = new Test(); $this->assertFalse(substr($test->server('request_uri', 'GET'), -1) === '?'); $test = new Test(); $this->assertFalse(substr($test->server('request_uri', 'POST'), -1) === '?'); $test = new Test(); $this->assertFalse(substr($test->server('request_uri', 'PUT'), -1) === '?'); $test = new Test(); $this->assertFalse(substr($test->server('request_uri', 'PATCH'), -1) === '?'); $test = new Test(); $this->assertFalse(substr($test->server('request_uri', 'DELETE'), -1) === '?'); } public function testNestedData() { $test = new Test(); $data = array( 'username' => 'myusername', 'password' => 'mypassword', 'more_data' => array( 'param1' => 'something', 'param2' => 'other thing', 'another' => array( 'extra' => 'level', 'because' => 'I need it', ), ), ); $this->assertEquals(http_build_query($data), $test->server('post', 'POST', $data)); } public function testPostStringUrlEncodedContentType() { $test = new Test(); $test->server('server', 'POST', 'foo=bar'); $this->assertEquals('application/x-www-form-urlencoded', $test->curl->requestHeaders['Content-Type']); } public function testPostArrayUrlEncodedContentType() { $test = new Test(); $test->server('server', 'POST', array( 'foo' => 'bar', )); $this->assertEquals('application/x-www-form-urlencoded', $test->curl->requestHeaders['Content-Type']); } public function testPostFileFormDataContentType() { $file_path = \Helper\get_png(); $test = new Test(); $test->server('server', 'POST', array( 'image' => '@' . $file_path, )); $this->assertEquals('100-continue', $test->curl->requestHeaders['Expect']); preg_match('/^multipart\/form-data; boundary=/', $test->curl->requestHeaders['Content-Type'], $content_type); $this->assertTrue(!empty($content_type)); unlink($file_path); $this->assertFalse(file_exists($file_path)); } public function testPostCurlFileFormDataContentType() { if (!class_exists('CURLFile')) { $this->markTestSkipped(); } $file_path = \Helper\get_png(); $test = new Test(); $test->server('server', 'POST', array( 'image' => new \CURLFile($file_path), )); $this->assertEquals('100-continue', $test->curl->requestHeaders['Expect']); preg_match('/^multipart\/form-data; boundary=/', $test->curl->requestHeaders['Content-Type'], $content_type); $this->assertTrue(!empty($content_type)); unlink($file_path) ; $this->assertFalse(file_exists($file_path)); } public function testJsonRequest() { foreach (array( array( array( 'key' => 'value', ), '{"key":"value"}', ), array( array( 'key' => 'value', 'strings' => array( 'a', 'b', 'c', ), ), '{"key":"value","strings":["a","b","c"]}', ), ) as $test) { list($data, $expected_response) = $test; $test = new Test(); $this->assertEquals($expected_response, $test->server('post_json', 'POST', json_encode($data))); foreach (array( 'Content-Type', 'content-type', 'CONTENT-TYPE') as $key) { foreach (array( 'APPLICATION/JSON', 'APPLICATION/JSON; CHARSET=UTF-8', 'APPLICATION/JSON;CHARSET=UTF-8', 'application/json', 'application/json; charset=utf-8', 'application/json;charset=UTF-8', ) as $value) { $test = new Test(); $test->curl->setHeader($key, $value); $this->assertEquals($expected_response, $test->server('post_json', 'POST', json_encode($data))); $test = new Test(); $test->curl->setHeader($key, $value); $this->assertEquals($expected_response, $test->server('post_json', 'POST', $data)); } } } } public function testJsonResponse() { foreach (array( 'Content-Type', 'content-type', 'CONTENT-TYPE') as $key) { foreach (array( 'APPLICATION/JSON', 'APPLICATION/JSON; CHARSET=UTF-8', 'APPLICATION/JSON;CHARSET=UTF-8', 'application/json', 'application/json; charset=utf-8', 'application/json;charset=UTF-8', ) as $value) { $test = new Test(); $test->server('json_response', 'POST', array( 'key' => $key, 'value' => $value, )); $response = $test->curl->response; $this->assertNotNull($response); $this->assertNull($response->null); $this->assertTrue($response->true); $this->assertFalse($response->false); $this->assertTrue(is_int($response->integer)); $this->assertTrue(is_float($response->float)); $this->assertEmpty($response->empty); $this->assertTrue(is_string($response->string)); $this->assertEquals(json_encode(array( 'null' => null, 'true' => true, 'false' => false, 'integer' => 1, 'float' => 3.14, 'empty' => '', 'string' => 'string', )), $test->curl->rawResponse); } } } public function testJsonDecoderOptions() { // Implicit default json decoder should return object. $test = new Test(); $test->server('json_response', 'GET'); $this->assertTrue(is_object($test->curl->response)); // Explicit default json decoder should return object. $test = new Test(); $test->curl->setDefaultJsonDecoder(); $test->server('json_response', 'GET'); $this->assertTrue(is_object($test->curl->response)); // Explicit default json decoder with options should return associative array as specified. $assoc = true; $depth = 512; $options = 0; $test = new Test(); $test->curl->setDefaultJsonDecoder($assoc, $depth, $options); $test->server('json_response', 'GET'); $this->assertTrue(is_array($test->curl->response)); } public function testJsonDecoder() { $data = array( 'key' => 'Content-Type', 'value' => 'application/json', ); $test = new Test(); $test->server('json_response', 'POST', $data); $this->assertTrue(is_object($test->curl->response)); $this->assertFalse(is_array($test->curl->response)); $test = new Test(); $test->curl->setJsonDecoder(function ($response) { return json_decode($response, true); }); $test->server('json_response', 'POST', $data); $this->assertFalse(is_object($test->curl->response)); $this->assertTrue(is_array($test->curl->response)); $test = new Test(); $test->curl->setJsonDecoder(false); $test->server('json_response', 'POST', $data); $this->assertTrue(is_string($test->curl->response)); } public function testJsonContentTypeDetection() { $json_content_types = array( 'application/alto-costmap+json', 'application/alto-costmapfilter+json', 'application/alto-directory+json', 'application/alto-endpointprop+json', 'application/alto-endpointpropparams+json', 'application/alto-endpointcost+json', 'application/alto-endpointcostparams+json', 'application/alto-error+json', 'application/alto-networkmapfilter+json', 'application/alto-networkmap+json', 'application/calendar+json', 'application/coap-group+json', 'application/jose+json', 'application/jrd+json', 'application/json', 'application/json-patch+json', 'application/json-seq', 'application/jwk+json', 'application/jwk-set+json', 'application/ld+json', 'application/merge-patch+json', 'application/rdap+json', 'application/reputon+json', 'application/vcard+json', 'application/vnd.apache.thrift.json', 'application/vnd.api+json', 'application/vnd.bekitzur-stech+json', 'application/vnd.collection.doc+json', 'application/vnd.collection+json', 'application/vnd.collection.next+json', 'application/vnd.document+json', 'application/vnd.geo+json', 'application/vnd.hal+json', 'application/vnd.heroku+json', 'application/vnd.ims.lis.v2.result+json', 'application/vnd.ims.lti.v2.toolconsumerprofile+json', 'application/vnd.ims.lti.v2.toolproxy.id+json', 'application/vnd.ims.lti.v2.toolproxy+json', 'application/vnd.ims.lti.v2.toolsettings+json', 'application/vnd.ims.lti.v2.toolsettings.simple+json', 'application/vnd.mason+json', 'application/vnd.micro+json', 'application/vnd.miele+json', 'application/vnd.oftn.l10n+json', 'application/vnd.oracle.resource+json', 'application/vnd.siren+json', 'application/vnd.xacml+json', // Non-standard 'application/x-json', 'text/json', 'text/x-json', ); $class = new \ReflectionClass('\Curl\Curl'); $property = $class->getProperty('jsonPattern'); $property->setAccessible(true); $json_pattern = $property->getValue(new Curl); foreach ($json_content_types as $json_content_type) { $message = '"' . $json_content_type . '" does not match pattern ' . $json_pattern; $this->assertEquals(1, preg_match($json_pattern, $json_content_type), $message); } $not_json_content_types = array( 'application/1d-interleaved-parityfec', 'application/3gpdash-qoe-report+xml', 'application/3gpp-ims+xml', 'application/A2L', 'application/activemessage', 'application/activemessage', 'application/AML', 'application/andrew-inset', 'application/applefile', 'application/ATF', 'application/ATFX', 'application/atom+xml', 'application/atomcat+xml', 'application/atomdeleted+xml', 'application/atomicmail', 'application/atomsvc+xml', 'application/ATXML', 'application/auth-policy+xml', 'application/bacnet-xdd+zip', 'application/batch-SMTP', 'application/beep+xml', 'application/calendar+xml', 'application/call-completion', 'application/cals-1840', 'application/cbor', 'application/ccmp+xml', 'application/ccxml+xml', 'application/CDFX+XML', 'application/cdmi-capability', 'application/cdmi-container', 'application/cdmi-domain', 'application/cdmi-object', 'application/cdmi-queue', 'application/CEA', 'application/cea-2018+xml', 'application/cellml+xml', 'application/cfw', 'application/cms', 'application/cnrp+xml', 'application/commonground', 'application/conference-info+xml', 'application/cpl+xml', 'application/csrattrs', 'application/csta+xml', 'application/CSTAdata+xml', 'application/cybercash', 'application/dash+xml', 'application/dashdelta', 'application/davmount+xml', 'application/dca-rft', 'application/DCD', 'application/dec-dx', 'application/dialog-info+xml', 'application/dicom', 'application/DII', 'application/DIT', 'application/dns', 'application/dskpp+xml', 'application/dssc+der', 'application/dssc+xml', 'application/dvcs', 'application/ecmascript', 'application/EDI-consent', 'application/EDIFACT', 'application/EDI-X12', 'application/emotionml+xml', 'application/encaprtp', 'application/epp+xml', 'application/epub+zip', 'application/eshop', 'application/example', 'application/fastinfoset', 'application/fastsoap', 'application/fdt+xml', 'application/fits', 'application/font-sfnt', 'application/font-tdpfr', 'application/font-woff', 'application/framework-attributes+xml', 'application/gzip', 'application/H224', 'application/held+xml', 'application/http', 'application/hyperstudio', 'application/ibe-key-request+xml', 'application/ibe-pkg-reply+xml', 'application/ibe-pp-data', 'application/iges', 'application/im-iscomposing+xml', 'application/index', 'application/index.cmd', 'application/index.obj', 'application/index.response', 'application/index.vnd', 'application/inkml+xml', 'application/IOTP', 'application/ipfix', 'application/ipp', 'application/ISUP', 'application/its+xml', 'application/javascript', 'application/jose', 'application/jwt', 'application/kpml-request+xml', 'application/kpml-response+xml', 'application/link-format', 'application/load-control+xml', 'application/lost+xml', 'application/lostsync+xml', 'application/LXF', 'application/mac-binhex40', 'application/macwriteii', 'application/mads+xml', 'application/marc', 'application/marcxml+xml', 'application/mathematica', 'application/mbms-associated-procedure-description+xml', 'application/mbms-deregister+xml', 'application/mbms-envelope+xml', 'application/mbms-msk-response+xml', 'application/mbms-msk+xml', 'application/mbms-protection-description+xml', 'application/mbms-reception-report+xml', 'application/mbms-register-response+xml', 'application/mbms-register+xml', 'application/mbms-schedule+xml', 'application/mbms-user-service-description+xml', 'application/mbox+xml', 'application/media_control+xml', 'application/media-policy-dataset+xml', 'application/mediaservercontrol+xml', 'application/metalink4+xml', 'application/mets+xml', 'application/MF4', 'application/mikey', 'application/mods+xml', 'application/moss-keys', 'application/moss-signature', 'application/mosskey-data', 'application/mosskey-request', 'application/mp21', 'application/mp4', 'application/mpeg4-generic', 'application/mpeg4-iod', 'application/mpeg4-iod-xmt', 'application/mrb-consumer+xml', 'application/mrb-publish+xml', 'application/msc-ivr+xml', 'application/msc-mixer+xml', 'application/msword', 'application/mxf', 'application/nasdata', 'application/news-checkgroups', 'application/news-groupinfo', 'application/news-transmission', 'application/nlsml+xml', 'application/nss', 'application/ocsp-request', 'application/oscp-response', 'application/octet-stream', 'application/ODA', 'application/ODX', 'application/oebps-package+xml', 'application/ogg', 'application/oxps', 'application/p2p-overlay+xml', 'application/patch-ops-error+xml', 'application/pdf', 'application/PDX', 'application/pgp-encrypted', 'application/pgp-signature', 'application/pidf-diff+xml', 'application/pidf+xml', 'application/pkcs10', 'application/pkcs7-mime', 'application/pkcs7-signature', 'application/pkcs8', 'application/pkix-attr-cert', 'application/pkix-cert', 'application/pkix-crl', 'application/pkix-pkipath', 'application/pkixcmp', 'application/pls+xml', 'application/poc-settings+xml', 'application/postscript', 'application/provenance+xml', 'application/prs.alvestrand.titrax-sheet', 'application/prs.cww', 'application/prs.hpub+zip', 'application/prs.nprend', 'application/prs.plucker', 'application/prs.rdf-xml-crypt', 'application/prs.xsf+xml', 'application/pskc+xml', 'application/rdf+xml', 'application/QSIG', 'application/raptorfec', 'application/reginfo+xml', 'application/relax-ng-compact-syntax', 'application/remote-printing', 'application/resource-lists-diff+xml', 'application/resource-lists+xml', 'application/riscos', 'application/rlmi+xml', 'application/rls-services+xml', 'application/rpki-ghostbusters', 'application/rpki-manifest', 'application/rpki-roa', 'application/rpki-updown', 'application/rtf', 'application/rtploopback', 'application/rtx', 'application/samlassertion+xml', 'application/samlmetadata+xml', 'application/sbml+xml', 'application/scaip+xml', 'application/scvp-cv-request', 'application/scvp-cv-response', 'application/scvp-vp-request', 'application/scvp-vp-response', 'application/sdp', 'application/sep-exi', 'application/sep+xml', 'application/session-info', 'application/set-payment', 'application/set-payment-initiation', 'application/set-registration', 'application/set-registration-initiation', 'application/SGML', 'application/sgml-open-catalog', 'application/shf+xml', 'application/sieve', 'application/simple-filter+xml', 'application/simple-message-summary', 'application/simpleSymbolContainer', 'application/slate', 'application/smil', 'application/smil+xml', 'application/smpte336m', 'application/soap+fastinfoset', 'application/soap+xml', 'application/spirits-event+xml', 'application/sql', 'application/srgs', 'application/srgs+xml', 'application/sru+xml', 'application/ssml+xml', 'application/tamp-apex-update', 'application/tamp-apex-update-confirm', 'application/tamp-community-update', 'application/tamp-community-update-confirm', 'application/tamp-error', 'application/tamp-sequence-adjust', 'application/tamp-sequence-adjust-confirm', 'application/tamp-status-query', 'application/tamp-status-response', 'application/tamp-update', 'application/tamp-update-confirm', 'application/tei+xml', 'application/thraud+xml', 'application/timestamp-query', 'application/timestamp-reply', 'application/timestamped-data', 'application/ttml+xml', 'application/tve-trigger', 'application/ulpfec', 'application/urc-grpsheet+xml', 'application/urc-ressheet+xml', 'application/urc-targetdesc+xml', 'application/urc-uisocketdesc+xml', 'application/vcard+xml', 'application/vemmi', 'application/vnd.3gpp.bsf+xml', 'application/vnd.3gpp.pic-bw-large', 'application/vnd.3gpp.pic-bw-small', 'application/vnd.3gpp.pic-bw-var', 'application/vnd.3gpp.sms', 'application/vnd.3gpp2.bcmcsinfo+xml', 'application/vnd.3gpp2.sms', 'application/vnd.3gpp2.tcap', 'application/vnd.3M.Post-it-Notes', 'application/vnd.accpac.simply.aso', 'application/vnd.accpac.simply.imp', 'application/vnd-acucobol', 'application/vnd.acucorp', 'application/vnd.adobe.flash-movie', 'application/vnd.adobe.formscentral.fcdt', 'application/vnd.adobe.fxp', 'application/vnd.adobe.partial-upload', 'application/vnd.adobe.xdp+xml', 'application/vnd.adobe.xfdf', 'application/vnd.aether.imp', 'application/vnd.ah-barcode', 'application/vnd.ahead.space', 'application/vnd.airzip.filesecure.azf', 'application/vnd.airzip.filesecure.azs', 'application/vnd.americandynamics.acc', 'application/vnd.amiga.ami', 'application/vnd.amundsen.maze+xml', 'application/vnd.anser-web-certificate-issue-initiation', 'application/vnd.antix.game-component', 'application/vnd.apache.thrift.binary', 'application/vnd.apache.thrift.compact', 'application/vnd.apple.mpegurl', 'application/vnd.apple.installer+xml', 'application/vnd.arastra.swi', 'application/vnd.aristanetworks.swi', 'application/vnd.artsquare', 'application/vnd.astraea-software.iota', 'application/vnd.audiograph', 'application/vnd.autopackage', 'application/vnd.avistar+xml', 'application/vnd.balsamiq.bmml+xml', 'application/vnd.blueice.multipass', 'application/vnd.bluetooth.ep.oob', 'application/vnd.bluetooth.le.oob', 'application/vnd.bmi', 'application/vnd.businessobjects', 'application/vnd.cab-jscript', 'application/vnd.canon-cpdl', 'application/vnd.canon-lips', 'application/vnd.cendio.thinlinc.clientconf', 'application/vnd.century-systems.tcp_stream', 'application/vnd.chemdraw+xml', 'application/vnd.chipnuts.karaoke-mmd', 'application/vnd.cinderella', 'application/vnd.cirpack.isdn-ext', 'application/vnd.citationstyles.style+xml', 'application/vnd.claymore', 'application/vnd.cloanto.rp9', 'application/vnd.clonk.c4group', 'application/vnd.cluetrust.cartomobile-config', 'application/vnd.cluetrust.cartomobile-config-pkg', 'application/vnd.coffeescript', 'application/vnd.commerce-battelle', 'application/vnd.commonspace', 'application/vnd.cosmocaller', 'application/vnd.contact.cmsg', 'application/vnd.crick.clicker', 'application/vnd.crick.clicker.keyboard', 'application/vnd.crick.clicker.palette', 'application/vnd.crick.clicker.template', 'application/vnd.crick.clicker.wordbank', 'application/vnd.criticaltools.wbs+xml', 'application/vnd.ctc-posml', 'application/vnd.ctct.ws+xml', 'application/vnd.cups-pdf', 'application/vnd.cups-postscript', 'application/vnd.cups-ppd', 'application/vnd.cups-raster', 'application/vnd.cups-raw', 'application/vnd-curl', 'application/vnd.cyan.dean.root+xml', 'application/vnd.cybank', 'application/vnd-dart', 'application/vnd.data-vision.rdz', 'application/vnd.debian.binary-package', 'application/vnd.dece.data', 'application/vnd.dece.ttml+xml', 'application/vnd.dece.unspecified', 'application/vnd.dece-zip', 'application/vnd.denovo.fcselayout-link', 'application/vnd.desmume-movie', 'application/vnd.dir-bi.plate-dl-nosuffix', 'application/vnd.dm.delegation+xml', 'application/vnd.dna', 'application/vnd.dolby.mobile.1', 'application/vnd.dolby.mobile.2', 'application/vnd.doremir.scorecloud-binary-document', 'application/vnd.dpgraph', 'application/vnd.dreamfactory', 'application/vnd.dtg.local', 'application/vnd.dtg.local.flash', 'application/vnd.dtg.local.html', 'application/vnd.dvb.ait', 'application/vnd.dvb.dvbj', 'application/vnd.dvb.esgcontainer', 'application/vnd.dvb.ipdcdftnotifaccess', 'application/vnd.dvb.ipdcesgaccess', 'application/vnd.dvb.ipdcesgaccess2', 'application/vnd.dvb.ipdcesgpdd', 'application/vnd.dvb.ipdcroaming', 'application/vnd.dvb.iptv.alfec-base', 'application/vnd.dvb.iptv.alfec-enhancement', 'application/vnd.dvb.notif-aggregate-root+xml', 'application/vnd.dvb.notif-container+xml', 'application/vnd.dvb.notif-generic+xml', 'application/vnd.dvb.notif-ia-msglist+xml', 'application/vnd.dvb.notif-ia-registration-request+xml', 'application/vnd.dvb.notif-ia-registration-response+xml', 'application/vnd.dvb.notif-init+xml', 'application/vnd.dvb.pfr', 'application/vnd.dvb_service', 'application/vnd-dxr', 'application/vnd.dynageo', 'application/vnd.dzr', 'application/vnd.easykaraoke.cdgdownload', 'application/vnd.ecdis-update', 'application/vnd.ecowin.chart', 'application/vnd.ecowin.filerequest', 'application/vnd.ecowin.fileupdate', 'application/vnd.ecowin.series', 'application/vnd.ecowin.seriesrequest', 'application/vnd.ecowin.seriesupdate', 'application/vnd.emclient.accessrequest+xml', 'application/vnd.enliven', 'application/vnd.enphase.envoy', 'application/vnd.eprints.data+xml', 'application/vnd.epson.esf', 'application/vnd.epson.msf', 'application/vnd.epson.quickanime', 'application/vnd.epson.salt', 'application/vnd.epson.ssf', 'application/vnd.ericsson.quickcall', 'application/vnd.eszigno3+xml', 'application/vnd.etsi.aoc+xml', 'application/vnd.etsi.asic-s+zip', 'application/vnd.etsi.asic-e+zip', 'application/vnd.etsi.cug+xml', 'application/vnd.etsi.iptvcommand+xml', 'application/vnd.etsi.iptvdiscovery+xml', 'application/vnd.etsi.iptvprofile+xml', 'application/vnd.etsi.iptvsad-bc+xml', 'application/vnd.etsi.iptvsad-cod+xml', 'application/vnd.etsi.iptvsad-npvr+xml', 'application/vnd.etsi.iptvservice+xml', 'application/vnd.etsi.iptvsync+xml', 'application/vnd.etsi.iptvueprofile+xml', 'application/vnd.etsi.mcid+xml', 'application/vnd.etsi.mheg5', 'application/vnd.etsi.overload-control-policy-dataset+xml', 'application/vnd.etsi.pstn+xml', 'application/vnd.etsi.sci+xml', 'application/vnd.etsi.simservs+xml', 'application/vnd.etsi.timestamp-token', 'application/vnd.etsi.tsl+xml', 'application/vnd.etsi.tsl.der', 'application/vnd.eudora.data', 'application/vnd.ezpix-album', 'application/vnd.ezpix-package', 'application/vnd.f-secure.mobile', 'application/vnd.fastcopy-disk-image', 'application/vnd-fdf', 'application/vnd.fdsn.mseed', 'application/vnd.fdsn.seed', 'application/vnd.ffsns', 'application/vnd.fints', 'application/vnd.FloGraphIt', 'application/vnd.fluxtime.clip', 'application/vnd.font-fontforge-sfd', 'application/vnd.framemaker', 'application/vnd.frogans.fnc', 'application/vnd.frogans.ltf', 'application/vnd.fsc.weblaunch', 'application/vnd.fujitsu.oasys', 'application/vnd.fujitsu.oasys2', 'application/vnd.fujitsu.oasys3', 'application/vnd.fujitsu.oasysgp', 'application/vnd.fujitsu.oasysprs', 'application/vnd.fujixerox.ART4', 'application/vnd.fujixerox.ART-EX', 'application/vnd.fujixerox.ddd', 'application/vnd.fujixerox.docuworks', 'application/vnd.fujixerox.docuworks.binder', 'application/vnd.fujixerox.docuworks.container', 'application/vnd.fujixerox.HBPL', 'application/vnd.fut-misnet', 'application/vnd.fuzzysheet', 'application/vnd.genomatix.tuxedo', 'application/vnd.geocube+xml', 'application/vnd.geogebra.file', 'application/vnd.geogebra.tool', 'application/vnd.geometry-explorer', 'application/vnd.geonext', 'application/vnd.geoplan', 'application/vnd.geospace', 'application/vnd.gerber', 'application/vnd.globalplatform.card-content-mgt', 'application/vnd.globalplatform.card-content-mgt-response', 'application/vnd.gmx', 'application/vnd.google-earth.kml+xml', 'application/vnd.google-earth.kmz', 'application/vnd.gov.sk.e-form+xml', 'application/vnd.gov.sk.e-form+zip', 'application/vnd.gov.sk.xmldatacontainer+xml', 'application/vnd.grafeq', 'application/vnd.gridmp', 'application/vnd.groove-account', 'application/vnd.groove-help', 'application/vnd.groove-identity-message', 'application/vnd.groove-injector', 'application/vnd.groove-tool-message', 'application/vnd.groove-tool-template', 'application/vnd.groove-vcard', 'application/vnd.hal+xml', 'application/vnd.HandHeld-Entertainment+xml', 'application/vnd.hbci', 'application/vnd.hcl-bireports', 'application/vnd.hhe.lesson-player', 'application/vnd.hp-HPGL', 'application/vnd.hp-hpid', 'application/vnd.hp-hps', 'application/vnd.hp-jlyt', 'application/vnd.hp-PCL', 'application/vnd.hp-PCLXL', 'application/vnd.httphone', 'application/vnd.hydrostatix.sof-data', 'application/vnd.hzn-3d-crossword', 'application/vnd.ibm.afplinedata', 'application/vnd.ibm.electronic-media', 'application/vnd.ibm.MiniPay', 'application/vnd.ibm.modcap', 'application/vnd.ibm.rights-management', 'application/vnd.ibm.secure-container', 'application/vnd.iccprofile', 'application/vnd.ieee.1905', 'application/vnd.igloader', 'application/vnd.immervision-ivp', 'application/vnd.immervision-ivu', 'application/vnd.ims.imsccv1p1', 'application/vnd.ims.imsccv1p2', 'application/vnd.ims.imsccv1p3', 'application/vnd.informedcontrol.rms+xml', 'application/vnd.infotech.project', 'application/vnd.infotech.project+xml', 'application/vnd.informix-visionary', 'application/vnd.innopath.wamp.notification', 'application/vnd.insors.igm', 'application/vnd.intercon.formnet', 'application/vnd.intergeo', 'application/vnd.intertrust.digibox', 'application/vnd.intertrust.nncp', 'application/vnd.intu.qbo', 'application/vnd.intu.qfx', 'application/vnd.iptc.g2.catalogitem+xml', 'application/vnd.iptc.g2.conceptitem+xml', 'application/vnd.iptc.g2.knowledgeitem+xml', 'application/vnd.iptc.g2.newsitem+xml', 'application/vnd.iptc.g2.newsmessage+xml', 'application/vnd.iptc.g2.packageitem+xml', 'application/vnd.iptc.g2.planningitem+xml', 'application/vnd.ipunplugged.rcprofile', 'application/vnd.irepository.package+xml', 'application/vnd.is-xpr', 'application/vnd.isac.fcs', 'application/vnd.jam', 'application/vnd.japannet-directory-service', 'application/vnd.japannet-jpnstore-wakeup', 'application/vnd.japannet-payment-wakeup', 'application/vnd.japannet-registration', 'application/vnd.japannet-registration-wakeup', 'application/vnd.japannet-setstore-wakeup', 'application/vnd.japannet-verification', 'application/vnd.japannet-verification-wakeup', 'application/vnd.jcp.javame.midlet-rms', 'application/vnd.jisp', 'application/vnd.joost.joda-archive', 'application/vnd.jsk.isdn-ngn', 'application/vnd.kahootz', 'application/vnd.kde.karbon', 'application/vnd.kde.kchart', 'application/vnd.kde.kformula', 'application/vnd.kde.kivio', 'application/vnd.kde.kontour', 'application/vnd.kde.kpresenter', 'application/vnd.kde.kspread', 'application/vnd.kde.kword', 'application/vnd.kenameaapp', 'application/vnd.kidspiration', 'application/vnd.Kinar', 'application/vnd.koan', 'application/vnd.kodak-descriptor', 'application/vnd.las.las+xml', 'application/vnd.liberty-request+xml', 'application/vnd.llamagraphics.life-balance.desktop', 'application/vnd.llamagraphics.life-balance.exchange+xml', 'application/vnd.lotus-1-2-3', 'application/vnd.lotus-approach', 'application/vnd.lotus-freelance', 'application/vnd.lotus-notes', 'application/vnd.lotus-organizer', 'application/vnd.lotus-screencam', 'application/vnd.lotus-wordpro', 'application/vnd.macports.portpkg', 'application/vnd.marlin.drm.actiontoken+xml', 'application/vnd.marlin.drm.conftoken+xml', 'application/vnd.marlin.drm.license+xml', 'application/vnd.marlin.drm.mdcf', 'application/vnd.maxmind.maxmind-db', 'application/vnd.mcd', 'application/vnd.medcalcdata', 'application/vnd.mediastation.cdkey', 'application/vnd.meridian-slingshot', 'application/vnd.MFER', 'application/vnd.mfmp', 'application/vnd.micrografx.flo', 'application/vnd.micrografx-igx', 'application/vnd.microsoft.portable-executable', 'application/vnd-mif', 'application/vnd.minisoft-hp3000-save', 'application/vnd.mitsubishi.misty-guard.trustweb', 'application/vnd.Mobius.DAF', 'application/vnd.Mobius.DIS', 'application/vnd.Mobius.MBK', 'application/vnd.Mobius.MQY', 'application/vnd.Mobius.MSL', 'application/vnd.Mobius.PLC', 'application/vnd.Mobius.TXF', 'application/vnd.mophun.application', 'application/vnd.mophun.certificate', 'application/vnd.motorola.flexsuite', 'application/vnd.motorola.flexsuite.adsi', 'application/vnd.motorola.flexsuite.fis', 'application/vnd.motorola.flexsuite.gotap', 'application/vnd.motorola.flexsuite.kmr', 'application/vnd.motorola.flexsuite.ttc', 'application/vnd.motorola.flexsuite.wem', 'application/vnd.motorola.iprm', 'application/vnd.mozilla.xul+xml', 'application/vnd.ms-artgalry', 'application/vnd.ms-asf', 'application/vnd.ms-cab-compressed', 'application/vnd.ms-3mfdocument', 'application/vnd.ms-excel', 'application/vnd.ms-excel.addin.macroEnabled.12', 'application/vnd.ms-excel.sheet.binary.macroEnabled.12', 'application/vnd.ms-excel.sheet.macroEnabled.12', 'application/vnd.ms-excel.template.macroEnabled.12', 'application/vnd.ms-fontobject', 'application/vnd.ms-htmlhelp', 'application/vnd.ms-ims', 'application/vnd.ms-lrm', 'application/vnd.ms-office.activeX+xml', 'application/vnd.ms-officetheme', 'application/vnd.ms-playready.initiator+xml', 'application/vnd.ms-powerpoint', 'application/vnd.ms-powerpoint.addin.macroEnabled.12', 'application/vnd.ms-powerpoint.presentation.macroEnabled.12', 'application/vnd.ms-powerpoint.slide.macroEnabled.12', 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12', 'application/vnd.ms-powerpoint.template.macroEnabled.12', 'application/vnd.ms-project', 'application/vnd.ms-tnef', 'application/vnd.ms-windows.printerpairing', 'application/vnd.ms-wmdrm.lic-chlg-req', 'application/vnd.ms-wmdrm.lic-resp', 'application/vnd.ms-wmdrm.meter-chlg-req', 'application/vnd.ms-wmdrm.meter-resp', 'application/vnd.ms-word.document.macroEnabled.12', 'application/vnd.ms-word.template.macroEnabled.12', 'application/vnd.ms-works', 'application/vnd.ms-wpl', 'application/vnd.ms-xpsdocument', 'application/vnd.msa-disk-image', 'application/vnd.mseq', 'application/vnd.msign', 'application/vnd.multiad.creator', 'application/vnd.multiad.creator.cif', 'application/vnd.musician', 'application/vnd.music-niff', 'application/vnd.muvee.style', 'application/vnd.mynfc', 'application/vnd.ncd.control', 'application/vnd.ncd.reference', 'application/vnd.nervana', 'application/vnd.netfpx', 'application/vnd.neurolanguage.nlu', 'application/vnd.nintendo.snes.rom', 'application/vnd.nintendo.nitro.rom', 'application/vnd.nitf', 'application/vnd.noblenet-directory', 'application/vnd.noblenet-sealer', 'application/vnd.noblenet-web', 'application/vnd.nokia.catalogs', 'application/vnd.nokia.conml+wbxml', 'application/vnd.nokia.conml+xml', 'application/vnd.nokia.iptv.config+xml', 'application/vnd.nokia.iSDS-radio-presets', 'application/vnd.nokia.landmark+wbxml', 'application/vnd.nokia.landmark+xml', 'application/vnd.nokia.landmarkcollection+xml', 'application/vnd.nokia.ncd', 'application/vnd.nokia.n-gage.ac+xml', 'application/vnd.nokia.n-gage.data', 'application/vnd.nokia.n-gage.symbian.install', 'application/vnd.nokia.pcd+wbxml', 'application/vnd.nokia.pcd+xml', 'application/vnd.nokia.radio-preset', 'application/vnd.nokia.radio-presets', 'application/vnd.novadigm.EDM', 'application/vnd.novadigm.EDX', 'application/vnd.novadigm.EXT', 'application/vnd.ntt-local.content-share', 'application/vnd.ntt-local.file-transfer', 'application/vnd.ntt-local.ogw_remote-access', 'application/vnd.ntt-local.sip-ta_remote', 'application/vnd.ntt-local.sip-ta_tcp_stream', 'application/vnd.oasis.opendocument.chart', 'application/vnd.oasis.opendocument.chart-template', 'application/vnd.oasis.opendocument.database', 'application/vnd.oasis.opendocument.formula', 'application/vnd.oasis.opendocument.formula-template', 'application/vnd.oasis.opendocument.graphics', 'application/vnd.oasis.opendocument.graphics-template', 'application/vnd.oasis.opendocument.image', 'application/vnd.oasis.opendocument.image-template', 'application/vnd.oasis.opendocument.presentation', 'application/vnd.oasis.opendocument.presentation-template', 'application/vnd.oasis.opendocument.spreadsheet', 'application/vnd.oasis.opendocument.spreadsheet-template', 'application/vnd.oasis.opendocument.text', 'application/vnd.oasis.opendocument.text-master', 'application/vnd.oasis.opendocument.text-template', 'application/vnd.oasis.opendocument.text-web', 'application/vnd.obn', 'application/vnd.oipf.contentaccessdownload+xml', 'application/vnd.oipf.contentaccessstreaming+xml', 'application/vnd.oipf.cspg-hexbinary', 'application/vnd.oipf.dae.svg+xml', 'application/vnd.oipf.dae.xhtml+xml', 'application/vnd.oipf.mippvcontrolmessage+xml', 'application/vnd.oipf.pae.gem', 'application/vnd.oipf.spdiscovery+xml', 'application/vnd.oipf.spdlist+xml', 'application/vnd.oipf.ueprofile+xml', 'application/vnd.oipf.userprofile+xml', 'application/vnd.olpc-sugar', 'application/vnd.oma.bcast.associated-procedure-parameter+xml', 'application/vnd.oma.bcast.drm-trigger+xml', 'application/vnd.oma.bcast.imd+xml', 'application/vnd.oma.bcast.ltkm', 'application/vnd.oma.bcast.notification+xml', 'application/vnd.oma.bcast.provisioningtrigger', 'application/vnd.oma.bcast.sgboot', 'application/vnd.oma.bcast.sgdd+xml', 'application/vnd.oma.bcast.sgdu', 'application/vnd.oma.bcast.simple-symbol-container', 'application/vnd.oma.bcast.smartcard-trigger+xml', 'application/vnd.oma.bcast.sprov+xml', 'application/vnd.oma.bcast.stkm', 'application/vnd.oma.cab-address-book+xml', 'application/vnd.oma.cab-feature-handler+xml', 'application/vnd.oma.cab-pcc+xml', 'application/vnd.oma.cab-subs-invite+xml', 'application/vnd.oma.cab-user-prefs+xml', 'application/vnd.oma.dcd', 'application/vnd.oma.dcdc', 'application/vnd.oma.dd2+xml', 'application/vnd.oma.drm.risd+xml', 'application/vnd.oma.group-usage-list+xml', 'application/vnd.oma.pal+xml', 'application/vnd.oma.poc.detailed-progress-report+xml', 'application/vnd.oma.poc.final-report+xml', 'application/vnd.oma.poc.groups+xml', 'application/vnd.oma.poc.invocation-descriptor+xml', 'application/vnd.oma.poc.optimized-progress-report+xml', 'application/vnd.oma.push', 'application/vnd.oma.scidm.messages+xml', 'application/vnd.oma.xcap-directory+xml', 'application/vnd.omads-email+xml', 'application/vnd.omads-file+xml', 'application/vnd.omads-folder+xml', 'application/vnd.omaloc-supl-init', 'application/vnd.oma-scws-config', 'application/vnd.oma-scws-http-request', 'application/vnd.oma-scws-http-response', 'application/vnd.openeye.oeb', 'application/vnd.openxmlformats-officedocument.custom-properties+xml', 'application/vnd.openxmlformats-officedocument.customXmlProperties+xml', 'application/vnd.openxmlformats-officedocument.drawing+xml', 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml', 'application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml', 'application/vnd.openxmlformats-officedocument.drawingml.diagramColors+xml', 'application/vnd.openxmlformats-officedocument.drawingml.diagramData+xml', 'application/vnd.openxmlformats-officedocument.drawingml.diagramLayout+xml', 'application/vnd.openxmlformats-officedocument.drawingml.diagramStyle+xml', 'application/vnd.openxmlformats-officedocument.extended-properties+xml', 'application/vnd.openxmlformats-officedocument.presentationml.commentAuthors+xml', 'application/vnd.openxmlformats-officedocument.presentationml.comments+xml', 'application/vnd.openxmlformats-officedocument.presentationml.handoutMaster+xml', 'application/vnd.openxmlformats-officedocument.presentationml.notesMaster+xml', 'application/vnd.openxmlformats-officedocument.presentationml.notesSlide+xml', 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml', 'application/vnd.openxmlformats-officedocument.presentationml.presProps+xml', 'application/vnd.openxmlformats-officedocument.presentationml.slide', 'application/vnd.openxmlformats-officedocument.presentationml.slide+xml', 'application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml', 'application/vnd.openxmlformats-officedocument.presentationml.slideMaster+xml', 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', 'application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml', 'application/vnd.openxmlformats-officedocument.presentationml.slideUpdateInfo+xml', 'application/vnd.openxmlformats-officedocument.presentationml.tableStyles+xml', 'application/vnd.openxmlformats-officedocument.presentationml.tags+xml', 'application/vnd.openxmlformats-officedocument.presentationml-template', 'application/vnd.openxmlformats-officedocument.presentationml.template.main+xml', 'application/vnd.openxmlformats-officedocument.presentationml.viewProps+xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.calcChain+xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.externalLink+xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheDefinition+xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheRecords+xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.pivotTable+xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.queryTable+xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.revisionHeaders+xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.revisionLog+xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.tableSingleCells+xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml-template', 'application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.userNames+xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.volatileDependencies+xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml', 'application/vnd.openxmlformats-officedocument.theme+xml', 'application/vnd.openxmlformats-officedocument.themeOverride+xml', 'application/vnd.openxmlformats-officedocument.vmlDrawing', 'application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml', 'application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml', 'application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml', 'application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml', 'application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml', 'application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml', 'application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml', 'application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml', 'application/vnd.openxmlformats-officedocument.wordprocessingml-template', 'application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml', 'application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml', 'application/vnd.openxmlformats-package.core-properties+xml', 'application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml', 'application/vnd.openxmlformats-package.relationships+xml', 'application/vnd.orange.indata', 'application/vnd.osa.netdeploy', 'application/vnd.osgeo.mapguide.package', 'application/vnd.osgi.bundle', 'application/vnd.osgi.dp', 'application/vnd.osgi.subsystem', 'application/vnd.otps.ct-kip+xml', 'application/vnd.palm', 'application/vnd.panoply', 'application/vnd.paos+xml', 'application/vnd.pawaafile', 'application/vnd.pcos', 'application/vnd.pg.format', 'application/vnd.pg.osasli', 'application/vnd.piaccess.application-licence', 'application/vnd.picsel', 'application/vnd.pmi.widget', 'application/vnd.poc.group-advertisement+xml', 'application/vnd.pocketlearn', 'application/vnd.powerbuilder6', 'application/vnd.powerbuilder6-s', 'application/vnd.powerbuilder7', 'application/vnd.powerbuilder75', 'application/vnd.powerbuilder75-s', 'application/vnd.powerbuilder7-s', 'application/vnd.preminet', 'application/vnd.previewsystems.box', 'application/vnd.proteus.magazine', 'application/vnd.publishare-delta-tree', 'application/vnd.pvi.ptid1', 'application/vwg-multiplexed', 'application/vnd.pwg-xhtml-print+xml', 'application/vnd.qualcomm.brew-app-res', 'application/vnd.Quark.QuarkXPress', 'application/vnd.quobject-quoxdocument', 'application/vnd.radisys.moml+xml', 'application/vnd.radisys.msml-audit-conf+xml', 'application/vnd.radisys.msml-audit-conn+xml', 'application/vnd.radisys.msml-audit-dialog+xml', 'application/vnd.radisys.msml-audit-stream+xml', 'application/vnd.radisys.msml-audit+xml', 'application/vnd.radisys.msml-conf+xml', 'application/vnd.radisys.msml-dialog-base+xml', 'application/vnd.radisys.msml-dialog-fax-detect+xml', 'application/vnd.radisys.msml-dialog-fax-sendrecv+xml', 'application/vnd.radisys.msml-dialog-group+xml', 'application/vnd.radisys.msml-dialog-speech+xml', 'application/vnd.radisys.msml-dialog-transform+xml', 'application/vnd.radisys.msml-dialog+xml', 'application/vnd.radisys.msml+xml', 'application/vnd.rainstor.data', 'application/vnd.rapid', 'application/vnd.realvnc.bed', 'application/vnd.recordare.musicxml', 'application/vnd.recordare.musicxml+xml', 'application/vnd.renlearn.rlprint', 'application/vnd.rig.cryptonote', 'application/vnd.route66.link66+xml', 'application/vnd.rs-274x', 'application/vnd.ruckus.download', 'application/vnd.s3sms', 'application/vnd.sailingtracker.track', 'application/vnd.sbm.cid', 'application/vnd.sbm.mid2', 'application/vnd.scribus', 'application/vnd.sealed.3df', 'application/vnd.sealed.csf', 'application/vnd.sealed-doc', 'application/vnd.sealed-eml', 'application/vnd.sealed-mht', 'application/vnd.sealed.net', 'application/vnd.sealed-ppt', 'application/vnd.sealed-tiff', 'application/vnd.sealed-xls', 'application/vnd.sealedmedia.softseal-html', 'application/vnd.sealedmedia.softseal-pdf', 'application/vnd.seemail', 'application/vnd-sema', 'application/vnd.semd', 'application/vnd.semf', 'application/vnd.shana.informed.formdata', 'application/vnd.shana.informed.formtemplate', 'application/vnd.shana.informed.interchange', 'application/vnd.shana.informed.package', 'application/vnd.SimTech-MindMapper', 'application/vnd.smaf', 'application/vnd.smart.notebook', 'application/vnd.smart.teacher', 'application/vnd.software602.filler.form+xml', 'application/vnd.software602.filler.form-xml-zip', 'application/vnd.solent.sdkm+xml', 'application/vnd.spotfire.dxp', 'application/vnd.spotfire.sfs', 'application/vnd.sss-cod', 'application/vnd.sss-dtf', 'application/vnd.sss-ntf', 'application/vnd.stepmania.package', 'application/vnd.stepmania.stepchart', 'application/vnd.street-stream', 'application/vnd.sun.wadl+xml', 'application/vnd.sus-calendar', 'application/vnd.svd', 'application/vnd.swiftview-ics', 'application/vnd.syncml.dm.notification', 'application/vnd.syncml.dmddf+xml', 'application/vnd.syncml.dmtnds+wbxml', 'application/vnd.syncml.dmtnds+xml', 'application/vnd.syncml.dmddf+wbxml', 'application/vnd.syncml.dm+wbxml', 'application/vnd.syncml.dm+xml', 'application/vnd.syncml.ds.notification', 'application/vnd.syncml+xml', 'application/vnd.tao.intent-module-archive', 'application/vnd.tcpdump.pcap', 'application/vnd.tmd.mediaflex.api+xml', 'application/vnd.tmobile-livetv', 'application/vnd.trid.tpt', 'application/vnd.triscape.mxs', 'application/vnd.trueapp', 'application/vnd.truedoc', 'application/vnd.ubisoft.webplayer', 'application/vnd.ufdl', 'application/vnd.uiq.theme', 'application/vnd.umajin', 'application/vnd.unity', 'application/vnd.uoml+xml', 'application/vnd.uplanet.alert', 'application/vnd.uplanet.alert-wbxml', 'application/vnd.uplanet.bearer-choice', 'application/vnd.uplanet.bearer-choice-wbxml', 'application/vnd.uplanet.cacheop', 'application/vnd.uplanet.cacheop-wbxml', 'application/vnd.uplanet.channel', 'application/vnd.uplanet.channel-wbxml', 'application/vnd.uplanet.list', 'application/vnd.uplanet.listcmd', 'application/vnd.uplanet.listcmd-wbxml', 'application/vnd.uplanet.list-wbxml', 'application/vnd.uplanet.signal', 'application/vnd.valve.source.material', 'application/vnd.vcx', 'application/vnd.vd-study', 'application/vnd.vectorworks', 'application/vnd.verimatrix.vcas', 'application/vnd.vidsoft.vidconference', 'application/vnd.visio', 'application/vnd.visionary', 'application/vnd.vividence.scriptfile', 'application/vnd.vsf', 'application/vnd.wap.sic', 'application/vnd.wap-slc', 'application/vnd.wap-wbxml', 'application/vnd-wap-wmlc', 'application/vnd.wap.wmlscriptc', 'application/vnd.webturbo', 'application/vnd.wfa.p2p', 'application/vnd.wfa.wsc', 'application/vnd.windows.devicepairing', 'application/vnd.wmc', 'application/vnd.wmf.bootstrap', 'application/vnd.wolfram.mathematica', 'application/vnd.wolfram.mathematica.package', 'application/vnd.wolfram.player', 'application/vnd.wordperfect', 'application/vnd.wqd', 'application/vnd.wrq-hp3000-labelled', 'application/vnd.wt.stf', 'application/vnd.wv.csp+xml', 'application/vnd.wv.csp+wbxml', 'application/vnd.wv.ssp+xml', 'application/vnd.xara', 'application/vnd.xfdl', 'application/vnd.xfdl.webform', 'application/vnd.xmi+xml', 'application/vnd.xmpie.cpkg', 'application/vnd.xmpie.dpkg', 'application/vnd.xmpie.plan', 'application/vnd.xmpie.ppkg', 'application/vnd.xmpie.xlim', 'application/vnd.yamaha.hv-dic', 'application/vnd.yamaha.hv-script', 'application/vnd.yamaha.hv-voice', 'application/vnd.yamaha.openscoreformat.osfpvg+xml', 'application/vnd.yamaha.openscoreformat', 'application/vnd.yamaha.remote-setup', 'application/vnd.yamaha.smaf-audio', 'application/vnd.yamaha.smaf-phrase', 'application/vnd.yamaha.through-ngn', 'application/vnd.yamaha.tunnel-udpencap', 'application/vnd.yaoweme', 'application/vnd.yellowriver-custom-menu', 'application/vnd.zul', 'application/vnd.zzazz.deck+xml', 'application/voicexml+xml', 'application/vq-rtcpxr', 'application/watcherinfo+xml', 'application/whoispp-query', 'application/whoispp-response', 'application/wita', 'application/wordperfect5.1', 'application/wsdl+xml', 'application/wspolicy+xml', 'application/x-www-form-urlencoded', 'application/x400-bp', 'application/xacml+xml', 'application/xcap-att+xml', 'application/xcap-caps+xml', 'application/xcap-diff+xml', 'application/xcap-el+xml', 'application/xcap-error+xml', 'application/xcap-ns+xml', 'application/xcon-conference-info-diff+xml', 'application/xcon-conference-info+xml', 'application/xenc+xml', 'application/xhtml-voice+xml', 'application/xhtml+xml', 'application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity', 'application/xml-patch+xml', 'application/xmpp+xml', 'application/xop+xml', 'application/xv+xml', 'application/yang', 'application/yin+xml', 'application/zip', 'application/zlib', ); foreach ($not_json_content_types as $json_content_type) { $message = '"' . $json_content_type . '" matches pattern ' . $json_pattern; $this->assertEquals(0, preg_match($json_pattern, $json_content_type), $message); } } public function testXMLResponse() { foreach (array( 'Content-Type', 'content-type', 'CONTENT-TYPE') as $key) { foreach (array( 'application/atom+xml; charset=UTF-8', 'application/atom+xml;charset=UTF-8', 'application/rss+xml', 'application/rss+xml; charset=utf-8', 'application/rss+xml;charset=utf-8', 'application/xml', 'application/xml; charset=utf-8', 'application/xml;charset=utf-8', 'text/xml', 'text/xml; charset=utf-8', 'text/xml;charset=utf-8', ) as $value) { $test = new Test(); $test->server('xml_response', 'POST', array( 'key' => $key, 'value' => $value, )); $this->assertInstanceOf('SimpleXMLElement', $test->curl->response); $doc = new \DOMDocument(); $doc->formatOutput = true; $rss = $doc->appendChild($doc->createElement('rss')); $rss->setAttribute('version', '2.0'); $channel = $doc->createElement('channel'); $title = $doc->createElement('title'); $title->appendChild($doc->createTextNode('Title')); $channel->appendChild($title); $link = $doc->createElement('link'); $link->appendChild($doc->createTextNode('Link')); $channel->appendChild($link); $description = $doc->createElement('description'); $description->appendChild($doc->createTextNode('Description')); $channel->appendChild($description); $rss->appendChild($channel); $xml = $doc->saveXML(); $this->assertEquals($xml, $test->curl->rawResponse); } } } public function testEmptyResponse() { $response = "\r\n\r\n"; $reflector = new \ReflectionClass('\Curl\Curl'); $reflection_method = $reflector->getMethod('parseResponseHeaders'); $reflection_method->setAccessible(true); $curl = new Curl(); $response_headers = $reflection_method->invoke($curl, $response); $this->assertArrayHasKey('Status-Line', $response_headers); } public function testArrayToStringConversion() { $test = new Test(); $test->server('post', 'POST', array( 'foo' => 'bar', 'baz' => array( ), )); $this->assertEquals('foo=bar&baz=', $test->curl->response); $test = new Test(); $test->server('post', 'POST', array( 'foo' => 'bar', 'baz' => array( 'qux' => array( ), ), )); $this->assertEquals('foo=bar&baz[qux]=', urldecode($test->curl->response)); $test = new Test(); $test->server('post', 'POST', array( 'foo' => 'bar', 'baz' => array( 'qux' => array( ), 'wibble' => 'wobble', ), )); $this->assertEquals('foo=bar&baz[qux]=&baz[wibble]=wobble', urldecode($test->curl->response)); } public function testSuccessCallback() { $before_send_called = false; $success_called = false; $error_called = false; $complete_called = false; $test = new Test(); $curl = $test->curl; $curl->setHeader('X-DEBUG-TEST', 'get'); $curl->beforeSend(function ($instance) use ( &$before_send_called, &$success_called, &$error_called, &$complete_called ) { \PHPUnit\Framework\Assert::assertInstanceOf('Curl\Curl', $instance); \PHPUnit\Framework\Assert::assertFalse($before_send_called); \PHPUnit\Framework\Assert::assertFalse($success_called); \PHPUnit\Framework\Assert::assertFalse($error_called); \PHPUnit\Framework\Assert::assertFalse($complete_called); $before_send_called = true; }); $curl->success(function ($instance) use ( &$before_send_called, &$success_called, &$error_called, &$complete_called ) { \PHPUnit\Framework\Assert::assertInstanceOf('Curl\Curl', $instance); \PHPUnit\Framework\Assert::assertTrue($before_send_called); \PHPUnit\Framework\Assert::assertFalse($success_called); \PHPUnit\Framework\Assert::assertFalse($error_called); \PHPUnit\Framework\Assert::assertFalse($complete_called); $success_called = true; }); $curl->error(function ($instance) use ( &$before_send_called, &$success_called, &$error_called, &$complete_called ) { $error_called = true; }); $curl->complete(function ($instance) use ( &$before_send_called, &$success_called, &$error_called, &$complete_called ) { \PHPUnit\Framework\Assert::assertInstanceOf('Curl\Curl', $instance); \PHPUnit\Framework\Assert::assertTrue($before_send_called); \PHPUnit\Framework\Assert::assertTrue($success_called); \PHPUnit\Framework\Assert::assertFalse($error_called); \PHPUnit\Framework\Assert::assertFalse($complete_called); $complete_called = true; }); $curl->get(Test::TEST_URL); $this->assertTrue($before_send_called); $this->assertTrue($success_called); $this->assertFalse($error_called); $this->assertTrue($complete_called); } public function testErrorCallback() { $before_send_called = false; $success_called = false; $error_called = false; $complete_called = false; $test = new Test(); $curl = $test->curl; $curl->setHeader('X-DEBUG-TEST', 'get'); $curl->setOpt(CURLOPT_CONNECTTIMEOUT_MS, 2000); $curl->beforeSend(function ($instance) use ( &$before_send_called, &$success_called, &$error_called, &$complete_called ) { \PHPUnit\Framework\Assert::assertInstanceOf('Curl\Curl', $instance); \PHPUnit\Framework\Assert::assertFalse($before_send_called); \PHPUnit\Framework\Assert::assertFalse($success_called); \PHPUnit\Framework\Assert::assertFalse($error_called); \PHPUnit\Framework\Assert::assertFalse($complete_called); $before_send_called = true; }); $curl->success(function ($instance) use ( &$before_send_called, &$success_called, &$error_called, &$complete_called ) { $success_called = true; }); $curl->error(function ($instance) use ( &$before_send_called, &$success_called, &$error_called, &$complete_called ) { \PHPUnit\Framework\Assert::assertInstanceOf('Curl\Curl', $instance); \PHPUnit\Framework\Assert::assertTrue($before_send_called); \PHPUnit\Framework\Assert::assertFalse($success_called); \PHPUnit\Framework\Assert::assertFalse($error_called); \PHPUnit\Framework\Assert::assertFalse($complete_called); $error_called = true; }); $curl->complete(function ($instance) use ( &$before_send_called, &$success_called, &$error_called, &$complete_called ) { \PHPUnit\Framework\Assert::assertInstanceOf('Curl\Curl', $instance); \PHPUnit\Framework\Assert::assertTrue($before_send_called); \PHPUnit\Framework\Assert::assertFalse($success_called); \PHPUnit\Framework\Assert::assertTrue($error_called); \PHPUnit\Framework\Assert::assertFalse($complete_called); $complete_called = true; }); $curl->get(Test::ERROR_URL); $this->assertTrue($before_send_called); $this->assertFalse($success_called); $this->assertTrue($error_called); $this->assertTrue($complete_called); } public function testClose() { $test = new Test(); $curl = $test->curl; $curl->setHeader('X-DEBUG-TEST', 'post'); $curl->post(Test::TEST_URL); $this->assertTrue(is_resource($curl->curl)); $curl->close(); $this->assertFalse(is_resource($curl->curl)); } /** * @expectedException \PHPUnit\Framework\Error\Warning */ public function testRequiredOptionCurlOptReturnTransferEmitsWarning() { $curl = new Curl(); $curl->setOpt(CURLOPT_RETURNTRANSFER, false); } public function testRequestMethodSuccessiveGetRequests() { $test = new Test(); $test->chainRequests('GET', 'POST'); $test->chainRequests('GET', 'PUT'); $test->chainRequests('GET', 'PATCH'); $test->chainRequests('GET', 'DELETE'); $test->chainRequests('GET', 'HEAD'); $test->chainRequests('GET', 'OPTIONS'); } public function testRequestMethodSuccessivePostRequests() { $test = new Test(); $test->chainRequests('POST', 'GET'); $test->chainRequests('POST', 'PUT'); $test->chainRequests('POST', 'PATCH'); $test->chainRequests('POST', 'DELETE'); $test->chainRequests('POST', 'HEAD'); $test->chainRequests('POST', 'OPTIONS'); } public function testRequestMethodSuccessivePutRequests() { $test = new Test(); $test->chainRequests('PUT', 'GET'); $test->chainRequests('PUT', 'POST'); $test->chainRequests('PUT', 'PATCH'); $test->chainRequests('PUT', 'DELETE'); $test->chainRequests('PUT', 'HEAD'); $test->chainRequests('PUT', 'OPTIONS'); } public function testRequestMethodSuccessivePatchRequests() { $test = new Test(); $test->chainRequests('PATCH', 'GET'); $test->chainRequests('PATCH', 'POST'); $test->chainRequests('PATCH', 'PUT'); $test->chainRequests('PATCH', 'DELETE'); $test->chainRequests('PATCH', 'HEAD'); $test->chainRequests('PATCH', 'OPTIONS'); } public function testRequestMethodSuccessiveDeleteRequests() { $test = new Test(); $test->chainRequests('DELETE', 'GET'); $test->chainRequests('DELETE', 'POST'); $test->chainRequests('DELETE', 'PUT'); $test->chainRequests('DELETE', 'PATCH'); $test->chainRequests('DELETE', 'HEAD'); $test->chainRequests('DELETE', 'OPTIONS'); } public function testRequestMethodSuccessiveHeadRequests() { $test = new Test(); $test->chainRequests('HEAD', 'GET'); $test->chainRequests('HEAD', 'POST'); $test->chainRequests('HEAD', 'PUT'); $test->chainRequests('HEAD', 'PATCH'); $test->chainRequests('HEAD', 'DELETE'); $test->chainRequests('HEAD', 'OPTIONS'); } public function testRequestMethodSuccessiveOptionsRequests() { $test = new Test(); $test->chainRequests('OPTIONS', 'GET'); $test->chainRequests('OPTIONS', 'POST'); $test->chainRequests('OPTIONS', 'PUT'); $test->chainRequests('OPTIONS', 'PATCH'); $test->chainRequests('OPTIONS', 'DELETE'); $test->chainRequests('OPTIONS', 'HEAD'); } public function testMemoryLeak() { // Skip memory leak test failing for PHP 7. // "Failed asserting that 8192 is less than 1000." if (getenv('TRAVIS_PHP_VERSION') === '7.0') { $this->markTestSkipped(); } ob_start(); echo '['; for ($i = 0; $i < 10; $i++) { if ($i >= 1) { echo ','; } echo '{"before":' . memory_get_usage() . ','; $curl = new Curl(); $curl->close(); echo '"after":' . memory_get_usage() . '}'; sleep(1); } echo ']'; $html = ob_get_contents(); ob_end_clean(); $results = json_decode($html, true); // Ensure memory does not leak excessively after instantiating a new // Curl instance and cleaning up. Memory diffs in the 2000-6000+ range // indicate a memory leak. $max_memory_diff = 1000; foreach ($results as $i => $result) { $memory_diff = $result['after'] - $result['before']; // Skip the first test to allow memory usage to settle. if ($i >= 1) { $this->assertLessThan($max_memory_diff, $memory_diff); } } } public function testAlternativeStandardErrorOutput() { // Skip test on HHVM due to "Segmentation fault". if (defined('HHVM_VERSION')) { $this->markTestSkipped(); } $buffer = fopen('php://memory', 'w+'); $curl = new Curl(); $curl->verbose(true, $buffer); $curl->post(Test::TEST_URL); rewind($buffer); $stderr = stream_get_contents($buffer); fclose($buffer); $this->assertNotEmpty($stderr); } public function testXMLDecoder() { $test = new Test(); $test->server('xml_with_cdata_response', 'POST'); $this->assertTrue(is_object($test->curl->response)); $this->assertInstanceOf('SimpleXMLElement', $test->curl->response); $this->assertFalse(strpos($test->curl->response->saveXML(), '<![CDATA[') === false); $test = new Test(); $test->curl->setXmlDecoder(function ($response) { return simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA); }); $test->server('xml_with_cdata_response', 'POST'); $this->assertTrue(is_object($test->curl->response)); $this->assertInstanceOf('SimpleXMLElement', $test->curl->response); $this->assertTrue(strpos($test->curl->response->saveXML(), '<![CDATA[') === false); $test = new Test(); $test->curl->setXmlDecoder(false); $test->server('xml_with_cdata_response', 'POST'); $this->assertTrue(is_string($test->curl->response)); } public function testDefaultDecoder() { // Default. $test = new Test(); $test->server('download_file_size', 'GET'); $this->assertTrue(is_string($test->curl->response)); // Callable. $test = new Test(); $test->curl->setDefaultDecoder(function ($response) { return '123'; }); $test->server('download_file_size', 'GET'); $this->assertEquals('123', $test->curl->response); // "json". $test = new Test(); $test->curl->setDefaultDecoder('json'); $test->server('json_response', 'POST', array( 'key' => 'Content-Type', 'value' => 'application/but-not-json', )); $this->assertInstanceOf('stdClass', $test->curl->response); // "xml". $test = new Test(); $test->curl->setDefaultDecoder('xml'); $test->server('xml_response', 'POST', array( 'key' => 'Content-Type', 'value' => 'text/but-not-xml', )); $this->assertInstanceOf('SimpleXMLElement', $test->curl->response); // False. $test = new Test(); $test->curl->setDefaultDecoder('json'); $test->curl->setDefaultDecoder(false); $test->server('json_response', 'POST', array( 'key' => 'Content-Type', 'value' => 'application/but-not-json', )); $this->assertTrue(is_string($test->curl->response)); } public function testTotalTime() { $test = new Test(); $test->server('request_method', 'GET'); $this->assertTrue(is_float($test->curl->totalTime)); } public function testOptionSet() { // Skip this test on 5.3, 5.4, and HHVM. if (version_compare(PHP_VERSION, '5.5.0', '<') || defined('HHVM_VERSION')) { $this->markTestSkipped(); } $option = CURLOPT_ENCODING; $value = 'gzip'; $null = chr(0); // Ensure the option is stored when curl_setopt() succeeds. $curl = new Curl(); $success = $curl->setOpt($option, $value); $this->assertTrue($success); $this->assertEquals($value, $curl->getOpt($option)); // Ensure the option is not stored when curl_setopt() fails. Make curl_setopt() return false and suppress // errors. Triggers warning: "curl_setopt(): Curl option contains invalid characters (\0)". $curl = new Curl(); $success = @$curl->setOpt($option, $null); $this->assertFalse($success); $this->assertNull($curl->getOpt($option)); // Ensure options following a Curl::setOpt() failure are not set when using Curl::setOpts(). $options = array( $option => $null, CURLOPT_COOKIE => 'a=b', ); $curl = new Curl(); $success = @$curl->setOpts($options); $this->assertFalse($success); $this->assertNull($curl->getOpt(CURLOPT_COOKIE)); // Ensure Curl::setOpts() returns true when all options are successfully set. $options = array( CURLOPT_COOKIE => 'a=b', CURLOPT_FOLLOWLOCATION => true, CURLOPT_VERBOSE => true, ); $curl = new Curl(); $success = $curl->setOpts($options); $this->assertTrue($success); $this->assertEquals('a=b', $curl->getOpt(CURLOPT_COOKIE)); $this->assertTrue($curl->getOpt(CURLOPT_FOLLOWLOCATION)); $this->assertTrue($curl->getOpt(CURLOPT_VERBOSE)); } public function testBuildUrlArgs() { $tests = array( array( 'args' => array( 'url' => 'https://www.example.com/', 'mixed_data' => null, ), 'expected' => 'https://www.example.com/', ), array( 'args' => array( 'url' => 'https://www.example.com/', 'mixed_data' => '', ), 'expected' => 'https://www.example.com/', ), array( 'args' => array( 'url' => 'https://www.example.com/', 'mixed_data' => array(), ), 'expected' => 'https://www.example.com/', ), array( 'args' => array( 'url' => 'https://www.example.com/', 'mixed_data' => array( 'a' => '1', 'b' => '2', 'c' => '3', ), ), 'expected' => 'https://www.example.com/?a=1&b=2&c=3', ), array( 'args' => array( 'url' => 'https://www.example.com/', 'mixed_data' => 'user_ids=user_1,user_2', ), 'expected' => 'https://www.example.com/?user_ids=user_1,user_2', ), ); foreach ($tests as $test) { $curl_1 = new Curl(); $reflector = new \ReflectionObject($curl_1); $method = $reflector->getMethod('buildUrl'); $method->setAccessible(true); $actual_url = $method->invoke($curl_1, $test['args']['url'], $test['args']['mixed_data']); $this->assertEquals($test['expected'], $actual_url); $curl_2 = new Curl(); $curl_2->setUrl($test['args']['url'], $test['args']['mixed_data']); $this->assertEquals($test['expected'], $curl_2->url); } } public function testBuildUrlArgSeparator() { $base_url = 'https://www.example.com/path'; $data = array( 'arg' => 'value', 'another' => 'one', ); $expected_url = $base_url . '?arg=value&another=one'; foreach (array(false, '&', '&') as $arg_separator) { if ($arg_separator) { ini_set('arg_separator.output', $arg_separator); } $curl = new Curl(); $reflector = new \ReflectionObject($curl); $method = $reflector->getMethod('buildUrl'); $method->setAccessible(true); $actual_url = $method->invoke($curl, $base_url, $data); $this->assertEquals($expected_url, $actual_url); } } public function testUnsetHeader() { $request_key = 'X-Request-Id'; $request_value = '1'; $data = array( 'test' => 'server', 'key' => 'HTTP_X_REQUEST_ID', ); $curl = new Curl(); $curl->setHeader($request_key, $request_value); $curl->get(Test::TEST_URL, $data); $this->assertEquals($request_value, $curl->response); $curl = new Curl(); $curl->setHeader($request_key, $request_value); $curl->unsetHeader($request_key); $curl->get(Test::TEST_URL, $data); $this->assertEquals('', $curl->response); } public function testGetInfo() { $test = new Test(); $test->server('server', 'GET'); $info = $test->curl->getInfo(); $expected_keys = array( 'url', 'content_type', 'http_code', 'header_size', 'request_size', 'filetime', 'ssl_verify_result', 'redirect_count', 'total_time', 'namelookup_time', 'connect_time', 'pretransfer_time', 'size_upload', 'size_download', 'speed_download', 'speed_upload', 'download_content_length', 'upload_content_length', 'starttransfer_time', 'redirect_time', 'certinfo', 'primary_ip', 'primary_port', 'local_ip', 'local_port', 'redirect_url', 'request_header', ); // Not all keys are included on PHP 5.3 (tested 5.3.29). if (version_compare(PHP_VERSION, '5.4.0', '<')) { foreach (array('primary_ip', 'primary_port', 'local_ip', 'local_port') as $value) { $key = array_search($value, $expected_keys); unset($expected_keys[$key]); } } // Not all keys are included on HHVM (tested 3.6.6). if (defined('HHVM_VERSION')) { foreach (array('certinfo', 'primary_ip', 'primary_port', 'local_ip', 'redirect_url') as $value) { $key = array_search($value, $expected_keys); unset($expected_keys[$key]); } } foreach ($expected_keys as $key) { $this->assertArrayHasKey($key, $info); } } }