Clue\React\Buzz\Io\Sender::send PHP Method

send() public method

public send ( Psr\Http\Message\RequestInterface $request, MessageFactory $messageFactory ) : PromiseInterface
$request Psr\Http\Message\RequestInterface
$messageFactory Clue\React\Buzz\Message\MessageFactory
return PromiseInterface Promise
    public function send(RequestInterface $request, MessageFactory $messageFactory)
    {
        $uri = $request->getUri();
        // URIs are required to be absolute for the HttpClient to work
        if ($uri->getScheme() === '' || $uri->getHost() === '') {
            return Promise\reject(new \InvalidArgumentException('Sending request requires absolute URI with scheme and host'));
        }
        $body = $request->getBody();
        // automatically assign a Content-Length header if the body size is known
        if ($body->getSize() !== null && $body->getSize() !== 0 && $request->hasHeader('Content-Length') !== null) {
            $request = $request->withHeader('Content-Length', $body->getSize());
        }
        if ($body instanceof ReadableStreamInterface && $body->isReadable() && !$request->hasHeader('Content-Length')) {
            $request = $request->withHeader('Transfer-Encoding', 'chunked');
        }
        $headers = array();
        foreach ($request->getHeaders() as $name => $values) {
            $headers[$name] = implode(', ', $values);
        }
        $deferred = new Deferred();
        $requestStream = $this->http->request($request->getMethod(), (string) $uri, $headers, $request->getProtocolVersion());
        $requestStream->on('error', function ($error) use($deferred) {
            $deferred->reject($error);
        });
        $requestStream->on('response', function (ResponseStream $responseStream) use($deferred, $messageFactory) {
            // apply response header values from response stream
            $deferred->resolve($messageFactory->response($responseStream->getVersion(), $responseStream->getCode(), $responseStream->getReasonPhrase(), $responseStream->getHeaders(), $responseStream));
        });
        if ($body instanceof ReadableStreamInterface) {
            if ($body->isReadable()) {
                if ($request->hasHeader('Content-Length')) {
                    // length is known => just write to request
                    $body->pipe($requestStream);
                } else {
                    // length unknown => apply chunked transfer-encoding
                    // this should be moved somewhere else obviously
                    $body->on('data', function ($data) use($requestStream) {
                        $requestStream->write(dechex(strlen($data)) . "\r\n" . $data . "\r\n");
                    });
                    $body->on('end', function () use($requestStream) {
                        $requestStream->end("0\r\n\r\n");
                    });
                }
            } else {
                // stream is not readable => end request without body
                $requestStream->end();
            }
        } else {
            // body is fully buffered => write as one chunk
            $requestStream->end((string) $body);
        }
        return $deferred->promise();
    }

Usage Example

コード例 #1
0
ファイル: SenderTest.php プロジェクト: clue/buzz-react
 /**
  * @dataProvider provideRequestProtocolVersion
  */
 public function testRequestProtocolVersion(Request $Request, $method, $uri, $headers, $protocolVersion)
 {
     $httpClientArguments = array();
     $ref = new \ReflectionClass('React\\HttpClient\\Client');
     if ($ref->getConstructor()->getNumberOfRequiredParameters() == 3) {
         $httpClientArguments[] = $this->getMock('React\\EventLoop\\LoopInterface');
     }
     $httpClientArguments[] = $this->getMock('React\\SocketClient\\ConnectorInterface');
     $httpClientArguments[] = $this->getMock('React\\SocketClient\\ConnectorInterface');
     $http = $this->getMock('React\\HttpClient\\Client', array('request'), $httpClientArguments);
     $requestArguments = array();
     $ref = new \ReflectionClass('React\\HttpClient\\Request');
     if ($ref->getConstructor()->getNumberOfRequiredParameters() == 3) {
         $requestArguments[] = $this->getMock('React\\EventLoop\\LoopInterface');
     }
     $requestArguments[] = $this->getMock('React\\SocketClient\\ConnectorInterface');
     $requestArguments[] = new RequestData($method, $uri, $headers, $protocolVersion);
     $request = $this->getMock('React\\HttpClient\\Request', array(), $requestArguments);
     $http->expects($this->once())->method('request')->with($method, $uri, $headers, $protocolVersion)->willReturn($request);
     $sender = new Sender($http);
     $sender->send($Request, $this->getMock('Clue\\React\\Buzz\\Message\\MessageFactory'));
 }