Psr18Transport::send()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 2
c 1
b 0
f 0
dl 0
loc 5
ccs 3
cts 3
cp 1
rs 10
cc 1
nc 1
nop 1
crap 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
    private ClientInterface $client;
27
28
    private string $uri;
29
30
    private array $headers;
31
32
    /**
33
     * @throws InvalidConfigException
34
     */
35
    public function __construct(ClientInterface $client, string $uri, array $headers = [])
36
    {
37
        if (!class_exists(Request::class)) {
38 8
            throw new InvalidConfigException(
39
                'Cannot create PSR-18 transport: package "nyholm/psr7" is required.'
40 8
            );
41
        }
42
43
        $this->client = $client;
44
        $this->uri = $uri;
45
        $this->headers = $headers;
46 8
47 8
        $this->headers['Content-Type'] = 'application/json';
48 8
    }
49
50 8
    public function send(string $request): string
51 8
    {
52
        $response = $this->sendRequest($request);
53 8
54
        return $this->getResponseContents($response);
55 8
    }
56
57 6
    /**
58
     * @throws RemoteProcedureCallFailedException
59
     */
60
    private function sendRequest(string $request): ResponseInterface
61
    {
62
        $psrRequest = new Request('POST', $this->uri, $this->headers, $request);
63 8
64
        try {
65 8
            $response = $this->client->sendRequest($psrRequest);
66
        } catch (ClientExceptionInterface $exception) {
67
            throw new RemoteProcedureCallFailedException(
68 8
                sprintf('JSON RPC request failed with error: %s.', $exception->getMessage()),
69 2
                0,
70 2
                $exception
71 2
            );
72 2
        }
73 2
74
        return $response;
75
    }
76
77 6
    /**
78
     * @throws RemoteProcedureCallFailedException
79
     */
80
    private function getResponseContents(ResponseInterface $response): string
81
    {
82
        $statusCode = $response->getStatusCode();
83 6
        $body = $response->getBody();
84
        $contents = $body->getContents();
85 6
86 6
        if (200 !== $statusCode) {
87 6
            throw new RemoteProcedureCallFailedException(
88
                sprintf('JSON RPC request failed with error %d: %s.', $statusCode, $contents)
89 6
            );
90 1
        }
91 1
92
        return $contents;
93
    }
94
}
95