Skip to content
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
Closed

Reading post data example #137

Mikulas opened this issue Jan 20, 2013 · 11 comments
Labels

Comments

@Mikulas
Copy link

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
Copy link
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
Copy link
Author

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 as completed Jan 20, 2013
@igorw
Copy link
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
Copy link

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.

@zba
Copy link

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
Copy link

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
Copy link

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
Copy link
Member

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

@generak13
Copy link

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
Copy link

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
Copy link
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
Labels
Projects
None yet
Development

No branches or pull requests

9 participants