Sharing components between Zend_Http_Server and Client

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Sharing components between Zend_Http_Server and Client

Shahar Evron
Hi,

Stefan and I recently started working on a proposal that will finalize
the implementation of the new (now in incubator) Zend_Http_Client. We
plan some changes to the structure, but no dramatic interface changes.

Mat proposed, and I agree, that it would be a good idea to discuss what
can be shared between the Client and Server components. Namely, both
share the need to handle HTTP messages (requests and responses).

The obvious part is that the server will probably be generating HTTP
responses while parsing HTTP requests, and the client will do the
opposite. Since requests and responses are quite similar in structure,
it might be a smart idea to design a common Zend_Http_Message class, and
then Zend_Http_Request and Zend_Http_Response (which already exists)
classes that inherit it. These classes could be used to both construct a
request / response, and parse it - and provide easy access to it's
different parts (headers, body, etc.)

My general thought is similar in design to the incubator
Zend_Http_Response class, having a factory method that parses a "string"
response and a public constructor, that can be used to create a request
/ response from scratch. Currently, the Response class provides only
getter methods (because I didn't plan to "build" HTTP responses, only
parse them), but we can add those so that the server can use the same
class to build a response.

I'd really like to hear everyone's comments on this. If you feel that a
set of common code should be proposed (which makes sense of course), we
should get working on that because we were planning to push
Zend_Http_Client out of the incubator in a couple of weeks - so if
further design changes are to be made, it's important that we do them
quickly.

TIA,

Shahar.
Reply | Threaded
Open this post in threaded view
|

Re: Sharing components between Zend_Http_Server and Client

Mat Scales
Hi,

 From the perspective of Zend_Http_Server, this sounds ideal.  The only
change I would make would be to add a method to both Request and
Response that returns the request/response as a string, ready to send to
the server/client as well as the factory method for doing the reverse.

A possible unit test for this would be to assert that, for valid requests:

$request = 'some http request as a string';
Zend_Http_Request::Parse( $request )->toString() === $request;

and the same for a response.

There are some benefits and some problems that follow as a direct result
of this shared codebase.  The major benefit is that a bug fixed in this
layer will apply to both the server and the client.  The main problem is
that if a non-standard behaviour is present in the shared layer, a unit
test involving a zend client talking to a zend server may not fail when
it should.



Shahar Evron wrote:

> Hi,
>
> Stefan and I recently started working on a proposal that will finalize
> the implementation of the new (now in incubator) Zend_Http_Client. We
> plan some changes to the structure, but no dramatic interface changes.
>
> Mat proposed, and I agree, that it would be a good idea to discuss what
> can be shared between the Client and Server components. Namely, both
> share the need to handle HTTP messages (requests and responses).
>
> The obvious part is that the server will probably be generating HTTP
> responses while parsing HTTP requests, and the client will do the
> opposite. Since requests and responses are quite similar in structure,
> it might be a smart idea to design a common Zend_Http_Message class, and
> then Zend_Http_Request and Zend_Http_Response (which already exists)
> classes that inherit it. These classes could be used to both construct a
> request / response, and parse it - and provide easy access to it's
> different parts (headers, body, etc.)
>
> My general thought is similar in design to the incubator
> Zend_Http_Response class, having a factory method that parses a "string"
> response and a public constructor, that can be used to create a request
> / response from scratch. Currently, the Response class provides only
> getter methods (because I didn't plan to "build" HTTP responses, only
> parse them), but we can add those so that the server can use the same
> class to build a response.
>
> I'd really like to hear everyone's comments on this. If you feel that a
> set of common code should be proposed (which makes sense of course), we
> should get working on that because we were planning to push
> Zend_Http_Client out of the incubator in a couple of weeks - so if
> further design changes are to be made, it's important that we do them
> quickly.
>
> TIA,
>
> Shahar.
>  

Reply | Threaded
Open this post in threaded view
|

Re: Sharing components between Zend_Http_Server and Client

Shahar Evron
Hi Mat,

A toString() method as you suggested should already exist in
Zend_Http_Response (if it doesn't, I'm stupid ;) ) - It is a very good
idea of course. Although I'm not sure if we should use the magic
__toString() here. Any thoughts?

About non standard behavior: My general thumb rule with Zend_Http_Client
and Zend_Http_Response (proposed by the list) was to always generate
standard requests, but be a bit more flexible when parsing responses. I
think the rule for Zend_Http_Server and Zend_Http_Request should be no
different.

Can you give an example of the problems that might arise from this?

Rgrds,

Shahar.

Mat Scales wrote:

> Hi,
>
> From the perspective of Zend_Http_Server, this sounds ideal.  The only
> change I would make would be to add a method to both Request and
> Response that returns the request/response as a string, ready to send to
> the server/client as well as the factory method for doing the reverse.
>
> A possible unit test for this would be to assert that, for valid requests:
>
> $request = 'some http request as a string';
> Zend_Http_Request::Parse( $request )->toString() === $request;
>
> and the same for a response.
>
> There are some benefits and some problems that follow as a direct result
> of this shared codebase.  The major benefit is that a bug fixed in this
> layer will apply to both the server and the client.  The main problem is
> that if a non-standard behaviour is present in the shared layer, a unit
> test involving a zend client talking to a zend server may not fail when
> it should.
>
>
>
> Shahar Evron wrote:
>> Hi,
>>
>> Stefan and I recently started working on a proposal that will finalize
>> the implementation of the new (now in incubator) Zend_Http_Client. We
>> plan some changes to the structure, but no dramatic interface changes.
>>
>> Mat proposed, and I agree, that it would be a good idea to discuss what
>> can be shared between the Client and Server components. Namely, both
>> share the need to handle HTTP messages (requests and responses).
>>
>> The obvious part is that the server will probably be generating HTTP
>> responses while parsing HTTP requests, and the client will do the
>> opposite. Since requests and responses are quite similar in structure,
>> it might be a smart idea to design a common Zend_Http_Message class, and
>> then Zend_Http_Request and Zend_Http_Response (which already exists)
>> classes that inherit it. These classes could be used to both construct a
>> request / response, and parse it - and provide easy access to it's
>> different parts (headers, body, etc.)
>>
>> My general thought is similar in design to the incubator
>> Zend_Http_Response class, having a factory method that parses a "string"
>> response and a public constructor, that can be used to create a request
>> / response from scratch. Currently, the Response class provides only
>> getter methods (because I didn't plan to "build" HTTP responses, only
>> parse them), but we can add those so that the server can use the same
>> class to build a response.
>>
>> I'd really like to hear everyone's comments on this. If you feel that a
>> set of common code should be proposed (which makes sense of course), we
>> should get working on that because we were planning to push
>> Zend_Http_Client out of the incubator in a couple of weeks - so if
>> further design changes are to be made, it's important that we do them
>> quickly.
>>
>> TIA,
>>
>> Shahar.
>>  
>
>
Reply | Threaded
Open this post in threaded view
|

Re: Sharing components between Zend_Http_Server and Client

Mat Scales
Shahar Evron wrote:
> Hi Mat,
>
> A toString() method as you suggested should already exist in
> Zend_Http_Response (if it doesn't, I'm stupid ;) ) - It is a very good
> idea of course. Although I'm not sure if we should use the magic
> __toString() here. Any thoughts?
>  
The version I developed my prototype server against did not - I had to
write it myself :)

I didn't like to use the magic method either.
> About non standard behavior: My general thumb rule with Zend_Http_Client
> and Zend_Http_Response (proposed by the list) was to always generate
> standard requests, but be a bit more flexible when parsing responses. I
> think the rule for Zend_Http_Server and Zend_Http_Request should be no
> different.
>
> Can you give an example of the problems that might arise from this?
>  
Obviously the aim is to create to the standards, but as an example, lets
say that our implementation of the Request accidentally used the @
character as the path seperator in URIs.  Then the zend client would
generate requests like:

GET @[hidden email] HTTP/1.1

and the zend server would happily decode that - but any real
client/server would be distinctly unhappy!

It's a stupid example, as it would become obvious pretty quickly, but it
demonstrates why we should be wary of unit tests that only involve a
zend server and zend client.

> Rgrds,
>
> Shahar.
>
> Mat Scales wrote:
>  
>> Hi,
>>
>> From the perspective of Zend_Http_Server, this sounds ideal.  The only
>> change I would make would be to add a method to both Request and
>> Response that returns the request/response as a string, ready to send to
>> the server/client as well as the factory method for doing the reverse.
>>
>> A possible unit test for this would be to assert that, for valid requests:
>>
>> $request = 'some http request as a string';
>> Zend_Http_Request::Parse( $request )->toString() === $request;
>>
>> and the same for a response.
>>
>> There are some benefits and some problems that follow as a direct result
>> of this shared codebase.  The major benefit is that a bug fixed in this
>> layer will apply to both the server and the client.  The main problem is
>> that if a non-standard behaviour is present in the shared layer, a unit
>> test involving a zend client talking to a zend server may not fail when
>> it should.
>>
>>
>>
>> Shahar Evron wrote:
>>    
>>> Hi,
>>>
>>> Stefan and I recently started working on a proposal that will finalize
>>> the implementation of the new (now in incubator) Zend_Http_Client. We
>>> plan some changes to the structure, but no dramatic interface changes.
>>>
>>> Mat proposed, and I agree, that it would be a good idea to discuss what
>>> can be shared between the Client and Server components. Namely, both
>>> share the need to handle HTTP messages (requests and responses).
>>>
>>> The obvious part is that the server will probably be generating HTTP
>>> responses while parsing HTTP requests, and the client will do the
>>> opposite. Since requests and responses are quite similar in structure,
>>> it might be a smart idea to design a common Zend_Http_Message class, and
>>> then Zend_Http_Request and Zend_Http_Response (which already exists)
>>> classes that inherit it. These classes could be used to both construct a
>>> request / response, and parse it - and provide easy access to it's
>>> different parts (headers, body, etc.)
>>>
>>> My general thought is similar in design to the incubator
>>> Zend_Http_Response class, having a factory method that parses a "string"
>>> response and a public constructor, that can be used to create a request
>>> / response from scratch. Currently, the Response class provides only
>>> getter methods (because I didn't plan to "build" HTTP responses, only
>>> parse them), but we can add those so that the server can use the same
>>> class to build a response.
>>>
>>> I'd really like to hear everyone's comments on this. If you feel that a
>>> set of common code should be proposed (which makes sense of course), we
>>> should get working on that because we were planning to push
>>> Zend_Http_Client out of the incubator in a couple of weeks - so if
>>> further design changes are to be made, it's important that we do them
>>> quickly.
>>>
>>> TIA,
>>>
>>> Shahar.
>>>  
>>>      
>>    

Reply | Threaded
Open this post in threaded view
|

Re: Sharing components between Zend_Http_Server and Client

Shahar Evron
Hi,

> Obviously the aim is to create to the standards, but as an example, lets
> say that our implementation of the Request accidentally used the @
> character as the path seperator in URIs.  Then the zend client would
> generate requests like:
>
> GET @[hidden email] HTTP/1.1
>
> and the zend server would happily decode that - but any real
> client/server would be distinctly unhappy!
>
> It's a stupid example, as it would become obvious pretty quickly, but it
> demonstrates why we should be wary of unit tests that only involve a
> zend server and zend client.

I see your point now (stupid example, but works for me!). It's just
problematic to test ourselves with our own code. I guess the answer
might be to make sure that the request / response classes not only
generate and parse their own code, but also get some "valid" request /
response texts and make sure we can generate *exactly* the same string.

I always had problems testing the Zend_Http_Client. I had to relay on
some external Apache and PHP scripts - otherwise I didn't see any useful
way to test it. This is definitely not an easy task.

Shahar.


>> Mat Scales wrote:
>>  
>>> Hi,
>>>
>>> From the perspective of Zend_Http_Server, this sounds ideal.  The only
>>> change I would make would be to add a method to both Request and
>>> Response that returns the request/response as a string, ready to send to
>>> the server/client as well as the factory method for doing the reverse.
>>>
>>> A possible unit test for this would be to assert that, for valid
>>> requests:
>>>
>>> $request = 'some http request as a string';
>>> Zend_Http_Request::Parse( $request )->toString() === $request;
>>>
>>> and the same for a response.
>>>
>>> There are some benefits and some problems that follow as a direct result
>>> of this shared codebase.  The major benefit is that a bug fixed in this
>>> layer will apply to both the server and the client.  The main problem is
>>> that if a non-standard behaviour is present in the shared layer, a unit
>>> test involving a zend client talking to a zend server may not fail when
>>> it should.
>>>
>>>
>>>
>>> Shahar Evron wrote:
>>>    
>>>> Hi,
>>>>
>>>> Stefan and I recently started working on a proposal that will finalize
>>>> the implementation of the new (now in incubator) Zend_Http_Client. We
>>>> plan some changes to the structure, but no dramatic interface changes.
>>>>
>>>> Mat proposed, and I agree, that it would be a good idea to discuss what
>>>> can be shared between the Client and Server components. Namely, both
>>>> share the need to handle HTTP messages (requests and responses).
>>>>
>>>> The obvious part is that the server will probably be generating HTTP
>>>> responses while parsing HTTP requests, and the client will do the
>>>> opposite. Since requests and responses are quite similar in structure,
>>>> it might be a smart idea to design a common Zend_Http_Message class,
>>>> and
>>>> then Zend_Http_Request and Zend_Http_Response (which already exists)
>>>> classes that inherit it. These classes could be used to both
>>>> construct a
>>>> request / response, and parse it - and provide easy access to it's
>>>> different parts (headers, body, etc.)
>>>>
>>>> My general thought is similar in design to the incubator
>>>> Zend_Http_Response class, having a factory method that parses a
>>>> "string"
>>>> response and a public constructor, that can be used to create a request
>>>> / response from scratch. Currently, the Response class provides only
>>>> getter methods (because I didn't plan to "build" HTTP responses, only
>>>> parse them), but we can add those so that the server can use the same
>>>> class to build a response.
>>>>
>>>> I'd really like to hear everyone's comments on this. If you feel that a
>>>> set of common code should be proposed (which makes sense of course), we
>>>> should get working on that because we were planning to push
>>>> Zend_Http_Client out of the incubator in a couple of weeks - so if
>>>> further design changes are to be made, it's important that we do them
>>>> quickly.
>>>>
>>>> TIA,
>>>>
>>>> Shahar.
>>>>        
>>>    
>
>