-
Notifications
You must be signed in to change notification settings - Fork 5
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
PSR-7 Compatibility? #2
Comments
I really like the idea of having a PSR-7 adaptor available, but I'm not sure it should be included in this package. If the user only writes asynchronous code, then there would be no reason to have the adaptor available or have a dependency on I could set up a separate repo for the adaptor and push a basic project skeleton. You could do a PR against that, does that sound reasonable? Here's some of what I had in mind to get you started: use Icicle\Http\Message\MessageInterface;
class SynchronousMessage implements \Psr\Http\Message\MessageInterface
{
private $message;
private $body;
public function __construct(MessageInterface $message)
{
$this->message = $message;
$this->body = new SynchronousStream($message->getBody());
}
// Other PSR-7 MessageInterface methods...
public function getBody()
{
return $this->body;
}
public function getAsyncMessage() // Or some other name
{
return $this->message;
}
} use Icicle\Loop;
use Icicle\Stream\ReadableStreamInterface;
class SynchronousStream implements \Psr\Http\Message\StreamInterface
{
private $stream;
public function __construct(ReadableStreamInterface $stream)
{
$this->stream = $stream;
}
public function read($length)
{
$promise = $this->stream->read($length);
// Blocks until promise is resolved.
while ($promise->isPending()) {
Loop\tick(true);
}
$result = $promise->getResult();
if ($promise->isRejected()) {
throw $result;
}
return $result;
}
// Similar methods for write and seek.
// Other PSR-7 StreamInterface methods...
public function getAsyncStream() // Or some other name
{
return $this->stream;
}
} |
Interesting approach. Sure, prepare a skeleton and I will send a PR. Still thinking, is dependency to psr7 that bad? You could at least reuse URI interface, as it is exactly the same as in PSR7 implementations. |
I avoided a dependency on Additionally, I intend to release v1 and v2 of Icicle (and all components for Icicle) simultaneously with v1 for PHP 5.5+ and v2 for PHP 7. The PHP 7 version will have type hints on methods and massive performance improvements. Assuming I did this to all the HTTP message interfaces, I created a new repo and committed a project skeleton and a little bit of code based on what's above at https://github.com/icicleio/Psr7Adaptor. Write any adaptor classes you think would be useful. Message, Request, Response, and Uri will all need to be wrapped. Also, something to convert PSR-7 messages back to Icicle messages would make sense, but an async stream would have to be provided with the message. Feel free to send me an email, DM me on twitter, or we could talk on gitter.im. |
I still think that sharing code with PSR-7 implementation is not bad - they are focused on processing HTTP messages which are almost the same here, they solve common problems like security (see (here)[https://github.com/zendframework/zend-diactoros/blob/master/src/HeaderSecurity.php] and (here)[http://framework.zend.com/security/advisory/ZF2015-04]). I feel that if someone is able to use your library, he will also read the manual and understand that it is different :) Before I go into coding, could you rename this package to something like |
I think that having a bridge package to interfaces that are 100% compatible with the synchronous interfaces of PSR-7 is the best solution. I've contributed to the zend-diactoros project before and probably will contribute again. :) I plan on keep a close eye on that package to ensure I incorporate any security fixes and contribute any fixes I make here. Most of what the linked class does is taken care of by this line: https://github.com/icicleio/Http/blob/master/src/Message/Message.php#L326 However, I will definitely take another look to make sure I've covered that vulnerability. I very much agree with the name change, bridge is a much better term, and doesn't have the spelling ambiguity problem. Already done: https://github.com/icicleio/Psr7Bridge. I might change React Adaptor to React Bridge as well. |
Understood :) BTW, you can use regex from my latest patch to // validate
if (preg_match('/[^\x09\x0a\x0d\x20-\x7E\x80-\xFE]/', $value)) {
return false;
} |
Closing this issue, to be followed up in new repo. |
Hm. Thanks to @mtymek for pointing me here. I have to disagree with twowski, though. Having an interface that looks and acts almost like PSR-7, but isn't, is more confusing that just being totally different. I don't follow why the streams area an issue. As for PHP 7 and scalar typing, I am all for adding that in time but that is best done PHP-globally. I specifically pushed for PSR-7 to have single, predictable return types specifically to make a PHP 7 version of it in the future easier. If anything, I'd petition FIG to start releasing PHP 7-ified versions of its interfaces for those who want the extra pedantry (including me). I think the current approach actually makes it more confusing, not less. |
I went with a PSR-7-like interface because I thought it would be familiar to users and immutability seemed like a good idea. Streams are an issue because in asynchronous code you cannot call I'm open to suggestions on how to make the interfaces different to avoid confusion, however, the interfaces of PSR-7 in general make a lot of sense. This package might benefit from mutable messages, simply because message objects are built in parts, requiring many clones before producing the final object to be sent to the client or server. Adding types in PHP 7 is a minor nicety of having interfaces specific to this package and was not a major contributing factor in the decision. I too would like to see PHP 7 versions of the FIG interfaces with all the necessary types added to prototypes. |
Looks like this library comes with it's own implementation of HTTP messages, almost identical to those defined in PSR-7 standard, but not compatible on interface level. I can see that:
UriInterface
can be used directlyRequestInterface
andResponseInterface
are almost compatibleI think it is worth to build building some kind of bridge between this implementations, for the sake of compatibility. It won't be very elegant if you think about good OOP practices, but it's going to be very pragmatic - say someone develops PSR-7 library for detecting mobile devices using headers, it could be used directly from within
icicle/http
app.This "bridge" can be implemented in many different ways. As an example, Request class could have following methods:
You get incompatible getBody(), but everything else (headers, uri) can be used as always.
What do you think? I could create a PR with example bridge implementation.
The text was updated successfully, but these errors were encountered: