diff options
Diffstat (limited to 'ext/standard/tests/http')
-rw-r--r-- | ext/standard/tests/http/bug38802.phpt | 174 | ||||
-rw-r--r-- | ext/standard/tests/http/bug43510.phpt | 30 | ||||
-rw-r--r-- | ext/standard/tests/http/bug48929.phpt | 58 | ||||
-rw-r--r-- | ext/standard/tests/http/bug53198.phpt | 57 | ||||
-rw-r--r-- | ext/standard/tests/http/bug60570.phpt | 53 | ||||
-rw-r--r-- | ext/standard/tests/http/ignore_errors.phpt | 126 | ||||
-rw-r--r-- | ext/standard/tests/http/server.inc | 92 |
7 files changed, 590 insertions, 0 deletions
diff --git a/ext/standard/tests/http/bug38802.phpt b/ext/standard/tests/http/bug38802.phpt new file mode 100644 index 0000000..73b4118 --- /dev/null +++ b/ext/standard/tests/http/bug38802.phpt @@ -0,0 +1,174 @@ +--TEST-- +Bug #38802 (ignore_errors and max_redirects) +--INI-- +allow_url_fopen=1 +--SKIPIF-- +<?php require 'server.inc'; http_server_skipif('tcp://127.0.0.1:12342'); ?> +--FILE-- +<?php +require 'server.inc'; + +function do_test($context_options) { + + $context = stream_context_create(array('http' => $context_options)); + + $responses = array( + "data://text/plain,HTTP/1.0 302 Moved Temporarily\r\nLocation: http://127.0.0.1:12342/foo/bar2\r\n\r\n1", + "data://text/plain,HTTP/1.0 301 Moved Permanently\r\nLocation: http://127.0.0.1:12342/foo/bar3\r\n\r\n", + "data://text/plain,HTTP/1.0 302 Moved Temporarily\r\nLocation: http://127.0.0.1:12342/foo/bar4\r\n\r\n3", + "data://text/plain,HTTP/1.0 200 OK\r\n\r\ndone.", + ); + + $pid = http_server("tcp://127.0.0.1:12342", $responses, $output); + + $fd = fopen('http://127.0.0.1:12342/foo/bar', 'rb', false, $context); + var_dump($fd); + + if ($fd) { + $meta_data = stream_get_meta_data($fd); + var_dump($meta_data['wrapper_data']); + + var_dump(stream_get_contents($fd)); + } + + fseek($output, 0, SEEK_SET); + var_dump(stream_get_contents($output)); + + http_server_kill($pid); +} + +echo "-- Test: follow all redirections --\n"; + +do_test(array(), 4); + +echo "-- Test: fail after 2 redirections --\n"; + +do_test(array('max_redirects' => 2), 2); + +echo "-- Test: fail at first redirection --\n"; + +do_test(array('max_redirects' => 0), 1); + +echo "-- Test: fail at first redirection (2) --\n"; + +do_test(array('max_redirects' => 1), 1); + +echo "-- Test: return at first redirection --\n"; + +do_test(array('max_redirects' => 0, 'ignore_errors' => 1), 1); + +echo "-- Test: return at first redirection (2) --\n"; + +do_test(array('max_redirects' => 1, 'ignore_errors' => 1), 1); + +echo "-- Test: return at second redirection --\n"; + +do_test(array('max_redirects' => 2, 'ignore_errors' => 1), 2); + +?> +--EXPECTF-- +-- Test: follow all redirections -- +resource(%d) of type (stream) +array(7) { + [0]=> + string(30) "HTTP/1.0 302 Moved Temporarily" + [1]=> + string(41) "Location: http://127.0.0.1:12342/foo/bar2" + [2]=> + string(30) "HTTP/1.0 301 Moved Permanently" + [3]=> + string(41) "Location: http://127.0.0.1:12342/foo/bar3" + [4]=> + string(30) "HTTP/1.0 302 Moved Temporarily" + [5]=> + string(41) "Location: http://127.0.0.1:12342/foo/bar4" + [6]=> + string(15) "HTTP/1.0 200 OK" +} +string(5) "done." +string(195) "GET /foo/bar HTTP/1.0 +Host: 127.0.0.1:12342 + +GET /foo/bar2 HTTP/1.0 +Host: 127.0.0.1:12342 + +GET /foo/bar3 HTTP/1.0 +Host: 127.0.0.1:12342 + +GET /foo/bar4 HTTP/1.0 +Host: 127.0.0.1:12342 + +" +-- Test: fail after 2 redirections -- + +Warning: fopen(http://127.0.0.1:12342/foo/bar): failed to open stream: Redirection limit reached, aborting in %s +bool(false) +string(97) "GET /foo/bar HTTP/1.0 +Host: 127.0.0.1:12342 + +GET /foo/bar2 HTTP/1.0 +Host: 127.0.0.1:12342 + +" +-- Test: fail at first redirection -- + +Warning: fopen(http://127.0.0.1:12342/foo/bar): failed to open stream: Redirection limit reached, aborting in %s +bool(false) +string(48) "GET /foo/bar HTTP/1.0 +Host: 127.0.0.1:12342 + +" +-- Test: fail at first redirection (2) -- + +Warning: fopen(http://127.0.0.1:12342/foo/bar): failed to open stream: Redirection limit reached, aborting in %s +bool(false) +string(48) "GET /foo/bar HTTP/1.0 +Host: 127.0.0.1:12342 + +" +-- Test: return at first redirection -- +resource(%d) of type (stream) +array(2) { + [0]=> + string(30) "HTTP/1.0 302 Moved Temporarily" + [1]=> + string(41) "Location: http://127.0.0.1:12342/foo/bar2" +} +string(1) "1" +string(48) "GET /foo/bar HTTP/1.0 +Host: 127.0.0.1:12342 + +" +-- Test: return at first redirection (2) -- +resource(%d) of type (stream) +array(2) { + [0]=> + string(30) "HTTP/1.0 302 Moved Temporarily" + [1]=> + string(41) "Location: http://127.0.0.1:12342/foo/bar2" +} +string(1) "1" +string(48) "GET /foo/bar HTTP/1.0 +Host: 127.0.0.1:12342 + +" +-- Test: return at second redirection -- +resource(%d) of type (stream) +array(4) { + [0]=> + string(30) "HTTP/1.0 302 Moved Temporarily" + [1]=> + string(41) "Location: http://127.0.0.1:12342/foo/bar2" + [2]=> + string(30) "HTTP/1.0 301 Moved Permanently" + [3]=> + string(41) "Location: http://127.0.0.1:12342/foo/bar3" +} +string(0) "" +string(97) "GET /foo/bar HTTP/1.0 +Host: 127.0.0.1:12342 + +GET /foo/bar2 HTTP/1.0 +Host: 127.0.0.1:12342 + +" diff --git a/ext/standard/tests/http/bug43510.phpt b/ext/standard/tests/http/bug43510.phpt new file mode 100644 index 0000000..d973612 --- /dev/null +++ b/ext/standard/tests/http/bug43510.phpt @@ -0,0 +1,30 @@ +--TEST-- +Bug #43510 (stream_get_meta_data() does not return same mode as used in fopen) +--INI-- +allow_url_fopen=1 +--SKIPIF-- +<?php require 'server.inc'; http_server_skipif('tcp://127.0.0.1:12342'); ?> +--FILE-- +<?php +require 'server.inc'; + +$responses = array( + "data://text/plain,HTTP/1.0 200 OK\r\n\r\n", + "data://text/plain,HTTP/1.0 200 OK\r\n\r\n", +); + +$pid = http_server("tcp://127.0.0.1:12342", $responses, $output); + +foreach(array('r', 'rb') as $mode) { + $fd = fopen('http://127.0.0.1:12342/', $mode, false); + $meta = stream_get_meta_data($fd); + var_dump($meta['mode']); + fclose($fd); +} + +http_server_kill($pid); + +?> +--EXPECT-- +string(1) "r" +string(2) "rb" diff --git a/ext/standard/tests/http/bug48929.phpt b/ext/standard/tests/http/bug48929.phpt new file mode 100644 index 0000000..2d1e459 --- /dev/null +++ b/ext/standard/tests/http/bug48929.phpt @@ -0,0 +1,58 @@ +--TEST-- +Bug #48929 (duplicate \r\n sent after last header line) +--INI-- +allow_url_fopen=1 +--SKIPIF-- +<?php require 'server.inc'; http_server_skipif('tcp://127.0.0.1:12342'); ?> +--FILE-- +<?php +require 'server.inc'; + +function do_test($context_options) { + + $context = stream_context_create(array('http' => $context_options)); + + $responses = array( + "data://text/plain,HTTP/1.0 200 OK\r\n\r\n", + ); + + $pid = http_server("tcp://127.0.0.1:12342", $responses, $output); + + foreach($responses as $r) { + + $fd = fopen('http://127.0.0.1:12342/', 'rb', false, $context); + + fseek($output, 0, SEEK_SET); + var_dump(stream_get_contents($output)); + fseek($output, 0, SEEK_SET); + } + + http_server_kill($pid); +} + +echo "-- Test: requests with 'header' as array --\n"; + +do_test(array('header' => array('X-Foo: bar', 'Content-Type: text/plain'), 'method' => 'POST', 'content' => 'ohai')); + +echo "-- Test: requests with 'header' as string --\n"; + +do_test(array('header' => "X-Foo: bar\r\nContent-Type: text/plain", 'method' => 'POST', 'content' => 'ohai')); + +?> +--EXPECT-- +-- Test: requests with 'header' as array -- +string(103) "POST / HTTP/1.0 +Host: 127.0.0.1:12342 +Content-Length: 4 +X-Foo: bar +Content-Type: text/plain + +ohai" +-- Test: requests with 'header' as string -- +string(103) "POST / HTTP/1.0 +Host: 127.0.0.1:12342 +Content-Length: 4 +X-Foo: bar +Content-Type: text/plain + +ohai" diff --git a/ext/standard/tests/http/bug53198.phpt b/ext/standard/tests/http/bug53198.phpt new file mode 100644 index 0000000..3c640fa --- /dev/null +++ b/ext/standard/tests/http/bug53198.phpt @@ -0,0 +1,57 @@ +--TEST-- +Bug #53198 (From: header cannot be changed with ini_set) +--SKIPIF-- +<?php require 'server.inc'; http_server_skipif('tcp://127.0.0.1:12342'); ?> +--INI-- +allow_url_fopen=1 +from=teste@teste.pt +--FILE-- +<?php +require 'server.inc'; + +function do_test() { + + $responses = array( + "data://text/plain,HTTP/1.0 200 OK\r\n\r\n", + ); + + $pid = http_server("tcp://127.0.0.1:12342", $responses, $output); + + foreach($responses as $r) { + + $fd = fopen('http://127.0.0.1:12342/', 'rb', false); + + fseek($output, 0, SEEK_SET); + var_dump(stream_get_contents($output)); + fseek($output, 0, SEEK_SET); + } + + http_server_kill($pid); + +} + +echo "-- Test: leave default --\n"; + +do_test(); + +echo "-- Test: after ini_set --\n"; + +ini_set('from', 'junk@junk.com'); + +do_test(); + +?> +--EXPECT-- +-- Test: leave default -- +string(63) "GET / HTTP/1.0 +From: teste@teste.pt +Host: 127.0.0.1:12342 + +" +-- Test: after ini_set -- +string(62) "GET / HTTP/1.0 +From: junk@junk.com +Host: 127.0.0.1:12342 + +" + diff --git a/ext/standard/tests/http/bug60570.phpt b/ext/standard/tests/http/bug60570.phpt new file mode 100644 index 0000000..d1784b0 --- /dev/null +++ b/ext/standard/tests/http/bug60570.phpt @@ -0,0 +1,53 @@ +--TEST-- +Bug #60570 (Stream context leaks when http request fails) +--SKIPIF-- +<?php require 'server.inc'; http_server_skipif('tcp://127.0.0.1:12342'); ?> +--INI-- +allow_url_fopen=1 +allow_url_include=1 +--FILE-- +<?php +require 'server.inc'; + +function do_test() { + + $responses = array( + "data://text/plain,HTTP/1.0 404 Not Found\r\n\r\n", + "data://text/plain,HTTP/1.0 404 Not Found\r\n\r\n", + "data://text/plain,HTTP/1.0 404 Not Found\r\n\r\n" + ); + + $pid = http_server("tcp://127.0.0.1:12342", $responses, $output); + + $a = $b = null; + + $i = 3; + while ($i--) { + $context = stream_context_create(array('http'=>array('timeout'=>1))); + file_get_contents('http://127.0.0.1:12342/', 0, $context); + unset($context); + + $b = $a; + $a = memory_get_usage(); + } + + http_server_kill($pid); + + echo "leak? penultimate iteration: $b, last one: $a\n"; + var_dump($a == $b); +} + +do_test(); + +--EXPECTF-- +Warning: file_get_contents(http://127.0.0.1:12342/): failed to open stream: HTTP request failed! HTTP/1.0 404 Not Found + in %s on line %d + +Warning: file_get_contents(http://127.0.0.1:12342/): failed to open stream: HTTP request failed! HTTP/1.0 404 Not Found + in %s on line %d + +Warning: file_get_contents(http://127.0.0.1:12342/): failed to open stream: HTTP request failed! HTTP/1.0 404 Not Found + in %s on line %d +leak? penultimate iteration: %d, last one: %d +bool(true) + diff --git a/ext/standard/tests/http/ignore_errors.phpt b/ext/standard/tests/http/ignore_errors.phpt new file mode 100644 index 0000000..ab54218 --- /dev/null +++ b/ext/standard/tests/http/ignore_errors.phpt @@ -0,0 +1,126 @@ +--TEST-- +http:// and ignore_errors +--INI-- +allow_url_fopen=1 +--SKIPIF-- +<?php require 'server.inc'; http_server_skipif('tcp://127.0.0.1:12342'); ?> +--FILE-- +<?php +require 'server.inc'; + +function do_test($context_options) { + + $context = stream_context_create(array('http' => $context_options)); + + $responses = array( + "data://text/plain,HTTP/1.0 200 Ok\r\nX-Foo: bar\r\n\r\n1", + "data://text/plain,HTTP/1.0 404 Not found\r\nX-bar: baz\r\n\r\n2", + ); + + $pid = http_server("tcp://127.0.0.1:12342", $responses, $output); + + foreach($responses as $r) { + + $fd = fopen('http://127.0.0.1:12342/foo/bar', 'rb', false, $context); + var_dump($fd); + + if ($fd) { + $meta_data = stream_get_meta_data($fd); + var_dump($meta_data['wrapper_data']); + + var_dump(stream_get_contents($fd)); + } + + fseek($output, 0, SEEK_SET); + var_dump(stream_get_contents($output)); + fseek($output, 0, SEEK_SET); + } + + http_server_kill($pid); +} + +echo "-- Test: requests without ignore_errors --\n"; + +do_test(array()); + +echo "-- Test: requests with ignore_errors --\n"; + +do_test(array('ignore_errors' => true)); + +echo "-- Test: requests with ignore_errors (2) --\n"; + +do_test(array('ignore_errors' => 1)); + +?> +--EXPECTF-- +-- Test: requests without ignore_errors -- +resource(%d) of type (stream) +array(2) { + [0]=> + string(15) "HTTP/1.0 200 Ok" + [1]=> + string(10) "X-Foo: bar" +} +string(1) "1" +string(48) "GET /foo/bar HTTP/1.0 +Host: 127.0.0.1:12342 + +" + +Warning: fopen(http://127.0.0.1:12342/foo/bar): failed to open stream: HTTP request failed! HTTP/1.0 404 Not found + in %s on line %d +bool(false) +string(48) "GET /foo/bar HTTP/1.0 +Host: 127.0.0.1:12342 + +" +-- Test: requests with ignore_errors -- +resource(%d) of type (stream) +array(2) { + [0]=> + string(15) "HTTP/1.0 200 Ok" + [1]=> + string(10) "X-Foo: bar" +} +string(1) "1" +string(48) "GET /foo/bar HTTP/1.0 +Host: 127.0.0.1:12342 + +" +resource(%d) of type (stream) +array(2) { + [0]=> + string(22) "HTTP/1.0 404 Not found" + [1]=> + string(10) "X-bar: baz" +} +string(1) "2" +string(48) "GET /foo/bar HTTP/1.0 +Host: 127.0.0.1:12342 + +" +-- Test: requests with ignore_errors (2) -- +resource(%d) of type (stream) +array(2) { + [0]=> + string(15) "HTTP/1.0 200 Ok" + [1]=> + string(10) "X-Foo: bar" +} +string(1) "1" +string(48) "GET /foo/bar HTTP/1.0 +Host: 127.0.0.1:12342 + +" +resource(%d) of type (stream) +array(2) { + [0]=> + string(22) "HTTP/1.0 404 Not found" + [1]=> + string(10) "X-bar: baz" +} +string(1) "2" +string(48) "GET /foo/bar HTTP/1.0 +Host: 127.0.0.1:12342 + +" diff --git a/ext/standard/tests/http/server.inc b/ext/standard/tests/http/server.inc new file mode 100644 index 0000000..b9ade0e --- /dev/null +++ b/ext/standard/tests/http/server.inc @@ -0,0 +1,92 @@ +<?php + +function http_server_skipif($socket_string) { + + if (!function_exists('pcntl_fork')) die('skip pcntl_fork() not available'); + if (!function_exists('posix_kill')) die('skip posix_kill() not available'); + if (!stream_socket_server($socket_string)) die('skip stream_socket_server() failed'); +} + +/* Minimal HTTP server with predefined responses. + * + * $socket_string is the socket to create and listen on (e.g. tcp://127.0.0.1:1234) + * $files is an array of files containing N responses for N expected requests. Server dies after N requests. + * $output is a stream on which everything sent by clients is written to + */ +function http_server($socket_string, array $files, &$output = null) { + + pcntl_alarm(60); + + $server = stream_socket_server($socket_string, $errno, $errstr); + if (!$server) { + return false; + } + + if ($output === null) { + $output = tmpfile(); + if ($output === false) { + return false; + } + } + + $pid = pcntl_fork(); + if ($pid == -1) { + die('could not fork'); + } else if ($pid) { + return $pid; + } + + foreach($files as $file) { + + $sock = stream_socket_accept($server); + if (!$sock) { + exit(1); + } + + // read headers + + $content_length = 0; + + stream_set_blocking($sock, 0); + while (!feof($sock)) { + + list($r, $w, $e) = array(array($sock), null, null); + if (!stream_select($r, $w, $e, 1)) continue; + + $line = stream_get_line($sock, 8192, "\r\n"); + if ($line === b'') { + fwrite($output, b"\r\n"); + break; + } else if ($line !== false) { + fwrite($output, b"$line\r\n"); + + if (preg_match(b'#^Content-Length\s*:\s*([[:digit:]]+)\s*$#i', $line, $matches)) { + $content_length = (int) $matches[1]; + } + } + } + stream_set_blocking($sock, 1); + + // read content + + if ($content_length > 0) { + stream_copy_to_stream($sock, $output, $content_length); + } + + // send response + + $fd = fopen($file, 'rb'); + stream_copy_to_stream($fd, $sock); + + fclose($sock); + } + + exit(0); +} + +function http_server_kill($pid) { + posix_kill($pid, SIGTERM); + pcntl_waitpid($pid, $status); +} + +?> |