update 1.0.8.0

Commits for version update
This commit is contained in:
Manish Verma
2016-10-17 12:02:27 +05:30
parent dec927987b
commit 76e85db070
9674 changed files with 495757 additions and 58922 deletions

View File

@@ -0,0 +1,529 @@
# HTTP Client Connection Adapters
`Zend\Http\Client` is based on a connection adapter design. The connection adapter is the object in
charge of performing the actual connection to the server, as well as writing requests and reading
responses. This connection adapter can be replaced, and you can create and extend the default
connection adapters to suit your special needs, without the need to extend or replace the entire
HTTP client class.
Currently, zend-http provides four built-in client connection adapters:
- `Zend\Http\Client\Adapter\Socket` (default)
- `Zend\Http\Client\Adapter\Proxy`
- `Zend\Http\Client\Adapter\Curl`
- `Zend\Http\Client\Adapter\Test`
The client can accept an adapter via either its `setAdapter()` method, or during
instantiation via its `adapter` configuration option. When using configuration,
the value of the `adapter` option may be one of:
- an adapter instance
- the fully qualified class name of an adapter
## The Socket adapter
The default connection adapter used when none is specified is the
`Zend\Http\Client\Adapter\Socket` adapter. The `Socket` adapter is based on
PHP's built-in `fsockopen()` function, and does not require any special
extensions or compilation flags.
The `Socket` adapter allows several extra configuration options that can be set
via either the client's constructor or `setOptions()` method:
Parameter | Description | Expected Type | Default Value
---------------------|--------------------------------------------------------------------------------------|---------------|--------------
`persistent` | Whether to use persistent TCP connections | boolean | `FALSE`
`ssltransport` | SSL transport layer (eg. `sslv2`, `tls`) | string | `ssl`
`sslcert` | Path to a PEM encoded SSL certificate | string | `NULL`
`sslpassphrase` | Passphrase for the SSL certificate file | string | `NULL`
`sslverifypeer` | Whether to verify the SSL peer | string | `TRUE`
`sslcapath` | Path to SSL certificate directory | string | `NULL`
`sslallowselfsigned` | Whether to allow self-signed certificates | string | `FALSE`
`sslusecontext` | Enables proxied connections to use SSL even if the proxy connection itself does not. | boolean | `FALSE`
> ### Persistent TCP connections
>
> Using persistent TCP connections can potentially speed up HTTP requests, but
> in most use cases, will have little positive effect and might overload the
> HTTP server you are connecting to. It is recommended to use persistent TCP
> connections only if you connect to the same server very frequently, and are
> sure that the server is capable of handling a large number of concurrent
> connections. In any case you are encouraged to benchmark the effect of
> persistent connections on both the client speed and server load before using
> this option.
>
> Additionally, when using persistent connections, we recommend enabling
> Keep-Alive HTTP requests as described in [the client configuration section](intro.md#configuration);
> otherwise persistent connections might have little or no effect.
> ### HTTPS SSL stream parameters
>
> `ssltransport`, `sslcert` and `sslpassphrase` are only relevant when
> connecting using HTTPS. While the default SSL/TLS settings should work for
> most applications, you might need to change them if the server you are
> connecting to requires special client setup. If so, please read the
> [PHP manual chapter on SSL and TLS transport options](http://php.net/transports.inet).
### Changing the HTTPS transport layer
```php
use Zend\Http\Client;
// Set the configuration parameters
$config = [
'adapter' => Client\Adapter\Socket::class,
'ssltransport' => 'tls',
];
// Instantiate a client object
$client = new Client('https://www.example.com', $config);
// The following request will be sent over a TLS secure connection.
$response = $client->send();
```
The result of the example above will be similar to opening a TCP connection
using the following PHP command:
```php
fsockopen('tls://www.example.com', 443);
```
### Customizing and accessing the Socket adapter stream context
`Zend\Http\Client\Adapter\Socket` provides direct access to the underlying
[stream context](http://php.net/stream.contexts) used to connect to the remote
server. This allows the user to pass specific options and parameters to the TCP
stream, and to the SSL wrapper in case of HTTPS connections.
You can access the stream context using the following methods of
`Zend\Http\Client\Adapter\Socket`:
- `setStreamContext($context)`: Sets the stream context to be used by the
adapter. Can accept either a stream context resource created using the
[stream_context_create()](http://php.net/stream_context_create) PHP function,
or an array of stream context options, in the same format provided to this
function. Providing an array will create a new stream context using these
options, and set it.
- `getStreamContext()`: Get the current stream context of the adapter. If no
stream context was set, this method will create a default stream context and
return it. You can then set or get the value of different context options
using regular PHP stream context functions.
#### Setting stream context options for the Socket adapter
```php
use Zend\Http\Client;
// Array of options
$options = [
'socket' => [
// Bind local socket side to a specific interface
'bindto' => '10.1.2.3:50505',
],
'ssl' => [
// Verify server side certificate,
// do not accept invalid or self-signed SSL certificates
'verify_peer' => true,
'allow_self_signed' => false,
// Capture the peer's certificate
'capture_peer_cert' => true,
],
];
// Create an adapter object and attach it to the HTTP client:
$adapter = new Client\Adapter\Socket();
$client = new Client();
$client->setAdapter($adapter);
// Method 1: pass the options array to setStreamContext():
$adapter->setStreamContext($options);
// Method 2: create a stream context and pass it to setStreamContext():
$context = stream_context_create($options);
$adapter->setStreamContext($context);
// Method 3: get the default stream context and set the options on it:
$context = $adapter->getStreamContext();
stream_context_set_option($context, $options);
// Now, perform the request:
$response = $client->send();
// If everything went well, you can now access the context again:
$opts = stream_context_get_options($adapter->getStreamContext());
echo $opts['ssl']['peer_certificate'];
```
> #### Set stream context options prior to requests
>
> Note that you must set any stream context options before using the adapter to
> perform actual requests. If no context is set before performing HTTP requests
> with the `Socket` adapter, a default stream context will be created. This
> context resource could be accessed after performing any requests using the
> `getStreamContext()` method.
## The Proxy adapter
`Zend\Http\Client\Adapter\Proxy` is similar to the default `Socket` adapter; the
primary difference is that the connection is made through an HTTP proxy server
instead of a direct connection to the target server. This allows usage of
`Zend\Http\Client` behind proxy servers, which is sometimes required for
security or performance reasons.
Using the `Proxy` adapter requires several additional client configuration
parameters to be set, in addition to the default `adapter` option:
Parameter | Description | Expected Type | Example Value
-------------|--------------------------------|---------------|--------------
`proxy_host` | Proxy server address | string | 'proxy.myhost.com' or '10.1.2.3'
`proxy_port` | Proxy server TCP port | integer | 8080 (default) or 81
`proxy_user` | Proxy user name, if required | string | 'shahar' or '' for none (default)
`proxy_pass` | Proxy password, if required | string | 'secret' or '' for none (default)
`proxy_auth` | Proxy HTTP authentication type | string | `Zend\Http\Client::AUTH_BASIC` (default)
`proxy_host` should always be set; if it is not set, the client will fall back
to a direct connection using `Zend\Http\Client\Adapter\Socket`. `proxy_port`
defaults to '8080'; if your proxy listens on a different port, you must set this
one as well.
`proxy_user` and `proxy_pass` are only required if your proxy server requires
you to authenticate. Providing these will add a 'Proxy-Authentication' header
to the request. If your proxy does not require authentication, you can leave
these two options out.
`proxy_auth` sets the proxy authentication type, if your proxy server requires
authentication. Possible values are similar to the ones accepted by the
`Zend\Http\Client::setAuth()` method. Currently, only basic authentication
(`Zend\Http\Client::AUTH_BASIC`) is supported.
### Using Zend\\Http\\Client behind a proxy server
```php
use Zend\Http\Client;
// Set the configuration parameters
$config = [
'adapter' => Client\Adapter\Proxy::class,
'proxy_host' => 'proxy.int.zend.com',
'proxy_port' => 8000,
'proxy_user' => 'shahar.e',
'proxy_pass' => 'bananashaped',
];
// Instantiate a client object
$client = new Client('http://www.example.com', $config);
// Continue working...
```
As mentioned, if `proxy_host` is not set or is set to a blank string, the
connection will fall back to a regular direct connection. This allows you to
write your application in a way that allows a proxy to be used optionally,
according to a configuration parameter.
> ### Access to stream context
>
> Since the proxy adapter inherits from `Zend\Http\Client\Adapter\Socket`, you
> can use the stream context access method (see
> [above](#setting-stream-context-options-for-the-socket-adapter)) to set stream
> context options on `Proxy` connections.
## The cURL Adapter
cURL is a standard HTTP client library that is distributed with many operating
systems and can be used in PHP via the cURL extension. It offers functionality
for many special cases which can occur for a HTTP client and make it a perfect
choice for a HTTP adapter. It supports secure connections, proxies, and multiple
authentication mechanisms. In particular, it is very performant with regards to
transfering large files.
### Setting cURL options
```php
use Zend\Http\Client;
$config = [
'adapter' => Client\Adapter\Curl::class,
'curloptions' => [CURLOPT_FOLLOWLOCATION => true],
];
$client = new Client($uri, $config);
```
By default, the cURL adapter is configured to behave exactly like the `Socket`
adapter, and it also accepts the same configuration parameters as the `Socket`
and `Proxy` adapters. You can also change the cURL options by either specifying
the 'curloptions' key in the constructor of the adapter, or by calling
`setCurlOption($name, $value)`; option names correspond to the `CURL_*`
constants of the cURL extension. You can get access to the underling cURL handle
by calling `$adapter->getHandle();`
### Transfering files by handle
You can use cURL to transfer very large files over HTTP by filehandle.
```php
use Zend\Http\Client;
$putFileSize = filesize('filepath');
$putFileHandle = fopen('filepath', 'r');
$adapter = new Client\Adapter\Curl();
$client = new Client();
$client->setAdapter($adapter);
$client->setMethod('PUT');
$adapter->setOptions([
'curloptions' => [
CURLOPT_INFILE => $putFileHandle,
CURLOPT_INFILESIZE => $putFileSize,
],
]);
$client->send();
```
## The Test adapter
Testing code that relies on HTTP connections poses difficulties. For example,
testing an application that pulls an RSS feed from a remote server will require
a network connection, which is not always available.
`Zend\Http\Client\Adapter\Test` provides a solution for these situations and
acts as a mock object for unit tests. You can write your application to use
`Zend\Http\Client`, and, when testing (either in your unit test suite, or in
non-production environments), replace the default adapter with the test adapter,
allowing you to run tests without actually performing server connections.
`Zend\Http\Client\Adapter\Test` provides two additional methods, `setResponse()`
and `addResponse()`. Each takes one parameter, which represents an HTTP
response as either text or a `Zend\Http\Response` object. `setResponse()` sets
an individual response to always return from any request; `addResponse()` allows
aggregating a sequence of responses. In both cases, responses are returned
without performing actual HTTP requests.
### Testing against a single HTTP response stub
```php
use Zend\Http\Client;
// Instantiate a new adapter and client
$adapter = new Client\Adapter\Test();
$client = new Client(
'http://www.example.com',
['adapter' => $adapter]
);
// Set the expected response
$adapter->setResponse(
"HTTP/1.1 200 OK\r\n"
. "Content-type: text/xml\r\n"
. "\r\n"
. '<?xml version="1.0" encoding="UTF-8"?>'
. '<rss version="2.0" '
. ' xmlns:content="http://purl.org/rss/1.0/modules/content/"'
. ' xmlns:wfw="http://wellformedweb.org/CommentAPI/"'
. ' xmlns:dc="http://purl.org/dc/elements/1.1/">'
. ' <channel>'
. ' <title>Premature Optimization</title>'
// and so on...
. '</rss>'
);
$response = $client->send();
// .. continue parsing $response..
```
The above example shows how you can preset your HTTP client to return the
response you need. Then, you can continue testing your own code, without being
dependent on a network connection, the server's response, etc. In this case, the
test would continue to check how the application parses the XML in the response
body.
Sometimes, a single method call to an object can result in that object
performing multiple HTTP transactions. In this case, it's not possible to use
`setResponse()` alone because there's no opportunity to set the next response(s)
your program might need before returning to the caller.
### Testing Against Multiple HTTP Response Stubs
```php
use Zend\Http\Client;
// Instantiate a new adapter and client
$adapter = new Client\Adapter\Test();
$client = new Client(
'http://www.example.com',
['adapter' => $adapter]
);
// Set the first expected response
$adapter->setResponse(
"HTTP/1.1 302 Found\r\n"
. "Location: /\r\n"
. "Content-Type: text/html\r\n"
. "\r\n"
. '<html>'
. ' <head><title>Moved</title></head>'
. ' <body><p>This page has moved.</p></body>'
. '</html>'
);
// Set the next successive response
$adapter->addResponse(
"HTTP/1.1 200 OK\r\n"
. "Content-Type: text/html\r\n"
. "\r\n"
. '<html>'
. ' <head><title>My Pet Store Home Page</title></head>'
. ' <body><p>...</p></body>'
. '</html>'
);
// inject the http client object ($client) into your object
// being tested and then test your object's behavior below
```
The `setResponse()` method clears any responses in the adapter's buffer and sets
the first response that will be returned. The `addResponse()` method will add
successive responses.
The responses will be replayed in the order that they were added. If more
requests are made than the number of responses stored, the responses will cycle
again in order.
In the example above, the adapter is configured to test your object's behavior
when it encounters a 302 redirect. Depending on your application, following a
redirect may or may not be desired behavior. In our example, we expect that the
redirect will be followed and we configure the test adapter to help us test
this. The initial 302 response is set up with the `setResponse()` method and the
200 response to be returned next is added with the `addResponse()` method. After
configuring the test adapter, inject the HTTP client containing the adapter into
your object under test and test its behavior.
### Forcing the adapter to fail
If you need the adapter to fail on demand you can use
`setNextRequestWillFail($flag)`. The method will cause the next call to
`connect()` to throw an `Zend\Http\Client\Adapter\Exception\RuntimeException`.
This can be useful when our application caches content from an external site (in
case the site goes down) and you want to test this feature.
```php
use Zend\Http\Client;
// Instantiate a new adapter and client
$adapter = new Client\Adapter\Test();
$client = new Client(
'http://www.example.com',
['adapter' => $adapter]
);
// Force the next request to fail with an exception
$adapter->setNextRequestWillFail(true);
try {
// This call will result in an exception.
$client->send();
} catch (Client\Adapter\Exception\RuntimeException $e) {
// ...
}
// Further requests will work as expected until
// you call setNextRequestWillFail(true) again
```
## Creating your own connection adapters
`Zend\Http\Client` has been designed so that you can create and use your own
connection adapters. You could, for example, create a connection adapter that
uses persistent sockets, or a connection adapter with caching abilities, and use
them as needed in your application.
In order to do so, you must create your own adapter class that implements
`Zend\Http\Client\Adapter\AdapterInterface`. The following example shows the
skeleton of a user-implemented adapter class. All the public functions defined
in this example must be defined in your adapter as well.
```php
namespace MyApp\Http\Client\Adapter;
use Zend\Http\Client\Adapter\AdapterInterface;
class BananaProtocol implements AdapterInterface
{
/**
* Set Adapter Options
*
* @param array $config
*/
public function setOptions($config = [])
{
// This rarely changes - you should usually copy the
// implementation in Zend\Http\Client\Adapter\Socket.
}
/**
* Connect to the remote server
*
* @param string $host
* @param int $port
* @param boolean $secure
*/
public function connect($host, $port = 80, $secure = false)
{
// Set up the connection to the remote server
}
/**
* Send request to the remote server
*
* @param string $method
* @param Zend\Uri\Http $url
* @param string $http_ver
* @param array $headers
* @param string $body
* @return string Request as text
*/
public function write(
$method,
$url,
$http_ver = '1.1',
$headers = [],
$body = ''
) {
// Send request to the remote server.
// This function is expected to return the full request
// (headers and body) as a string
}
/**
* Read response from server
*
* @return string
*/
public function read()
{
// Read response from remote server and return it as a string
}
/**
* Close the connection to the server
*
*/
public function close()
{
// Close the connection to the remote server - called last.
}
}
```
Use the adapter as you would any other:
```php
use MyApp\Http\Client\Adapter\BananaProtocol;
use Zend\Http\Client;
$client = new Client([
'adapter' => BananaProtocol::class,
]);
```

View File

@@ -0,0 +1,357 @@
# HTTP Client Advanced Usage
## HTTP redirections
`Zend\Http\Client` automatically handles HTTP redirections, and by default
will follow up to 5 redirections. This can be changed by setting the
`maxredirects` configuration parameter.
According to the HTTP/1.1 RFC, HTTP 301 and 302 responses should be treated by
the client by resending the same request to the specified location, using the
same request method. However, most clients to not implement this and always use
a `GET` request when redirecting. By default, `Zend\Http\Client` does the same;
when redirecting on a 301 or 302 response, all query and body parameters are
reset, and a `GET` request is sent to the new location. This behavior can be
changed by setting the `strictredirects` configuration parameter to boolean
`TRUE`:
```php
// Strict Redirections
$client->setOptions(['strictredirects' => true]);
// Non-strict Redirections
$client->setOptions(['strictredirects' => false]);
```
You can always get the number of redirections done after sending a request
using the `getRedirectionsCount()` method.
## Adding cookies and using cookie persistence
`Zend\Http\Client` provides an interface for adding cookies to your request, so
that no direct header modification is required. Cookies can be added using
either the addCookie() or `setCookies()` method. `addCookie()` can accept
either a name and value, a `SetCookie` header instance, or an array of
`SetCookie` header instances.
```php
use Zend\Http\Header\SetCookie;
// Basic usage: provide a cookie name and cookie value:
$client->addCookie('flavor', 'chocolate chips');
// Or provide a SetCookie instance:
$cookie = SetCookie::fromString('Set-Cookie: flavor=chocolate%20chips');
$client->addCookie($cookie);
// Multiple cookies can be set at once by providing an
// array of SetCookie instances:
$cookies = [
SetCookie::fromString('Set-Cookie: flavorOne=chocolate%20chips'),
SetCookie::fromString('Set-Cookie: flavorTwo=vanilla'),
];
$client->addCookie($cookies);
```
The `setCookies()` method works in a similar manner, except that it requires an
array of cookie name/value pairs as its only argument, and also clears the
cookie container before adding the new cookies:
```php
// setCookies accepts an array of cookie values as $name => $value
$client->setCookies([
'flavor' => 'chocolate chips',
'amount' => 10,
]);
```
See the [Headers documentation](../headers.md#setcookie) for more detail on the
`SetCookie` class.
### Enabling Cookie Stickiness
`Zend\Http\Client` also provides a means for simplifying cookie "stickiness"
&mdash; i.e., having the client internally store all sent and received cookies,
and resending them on subsequent requests. &mdash; via the `Zend\Http\Cookies`
class. This is useful when you need to log in to a remote site first and
receive an authentication or session ID cookie before sending further requests.
```php
$headers = $client->getRequest()->getHeaders();
$cookies = new Zend\Http\Cookies($headers);
// First request: log in and start a session
$client->setUri('http://example.com/login.php');
$client->setParameterPost(['user' => 'h4x0r', 'password' => 'l33t']);
$client->setMethod('POST');
$response = $client->getResponse();
$cookies->addCookiesFromResponse($response, $client->getUri());
// Now we can send our next request
$client->setUri('http://example.com/read_member_news.php');
$client->setCookies($cookies->getMatchingCookies($client->getUri()));
$client->setMethod('GET');
```
See the chapter on [cookies](cookies.md) for more detail.
## Setting custom request headers
Setting custom headers is performed by first fetching the header container from
the client's `Zend\Http\Request` instance. This `Headers` container offers a
number of methods for setting headers:
```php
use Zend\Http\Header;
// Fetch the container
$headers = $client->getRequest()->getHeaders();
// Setting a single header using a name and value. Will not overwrite any //
previously-added headers of the same name.
$headers->addHeaderLine('Host', 'www.example.com');
// You can also use a full header line:
$headers->addHeaderLine('Host: www.example.com');
// Sometimes you may want to use a HeaderInterface instance:
$headers->addHeader(Header\Host::fromString('Host: www.example.com'));
// You can also add multiple headers at once by passing an
// array to addHeaders() using any of the formats below:
$headers->addHeaders([
// Zend\Http\Header\* instance:
Header\Host::fromString('Host: www.example.com'),
// Header name/value pair:
'Cookie' => 'PHPSESSID=1234567890abcdef1234567890abcdef',
// Raw header string:
'Cookie: language=he',
]);
```
`Zend\Http\Client` also provides a convenience method for setting request
headers, `setHeaders()`. This method will create a new header container, add
the specified headers, and then store the new header container in its
`Zend\Http\Request` instance. As a consequence, any pre-existing headers will
be erased:
```php
use Zend\Http\Header;
// Setting multiple headers via the client; removes all existing headers,
// replacing the request header container with the following:
$client->setHeaders([
Zend\Http\Header\Host::fromString('Host: www.example.com'),
['Accept-Encoding' => 'gzip,deflate'],
'X-Powered-By: Zend Framework',
]);
```
## File uploads
You can upload files through HTTP using the `setFileUpload()` method. This
method takes a file name as the first parameter, a form name as the second
parameter, and data as a third optional parameter. If the third data parameter
is `NULL`, the first file name parameter is considered to be a real file on
disk, and `Zend\Http\Client` will try to read this file and upload it. If the
data parameter is not `NULL`, the first file name parameter will be sent as the
file name, but no actual file needs to exist on the disk. The second form name
parameter is always required, and is equivalent to the "name" attribute of an
`<input>` tag, if the file was to be uploaded through an HTML form. A fourth
optional parameter provides the file's `Content-Type`. If not specified, and
`Zend\Http\Client` reads the file from the disk, the `mime_content_type()`
function will be used to guess the file's content type, if it is available. In
any case, the default MIME type will be `application/octet-stream`.
```php
// Uploading arbitrary data as a file:
$text = 'this is some plain text';
$client->setFileUpload('some_text.txt', 'upload', $text, 'text/plain');
// Uploading an existing file:
$client->setFileUpload('/tmp/Backup.tar.gz', 'bufile');
// Send the files:
$client->setMethod('POST');
$client->send();
```
In the first example, the `$text` variable is uploaded and will be available as
`$_FILES['upload']` on the server side. In the second example, the existing
file `/tmp/Backup.tar.gz` is uploaded to the server and will be available as
`$_FILES['bufile']`. The content type will be guessed automatically if
possible, defaulting to `application/octet-stream`.
> ### Uploading files
>
> When uploading files, the HTTP request `Content-Type` is automatically set to
> `multipart/form-data`. Keep in mind that you must send a POST or PUT request
> in order to upload files; most servers will ignore the request body on other
> request methods.
## Sending raw POST data
You can send raw POST data via `Zend\Http\Client` using the `setRawBody()`
method. This method takes one parameter: the data to send in the request body.
When sending raw POST data, it is advisable to also set the encoding type using
`setEncType()`.
```php
$xml = '<book>'
. ' <title>Islands in the Stream</title>'
. ' <author>Ernest Hemingway</author>'
. ' <year>1970</year>'
. '</book>';
$client->setMethod('POST');
$client->setRawBody($xml);
$client->setEncType('text/xml');
$client->send();
```
The data should be available on the server side through PHP's `php://input`
stream.
> ### Raw POST data overrides other content
>
> Setting raw POST data for a request will override any POST parameters or file
> uploads; you should not try to use both on the same request. Keep in mind
> that most servers will ignore the request body unless you send a POST
> request.
## HTTP authentication
Currently, `Zend\Http\Client` only supports basic HTTP authentication. This feature is utilized
using the `setAuth()` method, or by specifying a username and a password in the URI. The `setAuth()`
method takes 3 parameters: the user name, the password and an optional authentication type
parameter.
```php
use Zend\Http\Client;
// Using basic authentication
$client->setAuth('shahar', 'myPassword!', Client::AUTH_BASIC);
// Since basic auth is default, you can just do this:
$client->setAuth('shahar', 'myPassword!');
// You can also specify username and password in the URI
$client->setUri('http://christer:secret@example.com');
```
## Sending multiple requests with the same client
`Zend\Http\Client` was also designed specifically to handle several consecutive
requests with the same object. This is useful in cases where a script requires
data to be fetched from several places, or when accessing a specific HTTP
resource requires logging in and obtaining a session cookie, for example.
When performing several requests to the same host, it is highly recommended to
enable the 'keepalive' configuration flag. This way, if the server supports
keep-alive connections, the connection to the server will only be closed once
all requests are done and the `Client` object is destroyed. This prevents the
overhead of opening and closing TCP connections to the server.
When you perform several requests with the same client, but want to make sure
all the request-specific parameters are cleared, you should use the
`resetParameters()` method. This ensures that GET and POST parameters, request
body, and request headers are reset and are not reused in the next request.
> ### Resetting parameters
>
> Note that cookies are not reset by default when the `resetParameters()`
> method is used. To clean all cookies as well, use `resetParameters(true)`, or
> call `clearCookies()` after calling `resetParameters()`.
Another feature designed specifically for consecutive requests is the
`Zend\Http\Cookies` object. This "Cookie Jar" allow you to save cookies set by
the server in a request, and send them back on consecutive requests
transparently. This allows, for example, going through an authentication
request before sending the actual data-fetching request.
If your application requires one authentication request per user, and
consecutive requests might be performed in more than one script in your
application, it might be a good idea to store the `Cookies` object in the user's
session. This way, you will only need to authenticate the user once every
session.
### Performing consecutive requests with one client
```php
use Zend\Http\Client;
use Zend\Http\Cookies;
// First, instantiate the client
$client = new Client(
'http://www.example.com/fetchdata.php',
['keepalive' => true]
);
// Do we have the cookies stored in our session?
if (isset($_SESSION['cookiejar'])
&& $_SESSION['cookiejar'] instanceof Cookies
) {
$cookieJar = $_SESSION['cookiejar'];
} else {
// If we don't, authenticate and store cookies
$client->setUri('http://www.example.com/login.php');
$client->setParameterPost([
'user' => 'shahar',
'pass' => 'somesecret',
]);
$response = $client->setMethod('POST')->send();
$cookieJar = Cookies::fromResponse($response);
// Now, clear parameters and set the URI to the original one
// (note that the cookies that were set by the server are now
// stored in the jar)
$client->resetParameters();
$client->setUri('http://www.example.com/fetchdata.php');
}
// Add the cookies to the new request
$client->setCookies($cookieJar->getMatchingCookies($client->getUri()));
$response = $client->setMethod('GET')->send();
// Store cookies in session, for next page
$_SESSION['cookiejar'] = $cookieJar;
```
## Data streaming
By default, `Zend\Http\Client` accepts and returns data as PHP strings.
However, in many cases there are big files to be received, thus keeping them in
memory might be unnecessary or too expensive. For these cases,
`Zend\Http\Client` supports writing data to files (streams).
In order to receive data from the server as stream, use `setStream()`. The
single, optional argument specifies the filename where the data will be stored.
If the argument is just `TRUE` (default), a temporary file will be used and
will be deleted once the response object is destroyed. Setting the argument to
`FALSE` disables the streaming functionality.
When using streaming, the `send()` method will return an object of class
`Zend\Http\Response\Stream`, which has two useful methods: `getStreamName()`
will return the name of the file where the response is stored, and
`getStream()` will return stream from which the response could be read.
You can either write the response to pre-defined file, or use temporary file
for storing it and send it out or write it to another file using regular stream
functions.
```php
$client-setStream(); // will use temp file
$response = $client-send();
// copy file:
copy($response-getStreamName(), 'my/downloads/file');
// use stream:
$fp = fopen('my/downloads/file2', 'w');
stream_copy_to_stream($response-getStream(), $fp);
// write to an existing file:
$client-setStream('my/downloads/myfile')-send();
```

View File

@@ -0,0 +1,128 @@
# Client Cookies
`Zend\Http\Cookies` can be used with `Zend\Http\Client` to manage sending
cookies in the request and setting cookies from the response; it is populated
from the `Set-Cookie` headers obtained from a client response, and then used to
populate the `Cookie` headers for a client request. This is highly useful in
cases where you need to maintain a user session over consecutive HTTP requests,
automatically sending the session ID cookies when required. Additionally, the
`Zend\Http\Cookies` object can be serialized and stored in `$_SESSION` when
needed.
`Zend\Http\Client` already provides methods for managing cookies for requests;
`Zend\Http\Cookies` manages the parsing of `Set-Cookie` headers returned in the
response, and allows persisting them. Additionally, `Cookies` can return a
subset of cookies that match the current request, ensuring you are only sending
relevant cookies.
## Usage
`Cookies` is an extension of `Zend\Http\Headers`, and inherits its methods. It
can be instantiated without any arguments.
```php
use Zend\Http\Cookies;
$cookies = new Cookies();
```
On your first client request, you likely won't have any cookies, so the
instance does nothing.
Once you've made your first request, you can start using it. Populate it from
the response:
```php
$response = $client->send();
$cookies->addCookiesFromResponse($response, $client->getUri());
```
Alternately, you can create your initial `Cookies` instance using the static `fromResponse()` method:
```php
$cookies = Cookies::fromResponse($response, $client->getUri());
```
On subsequent requests, we'll notify the client of our cookies. To do this, we
should use the same URI we'll use for the request.
```php
$client->setUri($uri);
$client->setCookies($cookies->getMatchingCookies($uri));
```
After the request, don't forget to add any cookies returned!
Essentially, `Cookies` aggregates all cookies for our client interactions, and
allows us to send only those relevant to a given request.
## Serializing and caching cookies
To cache cookies &mdash; e.g., to store in `$_SESSION`, or between job
invocations &mdash; you will need to serialize them. `Zend\Http\Cookies`
provides this functionality via the `getAllCookies()` method.
If your cache storage allows array structures, use the `COOKIE_STRING_ARRAY` constant:
```php
$cookiesToCache = $cookies->getAllCookies($cookies::COOKIE_STRING_ARRAY);
```
If your cache storage only allows string values, use `COOKIE_STRING_CONCAT`:
```php
$cookiesToCache = $cookies->getAllCookies($cookies::COOKIE_STRING_CONCAT);
```
When you retrieve the value later, you can test its type to determine how to
deserialize the values:
```php
use Zend\Http\Cookies;
use Zend\Http\Headers;
$cookies = new Cookies();
if (is_array($cachedCookies)) {
foreach ($cachedCookies as $cookie) {
$cookies->addCookie($cookie);
}
} elseif (is_string($cachedCookies)) {
foreach (Headers::fromString($cachedCookies) as $cookie) {
$cookies->addCookie($cookie);
}
}
```
## Public methods
Besides the methods demonstrated in the examples, `Zend\Http\Cookies` defines the following:
Method signature | Description
------------------------------------------------------------------- | -----------
`static fromResponse(Response $response, string $refUri) : Cookies` | Create a `Cookies` instance from a response and the request URI. Parses all `Set-Cookie` headers, maps them to the URI, and aggregates them.
`addCookie(string|SetCookie $cookie, string $refUri = null) : void` | Add a cookie, mapping it to the given URI. If no URI is provided, it will be inferred from the cookie value's domain and path.
`addCookiesFromResponse(Response $response, string $refUri) : void` | Add all `Set-Cookie` values from the provided response, mapping to the given URI.
`getAllCookies(int $retAs = self::COOKIE_OBJECT) : array|string` | Retrieve all cookies. Returned array will have either `SetCookie` instances (the default), strings for each `Set-Cookie` declaration, or a single string containing all declarations, based on the `COOKIE_*` constant used.
`getCookie(/* ... */) : string|SetCookie` | Retrieve a single cookie by name for the given URI. See below for argument details.
`getMatchingCookies(/* ... */) : array` | See below for details.
`isEmpty() : bool` | Whether or not the instance aggregates any cookies currently.
`reset() : void` | Clear all aggregated cookies from the instance.
`getCookie()` accepts the following arguments, in the following order:
Argument | Description
---------------------------------- | -----------
`string $uri` | URI to match when retrieving the cookie. Will use its protocol, domain, and path.
`string $cookieName` | The specific cookie name to retrieve.
`int $retAs = self::COOKIE_OBJECT` | How to return matched cookies; defaults to `SetCookie` objects. Can be any of the `Cookies::COOKIE_*` constant values.
`getMatchingCookies()` accepts the following arguments, in the following order:
Argument | Description
---------------------------------- | -----------
`string $uri` | URI to match when retrieving cookies. Will use its protocol, domain, and path.
`bool $matchSessionCookies = true` | Whether or not to also return related session cookies.
`int $retAs = self::COOKIE_OBJECT` | How to return matched cookies; defaults to `SetCookie` objects. Can be any of the `Cookies::COOKIE_*` constant values.
`int $now = null` | Timestamp against which to match; defaults to `time()`. Any expired cookies will be ignored.

View File

@@ -0,0 +1,258 @@
# HTTP Client
`Zend\Http\Client` provides an interface for performing Hyper-Text Transfer
Protocol (HTTP) requests. `Zend\Http\Client` supports all basic features
expected from an HTTP client, as well as some more complex features such as HTTP
authentication and file uploads. Successful requests (and most unsuccessful ones
too) return a `Zend\Http\Response` object, which provides access to the
response's headers and body (see the chapter on [Responses](../response.md) for
more details).
## Quick Start
The class constructor optionally accepts a URL as its first parameter (which can
be either a string or a `Zend\Uri\Http` object), and an array or `Traversable`
object containing configuration options. The `send()` method is used to submit
the request to the remote server, and a `Zend\Http\Response` object is returned:
```php
use Zend\Http\Client;
$client = new Client(
'http://example.org',
[
'maxredirects' => 0,
'timeout' => 30,
]
);
$response = $client->send();
```
Both constructor parameters can be left out, and set later using the `setUri()`
and `setOptions()` methods:
```php
use Zend\Http\Client;
$client = new Client();
$client->setUri('http://example.org');
$client->setOptions([
'maxredirects' => 0,
'timeout' => 30,
]);
$response = $client->send();
```
`Zend\Http\Client` can also dispatch requests using a separately configured
`request` object (see the [Request](../request.md) manual for full details of
the methods available):
```php
use Zend\Http\Client;
use Zend\Http\Request;
$request = new Request();
$request->setUri('http://example.org');
$client = new Client();
$response = $client->send($request);
```
> ### URL validation
>
> `Zend\Http\Client` uses `Zend\Uri\Http` to validate URLs. See the
> [zend-uri](http://framework.zend.com/manual/current/en/index.html#zend-uri)
> documentation for more information.
## Configuration
The constructor and `setOptions()` method accept an associative array or
`Traversable` instance containing configuration parameters. Setting these
parameters is optional, as they all have default values.
Parameter | Description | Expected Values | Default Value
------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------|--------------
`maxredirects` | Maximum number of redirections to follow (0 = none) | integer | 5
`strictredirects` | Whether to strictly follow the RFC when redirecting (see this section) | boolean | FALSE
`useragent` | User agent identifier string (sent in request headers) | string | `Zend\Http\Client`
`timeout` | Connection timeout (seconds) | integer | 10
`httpversion` | HTTP protocol version (usually '1.1' or '1.0') | string | 1.1
`adapter` | Connection adapter class to use (see this section) | mixed | `Zend\Http\Client\Adapter\Socket`
`keepalive` | Whether to enable keep-alive connections with the server. Useful and might improve performance if several consecutive requests to the same server are performed. | boolean | FALSE
`storeresponse` | Whether to store last response for later retrieval with getLastResponse(). If set to FALSE, getLastResponse() will return NULL. | boolean | TRUE
`encodecookies` | Whether to pass the cookie value through urlencode/urldecode. Enabling this breaks support with some web servers. Disabling this limits the range of values the cookies can contain. | boolean | TRUE
`outputstream` | Destination for streaming of received data (options: string (filename), true for temp file, false/null to disable streaming) | boolean | FALSE
`rfc3986strict` | Whether to strictly adhere to RFC 3986 (in practice, this means replacing '+' with '%20') | boolean | FALSE
The options are also passed to the adapter class upon instantiation, so the same
configuration can be used for adapter configuration. See the
[adapters](adapters.md) section for more information on the adapter-specific
options available.
## Examples
### Performing a GET request
GET is the default method used, and requires no special configuration.
```php
use Zend\Http\Client;
$client = new Client('http://example.org');
$response = $client->send();
```
### Using request methods other than GET
The request method can be set using `setMethod()`. If no method is specified,
the method set by the last `setMethod()` call is used. If `setMethod()` was
never called, the default request method is `GET`.
```php
use Zend\Http\Client;
$client = new Client('http://example.org');
// Performing a POST request
$client->setMethod('POST');
$response = $client->send();
```
For convenience, `Zend\Http\Request` defines all request methods as class
constants: `Zend\Http\Request::METHOD_GET`, `Zend\Http\Request::METHOD_POST` and
so on.
```php
use Zend\Http\Client;
use Zend\Http\Request;
$client = new Client('http://example.org');
// Performing a POST request
$client->setMethod(Request::METHOD_POST);
$response = $client->send();
```
### Setting query parameters
Adding query parameters to an HTTP request can be done either by specifying them
as part of the URL, or by using the `setParameterGet()` method. This method
takes the query parameters as an associative array of name/value pairs.
```php
use Zend\Http\Client;
$client = new Client();
// This is equivalent to setting a URL in the Client's constructor:
$client->setUri('http://example.com/index.php?knight=lancelot');
// Adding several parameters with one call
$client->setParameterGet([
'first_name' => 'Bender',
'middle_name' => 'Bending',
'last_name' => 'Rodríguez',
'made_in' => 'Mexico',
]);
```
### Setting form-encoded body parameters
While query parameters can be sent with every request method, other methods can
accept parameters via the request body. In many cases, these are
`application/x-www-form-urlencoded` parameters; zend-http allows you to specify
such parameters usingthe `setParameterPost()` method, which is identical to the
`setParameterGet()` method in structure.
```php
use Zend\Http\Client;
$client = new Client();
// Setting several POST parameters, one of them with several values
$client->setParameterPost([
'language' => 'es',
'country' => 'ar',
'selection' => [45, 32, 80],
]);
```
Note that when sending `POST` requests (or an request allowing a request body),
you can set both query and `POST` parameters. On the other hand, setting POST
parameters on a `GET` request will not trigger an error, rendering it useless.
### Connecting to SSL URLs
If you are trying to connect to an SSL or TLS (https) URL and are using the
default (`Zend\Http\Client\Adapter\Socket`) adapter, you may need to set the
`sslcapath` configuration option in order to allow PHP to validate the SSL
certificate:
```php
use Zend\Http\Client;
$client = new Client(
'https://example.org',
[
'sslcapath' => '/etc/ssl/certs',
]
);
$response = $client->send();
```
The exact path to use will vary depending on your operating system. Without this
you'll get the exception "Unable to enable crypto on TCP connection" when trying
to connect.
Alternatively, you could switch to the curl adapter, which negotiates SSL
connections more transparently:
```php
use Zend\Http\Client;
$client = new Client(
'https://example.org',
[
'adapter' => 'Zend\Http\Client\Adapter\Curl',
]
);
$response = $client->send();
```
## Complete Example
```php
use Zend\Http\Client;
$client = new Client();
$client->setUri('http://www.example.com');
$client->setMethod('POST');
$client->setParameterPost([
'foo' => 'bar',
]);
$response = $client->send();
if ($response->isSuccess()) {
// the POST was successful
}
```
or the same thing, using a request object:
```php
use Zend\Http\Client;
use Zend\Http\Request;
$request = new Request();
$request->setUri('http://www.example.com');
$request->setMethod('POST');
$request->getPost()->set('foo', 'bar');
$client = new Client();
$response = $client->send($request);
if ($response->isSuccess()) {
// the POST was successful
}
```

View File

@@ -0,0 +1,66 @@
# HTTP Client - Static Usage
zend-http provides another client implementation, `Zend\Http\ClientStatic`, a
static HTTP client which exposes a simplified API for quickly performing one-off `GET`
and `POST` operations.
## Quick Start
```php
use Zend\Http\ClientStatic;
// Simple GET request
$response = ClientStatic::get('http://example.org');
// More complex GET request, specifying query string 'foo=bar' and adding a
// custom header to request JSON data be returned (Accept: application/json):
$response = ClientStatic::get(
'http://example.org',
['foo' => 'bar'],
['Accept' => 'application/json']
);
// We can also do a POST request using the same format. Here we POST
// login credentials (username/password) to a login page:
$response = ClientStatic::post(
'https://example.org/login.php',
[
'username' => 'foo',
'password' => 'bar',
]
);
```
## Available Methods
### get()
```php
get(
string $url,
array $query = [],
array $headers = [],
mixed $body = null,
$clientOptions = null
) : Response
```
Perform an HTTP `GET` request using the provided URL, query string variables,
headers, and request body. The fifth parameter can be used to pass configuration
options to the HTTP client instance.
### post()
```php
post(
string $url,
array $params,
array $headers = [],
mixed $body = null,
$clientOptions = null
) : Response
```
Perform an HTTP `POST` request using the provided URL, parameters, headers, and
request body. The fifth parameter can be used to pass configuration options to
the HTTP client instance.

View File

@@ -0,0 +1,594 @@
# Headers
`Zend\Http\Headers` is a container for HTTP headers. It is typically accessed as
part of a `Zend\Http\Request` or `Zend\Http\Response` instance, via a
`getHeaders()` call. The `Headers` container will lazily load actual
`Zend\Http\Header\HeaderInterface` instances as to reduce the overhead of header
specific parsing.
The class under the `Zend\Http\Header` namespace are the domain specific
implementations for the various types of headers that one might encounter during
the typical HTTP request. If a header of unknown type is encountered, it will be
implemented as a `Zend\Http\Header\GenericHeader` instance. See the below table
for a list of the various HTTP headers and the API that is specific to each
header type.
## Quick Start
The quickest way to get started interacting with header objects is by retrieving
an already populated `Headers` container from a request or response instance.
```php
// $client is an instance of Zend\Http\Client
// You can retrieve the request headers by first retrieving
// the Request object and then calling getHeaders on it
$requestHeaders = $client->getRequest()->getHeaders();
// The same method also works for retrieving Response headers
$responseHeaders = $client->getResponse()->getHeaders();
```
`Zend\Http\Headers` can also extract headers from a string:
```php
use Zend\Http\Headers;
$headerString = <<<EOB
Host: www.example.com
Content-Type: text/html
Content-Length: 1337
EOB;
$headers = Headers::fromString($headerString);
// $headers is now populated with three objects
// (1) Zend\Http\Header\Host
// (2) Zend\Http\Header\ContentType
// (3) Zend\Http\Header\ContentLength
```
Now that you have an instance of `Zend\Http\Headers`, you can manipulate the
individual headers it contains using the provided public API methods outlined in
the [Available Methods](#available-methods) section.
## Configuration Options
No configuration options are available.
## Available Methods
The following is a list of methods available to `Zend\Http\Headers`. For
brevity, we map the following references to the following classes or namespaces:
- `HeaderInterface`: `Zend\Http\Header\HeaderInterface`
- `Headers`: `Zend\Http\Headers`
- `PluginClassLocator`: `Zend\Loader\PluginClassLocator`
Method signature | Description
------------------------------------------------------------------------- | -----------
`static fromString(string $string) : Headers` | Parses a string for headers, and aggregates them, in order, a new `Headers` instance, primarily as strings until they are needed (they will be lazy loaded).
`setPluginClassLoader(PluginClassLocator $pluginClassLoader) : self` | Set an alternate implementation for the plugin class loader.
`getPluginClassLoader() : PluginClassLocator` | Return an instance of a `PluginClassLocator`; lazy-load and inject map if necessary.
`addHeaders(array|Traversable $headers) : self` | Add many headers at once; expects an array (or `Traversable` object) of type/value pairs.
`addHeaderLine(string $headerFieldNameOrLine, string $fieldValue) : self` | Add a raw header line, either as separate name and value arguments, or as a single string in the form `name: value` This method allows for lazy-loading in that the parsing and instantiation of a `HeaderInterface` implementation will be delayed until they are retrieved by either `get()` or `current()`.
`addHeader(HeaderInterface $header) : self` | Add a header instance to the container; for raw values see `addHeaderLine()` and `addHeaders()`.
`removeHeader(HeaderInterface $header) : bool` | Remove a Header from the container.
`clearHeaders() : self` | Removes all headers from the container.
`get(string $name) : false|HeaderInterface|ArrayIterator` | Get all values for a given header. If none are found, `false` is returned. If the header is a single-value header, a `HeaderInterface` is returned. If the header is a multi-value header, an `ArrayIterator` containing all values is returned.
`has(string $name) : bool` | Test for existence of a header.
`next() : void` | Advance the pointer for this object as an iterator.
`key() : mixed` | Return the current key for this object as an iterator.
`valid() : bool` | Is this iterator still valid?
`rewind() : void` | Reset the internal pointer for this object as an iterator.
`current() : HeaderInterface` | Return the current value for this iterator, lazy loading it if need be.
`count() : int` | Return the number of headers in this container. If all headers have not been parsed, the actual count could decrease if `MultipleHeader` instances exist. If you need an exact count, iterate.
`toString() : string` | Render all headers at once. This method handles the normal iteration of headers; it is up to the concrete classes to prepend with the appropriate status/request line.
`toArray() : array` | Return all headers as an associative array.
`forceLoading() : bool` | By calling this, it will force parsing and loading of all headers, ensuring `count()` is accurate.
## HeaderInterface Methods
The following are methods available to all `HeaderInterface` implementations.
Method signature | Description
--------------------------------------------------------- | -----------
`static fromString(string $headerLine) : HeaderInterface` | Factory to generate a header object from a string.
`getFieldName() : string` | Retrieve header field name.
`getFieldValue() : string` | Retrieve header field value.
`toString() : string` | Cast the header to a well-formed HTTP header line (`Name: Value`).
## AbstractAccept Methods
`Zend\Http\Header\AbstractAccept` defines the following methods in addition to
those it inherits from the [HeaderInterface](#headerinterface-methods). The
`Accept`, `AcceptCharset`, `AcceptEncoding`, and `AcceptLanguage` header types
inherit from it.
For brevity, we map the following references to the following classes or
namespaces:
- `AcceptFieldValuePart`: `Zend\Http\Header\Accept\FieldValuePart\AcceptFieldValuePart`
- `InvalidArgumentException`: `Zend\Http\Header\Exception\InvalidArgumentException`
Method signature | Description
--------------------------------------------------------------- | -----------
`parseHeaderLine(string $headerLine) : void` | Parse the given header line and add the values discovered to the instance.
`getFieldValuePartsFromHeaderLine(string $headerLine) : array` | Parse the field value parts represented by an Accept* header line. Throws `InvalidArgumentException` if the header is invalid.
`getFieldValue(array|null $values = null) : string` | Get field value.
`match(array|string $matchAgainst) : bool|AcceptFieldValuePart` | Match a media string against this header. Returns the matched value or false.
`getPrioritized() : array` | Returns all the keys, values and parameters this header represents.
## AbstractDate Methods
`Zend\Http\Header\AbstractDate` defines the following methods in addition to
those it inherits from the [HeaderInterface](#headerinterface-methods). The
`Date`, `Expires`, `IfModifiedSince`, `IfUnmodifiedSince`, `LastModified`, and
`RetryAfter` header types inherit from it.
For brevity, we map the following references to the following classes or
namespaces:
- `InvalidArgumentException`: `Zend\Http\Header\Exception\InvalidArgumentException`
Method signature | Description
---------------------------------------------------- | -----------
`static fromTimestamp(int $time) : AbstractDate` | Create date-based header from Unix timestamp.
`static fromTimeString(string $time) : AbstractDate` | Create date-based header from `strtotime()`-compatible string.
`static setDateFormat(int $format) : void` | Set date output format; should be an index from the implementation's `$dateFormat` static property.
`static getDateFormat() : string` | Return current date output format.
`setDate(string|DateTime $date) : self` | Set the date for this header; this can be a string or an instance of `DateTime`. Throws `InvalidArgumentException` if the date is neither a valid string nor an instance of `DateTime`.
`getDate() : string` | Return string representation of the date for this header.
`compareTo(string|DateTime $date) : int` | Compare provided date to date for this header. Returns `< 0` if date in header is less than `$date`; `> 0` if it's greater, and `= 0` if they are equal. See [strcmp](http://www.php.net/manual/en/function.strcmp.php).
`date() | DateTime` | Return date for this header as an instance of `DateTime`.
## AbstractLocation Methods
`Zend\Http\Header\AbstractLocation` defines the following methods in addition to
those it inherits from the [HeaderInterface](#headerinterface-methods). The
`ContentLocation`, `Location`, and `Referer` header types inherit from it.
For brevity, we map the following references to the following classes or
namespaces:
- `Uri`: `Zend\Uri\UriInterface`
- `InvalidArgumentException`: `Zend\Http\Header\Exception\InvalidArgumentException`
Method signature | Description
-------------------------------- | -----------
`setUri(string|Uri $uri) : self` | Set the URI for this header; throws `InvalidArgumentException` for invalid `$uri` arguments.
`getUri() : string` | Return the URI for this header.
`uri() : Uri` | Return the `Uri` instance for this header.
## List of HTTP Header Types
Some header classes expose methods for manipulating their value. The following
list contains all of the classes available in the `Zend\Http\Header\*`
namespace, as well as any specific methods they contain. Each class implements
`Zend\Http\Header\HeaderInterface`.
### Accept
Extends [AbstractAccept](#abstractaccept-methods).
Method signature | Description
------------------------------------------------------------ | -----------
`addMediaType(string $type, int|float $priority = 1) : self` | Add a media type, with the given priority.
`hasMediaType(string $type): bool` | Does the header have the requested media type?
### AcceptCharset
Extends [AbstractAccept](#abstractaccept-methods).
Method signature | Description
---------------------------------------------------------- | -----------
`addCharset(string $type, int|float $priority = 1) : self` | Add a charset, with the given priority.
`hasCharset(string $type) : bool` | Does the header have the requested charset?
### AcceptEncoding
Extends [AbstractAccept](#abstractaccept-methods).
Method signature | Description
----------------------------------------------------------- | -----------
`addEncoding(string $type, int|float $priority = 1) : self` | Add an encoding, with the given priority.
`hasEncoding(string $type) : bool` | Does the header have the requested encoding?
### AcceptLanguage
Extends [AbstractAccept](#abstractaccept-methods).
Method signature | Description
---------------------------------------------------------- | -----------
`addLanguage(string $type, int|float $priority = 1): self` | Add a language, with the given priority.
`hasLanguage(string $type) : bool` | Does the header have the requested language?
### AcceptRanges
Method signature | Description
--------------------------------------- | -----------
`getRangeUnit() : mixed` | (unknown)
`setRangeUnit(mixed $rangeUnit) : self` | (unkown)
### Age
Method signature | Description
-------------------------------------- | -----------
`getDeltaSeconds() : int` | Get number of seconds.
`setDeltaSeconds(int $seconds) : self` | Set number of seconds
### Allow
Method signature | Description
---------------------------------------------------- | -----------
`getAllMethods() : string[]` | Get list of all defined methods.
`getAllowedMethods() : string[]` | Get list of allowed methods.
`allowMethods(array|string $allowedMethods) : self` | Allow methods or list of methods.
`disallowMethods(array|string $allowedMethods) self` | Disallow methods or list of methods.
`denyMethods(array|string $allowedMethods) : self` | Convenience alias for `disallowMethods()`.
`isAllowedMethod(string $method) : bool` | Check whether method is allowed.
### AuthenticationInfo
No additional methods.
### Authorization
No additional methods.
### CacheControl
Method signature | Description
------------------------------------------------------------- | -----------
`isEmpty(): bool` | Checks if the internal directives array is empty.
`addDirective(string $key, string|bool $value = true) : self` | Add a directive. For directives like `max-age=60`, call as `addDirective('max-age', 60)`. For directives like `private`, use the default `$value` (`true`).
`hasDirective(string $key) : bool` | Check the internal directives array for a directive.
`getDirective(string $key) : null|string` | Fetch the value of a directive from the internal directive array.
`removeDirective(string $key) : self` | Remove a directive.
### Connection
Method signature | Description
---------------------------------- | -----------
`setValue($value) : self` | Set arbitrary header value. RFC allows any token as value; 'close' and 'keep-alive' are commonly used.
`isPersistent() : bool` | Whether or not the connection is persistent.
`setPersistent(bool $flag) : self` | Set Connection header to define persistent connection.
### ContentDisposition
No additional methods.
### ContentEncoding
No additional methods.
### ContentLanguage
No additional methods.
### ContentLength
No additional methods.
### ContentLocation
See [AbstractLocation](#abstractlocation-methods).
### ContentMD5
No additional methods.
### ContentRange
No additional methods.
### ContentSecurityPolicy
Method signature | Description
--------------------------------------------------- | -----------
`getDirectives(): array` | Retrieve the defined directives for the policy.
`setDirective(string $name, array $sources) : self` | Set the directive with the given name to include the sources. See below for an example.
As an example: an auction site wishes to load images from any URI, plugin
content from a list of trusted media providers (including a content distribution
network), and scripts only from a server under its control hosting sanitized
Javacript:
```php
// http://www.w3.org/TR/2012/CR-CSP-20121115/#sample-policy-definitions
$csp = new ContentSecurityPolicy();
$csp->setDirective('default-src', []); // No sources
$csp->setDirective('img-src', ['*']);
$csp->setDirective('object-src', ['media1.example.com', 'media2.example.com', '*.cdn.example.com']);
$csp->setDirective('script-src', ['trustedscripts.example.com']);
```
### ContentTransferEncoding
No additional methods.
### ContentType
Method signature | Description
------------------------------------------------- | -----------
`match(array|string $matchAgainst) : bool|string` | Determine if the mediatype value in this header matches the provided criteria.
`getMediaType() : string` | Get the media type.
`setMediaType(string $mediaType) : self` | Set the media type.
`getParameters() : array` | Get any additional content-type parameters currently set.
`setParameters(array $parameters) : self` | Set additional content-type parameters.
`getCharset() : null|string` | Get the content-type character set encoding, if any.
`setCharset(string $charset) : self` | Set the content-type character set encoding.
### Cookie
Extends `ArrayObject`.
Method signature | Description
------------------------------------------------------- | -----------
`static fromSetCookieArray(array $setCookies) : Cookie` | Create an instance from the `$_COOKIE` array, or one structured like it.
`setEncodeValue(bool $encode) : self` | Set flag indicating whether or not to `urlencode()` the cookie values.
`getEncodeValue() : bool` | Get flag indicating whether or not to `urlencode()` the cookie values.
### Date
See [AbstractDate](#abstractdate-methods).
### Etag
No additional methods.
### Expect
No additional methods.
### Expires
See [AbstractDate](#abstractdate-methods).
### From
No additional methods.
### Host
No additional methods.
### IfMatch
No additional methods.
### IfModifiedSince
See [AbstractDate](#abstractdate-methods).
### IfNoneMatch
No additional methods.
### IfRange
No additional methods.
### IfUnmodifiedSince
See [AbstractDate](#abstractdate-methods).
### KeepAlive
No additional methods.
### LastModified
See [AbstractDate](#abstractdate-methods).
### Location
See [AbstractLocation](#abstractlocation-methods).
### MaxForwards
No additional methods.
### Origin
No additional methods.
### Pragma
No additional methods.
### ProxyAuthenticate
Method signature | Description
-------------------------------------------------- | -----------
`toStringMultipleHeaders(array $headers) : string` | Creates a string representation when multiple values are present.
### ProxyAuthorization
No additional methods.
### Range
No additional methods.
### Referer
See [AbstractLocation](#abstractlocation-methods).
### Refresh
No additional methods.
### RetryAfter
See [AbstractDate](#abstractdate-methods).
Method signature | Description
------------------------------------ | -----------
`setDeltaSeconds(int $delta) : self` | Set number of seconds.
`getDeltaSeconds() : int` | Get number of seconds.
### Server
No additional methods.
### SetCookie
Method signature | Description
--------------------------------------------------------------------- | -----------
`static matchCookieDomain(string $cookieDomain, string $host) : bool` | Check if a cookie's domain matches a host name.
`static matchCookiePath(string $cookiePath, string $path) : bool` | Check if a cookie's path matches a URL path.
`getName() : string` | Retrieve the cookie name.
`setName(string $name) : self` | Set the cookie name.
`getValue() : string` | Retrieve the cookie value.
`setValue(string $value) : self` | Set the cookie value.
`getExpires() : int` | Retrieve the expiration date for the cookie.
`setExpires(int|string $expires) : self` | Set the cookie expiration timestamp; null indicates a session cookie.
`getPath() : string` | Retrieve the URI path the cookie is bound to.
`setPath(string $path) : self` | Set the URI path the cookie is bound to.
`getDomain() : string` | Retrieve the domain the cookie is bound to.
`setDomain(string $domain) : self` | Set the domain the cookie is bound to.
`getMaxAge() : int` | Retrieve the maximum age for the cookie.
`setMaxAge(int|string $maxAge) : self` | Set the maximum age for the cookie.
`getVersion() : int` | Retrieve the cookie version.
`setVersion(int|string $version) : self` | Set the cookie version.
`isSecure(): bool` | Whether the cookies contains the Secure flag.
`setSecure(bool $secure) : self` | Set whether the cookies contain the Secure flag.
`isHttponly() : bool` | Whether the cookies can be accessed via the HTTP protocol only.
`setHttponly(bool $httponly) : self` | Set whether the cookies can be accessed only via HTTP protocol.
`isExpired() : bool` | Whether the cookie is expired.
`isSessionCookie() : bool` | Whether the cookie is a session cookie.
`setQuoteFieldValue(bool $quotedValue) : self` | Set whether the value for this cookie should be quoted.
`hasQuoteFieldValue() : bool` | Check whether the value for this cookie should be quoted.
`isValidForRequest() : bool` | Whether the cookie is valid for a given request domain, path and isSecure.
`match(string $uri, bool $matchSessionCookies, int $now) : bool` | Checks whether the cookie should be sent or not in a specific scenario.
`toStringMultipleHeaders(array $headers) : string` | Returns string representation when multiple values are present.
### TE
No additional methods.
### Trailer
No additional methods.
### TransferEncoding
No additional methods.
### Upgrade
No additional methods.
### UserAgent
No additional methods.
### Vary
No additional methods.
### Via
No additional methods.
### Warning
No additional methods.
### WWWAuthenticate
Defines a `toStringMultipleHeaders(array $headers)` method for serializing to
string when multiple values are present.
## Examples
### Retrieving headers from a Headers object
```php
// $client is an instance of Zend\Http\Client
$response = $client->send();
$headers = $response->getHeaders();
// We can check if the Request contains a specific header by
// using the ``has`` method. Returns boolean ``TRUE`` if at least
// one matching header found, and ``FALSE`` otherwise
$headers->has('Content-Type');
// We can retrieve all instances of a specific header by using
// the ``get`` method:
$contentTypeHeaders = $headers->get('Content-Type');
```
There are three possibilities for the return value of the above call to the `get` method:
- If no `Content-Type` header was set in the `Request`, `get` will return `false`.
- If only one `Content-Type` header was set in the `Request`, `get` will return
an instance of `Zend\Http\Header\ContentType`.
- If more than one `Content-Type` header was set in the `Request`, `get` will
return an `ArrayIterator` containing one `Zend\Http\Header\ContentType`
instance per header.
### Adding headers to a Headers object
```php
use Zend\Http\Header;
use Zend\Http\Headers;
$headers = new Headers();
// We can directly add any object that implements Zend\Http\Header\HeaderInterface
$typeHeader = Header\ContentType::fromString('Content-Type: text/html');
$headers->addHeader($typeHeader);
// We can add headers using the raw string representation, either
// passing the header name and value as separate arguments...
$headers->addHeaderLine('Content-Type', 'text/html');
// .. or we can pass the entire header as the only argument
$headers->addHeaderLine('Content-Type: text/html');
// We can also add headers in bulk using addHeaders, which accepts
// an array of individual header definitions that can be in any of
// the accepted formats outlined below:
$headers->addHeaders([
// An object implementing Header\HeaderInterface
Header\ContentType::fromString('Content-Type: text/html'),
// A raw header string
'Content-Type: text/html',
// We can also pass the header name as the array key and the
// header content as that array key's value
'Content-Type' => 'text/html',
]);
```
### Removing headers from a Headers object
We can remove all headers of a specific type using the `removeHeader` method,
which accepts a single object implementing `Zend\Http\Header\HeaderInterface`
```php
use ArrayIterator;
use Zend\Http\Header\HeaderInterface;
// $headers is a pre-configured instance of Zend\Http\Headers
// We can also delete individual headers or groups of headers
$matches = $headers->get('Content-Type');
if ($matches instanceof ArrayIterator) {
// If more than one header was found, iterate over the collection
// and remove each one individually
foreach ($headers as $header) {
$headers->removeHeader($header);
}
} elseif ($matches instanceof HeaderInterface) {
// If only a single header was found, remove it directly
$headers->removeHeader($header);
}
// In addition to this, we can clear all the headers currently stored in
// the container by calling the clearHeaders() method
$matches->clearHeaders();
```

View File

@@ -0,0 +1,10 @@
<div class="container">
<div class="jumbotron">
<h1>zend-http</h1>
<p>HTTP message and header abstractions, and HTTP client implementation. (Not a PSR-7 implementation; see <a href="//zendframework.github.io/zend-diactoros">Diactoros</a> for PSR-7 support.</p>
<pre><code class="language-bash">$ composer require zendframework/zend-http</code></pre>
</div>
</div>

View File

@@ -0,0 +1 @@
../../README.md

View File

@@ -0,0 +1,35 @@
# Introduction
zend-http provides the HTTP message abstraction used by
[zend-mvc](https://zendframework.github.io/zend-mvc/), and also provides an
extensible, adapter-driven HTTP client library. It provides the following
abstractions:
- Context-less `Request` and `Response` classes that expose a fluent API for
introspecting several aspects of HTTP messages:
- Request line information and response status information
- Parameters, such as those found in POST and GET
- Message Body
- Headers
- A client implementation with various adapters that allow for sending requests
and introspecting responses.
> ### Not PSR-7!
>
> This library **does not** support [PSR-7](http://www.php-fig.org/psr/psr-7), as
> it predates that specification. For PSR-7 support, please see our
> [Diactoros component](https://zendframework.github.io/zend-diactoros/).
## Zend\Http Request, Response and Headers
The request, response and headers implementations of the zend-http component
provides a fluent, object-oriented interface for introspecting information from
all the various parts of an HTTP request or HTTP response. The primary classes
are `Zend\Http\Request` and `Zend\Http\Response`. Both are “context-less”,
meaning that they model a request or response in the same way whether it is
presented by a client (to **send** a request and **receive** a response) or by a
server (to **receive** a request and **send** a response). In other words,
regardless of the context, the API remains the same for introspecting their
various respective parts. Each attempts to fully model a request or response so
that a developer can create these objects from a factory, or create and populate
them manually.

View File

@@ -0,0 +1,177 @@
# The Request Class
`Zend\Http\Request` is responsible for providing a fluent API that allows a
developer to interact with all the various parts of an HTTP request.
A typical HTTP request looks like this:
```text
| METHOD | URI | VERSION |
| HEADERS |
| BODY |
```
In simplified terms, the request consists of a method, URI, and HTTP version
number; together, they make up the "Request Line." This line is followed by zero
or more HTTP headers, which is followed by an empty line and then the request
body; the body is typically used when a client wishes to send data &mdash; which
could be urlencoded parameters, a JSON document, an XML document, or even one or
more files &mdash; to the server. More information on the structure and
specification of a HTTP request can be found in
[RFC-2616 on the W3.org site](http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html).
## Quick Start
Request objects can either be created from the provided `fromString()` factory,
or, if you wish to have a completely empty object to start with, by
manually instantiating the `Zend\Http\Request` class with no parameters.
```php
use Zend\Http\Request;
$request = Request::fromString(<<<EOS
POST /foo HTTP/1.1
HeaderField1: header-field-value1
HeaderField2: header-field-value2
foo=bar
EOS
);
// OR, the completely equivalent
$request = new Request();
$request->setMethod(Request::METHOD_POST);
$request->setUri('/foo');
$request->getHeaders()->addHeaders([
'HeaderField1' => 'header-field-value1',
'HeaderField2' => 'header-field-value2',
]);
$request->getPost()->set('foo', 'bar');
```
## Configuration Options
No configuration options are available.
## Available Methods
The following table details available methods, their signatures, and a brief
description. Note that the following references refer to the following
fully qualified class names and/or namespaces:
- `HeaderInterface`: `Zend\Http\Header\HeaderInterface`
- `Headers`: `Zend\Http\Headers`
- `Header`: `Zend\Http\Header`
- `Parameters`: `Zend\Stdlib\ParametersInterface`
- `Request`: `Zend\Http\Request`
- `Uri`: `Zend\Uri\Http`
Method signature | Description
--------------------------------------------------------------------------- | -----------
`static fromString(string $string) : Request` | A factory that produces a `Request` object from a well-formed HTTP request message string.
`setMethod(string $method) : self` | Set the method for this request.
`getMethod() : string` | Return the method for this request.
`setUri(string|Uri $uri) : self` | Set the URI/URL for this request; this can be a string or an instance of `Zend\Uri\Http`.
`getUri() : Uri` | Return the URI for this request object.
`getUriString() : string` | Return the URI for this request object as a string.
`setVersion(string $version) : self` | Set the HTTP version for this object, one of 1.0 or 1.1 (`Request::VERSION_10`, `Request::VERSION_11`).
`getVersion() : string` | Return the HTTP version for this request.
`setQuery(Parameters $query) : self` | Provide an alternate Parameter Container implementation for query parameters in this object. (This is NOT the primary API for value setting; for that, see `getQuery()`).
`getQuery(string|null $name, mixed|null $default) : null|string|Parameters` | Return the parameter container responsible for query parameters or a single query parameter based on `$name`.
`setPost(Parameters $post) : self` | Provide an alternate Parameter Container implementation for POST parameters in this object. (This is NOT the primary API for value setting; for that, see `getPost()`).
`getPost(string|null $name, mixed|null $default) : null|string|Parameters` | Return the parameter container responsible for POST parameters or a single POST parameter, based on `$name`.
`getCookie() : Header\Cookie` | Return the Cookie header, this is the same as calling `$request->getHeaders()->get('Cookie');`.
`setFiles(Parameters $files) : self` | Provide an alternate Parameter Container implementation for file parameters in this object, (This is NOT the primary API for value setting; for that, see `getFiles()`).
`getFiles(string|null $name, mixed|null $default) : null|string|Parameters` | Return the parameter container responsible for file parameters or a single file parameter, based on `$name`.
`setHeaders(Headers $headers) : self` | Provide an alternate Parameter Container implementation for headers in this object, (this is NOT the primary API for value setting, for that see `getHeaders()`).
`getHeaders(string|null $name, mixed|null $default) : mixed` | Return the container responsible for storing HTTP headers. This container exposes the primary API for manipulating headers set in the HTTP request. See the section on [Headers](headers.md) for more information. Return value is based on `$name`; `null` returns `Headers`, while a matched header returns a `Header\HeaderInterface` implementation for single-value headers or an `ArrayIterator` for multi-value headers.
`setMetadata(string|int|array|Traversable $spec, mixed $value) : self` | Set message metadata. Non-destructive setting of message metadata; always adds to the metadata, never overwrites the entire metadata container.
`getMetadata(null|string|int $key, null|mixed $default) : mixed` | Retrieve all metadata or a single metadatum as specified by key.
`setContent(mixed $value) : self` | Set request body (content).
`getContent() : mixed` | Get request body (content).
`isOptions() : bool` | Is this an OPTIONS method request?
`isGet() : bool` | Is this a GET method request?
`isHead() : bool` | Is this a HEAD method request?
`isPost() : bool` | Is this a POST method request?
`isPut() : bool` | Is this a PUT method request?
`isDelete() : bool` | Is this a DELETE method request?
`isTrace() : bool` | Is this a TRACE method request?
`isConnect() : bool` | Is this a CONNECT method request?
`isPatch() : bool` | Is this a PATCH method request?
`isXmlHttpRequest() : bool` | Is this a Javascript XMLHttpRequest?
`isFlashRequest() : bool` | Is this a Flash request?
`renderRequestLine() : string` | Return the formatted request line (first line) for this HTTP request.
`toString() : string` | Returns string
`__toString() : string` | Allow PHP casting of this object.
## Examples
### Generating a Request object from a string
```php
use Zend\Http\Request;
$string = "GET /foo HTTP/1.1\r\n\r\nSome Content";
$request = Request::fromString($string);
$request->getMethod(); // returns Request::METHOD_GET
$request->getUri(); // returns Zend\Uri\Http object
$request->getUriString(); // returns '/foo'
$request->getVersion(); // returns Request::VERSION_11 or '1.1'
$request->getContent(); // returns 'Some Content'
```
### Retrieving and setting headers
```php
use Zend\Http\Request;
use Zend\Http\Header\Cookie;
$request = new Request();
$request->getHeaders()->get('Content-Type'); // return content type
$request->getHeaders()->addHeader(new Cookie(['foo' => 'bar']));
foreach ($request->getHeaders() as $header) {
printf("%s with value %s\n", $header->getFieldName(), $header->getFieldValue());
}
```
### Retrieving and setting GET and POST values
```php
use Zend\Http\Request;
$request = new Request();
// getPost() and getQuery() both return, by default, a Parameters object, which
// extends ArrayObject
$request->getPost()->foo = 'Foo value';
$request->getQuery()->bar = 'Bar value';
$request->getPost('foo'); // returns 'Foo value'
$request->getQuery()->offsetGet('bar'); // returns 'Bar value'
```
### Generating a formatted HTTP Request from a Request object
```php
use Zend\Http\Request;
$request = new Request();
$request->setMethod(Request::METHOD_POST);
$request->setUri('/foo');
$request->getHeaders()->addHeaders([
'HeaderField1' => 'header-field-value1',
'HeaderField2' => 'header-field-value2',
]);
$request->getPost()->set('foo', 'bar');
$request->setContent($request->getPost()->toString());
echo $request->toString();
/** Will produce:
POST /foo HTTP/1.1
HeaderField1: header-field-value1
HeaderField2: header-field-value2
foo=bar
*/
```

View File

@@ -0,0 +1,140 @@
# The Response Class
`Zend\Http\Response` is responsible for providing a fluent API that allows a
developer to interact with all the various parts of an HTTP response.
A typical HTTP Response looks like this:
```text
| VERSION | CODE | REASON |
| HEADERS |
| BODY |
```
The first line of the response consists of the HTTP version, status code, and
the reason string for the provided status code; this is called the Response
Line. Next is a set of zero or more headers. The remainder of the response is
the response body, which is typically a string of HTML that will render on the
client's browser, but which can also be a place for request/response payload
data typical of an AJAX request. More information on the structure and
specification of an HTTP response can be found in
[RFC-2616 on the W3.org site](http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html).
## Quick Start
Response objects can either be created from the provided `fromString()` factory,
or, if you wish to have a completely empty object to start with, by
instantiating the `Zend\Http\Response` class with no arguments.
```php
use Zend\Http\Response;
$response = Response::fromString(<<<EOS
HTTP/1.0 200 OK
HeaderField1: header-field-value
HeaderField2: header-field-value2
<html>
<body>
Hello World
</body>
</html>
EOS);
// OR
$response = new Response();
$response->setStatusCode(Response::STATUS_CODE_200);
$response->getHeaders()->addHeaders([
'HeaderField1' => 'header-field-value',
'HeaderField2' => 'header-field-value2',
]);
$response->setContent(<<<EOS
<html>
<body>
Hello World
</body>
</html>
EOS
);
```
## Configuration Options
No configuration options are available.
## Available Methods
The following table details available methods, their signatures, and a brief
description. Note that the following references refer to the following
fully qualified class names and/or namespaces:
- `Headers`: `Zend\Http\Headers`
- `Response`: `Zend\Http\Response`
Method signature | Description
---------------------------------------------------------------------- | -----------
`stati fromString(string $string) : Response` | Populate object from string.
`renderStatusLine() : string` | Render the status line header
`setHeaders(Headers $headers) : self` | Provide an alternate Parameter Container implementation for headers in this object. (This is NOT the primary API for value setting; for that, see `getHeaders()`.)
`getHeaders() : Headers` | Return the container responsible for storing HTTP headers. This container exposes the primary API for manipulating headers set in the HTTP response. See the section on [Headers](headers.md) for more information.
`setVersion(string $version) : self` | Set the HTTP version for this object, one of 1.0 or 1.1 (`Request::VERSION_10`, `Request::VERSION_11`).
`getVersion() : string` | Return the HTTP version for this request.
`setStatusCode(int $code) : self` | Set HTTP status code.
`getStatusCode() : int` | Retrieve HTTP status code.
`setReasonPhrase(string $reasonPhrase) : self` | Set custom HTTP status message.
`getReasonPhrase() : string` | Get HTTP status message.
`isClientError() : bool` | Does the status code indicate a client error?
`isForbidden() : bool` | Is the request forbidden due to ACLs?
`isInformational() : bool` | Is the current status "informational"?
`isNotFound() : bool` | Does the status code indicate the resource is not found?
`isOk() : bool` | Do we have a normal, OK response?
`isServerError() : bool` | Does the status code reflect a server error?
`isRedirect() : bool` | Do we have a redirect?
`isSuccess() : bool` | Was the response successful?
`decodeChunkedBody(string $body) : string` | Decode a "chunked" transfer-encoded body and return the decoded text.
`decodeGzip(string $body) : string` | Decode a gzip encoded message (when `Content-Encoding` indicates gzip). Currently requires PHP with zlib support.
`decodeDeflate(string $body) : string` | Decode a zlib deflated message (when `Content-Encoding` indicates deflate). Currently requires PHP with zlib support.
`setMetadata(string|int|array|Traversable $spec, mixed $value) : self` | Non-destructive setting of message metadata; always adds to the metadata, never overwrites the entire metadata container.
`getMetadata(null|string|int $key, null|mixed $default) : mixed` | Retrieve all metadata or a single metadatum as specified by key.
`setContent(mixed $value) : self` | Set message content.
`getContent() : mixed` | Get raw message content.
`getBody() : mixed` | Get decoded message content.
`toString() : string` | Returns string representation of response.
## Examples
### Generating a Response object from a string
```php
use Zend\Http\Response;
$request = Response::fromString(<<<EOS
HTTP/1.0 200 OK
HeaderField1: header-field-value
HeaderField2: header-field-value2
<html>
<body>
Hello World
</body>
</html>
EOS);
```
### Generating a formatted HTTP Response from a Response object
```php
use Zend\Http\Response;
$response = new Response();
$response->setStatusCode(Response::STATUS_CODE_200);
$response->getHeaders()->addHeaders([
'HeaderField1' => 'header-field-value',
'HeaderField2' => 'header-field-value2',
]);
$response->setContent(<<<EOS
<html>
<body>
Hello World
</body>
</html>
EOS);
```