Coder Social home page Coder Social logo

socket-client's People

Contributors

alexmace avatar cboden avatar clue avatar daverandom avatar e3betht avatar elliot avatar igorw avatar jsor avatar robinvdvleuten avatar wyrihaximus avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

socket-client's Issues

Roadmap to stable v1.0.0

Let's face it, this project is stable and has been used in production for years :shipit:

However, we're currently following a v0.X.Y release scheme (http://sentimentalversioning.org/).

We should finally make this explicit and fully adhere to SemVer and release a stable v1.0.0.

To a large extend, a stable v1.0.0 helps making BC breaks more explicit and thus the whole project more reliable from a consumer perspective. This project is actively maintained and has received some major updates in the last weeks and has some major updates planned in the next weeks. Given our current versioning scheme, we'd like to ensure all anticipated BC breaks will be merged before the planned v1.0.0 release.

As such, I've set up a roadmap that enlists only the major changes for each version among with planned release dates towards a stable v1.0.0 release:

v0.5.0 ✅

  • Released 2016-03-19
  • Support Connector without DNS
  • Context options
  • Improved test suite and error handling

v0.5.1 ✅

  • Released 2016-11-20
  • Promise cancellation
  • Timeout handling

v0.5.2 ✅

  • Released 2016-12-20
  • Add examples and simplify internal stream handling

v0.5.3 ✅

  • Released 2016-12-24
  • Skip IPv6 tests if not supported and improve documentation

v0.6.0 ✅

  • Released 2017-02-17
  • URIs everywhere
  • Add ConnectionInterface
  • Cancellation support is now mandatory
  • Reduce public API

v0.6.1 ✅

  • Released 2017-03-10
  • Update stream component

v0.6.2 ✅

  • Released 2017-03-17
  • SNI on legacy PHP < 5.6

v0.7.0:white_check_mark:

  • Released 2017-04-02
  • Simpler facade API

v0.8.0

  • Planned 2017-??
  • Merge this component into Socket

v1.0.0

  • Planned 2017-??
  • No new changes planned, this should merely mark the previous release as "stable"

This ticket aims to serve as a basic overview and does not contain every single change. Please also see the milestone links and the CHANGELOG for more details.

Obviously, this roadmap is subject to change and I'll try to keep it updated as we progress. In order to avoid cluttering this, please keep discussion in this ticket to a minimum and consider reaching out to us through new tickets or Twitter etc.

Sync sockets.

Is there anything I can do, to create a synchronize call and get the result inline?

$stream->write('TESTING');
$line = $stream->read(1024); // Response
$stream->write('ONE');
$line = $stream->read(1024); // Response
$stream->write('TWO');
$line = $stream->read(1024); // Response

socket client without neverending loop

Is there a way to instantiate a pushing client which doesnt care about incoming messages? The current socket client requires a StreamSelectLoop argument..

Connection doesn't time out when using SSL

This is in support of phergie/phergie-irc-bot-react#42

i noticed the code never goes into this line https://github.com/reactphp/socket-client/blob/v0.4.4/src/SecureConnector.php#L22 because there is isn't a write event coming while it seems to be waiting for that https://github.com/reactphp/socket-client/blob/v0.4.4/src/Connector.php#L58

can someone confirm this and also explain why a write event is expected and what kind of write event is suppose to trigger this?

Support Promise cancellation

We should register a Promise cancellation handler so that the following code actually cleans up the underlying socket resource:

$promise = $connector->create('reactphp.org', 80);

$promise->cancel();

This can eventually also be used as the basis for timeout support (#28), similar to this:

$promise = $connector->create('reactphp.org', 80);
$loop->addTimer(3.0, function () use ($promise) {
    $promise->cancel();
});

Does not honor /etc/hosts

There's currently no way to connect to "localhost" or any other host names listed in the local /etc/hosts file. We could provide a hard-coded default for some common host names (like "localhost"), but this is bound to break.

In particular, this also affects usage with linked Docker containers where one container references another container by its host name. This means that there's currently no way to connect to other containers by their name.

Opening this ticket as a reminder - this actually depends on reactphp/dns#10

No support for SSL/TLS connections with HHVM

HHVM does not (currently) implement the required stream_socket_enable_crypto() function (facebook/hhvm#1647).

Trying to establish a SSL/TLS connection via the SecureConnector results in a fatal error:

Fatal error: Call to undefined function stream_socket_enable_crypto() […]

Opening this ticket as a reminder and for reference in related issues.

Server Name Indication (SNI) issues on legacy PHP < 5.6

Server Name Indication (SNI) works just fine on any recent PHP version and HHVM.

However, this is currently broken for legacy PHP versions (PHP < 5.6). This was introduced by #43 which landed in v0.5.0 and v0.4.5 (older versions work fine on legacy PHP versions). I stumbled upon this while trying to issue HTTPS requests against a host that requires proper SNI support.

This is a known issue for PHP < 5.6, see also https://github.com/amphp/socket/blob/aa784fe3a18fa8514e57714142488f629073c7a9/lib/functions.php#L87-90

False positive connection

<?php

require __DIR__ . '/vendor/autoload.php';
$loop = \React\EventLoop\Factory::create();

$tcpConnector = new React\SocketClient\TcpConnector($loop);

$tcpConnector->create('127.0.0.1', 8080)->then(function (React\Stream\Stream $stream) {
    echo "Connected\n";
}, function() {
    echo "Failed\n";
});

$loop->run();

Have no service listening to port 8080 (or any port to attempt to connect to), run script. Result is Connected, expected Failed.

Allow Connector to have no Resolver

...so I can connect to an ip address if I do something locally

It is already possible to call createSocketForAddress with the desired ip address, but it doesn't feel right that I need a dns resolver for that. One solution would be to have a resolving connector and non resolving connector. Or are there other suggestions?

I'm willing to try something in code if I know what the opinions are...

SecureStream is hard coded into StreamEncryption

SecureStream is hard coded into StreamEncryption and there is no easy ability to replace it with extended class.
Reason for replacement: I need to catch and correctly proceed exception " stream_get_contents(): SSL: Connection reset by peer " in method SecureStream::handleData();
Or would be nice updte code with correct catch;

        try {
            $this->handleData($stream);
        } catch (\Exception $e) {
            $this->emit('error', array($e, $this));
        }

\React\Stream\Stream

Keep connection open

Hi,

I have question regarding the capability of this library. Does this library works for Http Streaming connections?

Currently, I'm using a solution with fockopen and while($feof($fp)) to wait until server closes the connection or timeout.

Support for delayed secure connections (STARTTLS)

Hi!

I would like to exchange some data on a stream before enabling TLS on it. Currently, the SecureConnector doesn't allow this, and there is no clean way of enabling TLS on Streams after the connection.

Use cases:

  • Supporting HTTP proxy CONNECT (required to implement HTTPS proxy support in http-client)
  • Supporting SMTP STARTTLS

I'm going to implement this, however I would like your opinion on these solutions:

  1. Add a DelayedSecureConnector class. Its create() method would result in a DelayedSecureStream instance, with a connect() method

  2. Add a createDelayed() method on SecureConnector, returning the stream and a callback that would allow to enable TLS. Also add a SecureConnectorInterface.

    list ($stream, $enableTLS) = $connector->connectDelayed();
    // Do something with the stream
    // Then, enable TLS:
    $enableTLS()->then(...);
    
  3. Add a "prologue" callback argument to create(), allowing the callback to manipulate the stream before encryption is enabled

WDYT ?

Example doesn't seem to work.

In a terminal, I'm running netcat listening on port 3001, and expecting to to see "hello from react" in that terminal when I run the following php script, which is essential a copy of the example from the readme:

<?php

$loop = React\EventLoop\Factory::create();
$dnsResolverFactory = new React\Dns\Resolver\Factory();
$dns = $dnsResolverFactory->createCached('8.8.8.8', $loop);
$connector = new React\SocketClient\Connector($loop, $dns);

$connector->create('127.0.0.1', 3001)
->then(function (React\Stream\Stream $stream) {
  $stream->write("hello from react.\n");
  $stream->close();
};
?>

Instead, the script exits silently and nothing is recieved in the netcat window.

FWIW, using telnet to manually connect to port 3001 and type messages DOES cause them to be echoed in the nc terminal, as expected.

What am I doing wrong?

loop response

Hello!
May be I`m noob, but how may I read (use) response in loop?
My server broadcasts every 5-30 sec some data. How to cache this data?

Backport v0.5.0 fixes to v0.4 branch

All recent SSL context updates will land in the upcoming v0.5.0 release. This is done because they build on #46, which contains a (rather small) BC break.

Given that there are quite a few consumers which rely on version ~0.4.0 of this library, we should consider backporting the SSL context updates to a v0.4.xrelease.

Relevant tickets:

SecureStream should extend Stream

PR #14 by @cboden introduced a new SecureStream class to work around an SSL buffering issue.
The workaround is only applied to affected versions, i.e. to any but the newest PHP versions.

This workaround has been shipped with the latest v0.4.2 release.
I absolutely agree that we should provide this workaround.

However, the workaround introduces a subtle BC break - something that should not happen in a minor release.

The documentation of this project states that every call to create() resolves with a Stream instance. The (undocumented) workaround changes this to return a SecureStream instead.
The SecureStream currently does not extend the Stream class.

This breaks our backwards compatibility with all packages that depend on this project that explicitly expect a Stream instance. Arguably, we should have provided an interface to depend on to begin with.

The easiest fix would be to modify the SecureStream to extend the Stream class and release a v0.4.3 tag.

An alternative would be to update the documentation and state that we only return an object that implements the DuplexStreamInterface and release a v0.5.0 tag. In that case we would have to depend on react/stream: >= 0.4.2, < 0.5.0.

Timeout support (connect and execution)

For comparison curl provides you with two options:

  • CURLOPT_CONNECTTIMEOUT the time it may take to establish the connection.
  • CURLOPT_TIMEOUT the time the total execution of the request is allowed to take.

Both of these I'm currently using to "probe" ~150 servers per day and test their connect and response time. Since this is about speed, I'm not interested in keeping the connection open for more than a couple of seconds, so I would like to tweak both these parameters.

The timeout branch seemed to be aimed at the total execution time equivalent.
And the connection timeout is available in stream_socket_client, currently a fixed value Connector.php:43.

Return Connection object which exposes remote address

Each connector currently resolves with a Stream instance from the react/stream component. We should look into resolving with a Connection instance (which likely extends the Stream class) which should expose the remote address like this:

$connector->create('google.com', 80)->then(function (Connection $conn) {
    echo 'connected to ' . $conn->getRemoteAddress();
    $conn->close();
});

Note that the react/socket component already has a similar class (https://github.com/reactphp/socket/blob/master/src/Connection.php) which represents the server-side end of a connection.

Load balancer issue

I am trying to write a load balancer to change the proxy clients. The problem is that the results are being concatenated.
The good part is that this works, but for some reason the results are being concatenated in the same output.

Example of results. I don't understand what cache is in there, and why it keeps it even if I am initializing a new client connection every time + setup the new $server...

 "HTTP/1.1 200 OK Server: nginx/1.6.2 Date: Mon, 10 Nov 2014 12:35:22 GMT Content-Type: text/plain Transfer-Encoding: chunked Connection: close Cache-Control: no-cache f 176.10.100.228 0 HTTP/1.1 200 OK Server: nginx/1.6.2 Date: Mon, 10 Nov 2014 12:35:22 GMT Content-Type: text/plain Transfer-Encoding: chunked Connection: close Cache-Control: no-cache f 188.138.17.248 0 ";
$loop = React\EventLoop\Factory::create();
$dnsResolverFactory = new React\Dns\Resolver\Factory();
$dns = $dnsResolverFactory->createCached('8.8.8.8', $loop);

$socket = new React\Socket\Server($loop);
$socket->listen('2500','127.0.0.1');
$factory = new Socks\Factory($loop, $dns);

// set next SOCKS server as target
$target = $factory->createClient('127.0.0.1', '1020'); // initial port
$target->setResolveLocal(false);
// Extra

$server = new Socks\Server($socket, $loop, $target->createConnector());
$server->on('connection', function($conn)
{
    global $start, $stop, $factory, $loop, $socket, $target, $server;

    echo $conn->getRemoteAddress().' connected!'.PHP_EOL;
        $rand = rand(1020, 1050); // random selection of ports (socks5 proxy)

        echo "connected to [".$rand."]".PHP_EOL;
        $target2 = $factory->createClient('127.0.0.1', $rand );
        $server = new Socks\Server($socket, $loop, $target2->createConnector() );
});
$server->setProtocolVersion(5);

Streams closed while data still in buffer

Hey, Not sure if this is desired behaviour or not, but I've run into an issue where the data in the buffer doesn't ever get written.

As per example:

$connector->create('www.google.com', 80)->then(function (React\Stream\Stream $stream) {
    $stream->write('...');
    $stream->close();
});

From what I can see, the $stream->write() appends the data to the buffer and doesn't do a lot else at that point; it waits for the next tick of the event loop to come and write the buffer out. Because of that, when you follow it immediately with $stream->close(), it closes it and flushes the buffer.

As I said, I'm not sure if this is expected behaviour, and I can see benefits in both. As a work around, I'm doing this:

$connector->create('www.google.com', 80)->then(function (Stream $stream) use ($template) {
    $stream->write('…');
    $stream->getBuffer()->on('full-drain', function() use($stream) {
        $stream->close();
    });
});

Is this as simple as a doc update?

How to recieve data?

Here in readme it says:

Before you can actually transmit and receive data to/from a remote server, you have to establish a connection to the remote end. Establishing this connection through the internet/network takes some time as it requires several steps in order to complete:

But it was never explained how to recieve data from scoket server?

Add simpler API (Facade pattern)

Let's face it, our API might be clean (arguably), but it's cumbersome to work with.

IMO we should first figure out some use cases for our API to see how this is actually going to be used.

The socket-client component is quite lowlevel, so it's unlikely to be used by many users directly. It's probably more likely going to be used as part of some high level abstractions (say, a Redis or MySQL client implementation). See also https://libraries.io/packagist/react%2Fsocket-client/dependents

These high level components depend on a ConnectorInterface and will likely use DI to inject this. They probably care little about how the connector works. Neither should they care about any "additional" parameters. They do care about the target (hostname and port). Hence (IMHO) they should not have to take care of context options, connection timeouts or even selecting the "right" connector.

Afaict all they (essentially) need to do is to establish a connection to a given remote location. As such, I'm suggesting a simplified API similar to this:

// probably one of the most common use cases
$api->createConnection('tcp://www.google.com:80');

// automatically assumes TCP transport, as does fsockopen()
$api->createConnection('www.google.com:80');

// automatically picks use secure connector
$api->createConnection('tls://www.google.com:443');

Also, once we support Unix domain sockets (#37):

// create Unix domain socket, as does fsockopen()
$api->createConnection('unix:///var/tmp/demo.sock');

The implementation of such a facade would be pretty easy, it could accept a Connector and SecureConnector (or any other classes implementing the ConnectorInterface for that matter).

This facade would probably become the one class that every consumer of this component is going to use. The other classes should probably be left as-is and can still be used in advanced scenarios.

SSL Buffer Drain: The Redux

Related to #14, #24, #26...

Yesterday, I updated a project to v0.4.4, and was disappointed to find the SSL buffer issue rearing its ugly head, again. So much so, in fact, that I wanted to see if I could pinpoint which specific versions were affected. I've compiled a table here: https://gist.github.com/mcrumm/49d6ba5e5647429b9689

The list is by no means exhaustive, but it was a bit exhausting... 😃

To test this issue, I'm connecting to Slack's RealTime Messaging API via Pawl, and then waiting for messages. This has been discussed at length in other tickets, so the short version is that at least php-5.6.9 still suffers from the SSL buffer drain problem, and should likely be using fread. Additionally, there are versions < 5.6.8 that work without wrapSecure, but I don't know how much concern there is for targeting behavior for specific minor point releases.

PHP7 does not appear to suffer from this issue. Hurray.

The most problematic versions (of those tested):

  • 5.5.23
  • 5.6.7
  • 5.6.8 (Supposed source of the bugfix)

The fact that I couldn't get 5.6.8 working at all made me start to question the integrity of my tests, since that was the version that I had thought fixed the issue, so if someone else confirms 5.6.8 as working, I'll assume my build is the problem.

Is anyone else seeing similar results?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.