Open Journal Systems  3.3.0
PhpStreamRequestFactory.php
1 <?php
2 
3 namespace Guzzle\Stream;
4 
10 
17 {
19  protected $context;
20 
22  protected $contextOptions;
23 
25  protected $url;
26 
29 
36  public function fromRequest(RequestInterface $request, $context = array(), array $params = array())
37  {
38  if (is_resource($context)) {
39  $this->contextOptions = stream_context_get_options($context);
40  $this->context = $context;
41  } elseif (is_array($context) || !$context) {
42  $this->contextOptions = $context;
43  $this->createContext($params);
44  } elseif ($context) {
45  throw new InvalidArgumentException('$context must be an array or resource');
46  }
47 
48  // Dispatch the before send event
49  $request->dispatch('request.before_send', array(
50  'request' => $request,
51  'context' => $this->context,
52  'context_options' => $this->contextOptions
53  ));
54 
55  $this->setUrl($request);
56  $this->addDefaultContextOptions($request);
57  $this->addSslOptions($request);
58  $this->addBodyOptions($request);
59  $this->addProxyOptions($request);
60 
61  // Create the file handle but silence errors
62  return $this->createStream($params)
63  ->setCustomData('request', $request)
64  ->setCustomData('response_headers', $this->getLastResponseHeaders());
65  }
66 
75  protected function setContextValue($wrapper, $name, $value, $overwrite = false)
76  {
77  if (!isset($this->contextOptions[$wrapper])) {
78  $this->contextOptions[$wrapper] = array($name => $value);
79  } elseif (!$overwrite && isset($this->contextOptions[$wrapper][$name])) {
80  return;
81  }
82  $this->contextOptions[$wrapper][$name] = $value;
83  stream_context_set_option($this->context, $wrapper, $name, $value);
84  }
85 
91  protected function createContext(array $params)
92  {
93  $options = $this->contextOptions;
94  $this->context = $this->createResource(function () use ($params, $options) {
95  return stream_context_create($options, $params);
96  });
97  }
98 
104  public function getLastResponseHeaders()
105  {
107  }
108 
114  protected function addDefaultContextOptions(RequestInterface $request)
115  {
116  $this->setContextValue('http', 'method', $request->getMethod());
117  $headers = $request->getHeaderLines();
118 
119  // "Connection: close" is required to get streams to work in HTTP 1.1
120  if (!$request->hasHeader('Connection')) {
121  $headers[] = 'Connection: close';
122  }
123 
124  $this->setContextValue('http', 'header', $headers);
125  $this->setContextValue('http', 'protocol_version', $request->getProtocolVersion());
126  $this->setContextValue('http', 'ignore_errors', true);
127  }
128 
134  protected function setUrl(RequestInterface $request)
135  {
136  $this->url = $request->getUrl(true);
137 
138  // Check for basic Auth username
139  if ($request->getUsername()) {
140  $this->url->setUsername($request->getUsername());
141  }
142 
143  // Check for basic Auth password
144  if ($request->getPassword()) {
145  $this->url->setPassword($request->getPassword());
146  }
147  }
148 
154  protected function addSslOptions(RequestInterface $request)
155  {
156  if ($request->getCurlOptions()->get(CURLOPT_SSL_VERIFYPEER)) {
157  $this->setContextValue('ssl', 'verify_peer', true, true);
158  if ($cafile = $request->getCurlOptions()->get(CURLOPT_CAINFO)) {
159  $this->setContextValue('ssl', 'cafile', $cafile, true);
160  }
161  } else {
162  $this->setContextValue('ssl', 'verify_peer', false, true);
163  }
164  }
165 
171  protected function addBodyOptions(RequestInterface $request)
172  {
173  // Add the content for the request if needed
174  if (!($request instanceof EntityEnclosingRequestInterface)) {
175  return;
176  }
177 
178  if (count($request->getPostFields())) {
179  $this->setContextValue('http', 'content', (string) $request->getPostFields(), true);
180  } elseif ($request->getBody()) {
181  $this->setContextValue('http', 'content', (string) $request->getBody(), true);
182  }
183 
184  // Always ensure a content-length header is sent
185  if (isset($this->contextOptions['http']['content'])) {
186  $headers = isset($this->contextOptions['http']['header']) ? $this->contextOptions['http']['header'] : array();
187  $headers[] = 'Content-Length: ' . strlen($this->contextOptions['http']['content']);
188  $this->setContextValue('http', 'header', $headers, true);
189  }
190  }
191 
197  protected function addProxyOptions(RequestInterface $request)
198  {
199  if ($proxy = $request->getCurlOptions()->get(CURLOPT_PROXY)) {
200  $this->setContextValue('http', 'proxy', $proxy);
201  }
202  }
203 
211  protected function createStream(array $params)
212  {
213  $http_response_header = null;
214  $url = $this->url;
216  $fp = $this->createResource(function () use ($context, $url, &$http_response_header) {
217  return fopen((string) $url, 'r', false, $context);
218  });
219 
220  // Determine the class to instantiate
221  $className = isset($params['stream_class']) ? $params['stream_class'] : __NAMESPACE__ . '\\Stream';
222 
224  $stream = new $className($fp);
225 
226  // Track the response headers of the request
227  if (isset($http_response_header)) {
228  $this->lastResponseHeaders = $http_response_header;
229  $this->processResponseHeaders($stream);
230  }
231 
232  return $stream;
233  }
234 
240  protected function processResponseHeaders(StreamInterface $stream)
241  {
242  // Set the size on the stream if it was returned in the response
243  foreach ($this->lastResponseHeaders as $header) {
244  if ((stripos($header, 'Content-Length:')) === 0) {
245  $stream->setSize(trim(substr($header, 15)));
246  }
247  }
248  }
249 
258  protected function createResource($callback)
259  {
260  $errors = null;
261  set_error_handler(function ($_, $msg, $file, $line) use (&$errors) {
262  $errors[] = array(
263  'message' => $msg,
264  'file' => $file,
265  'line' => $line
266  );
267  return true;
268  });
269  $resource = call_user_func($callback);
270  restore_error_handler();
271 
272  if (!$resource) {
273  $message = 'Error creating resource. ';
274  foreach ($errors as $err) {
275  foreach ($err as $key => $value) {
276  $message .= "[$key] $value" . PHP_EOL;
277  }
278  }
279  throw new RuntimeException(trim($message));
280  }
281 
282  return $resource;
283  }
284 }
Guzzle\Http\Message\RequestInterface\getProtocolVersion
getProtocolVersion()
Guzzle\Http\Message\RequestInterface\getUsername
getUsername()
Guzzle\Http\Message\RequestInterface
Definition: lib/vendor/guzzle/guzzle/src/Guzzle/Http/Message/RequestInterface.php:16
Guzzle\Stream\PhpStreamRequestFactory\setUrl
setUrl(RequestInterface $request)
Definition: PhpStreamRequestFactory.php:146
Guzzle\Http\Message\RequestInterface\getUrl
getUrl($asObject=false)
Guzzle\Stream\PhpStreamRequestFactory\$lastResponseHeaders
$lastResponseHeaders
Definition: PhpStreamRequestFactory.php:40
Guzzle\Http\Message\RequestInterface\getCurlOptions
getCurlOptions()
Guzzle\Stream\PhpStreamRequestFactory\getLastResponseHeaders
getLastResponseHeaders()
Definition: PhpStreamRequestFactory.php:116
Guzzle\Http\Message\EntityEnclosingRequestInterface
Definition: EntityEnclosingRequestInterface.php:12
Guzzle\Stream\PhpStreamRequestFactory
Definition: PhpStreamRequestFactory.php:16
Guzzle\Stream\PhpStreamRequestFactory\$context
$context
Definition: PhpStreamRequestFactory.php:22
Guzzle\Stream\PhpStreamRequestFactory\createContext
createContext(array $params)
Definition: PhpStreamRequestFactory.php:103
Guzzle\Stream\PhpStreamRequestFactory\addProxyOptions
addProxyOptions(RequestInterface $request)
Definition: PhpStreamRequestFactory.php:209
Guzzle\Http\Url
Definition: Url.php:10
Guzzle\Common\HasDispatcherInterface\dispatch
dispatch($eventName, array $context=array())
Guzzle\Http\Message\RequestInterface\getPassword
getPassword()
Guzzle\Stream\PhpStreamRequestFactory\addDefaultContextOptions
addDefaultContextOptions(RequestInterface $request)
Definition: PhpStreamRequestFactory.php:126
Guzzle\Stream\StreamRequestFactoryInterface
Definition: StreamRequestFactoryInterface.php:10
Guzzle\Common\Exception\InvalidArgumentException
Definition: lib/vendor/guzzle/guzzle/src/Guzzle/Common/Exception/InvalidArgumentException.php:5
Guzzle\Stream\PhpStreamRequestFactory\createStream
createStream(array $params)
Definition: PhpStreamRequestFactory.php:223
Seboettg\Collection\count
count()
Definition: ArrayListTrait.php:253
Guzzle\Stream\PhpStreamRequestFactory\$contextOptions
$contextOptions
Definition: PhpStreamRequestFactory.php:28
Guzzle\Stream\PhpStreamRequestFactory\fromRequest
fromRequest(RequestInterface $request, $context=array(), array $params=array())
Definition: PhpStreamRequestFactory.php:48
Guzzle\Http\Message\RequestInterface\getMethod
getMethod()
Guzzle\Stream\PhpStreamRequestFactory\addSslOptions
addSslOptions(RequestInterface $request)
Definition: PhpStreamRequestFactory.php:166
Guzzle\Stream\PhpStreamRequestFactory\addBodyOptions
addBodyOptions(RequestInterface $request)
Definition: PhpStreamRequestFactory.php:183
Guzzle\Stream\PhpStreamRequestFactory\createResource
createResource($callback)
Definition: PhpStreamRequestFactory.php:270
Guzzle\Http\Message\MessageInterface\hasHeader
hasHeader($header)
Guzzle\Stream\StreamInterface
Definition: lib/vendor/guzzle/guzzle/src/Guzzle/Stream/StreamInterface.php:8
Guzzle\Stream
Definition: PhpStreamRequestFactory.php:3
Guzzle\Stream\PhpStreamRequestFactory\setContextValue
setContextValue($wrapper, $name, $value, $overwrite=false)
Definition: PhpStreamRequestFactory.php:87
Guzzle\Stream\PhpStreamRequestFactory\$url
$url
Definition: PhpStreamRequestFactory.php:34
Guzzle\Common\Exception\RuntimeException
Definition: lib/vendor/guzzle/guzzle/src/Guzzle/Common/Exception/RuntimeException.php:5
Guzzle\Http\Message\MessageInterface\getHeaderLines
getHeaderLines()
Guzzle\Stream\PhpStreamRequestFactory\processResponseHeaders
processResponseHeaders(StreamInterface $stream)
Definition: PhpStreamRequestFactory.php:252