$instance
$instance : \Guzzle\Http\Message\RequestFactory
Default HTTP request factory used to create the default {@see Request} and {@see EntityEnclosingRequest} objects.
$instance : \Guzzle\Http\Message\RequestFactory
getInstance() : \Guzzle\Http\Message\RequestFactory
Get a cached instance of the default request factory
fromMessage(string $message) : \Guzzle\Http\Message\RequestInterface
Create a new request based on an HTTP message
string | $message | HTTP message as a string |
fromParts(string $method, array $urlParts, array|\Guzzle\Common\Collection $headers = null, string|resource|array|\Guzzle\Http\EntityBodyInterface $body = null, string $protocol = 'HTTP', string $protocolVersion = '1.1') : \Guzzle\Http\Message\RequestInterface
Create a request from URL parts as returned from parse_url()
string | $method | HTTP method (GET, POST, PUT, HEAD, DELETE, etc) |
array | $urlParts | URL parts containing the same keys as parse_url()
|
array|\Guzzle\Common\Collection | $headers | HTTP headers |
string|resource|array|\Guzzle\Http\EntityBodyInterface | $body | Body to send in the request |
string | $protocol | Protocol (HTTP, SPYDY, etc) |
string | $protocolVersion | 1.0, 1.1, etc |
create(string $method, string|\Guzzle\Http\Url $url, array|\Guzzle\Common\Collection $headers = null, string|resource|array|\Guzzle\Http\EntityBodyInterface $body = null, array $options = array()) : \Guzzle\Http\Message\RequestInterface
Create a new request based on the HTTP method
string | $method | HTTP method (GET, POST, PUT, PATCH, HEAD, DELETE, ...) |
string|\Guzzle\Http\Url | $url | HTTP URL to connect to |
array|\Guzzle\Common\Collection | $headers | HTTP headers |
string|resource|array|\Guzzle\Http\EntityBodyInterface | $body | Body to send in the request |
array | $options | Array of options to apply to the request |
cloneRequestWithMethod(\Guzzle\Http\Message\RequestInterface $request, string $method) : \Guzzle\Http\Message\RequestInterface
Clone a request while changing the method. Emulates the behavior of {@see Guzzle\Http\Message\Request::clone}, but can change the HTTP method.
\Guzzle\Http\Message\RequestInterface | $request | Request to clone |
string | $method | Method to set |
applyOptions(\Guzzle\Http\Message\RequestInterface $request, array $options = array(), integer $flags = self::OPTIONS_NONE)
Apply an associative array of options to the request
\Guzzle\Http\Message\RequestInterface | $request | Request to update |
array | $options | Options to use with the request. Available options are: "headers": Associative array of headers "query": Associative array of query string values to add to the request "body": Body of a request, including an EntityBody, string, or array when sending POST requests. "auth": Array of HTTP authentication parameters to use with the request. The array must contain the username in index [0], the password in index [2], and can optionally contain the authentication type in index [3]. The authentication types are: "Basic", "Digest", "NTLM", "Any" (defaults to "Basic"). "cookies": Associative array of cookies "allow_redirects": Set to false to disable redirects "save_to": String, fopen resource, or EntityBody object used to store the body of the response "events": Associative array mapping event names to a closure or array of (priority, closure) "plugins": Array of plugins to add to the request "exceptions": Set to false to disable throwing exceptions on an HTTP level error (e.g. 404, 500, etc) "params": Set custom request data parameters on a request. (Note: these are not query string parameters) "timeout": Float describing the timeout of the request in seconds "connect_timeout": Float describing the number of seconds to wait while trying to connect. Use 0 to wait indefinitely. "verify": Set to true to enable SSL cert validation (the default), false to disable, or supply the path to a CA bundle to enable verification using a custom certificate. "cert": Set to a string to specify the path to a file containing a PEM formatted certificate. If a password is required, then set an array containing the path to the PEM file followed by the the password required for the certificate. "ssl_key": Specify the path to a file containing a private SSL key in PEM format. If a password is required, then set an array containing the path to the SSL key followed by the password required for the certificate. "proxy": Specify an HTTP proxy (e.g. "http://username:password@192.168.16.1:10") "debug": Set to true to display all data sent over the wire |
integer | $flags | Bitwise flags to apply when applying the options to the request. Defaults to no special
options. |
visit_headers(\Guzzle\Http\Message\RequestInterface $request, $value, $flags)
\Guzzle\Http\Message\RequestInterface | $request | |
$value | ||
$flags |
visit_body(\Guzzle\Http\Message\RequestInterface $request, $value, $flags)
\Guzzle\Http\Message\RequestInterface | $request | |
$value | ||
$flags |
visit_allow_redirects(\Guzzle\Http\Message\RequestInterface $request, $value, $flags)
\Guzzle\Http\Message\RequestInterface | $request | |
$value | ||
$flags |
visit_auth(\Guzzle\Http\Message\RequestInterface $request, $value, $flags)
\Guzzle\Http\Message\RequestInterface | $request | |
$value | ||
$flags |
visit_query(\Guzzle\Http\Message\RequestInterface $request, $value, $flags)
\Guzzle\Http\Message\RequestInterface | $request | |
$value | ||
$flags |
visit_cookies(\Guzzle\Http\Message\RequestInterface $request, $value, $flags)
\Guzzle\Http\Message\RequestInterface | $request | |
$value | ||
$flags |
visit_events(\Guzzle\Http\Message\RequestInterface $request, $value, $flags)
\Guzzle\Http\Message\RequestInterface | $request | |
$value | ||
$flags |
visit_plugins(\Guzzle\Http\Message\RequestInterface $request, $value, $flags)
\Guzzle\Http\Message\RequestInterface | $request | |
$value | ||
$flags |
visit_exceptions(\Guzzle\Http\Message\RequestInterface $request, $value, $flags)
\Guzzle\Http\Message\RequestInterface | $request | |
$value | ||
$flags |
visit_save_to(\Guzzle\Http\Message\RequestInterface $request, $value, $flags)
\Guzzle\Http\Message\RequestInterface | $request | |
$value | ||
$flags |
visit_params(\Guzzle\Http\Message\RequestInterface $request, $value, $flags)
\Guzzle\Http\Message\RequestInterface | $request | |
$value | ||
$flags |
visit_timeout(\Guzzle\Http\Message\RequestInterface $request, $value, $flags)
\Guzzle\Http\Message\RequestInterface | $request | |
$value | ||
$flags |
visit_connect_timeout(\Guzzle\Http\Message\RequestInterface $request, $value, $flags)
\Guzzle\Http\Message\RequestInterface | $request | |
$value | ||
$flags |
visit_debug(\Guzzle\Http\Message\RequestInterface $request, $value, $flags)
\Guzzle\Http\Message\RequestInterface | $request | |
$value | ||
$flags |
visit_verify(\Guzzle\Http\Message\RequestInterface $request, $value, $flags)
\Guzzle\Http\Message\RequestInterface | $request | |
$value | ||
$flags |
visit_proxy(\Guzzle\Http\Message\RequestInterface $request, $value, $flags)
\Guzzle\Http\Message\RequestInterface | $request | |
$value | ||
$flags |
visit_cert(\Guzzle\Http\Message\RequestInterface $request, $value, $flags)
\Guzzle\Http\Message\RequestInterface | $request | |
$value | ||
$flags |
visit_ssl_key(\Guzzle\Http\Message\RequestInterface $request, $value, $flags)
\Guzzle\Http\Message\RequestInterface | $request | |
$value | ||
$flags |
<?php
namespace Guzzle\Http\Message;
use Guzzle\Common\Collection;
use Guzzle\Common\Exception\InvalidArgumentException;
use Guzzle\Http\RedirectPlugin;
use Guzzle\Http\Url;
use Guzzle\Parser\ParserRegistry;
/**
* Default HTTP request factory used to create the default {@see Request} and {@see EntityEnclosingRequest} objects.
*/
class RequestFactory implements RequestFactoryInterface
{
/** @var RequestFactory Singleton instance of the default request factory */
protected static $instance;
/** @var array Hash of methods available to the class (provides fast isset() lookups) */
protected $methods;
/** @var string Class to instantiate for requests with no body */
protected $requestClass = 'Guzzle\\Http\\Message\\Request';
/** @var string Class to instantiate for requests with a body */
protected $entityEnclosingRequestClass = 'Guzzle\\Http\\Message\\EntityEnclosingRequest';
/**
* Get a cached instance of the default request factory
*
* @return RequestFactory
*/
public static function getInstance()
{
// @codeCoverageIgnoreStart
if (!static::$instance) {
static::$instance = new static();
}
// @codeCoverageIgnoreEnd
return static::$instance;
}
public function __construct()
{
$this->methods = array_flip(get_class_methods(__CLASS__));
}
public function fromMessage($message)
{
$parsed = ParserRegistry::getInstance()->getParser('message')->parseRequest($message);
if (!$parsed) {
return false;
}
$request = $this->fromParts($parsed['method'], $parsed['request_url'],
$parsed['headers'], $parsed['body'], $parsed['protocol'],
$parsed['version']);
// EntityEnclosingRequest adds an "Expect: 100-Continue" header when using a raw request body for PUT or POST
// requests. This factory method should accurately reflect the message, so here we are removing the Expect
// header if one was not supplied in the message.
if (!isset($parsed['headers']['Expect']) && !isset($parsed['headers']['expect'])) {
$request->removeHeader('Expect');
}
return $request;
}
public function fromParts(
$method,
array $urlParts,
$headers = null,
$body = null,
$protocol = 'HTTP',
$protocolVersion = '1.1'
) {
return $this->create($method, Url::buildUrl($urlParts), $headers, $body)
->setProtocolVersion($protocolVersion);
}
public function create($method, $url, $headers = null, $body = null, array $options = array())
{
$method = strtoupper($method);
if ($method == 'GET' || $method == 'HEAD' || $method == 'TRACE') {
// Handle non-entity-enclosing request methods
$request = new $this->requestClass($method, $url, $headers);
if ($body) {
// The body is where the response body will be stored
$type = gettype($body);
if ($type == 'string' || $type == 'resource' || $type == 'object') {
$request->setResponseBody($body);
}
}
} else {
// Create an entity enclosing request by default
$request = new $this->entityEnclosingRequestClass($method, $url, $headers);
if ($body || $body === '0') {
// Add POST fields and files to an entity enclosing request if an array is used
if (is_array($body) || $body instanceof Collection) {
// Normalize PHP style cURL uploads with a leading '@' symbol
foreach ($body as $key => $value) {
if (is_string($value) && substr($value, 0, 1) == '@') {
$request->addPostFile($key, $value);
unset($body[$key]);
}
}
// Add the fields if they are still present and not all files
$request->addPostFields($body);
} else {
// Add a raw entity body body to the request
$request->setBody($body, (string) $request->getHeader('Content-Type'));
if ((string) $request->getHeader('Transfer-Encoding') == 'chunked') {
$request->removeHeader('Content-Length');
}
}
}
}
if ($options) {
$this->applyOptions($request, $options);
}
return $request;
}
/**
* Clone a request while changing the method. Emulates the behavior of
* {@see Guzzle\Http\Message\Request::clone}, but can change the HTTP method.
*
* @param RequestInterface $request Request to clone
* @param string $method Method to set
*
* @return RequestInterface
*/
public function cloneRequestWithMethod(RequestInterface $request, $method)
{
// Create the request with the same client if possible
if ($request->getClient()) {
$cloned = $request->getClient()->createRequest($method, $request->getUrl(), $request->getHeaders());
} else {
$cloned = $this->create($method, $request->getUrl(), $request->getHeaders());
}
$cloned->getCurlOptions()->replace($request->getCurlOptions()->toArray());
$cloned->setEventDispatcher(clone $request->getEventDispatcher());
// Ensure that that the Content-Length header is not copied if changing to GET or HEAD
if (!($cloned instanceof EntityEnclosingRequestInterface)) {
$cloned->removeHeader('Content-Length');
} elseif ($request instanceof EntityEnclosingRequestInterface) {
$cloned->setBody($request->getBody());
}
$cloned->getParams()->replace($request->getParams()->toArray());
$cloned->dispatch('request.clone', array('request' => $cloned));
return $cloned;
}
public function applyOptions(RequestInterface $request, array $options = array(), $flags = self::OPTIONS_NONE)
{
// Iterate over each key value pair and attempt to apply a config using function visitors
foreach ($options as $key => $value) {
$method = "visit_{$key}";
if (isset($this->methods[$method])) {
$this->{$method}($request, $value, $flags);
}
}
}
protected function visit_headers(RequestInterface $request, $value, $flags)
{
if (!is_array($value)) {
throw new InvalidArgumentException('headers value must be an array');
}
if ($flags & self::OPTIONS_AS_DEFAULTS) {
// Merge headers in but do not overwrite existing values
foreach ($value as $key => $header) {
if (!$request->hasHeader($key)) {
$request->setHeader($key, $header);
}
}
} else {
$request->addHeaders($value);
}
}
protected function visit_body(RequestInterface $request, $value, $flags)
{
if ($request instanceof EntityEnclosingRequestInterface) {
$request->setBody($value);
} else {
throw new InvalidArgumentException('Attempting to set a body on a non-entity-enclosing request');
}
}
protected function visit_allow_redirects(RequestInterface $request, $value, $flags)
{
if ($value === false) {
$request->getParams()->set(RedirectPlugin::DISABLE, true);
}
}
protected function visit_auth(RequestInterface $request, $value, $flags)
{
if (!is_array($value)) {
throw new InvalidArgumentException('auth value must be an array');
}
$request->setAuth($value[0], isset($value[1]) ? $value[1] : null, isset($value[2]) ? $value[2] : 'basic');
}
protected function visit_query(RequestInterface $request, $value, $flags)
{
if (!is_array($value)) {
throw new InvalidArgumentException('query value must be an array');
}
if ($flags & self::OPTIONS_AS_DEFAULTS) {
// Merge query string values in but do not overwrite existing values
$query = $request->getQuery();
$query->overwriteWith(array_diff_key($value, $query->toArray()));
} else {
$request->getQuery()->overwriteWith($value);
}
}
protected function visit_cookies(RequestInterface $request, $value, $flags)
{
if (!is_array($value)) {
throw new InvalidArgumentException('cookies value must be an array');
}
foreach ($value as $name => $v) {
$request->addCookie($name, $v);
}
}
protected function visit_events(RequestInterface $request, $value, $flags)
{
if (!is_array($value)) {
throw new InvalidArgumentException('events value must be an array');
}
foreach ($value as $name => $method) {
if (is_array($method)) {
$request->getEventDispatcher()->addListener($name, $method[0], $method[1]);
} else {
$request->getEventDispatcher()->addListener($name, $method);
}
}
}
protected function visit_plugins(RequestInterface $request, $value, $flags)
{
if (!is_array($value)) {
throw new InvalidArgumentException('plugins value must be an array');
}
foreach ($value as $plugin) {
$request->addSubscriber($plugin);
}
}
protected function visit_exceptions(RequestInterface $request, $value, $flags)
{
if ($value === false || $value === 0) {
$dispatcher = $request->getEventDispatcher();
foreach ($dispatcher->getListeners('request.error') as $listener) {
if (is_array($listener) && $listener[0] == 'Guzzle\Http\Message\Request' && $listener[1] = 'onRequestError') {
$dispatcher->removeListener('request.error', $listener);
break;
}
}
}
}
protected function visit_save_to(RequestInterface $request, $value, $flags)
{
$request->setResponseBody($value);
}
protected function visit_params(RequestInterface $request, $value, $flags)
{
if (!is_array($value)) {
throw new InvalidArgumentException('params value must be an array');
}
$request->getParams()->overwriteWith($value);
}
protected function visit_timeout(RequestInterface $request, $value, $flags)
{
if (defined('CURLOPT_TIMEOUT_MS')) {
$request->getCurlOptions()->set(CURLOPT_TIMEOUT_MS, $value * 1000);
} else {
$request->getCurlOptions()->set(CURLOPT_TIMEOUT, $value);
}
}
protected function visit_connect_timeout(RequestInterface $request, $value, $flags)
{
if (defined('CURLOPT_CONNECTTIMEOUT_MS')) {
$request->getCurlOptions()->set(CURLOPT_CONNECTTIMEOUT_MS, $value * 1000);
} else {
$request->getCurlOptions()->set(CURLOPT_CONNECTTIMEOUT, $value);
}
}
protected function visit_debug(RequestInterface $request, $value, $flags)
{
if ($value) {
$request->getCurlOptions()->set(CURLOPT_VERBOSE, true);
}
}
protected function visit_verify(RequestInterface $request, $value, $flags)
{
$curl = $request->getCurlOptions();
if ($value === true || is_string($value)) {
$curl[CURLOPT_SSL_VERIFYHOST] = 2;
$curl[CURLOPT_SSL_VERIFYPEER] = true;
if ($value !== true) {
$curl[CURLOPT_CAINFO] = $value;
}
} elseif ($value === false) {
unset($curl[CURLOPT_CAINFO]);
$curl[CURLOPT_SSL_VERIFYHOST] = 0;
$curl[CURLOPT_SSL_VERIFYPEER] = false;
}
}
protected function visit_proxy(RequestInterface $request, $value, $flags)
{
$request->getCurlOptions()->set(CURLOPT_PROXY, $value, $flags);
}
protected function visit_cert(RequestInterface $request, $value, $flags)
{
if (is_array($value)) {
$request->getCurlOptions()->set(CURLOPT_SSLCERT, $value[0]);
$request->getCurlOptions()->set(CURLOPT_SSLCERTPASSWD, $value[1]);
} else {
$request->getCurlOptions()->set(CURLOPT_SSLCERT, $value);
}
}
protected function visit_ssl_key(RequestInterface $request, $value, $flags)
{
if (is_array($value)) {
$request->getCurlOptions()->set(CURLOPT_SSLKEY, $value[0]);
$request->getCurlOptions()->set(CURLOPT_SSLKEYPASSWD, $value[1]);
} else {
$request->getCurlOptions()->set(CURLOPT_SSLKEY, $value);
}
}
}