m6w6 / ext-http Goto Github PK
View Code? Open in Web Editor NEWExtended HTTP Support
License: BSD 2-Clause "Simplified" License
Extended HTTP Support
License: BSD 2-Clause "Simplified" License
Given the following trivial test program that always sends a cookie "test" and, if Cookie "test" was received, the additional cookie "test2":
<?php if (!empty($_COOKIE["test"])) setcookie("test2", $_COOKIE["test"]); setcookie("test", "1"); echo "done";
Then ext-httpd 3.0.1 unexpectedly sends the "test" cookie in the second request of the test program below:
<?php
$url = 'http://192.168.56.1:14080/cookie.php';
foreach (array('a', 'B') as $id) {
$client = new http\Client('curl', $id);
$req1 = new http\Client\Request('GET', $url);
$client->enqueue($req1);
$client->send();
$response1 = $client->getResponse($req1);
fprintf(STDERR, ">%s<\n", print_r($response1->getHeaders(), true));
printf("curl: %s http: %s\n\n\n", $response1->getTransferInfo('curlcode'), $response1->getTransferInfo('response_code'));
}
i.e. the output contains test2=1
, although the persistent handle was different for each request, and both client and request were new objects:
[Set-Cookie] => Array
(
[0] => test2=1
[1] => test=1
)
This bahaviour is not present if no persistent handle id is used.
Hi,
Previously (v 1.7.3) there was always Content-Length header with all POST requests, even with empty post body. What rationale was behind the decision to do not include this header with empty POSTs in 2.X version?
Our issue is that couple API clients stop working after migration, because most of the servers require this header even with empty POSTs (For example most of the Microsoft API endpoints).
According to RFC, nothing bad in including "Content-Length: 0" for empty requests.
Regards,
Igor
Also - where is the right place to ask this question?
The following somewhat weird program crashes reproducibly. $url
points to a server secured by Basic auth. As I don't provide any credentials the expected response is 401
.
I won't publish the URL here but will send it to you via mail if you should need it.
<?php
$url = 'https://...if needed I will provide the URL on request...';
$request = new http\Client\Request('GET', $url);
// If compression is deactivated, it won't crash.
$request->setOptions([ 'compress' => true ]);
// If this function code is inlined it won't crash.
function send(http\Client\Request $request) {
$client = new http\Client();
$client->enqueue($request);
$client->send();
$x = // If this line is removed it won't crash.
$client->getResponse($request);
}
send($request);
$client2 = new http\Client();
$request2 = new http\Client\Request('GET', 'http://example.com/');
$client2->enqueue($request2);
$client2->send(); // >>>>>>>> Crash!
print("OK\n");
Program received signal SIGSEGV, Segmentation fault.
zend_mm_alloc_small (bin_num=5, size=<optimized out>, heap=0x7ffff3600040) at /build/php-7.0.7/Zend/zend_alloc.c:1295
1295 heap->free_slot[bin_num] = p->next_free_slot;
(gdb) bt
#0 zend_mm_alloc_small (bin_num=5, size=<optimized out>, heap=0x7ffff3600040) at /build/php-7.0.7/Zend/zend_alloc.c:1295
#1 zend_mm_alloc_heap (size=<optimized out>, heap=0x7ffff3600040) at /build/php-7.0.7/Zend/zend_alloc.c:1366
#2 _emalloc (size=<optimized out>) at /build/php-7.0.7/Zend/zend_alloc.c:2450
#3 0x00007ffff2d86aa0 in zend_string_alloc (persistent=0, len=19) at /home/joe/FIT/git/dist/include/php/Zend/zend_string.h:121
#4 zend_string_init (persistent=0, len=19, str=0xe64260 "http://example.com/") at /home/joe/FIT/git/dist/include/php/Zend/zend_string.h:157
#5 php_http_curle_get_info (info=0x7ffff3656498, ch=0xe7aab0) at /build/pecl_http-3.1.0-dev/src/php_http_client_curl.c:347
#6 php_http_client_curl_getopt (h=<optimized out>, opt=<optimized out>, arg=<optimized out>, res=0x7fffffffa0d8)
at /build/pecl_http-3.1.0-dev/src/php_http_client_curl.c:2565
#7 0x00007ffff2d85a77 in php_http_client_getopt (h=h@entry=0x7ffff3677480, opt=opt@entry=PHP_HTTP_CLIENT_OPT_TRANSFER_INFO, arg=<optimized out>,
res_ptr=res_ptr@entry=0x7fffffffa0d8) at /build/pecl_http-3.1.0-dev/src/php_http_client.c:322
#8 0x00007ffff2d8606d in handle_response (arg=<optimized out>, client=0x7ffff3677480, e=0x7ffff3689048, response=<optimized out>)
at /build/pecl_http-3.1.0-dev/src/php_http_client.c:410
#9 0x00007ffff2d8bd2d in php_http_curlm_responsehandler (context=0x7ffff3677480)
at /build/pecl_http-3.1.0-dev/src/php_http_client_curl.c:715
#10 php_http_client_curl_once (h=h@entry=0x7ffff3677480) at /build/pecl_http-3.1.0-dev/src/php_http_client_curl.c:2446
#11 0x00007ffff2d8bf64 in php_http_client_curl_exec (h=0x7ffff3677480) at /build/pecl_http-3.1.0-dev/src/php_http_client_curl.c:2474
#12 0x00007ffff2d8544c in php_http_client_exec (h=<optimized out>) at /build/pecl_http-3.1.0-dev/src/php_http_client.c:294
#13 0x00007ffff2d854ed in zim_HttpClient_send (execute_data=0x7ffff36141b0, return_value=0x7ffff36141a0)
at /build/pecl_http-3.1.0-dev/src/php_http_client.c:788
#14 0x0000000000760f1a in ZEND_DO_FCALL_SPEC_HANDLER () at /build/php-7.0.7/Zend/zend_vm_execute.h:842
#15 0x000000000072bfb2 in execute_ex (ex=<optimized out>) at /build/php-7.0.7/Zend/zend_vm_execute.h:414
#16 0x000000000077f4dc in zend_execute (op_array=0x7ffff365d780, return_value=0x0) at /build/php-7.0.7/Zend/zend_vm_execute.h:458
#17 0x00000000006db40e in zend_execute_scripts (type=type@entry=8, retval=0x7ffff3614030, retval@entry=0x0, file_count=file_count@entry=3)
at /build/php-7.0.7/Zend/zend.c:1427
#18 0x000000000066c136 in php_execute_script (primary_file=primary_file@entry=0x7fffffffc790) at /build/php-7.0.7/main/main.c:2494
#19 0x0000000000780c4d in do_cli (argc=argc@entry=2, argv=argv@entry=0xcdbe00) at /build/php-7.0.7/sapi/cli/php_cli.c:974
#20 0x00000000007819aa in main (argc=2, argv=0xcdbe00) at /build/php-7.0.7/sapi/cli/php_cli.c:1344
Besides a couple of memory leaks valgrind
complains about Conditional jump or move depends on uninitialised value(s)
and Use of uninitialised value of size 8
.
I'm using master
(74e7358).
I have installed http and required extension on ubuntu 16.04
PHP Version 7.0
getting this error
/usr/sbin/apache2: symbol lookup error: /usr/lib/php/20151012/http.so: undefined symbol: uidna_IDNToASCII
thanks
<?php
$url = 'https://de.wikipedia.org/w/index.php?title=%';
$client = new http\Client();
$request = new http\Client\Request('GET', $url);
$client->enqueue($request);
throws an exception
$ php -ddisplay_errors=1 /tmp/test.php
Warning: http\Client\Request::__construct(): Failed to parse query; invalid percent encoding at pos 6 in 'title=%' in /tmp/test.php on line 6
Warning: http\Client\Request::__construct(): Failed to parse URL query: '%' in /tmp/test.php on line 6
Fatal error: Uncaught http\Exception\RuntimeException: http\Client::enqueue(): Cannot request empty URL in /tmp/test.php:7
Stack trace:
#0 /tmp/test.php(7): http\Client->enqueue(Object(http\Client\Request))
#1 {main}
thrown in /tmp/test.php on line 7
Compared to the behavior of other clients (Firefox, Chrome, curl, wget) the URL parsing appears to be too strict here. So for consistency with other clients, %
characters not followed by two hex digits should be silently treated as %25
.
A client with persistent handle sends requests to unexpected hosts when using the pre-populated DNS cache via the resolve
option:
<?php
$request = new http\Client\Request('GET', 'http://example.com/');
$client = new http\Client('curl', 'persistentID');
$client->enqueue($request);
$client->send(); // opens persistent connection to example.com
$request2 = new http\Client\Request('GET', 'http://example.com/');
$options = [ 'resolve' => ['example.com:80:127.0.0.1'] ];
$request2->setOptions($options); // remap example.com to 127.0.0.1
$client->enqueue($request2);
$client->send(); // Unexpectedly re-uses handle, issues 2nd request to example.com
print(substr($client->getResponse($request2)->getBody(), 0, 150));
I expected it to open a fresh connection when the resolve
option is actually effective.
I want to send using only 1 client instance lot of requests (100000) using enqueue() + a callback and a send() each 50 requests, but memory keeps constantly growing despite that finished requests are dequeued (count() is never above 50), only a call reset() on client (or destroy then recreate client instance) seems to free memory... it seems to keep references of finished requests is that a normal behaviour? php script is at 128MB around 1500 requests...
Tested on 2.5.5 version with PHP 5.6
I keep getting this message even though i have installed all necessary dependancies.
Trying to set URL like https://foo_bar-bucket.s3.amazonaws.com
causes an error: http\Message::setRequestUrl(): Failed to parse IDN; ICU error 66563
.
While cURL
works correctly with such domain names.
Trying to load http://www.köln.de
punycode encoded results in warnings and fatal errors.
<?php
$url = 'http://www.xn--kln-sna.de';
$req = new \http\Client\Request('GET', $url);
$client = (new \http\Client())->enqueue($req)->send();
PHP Warning: http\Client\Request::__construct(): Failed to parse host; unexpected '-' at pos 7 in 'www.xn--kln-sna.de'
PHP Fatal error: Uncaught http\Exception\RuntimeException: http\Client::enqueue(): Cannot request empty URL
Stack trace:
#0 ...: http\Client->enqueue(Object(http\Client\Request))
#1 {main}
wrt SSL, UNIX_SOCKETS, etc. pp.
$url = new http\Url("http://www.example.com/?x=a|b");
The above code results in a fatal error:
Uncaught exception 'http\Exception\BadUrlException' with message 'http\Url::__construct(): Failed to parse query; unexpected byte 0x7c at pos 3 in 'x=a|b''
However, pipe characters are valid in URLs, and widely used (for example by Google).
In general -- I would be in favour of making http\Url::__construct() as tolerant as possible, even when you pass an invalid URL to the constructor, the object should do its best to parse as much from it as is reasonably possible.
Since the behaviour of ssl/cainfo and ssl/capath depends on the SSL backend used by curl, it would be useful to be able to retrieve this information at runtime. With ext/curl, curl_version() could be used, I'm not aware of any equivalent function in pecl_http.
Were procedural functions removed from the new version? (3.0)
http\Url
class.Steps to reproduce: If you create apache site with document root pointed to the directory with this file test.php
and open an url http://localhost/test.php
it behaves incorrectly.
//test.php
use http\Url;
$url2 = new Url('http://foo.bar');
$url2->port = '123';
var_dump("$url2");
string 'http://foo.bar:123/test.php' (length=27)
If you use cli to run php ./test.php it works well returning string(19) "http://foo.bar:123/"
As of 3.0.1, ext-http cannot send multiple header fields with identical names, e.g.
$request->setHeaders('Foo' => Array(0 => 'aaa', 1 => 'bbb')));
results in a log message ("PHP Notice: Array to string conversion in ..../pecl_http.php on line 27") and a request that sends a header:
Foo: Array
While headers (excluding a few documented exceptions) can be combined into comma separated lists, not all servers / web applications handle this properly, therefore it is desirable to be able to actually send multiple header fields instead of combining them.
See https://apps.fedoraproject.org/koschei/package/php-pecl-http
TEST 29/182 [tests/client021.phpt]
========DIFF========
007+ Set-Cookie: counter=1;
007- Set-Cookie: counter=2;
011+ Set-Cookie: counter=1;
011- Set-Cookie: counter=3;
015+ Set-Cookie: counter=1;
015- Set-Cookie: counter=4;
019+ Set-Cookie: counter=1;
019- Set-Cookie: counter=5;
023+ Set-Cookie: counter=1;
024+ Etag: ""
025+ X-Original-Transfer-Encoding: chunked
026+ HTTP/1.1 200 OK
027+ Set-Cookie: counter=1;
028+ Etag: ""
029+ X-Original-Transfer-Encoding: chunked
030+ HTTP/1.1 200 OK
031+ Set-Cookie: counter=1;
023- Set-Cookie: counter=6;
039- Set-Cookie: counter=2;
042- HTTP/1.1 200 OK
047+ Set-Cookie: counter=1;
050+ ===DONE===
043- Set-Cookie: counter=3;
044- Etag: ""
045- X-Original-Transfer-Encoding: chunked
046- HTTP/1.1 200 OK
047- Set-Cookie: counter=4;
048- Etag: ""
049- X-Original-Transfer-Encoding: chunked
050- ===DONE===
========DONE========
FAIL client cookies [tests/client021.phpt]
Explan,ation from curl maintainer in Fedora:
The cookie is dropped by libcurl because the domain "localhost" is recognized
as a public suffix by libpsl. You can have a look at the attached minimal
example.
Contrary to CURL, it's not possible to unset the User-Agent request header by setting the 'useragent' configuration option to NULL.
I seem to be getting this error even though all dependencies have been installed?
If ext-http is built with libidn, URLs with "_" (undescore) in the hostname cannot be loaded due to a libidn parse failure. The code below logs the error messages given underneath:
$client = new http\Client();
$client->enqueue(new http\Client\Request("GET", "http://local_host:80/"));
$client->send();
Warning: http\Client\Request::__construct(): Failed to parse IDN; Non-digit/letter/hyphen in input in pecl_http-3.1.0beta1/tests/client030.phpt on line 12
Fatal error: Uncaught http\Exception\RuntimeException: http\Client::enqueue(): Cannot request empty URL in pecl_http-3.1.0beta1/tests/client030.phpt:12
Stack trace:
#0 pecl_http-3.1.0beta1/tests/client030.phpt(12): http\Client->enqueue(Object(http\Client\Request))
#1 {main}
thrown in pecl_http-3.1.0beta1/tests/client030.phpt on line 12
URLs containing _ can be loaded if ext-http is not built with libidn support. The curl command line client or browsers (such as Firefox or Chrome) also handle such URLs.
In /etc/php/conf.d I have these configuration files:
http.ini:
extension=http.so
propro.ini:
extension=propro.so
raphf.ini:
extension=raphf.so
When I execute php -m
with PHP 7.0.0 Beta 1 from the AUR and the phpng branches of raphf, propro, and this extension, I get:
PHP Warning: PHP Startup: Unable to load dynamic library '/usr/lib/php/modules/http.so' - /usr/lib/php/modules/http.so: undefined symbol: php_persistent_handle_abandon in Unknown on line 0
Warning: PHP Startup: Unable to load dynamic library '/usr/lib/php/modules/http.so' - /usr/lib/php/modules/http.so: undefined symbol: php_persistent_handle_abandon in Unknown on line 0
[PHP Modules]
...
raphf
...
which clearly indicates that raphf has for some reason been loaded after http, while http depends on it. Accordingly, http is loaded just fine when I move extension=raphf.so
from raphf.ini right before extension=http.so
in http.ini
However, when I disable propro, I get:
PHP Warning: Cannot load module 'http' because required module 'propro' is not loaded in Unknown on line 0
Warning: Cannot load module 'http' because required module 'propro' is not loaded in Unknown on line 0
[PHP Modules]
...
Since this time PHP complains about missing modules instead of missing symbols, I'm pretty sure that the raphf error originates from a bug regarding dependency resolution in http. Any thoughts?
Sometimes, we're getting segfaults in http\Client->send() in one of our unit tests that makes use of NTLM Proxy authentication if a persistent client that did not previously use Proxy auth is re-used. An xdebug call trace call shows that the attached observer receives a few updates before the segfault occurs, and usually ends on SplObjectStorage->valid()
, which is associated with the send()
call. The segault is always in __strcasecmp_l_avx() via curl_strequal().
Just the ext-http calls by themselves, such as in ntlm_clean.php appear to be insufficient to cause a segfault, so for the time being, I can't provide a reproducer. The "proxy" used in the tests is just an Apache httpd that responds with 404.
(gdb) zbacktrace
[0x7ffff14179d0] http\Client->send() [internal function]
[0x7ffff14175e0] RequestLoader->send() /lib/php/http/RequestLoader.php:1021
(gdb) bt
#0 __strcasecmp_l_avx () at ../sysdeps/x86_64/multiarch/strcmp-sse42.S:165
#1 0x00007ffff6dc26e9 in curl_strequal (first=<optimized out>, second=<optimized out>) at strequal.c:37
#2 0x00007ffff6dba7bc in ConnectionExists (waitpipe=<synthetic pointer>, force_reuse=<synthetic pointer>, usethis=<synthetic pointer>, needle=0xf859a0, data=0xf7a6c0) at url.c:3344
#3 create_conn (async=0x7fffffff9e58, in_connect=0xf7a6d0, data=<optimized out>) at url.c:5719
#4 Curl_connect (data=data@entry=0xf7a6c0, in_connect=in_connect@entry=0xf7a6d0, asyncp=asyncp@entry=0x7fffffff9e58, protocol_done=protocol_done@entry=0x7fffffff9e59) at url.c:5979
#5 0x00007ffff6dcb5d3 in multi_runsingle (multi=multi@entry=0xed0b90, now=..., data=data@entry=0xf7a6c0) at multi.c:1089
#6 0x00007ffff6dcc02d in curl_multi_perform (multi_handle=0xed0b90, running_handles=running_handles@entry=0x7fffdd8d2548) at multi.c:1793
#7 0x00007fffee6f9deb in php_http_client_curl_once (h=0x7fffdd410cc0) at /external/pecl_http-3.0.1/src/php_http_client_curl.c:2394
#8 php_http_client_curl_exec (h=0x7fffdd410cc0) at /external/pecl_http-3.0.1/src/php_http_client_curl.c:2424
#9 0x00007fffee6f36f1 in zim_HttpClient_send (execute_data=0x7ffff14179d0, return_value=0x7ffff14178d0) at /external/pecl_http-3.0.1/src/php_http_client.c:788
#10 0x000000000075cec2 in ZEND_DO_FCALL_SPEC_HANDLER () at /external/php-7.0.5/Zend/zend_vm_execute.h:842
#11 0x000000000071ab6b in execute_ex (ex=<optimized out>) at /external/php-7.0.5/Zend/zend_vm_execute.h:414
#12 0x00000000006c5d6d in zend_call_function (fci=fci@entry=0x7fffffffa220, fci_cache=fci_cache@entry=0x7fffffffa1f0) at /external/php-7.0.5/Zend/zend_execute_API.c:863
#13 0x0000000000572e78 in zim_reflection_method_invokeArgs (execute_data=<optimized out>, return_value=0x7ffff1417020) at /external/php-7.0.5/ext/reflection/php_reflection.c:3348
#14 0x000000000075cec2 in ZEND_DO_FCALL_SPEC_HANDLER () at /external/php-7.0.5/Zend/zend_vm_execute.h:842
#15 0x000000000071ab6b in execute_ex (ex=<optimized out>) at /external/php-7.0.5/Zend/zend_vm_execute.h:414
#16 0x000000000077d7fb in zend_execute (op_array=0x7ffff1488000, op_array@entry=0x7ffff1416e20, return_value=return_value@entry=0x0) at /external/php-7.0.5/Zend/zend_vm_execute.h:458
#17 0x00000000006d4a00 in zend_execute_scripts (type=type@entry=8, retval=retval@entry=0x0, file_count=file_count@entry=2) at /external/php-7.0.5/Zend/zend.c:1427
#18 0x000000000066a63a in php_execute_script (primary_file=primary_file@entry=0x7fffffffc900) at /external/php-7.0.5/main/main.c:2503
#19 0x000000000077f786 in do_cli (argc=4, argv=0xd056b0) at /external/php-7.0.5/sapi/cli/php_cli.c:974
#20 0x000000000042d824 in main (argc=4, argv=0xd056b0) at /external/php-7.0.5/sapi/cli/php_cli.c:1344
(gdb) bt full
#0 __strcasecmp_l_avx () at ../sysdeps/x86_64/multiarch/strcmp-sse42.S:165
No locals.
#1 0x00007ffff6dc26e9 in curl_strequal (first=<optimized out>, second=<optimized out>) at strequal.c:37
No locals.
#2 0x00007ffff6dba7bc in ConnectionExists (waitpipe=<synthetic pointer>, force_reuse=<synthetic pointer>, usethis=<synthetic pointer>, needle=0xf859a0,
data=0xf7a6c0) at url.c:3344
match = true
pipeLen = 0
max_pipe_len = 5
best_pipe_len = 5
curr = 0x0
chosen = 0x0
bundle = <optimized out>
wantProxyNTLMhttp = true
check = 0xf83710
canPipeline = false
wantNTLMhttp = true
#3 create_conn (async=0x7fffffff9e58, in_connect=0xf7a6d0, data=<optimized out>) at url.c:5719
conn = <optimized out>
result = <optimized out>
options = 0x15b00 <error: Cannot access memory at address 0x15b00>
proxy = 0x0
max_host_connections = <optimized out>
conn_temp = 0x0
urllen = <optimized out>
passwd = 0xf85860 ""
prot_missing = <optimized out>
connections_available = true
max_total_connections = <optimized out>
user = 0xf85840 ""
reuse = <optimized out>
force_reuse = false
waitpipe = false
#4 Curl_connect (data=data@entry=0xf7a6c0, in_connect=in_connect@entry=0xf7a6d0, asyncp=asyncp@entry=0x7fffffff9e58,
protocol_done=protocol_done@entry=0x7fffffff9e59) at url.c:5979
result = <optimized out>
#5 0x00007ffff6dcb5d3 in multi_runsingle (multi=multi@entry=0xed0b90, now=..., data=data@entry=0xf7a6c0) at multi.c:1089
disconnect_conn = false
msg = <optimized out>
connected = false
async = false
protocol_connect = false
dophase_done = false
done = false
rc = CURLM_OK
result = CURLE_OK
k = <optimized out>
timeout_ms = <optimized out>
control = 32767
#6 0x00007ffff6dcc02d in curl_multi_perform (multi_handle=0xed0b90, running_handles=running_handles@entry=0x7fffdd8d2548) at multi.c:1793
result = <optimized out>
wc = 0xf83258
pipe_st = {old_pipe_act = {__sigaction_handler = {sa_handler = 0x1, sa_sigaction = 0x1}, sa_mask = {__val = {4096, 140736911328648,
6545642012970847240, 140736911609880, 6545642014900255232, 140737488330224, 6545642014900255232, 140737488330224, 140737193644977,
140736911328648, 140733193391112, 140737488330296, 140737488330292, 140736905654208, 6545642014900255232, 140736911329576}},
sa_flags = 335544320, sa_restorer = 0x7ffff640e2f0 <__restore_rt>}, no_signal = false}
multi = 0xed0b90
data = 0xf7a6c0
returncode = CURLM_OK
t = 0x0
#7 0x00007fffee6f9deb in php_http_client_curl_once (h=0x7fffdd410cc0)
at /external/pecl_http-3.0.1/src/php_http_client_curl.c:2394
curl = 0x7fffdd8d2540
#8 php_http_client_curl_exec (h=0x7fffdd410cc0) at /external/pecl_http-3.0.1/src/php_http_client_curl.c:2424
No locals.
#9 0x00007fffee6f36f1 in zim_HttpClient_send (execute_data=0x7ffff14179d0, return_value=0x7ffff14178d0)
at /external/pecl_http-3.0.1/src/php_http_client.c:788
__zeh = {handling = EH_NORMAL, exception = 0x0, user_handler = {value = {lval = 140736905654208, dval = 6.9533270185744858e-310,
counted = 0x7fffdd44afc0, str = 0x7fffdd44afc0, arr = 0x7fffdd44afc0, obj = 0x7fffdd44afc0, res = 0x7fffdd44afc0, ref = 0x7fffdd44afc0,
ast = 0x7fffdd44afc0, zv = 0x7fffdd44afc0, ptr = 0x7fffdd44afc0, ce = 0x7fffdd44afc0, func = 0x7fffdd44afc0, ww = {w1 = 3712266176, w2 = 32767}},
u1 = {v = {type = 7 '\a', type_flags = 28 '\034', const_flags = 0 '\000', reserved = 0 '\000'}, type_info = 7175}, u2 = {var_flags = 0, next = 0,
cache_slot = 0, lineno = 0, num_args = 0, fe_pos = 0, fe_iter_idx = 0}}}
#10 0x000000000075cec2 in ZEND_DO_FCALL_SPEC_HANDLER () at /external/php-7.0.5/Zend/zend_vm_execute.h:842
should_change_scope = 1
call = 0x7ffff14179d0
fbc = 0xeb35d0
object = <optimized out>
ret = <optimized out>
#11 0x000000000071ab6b in execute_ex (ex=<optimized out>) at /external/php-7.0.5/Zend/zend_vm_execute.h:414
orig_opline = 0x0
orig_execute_data = 0xe46c20
#12 0x00000000006c5d6d in zend_call_function (fci=fci@entry=0x7fffffffa220, fci_cache=fci_cache@entry=0x7fffffffa1f0)
at /external/php-7.0.5/Zend/zend_execute_API.c:863
call_via_handler = 1
i = <optimized out>
calling_scope = <optimized out>
call = 0xc3
dummy_execute_data = {opline = 0x0, call = 0x0, return_value = 0x7fffffffa150, func = 0x80, This = {value = {lval = 0, dval = 0, counted = 0x0,
str = 0x0, arr = 0x0, obj = 0x0, res = 0x0, ref = 0x0, ast = 0x0, zv = 0x0, ptr = 0x0, ce = 0x0, func = 0x0, ww = {w1 = 0, w2 = 0}}, u1 = {v = {
type = 0 '\000', type_flags = 0 '\000', const_flags = 0 '\000', reserved = 0 '\000'}, type_info = 0}, u2 = {var_flags = 32767, next = 32767,
cache_slot = 32767, lineno = 32767, num_args = 32767, fe_pos = 32767, fe_iter_idx = 32767}}, called_scope = 0xe46c20,
prev_execute_data = 0x710c9a <zend_object_std_init+42>, symbol_table = 0xe46c20, run_time_cache = 0xe46c20, literals = 0x7fffdd9a0238}
fci_cache_local = {initialized = 64 '@', function_handler = 0x7fffdd44bc5b, calling_scope = 0xe46c20,
called_scope = 0x713c07 <zend_std_write_property+439>, object = 0x0}
func = 0x7fffddb22f68
orig_scope = 0x7ffff14175e0
#13 0x0000000000572e78 in zim_reflection_method_invokeArgs (execute_data=<optimized out>, return_value=0x7ffff1417020)
at /external/php-7.0.5/ext/reflection/php_reflection.c:3348
retval = {value = {lval = 140736912917632, dval = 6.9533273774353128e-310, counted = 0x7fffddb38480, str = 0x7fffddb38480, arr = 0x7fffddb38480,
obj = 0x7fffddb38480, res = 0x7fffddb38480, ref = 0x7fffddb38480, ast = 0x7fffddb38480, zv = 0x7fffddb38480, ptr = 0x7fffddb38480,
ce = 0x7fffddb38480, func = 0x7fffddb38480, ww = {w1 = 3719529600, w2 = 32767}}, u1 = {v = {type = 0 '\000', type_flags = 0 '\000',
const_flags = 0 '\000', reserved = 0 '\000'}, type_info = 0}, u2 = {var_flags = 0, next = 0, cache_slot = 0, lineno = 0, num_args = 0,
fe_pos = 0, fe_iter_idx = 0}}
params = 0x7fffdd831560
val = <optimized out>
object = 0x7ffff14173b0
mptr = <optimized out>
i = <optimized out>
argc = <optimized out>
result = <optimized out>
fci = {size = 72, function_table = 0x0, function_name = {value = {lval = 140736911386712, dval = 6.9533273017978149e-310, counted = 0x7fffdd9c2858,
str = 0x7fffdd9c2858, arr = 0x7fffdd9c2858, obj = 0x7fffdd9c2858, res = 0x7fffdd9c2858, ref = 0x7fffdd9c2858, ast = 0x7fffdd9c2858,
zv = 0x7fffdd9c2858, ptr = 0x7fffdd9c2858, ce = 0x7fffdd9c2858, func = 0x7fffdd9c2858, ww = {w1 = 3717998680, w2 = 32767}}, u1 = {v = {
type = 0 '\000', type_flags = 0 '\000', const_flags = 0 '\000', reserved = 0 '\000'}, type_info = 0}, u2 = {var_flags = 0, next = 0,
cache_slot = 0, lineno = 0, num_args = 0, fe_pos = 0, fe_iter_idx = 0}}, symbol_table = 0x0, retval = 0x7fffffffa1e0, params = 0x7fffdd831560,
object = 0x7fffddb88300, no_separation = 1 '\001', param_count = 0}
fcc = {initialized = 1 '\001', function_handler = 0x7fffddb22f68, calling_scope = 0x7fffddb20a60, called_scope = 0x7fffddb20a60,
object = 0x7fffddb88300}
obj_ce = 0x7fffddb20a60
param_array = 0x7ffff14173c0
#14 0x000000000075cec2 in ZEND_DO_FCALL_SPEC_HANDLER () at /external/php-7.0.5/Zend/zend_vm_execute.h:842
should_change_scope = 1
call = 0x7ffff1417350
fbc = 0xd50230
object = <optimized out>
ret = <optimized out>
#15 0x000000000071ab6b in execute_ex (ex=<optimized out>) at /external/php-7.0.5/Zend/zend_vm_execute.h:414
orig_opline = 0x1
orig_execute_data = 0x7ffff1488000
#16 0x000000000077d7fb in zend_execute (op_array=0x7ffff1488000, op_array@entry=0x7ffff1416e20, return_value=return_value@entry=0x0)
at /external/php-7.0.5/Zend/zend_vm_execute.h:458
execute_data = 0x7ffff1414030
#17 0x00000000006d4a00 in zend_execute_scripts (type=type@entry=8, retval=retval@entry=0x0, file_count=file_count@entry=2)
at /external/php-7.0.5/Zend/zend.c:1427
files = {{gp_offset = 32, fp_offset = 32767, overflow_arg_area = 0x7fffffffa400, reg_save_area = 0x7fffffffa390}}
i = 0
file_handle = 0x7fffffffc900
op_array = 0x7ffff1416e20
#18 0x000000000066a63a in php_execute_script (primary_file=primary_file@entry=0x7fffffffc900)
at /external/php-7.0.5/main/main.c:2503
orig_start_lineno = 2
realfile = "/scripts/devel/runTest.php\000\000\000\vzN\000\000\000\000\000`\000\000\000\000\000\000\000\022\000\000\000\000\000\000\000\254\272\377\377\377\177\000\000\200\267\377\377\377\177\000\000\020\272\377\377\377\177\000\000\264\267\377\377\377\177\000\000\001\000\000\000\000\000\000\000\a\000\000\000\061", '\000' <repeats 19 times>, "[\000\000\000n", '\000' <repeats 19 times>, "w\000\000\000|\000\000\000\260\070\331\000\000\000\000\000\200\273\325\000\000\000\000\000\001\000\000\000\001", '\000' <repeats 11 times>...
__orig_bailout = 0x7fffffffc970
__bailout = {{__jmpbuf = {140737488341360, 3230684716981082733, 13653776, 10123608, 1, 140737488345880, 3230684720271514221, -3230684498283668883},
__mask_was_saved = 0, __saved_mask = {__val = {140737351952052, 130, 140737274569429, 0, 140737351916829, 33780297937977475, 140733344413699,
33780297971531907, 33884779560597507, 7228277404077127176, 13109978517422995065, 8651696361302917119, 18446603336858761216, 140737488336367,
140737277096190, 0}}}}
prepend_file_p = 0x7fffffffb430
append_file_p = 0x0
prepend_file = {handle = {fd = -246959360, fp = 0x7ffff147b300, stream = {handle = 0x7ffff147b300, isatty = 0, mmap = {len = 4510, pos = 0, map = 0x0,
buf = 0x7ffff7ff3000 "", old_handle = 0x0, old_closer = 0x0}, reader = 0x683ef0 <_php_stream_read>, fsizer = 0x668020 <php_zend_stream_fsizer>,
closer = 0x668000 <php_zend_stream_mmap_closer>}}, filename = 0xd22a18 "init/bootstrap.php", opened_path = 0x0, type = ZEND_HANDLE_MAPPED,
free_filename = 0 '\000'}
append_file = {handle = {fd = 0, fp = 0x0, stream = {handle = 0x0, isatty = 0, mmap = {len = 0, pos = 0, map = 0x0, buf = 0x0, old_handle = 0x0,
old_closer = 0x0}, reader = 0x0, fsizer = 0x0, closer = 0x0}}, filename = 0x0, opened_path = 0x0, type = ZEND_HANDLE_FILENAME,
free_filename = 0 '\000'}
old_cwd = 0x7fffffffa400 ""
retval = 0
#19 0x000000000077f786 in do_cli (argc=4, argv=0xd056b0) at /external/php-7.0.5/sapi/cli/php_cli.c:974
__orig_bailout = 0x7fffffffdb20
__bailout = {{__jmpbuf = {13377760, 3230684717153573485, 0, 0, 0, 140737488345880, 3230684717016734317, -3230684354615518611}, __mask_was_saved = 0,
__saved_mask = {__val = {10004352, 10004376, 9893079, 9893100, 10004389, 10004409, 10004426, 10004990, 10004447, 10004461, 10004483, 10004502,
10004529, 10004558, 0, 2133424}}}}
c = <optimized out>
file_handle = {handle = {fd = -246951760, fp = 0x7ffff147d0b0, stream = {handle = 0x7ffff147d0b0, isatty = 0, mmap = {len = 7396, pos = 0,
map = 0x7ffff7fec000, buf = 0x7ffff7fec014 <error: Cannot access memory at address 0x7ffff7fec014>, old_handle = 0xeccef0,
old_closer = 0x6f2b50 <zend_stream_stdio_closer>}, reader = 0x6f2b80 <zend_stream_stdio_reader>, fsizer = 0x6f2ad0 <zend_stream_stdio_fsizer>,
closer = 0x6f2a50 <zend_stream_mmap_closer>}}, filename = 0xd05710 "/scripts/devel/runTest.php", opened_path = 0x0,
type = ZEND_HANDLE_MAPPED, free_filename = 0 '\000'}
behavior = <optimized out>
reflection_what = 0x0
request_started = 1
exit_status = 0
php_optarg = 0x0
php_optind = 2
exec_direct = <optimized out>
exec_run = <optimized out>
exec_begin = <optimized out>
exec_end = <optimized out>
arg_free = <optimized out>
arg_excp = <optimized out>
script_file = <optimized out>
translated_path = 0xecce40 "/scripts/devel/runTest.php"
lineno = 2
param_error = 0x0
#20 0x000000000042d824 in main (argc=4, argv=0xd056b0) at /external/php-7.0.5/sapi/cli/php_cli.c:1344
__orig_bailout = 0x0
__bailout = {{__jmpbuf = {13377760, 3230684717153573485, 0, 0, 0, 140737488345880, 3230684717102717549, -3230684191535080851}, __mask_was_saved = 0,
__saved_mask = {__val = {4131212846, 4294967295, 140737351944685, 140737324683768, 140737353954544, 1, 140737324664544, 10, 4, 140737488346376,
140737351974768, 140737301641600, 140737351974768, 4294958068, 0, 1}}}}
c = <optimized out>
exit_status = 0
module_started = 1
sapi_started = 1
php_optarg = 0x0
php_optind = 1
use_extended_info = 0
ini_path_override = 0x0
ini_entries = 0xd059b0 "html_errors=0\nregister_argc_argv=1\nimplicit_flush=1\noutput_buffering=0\nmax_execution_time=0\nmax_input_time=-1\n"
ini_entries_len = 0
ini_ignore = 0
sapi_module = <optimized out>
I would like to modify outgoing requests and inject custom http headers.
While I can specify an observer receiving any such requests, the first notification happens in https://github.com/m6w6/ext-http/blob/master/src/php_http_client_curl.c#L2194, e.g. after the request was built. Changing the request at this point in time, will not have any effect.
Can we add a prepare stage that notifies the observer before the request is build?
With curl 7.43 (Fedora 23) or 7.50 (Fedora 25)
/dev/shm/BUILD/php70-php-pecl-http-3.1.0/NTS/src/php_http_client_curl.c: In function 'php_http_curle_option_set_ssl_tlsauthtype':
/dev/shm/BUILD/php70-php-pecl-http-3.1.0/NTS/src/php_http_client_curl.c:1113:19: error: 'PHP_HTTP_LIBCURL_TLSAUTH_SRP' undeclared (first use in this function)
if (CURLE_OK == curl_easy_setopt(ch, CURLOPT_TLSAUTH_TYPE, PHP_HTTP_LIBCURL_TLSAUTH_SRP)) {
^
/dev/shm/BUILD/php70-php-pecl-http-3.1.0/NTS/src/php_http_client_curl.c:1113:19: note: each undeclared identifier is reported only once for each function it appears in
/dev/shm/BUILD/php70-php-pecl-http-3.1.0/NTS/src/php_http_client_curl.c:1121:17: error: 'PHP_HTTP_LIBCURL_TLSAUTH_DEF' undeclared (first use in this function)
if (CURLE_OK != curl_easy_setopt(ch, CURLOPT_TLSAUTH_TYPE, PHP_HTTP_LIBCURL_TLSAUTH_DEF)) {
^
We want to abort curl requests as soon as possible in case the resolved IP address is in our blacklist, however using the http\Client::dequeue() (http\Client::reset()) method from the setDebug()-callback causes a segmentation fault. We are using pecl_http 3.1.0 (master) with PHP 7.0.9 and curl 7.29.0.
To demonstrate the problem, I took the example from #35 and used the http\Client::dequeue() method within the setDebug():
<?php
$c = new http\Client;
$c->enqueue(new http\Client\Request("GET", "https://m6w6.name"));
$c->setDebug(function(http\Client $c, http\Client\Request $r, int $type, string $data) {
if ($type & http\Client::DEBUG_HEADER) {
$c->dequeue($r);
}
});
$c->send();
With gdb I get this backtrace:
#0 0x00007ffff7754c7a in multi_runsingle (multi=multi@entry=0xda6bb0, now=..., easy=easy@entry=0xdbe1b0) at multi.c:1239
#1 0x00007ffff7755121 in curl_multi_perform (multi_handle=0xda6bb0, running_handles=running_handles@entry=0x7ffff14b9148) at multi.c:1723
#2 0x00007fffe859fe5e in php_http_client_curl_once (h=0x7ffff1477840) at pecl_http-3.1.0-dev/src/php_http_client_curl.c:2268
#3 php_http_client_curl_exec (h=0x7ffff1477840) at pecl_http-3.1.0-dev/src/php_http_client_curl.c:2285
#4 0x00007fffe859a1ef in zim_HttpClient_send (execute_data=0x7ffff1414130, return_value=0x7ffff1414120) at pecl_http-3.1.0-dev/src/php_http_client.c:867
#5 0x00000000006db70b in ZEND_DO_FCALL_SPEC_HANDLER () at php-7.0.9/Zend/zend_vm_execute.h:842
#6 0x00000000006a1f7b in execute_ex (ex=<optimized out>) at php-7.0.9/Zend/zend_vm_execute.h:414
#7 0x00000000006fddc3 in zend_execute (op_array=0x7ffff1484000, op_array@entry=0x7ffff1414030, return_value=return_value@entry=0x0)
at php-7.0.9/Zend/zend_vm_execute.h:458
#8 0x000000000065fcc0 in zend_execute_scripts (type=type@entry=8, retval=retval@entry=0x0, file_count=file_count@entry=2) at php-7.0.9/Zend/zend.c:1427
#9 0x00000000005fa05b in php_execute_script (primary_file=primary_file@entry=0x7fffffffcec0) at php-7.0.9/main/main.c:2510
#10 0x00000000006ffb3f in do_cli (argc=2, argv=0xc28ee0) at php-7.0.9/sapi/cli/php_cli.c:974
#11 0x000000000042d45b in main (argc=2, argv=0xc28ee0) at php-7.0.9/sapi/cli/php_cli.c:1344
I stumbled across another null ptr deref in sanitize_value()
/php_url_mod()
caused by the following code:
<?php
/* url_mod.php */
$urls = [
"",
"? = ="
];
$url0=new http\Url($urls[0]);
$url1=$url0->mod($urls[1]);
?>
Result:
$ sapi/cli/php url_mod.php
[1] 22267 segmentation fault (core dumped) sapi/cli/php url_mod.php
I came up with a quick fix for this issue in ab5d9e2. However, since I'm not very familiar with the code base I'm not sure if it's the right thing to do. If it is, just ping me and I'll be happy to open a PR. :)
Backtrace and registers:
gdb> r url_mod.php
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
Program received signal SIGSEGV, Segmentation fault.
sanitize_value (flags=<optimized out>, str=0x7ffff167100a " =", len=2, zv=0x0, rfc5987=<optimized out>) at ext/http/src/php_http_params.c:368
0x00000000010eae41 e8 2a 7e 39 ff sanitize_value+53 callq 0x482c70 <memcpy@plt>
0x00000000010eae46 41 c6 44 1f 18 00 sanitize_value+58 movb $0x0,0x18(%r15,%rbx,1)
0x00000000010eae4c 41 f6 44 24 09 04 sanitize_value+64 testb $0x4,0x9(%r12) <-
0x00000000010eae52 74 60 sanitize_value+70 je 0x10eaeb4 <push_param+1220>
0x00000000010eae54 64 48 8b 04 25 00 00 00 00 sanitize_value+72 mov %fs:0x0,%rax
gdb> bt
#0 sanitize_value (flags=<optimized out>, str=0x7ffff167100a " =", len=2, zv=0x0, rfc5987=<optimized out>) at ext/http/src/php_http_params.c:368
#1 push_param (params=<optimized out>, state=<optimized out>, opts=<optimized out>) at ext/http/src/php_http_params.c:558
#2 0x00000000010ea034 in php_http_params_parse (params=<optimized out>, opts=<optimized out>) at ext/http/src/php_http_params.c:753
#3 0x00000000010f6060 in php_http_querystring_parse (ht=<optimized out>, str=<optimized out>, len=<optimized out>) at ext/http/src/php_http_querystring.c:224
#4 0x00000000010f6739 in php_http_querystring_update (qarray=<optimized out>, params=0x7fffffff9f58, outstring=0x0) at ext/http/src/php_http_querystring.c:268
#5 0x00000000010fe4c0 in php_http_url_mod (old_url=<optimized out>, new_url=<optimized out>, flags=<optimized out>) at ext/http/src/php_http_url.c:237
#6 0x000000000110833e in zim_HttpUrl_mod (execute_data=0x7ffff1613130, return_value=<optimized out>) at ext/http/src/php_http_url.c:1670
#7 0x00000000013fedfd in ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER (execute_data=0x7ffff1613030) at Zend/zend_vm_execute.h:1103
#8 0x000000000139b6ae in execute_ex (ex=<optimized out>) at Zend/zend_vm_execute.h:432
#9 0x000000000139c144 in zend_execute (op_array=<optimized out>, return_value=<optimized out>) at Zend/zend_vm_execute.h:474
#10 0x00000000012b364b in zend_execute_scripts (type=<optimized out>, retval=<optimized out>, file_count=<optimized out>) at Zend/zend.c:1441
#11 0x000000000116b2b8 in php_execute_script (primary_file=<optimized out>) at main/main.c:2532
#12 0x000000000150cffb in do_cli (argc=<optimized out>, argv=<optimized out>) at sapi/cli/php_cli.c:990
#13 0x000000000150ac11 in main (argc=<optimized out>, argv=<optimized out>) at sapi/cli/php_cli.c:1383
gdb> i r
rax 0x7ffff16556b8 140737243338424
rbx 0x2 2
rcx 0x3d20 15648
rdx 0x2 2
rsi 0x7ffff1673d20 140737243462944
rdi 0x7ffff16556b8 140737243338424
rbp 0x7ffff167100a 0x7ffff167100a
rsp 0x7fffffff9b60 0x7fffffff9b60
r8 0x7fffffff9b8f 140737488329615
r9 0x1 1
r10 0x477 1143
r11 0x7ffff2c54ea0 140737266405024
r12* 0x0 0
r13 0x7fffffff9d00 140737488329984
r14 0x1dad868 31119464
r15 0x7ffff16556a0 140737243338400
rip 0x10eae4c 0x10eae4c <push_param+1116>
eflags 0x10202 [ IF RF ]
[...]
Compiling php_http.dll on Windows (x64, PHP7.0.11, nts, VC14) leads to this error with the 3.0.1RC1 release or the sources from git head
c:\php-sdk\php70dev\ext\http\src\php_http_api.h(116): error C2016: C requires that a struct
or union has at least one member (compiling source file ext\http\src\php_http_options.c)
If PHP was built without the curl extension (i.e. --without-curl or --disable-all without --with-curl), even a simple pecl_http test program emits a warning:
PHP Notice: http\Client::enqueue(): Could not set option proxy_service_name (An unknown option was passed in to libcurl)
I'm using stock pecl_http-3.0.1 with PHP 7.0.5.
Affected version: 2.5.2
reproduction:
<?php
$request = new \http\Client\Request();
$request->setRequestUrl("https://.example.com/"); // seg fault
First of all, i'm not sure i'm running the latest version, but couldn't find anything about this in the changelogs.
When you join query and the original parameter value is empty, it's removed from the modifies query string.
Example:
$hurl = new http\url("http://www.google.com/?a");
$hurl = $hurl->mod(array(
'query' => 'b=3'),
http\url::JOIN_QUERY
);
$url = $hurl->toString();
Output: http://www.google.com/?b=3
Expected output: http://www.google.com/?a&b=3
Sometimes, it's necessary to inspect the actual request including all header that have been sent. The PHP curl extension implements this via the CURLINFO_HEADER_OUT option. The patch below provides similar functionality for ext-http.
When we try to execute this code:
<?php
error_reporting(E_ALL);
ini_set('display_errors', true);
$req = new \http\Client\Request("GET", "http://google.com");
$req->setOptions([
'redirect' => 10,
'timeout' => 30,
'connecttimeout' => 30,
'cookiesession' => true,
]);
$req->setSslOptions([
'verifypeer' => false,
'verifyhost' => false
]);
$response = (new \http\Client())->enqueue($req)->send()->getResponse($req);
var_dump($response->getBody()->toString());
It barks with notices:
Notice: http\Client::enqueue(): Could not set option verifystatus (No error) in /Users/igor/Sites/scalr/test.php on line 20
Notice: http\Client::enqueue(): Could not set option ssl (No error) in /Users/igor/Sites/scalr/test.php on line 20
$ php -i | grep -i -A1 "http support"
HTTP Support => enabled
Extension Version => 2.5.5
$ php -i | grep -i "libcurl"
libcurl => 7.43.0 => 7.43.0
$ curl -V
curl 7.43.0 (x86_64-apple-darwin15.0) libcurl/7.43.0 SecureTransport zlib/1.2.5
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp
Features: AsynchDNS IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz UnixSockets
$ php -v
PHP 5.6.16 (cli) (built: Nov 27 2015 10:28:34)
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2015 Zend Technologies
Program received signal SIGILL, Illegal instruction.
0x000000302ee14be0 in _dl_x86_64_save_sse () from /lib64/ld-linux-x86-64.so.2
(gdb) bt
#0 0x000000302ee14be0 in _dl_x86_64_save_sse () from /lib64/ld-linux-x86-64.so.2
#1 0x000000302ee0aad8 in _dl_lookup_symbol_x () from /lib64/ld-linux-x86-64.so.2
#2 0x000000302ee0df40 in _dl_fixup () from /lib64/ld-linux-x86-64.so.2
#3 0x000000302ee14625 in _dl_runtime_resolve () from /lib64/ld-linux-x86-64.so.2
#4 0x00007fffedf1b1d4 in zm_startup_http_client_curl (type=, module_number=43) at /home/zhaoxu-b/ext-http-RELEASE_3_0_0_RC1/src/php_http_client_curl.c:2510
#5 0x00007fffedf14c17 in zm_startup_http (type=1, module_number=43) at /home/zhaoxu-b/ext-http-RELEASE_3_0_0_RC1/src/php_http.c:147
#6 0x000000000080a563 in zend_startup_module_ex (module=0x11504d0) at /home/zhaoxu-b/php-7.0.0/Zend/zend_API.c:1841
#7 0x0000000000812223 in zend_hash_apply (ht=0x113b280, apply_func=0x80a5f0 <zend_startup_module_zval>) at /home/zhaoxu-b/php-7.0.0/Zend/zend_hash.c:1500
#8 0x000000000080d05a in zend_startup_modules () at /home/zhaoxu-b/php-7.0.0/Zend/zend_API.c:1967
#9 0x00000000007a9c25 in php_module_startup (sf=, additional_modules=, num_additional_modules=) at /home/zhaoxu-b/php-7.0.0/main/main.c:2194
#10 0x0000000000898fcd in php_cli_startup (sapi_module=) at /home/zhaoxu-b/php-7.0.0/sapi/cli/php_cli.c:423
#11 0x000000000089a741 in main (argc=1, argv=0x113ea80) at /home/zhaoxu-b/php-7.0.0/sapi/cli/php_cli.c:1325
Someone should enable, review & test http\Url's IDN support for Windows:
https://github.com/m6w6/ext-http/blob/master/src/php_http_url.c#L986
After a curl error (e.g. timeout, failed SSL handshake), the errorcode
is not properly reset. I'm using persistent handles. Resetting the errorcode
in php_http_curlm_responsehandler
seems to help:
if (CURLE_OK != msg->data.result) {
…
} else {
st = php_http_curle_get_storage(msg->easy_handle);
st->errorcode = 0;
…
}
In testing the PHP 7 branch I've run into a strange issue:
When the query string contains nested array keys of the form ?a[0][0]=x&a[1][0]=x
(outer key changes), PHP crashes (SIGSEGV).
It only happens with some scripts and not others; where it does happen, it happens reliably. I cannot figure out what the common factor is.
Backtrace:
#0 0x00000000007854b1 in _zend_hash_index_update ()
#1 0x00007f18351877c7 in push_param () from /php7/lib/php/extensions/no-debug-non-zts-20141001/http.so
#2 0x00007f1835186738 in php_http_params_parse () from /php7/lib/php/extensions/no-debug-non-zts-20141001/http.so
#3 0x00007f183518a81e in php_http_querystring_parse () from /php7/lib/php/extensions/no-debug-non-zts-20141001/http.so
#4 0x00007f183518a9ff in php_http_querystring_update () from /php7/lib/php/extensions/no-debug-non-zts-20141001/http.so
#5 0x00007f183518adae in zim_HttpQueryString___construct () from /php7/lib/php/extensions/no-debug-non-zts-20141001/http.so
#6 0x00000000007cc060 in ZEND_DO_FCALL_SPEC_HANDLER ()
#7 0x00000000007b68c8 in execute_ex ()
#8 0x00000000007b6d2e in zend_execute ()
#9 0x00000000007757a6 in zend_execute_scripts ()
#10 0x000000000070d56f in php_execute_script ()
#11 0x0000000000814de2 in main ()
Using latest source (GitHub) version of ext-http and PHP 7. Debian x86_64, clang 3.5.2.
By default, ext-http currently does not verify certificates against the 'capath' that is built into the SSL backend used by curl. Therefore, a hashed directory of certificates isn't checked unless the location is explicitly set.
Since the correct value for CURLOPT_CAPATH depends on the type of SSL backend used and its compile-time and run-time configuration, it's difficult to even make a good educated guess which value to set in ['ssl']['capath'].
With the "plain" curl PHP extension, the default CAPATH of the SSL backend is used to verify a peer's SSL certificate, even if CURLOP_CAINFO is set to a non-default file.
There is a reproducible crash (SIGSEGV) that seems to happen due to incorrect handling of the "Array to string conversion" notice when converted to an Exception by a custom error handler.
If a form or query parameter is an array but is cast to string by passing http\QueryString::TYPE_STRING to getForm/getQuery, PHP raises an E_NOTICE level error for the array-to-string conversion.
If there is a custom error handler defined that throws exceptions, this causes a segmentation fault and the entire worker process crashes.
Reproduction script (Debian x86_64, gcc 4.9.3, http 2.5.0, PHP 5.6.11):
<?php
set_error_handler(function() {
throw new Exception();
});
$request = new http\Env\Request();
var_dump($request->getForm("test", http\QueryString::TYPE_STRING));
?>
<form method="POST">
<input type="text" name="test[array]">
<button type="submit">Submit</button>
</form>
I just successfully rebuilt PHP7 beta 1 with ZTS enabled. However, when trying to rebuild ext-http I get the following error:
...
clang -I. -I/home/jakob/Downloads/ext-http -DPHP_ATOM_INC -I/home/jakob/Downloads/ext-http/include -I/home/jakob/Downloads/ext-http/main -I/home/jakob/Downloads/ext-http -I/usr/include/php -I/usr/include/php/main -I/usr/include/php/TSRM -I/usr/include/php/Zend -I/usr/include/php/ext -I/usr/include/php/ext/date/lib -I/usr/include/php/ext/raphf -I/usr/include/php/ext/propro -I/usr/include/php/ext/hash -DHAVE_CONFIG_H -g -O0 -c /home/jakob/Downloads/ext-http/php_http_client_curl.c -fPIC -DPIC -o .libs/php_http_client_curl.o
/home/jakob/Downloads/ext-http/php_http_client_curl.c:223:2: error: use of
undeclared identifier 'ERROR'
TSRMLS_FETCH_FROM_CTX(body->ts);
^
./php_http_api.h:124:37: note: expanded from macro 'TSRMLS_FETCH_FROM_CTX'
# define TSRMLS_FETCH_FROM_CTX(ctx) ERROR
^
/home/jakob/Downloads/ext-http/php_http_client_curl.c:1646:2: error: use of
undeclared identifier 'ERROR'
TSRMLS_FETCH_FROM_CTX(client->ts);
^
./php_http_api.h:124:37: note: expanded from macro 'TSRMLS_FETCH_FROM_CTX'
# define TSRMLS_FETCH_FROM_CTX(ctx) ERROR
^
/home/jakob/Downloads/ext-http/php_http_client_curl.c:2417:2: error: use of
undeclared identifier 'ERROR'
TSRMLS_FETCH_FROM_CTX(h->ts);
^
./php_http_api.h:124:37: note: expanded from macro 'TSRMLS_FETCH_FROM_CTX'
# define TSRMLS_FETCH_FROM_CTX(ctx) ERROR
^
3 errors generated.
Makefile:200: recipe for target 'php_http_client_curl.lo' failed
make: *** [php_http_client_curl.lo] Error 1
When compiling with gcc instead of clang the error messages differ, but not the error itself, so I'm pretty sure this isn't related to the compiler.
@m6w6 Hi Mike,
What is the status of propro, raphf and http on Windows (VC14)? I got it to compile, but had to make some changes. See my forks at https://github.com/Jan-E/repositories
Building wit cUrl support failed with these errormessages:
ext\http\src/php_http_client_curl.c(2181): error C2039: 'client': is not a member of '_zend_php_http_globals'
ext\http\src/php_http_client_curl.c(2181): error C2198: 'php_persistent_handle_concede': too few arguments for call
ext\http\src/php_http_client_curl.c(2501): error C2039: 'client': is not a member of '_zend_php_http_globals'
ext\http\src/php_http_client_curl.c(2502): error C2039: 'client': is not a member of '_zend_php_http_globals'
ext\http\src/php_http_client_curl.c(2503): error C2039: 'client': is not a member of '_zend_php_http_globals'
ext\http\src/php_http_client_curl.c(2504): error C2039: 'client': is not a member of '_zend_php_http_globals'
ext\http\src/php_http_client_curl.c(2506): error C2039: 'client': is not a member of '_zend_php_http_globals'
ext\http\src/php_http_client_curl.c(2506): error C2198: 'php_http_client_driver_add': too few arguments for call
ext\http\src/php_http_client_curl.c(2510): error C2039: 'client': is not a member of '_zend_php_http_globals'
ext\http\src/php_http_client_curl.c(2510): error C2198: 'php_persistent_handle_provide': too few arguments for call
ext\http\src/php_http_client_curl.c(2513): error C2039: 'client': is not a member of '_zend_php_http_globals'
ext\http\src/php_http_client_curl.c(2513): error C2198: 'php_persistent_handle_provide': too few arguments for call
ext\http\src/php_http_client_curl.c(2607): error C2039: 'client': is not a member of '_zend_php_http_globals'
ext\http\src/php_http_client_curl.c(2607): error C2198: 'php_persistent_handle_cleanup': too few arguments for call
ext\http\src/php_http_client_curl.c(2608): error C2039: 'client': is not a member of '_zend_php_http_globals'
ext\http\src/php_http_client_curl.c(2608): error C2198: 'php_persistent_handle_cleanup': too few arguments for call
ext\http\src/php_http_client_curl.c(2609): error C2039: 'client': is not a member of '_zend_php_http_globals'
ext\http\src/php_http_client_curl.c(2609): error C2198: 'zend_string_release': too few arguments for call
ext\http\src/php_http_client_curl.c(2610): error C2039: 'client': is not a member of '_zend_php_http_globals'
ext\http\src/php_http_client_curl.c(2610): error C2198: 'zend_string_release': too few arguments for call
ext\http\src/php_http_client_curl.c(2611): error C2039: 'client': is not a member of '_zend_php_http_globals'
ext\http\src/php_http_client_curl.c(2611): error C2198: 'zend_string_release': too few arguments for call
All the modules compile fine except for this one:
libtool: compile: cc -I. -I/tmp/pear/temp/pecl_http -DPHP_ATOM_INC -I/tmp/pear/temp/pear-build-frd-opsDznPSo/pecl_http-2.5.0/include -I/tmp/pear/temp/pear-build-frd-opsDznPSo/pecl_http-2.5.0/main -I/tmp/pear/temp/pecl_http -I/usr/include/php5 -I/usr/include/php5/main -I/usr/include/php5/TSRM -I/usr/include/php5/Zend -I/usr/include/php5/ext -I/usr/include/php5/ext/date/lib -I/usr/include/php5/ext/raphf -I/usr/include/php5/ext/propro -I/usr/include/php5/ext/hash -DHAVE_CONFIG_H -g -O2 -c /tmp/pear/temp/pecl_http/php_http_querystring.c -fPIC -DPIC -o .libs/php_http_querystring.o
/tmp/pear/temp/pecl_http/php_http_querystring.c: In function 'php_http_querystring_xlate':
/tmp/pear/temp/pecl_http/php_http_querystring.c:89:8: error: 'PHP_ICONV_ERR_SUCCESS' undeclared (first use in this function)
if (PHP_ICONV_ERR_SUCCESS != php_iconv_string(key.str, key.len-1, &xkey, &xlen, oe, ie)) {
^
/tmp/pear/temp/pecl_http/php_http_querystring.c:89:8: note: each undeclared identifier is reported only once for each function it appears in
make: *** [php_http_querystring.lo] Error 1
ERROR: `make' failed
Any ideas what dependency is missing? Already installed all dependencies listed on the PECL page. This is on OpenSUSE x64 13.1 with PHP 5.6.9 on pecl_http 2.5.0
Compiling PHP 5.5.27 with VC11:
php_http_env_response.c
ext\http\php_http_env_response.c(232) : error C2143: syntax error : missing ';' before 'type'
ext\http\php_http_env_response.c(234) : error C2065: 'status' : undeclared identifier
ext\http\php_http_env_response.c(249) : error C2061: syntax error : identifier 'output'
ext\http\php_http_env_response.c(249) : error C2059: syntax error : ';'
ext\http\php_http_env_response.c(249) : error C2059: syntax error : 'type'
ext\http\php_http_env_response.c(289) : error C2065: 'output' : undeclared identifier
ext\http\php_http_env_response.c(289) : warning C4047: 'function' : 'php_http_buffer_pass_func_t' differs in levels of indirection from 'int'
ext\http\php_http_env_response.c(289) : warning C4024: 'php_http_buffer_chunked_output' : different types for formal and actual parameter 5
ext\http\php_http_env_response.c(292) : error C2065: 'output' : undeclared identifier
ext\http\php_http_env_response.c(292) : warning C4047: 'function' : 'php_http_buffer_pass_func_t' differs in levels of indirection from 'int'
ext\http\php_http_env_response.c(292) : warning C4024: 'php_http_buffer_chunked_output' : different types for formal and actual parameter 5
NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\BIN\cl.
exe"' : return code '0x2'
Stop.
Lines 231 and 232 in php_http_env_responce.c should be switched.
Adding this here for reference and to possibly gather more feedback, re curl/curl#888
In the past libcurl provided the response line HTTP/2.0 NNN
to the header callback, where NNN
is the response status code.
In 7.49.1 libcurl changed that string from HTTP/2.0 NNN
to just HTTP/2 NNN
(note the missing minor version including the separator) in a bug fix/consistency cleanup. The HTTP/2 working group (and the community?) made clear that they do not plan to incrementally produce minor version upgrades (e.g. to HTTP/2.1) of HTTP/2. As such, the protocol's name actually is HTTP/2 and not HTTP/2.0.
While the burden for header parsers is minor, even the HTTP/2 spec uses HTTP/2.0
in the connection preface, apparently for BC's sake.
I think this is a reasonable approach, so we'll wait how the curl project decides to move on with this issue.
See m6w6/ext-raphf#4
On RHEL-6, with gcc 4.4.7
/builddir/build/BUILD/php-pecl-http-3.1.0/NTS/src/php_http_url.c: In function 'parse_uidn_2003':
/builddir/build/BUILD/php-pecl-http-3.1.0/NTS/src/php_http_url.c:1007: error: #pragma GCC diagnostic not allowed inside functions
/builddir/build/BUILD/php-pecl-http-3.1.0/NTS/src/php_http_url.c:1011: error: #pragma GCC diagnostic not allowed inside functions
The documentation states that this will "Retrieve the first line of a request", but it is inconsistent with what actually ends up on the wire.
For example, the following:
$req = new http\Client\Request('GET', 'http://www.php.net/');
printf("%s\n", $req->getInfo());
outputs:
$ php getInfo.php
GET http://www.php.net/ HTTP/1.1
However, when running tcpdump -A, i see:
GET / HTTP/1.1
I'm arguing that getInfo() should represent what goes on the wire. It would also be nice if a new http\Client\Request
object would have its $headers
initialised with what will go on the wire too, specifically the Host header.
Cheers,
dlg
Hi.
You want to do, the server http\Server
?
Use libevent
, but better libuv
https://github.com/bwoebi/php-uv
In PHP this is not enough.
Thank.
I've stumbled accross a problem related to #32 when attempting to override http_proxy and related environment variables by setting CURLOPT_PROXY to an empty string via 'proxyhost'. ext-http internally substitutes NULL for the empty string, which does not have the desired effect. The enclosed trivial patch retains the empty string as is when calling curl_easy_setopt().
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.