Skip to content

Commit d5d3b3c

Browse files
authored
Merge pull request #95 from SimonFrings/http
Update to reactphp/http v1.0.0, add improved HTTP examples and adapt documentation
2 parents 54f2344 + 9f60f89 commit d5d3b3c

19 files changed

Lines changed: 367 additions & 172 deletions

README.md

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -272,12 +272,35 @@ $connector = new React\Socket\Connector($loop, array(
272272

273273
#### HTTP requests
274274

275-
HTTP operates on a higher layer than this low-level SOCKS implementation.
276-
If you want to issue HTTP requests, you can add a dependency for
277-
[clue/reactphp-buzz](https://github.com/clue/reactphp-buzz).
278-
It can interact with this library by issuing all
279-
[HTTP requests through a SOCKS proxy server](https://github.com/clue/reactphp-buzz#socks-proxy).
280-
This works for both plain HTTP and TLS-encrypted HTTPS requests.
275+
This library also allows you to send
276+
[HTTP requests through a SOCKS proxy server](https://github.com/reactphp/http#socks-proxy).
277+
278+
In order to send HTTP requests, you first have to add a dependency for
279+
[ReactPHP's async HTTP client](https://github.com/reactphp/http#client-usage).
280+
This allows you to send both plain HTTP and TLS-encrypted HTTPS requests like this:
281+
282+
```php
283+
$proxy = new Clue\React\Socks\Client(
284+
'socks://127.0.0.1:1080',
285+
new React\Socket\Connector($loop)
286+
);
287+
288+
$connector = new React\Socket\Connector($loop, array(
289+
'tcp' => $proxy,
290+
'dns' => false
291+
));
292+
293+
$browser = new React\Http\Browser($loop, $connector);
294+
295+
$browser->get('https://example.com/')->then(function (Psr\Http\Message\ResponseInterface $response) {
296+
var_dump($response->getHeaders(), (string) $response->getBody());
297+
}, function (Exception $e) {
298+
echo 'Error: ' . $e->getMessage() . PHP_EOL;
299+
});
300+
```
301+
302+
See also [ReactPHP's HTTP client](https://github.com/reactphp/http#client-usage)
303+
and any of the [examples](examples) for more details.
281304

282305
#### Protocol version
283306

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"require-dev": {
2525
"phpunit/phpunit": "^9.0 || ^7.0 || ^6.0 || ^5.7 || ^4.8.35",
2626
"react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3",
27+
"react/http": "^1.0",
2728
"clue/connection-manager-extra": "^1.0 || ^0.7",
2829
"clue/block-react": "^1.1"
2930
}

examples/01-http.php

Lines changed: 0 additions & 38 deletions
This file was deleted.

examples/01-https-request.php

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
// A simple example which uses an HTTP client to request https://example.com/ through a SOCKS proxy.
4+
// You can use any kind of proxy, for example https://github.com/leproxy/leproxy (defaults to localhost:8080) and execute it like this:
5+
//
6+
// $ php leproxy.php
7+
//
8+
// The proxy in this example defaults to localhost:1080.
9+
// To run the example go to the project root and run:
10+
//
11+
// $ php examples/01-https-request.php
12+
//
13+
// To run the same example with your proxy, the proxy URL can be given as an environment variable:
14+
//
15+
// $ socks_proxy=127.0.0.2:1080 php examples/01-https-request.php
16+
17+
require __DIR__ . '/../vendor/autoload.php';
18+
19+
$url = getenv('socks_proxy');
20+
if ($url === false) {
21+
$url = 'localhost:1080';
22+
}
23+
24+
$loop = React\EventLoop\Factory::create();
25+
$client = new Clue\React\Socks\Client($url, new React\Socket\Connector($loop));
26+
27+
$connector = new React\Socket\Connector($loop, array(
28+
'tcp' => $client,
29+
'timeout' => 3.0,
30+
'dns' => false
31+
));
32+
33+
$browser = new React\Http\Browser($loop, $connector);
34+
35+
$browser->get('https://example.com/')->then(function (Psr\Http\Message\ResponseInterface $response) {
36+
var_dump($response->getHeaders(), (string) $response->getBody());
37+
}, function (Exception $e) {
38+
echo 'Error: ' . $e->getMessage() . PHP_EOL;
39+
});
40+
41+
$loop->run();

examples/02-https.php

Lines changed: 0 additions & 38 deletions
This file was deleted.
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
// A simple example which uses an HTTP client to request https://example.com/ (optional: Through a SOCKS proxy.)
4+
// To run the example, go to the project root and run:
5+
//
6+
// $ php examples/02-optional-proxy-https-request.php
7+
//
8+
// 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:
9+
//
10+
// $ php leproxy.php
11+
//
12+
// To run the same example with your proxy, the proxy URL can be given as an environment variable:
13+
//
14+
// $ socks_proxy=127.0.0.2:1080 php examples/02-optional-proxy-https-request.php
15+
16+
require __DIR__ . '/../vendor/autoload.php';
17+
18+
$loop = React\EventLoop\Factory::create();
19+
20+
$connector = null;
21+
$url = getenv('socks_proxy');
22+
if ($url !== false) {
23+
$connector = new React\Socket\Connector($loop);
24+
$client = new Clue\React\Socks\Client($url, $connector);
25+
$connector = new React\Socket\Connector($loop, array(
26+
'tcp' => $client,
27+
'timeout' => 3.0,
28+
'dns' => false
29+
));
30+
}
31+
32+
$browser = new React\Http\Browser($loop, $connector);
33+
34+
$browser->get('https://example.com/')->then(function (Psr\Http\Message\ResponseInterface $response) {
35+
var_dump($response->getHeaders(), (string) $response->getBody());
36+
}, function (Exception $e) {
37+
echo 'Error: ' . $e->getMessage() . PHP_EOL;
38+
});
39+
40+
$loop->run();
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
// A simple example which requests http://google.com/ through a SOCKS proxy.
4+
// You can use any kind of proxy, for example https://github.com/leproxy/leproxy (defaults to localhost:8080) and execute it like this:
5+
//
6+
// $ php leproxy.php
7+
//
8+
// The proxy in this example defaults to localhost:1080.
9+
// To run the example, go to the project root and run:
10+
//
11+
// $ php examples/11-proxy-raw-http-protocol.php
12+
//
13+
// To run the same example with your proxy, the proxy URL can be given as an environment variable:
14+
//
15+
// $ socks_proxy=127.0.0.2:1080 php examples/11-proxy-raw-http-protocol.php
16+
//
17+
// For illustration purposes only. If you want to send HTTP requests in a real
18+
// world project, take a look at example #01, example #02 and https://github.com/reactphp/http#client-usage.
19+
20+
require __DIR__ . '/../vendor/autoload.php';
21+
22+
$url = getenv('socks_proxy');
23+
if ($url === false) {
24+
$url = 'localhost:1080';
25+
}
26+
27+
$loop = React\EventLoop\Factory::create();
28+
29+
$client = new Clue\React\Socks\Client($url, new React\Socket\Connector($loop));
30+
$connector = new React\Socket\Connector($loop, array(
31+
'tcp' => $client,
32+
'timeout' => 3.0,
33+
'dns' => false
34+
));
35+
36+
echo 'Demo SOCKS client connecting to SOCKS server ' . $url . PHP_EOL;
37+
38+
$connector->connect('tcp://www.google.com:80')->then(function (React\Socket\ConnectionInterface $stream) {
39+
echo 'connected' . PHP_EOL;
40+
$stream->write("GET / HTTP/1.0\r\n\r\n");
41+
$stream->on('data', function ($data) {
42+
echo $data;
43+
});
44+
}, function (Exception $e) {
45+
echo 'Error: ' . $e->getMessage() . PHP_EOL;
46+
});
47+
48+
$loop->run();
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
// A simple example which requests http://google.com/ directly (optional: Through a SOCKS proxy.)
4+
// To run the example, go to the project root and run:
5+
//
6+
// $ php examples/12-optional-proxy-raw-http-protocol.php
7+
//
8+
// 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:
9+
//
10+
// $ php leproxy.php
11+
//
12+
// To run the same example with your proxy, the proxy URL can be given as an environment variable:
13+
//
14+
// $ socks_proxy=127.0.0.2:1080 php examples/12-optional-proxy-raw-http-protocol.php
15+
//
16+
// This example highlights how changing from direct connection to using a proxy
17+
// actually adds very little complexity and does not mess with your actual
18+
// network protocol otherwise.
19+
//
20+
// For illustration purposes only. If you want to send HTTP requests in a real
21+
// world project, take a look at example #01, example #02 and https://github.com/reactphp/http#client-usage.
22+
23+
require __DIR__ . '/../vendor/autoload.php';
24+
25+
$loop = React\EventLoop\Factory::create();
26+
27+
$connector = new React\Socket\Connector($loop);
28+
29+
$url = getenv('socks_proxy');
30+
if ($url !== false) {
31+
$client = new Clue\React\Socks\Client($url, $connector);
32+
$connector = new React\Socket\Connector($loop, array(
33+
'tcp' => $client,
34+
'timeout' => 3.0,
35+
'dns' => false
36+
));
37+
}
38+
39+
echo 'Demo SOCKS client connecting to SOCKS server ' . $url . PHP_EOL;
40+
41+
$connector->connect('tcp://www.google.com:80')->then(function (React\Socket\ConnectionInterface $stream) {
42+
echo 'connected' . PHP_EOL;
43+
$stream->write("GET / HTTP/1.0\r\n\r\n");
44+
$stream->on('data', function ($data) {
45+
echo $data;
46+
});
47+
}, function (Exception $e) {
48+
echo 'Error: ' . $e->getMessage() . PHP_EOL;
49+
});
50+
51+
$loop->run();
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
// A simple example which requests http://google.com/ through a SOCKS proxy.
4+
// You can use any kind of proxy, for example https://github.com/leproxy/leproxy (defaults to localhost:8080) and execute it like this:
5+
//
6+
// $ php leproxy.php
7+
//
8+
// The proxy in this example defaults to localhost:1080.
9+
// To run the example, go to the project root and run:
10+
//
11+
// $ php examples/13-proxy-raw-https-protocol.php
12+
//
13+
// To run the same example with your proxy, the proxy URL can be given as an environment variable:
14+
//
15+
// $ socks_proxy=127.0.0.2:1080 php examples/13-proxy-raw-https-protocol.php
16+
//
17+
// For illustration purposes only. If you want to send HTTP requests in a real
18+
// world project, take a look at example #01, example #02 and https://github.com/reactphp/http#client-usage.
19+
20+
require __DIR__ . '/../vendor/autoload.php';
21+
22+
$url = getenv('socks_proxy');
23+
if ($url === false) {
24+
$url = 'localhost:1080';
25+
}
26+
27+
$loop = React\EventLoop\Factory::create();
28+
29+
$client = new Clue\React\Socks\Client($url, new React\Socket\Connector($loop));
30+
$connector = new React\Socket\Connector($loop, array(
31+
'tcp' => $client,
32+
'timeout' => 3.0,
33+
'dns' => false
34+
));
35+
36+
echo 'Demo SOCKS client connecting to SOCKS server ' . $url . PHP_EOL;
37+
38+
$connector->connect('tls://www.google.com:443')->then(function (React\Socket\ConnectionInterface $stream) {
39+
echo 'connected' . PHP_EOL;
40+
$stream->write("GET / HTTP/1.0\r\n\r\n");
41+
$stream->on('data', function ($data) {
42+
echo $data;
43+
});
44+
}, function (Exception $e) {
45+
echo 'Error: ' . $e->getMessage() . PHP_EOL;
46+
});
47+
48+
$loop->run();

0 commit comments

Comments
 (0)