Skip to content

Forwarding requests to multiple ports as json. Second one arrives empty. #387

Description

@eitelkrauss

Trying to forward requests to multiple ports as application/json, but the second request arrives empty. This doesn't happen when sent as text/plain.


<?php

require_once 'vendor/autoload.php';

$loop = \React\EventLoop\Factory::create();

$browser = new \React\Http\Browser($loop);

$clients = ["http://127.0.0.1:8001", "http://127.0.0.1:8002"];

$server = new \React\Http\Server($loop, function (\Psr\Http\Message\ServerRequestInterface $request) use ($browser, $clients){
    
    # forward requests to multiple ports as json
    foreach($clients as $client){
        $browser->post(
            $client,
            ['Content-Type' => 'application/json'],
            $request->getBody()
        )
    }
    # this works and is received on both 8001, 8002
    foreach($clients as $client){
        $browser->post(
            $client,
            ['Content-Type' => 'text/plain'],
            "hello"
        )
    }
});

$socket = new \React\Socket\Server('127.0.0.1:8000', $loop);

$server->listen($socket);

$loop->run();

Activity

  1. legionth commented on Aug 25, 2020

    @legionth
    Contributor

    The request uses a RingCentral\Psr7\BufferStream as return value of $request->getBody(). By calling $request->getBody() this buffer will be emptied and is not available for our future requests.

    What you may want is to call $request->getBody()->getContents() and save the value to a variable for reusage.
    e.g.

    $server = new \React\Http\Server($loop, function (\Psr\Http\Message\ServerRequestInterface $request) use ($browser, $clients){
        
        $body = $request->getBody()->getContents();
    
        # forward requests to multiple ports as json
        foreach($clients as $client){
            $browser->post(
                $client,
                ['Content-Type' => 'application/json'],
                $body
            )
        }
        # this works and is received on both 8001, 8002
        foreach($clients as $client){
            $browser->post(
                $client,
                ['Content-Type' => 'text/plain'],
                "hello"
            )
        }
    });

    I hope this helps 👍

  2. eitelkrauss commented on Aug 26, 2020

    @eitelkrauss
    Author

    @legionth works! thank you!! :)

  3. clue commented on Sep 16, 2020

    @clue
    Member

    @eitelkrauss Thanks for bringing this up!

    I agree that only being able to read the request body once (and only for some requests) is somewhat inconsistent, so I've just filed #395 to make sure you can always read the raw request body. Note that the getContents() method will only read the remainder of the buffer as per the PSR-7 definition. Reading will advance this previous position, so a second call will return an empty string unless you rewind() or seek() the request body.

    In your specific use case, assigning this to a string once and reusing this sounds like a reasonable alternative 👍

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions