StreamTransport.php 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. <?php
  2. /**
  3. * @link http://www.yiiframework.com/
  4. * @copyright Copyright (c) 2008 Yii Software LLC
  5. * @license http://www.yiiframework.com/license/
  6. */
  7. namespace yii\httpclient;
  8. use yii\helpers\ArrayHelper;
  9. use yii\helpers\Inflector;
  10. use Yii;
  11. /**
  12. * StreamTransport sends HTTP messages using [Streams](http://php.net/manual/en/book.stream.php)
  13. *
  14. * For this transport, you may setup request options using [Context Options](http://php.net/manual/en/context.php)
  15. *
  16. * @author Paul Klimov <klimov.paul@gmail.com>
  17. * @since 2.0
  18. */
  19. class StreamTransport extends Transport
  20. {
  21. /**
  22. * @inheritdoc
  23. */
  24. public function send($request)
  25. {
  26. $request->beforeSend();
  27. $request->prepare();
  28. $url = $request->getFullUrl();
  29. $method = strtoupper($request->getMethod());
  30. $contextOptions = [
  31. 'http' => [
  32. 'method' => $method,
  33. 'ignore_errors' => true,
  34. ],
  35. 'ssl' => [
  36. 'verify_peer' => false,
  37. ],
  38. ];
  39. $content = $request->getContent();
  40. if ($content !== null) {
  41. $contextOptions['http']['content'] = $content;
  42. }
  43. $headers = $request->composeHeaderLines();
  44. $contextOptions['http']['header'] = $headers;
  45. $contextOptions = ArrayHelper::merge($contextOptions, $this->composeContextOptions($request->getOptions()));
  46. $token = $request->client->createRequestLogToken($method, $url, $headers, $content);
  47. Yii::info($token, __METHOD__);
  48. Yii::beginProfile($token, __METHOD__);
  49. try {
  50. $context = stream_context_create($contextOptions);
  51. $stream = fopen($url, 'rb', false, $context);
  52. $responseContent = stream_get_contents($stream);
  53. // see http://php.net/manual/en/reserved.variables.httpresponseheader.php
  54. $responseHeaders = $http_response_header;
  55. fclose($stream);
  56. } catch (\Exception $e) {
  57. Yii::endProfile($token, __METHOD__);
  58. throw new Exception($e->getMessage(), $e->getCode(), $e);
  59. }
  60. Yii::endProfile($token, __METHOD__);
  61. $response = $request->client->createResponse($responseContent, $responseHeaders);
  62. $request->afterSend($response);
  63. return $response;
  64. }
  65. /**
  66. * Composes stream context options from raw request options.
  67. * @param array $options raw request options.
  68. * @return array stream context options.
  69. */
  70. private function composeContextOptions(array $options)
  71. {
  72. $contextOptions = [];
  73. foreach ($options as $key => $value) {
  74. $section = 'http';
  75. if (strpos($key, 'ssl') === 0) {
  76. $section = 'ssl';
  77. $key = substr($key, 3);
  78. }
  79. $key = Inflector::underscore($key);
  80. $contextOptions[$section][$key] = $value;
  81. }
  82. return $contextOptions;
  83. }
  84. }