HTTP Message PSR Retry?

124 views
Skip to first unread message

Phil Sturgeon

unread,
Aug 22, 2013, 11:32:13 AM8/22/13
to php...@googlegroups.com
Now that we're starting to see progress on PSRs as they work their way through the workflow, the next logical step IMO is for somebody to start preparing a HTTP Message PSR, so we can all get Request / Response agreed before moving onto a HTTP Client Interface.

Whatever the exact path, we need somebody to work as an Editor, pull together a Pre-Draft and produce a meta document outlining the history of HTTP PSR attempts. It would be best if it were somebody involved in those discussions last time around, but doesn't have to be.

I'm not going to put myself forward as not only do we have people in the group much better suited to handle the task, but I am already coordinator for two other PSRs and I don't want to hog all the fun.

Who is going to be Editor? And who would consider sponsoring this?

Evert Pot

unread,
Aug 22, 2013, 11:44:32 AM8/22/13
to php...@googlegroups.com
This particular PSR is something that greatly interests me. I recently have done an actual implementation of this. I'm not 100% happy with it yet, but the work in progress is here:

https://github.com/fruux/sabre-http/blob/master/lib/Sabre/HTTP/RequestInterface.php
https://github.com/fruux/sabre-http/blob/master/lib/Sabre/HTTP/ResponseInterface.php
https://github.com/fruux/sabre-http/blob/master/lib/Sabre/HTTP/MessageInterface.php

One thing I realized is that _just_ an abstraction of the HTTP message is not enough for it to be useful for either a client, or a server.

On the server-side it's critical to have access to some CGI variables such as for example PATH_INFO.
Similarly on the client, it's absolutely required to be able to inject other configuration settings such as timeouts, proxy, etc..

On the client side, I'm simply allowing users to add additional curl options, but for the server part I did add methods to access values from the $_SERVER array, as well as access to $_POST, because when PHP propagates $_POST, there's unfortunately no way to still use php://input.

Anyway, my point is.. this is an implementation that already has seen a ton of real-world use, in one of the most complex HTTP applications (DAV) as both a server and a client.. so I'd love to help and be involved with this.

However, I cannot commit to being an Editor, I simply can't spare the hours. If there's others who'd like to dig into this, I'd love to discuss ideas, and I'm perhaps even secretly hoping that those 3 interfaces could serve as a starting point for such a PSR.

Cheers,
Evert

Michael Dowling

unread,
Aug 22, 2013, 12:34:40 PM8/22/13
to php...@googlegroups.com
There's already a really good start on an HTTP message PSR that has
had a lot of collaboration:
https://github.com/php-fig/fig-standards/pull/72. I think this PSR
does a really good job of only concerning itself with HTTP messages
(e.g., no server variables, no client settings, just HTTP messages).
There are a few things left that need to be considered (more
information on handling headers), but it's pretty close.

It would be great if Chris Wilkinson could keep this PSR going. I
don't have his email address, but I pinged him on Twitter.

-Michael

Paul M. Jones

unread,
Aug 22, 2013, 12:37:48 PM8/22/13
to php...@googlegroups.com

On Aug 22, 2013, at 10:44 AM, Evert Pot <ever...@gmail.com> wrote:

> One thing I realized is that _just_ an abstraction of the HTTP message is not enough for it to be useful for either a client, or a server.
>
> On the server-side it's critical to have access to some CGI variables such as for example PATH_INFO.
> Similarly on the client, it's absolutely required to be able to inject other configuration settings such as timeouts, proxy, etc..
>
> On the client side, I'm simply allowing users to add additional curl options, but for the server part I did add methods to access values from the $_SERVER array, as well as access to $_POST, because when PHP propagates $_POST, there's unfortunately no way to still use php://input.
>
> Anyway, my point is.. this is an implementation that already has seen a ton of real-world use, in one of the most complex HTTP applications (DAV) as both a server and a client.. so I'd love to help and be involved with this.

It seems to me that once we start adding things that are outside the HTTP spec, that makes it *not* an "HTTP" (proper) message/request/response. It's a "web" request/response, maybe, but not HTTP proper.

I'm in favor of having something with a superset of HTTP stuff, but to call it HTTP is perhaps misleading.



--
Paul M. Jones
pmjo...@gmail.com
http://paul-m-jones.com

Evert Pot

unread,
Aug 22, 2013, 12:53:19 PM8/22/13
to php...@googlegroups.com
There's no specific DAV stuff in there though.. Just all the IETF status codes, but that's where it ends.

Evert

Evert Pot

unread,
Aug 22, 2013, 2:54:19 PM8/22/13
to php...@googlegroups.com
On Aug 22, 2013, at 5:34 PM, Michael Dowling <mtdo...@gmail.com> wrote:

> There's already a really good start on an HTTP message PSR that has
> had a lot of collaboration:
> https://github.com/php-fig/fig-standards/pull/72. I think this PSR
> does a really good job of only concerning itself with HTTP messages
> (e.g., no server variables, no client settings, just HTTP messages).
> There are a few things left that need to be considered (more
> information on handling headers), but it's pretty close.

For what it's worth, I do agree with the idea that they should be kept out of the interfaces. I wanted to point it out because transport information is pretty much *required* to actually put those interfaces to use.

So if that's addressed by a future PSR, I'd be completely happy, and it looks like I'm for the most part already compatible with those interfaces.

The biggest issue I have with this proposal, is that I strongly feel that there should be support for streams right away.
They're very easy to deal with[1]. Adding support for objects supporting __toString() doesn't solve that, as the implication is that a stream will first have to be converted to a string anyway.

But yea, whoever is working on this, let me know if I can help anywhere.

Evert

[1]: https://github.com/fruux/sabre-http/blob/master/lib/Sabre/HTTP/Message.php#L52

Evert Pot

unread,
Aug 22, 2013, 3:13:59 PM8/22/13
to php...@googlegroups.com
A second issue:

setUrl / getUrl[1] should allow for relative urls. This reflects how the HTTP message also looks like (e.g.: a Host: header, and a relative or absolute url).
A full absolute url may in certain cases not be possible to determine.

The Host: header is optional in HTTP/1.0, and to determine the protocol (http, https) you need to rely on cgi variables that are not technically part of the HTTP message. The port may also not be available.

The __toString[2] method on Message/Request/Response is sugar, or perhaps nice for debugging, but not strictly needed. This functionality can be delegated to a different object, and in the interest of keeping it simple, I'd opt to remove it.

I'd personally also make all the set* method return nothing. Currently they return their own instance, and I feel that that's unneeded sugar that doesn't belong in a PSR. (but that's much more of a subjective thing, just wanted to put it out there..).

Support for objects implementing __toString() in setBody() is imho also a bad idea. Relying on __toString() is a form of ducktyping, and I feel this 'claims' a specific purpose for __toString(), when implementors may use that for something else entirely.

The proper thing to do is, imho, to define a separate body interface with a specific method that returns the contents of the body, but that in itself, I feel, should be out of scope for an initial PSR.

Anyway, I like the direction this is going, I hope this stuff is considered useful. Just wanted to put it out there..

Cheers,
Evert



[1]: https://github.com/php-fig/fig-standards/pull/72/files#L0R235
[2]: https://github.com/php-fig/fig-standards/pull/72/files#L0R57

Larry Garfield

unread,
Aug 22, 2013, 4:17:17 PM8/22/13
to php...@googlegroups.com
I am very interested in this topic and would love to see this proposal
move forward. I'm open to working on it either as an Editor or Coordinator.

That said, I'd prefer to get at least one of the three PSRs we just
approved for draft status (or are about to) put to bed first so we don't
flood ourselves with too many open discussions. That tends to not work
out so well. :-)

I really really hope we can get caching put to bed in the not too
distant future (all things being relative), after which I'll have more
time to devote to HTTP objects.

--Larry Garfield

Michael Dowling

unread,
Aug 22, 2013, 4:54:20 PM8/22/13
to php...@googlegroups.com
> setUrl / getUrl[1] should allow for relative urls. This reflects how the HTTP message also looks like (e.g.: a Host: header, and a relative or absolute url).
A full absolute url may in certain cases not be possible to determine.

Agreed.

> The __toString[2] method on Message/Request/Response is sugar, or perhaps nice for debugging, but not strictly needed. This functionality can be delegated to a different object, and in the interest of keeping it simple, I'd opt to remove it.

That's a fair point.

> Support for objects implementing __toString() in setBody() is imho also a bad idea.

I think it makes the API easy to use, works for most simple use cases,
and it defers the need to wait on some sort of stream API PSR to
support streaming (e.g, and object that supports read(), write(),
__toString(), etc).

> The proper thing to do is, imho, to define a separate body interface with a specific method that returns the contents of the body, but that in itself, I feel, should be out of scope for an initial PSR.

Yes, that would be outside the scope of the HTTP PSR, but it would be
the best route. Guzzle currently does this with it's stream API. If
you and everyone else feels strongly that this is a blocker, then an
HTTP message PSR should be blocked on a stream abstraction PSR.

Evert Pot

unread,
Aug 23, 2013, 3:22:40 AM8/23/13
to php...@googlegroups.com
> I think it makes the API easy to use, works for most simple use cases,
> and it defers the need to wait on some sort of stream API PSR to
> support streaming (e.g, and object that supports read(), write(),
> __toString(), etc).

I could live with this, although I do still feel that it's not great design =)

>
>> The proper thing to do is, imho, to define a separate body interface with a specific method that returns the contents of the body, but that in itself, I feel, should be out of scope for an initial PSR.
>
> Yes, that would be outside the scope of the HTTP PSR, but it would be
> the best route. Guzzle currently does this with it's stream API. If
> you and everyone else feels strongly that this is a blocker, then an
> HTTP message PSR should be blocked on a stream abstraction PSR.

Personally, I wouldn't care that much about an abstraction layer for this.. But the ability to set and get simple php streams is very important.

On the server side, the Request and Response should wrap php://input and php://output by default. That way sending a file back to a client is a matter of stream_copy_to_stream, which is the least CPU and memory-intensive way to go about.

Similarly when writing a client, you really want to be able to just fopen() a file for upload.

PHP streams rock, except for the api's that don't natively support it (looking at you, XMLWriter!). I can see why wrapping them in objects can in certain cases be helpful, but I think supporting native php streams is even more important =)

Evert


Chris Wilkinson

unread,
Aug 23, 2013, 7:21:29 AM8/23/13
to php...@googlegroups.com
Good to see this raised again; I have kept an eye on here, but my proposal was rather drowned out with all the caching/autoloading talk! I need to read through the new workflow stuff.

The big areas that were up for discussion are headers (array vs collection, and should there be header objects - I did propose some interfaces) and URIs (strings aren't very useful - I had a separate PSR proposal at https://groups.google.com/forum/?fromgroups#!topic/php-fig/06BSXGqPRiU).

Apart from that, I think it's mainly just polishing. (A lot of it writes itself, since it's following the RFCs.)

On Friday, 23 August 2013 08:22:40 UTC+1, Evert Pot wrote:
Personally, I wouldn't care that much about an abstraction layer for this.. But the ability to set and get simple php streams is very important.

On the server side, the Request and Response should wrap php://input and php://output by default. That way sending a file back to a client is a matter of stream_copy_to_stream, which is the least CPU and memory-intensive way to go about.

Similarly when writing a client, you really want to be able to just fopen() a file for upload.

PHP streams rock, except for the api's that don't natively support it (looking at you, XMLWriter!). I can see why wrapping them in objects can in certain cases be helpful, but I think supporting native php streams is even more important =)

As you say, streams are important for "serious" usage, but if you look through the reference implementations not all support them, and I don't think the PSR should force them to. Allowing objects that implement __toString() allows wrapper objects as Michael says; I agree with having a PSR for it (see https://github.com/php-fig/fig-standards/pull/72/files#r4198530 - of the top of my head Guzzle and Drupal have one, and I'm sure there's a load of them out there). Implementations could test whether the body is an instance of a PSR StreamInterface (rather than just their own) and handle it appropriately, or just cast it to a string if they don't handle streams.

In my draft I had "An implementation MAY accept other types, but MUST reject anything that it does not know how to turn into a string." on the setBody() method, which means you can choose to handle native streams in your implementation (though others would throw an exception).

Evert Pot

unread,
Aug 23, 2013, 7:39:40 AM8/23/13
to php...@googlegroups.com
On Aug 23, 2013, at 12:21 PM, Chris Wilkinson <chriswil...@gmail.com> wrote:

> Good to see this raised again; I have kept an eye on here, but my proposal was rather drowned out with all the caching/autoloading talk! I need to read through the new workflow stuff.
>
> The big areas that were up for discussion are headers (array vs collection, and should there be header objects - I did propose some interfaces) and URIs (strings aren't very useful - I had a separate PSR proposal at https://groups.google.com/forum/?fromgroups#!topic/php-fig/06BSXGqPRiU).
>
> Apart from that, I think it's mainly just polishing. (A lot of it writes itself, since it's following the RFCs.)

I'd also agree with pmjones and Paul D to not make the Http message interface depend on an uri interface.
I think creating a uri interface is a great idea though.. But http url's can easily be packed into a string.

I'd also vote to *not* add header collection objects. I think the current way this is handled is perfect.. Except that I would maybe not use setHeader() to also remove headers, and add a dedicated removeHeader() method, for clarity.

Evert

Phil Sturgeon

unread,
Aug 23, 2013, 9:59:29 AM8/23/13
to php...@googlegroups.com

On Thursday, 22 August 2013 16:17:17 UTC-4, Larry Garfield wrote:
That said, I'd prefer to get at least one of the three PSRs we just
approved for draft status (or are about to) put to bed first so we don't
flood ourselves with too many open discussions. That tends to not work
out so well. :-)

I really really hope we can get caching put to bed in the not too
distant future (all things being relative), after which I'll have more
time to devote to HTTP objects.

--Larry Garfield

Absolutely understandable, but this is early stages right now.

Finding the working group and putting together the meta doc will take a few weeks or a month, and getting it through the entrance vote takes another two weeks, so realistically now is the perfect time to start this up.

Chris: Would you take ownership as the Editor for this, and turn that PR into something that complies with the new Workflow Bylaw

Karsten Dambekalns

unread,
Aug 26, 2013, 4:43:57 AM8/26/13
to php...@googlegroups.com
Hi.

On 23. August2013 at 13:21:34 , Chris Wilkinson (chriswil...@gmail.com) wrote:
>Good to see this raised again; I have kept an eye on here, but my proposal
>was rather drowned out with all the caching/autoloading talk! I need to
>read through the new workflow stuff.

I think the open proposals should be dealt with before this one goes full speed, but count us in with this one. Robert created a pretty strict implementation of HTTP for Flow 2.0 which I'd like to point out here. I am sure it contains a lot to draw from.

https://git.typo3.org/Packages/TYPO3.Flow.git/tree/HEAD:/Classes/TYPO3/Flow/Http

Regards,
Karsten


Reply all
Reply to author
Forward
0 new messages