Completed
Push — master ( 8a6a3b...86b2ed )
by Nicolas
03:28
created

HttpAdapter::_createHttpAdapterRequest()   B

Complexity

Conditions 8
Paths 18

Size

Total Lines 28

Duplication

Lines 4
Ratio 14.29 %

Importance

Changes 0
Metric Value
dl 4
loc 28
rs 8.4444
c 0
b 0
f 0
cc 8
nc 18
nop 2
1
<?php
2
namespace Elastica\Transport;
3
4
use Elastica\Connection;
5
use Elastica\Exception\PartialShardFailureException;
6
use Elastica\Exception\ResponseException;
7
use Elastica\JSON;
8
use Elastica\Request as ElasticaRequest;
9
use Elastica\Response as ElasticaResponse;
10
use Elastica\Util;
11
use Ivory\HttpAdapter\HttpAdapterInterface;
12
use Ivory\HttpAdapter\Message\Request as HttpAdapterRequest;
13
use Ivory\HttpAdapter\Message\Response as HttpAdapterResponse;
14
use Ivory\HttpAdapter\Message\Stream\StringStream;
15
16
class HttpAdapter extends AbstractTransport
17
{
18
    /**
19
     * @var HttpAdapterInterface
20
     */
21
    private $httpAdapter;
22
23
    /**
24
     * @var string
25
     */
26
    private $_scheme = 'http';
27
28
    /**
29
     * Construct transport.
30
     *
31
     * @param Connection           $connection
32
     * @param HttpAdapterInterface $httpAdapter
33
     */
34
    public function __construct(Connection $connection = null, HttpAdapterInterface $httpAdapter)
35
    {
36
        parent::__construct($connection);
37
        $this->httpAdapter = $httpAdapter;
38
    }
39
40
    /**
41
     * Makes calls to the elasticsearch server.
42
     *
43
     * All calls that are made to the server are done through this function
44
     *
45
     * @param \Elastica\Request $elasticaRequest
46
     * @param array             $params          Host, Port, ...
47
     *
48
     * @throws \Elastica\Exception\ConnectionException
49
     * @throws \Elastica\Exception\ResponseException
50
     * @throws \Elastica\Exception\Connection\HttpException
51
     *
52
     * @return \Elastica\Response Response object
53
     */
54
    public function exec(ElasticaRequest $elasticaRequest, array $params)
55
    {
56
        $connection = $this->getConnection();
57
58
        if ($timeout = $connection->getTimeout()) {
59
            $this->httpAdapter->getConfiguration()->setTimeout($timeout);
60
        }
61
62
        $httpAdapterRequest = $this->_createHttpAdapterRequest($elasticaRequest, $connection);
63
64
        $start = microtime(true);
65
        $httpAdapterResponse = $this->httpAdapter->sendRequest($httpAdapterRequest);
66
        $end = microtime(true);
67
68
        $elasticaResponse = $this->_createElasticaResponse($httpAdapterResponse);
69
        $elasticaResponse->setQueryTime($end - $start);
70
71
        $elasticaResponse->setTransferInfo(
72
            [
73
                'request_header' => $httpAdapterRequest->getMethod(),
74
                'http_code' => $httpAdapterResponse->getStatusCode(),
75
            ]
76
        );
77
78
        if ($elasticaResponse->hasError()) {
79
            throw new ResponseException($elasticaRequest, $elasticaResponse);
80
        }
81
82
        if ($elasticaResponse->hasFailedShards()) {
83
            throw new PartialShardFailureException($elasticaRequest, $elasticaResponse);
84
        }
85
86
        return $elasticaResponse;
87
    }
88
89
    /**
90
     * @param HttpAdapterResponse $httpAdapterResponse
91
     *
92
     * @return ElasticaResponse
93
     */
94
    protected function _createElasticaResponse(HttpAdapterResponse $httpAdapterResponse)
95
    {
96
        return new ElasticaResponse((string) $httpAdapterResponse->getBody(), $httpAdapterResponse->getStatusCode());
97
    }
98
99
    /**
100
     * @param ElasticaRequest $elasticaRequest
101
     * @param Connection      $connection
102
     *
103
     * @return HttpAdapterRequest
104
     */
105
    protected function _createHttpAdapterRequest(ElasticaRequest $elasticaRequest, Connection $connection)
106
    {
107
        $data = $elasticaRequest->getData();
108
        $body = null;
109
        $method = $elasticaRequest->getMethod();
110
        $headers = $connection->hasConfig('headers') ?: [];
111
        if (!empty($data) || '0' === $data) {
112
            if ($method == ElasticaRequest::GET) {
113
                $method = ElasticaRequest::POST;
114
            }
115
116 View Code Duplication
            if ($this->hasParam('postWithRequestBody') && $this->getParam('postWithRequestBody') == true) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
117
                $elasticaRequest->setMethod(ElasticaRequest::POST);
118
                $method = ElasticaRequest::POST;
119
            }
120
121
            if (is_array($data)) {
122
                $body = JSON::stringify($data, JSON_UNESCAPED_UNICODE);
123
            } else {
124
                $body = $data;
125
            }
126
        }
127
128
        $url = $this->_getUri($elasticaRequest, $connection);
129
        $streamBody = new StringStream($body);
130
131
        return new HttpAdapterRequest($url, $method, HttpAdapterRequest::PROTOCOL_VERSION_1_1, $headers, $streamBody);
132
    }
133
134
    /**
135
     * @param ElasticaRequest      $request
136
     * @param \Elastica\Connection $connection
137
     *
138
     * @return string
139
     */
140
    protected function _getUri(ElasticaRequest $request, Connection $connection)
141
    {
142
        $url = $connection->hasConfig('url') ? $connection->getConfig('url') : '';
143
144 View Code Duplication
        if (!empty($url)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
145
            $baseUri = $url;
146
        } else {
147
            $baseUri = $this->_scheme.'://'.$connection->getHost().':'.$connection->getPort().'/'.$connection->getPath();
148
        }
149
150
        $requestPath = $request->getPath();
151
        if (!Util::isDateMathEscaped($requestPath)) {
152
            $requestPath = Util::escapeDateMath($requestPath);
153
        }
154
155
        $baseUri .= $requestPath;
156
157
        $query = $request->getQuery();
158
159
        if (!empty($query)) {
160
            $baseUri .= '?'.http_build_query($query);
161
        }
162
163
        return $baseUri;
164
    }
165
}
166