Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to reactphp/http v1.0.0, add improved HTTP examples and adapt documentation #95

Merged
merged 2 commits into from
Oct 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 29 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -272,12 +272,35 @@ $connector = new React\Socket\Connector($loop, array(

#### HTTP requests

HTTP operates on a higher layer than this low-level SOCKS implementation.
If you want to issue HTTP requests, you can add a dependency for
[clue/reactphp-buzz](https://github.com/clue/reactphp-buzz).
It can interact with this library by issuing all
[HTTP requests through a SOCKS proxy server](https://github.com/clue/reactphp-buzz#socks-proxy).
This works for both plain HTTP and TLS-encrypted HTTPS requests.
This library also allows you to send
[HTTP requests through a SOCKS proxy server](https://github.com/reactphp/http#socks-proxy).

In order to send HTTP requests, you first have to add a dependency for
[ReactPHP's async HTTP client](https://github.com/reactphp/http#client-usage).
This allows you to send both plain HTTP and TLS-encrypted HTTPS requests like this:

```php
$proxy = new Clue\React\Socks\Client(
'socks://127.0.0.1:1080',
new React\Socket\Connector($loop)
);

$connector = new React\Socket\Connector($loop, array(
'tcp' => $proxy,
'dns' => false
));

$browser = new React\Http\Browser($loop, $connector);

$browser->get('https://example.com/')->then(function (Psr\Http\Message\ResponseInterface $response) {
var_dump($response->getHeaders(), (string) $response->getBody());
}, function (Exception $e) {
echo 'Error: ' . $e->getMessage() . PHP_EOL;
});
```

See also [ReactPHP's HTTP client](https://github.com/reactphp/http#client-usage)
and any of the [examples](examples) for more details.

#### Protocol version

Expand Down
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"require-dev": {
"phpunit/phpunit": "^9.0 || ^7.0 || ^6.0 || ^5.7 || ^4.8.35",
"react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3",
"react/http": "^1.0",
"clue/connection-manager-extra": "^1.0 || ^0.7",
"clue/block-react": "^1.1"
}
Expand Down
38 changes: 0 additions & 38 deletions examples/01-http.php

This file was deleted.

41 changes: 41 additions & 0 deletions examples/01-https-request.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

// A simple example which uses an HTTP client to request https://example.com/ through a SOCKS proxy.
// You can use any kind of proxy, for example https://github.com/leproxy/leproxy (defaults to localhost:8080) and execute it like this:
//
// $ php leproxy.php
//
// The proxy in this example defaults to localhost:1080.
// To run the example go to the project root and run:
//
// $ php examples/01-https-request.php
//
// To run the same example with your proxy, the proxy URL can be given as an environment variable:
//
// $ socks_proxy=127.0.0.2:1080 php examples/01-https-request.php

require __DIR__ . '/../vendor/autoload.php';

$url = getenv('socks_proxy');
if ($url === false) {
$url = 'localhost:1080';
}

$loop = React\EventLoop\Factory::create();
$client = new Clue\React\Socks\Client($url, new React\Socket\Connector($loop));

$connector = new React\Socket\Connector($loop, array(
'tcp' => $client,
'timeout' => 3.0,
'dns' => false
));

$browser = new React\Http\Browser($loop, $connector);

$browser->get('https://example.com/')->then(function (Psr\Http\Message\ResponseInterface $response) {
var_dump($response->getHeaders(), (string) $response->getBody());
}, function (Exception $e) {
echo 'Error: ' . $e->getMessage() . PHP_EOL;
});

$loop->run();
38 changes: 0 additions & 38 deletions examples/02-https.php

This file was deleted.

40 changes: 40 additions & 0 deletions examples/02-optional-proxy-https-request.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

// A simple example which uses an HTTP client to request https://example.com/ (optional: Through a SOCKS proxy.)
// To run the example, go to the project root and run:
//
// $ php examples/02-optional-proxy-https-request.php
//
// If you chose the optional route, you can use any kind of proxy, for example https://github.com/leproxy/leproxy (defaults to localhost:8080) and execute it like this:
//
// $ php leproxy.php
//
// To run the same example with your proxy, the proxy URL can be given as an environment variable:
//
// $ socks_proxy=127.0.0.2:1080 php examples/02-optional-proxy-https-request.php

require __DIR__ . '/../vendor/autoload.php';

$loop = React\EventLoop\Factory::create();

$connector = null;
$url = getenv('socks_proxy');
if ($url !== false) {
$connector = new React\Socket\Connector($loop);
$client = new Clue\React\Socks\Client($url, $connector);
$connector = new React\Socket\Connector($loop, array(
'tcp' => $client,
'timeout' => 3.0,
'dns' => false
));
}

$browser = new React\Http\Browser($loop, $connector);

$browser->get('https://example.com/')->then(function (Psr\Http\Message\ResponseInterface $response) {
var_dump($response->getHeaders(), (string) $response->getBody());
}, function (Exception $e) {
echo 'Error: ' . $e->getMessage() . PHP_EOL;
});

$loop->run();
48 changes: 48 additions & 0 deletions examples/11-proxy-raw-http-protocol.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

// A simple example which requests http://google.com/ through a SOCKS proxy.
// You can use any kind of proxy, for example https://github.com/leproxy/leproxy (defaults to localhost:8080) and execute it like this:
//
// $ php leproxy.php
//
// The proxy in this example defaults to localhost:1080.
// To run the example, go to the project root and run:
//
// $ php examples/11-proxy-raw-http-protocol.php
//
// To run the same example with your proxy, the proxy URL can be given as an environment variable:
//
// $ socks_proxy=127.0.0.2:1080 php examples/11-proxy-raw-http-protocol.php
//
// For illustration purposes only. If you want to send HTTP requests in a real
// world project, take a look at example #01, example #02 and https://github.com/reactphp/http#client-usage.

require __DIR__ . '/../vendor/autoload.php';

$url = getenv('socks_proxy');
if ($url === false) {
$url = 'localhost:1080';
}

$loop = React\EventLoop\Factory::create();

$client = new Clue\React\Socks\Client($url, new React\Socket\Connector($loop));
$connector = new React\Socket\Connector($loop, array(
'tcp' => $client,
'timeout' => 3.0,
'dns' => false
));

echo 'Demo SOCKS client connecting to SOCKS server ' . $url . PHP_EOL;

$connector->connect('tcp://www.google.com:80')->then(function (React\Socket\ConnectionInterface $stream) {
echo 'connected' . PHP_EOL;
$stream->write("GET / HTTP/1.0\r\n\r\n");
$stream->on('data', function ($data) {
echo $data;
});
}, function (Exception $e) {
echo 'Error: ' . $e->getMessage() . PHP_EOL;
});

$loop->run();
51 changes: 51 additions & 0 deletions examples/12-optional-proxy-raw-http-protocol.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

// A simple example which requests http://google.com/ directly (optional: Through a SOCKS proxy.)
// To run the example, go to the project root and run:
//
// $ php examples/12-optional-proxy-raw-http-protocol.php
//
// If you chose the optional route, you can use any kind of proxy, for example https://github.com/leproxy/leproxy (defaults to localhost:8080) and execute it like this:
//
// $ php leproxy.php
//
// To run the same example with your proxy, the proxy URL can be given as an environment variable:
//
// $ socks_proxy=127.0.0.2:1080 php examples/12-optional-proxy-raw-http-protocol.php
//
// This example highlights how changing from direct connection to using a proxy
// actually adds very little complexity and does not mess with your actual
// network protocol otherwise.
//
// For illustration purposes only. If you want to send HTTP requests in a real
// world project, take a look at example #01, example #02 and https://github.com/reactphp/http#client-usage.

require __DIR__ . '/../vendor/autoload.php';

$loop = React\EventLoop\Factory::create();

$connector = new React\Socket\Connector($loop);

$url = getenv('socks_proxy');
if ($url !== false) {
$client = new Clue\React\Socks\Client($url, $connector);
$connector = new React\Socket\Connector($loop, array(
'tcp' => $client,
'timeout' => 3.0,
'dns' => false
));
}

echo 'Demo SOCKS client connecting to SOCKS server ' . $url . PHP_EOL;

$connector->connect('tcp://www.google.com:80')->then(function (React\Socket\ConnectionInterface $stream) {
echo 'connected' . PHP_EOL;
$stream->write("GET / HTTP/1.0\r\n\r\n");
$stream->on('data', function ($data) {
echo $data;
});
}, function (Exception $e) {
echo 'Error: ' . $e->getMessage() . PHP_EOL;
});

$loop->run();
48 changes: 48 additions & 0 deletions examples/13-proxy-raw-https-protocol.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

// A simple example which requests http://google.com/ through a SOCKS proxy.
// You can use any kind of proxy, for example https://github.com/leproxy/leproxy (defaults to localhost:8080) and execute it like this:
//
// $ php leproxy.php
//
// The proxy in this example defaults to localhost:1080.
// To run the example, go to the project root and run:
//
// $ php examples/13-proxy-raw-https-protocol.php
//
// To run the same example with your proxy, the proxy URL can be given as an environment variable:
//
// $ socks_proxy=127.0.0.2:1080 php examples/13-proxy-raw-https-protocol.php
//
// For illustration purposes only. If you want to send HTTP requests in a real
// world project, take a look at example #01, example #02 and https://github.com/reactphp/http#client-usage.

require __DIR__ . '/../vendor/autoload.php';

$url = getenv('socks_proxy');
if ($url === false) {
$url = 'localhost:1080';
}

$loop = React\EventLoop\Factory::create();

$client = new Clue\React\Socks\Client($url, new React\Socket\Connector($loop));
$connector = new React\Socket\Connector($loop, array(
'tcp' => $client,
'timeout' => 3.0,
'dns' => false
));

echo 'Demo SOCKS client connecting to SOCKS server ' . $url . PHP_EOL;

$connector->connect('tls://www.google.com:443')->then(function (React\Socket\ConnectionInterface $stream) {
echo 'connected' . PHP_EOL;
$stream->write("GET / HTTP/1.0\r\n\r\n");
$stream->on('data', function ($data) {
echo $data;
});
}, function (Exception $e) {
echo 'Error: ' . $e->getMessage() . PHP_EOL;
});

$loop->run();
Loading