Completed
Push — master ( d3ac62...0cb203 )
by Federico
02:08
created

lib/Elastica/Transport/Guzzle.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Elastica\Transport;
4
5
use Elastica\Connection;
6
use Elastica\Exception\Connection\GuzzleException;
7
use Elastica\Exception\PartialShardFailureException;
8
use Elastica\Exception\ResponseException;
9
use Elastica\JSON;
10
use Elastica\Request;
11
use Elastica\Response;
12
use Elastica\Util;
13
use GuzzleHttp\Client;
14
use GuzzleHttp\Exception\TransferException;
15
use GuzzleHttp\Psr7;
16
use GuzzleHttp\Psr7\Uri;
17
18
/**
19
 * Elastica Guzzle Transport object.
20
 *
21
 * @author Milan Magudia <[email protected]>
22
 */
23
class Guzzle extends AbstractTransport
24
{
25
    /**
26
     * Http scheme.
27
     *
28
     * @var string Http scheme
29
     */
30
    protected $_scheme = 'http';
31
32
    /**
33
     * Curl resource to reuse.
34
     *
35
     * @var Client Guzzle client to reuse
36
     */
37
    protected static $_guzzleClientConnection;
38
39
    /**
40
     * Makes calls to the elasticsearch server.
41
     *
42
     * All calls that are made to the server are done through this function
43
     *
44
     * @param \Elastica\Request $request
45
     * @param array             $params  Host, Port, ...
46
     *
47
     * @throws \Elastica\Exception\ConnectionException
48
     * @throws \Elastica\Exception\ResponseException
49
     * @throws \Elastica\Exception\Connection\HttpException
50
     *
51
     * @return \Elastica\Response Response object
52
     */
53
    public function exec(Request $request, array $params)
54
    {
55
        $connection = $this->getConnection();
56
57
        $client = $this->_getGuzzleClient($this->_getBaseUrl($connection), $connection->isPersistent(), $request);
58
59
        $options = [
60
            'exceptions' => false, // 4xx and 5xx is expected and NOT an exceptions in this context
61
        ];
62
        if ($connection->getTimeout()) {
63
            $options['timeout'] = $connection->getTimeout();
64
        }
65
66
        $proxy = $connection->getProxy();
67
68
        // See: https://github.com/facebook/hhvm/issues/4875
69 View Code Duplication
        if (is_null($proxy) && defined('HHVM_VERSION')) {
70
            $proxy = getenv('http_proxy') ?: null;
71
        }
72
73
        if (!is_null($proxy)) {
74
            $options['proxy'] = $proxy;
75
        }
76
77
        $req = $this->_createPsr7Request($request, $connection);
78
79
        try {
80
            $start = microtime(true);
81
            $res = $client->send($req, $options);
82
            $end = microtime(true);
83
        } catch (TransferException $ex) {
84
            throw new GuzzleException($ex, $request, new Response($ex->getMessage()));
85
        }
86
87
        $responseBody = (string) $res->getBody();
88
        $response = new Response($responseBody, $res->getStatusCode());
89
        $response->setQueryTime($end - $start);
90
        if ($connection->hasConfig('bigintConversion')) {
91
            $response->setJsonBigintConversion($connection->getConfig('bigintConversion'));
0 ignored issues
show
$connection->getConfig('bigintConversion') is of type array|string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
92
        }
93
94
        $response->setTransferInfo(
95
            [
96
                'request_header' => $request->getMethod(),
97
                'http_code' => $res->getStatusCode(),
98
                'body' => $responseBody,
99
            ]
100
        );
101
102
        if ($response->hasError()) {
103
            throw new ResponseException($request, $response);
104
        }
105
106
        if ($response->hasFailedShards()) {
107
            throw new PartialShardFailureException($request, $response);
108
        }
109
110
        return $response;
111
    }
112
113
    /**
114
     * @param Request    $request
115
     * @param Connection $connection
116
     *
117
     * @return Psr7\Request
118
     */
119
    protected function _createPsr7Request(Request $request, Connection $connection)
120
    {
121
        $req = new Psr7\Request(
122
            $request->getMethod(),
123
            $this->_getActionPath($request),
124
            $connection->hasConfig('headers') && is_array($connection->getConfig('headers'))
125
                ? $connection->getConfig('headers')
126
                : []
127
        );
128
129
        $data = $request->getData();
130
        if (!empty($data) || '0' === $data) {
131
            if (Request::GET == $req->getMethod()) {
132
                $req = $req->withMethod(Request::POST);
133
            }
134
135 View Code Duplication
            if ($this->hasParam('postWithRequestBody') && true == $this->getParam('postWithRequestBody')) {
136
                $request->setMethod(Request::POST);
137
                $req = $req->withMethod(Request::POST);
138
            }
139
140
            $req = $req->withBody(
141
                Psr7\stream_for(is_array($data)
142
                    ? JSON::stringify($data, JSON_UNESCAPED_UNICODE)
143
                    : $data
144
                )
145
            );
146
        }
147
148
        return $req;
149
    }
150
151
    /**
152
     * Return Guzzle resource.
153
     *
154
     * @param string  $baseUrl
155
     * @param bool    $persistent False if not persistent connection
156
     * @param Request $request    Elastica Request Object
157
     *
158
     * @return Client
159
     */
160
    protected function _getGuzzleClient($baseUrl, $persistent = true, Request $request)
161
    {
162
        if (!$persistent || !self::$_guzzleClientConnection) {
163
            self::$_guzzleClientConnection = new Client([
164
                'base_uri' => $baseUrl,
165
                'headers' => [
166
                    'Content-Type' => $request->getContentType(),
167
                ],
168
            ]);
169
        }
170
171
        return self::$_guzzleClientConnection;
172
    }
173
174
    /**
175
     * Builds the base url for the guzzle connection.
176
     *
177
     * @param \Elastica\Connection $connection
178
     *
179
     * @return string
180
     */
181
    protected function _getBaseUrl(Connection $connection)
182
    {
183
        // If url is set, url is taken. Otherwise port, host and path
184
        $url = $connection->hasConfig('url') ? $connection->getConfig('url') : '';
185
186
        if (!empty($url)) {
187
            $baseUri = $url;
188
        } else {
189
            $baseUri = (string) Uri::fromParts([
190
                'scheme' => $this->_scheme,
191
                'host' => $connection->getHost(),
192
                'port' => $connection->getPort(),
193
                'path' => ltrim('/', $connection->getPath()),
194
            ]);
195
        }
196
197
        return rtrim($baseUri, '/');
198
    }
199
200
    /**
201
     * Builds the action path url for each request.
202
     *
203
     * @param \Elastica\Request $request
204
     *
205
     * @return string
206
     */
207
    protected function _getActionPath(Request $request)
208
    {
209
        $action = $request->getPath();
210
        if ($action) {
211
            $action = '/'.ltrim($action, '/');
212
        }
213
214
        if (!Util::isDateMathEscaped($action)) {
215
            $action = Util::escapeDateMath($action);
216
        }
217
218
        $query = $request->getQuery();
219
220
        if (!empty($query)) {
221
            $action .= '?'.http_build_query(
222
                $this->sanityzeQueryStringBool($query)
223
                );
224
        }
225
226
        return $action;
227
    }
228
}
229