Fix #18 remove all traces of http parser

This commit is contained in:
Bob Weinand 2016-10-30 00:57:41 +02:00
parent b47c511163
commit 567ca4f30b
9 changed files with 2 additions and 442 deletions

104
README.md
View File

@ -1,13 +1,8 @@
# php-uv
[![Build Status](https://secure.travis-ci.org/chobie/php-uv.png)](http://travis-ci.org/bwoebi/php-uv)
[![Build Status](https://secure.travis-ci.org/bwoebi/php-uv.png)](http://travis-ci.org/bwoebi/php-uv)
interface to libuv for php (experimental). also supports http-parser.
# Experimental
This extension is experimental, its functions may change their names
or move to extension all together so do not rely to much on them you have been warned!
Interface to libuv for php.
# Install
@ -2900,101 +2895,6 @@ uv_run();
### void uv_fs_poll_stop(resource $poll)
### resource uv_http_parser_init(long $target = UV::HTTP_REQUEST)
##### *Description*
initialize http parser.
##### *Parameters*
*long $target*: this expects UV::HTTP_REQUEST, UV::HTTP_RESPONSE or UV::HTTP_BOTH.
##### *Return Value*
*resource uv_http*:
##### *Example*
````php
<?php
$parser = uv_http_parser_init(UV::HTTP_REQUEST);
````
### bool uv_http_parser_execute(resource $parser, string $body, array &$result)
##### *Description*
execute http parser.
##### *Parameters*
*resource $parser*: uv_http_parser resoruce.
*string $body*: http message.
*array &$result*: result array.
##### *Return Value*
*bool finished*: this parser returns false when specified http message is invalid or not enough message.
##### *Example*
````php
<?php
$parser = uv_http_parser_init(UV::HTTP_REQUEST);
if (uv_http_parser_execute($parser, "GET /img/http-parser.png?key=value#frag HTTP/1.1
Host: chobie.net
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:12.0) Gecko/20100101 Firefox/12.0
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Referer: http://chobie.net/
Cookie: key=value
Cache-Control: max-age=0
",$result)) {
var_dump($result);
//array(6) {
// ["headers"]=>
// array(8) {
// ["Host"]=>
// string(10) "chobie.net"
// ["User-Agent"]=>
// string(81) "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:12.0) Gecko/20100101 Firefox/12.0"
// ["Accept-Language"]=>
// string(14) "en-us,en;q=0.5"
// ["Accept-Encoding"]=>
// string(13) "gzip, deflate"
// ["Connection"]=>
// string(10) "keep-alive"
// ["Referer"]=>
// string(18) "http://chobie.net/"
// ["Cookie"]=>
// string(9) "key=value"
// ["Cache-Control"]=>
// string(9) "max-age=0"
// }
// ["QUERY_STRING"]=>
// string(35) "/img/http-parser.png?key=value#frag"
// ["path"]=>
// string(20) "/img/http-parser.png"
// ["query"]=>
// string(9) "key=value"
// ["fragment"]=>
// string(4) "frag"
// ["REQUEST_METHOD"]=>
// string(3) "GET"
//}
}
````
### void uv_stop([resource $uv_loop])
##### *Description*

View File

@ -1,140 +0,0 @@
<?php
/**
* TODO: this implementation is not correct some error handling.
*/
function createServer(Closure $closure)
{
$server = new HttpServer();
$server->addListener($closure);
return $server;
}
class HttpResponse
{
protected $server;
protected $client;
protected $code = 200;
protected $headers = array();
protected $body = array();
protected $http_version = "1.0";
public function __construct($server, $client)
{
$this->server = $server;
$this->client = $client;
}
public function writeHead($code, array $headers)
{
$this->code = $code;
$this->headers = $headers;
}
public function write($data)
{
$this->body[] = $data;
}
public function end()
{
// Todo: implement correctly
$buffer = "HTTP/1.0 200 OK\r\n";
foreach ($this->headers as $key => $value) {
$buffer .= $key . ": " . $value . "\r\n";
}
$buffer .= "\r\n";
$buffer .= join("", $this->body);
uv_write($this->client, $buffer, array($this->server, "onWrite"));
}
}
class HttpServer
{
protected $server;
protected $clients = array();
protected $parsers = array();
protected $closure;
public function __construct()
{
$this->server = uv_tcp_init();
}
public function addListener($closure)
{
$this->closure = $closure;
}
public function onShutdown($handle, $status)
{
uv_close($handle, array($this, "onClose"));
}
public function onClose($handle)
{
unset($this->clients[(int)$handle]);
unset($this->parsers[(int)$handle]);
}
public function onWrite($client, $status)
{
if ($status == 0) {
uv_shutdown($client, array($this, "onShutdown"));
} else {
echo "[write_failed]";
}
}
public function onRead($client, $nread, $buffer)
{
//echo $buffer;
//echo "--Error: " . uv_err_name(uv_last_error(uv_default_loop())) . PHP_EOL;
if ($nread < 0) {
//echo "[NREAD={$nread}]\n";
uv_shutdown($client, array($this, "onShutdown"));
} else if ($nread == 0) {
// nothing to do.
//echo "[NREAD=0]\n";
} else {
$result = array();
if (uv_http_parser_execute($this->parsers[(int)($client)], $buffer, $result)){
$response = new HttpResponse($this, $client);
$closure = $this->closure;
$closure($result, $response);
} else {
// nothing to do. (waiting next buffer)
}
}
}
public function onConnect($server, $status)
{
$client = uv_tcp_init();
uv_tcp_nodelay($client, 1);
uv_accept($server,$client);
$this->clients[(int)$client] = $client;
$this->parsers[(int)($client)] = uv_http_parser_init();
uv_read_start($client, array($this, "onRead"));
}
public function listen($port)
{
uv_tcp_nodelay($this->server, 1);
uv_tcp_bind6($this->server, uv_ip6_addr("::1",$port));
uv_listen($this->server, 511, array($this, "onConnect"));
uv_run(uv_default_loop());
}
}

View File

@ -1,9 +0,0 @@
<?php
require "http.php";
require "debug_timer.php";
createServer(function($request, $response){
$response->writeHead(200, array("Content-Type" => "text/plain"));
$response->write("Hello World");
$response->end();
})->listen(8888);

View File

@ -1,70 +0,0 @@
<?php
require "debug_timer.php";
$address = "::1";
$port = 8888;
$banner = <<<EOF
# # ##### ##### ##### ##### ##### ##### # # ##### #####
# # # # # # # # # # # # # # #
###### # # # # ##### ##### ##### ##### # # ##### #####
# # # # ##### # # # # # # # # #
# # # # # # # # # ## # # # # ##
# # # # # ##### ##### # # # ##### # #
http server started on port $port
EOF;
echo $banner;
$server = uv_tcp_init();
uv_tcp_bind6($server, uv_ip6_addr($address, $port));
$clients = array();
$parsers = array();
uv_listen($server, 511, function($server_stream) use (&$parsers, &$clients){
$client = uv_tcp_init();
uv_accept($server_stream, $client);
$clients[(int)$client] = $client;
$parsers[(int)$client] = uv_http_parser_init();
uv_read_start($client, function($client, $nread, $buffer) use (&$parsers, &$clients){
if ($nread < 0) {
uv_shutdown($client, function($client) use (&$parsers, &$clients){
uv_close($client, function($client) use (&$parsers, &$clients){
unset($parsers[(int)$client]);
unset($clients[(int)$client]);
});
});
return;
} else if ($nread == 0) {
if (uv_last_error() == UV::EOF) {
uv_shutdown($client, function($client) use (&$parsers, &$clients){
uv_close($client, function($client) use (&$parsers, &$clients){
unset($parsers[(int)$client]);
unset($clients[(int)$client]);
});
});
return;
}
} else {
$result = array();
if (uv_http_parser_execute($parsers[(int)$client], $buffer, $result)){
$response = "HTTP/1.1 200 OK\r\n\r\nHello World";
uv_write($client, $response, function($client) use (&$parsers, &$clients){
uv_close($client, function($client) use (&$parsers, &$clients){
unset($parsers[(int)$client]);
unset($clients[(int)$client]);
});
});
}
}
});
});
uv_run(uv_default_loop());

View File

@ -2497,9 +2497,6 @@ PHP_MINIT_FUNCTION(uv)
uv_lock_handle = zend_register_list_destructors_ex(destruct_uv_lock, NULL, PHP_UV_LOCK_RESOURCE_NAME, module_number);
uv_stdio_handle = zend_register_list_destructors_ex(destruct_uv_stdio, NULL, PHP_UV_STDIO_RESOURCE_NAME, module_number);
#ifdef ENABLE_HTTPPARSER
register_httpparser(module_number);
#endif
#if !defined(PHP_WIN32) && !(defined(HAVE_SOCKETS) && !defined(COMPILE_DL_SOCKETS))
{
@ -6489,28 +6486,20 @@ static zend_function_entry uv_functions[] = {
PHP_FE(uv_signal_init, arginfo_uv_signal_init)
PHP_FE(uv_signal_start, arginfo_uv_signal_start)
PHP_FE(uv_signal_stop, arginfo_uv_signal_stop)
#ifdef ENABLE_HTTPPARSER
/* http parser */
PHP_FE(uv_http_parser_init, arginfo_uv_http_parser_init)
PHP_FE(uv_http_parser_execute, arginfo_uv_http_parser_execute)
#endif
{NULL, NULL, NULL}
};
PHP_MINFO_FUNCTION(uv)
{
char uv_version[20];
// char http_parser_version[20];
sprintf(uv_version, "%d.%d",UV_VERSION_MAJOR, UV_VERSION_MINOR);
// sprintf(http_parser_version, "%d.%d",HTTP_PARSER_VERSION_MAJOR, HTTP_PARSER_VERSION_MINOR);
php_printf("PHP libuv Extension\n");
php_info_print_table_start();
php_info_print_table_header(2,"libuv Support", "enabled");
php_info_print_table_row(2,"Version", PHP_UV_VERSION);
php_info_print_table_row(2,"libuv Version", uv_version);
// php_info_print_table_row(2,"http-parser Version", http_parser_version);
php_info_print_table_end();
}

View File

@ -32,10 +32,6 @@
#include "php.h"
#include "uv.h"
#ifdef ENABLE_HTTPPARSER
#include "uv_http_parser.h"
#endif
#include "php_network.h"
#include "php_streams.h"

View File

@ -1,97 +0,0 @@
--TEST--
Check for uv_http_parser
--SKIPIF--
<?php if (!function_exists('uv_http_parser_execute')) die("Skipped: needs http parser."); ?>
--FILE--
<?php
$parser = uv_http_parser_init();
$result = array();
if (uv_http_parser_execute($parser, "GET /img/http-parser.png?key=value#frag HTTP/1.1
Host: chobie.net
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:12.0) Gecko/20100101 Firefox/12.0
Accept: image/png,image/*;q=0.8,*/*;q=0.5
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Referer: http://chobie.net/
Cookie: key=value
Cache-Control: max-age=0
", $result)) {
echo "# Headers count\n";
echo count($result['HEADERS']) . PHP_EOL;
echo "# Headers values\n";
echo $result['HEADERS']['HOST'] . PHP_EOL;
echo $result['HEADERS']['USER_AGENT'] . PHP_EOL;
echo $result['HEADERS']['ACCEPT'] . PHP_EOL;
echo $result['HEADERS']['ACCEPT_LANGUAGE'] . PHP_EOL;
echo $result['HEADERS']['ACCEPT_ENCODING'] . PHP_EOL;
echo $result['HEADERS']['CONNECTION'] . PHP_EOL;
echo $result['HEADERS']['REFERER'] . PHP_EOL;
echo $result['HEADERS']['COOKIE'] . PHP_EOL;
echo $result['HEADERS']['CACHE_CONTROL'] . PHP_EOL;
echo "# other values" . PHP_EOL;
echo $result['QUERY_STRING'] . PHP_EOL;
echo $result['PATH'] . PHP_EOL;
echo $result['QUERY'] . PHP_EOL;
echo $result['FRAGMENT'] . PHP_EOL;
echo $result['UPGRADE'] . PHP_EOL;
}
$buffer = "GET /demo HTTP/1.1
Upgrade: WebSocket
Connection: Upgrade
Host: example.com
Origin: http://example.com
WebSocket-Protocol: sample
";
$parser = uv_http_parser_init();
$result = array();
uv_http_parser_execute($parser, $buffer, $result);
var_dump($result);
--EXPECT--
# Headers count
10
# Headers values
chobie.net
Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:12.0) Gecko/20100101 Firefox/12.0
image/png,image/*;q=0.8,*/*;q=0.5
en-us,en;q=0.5
gzip, deflate
keep-alive
http://chobie.net/
key=value
max-age=0
# other values
/img/http-parser.png?key=value#frag
/img/http-parser.png
key=value
frag
0
array(5) {
["QUERY_STRING"]=>
string(5) "/demo"
["PATH"]=>
string(5) "/demo"
["REQUEST_METHOD"]=>
string(3) "GET"
["UPGRADE"]=>
int(1)
["HEADERS"]=>
array(6) {
["UPGRADE"]=>
string(9) "WebSocket"
["CONNECTION"]=>
string(7) "Upgrade"
["HOST"]=>
string(11) "example.com"
["ORIGIN"]=>
string(18) "http://example.com"
["WEBSOCKET_PROTOCOL"]=>
string(6) "sample"
["VERSION"]=>
string(3) "1.1"
}
}

View File

@ -9,6 +9,5 @@ cd libuv-1.6.1 && ./autogen.sh && ./configure --prefix=$(readlink -f `pwd`/../li
cd ..
#install 'php-uv'
#phpize && ./configure --with-uv=$(readlink -f `pwd`/libuv) --enable-httpparser && make && make install
phpize && ./configure --with-uv=$(readlink -f `pwd`/libuv) && make && make install
echo "extension = uv.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini

8
uv.c
View File

@ -32,7 +32,6 @@ static int php_uv_class_init(TSRMLS_D)
zend_class_entry ce;
INIT_CLASS_ENTRY(ce, "UV", php_uv_methods);
uv_class_entry = zend_register_internal_class(&ce TSRMLS_CC);
//uv_class_entry->create_object = php_uv_new;
zend_declare_class_constant_long(uv_class_entry, "RUN_DEFAULT", sizeof("RUN_DEFAULT")-1, UV_RUN_DEFAULT TSRMLS_CC);
zend_declare_class_constant_long(uv_class_entry, "RUN_ONCE", sizeof("RUN_ONCE")-1, UV_RUN_ONCE TSRMLS_CC);
@ -196,13 +195,6 @@ static int php_uv_class_init(TSRMLS_D)
zend_declare_class_constant_long(uv_class_entry, "PROCESS_WINDOWS_VERBATIM_ARGUMENTS", sizeof("PROCESS_WINDOWS_VERBATIM_ARGUMENTS")-1, UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS TSRMLS_CC);
zend_declare_class_constant_long(uv_class_entry, "PROCESS_DETACHED", sizeof("PROCESS_DETACHED")-1, UV_PROCESS_DETACHED TSRMLS_CC);
#ifdef ENABLE_HTTPPARSER
/* http parser */
zend_declare_class_constant_long(uv_class_entry, "HTTP_BOTH", sizeof("HTTP_BOTH")-1, HTTP_BOTH TSRMLS_CC);
zend_declare_class_constant_long(uv_class_entry, "HTTP_REQUEST", sizeof("HTTP_REQUEST")-1, HTTP_REQUEST TSRMLS_CC);
zend_declare_class_constant_long(uv_class_entry, "HTTP_RESPONSE", sizeof("HTTP_RESPONSE")-1, HTTP_RESPONSE TSRMLS_CC);
#endif
#define PHP_UV_ERRNO_GEN(name, msg_notused) zend_declare_class_constant_long(uv_class_entry, ZEND_STRL(#name), UV_##name);
UV_ERRNO_MAP(PHP_UV_ERRNO_GEN)
#undef PHP_UV_ERRNO_GEN