CakePHP
  • Documentation
    • Book
    • API
    • Videos
    • Logos & Trademarks
  • Business Solutions
  • Swag
  • Road Trip
  • Team
  • Community
    • Community
    • Team
    • Issues (Github)
    • YouTube Channel
    • Get Involved
    • Bakery
    • Featured Resources
    • Newsletter
    • Certification
    • My CakePHP
    • CakeFest
    • Facebook
    • Twitter
    • Help & Support
    • Forum
    • Stack Overflow
    • IRC
    • Slack
    • Paid Support
CakePHP

C CakePHP 3.1 Red Velvet API

  • Overview
  • Tree
  • Deprecated
  • Version:
    • 3.1
      • 3.8
      • 3.7
      • 3.6
      • 3.5
      • 3.4
      • 3.3
      • 3.2
      • 3.1
      • 3.0
      • 2.10
      • 2.9
      • 2.8
      • 2.7
      • 2.6
      • 2.5
      • 2.4
      • 2.3
      • 2.2
      • 2.1
      • 2.0
      • 1.3
      • 1.2

Namespaces

  • Cake
    • Auth
      • Storage
    • Cache
      • Engine
    • Collection
      • Iterator
    • Console
      • Exception
    • Controller
      • Component
      • Exception
    • Core
      • Configure
        • Engine
      • Exception
    • Database
      • Driver
      • Exception
      • Expression
      • Schema
      • Statement
      • Type
    • Datasource
      • Exception
    • Error
    • Event
    • Filesystem
    • Form
    • I18n
      • Formatter
      • Parser
    • Log
      • Engine
    • Mailer
      • Exception
      • Transport
    • Network
      • Exception
      • Http
        • Adapter
        • Auth
        • FormData
      • Session
    • ORM
      • Association
      • Behavior
        • Translate
      • Exception
      • Locator
      • Rule
    • Routing
      • Exception
      • Filter
      • Route
    • Shell
      • Helper
      • Task
    • TestSuite
      • Fixture
      • Stub
    • Utility
      • Exception
    • Validation
    • View
      • Exception
      • Form
      • Helper
      • Widget
  • None

Classes

  • Stream
  1: <?php
  2: /**
  3:  * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  4:  * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  5:  *
  6:  * Licensed under The MIT License
  7:  * Redistributions of files must retain the above copyright notice.
  8:  *
  9:  * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
 10:  * @link          http://cakephp.org CakePHP(tm) Project
 11:  * @since         3.0.0
 12:  * @license       http://www.opensource.org/licenses/mit-license.php MIT License
 13:  */
 14: namespace Cake\Network\Http\Adapter;
 15: 
 16: use Cake\Core\Exception\Exception;
 17: use Cake\Network\Http\FormData;
 18: use Cake\Network\Http\Request;
 19: use Cake\Network\Http\Response;
 20: 
 21: /**
 22:  * Implements sending Cake\Network\Http\Request
 23:  * via php's stream API.
 24:  *
 25:  * This approach and implementation is partly inspired by Aura.Http
 26:  */
 27: class Stream
 28: {
 29: 
 30:     /**
 31:      * Context resource used by the stream API.
 32:      *
 33:      * @var resource
 34:      */
 35:     protected $_context;
 36: 
 37:     /**
 38:      * Array of options/content for the HTTP stream context.
 39:      *
 40:      * @var array
 41:      */
 42:     protected $_contextOptions;
 43: 
 44:     /**
 45:      * Array of options/content for the SSL stream context.
 46:      *
 47:      * @var array
 48:      */
 49:     protected $_sslContextOptions;
 50: 
 51:     /**
 52:      * The stream resource.
 53:      *
 54:      * @var resource
 55:      */
 56:     protected $_stream;
 57: 
 58:     /**
 59:      * Connection error list.
 60:      *
 61:      * @var array
 62:      */
 63:     protected $_connectionErrors = [];
 64: 
 65:     /**
 66:      * Send a request and get a response back.
 67:      *
 68:      * @param \Cake\Network\Http\Request $request The request object to send.
 69:      * @param array $options Array of options for the stream.
 70:      * @return array Array of populated Response objects
 71:      */
 72:     public function send(Request $request, array $options)
 73:     {
 74:         $this->_stream = null;
 75:         $this->_context = [];
 76:         $this->_contextOptions = [];
 77:         $this->_sslContextOptions = [];
 78:         $this->_connectionErrors = [];
 79: 
 80:         $this->_buildContext($request, $options);
 81:         return $this->_send($request);
 82:     }
 83: 
 84:     /**
 85:      * Create the response list based on the headers & content
 86:      *
 87:      * Creates one or many response objects based on the number
 88:      * of redirects that occurred.
 89:      *
 90:      * @param array $headers The list of headers from the request(s)
 91:      * @param string $content The response content.
 92:      * @return array The list of responses from the request(s)
 93:      */
 94:     public function createResponses($headers, $content)
 95:     {
 96:         $indexes = $responses = [];
 97:         foreach ($headers as $i => $header) {
 98:             if (strtoupper(substr($header, 0, 5)) === 'HTTP/') {
 99:                 $indexes[] = $i;
100:             }
101:         }
102:         $last = count($indexes) - 1;
103:         foreach ($indexes as $i => $start) {
104:             $end = isset($indexes[$i + 1]) ? $indexes[$i + 1] - $start : null;
105:             $headerSlice = array_slice($headers, $start, $end);
106:             $body = $i == $last ? $content : '';
107:             $responses[] = new Response($headerSlice, $body);
108:         }
109:         return $responses;
110:     }
111: 
112:     /**
113:      * Build the stream context out of the request object.
114:      *
115:      * @param \Cake\Network\Http\Request $request The request to build context from.
116:      * @param array $options Additional request options.
117:      * @return void
118:      */
119:     protected function _buildContext(Request $request, $options)
120:     {
121:         $this->_buildContent($request, $options);
122:         $this->_buildHeaders($request, $options);
123:         $this->_buildOptions($request, $options);
124: 
125:         $url = $request->url();
126:         $scheme = parse_url($url, PHP_URL_SCHEME);
127:         if ($scheme === 'https') {
128:             $this->_buildSslContext($request, $options);
129:         }
130:         $this->_context = stream_context_create([
131:             'http' => $this->_contextOptions,
132:             'ssl' => $this->_sslContextOptions,
133:         ]);
134:     }
135: 
136:     /**
137:      * Build the header context for the request.
138:      *
139:      * Creates cookies & headers.
140:      *
141:      * @param \Cake\Network\Http\Request $request The request being sent.
142:      * @param array $options Array of options to use.
143:      * @return void
144:      */
145:     protected function _buildHeaders(Request $request, $options)
146:     {
147:         $headers = [];
148:         foreach ($request->headers() as $name => $value) {
149:             $headers[] = "$name: $value";
150:         }
151: 
152:         $cookies = [];
153:         foreach ($request->cookies() as $name => $value) {
154:             $cookies[] = "$name=$value";
155:         }
156:         if ($cookies) {
157:             $headers[] = 'Cookie: ' . implode('; ', $cookies);
158:         }
159:         $this->_contextOptions['header'] = implode("\r\n", $headers);
160:     }
161: 
162:     /**
163:      * Builds the request content based on the request object.
164:      *
165:      * If the $request->body() is a string, it will be used as is.
166:      * Array data will be processed with Cake\Network\Http\FormData
167:      *
168:      * @param \Cake\Network\Http\Request $request The request being sent.
169:      * @param array $options Array of options to use.
170:      * @return void
171:      */
172:     protected function _buildContent(Request $request, $options)
173:     {
174:         $content = $request->body();
175:         if (empty($content)) {
176:             return;
177:         }
178:         if (is_string($content)) {
179:             $this->_contextOptions['content'] = $content;
180:             return;
181:         }
182:         if (is_array($content)) {
183:             $formData = new FormData();
184:             $formData->addMany($content);
185:             $type = $formData->contentType();
186:             $request->header('Content-Type', $type);
187:             $this->_contextOptions['content'] = (string)$formData;
188:             return;
189:         }
190:         $this->_contextOptions['content'] = $content;
191:     }
192: 
193:     /**
194:      * Build miscellaneous options for the request.
195:      *
196:      * @param \Cake\Network\Http\Request $request The request being sent.
197:      * @param array $options Array of options to use.
198:      * @return void
199:      */
200:     protected function _buildOptions(Request $request, $options)
201:     {
202:         $this->_contextOptions['method'] = $request->method();
203:         $this->_contextOptions['protocol_version'] = $request->version();
204:         $this->_contextOptions['ignore_errors'] = true;
205: 
206:         if (isset($options['timeout'])) {
207:             $this->_contextOptions['timeout'] = $options['timeout'];
208:         }
209:         if (isset($options['redirect'])) {
210:             $this->_contextOptions['max_redirects'] = (int)$options['redirect'];
211:         }
212:         if (isset($options['proxy']['proxy'])) {
213:             $this->_contextOptions['proxy'] = $options['proxy']['proxy'];
214:         }
215:     }
216: 
217:     /**
218:      * Build SSL options for the request.
219:      *
220:      * @param \Cake\Network\Http\Request $request The request being sent.
221:      * @param array $options Array of options to use.
222:      * @return void
223:      */
224:     protected function _buildSslContext(Request $request, $options)
225:     {
226:         $sslOptions = [
227:             'ssl_verify_peer',
228:             'ssl_verify_depth',
229:             'ssl_allow_self_signed',
230:             'ssl_cafile',
231:             'ssl_local_cert',
232:             'ssl_passphrase',
233:         ];
234:         if (empty($options['ssl_cafile'])) {
235:             $options['ssl_cafile'] = CORE_PATH . 'config' . DS . 'cacert.pem';
236:         }
237:         if (!empty($options['ssl_verify_host'])) {
238:             $url = $request->url();
239:             $host = parse_url($url, PHP_URL_HOST);
240:             $this->_sslContextOptions['peer_name'] = $host;
241:         }
242:         foreach ($sslOptions as $key) {
243:             if (isset($options[$key])) {
244:                 $name = substr($key, 4);
245:                 $this->_sslContextOptions[$name] = $options[$key];
246:             }
247:         }
248:     }
249: 
250:     /**
251:      * Open the stream and send the request.
252:      *
253:      * @param \Cake\Network\Http\Request $request The request object.
254:      * @return array Array of populated Response objects
255:      * @throws \Cake\Core\Exception\Exception
256:      */
257:     protected function _send(Request $request)
258:     {
259:         $url = $request->url();
260:         $this->_open($url);
261:         $content = '';
262:         while (!feof($this->_stream)) {
263:             $content .= fread($this->_stream, 8192);
264:         }
265:         $meta = stream_get_meta_data($this->_stream);
266:         fclose($this->_stream);
267: 
268:         if ($meta['timed_out']) {
269:             throw new Exception('Connection timed out ' . $url);
270:         }
271:         $headers = $meta['wrapper_data'];
272:         if (isset($headers['headers']) && is_array($headers['headers'])) {
273:             $headers = $headers['headers'];
274:         }
275:         return $this->createResponses($headers, $content);
276:     }
277: 
278:     /**
279:      * Open the socket and handle any connection errors.
280:      *
281:      * @param string $url The url to connect to.
282:      * @return void
283:      * @throws \Cake\Core\Exception\Exception
284:      */
285:     protected function _open($url)
286:     {
287:         set_error_handler([$this, '_connectionErrorHandler']);
288:         $this->_stream = fopen($url, 'rb', false, $this->_context);
289:         restore_error_handler();
290: 
291:         if (!$this->_stream || !empty($this->_connectionErrors)) {
292:             throw new Exception(implode("\n", $this->_connectionErrors));
293:         }
294:     }
295: 
296:     /**
297:      * Local error handler to capture errors triggered during
298:      * stream connection.
299:      *
300:      * @param int $code Error code.
301:      * @param string $message Error message.
302:      * @return void
303:      */
304:     protected function _connectionErrorHandler($code, $message)
305:     {
306:         $this->_connectionErrors[] = $message;
307:     }
308: 
309:     /**
310:      * Get the context options
311:      *
312:      * Useful for debugging and testing context creation.
313:      *
314:      * @return array
315:      */
316:     public function contextOptions()
317:     {
318:         return array_merge($this->_contextOptions, $this->_sslContextOptions);
319:     }
320: }
321: 
Follow @CakePHP
#IRC
OpenHub
Rackspace
Rackspace
  • Business Solutions
  • Showcase
  • Documentation
  • Book
  • API
  • Videos
  • Logos & Trademarks
  • Community
  • Team
  • Issues (Github)
  • YouTube Channel
  • Get Involved
  • Bakery
  • Featured Resources
  • Newsletter
  • Certification
  • My CakePHP
  • CakeFest
  • Facebook
  • Twitter
  • Help & Support
  • Forum
  • Stack Overflow
  • IRC
  • Slack
  • Paid Support

Generated using CakePHP API Docs