1[[per_request_configuration]]
2== Per-request configuration
3
4There are several configurations that can be set on a per-request basis, rather than at a connection- or client-level.
5These are specified as part of the request associative array.
6
7=== Ignoring exceptions
8The library attempts to throw exceptions for common problems.  These exceptions match the HTTP response code provided
9by Elasticsearch.  For example, attempting to GET a nonexistent document will throw a `MissingDocument404Exception`.
10
11Exceptions are a useful and consistent way to deal with problems like missing documents, syntax errors, version
12conflicts, etc.  But sometimes you want to deal with the response body rather than catch exceptions (often useful
13in test suites).
14
15If you need that behavior, you can configure an `ignore` parameter.  This should be configured in the `client` parameter
16of the request array.  For example, this example will ignore the `MissingDocument404Exception`
17exception and instead return the JSON provided by Elasticsearch.
18
19
20[source,php]
21----
22$client = ClientBuilder::create()->build();
23
24$params = [
25    'index'  => 'test_missing',
26    'id'     => 1,
27    'client' => [ 'ignore' => 404 ] <1>
28];
29echo $client->get($params);
30
31> {"_index":"test_missing","_type":"_doc","_id":"1","found":false}
32----
33<1> This will ignore just the 404 missing exception
34
35You can specify multiple HTTP status codes to ignore, by providing an array of values:
36
37[source,php]
38----
39$client = ClientBuilder::create()->build();
40
41$params = [
42    'index'  => 'test_missing',
43    'client' => [ 'ignore' => [400, 404] ] <1>
44];
45echo $client->get($params);
46
47> No handler found for uri [/test_missing/test/] and method [GET]
48
49----
50<1> `ignore` also accepts an array of exceptions to ignore. In this example,
51the `BadRequest400Exception` is being ignored
52
53
54It should be noted that the response is simply a string, which may or may not be encoded as JSON.  In the first example,
55the response body was a complete JSON object which could be decoded.  In the second example, it was simply a string.
56
57Since the client has no way of knowing what the exception response will contain, no attempts to decode it are taken.
58
59=== Providing custom query parameters
60
61Sometimes you need to provide custom query params, such as authentication tokens for a third-party plugin or proxy.
62All query parameters are white-listed in Elasticsearch-php, which is to protect you from specifying a param which is
63not accepted by Elasticsearch.
64
65If you need custom parameters, you need to bypass this whitelisting mechanism.  To do so, add them to the `custom`
66parameter as an array of values:
67
68[source,php]
69----
70$client = ClientBuilder::create()->build();
71
72$params = [
73    'index'  => 'test',
74    'id'     => 1,
75    'parent' => 'abc',              // white-listed Elasticsearch parameter
76    'client' => [
77        'custom' => [
78            'customToken' => 'abc', // user-defined, not white listed, not checked
79            'otherToken'  => 123
80        ]
81    ]
82];
83$exists = $client->exists($params);
84----
85
86
87=== Increasing the Verbosity of responses
88
89By default, the client will only return the response body.  If you require more information (e.g. stats about the transfer,
90headers, status codes, etc), you can tell the client to return a more verbose response.  This is enabled via the
91`verbose` parameter in the client options.
92
93Without verbosity, all you see is the response body:
94
95[source,php]
96----
97$client = ClientBuilder::create()->build();
98
99$params = [
100    'index' => 'test',
101    'id'    => 1
102];
103$response = $client->get($params);
104print_r($response);
105
106
107Array
108(
109    [_index] => test
110    [_type] => _doc
111    [_id] => 1
112    [_version] => 1
113    [found] => 1
114    [_source] => Array
115        (
116            [field] => value
117        )
118
119)
120----
121
122With verbosity turned on, you will see all of the transfer stats:
123
124[source,php]
125----
126$client = ClientBuilder::create()->build();
127
128$params = [
129    'index'  => 'test',
130    'id'     => 1,
131    'client' => [
132        'verbose' => true
133    ]
134];
135$response = $client->get($params);
136print_r($response);
137
138
139Array
140(
141    [transfer_stats] => Array
142        (
143            [url] => http://127.0.0.1:9200/test/test/1
144            [content_type] => application/json; charset=UTF-8
145            [http_code] => 200
146            [header_size] => 86
147            [request_size] => 51
148            [filetime] => -1
149            [ssl_verify_result] => 0
150            [redirect_count] => 0
151            [total_time] => 0.00289
152            [namelookup_time] => 9.7E-5
153            [connect_time] => 0.000265
154            [pretransfer_time] => 0.000322
155            [size_upload] => 0
156            [size_download] => 96
157            [speed_download] => 33217
158            [speed_upload] => 0
159            [download_content_length] => 96
160            [upload_content_length] => -1
161            [starttransfer_time] => 0.002796
162            [redirect_time] => 0
163            [redirect_url] =>
164            [primary_ip] => 127.0.0.1
165            [certinfo] => Array
166                (
167                )
168
169            [primary_port] => 9200
170            [local_ip] => 127.0.0.1
171            [local_port] => 62971
172        )
173
174    [curl] => Array
175        (
176            [error] =>
177            [errno] => 0
178        )
179
180    [effective_url] => http://127.0.0.1:9200/test/test/1
181    [headers] => Array
182        (
183            [Content-Type] => Array
184                (
185                    [0] => application/json; charset=UTF-8
186                )
187
188            [Content-Length] => Array
189                (
190                    [0] => 96
191                )
192
193        )
194
195    [status] => 200
196    [reason] => OK
197    [body] => Array
198        (
199            [_index] => test
200            [_type] => _doc
201            [_id] => 1
202            [_version] => 1
203            [found] => 1
204            [_source] => Array
205                (
206                    [field] => value
207                )
208        )
209)
210----
211
212=== Curl Timeouts
213
214It is possible to configure per-request curl timeouts via the `timeout` and `connect_timeout` parameters.  These
215control the client-side, curl timeouts.  The `connect_timeout` paramter controls how long curl should wait for the
216"connect" phase to finish, while the `timeout` parameter controls how long curl should wait for the entire request
217to finish.
218
219If either timeout expires, curl will close the connection and return an error.  Both parameters should be specified
220in seconds.
221
222Note: client-side timeouts *do not* mean that Elasticsearch aborts the request.  Elasticsearch will continue executing
223the request until it completes.  In the case of a slow query or bulk request, the operation will continue executing
224"in the background", unknown to your client.  If your client kills connections rapidly with a timeout, only to immediately
225execute another request, it is possible to swamp the server with many connections because there is no "back-pressure" on the
226client.  In these situations, you will see the appropriate threadpool queue growing in size, and may start receiving
227`EsRejectedExecutionException` exceptions from Elasticsearch when the queue finally reaches capacity.
228
229[source,php]
230----
231$client = ClientBuilder::create()->build();
232
233$params = [
234    'index'  => 'test',
235    'id'     => 1,
236    'client' => [
237        'timeout' => 10,        // ten second timeout
238        'connect_timeout' => 10
239    ]
240];
241$response = $client->get($params);
242----
243
244=== Enabling Future Mode
245
246The client supports asynchronous, batch processing of requests.  This is enabled (if your HTTP handler supports it) on
247a per-request basis via the `future` parameter in the client options:
248
249[source,php]
250----
251$client = ClientBuilder::create()->build();
252
253$params = [
254    'index'  => 'test',
255    'id'     => 1,
256    'client' => [
257        'future' => 'lazy'
258    ]
259];
260$future = $client->get($params);
261$results = $future->wait();       // resolve the future
262----
263
264Future mode supports two options: `true` or `'lazy'`.  For more details about how asynchronous execution functions, and
265how to work with the results, see the dedicated page on <<future_mode>>.
266
267=== SSL Encryption
268
269Normally, you will specify SSL configurations when you create the client (see
270<<security>> for more details), since encryption typically
271applies to all requests. However, it is possible to configure on a per-request basis too if you need that functionality.
272For example, if you  need to use a self-signed cert on a specific request, you can specify it via the `verify` parameter
273in the client options:
274
275
276[source,php]
277----
278$client = ClientBuilder::create()->build();
279
280$params = [
281    'index'  => 'test',
282    'id'     => 1,
283    'client' => [
284        'verify' => 'path/to/cacert.pem'      //Use a self-signed certificate
285    ]
286];
287$result = $client->get($params);
288----
289