From 8df3db566a3a937b45ebf11adb90d265e6f5e2d4 Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Sun, 17 Nov 2019 20:45:02 +0100 Subject: initial checking of customized version 1.0rc9 --- vendor/guzzle/guzzle/docs/http-client/client.rst | 569 ++++++++++++++++++ .../guzzle/docs/http-client/entity-bodies.rst | 151 +++++ .../guzzle/docs/http-client/http-redirects.rst | 99 +++ vendor/guzzle/guzzle/docs/http-client/request.rst | 667 +++++++++++++++++++++ vendor/guzzle/guzzle/docs/http-client/response.rst | 141 +++++ .../guzzle/docs/http-client/uri-templates.rst | 52 ++ 6 files changed, 1679 insertions(+) create mode 100644 vendor/guzzle/guzzle/docs/http-client/client.rst create mode 100644 vendor/guzzle/guzzle/docs/http-client/entity-bodies.rst create mode 100644 vendor/guzzle/guzzle/docs/http-client/http-redirects.rst create mode 100644 vendor/guzzle/guzzle/docs/http-client/request.rst create mode 100644 vendor/guzzle/guzzle/docs/http-client/response.rst create mode 100644 vendor/guzzle/guzzle/docs/http-client/uri-templates.rst (limited to 'vendor/guzzle/guzzle/docs/http-client') diff --git a/vendor/guzzle/guzzle/docs/http-client/client.rst b/vendor/guzzle/guzzle/docs/http-client/client.rst new file mode 100644 index 0000000..723d729 --- /dev/null +++ b/vendor/guzzle/guzzle/docs/http-client/client.rst @@ -0,0 +1,569 @@ +====================== +The Guzzle HTTP client +====================== + +Guzzle gives PHP developers complete control over HTTP requests while utilizing HTTP/1.1 best practices. Guzzle's HTTP +functionality is a robust framework built on top of the `PHP libcurl bindings `_. + +The three main parts of the Guzzle HTTP client are: + ++--------------+-------------------------------------------------------------------------------------------------------+ +| Clients | ``Guzzle\Http\Client`` (creates and sends requests, associates a response with a request) | ++--------------+-------------------------------------------------------------------------------------------------------+ +| Requests | ``Guzzle\Http\Message\Request`` (requests with no body), | +| | ``Guzzle\Http\Message\EntityEnclosingRequest`` (requests with a body) | ++--------------+-------------------------------------------------------------------------------------------------------+ +| Responses | ``Guzzle\Http\Message\Response`` | ++--------------+-------------------------------------------------------------------------------------------------------+ + +Creating a Client +----------------- + +Clients create requests, send requests, and set responses on a request object. When instantiating a client object, +you can pass an optional "base URL" and optional array of configuration options. A base URL is a +:doc:`URI template ` that contains the URL of a remote server. When creating requests with a relative +URL, the base URL of a client will be merged into the request's URL. + +.. code-block:: php + + use Guzzle\Http\Client; + + // Create a client and provide a base URL + $client = new Client('https://api.github.com'); + + $request = $client->get('/user'); + $request->setAuth('user', 'pass'); + echo $request->getUrl(); + // >>> https://api.github.com/user + + // You must send a request in order for the transfer to occur + $response = $request->send(); + + echo $response->getBody(); + // >>> {"type":"User", ... + + echo $response->getHeader('Content-Length'); + // >>> 792 + + $data = $response->json(); + echo $data['type']; + // >>> User + +Base URLs +~~~~~~~~~ + +Notice that the URL provided to the client's ``get()`` method is relative. Relative URLs will always merge into the +base URL of the client. There are a few rules that control how the URLs are merged. + +.. tip:: + + Guzzle follows `RFC 3986 `_ when merging base URLs and + relative URLs. + +In the above example, we passed ``/user`` to the ``get()`` method of the client. This is a relative URL, so it will +merge into the base URL of the client-- resulting in the derived URL of ``https://api.github.com/users``. + +``/user`` is a relative URL but uses an absolute path because it contains the leading slash. Absolute paths will +overwrite any existing path of the base URL. If an absolute path is provided (e.g. ``/path/to/something``), then the +path specified in the base URL of the client will be replaced with the absolute path, and the query string provided +by the relative URL will replace the query string of the base URL. + +Omitting the leading slash and using relative paths will add to the path of the base URL of the client. So using a +client base URL of ``https://api.twitter.com/v1.1`` and creating a GET request with ``statuses/user_timeline.json`` +will result in a URL of ``https://api.twitter.com/v1.1/statuses/user_timeline.json``. If a relative path and a query +string are provided, then the relative path will be appended to the base URL path, and the query string provided will +be merged into the query string of the base URL. + +If an absolute URL is provided (e.g. ``http://httpbin.org/ip``), then the request will completely use the absolute URL +as-is without merging in any of the URL parts specified in the base URL. + +Configuration options +~~~~~~~~~~~~~~~~~~~~~ + +The second argument of the client's constructor is an array of configuration data. This can include URI template data +or special options that alter the client's behavior: + ++-------------------------------+-------------------------------------------------------------------------------------+ +| ``request.options`` | Associative array of :ref:`Request options ` to apply to every | +| | request created by the client. | ++-------------------------------+-------------------------------------------------------------------------------------+ +| ``redirect.disable`` | Disable HTTP redirects for every request created by the client. | ++-------------------------------+-------------------------------------------------------------------------------------+ +| ``curl.options`` | Associative array of cURL options to apply to every request created by the client. | +| | if either the key or value of an entry in the array is a string, Guzzle will | +| | attempt to find a matching defined cURL constant automatically (e.g. | +| | "CURLOPT_PROXY" will be converted to the constant ``CURLOPT_PROXY``). | ++-------------------------------+-------------------------------------------------------------------------------------+ +| ``ssl.certificate_authority`` | Set to true to use the Guzzle bundled SSL certificate bundle (this is used by | +| | default, 'system' to use the bundle on your system, a string pointing to a file to | +| | use a specific certificate file, a string pointing to a directory to use multiple | +| | certificates, or ``false`` to disable SSL validation (not recommended). | +| | | +| | When using Guzzle inside of a phar file, the bundled SSL certificate will be | +| | extracted to your system's temp folder, and each time a client is created an MD5 | +| | check will be performed to ensure the integrity of the certificate. | ++-------------------------------+-------------------------------------------------------------------------------------+ +| ``command.params`` | When using a ``Guzzle\Service\Client`` object, this is an associative array of | +| | default options to set on each command created by the client. | ++-------------------------------+-------------------------------------------------------------------------------------+ + +Here's an example showing how to set various configuration options, including default headers to send with each request, +default query string parameters to add to each request, a default auth scheme for each request, and a proxy to use for +each request. Values can be injected into the client's base URL using variables from the configuration array. + +.. code-block:: php + + use Guzzle\Http\Client; + + $client = new Client('https://api.twitter.com/{version}', array( + 'version' => 'v1.1', + 'request.options' => array( + 'headers' => array('Foo' => 'Bar'), + 'query' => array('testing' => '123'), + 'auth' => array('username', 'password', 'Basic|Digest|NTLM|Any'), + 'proxy' => 'tcp://localhost:80' + ) + )); + +Setting a custom User-Agent +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The default Guzzle User-Agent header is ``Guzzle/ curl/ PHP/``. You can +customize the User-Agent header of a client by calling the ``setUserAgent()`` method of a Client object. + +.. code-block:: php + + // Completely override the default User-Agent + $client->setUserAgent('Test/123'); + + // Prepend a string to the default User-Agent + $client->setUserAgent('Test/123', true); + +Creating requests with a client +------------------------------- + +A Client object exposes several methods used to create Request objects: + +* Create a custom HTTP request: ``$client->createRequest($method, $uri, array $headers, $body, $options)`` +* Create a GET request: ``$client->get($uri, array $headers, $options)`` +* Create a HEAD request: ``$client->head($uri, array $headers, $options)`` +* Create a DELETE request: ``$client->delete($uri, array $headers, $body, $options)`` +* Create a POST request: ``$client->post($uri, array $headers, $postBody, $options)`` +* Create a PUT request: ``$client->put($uri, array $headers, $body, $options)`` +* Create a PATCH request: ``$client->patch($uri, array $headers, $body, $options)`` + +.. code-block:: php + + use Guzzle\Http\Client; + + $client = new Client('http://baseurl.com/api/v1'); + + // Create a GET request using Relative to base URL + // URL of the request: http://baseurl.com/api/v1/path?query=123&value=abc) + $request = $client->get('path?query=123&value=abc'); + $response = $request->send(); + + // Create HEAD request using a relative URL with an absolute path + // URL of the request: http://baseurl.com/path?query=123&value=abc + $request = $client->head('/path?query=123&value=abc'); + $response = $request->send(); + + // Create a DELETE request using an absolute URL + $request = $client->delete('http://www.example.com/path?query=123&value=abc'); + $response = $request->send(); + + // Create a PUT request using the contents of a PHP stream as the body + // Specify custom HTTP headers + $request = $client->put('http://www.example.com/upload', array( + 'X-Header' => 'My Header' + ), fopen('http://www.test.com/', 'r')); + $response = $request->send(); + + // Create a POST request and add the POST files manually + $request = $client->post('http://localhost:8983/solr/update') + ->addPostFiles(array('file' => '/path/to/documents.xml')); + $response = $request->send(); + + // Check if a resource supports the DELETE method + $supportsDelete = $client->options('/path')->send()->isMethodAllowed('DELETE'); + $response = $request->send(); + +Client objects create Request objects using a request factory (``Guzzle\Http\Message\RequestFactoryInterface``). +You can inject a custom request factory into the Client using ``$client->setRequestFactory()``, but you can typically +rely on a Client's default request factory. + +Static clients +-------------- + +You can use Guzzle's static client facade to more easily send simple HTTP requests. + +.. code-block:: php + + // Mount the client so that you can access it at \Guzzle + Guzzle\Http\StaticClient::mount(); + $response = Guzzle::get('http://guzzlephp.org'); + +Each request method of the static client (e.g. ``get()``, ``post()`, ``put()``, etc) accepts an associative array of request +options to apply to the request. + +.. code-block:: php + + $response = Guzzle::post('http://test.com', array( + 'headers' => array('X-Foo' => 'Bar'), + 'body' => array('Test' => '123'), + 'timeout' => 10 + )); + +.. _request-options: + +Request options +--------------- + +Request options can be specified when creating a request or in the ``request.options`` parameter of a client. These +options can control various aspects of a request including: headers to send, query string data, where the response +should be downloaded, proxies, auth, etc. + +headers +~~~~~~~ + +Associative array of headers to apply to the request. When specified in the ``$options`` argument of a client creational +method (e.g. ``get()``, ``post()``, etc), the headers in the ``$options`` array will overwrite headers specified in the +``$headers`` array. + +.. code-block:: php + + $request = $client->get($url, array(), array( + 'headers' => array('X-Foo' => 'Bar') + )); + +Headers can be specified on a client to add default headers to every request sent by a client. + +.. code-block:: php + + $client = new Guzzle\Http\Client(); + + // Set a single header using path syntax + $client->setDefaultOption('headers/X-Foo', 'Bar'); + + // Set all headers + $client->setDefaultOption('headers', array('X-Foo' => 'Bar')); + +.. note:: + + In addition to setting request options when creating requests or using the ``setDefaultOption()`` method, any + default client request option can be set using a client's config object: + + .. code-block:: php + + $client->getConfig()->setPath('request.options/headers/X-Foo', 'Bar'); + +query +~~~~~ + +Associative array of query string parameters to the request. When specified in the ``$options`` argument of a client +creational method, the query string parameters in the ``$options`` array will overwrite query string parameters +specified in the `$url`. + +.. code-block:: php + + $request = $client->get($url, array(), array( + 'query' => array('abc' => '123') + )); + +Query string parameters can be specified on a client to add default query string parameters to every request sent by a +client. + +.. code-block:: php + + $client = new Guzzle\Http\Client(); + + // Set a single query string parameter using path syntax + $client->setDefaultOption('query/abc', '123'); + + // Set an array of default query string parameters + $client->setDefaultOption('query', array('abc' => '123')); + +body +~~~~ + +Sets the body of a request. The value supplied to the body option can be a ``Guzzle\Http\EntityBodyInterface``, string, +fopen resource, or array when sending POST requests. When a ``body`` request option is supplied, the option value will +overwrite the ``$body`` argument of a client creational method. + +auth +~~~~ + +Specifies and array of HTTP authorization parameters parameters to use with the request. The array must contain the +username in index [0], the password in index [1], and can optionally contain the authentication type in index [2]. +The available authentication types are: "Basic" (default), "Digest", "NTLM", or "Any". + +.. code-block:: php + + $request = $client->get($url, array(), array( + 'auth' => array('username', 'password', 'Digest') + )); + + // You can add auth headers to every request of a client + $client->setDefaultOption('auth', array('username', 'password', 'Digest')); + +cookies +~~~~~~~ + +Specifies an associative array of cookies to add to the request. + +allow_redirects +~~~~~~~~~~~~~~~ + +Specifies whether or not the request should follow redirects. Requests will follow redirects by default. Set +``allow_redirects`` to ``false`` to disable redirects. + +save_to +~~~~~~~ + +The ``save_to`` option specifies where the body of a response is downloaded. You can pass the path to a file, an fopen +resource, or a ``Guzzle\Http\EntityBodyInterface`` object. + +See :ref:`Changing where a response is downloaded ` for more information on setting the +`save_to` option. + +events +~~~~~~ + +The `events` option makes it easy to attach listeners to the various events emitted by a request object. The `events` +options must be an associative array mapping an event name to a Closure or array the contains a Closure and the +priority of the event. + +.. code-block:: php + + $request = $client->get($url, array(), array( + 'events' => array( + 'request.before_send' => function (\Guzzle\Common\Event $e) { + echo 'About to send ' . $e['request']; + } + ) + )); + + // Using the static client: + Guzzle::get($url, array( + 'events' => array( + 'request.before_send' => function (\Guzzle\Common\Event $e) { + echo 'About to send ' . $e['request']; + } + ) + )); + +plugins +~~~~~~~ + +The `plugins` options makes it easy to attach an array of plugins to a request. + +.. code-block:: php + + // Using the static client: + Guzzle::get($url, array( + 'plugins' => array( + new Guzzle\Plugin\Cache\CachePlugin(), + new Guzzle\Plugin\Cookie\CookiePlugin() + ) + )); + +exceptions +~~~~~~~~~~ + +The `exceptions` option can be used to disable throwing exceptions for unsuccessful HTTP response codes +(e.g. 404, 500, etc). Set `exceptions` to false to not throw exceptions. + +params +~~~~~~ + +The `params` options can be used to specify an associative array of data parameters to add to a request. Note that +these are not query string parameters. + +timeout / connect_timeout +~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can specify the maximum number of seconds to allow for an entire transfer to take place before timing out using +the `timeout` request option. You can specify the maximum number of seconds to wait while trying to connect using the +`connect_timeout` request option. Set either of these options to 0 to wait indefinitely. + +.. code-block:: php + + $request = $client->get('http://www.example.com', array(), array( + 'timeout' => 20, + 'connect_timeout' => 1.5 + )); + +verify +~~~~~~ + +Set to true to enable SSL certificate validation (the default), false to disable SSL certificate validation, or supply +the path to a CA bundle to enable verification using a custom certificate. + +cert +~~~~ + +The `cert` option lets you specify a PEM formatted SSL client certificate to use with servers that require one. If the +certificate requires a password, provide an array with the password as the second item. + +This would typically be used in conjunction with the `ssl_key` option. + +.. code-block:: php + + $request = $client->get('https://www.example.com', array(), array( + 'cert' => '/etc/pki/client_certificate.pem' + ) + + $request = $client->get('https://www.example.com', array(), array( + 'cert' => array('/etc/pki/client_certificate.pem', 's3cr3tp455w0rd') + ) + +ssl_key +~~~~~~~ + +The `ssl_key` option lets you specify a file containing your PEM formatted private key, optionally protected by a password. +Note: your password is sensitive, keep the PHP script containing it safe. + +This would typically be used in conjunction with the `cert` option. + +.. code-block:: php + + $request = $client->get('https://www.example.com', array(), array( + 'ssl_key' => '/etc/pki/private_key.pem' + ) + + $request = $client->get('https://www.example.com', array(), array( + 'ssl_key' => array('/etc/pki/private_key.pem', 's3cr3tp455w0rd') + ) + +proxy +~~~~~ + +The `proxy` option is used to specify an HTTP proxy (e.g. `http://username:password@192.168.16.1:10`). + +debug +~~~~~ + +The `debug` option is used to show verbose cURL output for a transfer. + +stream +~~~~~~ + +When using a static client, you can set the `stream` option to true to return a `Guzzle\Stream\Stream` object that can +be used to pull data from a stream as needed (rather than have cURL download the entire contents of a response to a +stream all at once). + +.. code-block:: php + + $stream = Guzzle::get('http://guzzlephp.org', array('stream' => true)); + while (!$stream->feof()) { + echo $stream->readLine(); + } + +Sending requests +---------------- + +Requests can be sent by calling the ``send()`` method of a Request object, but you can also send requests using the +``send()`` method of a Client. + +.. code-block:: php + + $request = $client->get('http://www.amazon.com'); + $response = $client->send($request); + +Sending requests in parallel +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The Client's ``send()`` method accept a single ``Guzzle\Http\Message\RequestInterface`` object or an array of +RequestInterface objects. When an array is specified, the requests will be sent in parallel. + +Sending many HTTP requests serially (one at a time) can cause an unnecessary delay in a script's execution. Each +request must complete before a subsequent request can be sent. By sending requests in parallel, a pool of HTTP +requests can complete at the speed of the slowest request in the pool, significantly reducing the amount of time +needed to execute multiple HTTP requests. Guzzle provides a wrapper for the curl_multi functions in PHP. + +Here's an example of sending three requests in parallel using a client object: + +.. code-block:: php + + use Guzzle\Common\Exception\MultiTransferException; + + try { + $responses = $client->send(array( + $client->get('http://www.google.com/'), + $client->head('http://www.google.com/'), + $client->get('https://www.github.com/') + )); + } catch (MultiTransferException $e) { + + echo "The following exceptions were encountered:\n"; + foreach ($e as $exception) { + echo $exception->getMessage() . "\n"; + } + + echo "The following requests failed:\n"; + foreach ($e->getFailedRequests() as $request) { + echo $request . "\n\n"; + } + + echo "The following requests succeeded:\n"; + foreach ($e->getSuccessfulRequests() as $request) { + echo $request . "\n\n"; + } + } + +If the requests succeed, an array of ``Guzzle\Http\Message\Response`` objects are returned. A single request failure +will not cause the entire pool of requests to fail. Any exceptions thrown while transferring a pool of requests will +be aggregated into a ``Guzzle\Common\Exception\MultiTransferException`` exception. + +Plugins and events +------------------ + +Guzzle provides easy to use request plugins that add behavior to requests based on signal slot event notifications +powered by the +`Symfony2 Event Dispatcher component `_. Any +event listener or subscriber attached to a Client object will automatically be attached to each request created by the +client. + +Using the same cookie session for each request +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Attach a ``Guzzle\Plugin\Cookie\CookiePlugin`` to a client which will in turn add support for cookies to every request +created by a client, and each request will use the same cookie session: + +.. code-block:: php + + use Guzzle\Plugin\Cookie\CookiePlugin; + use Guzzle\Plugin\Cookie\CookieJar\ArrayCookieJar; + + // Create a new cookie plugin + $cookiePlugin = new CookiePlugin(new ArrayCookieJar()); + + // Add the cookie plugin to the client + $client->addSubscriber($cookiePlugin); + +.. _client-events: + +Events emitted from a client +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A ``Guzzle\Http\Client`` object emits the following events: + ++------------------------------+--------------------------------------------+------------------------------------------+ +| Event name | Description | Event data | ++==============================+============================================+==========================================+ +| client.create_request | Called when a client creates a request | * client: The client | +| | | * request: The created request | ++------------------------------+--------------------------------------------+------------------------------------------+ + +.. code-block:: php + + use Guzzle\Common\Event; + use Guzzle\Http\Client; + + $client = new Client(); + + // Add a listener that will echo out requests as they are created + $client->getEventDispatcher()->addListener('client.create_request', function (Event $e) { + echo 'Client object: ' . spl_object_hash($e['client']) . "\n"; + echo "Request object: {$e['request']}\n"; + }); diff --git a/vendor/guzzle/guzzle/docs/http-client/entity-bodies.rst b/vendor/guzzle/guzzle/docs/http-client/entity-bodies.rst new file mode 100644 index 0000000..823b0c0 --- /dev/null +++ b/vendor/guzzle/guzzle/docs/http-client/entity-bodies.rst @@ -0,0 +1,151 @@ +=========================== +Request and response bodies +=========================== + +`Entity body `_ is the term used for the body of an HTTP +message. The entity body of requests and responses is inherently a +`PHP stream `_ in Guzzle. The body of the request can be either a string or +a PHP stream which are converted into a ``Guzzle\Http\EntityBody`` object using its factory method. When using a +string, the entity body is stored in a `temp PHP stream `_. The use of +temp PHP streams helps to protect your application from running out of memory when sending or receiving large entity +bodies in your messages. When more than 2MB of data is stored in a temp stream, it automatically stores the data on +disk rather than in memory. + +EntityBody objects provide a great deal of functionality: compression, decompression, calculate the Content-MD5, +calculate the Content-Length (when the resource is repeatable), guessing the Content-Type, and more. Guzzle doesn't +need to load an entire entity body into a string when sending or retrieving data; entity bodies are streamed when +being uploaded and downloaded. + +Here's an example of gzip compressing a text file then sending the file to a URL: + +.. code-block:: php + + use Guzzle\Http\EntityBody; + + $body = EntityBody::factory(fopen('/path/to/file.txt', 'r+')); + echo $body->read(1024); + $body->seek(0, SEEK_END); + $body->write('foo'); + echo $body->ftell(); + $body->rewind(); + + // Send a request using the body + $response = $client->put('http://localhost:8080/uploads', null, $body)->send(); + +The body of the request can be specified in the ``Client::put()`` or ``Client::post()`` method, or, you can specify +the body of the request by calling the ``setBody()`` method of any +``Guzzle\Http\Message\EntityEnclosingRequestInterface`` object. + +Compression +----------- + +You can compress the contents of an EntityBody object using the ``compress()`` method. The compress method accepts a +filter that must match to one of the supported +`PHP stream filters `_ on your system (e.g. `zlib.deflate`, +``bzip2.compress``, etc). Compressing an entity body will stream the entire entity body through a stream compression +filter into a temporary PHP stream. You can uncompress an entity body using the ``uncompress()`` method and passing +the PHP stream filter to use when decompressing the stream (e.g. ``zlib.inflate``). + +.. code-block:: php + + use Guzzle\Http\EntityBody; + + $body = EntityBody::factory(fopen('/tmp/test.txt', 'r+')); + echo $body->getSize(); + // >>> 1048576 + + // Compress using the default zlib.deflate filter + $body->compress(); + echo $body->getSize(); + // >>> 314572 + + // Decompress the stream + $body->uncompress(); + echo $body->getSize(); + // >>> 1048576 + +Decorators +---------- + +Guzzle provides several EntityBody decorators that can be used to add functionality to an EntityBody at runtime. + +IoEmittingEntityBody +~~~~~~~~~~~~~~~~~~~~ + +This decorator will emit events when data is read from a stream or written to a stream. Add an event subscriber to the +entity body's ``body.read`` or ``body.write`` methods to receive notifications when data data is transferred. + +.. code-block:: php + + use Guzzle\Common\Event; + use Guzzle\Http\EntityBody; + use Guzzle\Http\IoEmittingEntityBody; + + $original = EntityBody::factory(fopen('/tmp/test.txt', 'r+')); + $body = new IoEmittingEntityBody($original); + + // Listen for read events + $body->getEventDispatcher()->addListener('body.read', function (Event $e) { + // Grab data from the event + $entityBody = $e['body']; + // Amount of data retrieved from the body + $lengthOfData = $e['length']; + // The actual data that was read + $data = $e['read']; + }); + + // Listen for write events + $body->getEventDispatcher()->addListener('body.write', function (Event $e) { + // Grab data from the event + $entityBody = $e['body']; + // The data that was written + $data = $e['write']; + // The actual amount of data that was written + $data = $e['read']; + }); + +ReadLimitEntityBody +~~~~~~~~~~~~~~~~~~~ + +The ReadLimitEntityBody decorator can be used to transfer a subset or slice of an existing EntityBody object. This can +be useful for breaking a large file into smaller pieces to be sent in chunks (e.g. Amazon S3's multipart upload API). + +.. code-block:: php + + use Guzzle\Http\EntityBody; + use Guzzle\Http\ReadLimitEntityBody; + + $original = EntityBody::factory(fopen('/tmp/test.txt', 'r+')); + echo $original->getSize(); + // >>> 1048576 + + // Limit the size of the body to 1024 bytes and start reading from byte 2048 + $body = new ReadLimitEntityBody($original, 1024, 2048); + echo $body->getSize(); + // >>> 1024 + echo $body->ftell(); + // >>> 0 + +CachingEntityBody +~~~~~~~~~~~~~~~~~ + +The CachingEntityBody decorator is used to allow seeking over previously read bytes on non-seekable read streams. This +can be useful when transferring a non-seekable entity body fails due to needing to rewind the stream (for example, +resulting from a redirect). Data that is read from the remote stream will be buffered in a PHP temp stream so that +previously read bytes are cached first in memory, then on disk. + +.. code-block:: php + + use Guzzle\Http\EntityBody; + use Guzzle\Http\CachingEntityBody; + + $original = EntityBody::factory(fopen('http://www.google.com', 'r')); + $body = new CachingEntityBody($original); + + $body->read(1024); + echo $body->ftell(); + // >>> 1024 + + $body->seek(0); + echo $body->ftell(); + // >>> 0 diff --git a/vendor/guzzle/guzzle/docs/http-client/http-redirects.rst b/vendor/guzzle/guzzle/docs/http-client/http-redirects.rst new file mode 100644 index 0000000..32ba268 --- /dev/null +++ b/vendor/guzzle/guzzle/docs/http-client/http-redirects.rst @@ -0,0 +1,99 @@ +============== +HTTP redirects +============== + +By default, Guzzle will automatically follow redirects using the non-RFC compliant implementation used by most web +browsers. This means that redirects for POST requests are followed by a GET request. You can force RFC compliance by +enabling the strict mode on a request's parameter object: + +.. code-block:: php + + // Set per request + $request = $client->post(); + $request->getParams()->set('redirect.strict', true); + + // You can set globally on a client so all requests use strict redirects + $client->getConfig()->set('request.params', array( + 'redirect.strict' => true + )); + +By default, Guzzle will redirect up to 5 times before throwing a ``Guzzle\Http\Exception\TooManyRedirectsException``. +You can raise or lower this value using the ``redirect.max`` parameter of a request object: + +.. code-block:: php + + $request->getParams()->set('redirect.max', 2); + +Redirect history +---------------- + +You can get the number of redirects of a request using the resulting response object's ``getRedirectCount()`` method. +Similar to cURL's ``effective_url`` property, Guzzle provides the effective URL, or the last redirect URL that returned +the request, in a response's ``getEffectiveUrl()`` method. + +When testing or debugging, it is often useful to see a history of redirects for a particular request. This can be +achieved using the HistoryPlugin. + +.. code-block:: php + + $request = $client->get('/'); + $history = new Guzzle\Plugin\History\HistoryPlugin(); + $request->addSubscriber($history); + $response = $request->send(); + + // Get the last redirect URL or the URL of the request that received + // this response + echo $response->getEffectiveUrl(); + + // Get the number of redirects + echo $response->getRedirectCount(); + + // Iterate over each sent request and response + foreach ($history->getAll() as $transaction) { + // Request object + echo $transaction['request']->getUrl() . "\n"; + // Response object + echo $transaction['response']->getEffectiveUrl() . "\n"; + } + + // Or, simply cast the HistoryPlugin to a string to view each request and response + echo $history; + +Disabling redirects +------------------- + +You can disable redirects on a client by passing a configuration option in the client's constructor: + +.. code-block:: php + + $client = new Client(null, array('redirect.disable' => true)); + +You can also disable redirects per request: + +.. code-block:: php + + $request = $client->get($url, array(), array('allow_redirects' => false)); + +Redirects and non-repeatable streams +------------------------------------ + +If you are redirected when sending data from a non-repeatable stream and some of the data has been read off of the +stream, then you will get a ``Guzzle\Http\Exception\CouldNotRewindStreamException``. You can get around this error by +adding a custom rewind method to the entity body object being sent in the request. + +.. code-block:: php + + $request = $client->post( + 'http://httpbin.com/redirect/2', + null, + fopen('http://httpbin.com/get', 'r') + ); + + // Add a custom function that can be used to rewind the stream + // (reopen in this example) + $request->getBody()->setRewindFunction(function ($body) { + $body->setStream(fopen('http://httpbin.com/get', 'r')); + return true; + ); + + $response = $client->send(); diff --git a/vendor/guzzle/guzzle/docs/http-client/request.rst b/vendor/guzzle/guzzle/docs/http-client/request.rst new file mode 100644 index 0000000..a8387a9 --- /dev/null +++ b/vendor/guzzle/guzzle/docs/http-client/request.rst @@ -0,0 +1,667 @@ +===================== +Using Request objects +===================== + +HTTP request messages +--------------------- + +Request objects are all about building an HTTP message. Each part of an HTTP request message can be set individually +using methods on the request object or set in bulk using the ``setUrl()`` method. Here's the format of an HTTP request +with each part of the request referencing the method used to change it:: + + PUT(a) /path(b)?query=123(c) HTTP/1.1(d) + X-Header(e): header + Content-Length(e): 4 + + data(f) + ++-------------------------+---------------------------------------------------------------------------------+ +| a. **Method** | The request method can only be set when instantiating a request | ++-------------------------+---------------------------------------------------------------------------------+ +| b. **Path** | ``$request->setPath('/path');`` | ++-------------------------+---------------------------------------------------------------------------------+ +| c. **Query** | ``$request->getQuery()->set('query', '123');`` | ++-------------------------+---------------------------------------------------------------------------------+ +| d. **Protocol version** | ``$request->setProtocolVersion('1.1');`` | ++-------------------------+---------------------------------------------------------------------------------+ +| e. **Header** | ``$request->setHeader('X-Header', 'header');`` | ++-------------------------+---------------------------------------------------------------------------------+ +| f. **Entity Body** | ``$request->setBody('data'); // Only available with PUT, POST, PATCH, DELETE`` | ++-------------------------+---------------------------------------------------------------------------------+ + +Creating requests with a client +------------------------------- + +Client objects are responsible for creating HTTP request objects. + +GET requests +~~~~~~~~~~~~ + +`GET requests `_ are the most common form of HTTP +requests. When you visit a website in your browser, the HTML of the website is downloaded using a GET request. GET +requests are idempotent requests that are typically used to download content (an entity) identified by a request URL. + +.. code-block:: php + + use Guzzle\Http\Client; + + $client = new Client(); + + // Create a request that has a query string and an X-Foo header + $request = $client->get('http://www.amazon.com?a=1', array('X-Foo' => 'Bar')); + + // Send the request and get the response + $response = $request->send(); + +You can change where the body of a response is downloaded on any request using the +``$request->setResponseBody(string|EntityBodyInterface|resource)`` method of a request. You can also set the ``save_to`` +option of a request: + +.. code-block:: php + + // Send the response body to a file + $request = $client->get('http://test.com', array(), array('save_to' => '/path/to/file')); + + // Send the response body to an fopen resource + $request = $client->get('http://test.com', array(), array('save_to' => fopen('/path/to/file', 'w'))); + +HEAD requests +~~~~~~~~~~~~~ + +`HEAD requests `_ work exactly like GET requests except +that they do not actually download the response body (entity) of the response message. HEAD requests are useful for +retrieving meta information about an entity identified by a Request-URI. + +.. code-block:: php + + $client = new Guzzle\Http\Client(); + $request = $client->head('http://www.amazon.com'); + $response = $request->send(); + echo $response->getContentLength(); + // >>> Will output the Content-Length header value + +DELETE requests +~~~~~~~~~~~~~~~ + +A `DELETE method `_ requests that the origin server +delete the resource identified by the Request-URI. + +.. code-block:: php + + $client = new Guzzle\Http\Client(); + $request = $client->delete('http://example.com'); + $response = $request->send(); + +POST requests +~~~~~~~~~~~~~ + +While `POST requests `_ can be used for a number of +reasons, POST requests are often used when submitting HTML form data to a website. POST requests can include an entity +body in the HTTP request. + +POST requests in Guzzle are sent with an ``application/x-www-form-urlencoded`` Content-Type header if POST fields are +present but no files are being sent in the POST. If files are specified in the POST request, then the Content-Type +header will become ``multipart/form-data``. + +The ``post()`` method of a client object accepts four arguments: the URL, optional headers, post fields, and an array of +request options. To send files in the POST request, prepend the ``@`` symbol to the array value (just like you would if +you were using the PHP ``curl_setopt`` function). + +Here's how to create a multipart/form-data POST request containing files and fields: + +.. code-block:: php + + $request = $client->post('http://httpbin.org/post', array(), array( + 'custom_field' => 'my custom value', + 'file_field' => '@/path/to/file.xml' + )); + + $response = $request->send(); + +.. note:: + + Remember to **always** sanitize user input when sending POST requests: + + .. code-block:: php + + // Prevent users from accessing sensitive files by sanitizing input + $_POST = array('firstname' => '@/etc/passwd'); + $request = $client->post('http://www.example.com', array(), array ( + 'firstname' => str_replace('@', '', $_POST['firstname']) + )); + +You can alternatively build up the contents of a POST request. + +.. code-block:: php + + $request = $client->post('http://httpbin.org/post') + ->setPostField('custom_field', 'my custom value') + ->addPostFile('file', '/path/to/file.xml'); + + $response = $request->send(); + +Raw POST data +^^^^^^^^^^^^^ + +POST requests can also contain raw POST data that is not related to HTML forms. + +.. code-block:: php + + $request = $client->post('http://httpbin.org/post', array(), 'this is the body'); + $response = $request->send(); + +You can set the body of POST request using the ``setBody()`` method of the +``Guzzle\Http\Message\EntityEnclosingRequest`` object. This method accepts a string, a resource returned from +``fopen``, or a ``Guzzle\Http\EntityBodyInterface`` object. + +.. code-block:: php + + $request = $client->post('http://httpbin.org/post'); + // Set the body of the POST to stream the contents of /path/to/large_body.txt + $request->setBody(fopen('/path/to/large_body.txt', 'r')); + $response = $request->send(); + +PUT requests +~~~~~~~~~~~~ + +The `PUT method `_ requests that the enclosed entity be +stored under the supplied Request-URI. PUT requests are similar to POST requests in that they both can send an entity +body in the request message. + +The body of a PUT request (any any ``Guzzle\Http\Message\EntityEnclosingRequestInterface`` object) is always stored as +a ``Guzzle\Http\Message\EntityBodyInterface`` object. This allows a great deal of flexibility when sending data to a +remote server. For example, you can stream the contents of a stream returned by fopen, stream the contents of a +callback function, or simply send a string of data. + +.. code-block:: php + + $request = $client->put('http://httpbin.org/put', array(), 'this is the body'); + $response = $request->send(); + +Just like with POST, PATH, and DELETE requests, you can set the body of a PUT request using the ``setBody()`` method. + +.. code-block:: php + + $request = $client->put('http://httpbin.org/put'); + $request->setBody(fopen('/path/to/large_body.txt', 'r')); + $response = $request->send(); + +PATCH requests +~~~~~~~~~~~~~~ + +`PATCH requests `_ are used to modify a resource. + +.. code-block:: php + + $request = $client->patch('http://httpbin.org', array(), 'this is the body'); + $response = $request->send(); + +OPTIONS requests +~~~~~~~~~~~~~~~~ + +The `OPTIONS method `_ represents a request for +information about the communication options available on the request/response chain identified by the Request-URI. + +.. code-block:: php + + $request = $client->options('http://httpbin.org'); + $response = $request->send(); + + // Check if the PUT method is supported by this resource + var_export($response->isMethodAllows('PUT')); + +Custom requests +~~~~~~~~~~~~~~~ + +You can create custom HTTP requests that use non-standard HTTP methods using the ``createRequest()`` method of a +client object. + +.. code-block:: php + + $request = $client->createRequest('COPY', 'http://example.com/foo', array( + 'Destination' => 'http://example.com/bar', + 'Overwrite' => 'T' + )); + $response = $request->send(); + +Query string parameters +----------------------- + +Query string parameters of a request are owned by a request's ``Guzzle\Http\Query`` object that is accessible by +calling ``$request->getQuery()``. The Query class extends from ``Guzzle\Common\Collection`` and allows you to set one +or more query string parameters as key value pairs. You can set a parameter on a Query object using the +``set($key, $value)`` method or access the query string object like an associative array. Any previously specified +value for a key will be overwritten when using ``set()``. Use ``add($key, $value)`` to add a value to query string +object, and in the event of a collision with an existing value at a specific key, the value will be converted to an +array that contains all of the previously set values. + +.. code-block:: php + + $request = new Guzzle\Http\Message\Request('GET', 'http://www.example.com?foo=bar&abc=123'); + + $query = $request->getQuery(); + echo "{$query}\n"; + // >>> foo=bar&abc=123 + + $query->remove('abc'); + echo "{$query}\n"; + // >>> foo=bar + + $query->set('foo', 'baz'); + echo "{$query}\n"; + // >>> foo=baz + + $query->add('foo', 'bar'); + echo "{$query}\n"; + // >>> foo%5B0%5D=baz&foo%5B1%5D=bar + +Whoah! What happened there? When ``foo=bar`` was added to the existing ``foo=baz`` query string parameter, the +aggregator associated with the Query object was used to help convert multi-value query string parameters into a string. +Let's disable URL-encoding to better see what's happening. + +.. code-block:: php + + $query->useUrlEncoding(false); + echo "{$query}\n"; + // >>> foo[0]=baz&foo[1]=bar + +.. note:: + + URL encoding can be disabled by passing false, enabled by passing true, set to use RFC 1738 by passing + ``Query::FORM_URLENCODED`` (internally uses PHP's ``urlencode`` function), or set to RFC 3986 by passing + ``Query::RFC_3986`` (this is the default and internally uses PHP's ``rawurlencode`` function). + +As you can see, the multiple values were converted into query string parameters following the default PHP convention of +adding numerically indexed square bracket suffixes to each key (``foo[0]=baz&foo[1]=bar``). The strategy used to convert +multi-value parameters into a string can be customized using the ``setAggregator()`` method of the Query class. Guzzle +ships with the following query string aggregators by default: + +1. ``Guzzle\Http\QueryAggregator\PhpAggregator``: Aggregates using PHP style brackets (e.g. ``foo[0]=baz&foo[1]=bar``) +2. ``Guzzle\Http\QueryAggregator\DuplicateAggregator``: Performs no aggregation and allows for key value pairs to be + repeated in a URL (e.g. ``foo=baz&foo=bar``) +3. ``Guzzle\Http\QueryAggregator\CommaAggregator``: Aggregates using commas (e.g. ``foo=baz,bar``) + +.. _http-message-headers: + +HTTP Message Headers +-------------------- + +HTTP message headers are case insensitive, multiple occurrences of any header can be present in an HTTP message +(whether it's valid or not), and some servers require specific casing of particular headers. Because of this, request +and response headers are stored in ``Guzzle\Http\Message\Header`` objects. The Header object can be cast as a string, +counted, or iterated to retrieve each value from the header. Casting a Header object to a string will return all of +the header values concatenated together using a glue string (typically ", "). + +A request (and response) object have several methods that allow you to retrieve and modify headers. + +* ``getHeaders()``: Get all of the headers of a message as a ``Guzzle\Http\Message\Header\HeaderCollection`` object. +* ``getHeader($header)``: Get a specific header from a message. If the header exists, you'll get a + ``Guzzle\Http\Message\Header`` object. If the header does not exist, this methods returns ``null``. +* ``hasHeader($header)``: Returns true or false based on if the message has a particular header. +* ``setHeader($header, $value)``: Set a header value and overwrite any previously set value for this header. +* ``addHeader($header, $value)``: Add a header with a particular name. If a previous value was already set by the same, + then the header will contain multiple values. +* ``removeHeader($header)``: Remove a header by name from the message. + +.. code-block:: php + + $request = new Request('GET', 'http://httpbin.com/cookies'); + // addHeader will set and append to any existing header values + $request->addHeader('Foo', 'bar'); + $request->addHeader('foo', 'baz'); + // setHeader overwrites any existing values + $request->setHeader('Test', '123'); + + // Request headers can be cast as a string + echo $request->getHeader('Foo'); + // >>> bar, baz + echo $request->getHeader('Test'); + // >>> 123 + + // You can count the number of headers of a particular case insensitive name + echo count($request->getHeader('foO')); + // >>> 2 + + // You can iterate over Header objects + foreach ($request->getHeader('foo') as $header) { + echo $header . "\n"; + } + + // You can get all of the request headers as a Guzzle\Http\Message\Header\HeaderCollection object + $headers = $request->getHeaders(); + + // Missing headers return NULL + var_export($request->getHeader('Missing')); + // >>> null + + // You can see all of the different variations of a header by calling raw() on the Header + var_export($request->getHeader('foo')->raw()); + +Setting the body of a request +----------------------------- + +Requests that can send a body (e.g. PUT, POST, DELETE, PATCH) are instances of +``Guzzle\Http\Message\EntityEnclosingRequestInterface``. Entity enclosing requests contain several methods that allow +you to specify the body to send with a request. + +Use the ``setBody()`` method of a request to set the body that will be sent with a request. This method accepts a +string, a resource returned by ``fopen()``, an array, or an instance of ``Guzzle\Http\EntityBodyInterface``. The body +will then be streamed from the underlying ``EntityBodyInterface`` object owned by the request. When setting the body +of the request, you can optionally specify a Content-Type header and whether or not to force the request to use +chunked Transfer-Encoding. + +.. code-block:: php + + $request = $client->put('/user.json'); + $request->setBody('{"foo":"baz"}', 'application/json'); + +Content-Type header +~~~~~~~~~~~~~~~~~~~ + +Guzzle will automatically add a Content-Type header to a request if the Content-Type can be guessed based on the file +extension of the payload being sent or the file extension present in the path of a request. + +.. code-block:: php + + $request = $client->put('/user.json', array(), '{"foo":"bar"}'); + // The Content-Type was guessed based on the path of the request + echo $request->getHeader('Content-Type'); + // >>> application/json + + $request = $client->put('/user.json'); + $request->setBody(fopen('/tmp/user_data.json', 'r')); + // The Content-Type was guessed based on the path of the entity body + echo $request->getHeader('Content-Type'); + // >>> application/json + +Transfer-Encoding: chunked header +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When sending HTTP requests that contain a payload, you must let the remote server know how to determine when the entire +message has been sent. This usually is done by supplying a ``Content-Length`` header that tells the origin server the +size of the body that is to be sent. In some cases, the size of the payload being sent in a request cannot be known +before initiating the transfer. In these cases (when using HTTP/1.1), you can use the ``Transfer-Encoding: chunked`` +header. + +If the Content-Length cannot be determined (i.e. using a PHP ``http://`` stream), then Guzzle will automatically add +the ``Transfer-Encoding: chunked`` header to the request. + +.. code-block:: php + + $request = $client->put('/user.json'); + $request->setBody(fopen('http://httpbin.org/get', 'r')); + + // The Content-Length could not be determined + echo $request->getHeader('Transfer-Encoding'); + // >>> chunked + +See :doc:`/http-client/entity-bodies` for more information on entity bodies. + +Expect: 100-Continue header +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``Expect: 100-Continue`` header is used to help a client prevent sending a large payload to a server that will +reject the request. This allows clients to fail fast rather than waste bandwidth sending an erroneous payload. Guzzle +will automatically add the ``Expect: 100-Continue`` header to a request when the size of the payload exceeds 1MB or if +the body of the request is not seekable (this helps to prevent errors when a non-seekable body request is redirected). + +.. note:: + + If you find that your larger requests are taking too long to complete, you should first check if the + ``Expect: 100-Continue`` header is being sent with the request. Some servers do not respond well to this header, + which causes cURL to sleep for `1 second `_. + +POST fields and files +~~~~~~~~~~~~~~~~~~~~~ + +Any entity enclosing request can send POST style fields and files. This includes POST, PUT, PATCH, and DELETE requests. +Any request that has set POST fields or files will use cURL's POST message functionality. + +.. code-block:: php + + $request = $client->post('/post'); + // Set an overwrite any previously specified value + $request->setPostField('foo', 'bar'); + // Append a value to any existing values + $request->getPostFields()->add('foo', 'baz'); + // Remove a POST field by name + $request->removePostField('fizz'); + + // Add a file to upload (forces multipart/form-data) + $request->addPostFile('my_file', '/path/to/file', 'plain/text'); + // Remove a POST file by POST key name + $request->removePostFile('my_other_file'); + +.. tip:: + + Adding a large number of POST fields to a POST request is faster if you use the ``addPostFields()`` method so that + you can add and process multiple fields with a single call. Adding multiple POST files is also faster using + ``addPostFiles()``. + +Working with cookies +-------------------- + +Cookies can be modified and retrieved from a request using the following methods: + +.. code-block:: php + + $request->addCookie($name, $value); + $request->removeCookie($name); + $value = $request->getCookie($name); + $valueArray = $request->getCookies(); + +Use the :doc:`cookie plugin ` if you need to reuse cookies between requests. + +.. _request-set-response-body: + +Changing where a response is downloaded +---------------------------------------- + +When a request is sent, the body of the response will be stored in a PHP temp stream by default. You can change the +location in which the response will be downloaded using ``$request->setResponseBody($body)`` or the ``save_to`` request +option. This can be useful for downloading the contents of a URL to a specific file. + +Here's an example of using request options: + +.. code-block:: php + + $request = $this->client->get('http://example.com/large.mov', array(), array( + 'save_to' => '/tmp/large_file.mov' + )); + $request->send(); + var_export(file_exists('/tmp/large_file.mov')); + // >>> true + +Here's an example of using ``setResponseBody()``: + +.. code-block:: php + + $body = fopen('/tmp/large_file.mov', 'w'); + $request = $this->client->get('http://example.com/large.mov'); + $request->setResponseBody($body); + + // You can more easily specify the name of a file to save the contents + // of the response to by passing a string to ``setResponseBody()``. + + $request = $this->client->get('http://example.com/large.mov'); + $request->setResponseBody('/tmp/large_file.mov'); + +Custom cURL options +------------------- + +Most of the functionality implemented in the libcurl bindings has been simplified and abstracted by Guzzle. Developers +who need access to `cURL specific functionality `_ can still add cURL handle +specific behavior to Guzzle HTTP requests by modifying the cURL options collection of a request: + +.. code-block:: php + + $request->getCurlOptions()->set(CURLOPT_LOW_SPEED_LIMIT, 200); + +Other special options that can be set in the ``curl.options`` array include: + ++-------------------------+---------------------------------------------------------------------------------+ +| debug | Adds verbose cURL output to a temp stream owned by the cURL handle object | ++-------------------------+---------------------------------------------------------------------------------+ +| progress | Instructs cURL to emit events when IO events occur. This allows you to be | +| | notified when bytes are transferred over the wire by subscribing to a request's | +| | ``curl.callback.read``, ``curl.callback.write``, and ``curl.callback.progress`` | +| | events. | ++-------------------------+---------------------------------------------------------------------------------+ + +Request options +--------------- + +Requests options can be specified when creating a request or in the ``request.options`` parameter of a client. These +options can control various aspects of a request including: headers to send, query string data, where the response +should be downloaded, proxies, auth, etc. + +.. code-block:: php + + $request = $client->get($url, $headers, array('proxy' => 'http://proxy.com')); + +See :ref:`Request options ` for more information. + +Working with errors +------------------- + +HTTP errors +~~~~~~~~~~~ + +Requests that receive a 4xx or 5xx response will throw a ``Guzzle\Http\Exception\BadResponseException``. More +specifically, 4xx errors throw a ``Guzzle\Http\Exception\ClientErrorResponseException``, and 5xx errors throw a +``Guzzle\Http\Exception\ServerErrorResponseException``. You can catch the specific exceptions or just catch the +BadResponseException to deal with either type of error. Here's an example of catching a generic BadResponseException: + +.. code-block:: php + + try { + $response = $client->get('/not_found.xml')->send(); + } catch (Guzzle\Http\Exception\BadResponseException $e) { + echo 'Uh oh! ' . $e->getMessage(); + echo 'HTTP request URL: ' . $e->getRequest()->getUrl() . "\n"; + echo 'HTTP request: ' . $e->getRequest() . "\n"; + echo 'HTTP response status: ' . $e->getResponse()->getStatusCode() . "\n"; + echo 'HTTP response: ' . $e->getResponse() . "\n"; + } + +Throwing an exception when a 4xx or 5xx response is encountered is the default behavior of Guzzle requests. This +behavior can be overridden by adding an event listener with a higher priority than -255 that stops event propagation. +You can subscribe to ``request.error`` to receive notifications any time an unsuccessful response is received. + +You can change the response that will be associated with the request by calling ``setResponse()`` on the +``$event['request']`` object passed into your listener, or by changing the ``$event['response']`` value of the +``Guzzle\Common\Event`` object that is passed to your listener. Transparently changing the response associated with a +request by modifying the event allows you to retry failed requests without complicating the code that uses the client. +This might be useful for sending requests to a web service that has expiring auth tokens. When a response shows that +your token has expired, you can get a new token, retry the request with the new token, and return the successful +response to the user. + +Here's an example of retrying a request using updated authorization credentials when a 401 response is received, +overriding the response of the original request with the new response, and still allowing the default exception +behavior to be called when other non-200 response status codes are encountered: + +.. code-block:: php + + // Add custom error handling to any request created by this client + $client->getEventDispatcher()->addListener('request.error', function(Event $event) { + + if ($event['response']->getStatusCode() == 401) { + + $newRequest = $event['request']->clone(); + $newRequest->setHeader('X-Auth-Header', MyApplication::getNewAuthToken()); + $newResponse = $newRequest->send(); + + // Set the response object of the request without firing more events + $event['response'] = $newResponse; + + // You can also change the response and fire the normal chain of + // events by calling $event['request']->setResponse($newResponse); + + // Stop other events from firing when you override 401 responses + $event->stopPropagation(); + } + + }); + +cURL errors +~~~~~~~~~~~ + +Connection problems and cURL specific errors can also occur when transferring requests using Guzzle. When Guzzle +encounters cURL specific errors while transferring a single request, a ``Guzzle\Http\Exception\CurlException`` is +thrown with an informative error message and access to the cURL error message. + +A ``Guzzle\Http\Exception\MultiTransferException`` exception is thrown when a cURL specific error occurs while +transferring multiple requests in parallel. You can then iterate over all of the exceptions encountered during the +transfer. + +Plugins and events +------------------ + +Guzzle request objects expose various events that allow you to hook in custom logic. A request object owns a +``Symfony\Component\EventDispatcher\EventDispatcher`` object that can be accessed by calling +``$request->getEventDispatcher()``. You can use the event dispatcher to add listeners (a simple callback function) or +event subscribers (classes that listen to specific events of a dispatcher). You can add event subscribers to a request +directly by just calling ``$request->addSubscriber($mySubscriber);``. + +.. _request-events: + +Events emitted from a request +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A ``Guzzle\Http\Message\Request`` and ``Guzzle\Http\Message\EntityEnclosingRequest`` object emit the following events: + ++------------------------------+--------------------------------------------+------------------------------------------+ +| Event name | Description | Event data | ++==============================+============================================+==========================================+ +| request.before_send | About to send request | * request: Request to be sent | ++------------------------------+--------------------------------------------+------------------------------------------+ +| request.sent | Sent the request | * request: Request that was sent | +| | | * response: Received response | ++------------------------------+--------------------------------------------+------------------------------------------+ +| request.complete | Completed a full HTTP transaction | * request: Request that was sent | +| | | * response: Received response | ++------------------------------+--------------------------------------------+------------------------------------------+ +| request.success | Completed a successful request | * request: Request that was sent | +| | | * response: Received response | ++------------------------------+--------------------------------------------+------------------------------------------+ +| request.error | Completed an unsuccessful request | * request: Request that was sent | +| | | * response: Received response | ++------------------------------+--------------------------------------------+------------------------------------------+ +| request.exception | An unsuccessful response was | * request: Request | +| | received. | * response: Received response | +| | | * exception: BadResponseException | ++------------------------------+--------------------------------------------+------------------------------------------+ +| request.receive.status_line | Received the start of a response | * line: Full response start line | +| | | * status_code: Status code | +| | | * reason_phrase: Reason phrase | +| | | * previous_response: (e.g. redirect) | ++------------------------------+--------------------------------------------+------------------------------------------+ +| curl.callback.progress | cURL progress event (only dispatched when | * handle: CurlHandle | +| | ``emit_io`` is set on a request's curl | * download_size: Total download size | +| | options) | * downloaded: Bytes downloaded | +| | | * upload_size: Total upload bytes | +| | | * uploaded: Bytes uploaded | ++------------------------------+--------------------------------------------+------------------------------------------+ +| curl.callback.write | cURL event called when data is written to | * request: Request | +| | an outgoing stream | * write: Data being written | ++------------------------------+--------------------------------------------+------------------------------------------+ +| curl.callback.read | cURL event called when data is written to | * request: Request | +| | an incoming stream | * read: Data being read | ++------------------------------+--------------------------------------------+------------------------------------------+ + +Creating a request event listener +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Here's an example that listens to the ``request.complete`` event of a request and prints the request and response. + +.. code-block:: php + + use Guzzle\Common\Event; + + $request = $client->get('http://www.google.com'); + + // Echo out the response that was received + $request->getEventDispatcher()->addListener('request.complete', function (Event $e) { + echo $e['request'] . "\n\n"; + echo $e['response']; + }); diff --git a/vendor/guzzle/guzzle/docs/http-client/response.rst b/vendor/guzzle/guzzle/docs/http-client/response.rst new file mode 100644 index 0000000..ba48731 --- /dev/null +++ b/vendor/guzzle/guzzle/docs/http-client/response.rst @@ -0,0 +1,141 @@ +====================== +Using Response objects +====================== + +Sending a request will return a ``Guzzle\Http\Message\Response`` object. You can view the raw HTTP response message by +casting the Response object to a string. Casting the response to a string will return the entity body of the response +as a string too, so this might be an expensive operation if the entity body is stored in a file or network stream. If +you only want to see the response headers, you can call ``getRawHeaders()``. + +Response status line +-------------------- + +The different parts of a response's `status line `_ +(the first line of the response HTTP message) are easily retrievable. + +.. code-block:: php + + $response = $client->get('http://www.amazon.com')->send(); + + echo $response->getStatusCode(); // >>> 200 + echo $response->getReasonPhrase(); // >>> OK + echo $response->getProtocol(); // >>> HTTP + echo $response->getProtocolVersion(); // >>> 1.1 + +You can determine the type of the response using several helper methods: + +.. code-block:: php + + $response->isSuccessful(); // true + $response->isInformational(); + $response->isRedirect(); + $response->isClientError(); + $response->isServerError(); + +Response headers +---------------- + +The Response object contains helper methods for retrieving common response headers. These helper methods normalize the +variations of HTTP response headers. + +.. code-block:: php + + $response->getCacheControl(); + $response->getContentType(); + $response->getContentLength(); + $response->getContentEncoding(); + $response->getContentMd5(); + $response->getEtag(); + // etc... There are methods for every known response header + +You can interact with the Response headers using the same exact methods used to interact with Request headers. See +:ref:`http-message-headers` for more information. + +.. code-block:: php + + echo $response->getHeader('Content-Type'); + echo $response->getHeader('Content-Length'); + echo $response->getHeaders()['Content-Type']; // PHP 5.4 + +Response body +------------- + +The entity body object of a response can be retrieved by calling ``$response->getBody()``. The response EntityBody can +be cast to a string, or you can pass ``true`` to this method to retrieve the body as a string. + +.. code-block:: php + + $request = $client->get('http://www.amazon.com'); + $response = $request->send(); + echo $response->getBody(); + +See :doc:`/http-client/entity-bodies` for more information on entity bodies. + +JSON Responses +~~~~~~~~~~~~~~ + +You can easily parse and use a JSON response as an array using the ``json()`` method of a response. This method will +always return an array if the response is valid JSON or if the response body is empty. You will get an exception if you +call this method and the response is not valid JSON. + +.. code-block:: php + + $data = $response->json(); + echo gettype($data); + // >>> array + +XML Responses +~~~~~~~~~~~~~ + +You can easily parse and use a XML response as SimpleXMLElement object using the ``xml()`` method of a response. This +method will always return a SimpleXMLElement object if the response is valid XML or if the response body is empty. You +will get an exception if you call this method and the response is not valid XML. + +.. code-block:: php + + $xml = $response->xml(); + echo $xml->foo; + // >>> Bar! + +Streaming responses +------------------- + +Some web services provide streaming APIs that allow a client to keep a HTTP request open for an extended period of +time while polling and reading. Guzzle provides a simple way to convert HTTP request messages into +``Guzzle\Stream\Stream`` objects so that you can send the initial headers of a request, read the response headers, and +pull in the response body manually as needed. + +Here's an example using the Twitter Streaming API to track the keyword "bieber": + +.. code-block:: php + + use Guzzle\Http\Client; + use Guzzle\Stream\PhpStreamRequestFactory; + + $client = new Client('https://stream.twitter.com/1'); + + $request = $client->post('statuses/filter.json', null, array( + 'track' => 'bieber' + )); + + $request->setAuth('myusername', 'mypassword'); + + $factory = new PhpStreamRequestFactory(); + $stream = $factory->fromRequest($request); + + // Read until the stream is closed + while (!$stream->feof()) { + // Read a line from the stream + $line = $stream->readLine(); + // JSON decode the line of data + $data = json_decode($line, true); + } + +You can use the ``stream`` request option when using a static client to more easily create a streaming response. + +.. code-block:: php + + $stream = Guzzle::get('http://guzzlephp.org', array('stream' => true)); + while (!$stream->feof()) { + echo $stream->readLine(); + } diff --git a/vendor/guzzle/guzzle/docs/http-client/uri-templates.rst b/vendor/guzzle/guzzle/docs/http-client/uri-templates.rst new file mode 100644 index 0000000..c18ac3e --- /dev/null +++ b/vendor/guzzle/guzzle/docs/http-client/uri-templates.rst @@ -0,0 +1,52 @@ +============= +URI templates +============= + +The ``$uri`` passed to one of the client's request creational methods or the base URL of a client can utilize URI +templates. Guzzle supports the entire `URI templates RFC `_. URI templates add a +special syntax to URIs that replace template place holders with user defined variables. + +Every request created by a Guzzle HTTP client passes through a URI template so that URI template expressions are +automatically expanded: + +.. code-block:: php + + $client = new Guzzle\Http\Client('https://example.com/', array('a' => 'hi')); + $request = $client->get('/{a}'); + +Because of URI template expansion, the URL of the above request will become ``https://example.com/hi``. Notice that +the template was expanded using configuration variables of the client. You can pass in custom URI template variables +by passing the URI of your request as an array where the first index of the array is the URI template and the second +index of the array are template variables that are merged into the client's configuration variables. + +.. code-block:: php + + $request = $client->get(array('/test{?a,b}', array('b' => 'there'))); + +The URL for this request will become ``https://test.com?a=hi&b=there``. URI templates aren't limited to just simple +variable replacements; URI templates can provide an enormous amount of flexibility when creating request URIs. + +.. code-block:: php + + $request = $client->get(array('http://example.com{+path}{/segments*}{?query,data*}', array( + 'path' => '/foo/bar', + 'segments' => array('one', 'two'), + 'query' => 'test', + 'data' => array( + 'more' => 'value' + ) + ))); + +The resulting URL would become ``http://example.com/foo/bar/one/two?query=test&more=value``. + +By default, URI template expressions are enclosed in an opening and closing brace (e.g. ``{var}``). If you are working +with a web service that actually uses braces (e.g. Solr), then you can specify a custom regular expression to use to +match URI template expressions. + +.. code-block:: php + + $client->getUriTemplate()->setRegex('/\<\$(.+)\>/'); + $client->get('/<$a>'); + +You can learn about all of the different features of URI templates by reading the +`URI templates RFC `_. -- cgit v1.2.3-54-g00ecf