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

Add HTTP client implementation (import clue/reactphp-buzz v2.9.0) #368

Merged
merged 5 commits into from
Jul 8, 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
3 changes: 3 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
The MIT License (MIT)

Copyright (c) 2013 Christian Lück
Copyright (c) 2012 Igor Wiedler, Chris Boden

Permission is hereby granted, free of charge, to any person obtaining a copy
Expand Down
1,233 changes: 1,203 additions & 30 deletions README.md

Large diffs are not rendered by default.

19 changes: 12 additions & 7 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
{
"name": "react/http",
"description": "Event-driven, streaming plaintext HTTP and secure HTTPS server for ReactPHP",
"keywords": ["event-driven", "streaming", "HTTP", "HTTPS", "server", "ReactPHP"],
"description": "Event-driven, streaming HTTP client and server implementation for ReactPHP",
"keywords": ["HTTP client", "HTTP server", "HTTP", "HTTPS", "event-driven", "streaming", "client", "server", "PSR-7", "async", "ReactPHP"],
"license": "MIT",
"require": {
"php": ">=5.3.0",
"ringcentral/psr7": "^1.2",
"react/socket": "^1.0 || ^0.8.3",
"react/stream": "^1.0 || ^0.7.1",
"react/promise": "^2.3 || ^1.2.1",
"evenement/evenement": "^3.0 || ^2.0 || ^1.0",
"react/promise-stream": "^1.1"
"psr/http-message": "^1.0",
"react/event-loop": "^1.0 || ^0.5",
"react/promise": "^2.3 || ^1.2.1",
"react/promise-stream": "^1.1",
"react/socket": "^1.1",
"react/stream": "^1.0 || ^0.7.5",
"ringcentral/psr7": "^1.2"
},
"require-dev": {
"clue/block-react": "^1.1",
"clue/http-proxy-react": "^1.3",
"clue/reactphp-ssh-proxy": "^1.0",
"clue/socks-react": "^1.0",
"phpunit/phpunit": "^9.0 || ^5.7 || ^4.8.35"
},
"autoload": {
Expand Down
15 changes: 15 additions & 0 deletions examples/01-client-get-request.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

use React\Http\Browser;
use Psr\Http\Message\ResponseInterface;

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

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

$client->get('http://google.com/')->then(function (ResponseInterface $response) {
var_dump($response->getHeaders(), (string)$response->getBody());
});

$loop->run();
23 changes: 23 additions & 0 deletions examples/02-client-concurrent-requests.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

use React\Http\Browser;
use Psr\Http\Message\ResponseInterface;

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

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

$client->head('http://www.github.com/clue/http-react')->then(function (ResponseInterface $response) {
var_dump($response->getHeaders(), (string)$response->getBody());
});

$client->get('http://google.com/')->then(function (ResponseInterface $response) {
var_dump($response->getHeaders(), (string)$response->getBody());
});

$client->get('http://www.lueck.tv/psocksd')->then(function (ResponseInterface $response) {
var_dump($response->getHeaders(), (string)$response->getBody());
});

$loop->run();
32 changes: 32 additions & 0 deletions examples/03-client-request-any.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

// concurrently request a number of URLs.
// return immediately once the first is completed, cancel all others.

use React\Http\Browser;
use Psr\Http\Message\ResponseInterface;

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

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

$promises = array(
$client->head('http://www.github.com/clue/http-react'),
$client->get('https://httpbin.org/'),
$client->get('https://google.com'),
$client->get('http://www.lueck.tv/psocksd'),
$client->get('http://www.httpbin.org/absolute-redirect/5')
);

React\Promise\any($promises)->then(function (ResponseInterface $response) use ($promises) {
// first response arrived => cancel all other pending requests
foreach ($promises as $promise) {
$promise->cancel();
}

var_dump($response->getHeaders());
echo PHP_EOL . $response->getBody();
});

$loop->run();
29 changes: 29 additions & 0 deletions examples/04-client-post-json.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

use React\Http\Browser;
use Psr\Http\Message\ResponseInterface;

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

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

$data = array(
'name' => array(
'first' => 'Alice',
'name' => 'Smith'
),
'email' => 'alice@example.com'
);

$client->post(
'https://httpbin.org/post',
array(
'Content-Type' => 'application/json'
),
json_encode($data)
)->then(function (ResponseInterface $response) {
echo (string)$response->getBody();
}, 'printf');

$loop->run();
26 changes: 26 additions & 0 deletions examples/05-client-put-xml.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

use React\Http\Browser;
use Psr\Http\Message\ResponseInterface;

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

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

$xml = new SimpleXMLElement('<users></users>');
$child = $xml->addChild('user');
$child->alias = 'clue';
$child->name = 'Christian Lück';

$client->put(
'https://httpbin.org/put',
array(
'Content-Type' => 'text/xml'
),
$xml->asXML()
)->then(function (ResponseInterface $response) {
echo (string)$response->getBody();
}, 'printf');

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

// not already running a HTTP CONNECT proxy server?
// Try LeProxy.org or this:
//
// $ php examples/72-server-http-connect-proxy.php 8080
// $ php examples/11-client-http-connect-proxy.php

use React\Http\Browser;
use Clue\React\HttpProxy\ProxyConnector as HttpConnectClient;
use Psr\Http\Message\ResponseInterface;
use React\EventLoop\Factory as LoopFactory;
use React\Socket\Connector;

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

$loop = LoopFactory::create();

// create a new HTTP CONNECT proxy client which connects to a HTTP CONNECT proxy server listening on localhost:8080
$proxy = new HttpConnectClient('127.0.0.1:8080', new Connector($loop));

// create a Browser object that uses the HTTP CONNECT proxy client for connections
$connector = new Connector($loop, array(
'tcp' => $proxy,
'dns' => false
));
$browser = new Browser($loop, $connector);

// demo fetching HTTP headers (or bail out otherwise)
$browser->get('https://www.google.com/')->then(function (ResponseInterface $response) {
echo RingCentral\Psr7\str($response);
}, 'printf');

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

// not already running a SOCKS proxy server?
// Try LeProxy.org or this: `ssh -D 1080 localhost`

use React\Http\Browser;
use Clue\React\Socks\Client as SocksClient;
use Psr\Http\Message\ResponseInterface;
use React\EventLoop\Factory as LoopFactory;
use React\Socket\Connector;

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

$loop = LoopFactory::create();

// create a new SOCKS proxy client which connects to a SOCKS proxy server listening on localhost:1080
$proxy = new SocksClient('127.0.0.1:1080', new Connector($loop));

// create a Browser object that uses the SOCKS proxy client for connections
$connector = new Connector($loop, array(
'tcp' => $proxy,
'dns' => false
));
$browser = new Browser($loop, $connector);

// demo fetching HTTP headers (or bail out otherwise)
$browser->get('https://www.google.com/')->then(function (ResponseInterface $response) {
echo RingCentral\Psr7\str($response);
}, 'printf');

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

use React\Http\Browser;
use Clue\React\SshProxy\SshSocksConnector;
use Psr\Http\Message\ResponseInterface;
use React\EventLoop\Factory as LoopFactory;
use React\Socket\Connector;

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

$loop = LoopFactory::create();

// create a new SSH proxy client which connects to a SSH server listening on localhost:22
// You can pass any SSH server address as first argument, e.g. user@example.com
$proxy = new SshSocksConnector(isset($argv[1]) ? $argv[1] : 'localhost:22', $loop);

// create a Browser object that uses the SSH proxy client for connections
$connector = new Connector($loop, array(
'tcp' => $proxy,
'dns' => false
));
$browser = new Browser($loop, $connector);

// demo fetching HTTP headers (or bail out otherwise)
$browser->get('https://www.google.com/')->then(function (ResponseInterface $response) {
echo RingCentral\Psr7\str($response);
}, 'printf');

$loop->run();
27 changes: 27 additions & 0 deletions examples/14-client-unix-domain-sockets.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

use React\Http\Browser;
use Psr\Http\Message\ResponseInterface;
use React\EventLoop\Factory as LoopFactory;
use React\Socket\FixedUriConnector;
use React\Socket\UnixConnector;
use RingCentral\Psr7;

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

$loop = LoopFactory::create();

// create a Browser object that uses the a Unix Domain Sockets (UDS) path for all requests
$connector = new FixedUriConnector(
'unix:///var/run/docker.sock',
new UnixConnector($loop)
);

$browser = new Browser($loop, $connector);

// demo fetching HTTP headers (or bail out otherwise)
$browser->get('http://localhost/info')->then(function (ResponseInterface $response) {
echo Psr7\str($response);
}, 'printf');

$loop->run();
33 changes: 33 additions & 0 deletions examples/21-client-request-streaming-to-stdout.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

use React\Http\Browser;
use Psr\Http\Message\ResponseInterface;
use React\Stream\ReadableStreamInterface;
use React\Stream\WritableResourceStream;
use RingCentral\Psr7;

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

if (DIRECTORY_SEPARATOR === '\\') {
fwrite(STDERR, 'Non-blocking console I/O not supported on Windows' . PHP_EOL);
exit(1);
}

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

$out = new WritableResourceStream(STDOUT, $loop);
$info = new WritableResourceStream(STDERR, $loop);

$url = isset($argv[1]) ? $argv[1] : 'http://google.com/';
$info->write('Requesting ' . $url . '…' . PHP_EOL);

$client->requestStreaming('GET', $url)->then(function (ResponseInterface $response) use ($info, $out) {
$info->write('Received' . PHP_EOL . Psr7\str($response));

$body = $response->getBody();
assert($body instanceof ReadableStreamInterface);
$body->pipe($out);
}, 'printf');

$loop->run();
27 changes: 27 additions & 0 deletions examples/22-client-stream-upload-from-stdin.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

use React\Http\Browser;
use Psr\Http\Message\ResponseInterface;
use React\Stream\ReadableResourceStream;
use RingCentral\Psr7;

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

if (DIRECTORY_SEPARATOR === '\\') {
fwrite(STDERR, 'Non-blocking console I/O not supported on Windows' . PHP_EOL);
exit(1);
}

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

$in = new ReadableResourceStream(STDIN, $loop);

$url = isset($argv[1]) ? $argv[1] : 'https://httpbin.org/post';
echo 'Sending STDIN as POST to ' . $url . '…' . PHP_EOL;

$client->post($url, array(), $in)->then(function (ResponseInterface $response) {
echo 'Received' . PHP_EOL . Psr7\str($response);
}, 'printf');

$loop->run();
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// Simple JSON-based HTTP API example as a base to build RESTful/RESTish APIs
// Launch demo and use your favorite CLI tool to test API requests
//
// $ php examples/09-json-api.php 8080
// $ php examples/59-server-json-api.php 8080
// $ curl -v http://localhost:8080/ -H 'Content-Type: application/json' -d '{"name":"Alice"}'

use Psr\Http\Message\ServerRequestInterface;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// Simple HTML form with file upload
// Launch demo and use your favorite browser or CLI tool to test form submissions
//
// $ php examples/12-upload.php 8080
// $ php examples/62-server-form-upload.php 8080
// $ curl --form name=test --form age=30 http://localhost:8080/
// $ curl --form name=hi --form avatar=@avatar.png http://localhost:8080/

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
<?php

// $ php examples/71-server-http-proxy.php 8080
// $ curl -v --proxy http://localhost:8080 http://reactphp.org/

use Psr\Http\Message\RequestInterface;
use React\EventLoop\Factory;
use React\Http\Response;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
<?php

// $ php examples/72-server-http-connect-proxy.php 8080
// $ curl -v --proxy http://localhost:8080 https://reactphp.org/

use Psr\Http\Message\ServerRequestInterface;
use React\EventLoop\Factory;
use React\Http\Response;
Expand Down
File renamed without changes.
File renamed without changes.
Loading