Here is a pull request that is related:

https://github.com/fabpot/symfony/pull/182

--
Fabien Potencier
Sensio CEO - symfony lead developer
sensiolabs.com | symfony-project.org | fabien.potencier.org
Tél: +33 1 40 99 80 80

On 11/29/10 3:53 PM, Nicolas A. Bérard-Nault wrote:
Hi,

2010/11/26 Nicolas A. Bérard-Nault <[email protected]
<mailto:[email protected]>>

    Hi,

    I am writing a test for a REST controller which uses the PUT http
    method. Here is an excerpt of code showing how Symfony 2's test
    client handles request parameters:

    if (in_array(strtolower($method), array('post', 'put', 'delete'))) {
                 $request = $parameters;
                 $query = array();
                 $defaults['CONTENT_TYPE'] =
    'application/x-www-form-urlencoded';
    }

    Unfortunately, that is not PHP's default behavior for PUT. This
    works as expected for POST but not for PUT, as the request has to be
    explicitly read from php://input, as explained on
    http://php.net/manual/en/features.file-upload.put-method.php.
    According to my tests, the content body of the request is not parsed
    into $_POST when the method is PUT. The test client's behavior is
    different from PHP's behavior. Hence, I have two questions:

    1) What would be the best way to support this in the test client ? I
    doubt it is possible for the test client to write on php://input so
    I fail to see what options we have there.
    2) What would be the best way to support this  seamlessly with the
    Request object, considering that PUT can be used to send something
    else than files, especially in a REST context ?

After crawling through the code, here are my conclusions, albeit rather
shallow.

The HttpFoundation\Request class' constructor has the following parameters:
     array $query = null, array $request = null, array $attributes =
null, array $cookies = null, array $files = null, array $server = null

The two first parameters are hashmaps that map directly to $_GET and
$_POST. Although sufficient for many applications, this is unfortunately
a huge limitation. It becomes very apparent when one deals with, for
example, JSON requests, which need to be read and parsed differently
than url encoded requests. $_POST is only meaningful in a very limited,
although very common, subset of requests bodies, namely url encoded
key-values, mostly passed by html forms.

The request can in fact be of any content-type and this is unfortunately
currently unsupported. Hence, when dealing with a JSON request:

1) In the code, it is impossible to use the Request object :
file_get_contents('php://input') has to be used directly to read the
content, which defeats the purpose of having an abstraction.
2) It is impossible to test any code that uses php://input as the test
client assumes url encoded data and does not provide any facility to
hijack PHP's stream.

My proposition is simple: the Request class should lay its bases closer
to the HTTP RFC rather than using PHP's superglobals.

1) For the request parameter, the default constructor should only accept
low-level, unparsed data. In the event that the content-type of the
request happens to be url-encoded, then it would be possible to obtain
the parsed array of parameters using a method on the object with code
along the lines of:

$urlencodedRequest =  file_get_contents('php://input');
$_POST == $queryParameters = parse_str($urlencodedRequest); // Equality
only there for illustration purposes

2) A factory method could be used to create a vanilla Request object
with an url encoded request body, which is really a "specification" of
the much broader concept of an HTTP request. Other such specifications
(although I can't think of any right now) could also warrant factory
methods. Such a method could use $_POST directly.

Now, I fear this is not trivial to implement and will need a lot of
discussions and love, which I'm ready to give in profuse amount. Since
I'm not that well acquainted with the framework, I'll need your advice
and I hence thank you in advance for your time.

NABN.

    Thank you for your comments,
    --
    Nicolas A. Bérard-Nault ([email protected] <mailto:[email protected]>)




--
Nicolas A. Bérard-Nault ([email protected] <mailto:[email protected]>)

--
If you want to report a vulnerability issue on symfony, please send it
to security at symfony-project.com

You received this message because you are subscribed to the Google
Groups "symfony developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/symfony-devs?hl=en

--
If you want to report a vulnerability issue on symfony, please send it to 
security at symfony-project.com

You received this message because you are subscribed to the Google
Groups "symfony developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/symfony-devs?hl=en

Reply via email to