Completed
Pull Request — master (#7)
by Igor
04:25
created

Psr18Transport::sendRequest()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 8
c 1
b 0
f 0
dl 0
loc 15
rs 10
cc 2
nc 2
nop 1
1
<?php
2
/*
3
 * This file is part of JSON RPC Client.
4
 *
5
 * (c) Igor Lazarev <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Strider2038\JsonRpcClient\Transport\Http;
12
13
use Nyholm\Psr7\Request;
14
use Psr\Http\Client\ClientExceptionInterface;
15
use Psr\Http\Client\ClientInterface;
16
use Psr\Http\Message\ResponseInterface;
17
use Strider2038\JsonRpcClient\Exception\InvalidConfigException;
18
use Strider2038\JsonRpcClient\Exception\RemoteProcedureCallFailedException;
19
use Strider2038\JsonRpcClient\Transport\TransportInterface;
20
21
/**
22
 * @author Igor Lazarev <[email protected]>
23
 */
24
class Psr18Transport implements TransportInterface
25
{
26
    /** @var ClientInterface */
27
    private $client;
28
29
    /** @var string */
30
    private $uri;
31
32
    /** @var array */
33
    private $headers;
34
35
    /**
36
     * @throws InvalidConfigException
37
     */
38
    public function __construct(ClientInterface $client, string $uri, array $headers = [])
39
    {
40
        if (!class_exists(Request::class)) {
41
            throw new InvalidConfigException(
42
                'Cannot create PSR-18 transport: package "nyholm/psr7" is required.'
43
            );
44
        }
45
46
        $this->client = $client;
47
        $this->uri = $uri;
48
        $this->headers = $headers;
49
50
        $this->headers['Content-Type'] = 'application/json';
51
    }
52
53
    public function send(string $request): string
54
    {
55
        $response = $this->sendRequest($request);
56
57
        return $this->getResponseContents($response);
58
    }
59
60
    /**
61
     * @throws RemoteProcedureCallFailedException
62
     */
63
    private function sendRequest(string $request): ResponseInterface
64
    {
65
        $psrRequest = new Request('POST', $this->uri, $this->headers, $request);
66
67
        try {
68
            $response = $this->client->sendRequest($psrRequest);
69
        } catch (ClientExceptionInterface $exception) {
70
            throw new RemoteProcedureCallFailedException(
71
                sprintf('JSON RPC request failed with error: %s.', $exception->getMessage()),
72
                0,
73
                $exception
74
            );
75
        }
76
77
        return $response;
78
    }
79
80
    /**
81
     * @throws RemoteProcedureCallFailedException
82
     */
83
    private function getResponseContents(ResponseInterface $response): string
84
    {
85
        $statusCode = $response->getStatusCode();
86
        $body = $response->getBody();
87
        $contents = $body->getContents();
88
89
        if (200 !== $statusCode) {
90
            throw new RemoteProcedureCallFailedException(
91
                sprintf('JSON RPC request failed with error %d: %s.', $statusCode, $contents)
92
            );
93
        }
94
95
        return $contents;
96
    }
97
}
98