1=============
2Specification
3=============
4
5RingPHP applications consist of handlers, requests, responses, and
6middleware.
7
8Handlers
9--------
10
11Handlers are implemented as a PHP ``callable`` that accept a request array
12and return a response array (``GuzzleHttp\Ring\Future\FutureArrayInterface``).
13
14For example:
15
16.. code-block:: php
17
18    use GuzzleHttp\Ring\Future\CompletedFutureArray;
19
20    $mockHandler = function (array $request) {
21        return new CompletedFutureArray([
22            'status'  => 200,
23            'headers' => ['X-Foo' => ['Bar']],
24            'body'    => 'Hello!'
25         ]);
26    };
27
28This handler returns the same response each time it is invoked. All RingPHP
29handlers must return a ``GuzzleHttp\Ring\Future\FutureArrayInterface``. Use
30``GuzzleHttp\Ring\Future\CompletedFutureArray`` when returning a response that
31has already completed.
32
33Requests
34--------
35
36A request array is a PHP associative array that contains the configuration
37settings need to send a request.
38
39.. code-block:: php
40
41    $request = [
42        'http_method' => 'GET',
43        'scheme'      => 'http',
44        'uri'         => '/',
45        'body'        => 'hello!',
46        'client'      => ['timeout' => 1.0],
47        'headers'     => [
48            'host'  => ['httpbin.org'],
49            'X-Foo' => ['baz', 'bar']
50        ]
51    ];
52
53The request array contains the following key value pairs:
54
55request_method
56    (string, required) The HTTP request method, must be all caps corresponding
57    to a HTTP request method, such as ``GET`` or ``POST``.
58
59scheme
60    (string) The transport protocol, must be one of ``http`` or ``https``.
61    Defaults to ``http``.
62
63uri
64    (string, required) The request URI excluding the query string. Must
65    start with "/".
66
67query_string
68    (string) The query string, if present (e.g., ``foo=bar``).
69
70version
71    (string) HTTP protocol version. Defaults to ``1.1``.
72
73headers
74    (required, array) Associative array of headers. Each key represents the
75    header name. Each value contains an array of strings where each entry of
76    the array SHOULD be sent over the wire on a separate header line.
77
78body
79    (string, fopen resource, ``Iterator``, ``GuzzleHttp\Stream\StreamInterface``)
80    The body of the request, if present. Can be a string, resource returned
81    from fopen, an ``Iterator`` that yields chunks of data, an object that
82    implemented ``__toString``, or a ``GuzzleHttp\Stream\StreamInterface``.
83
84future
85    (bool, string) Controls the asynchronous behavior of a response.
86
87    Set to ``true`` or omit the ``future`` option to *request* that a request
88    will be completed asynchronously. Keep in mind that your request might not
89    necessarily be completed asynchronously based on the handler you are using.
90    Set the ``future`` option to ``false`` to request that a synchronous
91    response be provided.
92
93    You can provide a string value to specify fine-tuned future behaviors that
94    may be specific to the underlying handlers you are using. There are,
95    however, some common future options that handlers should implement if
96    possible.
97
98    lazy
99        Requests that the handler does not open and send the request
100        immediately, but rather only opens and sends the request once the
101        future is dereferenced. This option is often useful for sending a large
102        number of requests concurrently to allow handlers to take better
103        advantage of non-blocking transfers by first building up a pool of
104        requests.
105
106    If an handler does not implement or understand a provided string value,
107    then the request MUST be treated as if the user provided ``true`` rather
108    than the string value.
109
110    Future responses created by asynchronous handlers MUST attempt to complete
111    any outstanding future responses when they are destructed. Asynchronous
112    handlers MAY choose to automatically complete responses when the number
113    of outstanding requests reaches an handler-specific threshold.
114
115Client Specific Options
116~~~~~~~~~~~~~~~~~~~~~~~
117
118The following options are only used in ring client handlers.
119
120.. _client-options:
121
122client
123    (array) Associative array of client specific transfer options. The
124    ``client`` request key value pair can contain the following keys:
125
126    cert
127        (string, array) Set to a string to specify the path to a file
128        containing a PEM formatted SSL client side certificate. If a password
129        is required, then set ``cert`` to an array containing the path to the
130        PEM file in the first array element followed by the certificate
131        password in the second array element.
132
133    connect_timeout
134        (float) Float describing the number of seconds to wait while trying to
135        connect to a server. Use ``0`` to wait indefinitely (the default
136        behavior).
137
138    debug
139        (bool, fopen() resource) Set to true or set to a PHP stream returned by
140        fopen() to enable debug output with the handler used to send a request.
141        If set to ``true``, the output is written to PHP's STDOUT. If a PHP
142        ``fopen`` resource handle is provided, the output is written to the
143        stream.
144
145        "Debug output" is handler specific: different handlers will yield
146        different output and various various level of detail. For example, when
147        using cURL to transfer requests, cURL's `CURLOPT_VERBOSE <http://curl.haxx.se/libcurl/c/CURLOPT_VERBOSE.html>`_
148        will be used. When using the PHP stream wrapper, `stream notifications <http://php.net/manual/en/function.stream-notification-callback.php>`_
149        will be emitted.
150
151    decode_content
152        (bool) Specify whether or not ``Content-Encoding`` responses
153        (gzip, deflate, etc.) are automatically decoded. Set to ``true`` to
154        automatically decode encoded responses. Set to ``false`` to not decode
155        responses. By default, content is *not* decoded automatically.
156
157    delay
158        (int) The number of milliseconds to delay before sending the request.
159        This is often used for delaying before retrying a request. Handlers
160        SHOULD implement this if possible, but it is not a strict requirement.
161
162    progress
163        (function) Defines a function to invoke when transfer progress is made.
164        The function accepts the following arguments:
165
166        1. The total number of bytes expected to be downloaded
167        2. The number of bytes downloaded so far
168        3. The number of bytes expected to be uploaded
169        4. The number of bytes uploaded so far
170
171    proxy
172        (string, array) Pass a string to specify an HTTP proxy, or an
173        associative array to specify different proxies for different protocols
174        where the scheme is the key and the value is the proxy address.
175
176        .. code-block:: php
177
178            $request = [
179                'http_method' => 'GET',
180                'headers'     => ['host' => ['httpbin.org']],
181                'client'      => [
182                    // Use different proxies for different URI schemes.
183                    'proxy' => [
184                        'http'  => 'http://proxy.example.com:5100',
185                        'https' => 'https://proxy.example.com:6100'
186                    ]
187                ]
188            ];
189
190    ssl_key
191        (string, array) Specify the path to a file containing a private SSL key
192        in PEM format. If a password is required, then set to an array
193        containing the path to the SSL key in the first array element followed
194        by the password required for the certificate in the second element.
195
196    save_to
197        (string, fopen resource, ``GuzzleHttp\Stream\StreamInterface``)
198        Specifies where the body of the response is downloaded. Pass a string to
199        open a local file on disk and save the output to the file. Pass an fopen
200        resource to save the output to a PHP stream resource. Pass a
201        ``GuzzleHttp\Stream\StreamInterface`` to save the output to a Guzzle
202        StreamInterface. Omitting this option will typically save the body of a
203        response to a PHP temp stream.
204
205    stream
206        (bool) Set to true to stream a response rather than download it all
207        up-front. This option will only be utilized when the corresponding
208        handler supports it.
209
210    timeout
211        (float) Float describing the timeout of the request in seconds. Use 0 to
212        wait indefinitely (the default behavior).
213
214    verify
215        (bool, string) Describes the SSL certificate verification behavior of a
216        request. Set to true to enable SSL certificate verification using the
217        system CA bundle when available (the default). Set to false to disable
218        certificate verification (this is insecure!). Set to a string to provide
219        the path to a CA bundle on disk to enable verification using a custom
220        certificate.
221
222    version
223        (string) HTTP protocol version to use with the request.
224
225Server Specific Options
226~~~~~~~~~~~~~~~~~~~~~~~
227
228The following options are only used in ring server handlers.
229
230server_port
231    (integer) The port on which the request is being handled. This is only
232    used with ring servers, and is required.
233
234server_name
235    (string) The resolved server name, or the server IP address. Required when
236    using a Ring server.
237
238remote_addr
239    (string) The IP address of the client or the last proxy that sent the
240    request. Required when using a Ring server.
241
242Responses
243---------
244
245A response is an array-like object that implements
246``GuzzleHttp\Ring\Future\FutureArrayInterface``. Responses contain the
247following key value pairs:
248
249body
250    (string, fopen resource, ``Iterator``, ``GuzzleHttp\Stream\StreamInterface``)
251    The body of the response, if present. Can be a string, resource returned
252    from fopen, an ``Iterator`` that yields chunks of data, an object that
253    implemented ``__toString``, or a ``GuzzleHttp\Stream\StreamInterface``.
254
255effective_url
256    (string) The URL that returned the resulting response.
257
258error
259    (``\Exception``) Contains an exception describing any errors that were
260    encountered during the transfer.
261
262headers
263    (Required, array) Associative array of headers. Each key represents the
264    header name. Each value contains an array of strings where each entry of
265    the array is a header line. The headers array MAY be an empty array in the
266    event an error occurred before a response was received.
267
268reason
269    (string) Optional reason phrase. This option should be provided when the
270    reason phrase does not match the typical reason phrase associated with the
271    ``status`` code. See `RFC 7231 <http://tools.ietf.org/html/rfc7231#section-6.1>`_
272    for a list of HTTP reason phrases mapped to status codes.
273
274status
275    (Required, integer) The HTTP status code. The status code MAY be set to
276    ``null`` in the event an error occurred before a response was received
277    (e.g., a networking error).
278
279transfer_stats
280    (array) Provides an associative array of arbitrary transfer statistics if
281    provided by the underlying handler.
282
283version
284    (string) HTTP protocol version. Defaults to ``1.1``.
285
286Middleware
287----------
288
289Ring middleware augments the functionality of handlers by invoking them in the
290process of generating responses. Middleware is typically implemented as a
291higher-order function that takes one or more handlers as arguments followed by
292an optional associative array of options as the last argument, returning a new
293handler with the desired compound behavior.
294
295Here's an example of a middleware that adds a Content-Type header to each
296request.
297
298.. code-block:: php
299
300    use GuzzleHttp\Ring\Client\CurlHandler;
301    use GuzzleHttp\Ring\Core;
302
303    $contentTypeHandler = function(callable $handler, $contentType) {
304        return function (array $request) use ($handler, $contentType) {
305            return $handler(Core::setHeader('Content-Type', $contentType));
306        };
307    };
308
309    $baseHandler = new CurlHandler();
310    $wrappedHandler = $contentTypeHandler($baseHandler, 'text/html');
311    $response = $wrappedHandler([/** request hash **/]);
312