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

Reading post data example #137

Closed
Mikulas opened this Issue Jan 20, 2013 · 11 comments

Comments

Projects
None yet
9 participants
@Mikulas

Mikulas commented Jan 20, 2013

Hi,
could you please add an example of how post data would be read from request?
I tried reading the request as stream, but the result was empty so I suppose it's not the correct approach.

Request:
curl --data "key=value" http://127.0.0.1:1337

Thank you

@igorw

This comment has been minimized.

Contributor

igorw commented Jan 20, 2013

There is one feature missing before we can do this effectively, and that is detecting the end of the request. This is part of #3.

Once that is implemented, it should be possible to do this:

$http->on('request', function ($request, $response) {
    $sink = new React\Stream\BufferedSink();
    $request->pipe($sink);

    $sink->promise()->then(function ($requestBody) use ($response) {
        parse_str($requestBody, $requestData);
        var_dump($requestData);

        $response->writeHead();
        $response->end("Hi, thanks man.\n");
    });
});

The reason it is not possible currently is because the request does not emit an end event until the connection is closed.

@Mikulas

This comment has been minimized.

Mikulas commented Jan 20, 2013

That will be pretty cool indeed.
Alright, for the time being, I will read it with simple

$http->on('request', function ($req, $res) use ($container) {
    $req->on('data', function($data) use ($container, $req, $res) {

Thanks

@Mikulas Mikulas closed this Jan 20, 2013

@igorw

This comment has been minimized.

Contributor

igorw commented Jan 20, 2013

Yeah, you can read the individual chunks. And you can figure out yourself how to detect the last chunk (check #3). If you need any help, feel free to ask on IRC ;-)

@NateEag

This comment has been minimized.

NateEag commented Jan 13, 2014

I started prototyping an idea using React, and discovered a situation where I want to wait for the full request body pretty quickly.

Is a built-in solution to this any closer? Or are there any examples of detecting request-end without the framework's help?

I realize I'm necroing a long-closed thread, but it seemed more appropriate than starting a new ticket, since this is exactly what I'm curious about.

@cboden cboden added the question label May 13, 2014

@zba

This comment has been minimized.

zba commented May 15, 2014

to anybody who will get here, i made a dirty example of request data receive

    $app = function ($request, $response) {
       $requestBody='';
        $headers=$request->getHeaders();
        $contentLength=(int)$headers['Content-Length'];
        $receivedData=0;
        $request->on('data',function($data) 
            use ($request, $response,&$requestBody,&$receivedData,$contentLength) {
                $requestBody.=$data;
                $receivedData+=strlen($data);
                if ($receivedData>=$contentLength) {
                        parse_str($requestBody, $requestData);
                        print_r($requestData); //here is our data
                        $response->end();
                }
        });
    }
@ingus

This comment has been minimized.

ingus commented Apr 20, 2016

To anybody who will get here pulling out hair because of memory leaks on post data reading with the example code above, be sure to call not only $response -> end(), but $request -> close(); as well.

@generak13

This comment has been minimized.

generak13 commented Oct 15, 2016

Hi. Is 'end' event implemented correctly? It doesn't work for me.
Code posted by zba is a the only approach to receive full POST data?

@WyriHaximus

This comment has been minimized.

Member

WyriHaximus commented Oct 15, 2016

FYI the components have their on repository where development happens. In regards to POST data: reactphp/http#41 (comment)

@generak13

This comment has been minimized.

generak13 commented Dec 20, 2016

I just have noticed that the second chunk of POST data in event onData triggers in 1 second. If there are three or more chunks issue is still reproduced only for second chunk, for others guys all works fine. Any ideas?

@generak13

This comment has been minimized.

generak13 commented Dec 23, 2016

The problem was that I used cURL php library for sending request to server written on reactphp. As far as I can see, when I send long POST data cURL sets Expect: 100-continue header.
So it doesn't send POST body at this moment. That is why first chunk of the data on my server is empty. The example posted by zba does not handle this header.

I think that cURL has something like timeout. So it does not receive any response from the server and sends request again with the actual data.

In order to fix this problem you should remove the header Expect from the client request:
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));

or handle it on your server. I modified zba code example with something like this:

$app = function ($request, $response) {
       $requestBody='';
        $headers=$request->getHeaders();
        $contentLength=(int)$headers['Content-Length'];
        $receivedData=0;
        if($request->expectsContinue()) {
            $response->writeContinue();
            $request->close(); //Need I close request connection?
        }
        $request->on('data',function($data) 
            use ($request, $response,&$requestBody,&$receivedData,$contentLength) {
                $requestBody.=$data;
                $receivedData+=strlen($data);
                if ($receivedData>=$contentLength) {
                        parse_str($requestBody, $requestData);
                        print_r($requestData); //here is our data
                        $response->end();
                }
        });
    }
@clue

This comment has been minimized.

Member

clue commented Dec 23, 2016

@generak13 this is expected behavior as per the RFC, see also reactphp/http#47 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment