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.8 Red Velvet API

  • Overview
  • Tree
  • Deprecated
  • Version:
    • 3.8
      • 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
    • Command
    • Console
      • Exception
    • Controller
      • Component
      • Exception
    • Core
      • Configure
        • Engine
      • Exception
      • Retry
    • Database
      • Driver
      • Exception
      • Expression
      • Schema
      • Statement
      • Type
    • Datasource
      • Exception
    • Error
      • Middleware
    • Event
      • Decorator
    • Filesystem
    • Form
    • Http
      • Client
        • Adapter
        • Auth
      • Cookie
      • Exception
      • Middleware
      • Session
    • I18n
      • Formatter
      • Middleware
      • Parser
    • Log
      • Engine
    • Mailer
      • Exception
      • Transport
    • Network
      • Exception
    • ORM
      • Association
      • Behavior
        • Translate
      • Exception
      • Locator
      • Rule
    • Routing
      • Exception
      • Filter
      • Middleware
      • Route
    • Shell
      • Helper
      • Task
    • TestSuite
      • Fixture
      • Stub
    • Utility
      • Exception
    • Validation
    • View
      • Exception
      • Form
      • Helper
      • Widget
  • None

Classes

  • ActionDispatcher
  • BaseApplication
  • Client
  • ControllerFactory
  • CorsBuilder
  • MiddlewareQueue
  • Response
  • ResponseEmitter
  • Runner
  • Server
  • ServerRequest
  • ServerRequestFactory
  • Session
  1: <?php
  2: /**
  3:  * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
  4:  * Copyright (c) Cake Software Foundation, Inc. (https://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. (https://cakefoundation.org)
 10:  * @link          https://cakephp.org CakePHP(tm) Project
 11:  * @since         3.0.0
 12:  * @license       https://opensource.org/licenses/mit-license.php MIT License
 13:  */
 14: namespace Cake\Http;
 15: 
 16: use Cake\Core\App;
 17: use Cake\Core\Exception\Exception;
 18: use Cake\Core\InstanceConfigTrait;
 19: use Cake\Http\Client\AdapterInterface;
 20: use Cake\Http\Client\Adapter\Curl;
 21: use Cake\Http\Client\Adapter\Stream;
 22: use Cake\Http\Client\Request;
 23: use Cake\Http\Cookie\CookieCollection;
 24: use Cake\Http\Cookie\CookieInterface;
 25: use Cake\Utility\Hash;
 26: use InvalidArgumentException;
 27: use Zend\Diactoros\Uri;
 28: 
 29: /**
 30:  * The end user interface for doing HTTP requests.
 31:  *
 32:  * ### Scoped clients
 33:  *
 34:  * If you're doing multiple requests to the same hostname it's often convenient
 35:  * to use the constructor arguments to create a scoped client. This allows you
 36:  * to keep your code DRY and not repeat hostnames, authentication, and other options.
 37:  *
 38:  * ### Doing requests
 39:  *
 40:  * Once you've created an instance of Client you can do requests
 41:  * using several methods. Each corresponds to a different HTTP method.
 42:  *
 43:  * - get()
 44:  * - post()
 45:  * - put()
 46:  * - delete()
 47:  * - patch()
 48:  *
 49:  * ### Cookie management
 50:  *
 51:  * Client will maintain cookies from the responses done with
 52:  * a client instance. These cookies will be automatically added
 53:  * to future requests to matching hosts. Cookies will respect the
 54:  * `Expires`, `Path` and `Domain` attributes. You can get the client's
 55:  * CookieCollection using cookies()
 56:  *
 57:  * You can use the 'cookieJar' constructor option to provide a custom
 58:  * cookie jar instance you've restored from cache/disk. By default
 59:  * an empty instance of Cake\Http\Client\CookieCollection will be created.
 60:  *
 61:  * ### Sending request bodies
 62:  *
 63:  * By default any POST/PUT/PATCH/DELETE request with $data will
 64:  * send their data as `application/x-www-form-urlencoded` unless
 65:  * there are attached files. In that case `multipart/form-data`
 66:  * will be used.
 67:  *
 68:  * When sending request bodies you can use the `type` option to
 69:  * set the Content-Type for the request:
 70:  *
 71:  * ```
 72:  * $http->get('/users', [], ['type' => 'json']);
 73:  * ```
 74:  *
 75:  * The `type` option sets both the `Content-Type` and `Accept` header, to
 76:  * the same mime type. When using `type` you can use either a full mime
 77:  * type or an alias. If you need different types in the Accept and Content-Type
 78:  * headers you should set them manually and not use `type`
 79:  *
 80:  * ### Using authentication
 81:  *
 82:  * By using the `auth` key you can use authentication. The type sub option
 83:  * can be used to specify which authentication strategy you want to use.
 84:  * CakePHP comes with a few built-in strategies:
 85:  *
 86:  * - Basic
 87:  * - Digest
 88:  * - Oauth
 89:  *
 90:  * ### Using proxies
 91:  *
 92:  * By using the `proxy` key you can set authentication credentials for
 93:  * a proxy if you need to use one. The type sub option can be used to
 94:  * specify which authentication strategy you want to use.
 95:  * CakePHP comes with built-in support for basic authentication.
 96:  */
 97: class Client
 98: {
 99:     use InstanceConfigTrait;
100: 
101:     /**
102:      * Default configuration for the client.
103:      *
104:      * @var array
105:      */
106:     protected $_defaultConfig = [
107:         'adapter' => null,
108:         'host' => null,
109:         'port' => null,
110:         'scheme' => 'http',
111:         'timeout' => 30,
112:         'ssl_verify_peer' => true,
113:         'ssl_verify_peer_name' => true,
114:         'ssl_verify_depth' => 5,
115:         'ssl_verify_host' => true,
116:         'redirect' => false,
117:     ];
118: 
119:     /**
120:      * List of cookies from responses made with this client.
121:      *
122:      * Cookies are indexed by the cookie's domain or
123:      * request host name.
124:      *
125:      * @var \Cake\Http\Cookie\CookieCollection
126:      */
127:     protected $_cookies;
128: 
129:     /**
130:      * Adapter for sending requests.
131:      *
132:      * @var \Cake\Http\Client\AdapterInterface
133:      */
134:     protected $_adapter;
135: 
136:     /**
137:      * Create a new HTTP Client.
138:      *
139:      * ### Config options
140:      *
141:      * You can set the following options when creating a client:
142:      *
143:      * - host - The hostname to do requests on.
144:      * - port - The port to use.
145:      * - scheme - The default scheme/protocol to use. Defaults to http.
146:      * - timeout - The timeout in seconds. Defaults to 30
147:      * - ssl_verify_peer - Whether or not SSL certificates should be validated.
148:      *   Defaults to true.
149:      * - ssl_verify_peer_name - Whether or not peer names should be validated.
150:      *   Defaults to true.
151:      * - ssl_verify_depth - The maximum certificate chain depth to traverse.
152:      *   Defaults to 5.
153:      * - ssl_verify_host - Verify that the certificate and hostname match.
154:      *   Defaults to true.
155:      * - redirect - Number of redirects to follow. Defaults to false.
156:      * - adapter - The adapter class name or instance. Defaults to
157:      *   \Cake\Http\Client\Adapter\Curl if `curl` extension is loaded else
158:      *   \Cake\Http\Client\Adapter\Stream.
159:      *
160:      * @param array $config Config options for scoped clients.
161:      * @throws \InvalidArgumentException
162:      */
163:     public function __construct($config = [])
164:     {
165:         $this->setConfig($config);
166: 
167:         $adapter = $this->_config['adapter'];
168:         if ($adapter === null) {
169:             $adapter = Curl::class;
170: 
171:             if (!extension_loaded('curl')) {
172:                 $adapter = Stream::class;
173:             }
174:         } else {
175:             $this->setConfig('adapter', null);
176:         }
177: 
178:         if (is_string($adapter)) {
179:             $adapter = new $adapter();
180:         }
181: 
182:         if (!$adapter instanceof AdapterInterface) {
183:             throw new InvalidArgumentException('Adapter must be an instance of Cake\Http\Client\AdapterInterface');
184:         }
185:         $this->_adapter = $adapter;
186: 
187:         if (!empty($this->_config['cookieJar'])) {
188:             $this->_cookies = $this->_config['cookieJar'];
189:             $this->setConfig('cookieJar', null);
190:         } else {
191:             $this->_cookies = new CookieCollection();
192:         }
193:     }
194: 
195:     /**
196:      * Get the cookies stored in the Client.
197:      *
198:      * @return \Cake\Http\Cookie\CookieCollection
199:      */
200:     public function cookies()
201:     {
202:         return $this->_cookies;
203:     }
204: 
205:     /**
206:      * Adds a cookie to the Client collection.
207:      *
208:      * @param \Cake\Http\Cookie\CookieInterface $cookie Cookie object.
209:      * @return $this
210:      * @throws \InvalidArgumentException
211:      */
212:     public function addCookie(CookieInterface $cookie)
213:     {
214:         if (!$cookie->getDomain() || !$cookie->getPath()) {
215:             throw new InvalidArgumentException('Cookie must have a domain and a path set.');
216:         }
217:         $this->_cookies = $this->_cookies->add($cookie);
218: 
219:         return $this;
220:     }
221: 
222:     /**
223:      * Do a GET request.
224:      *
225:      * The $data argument supports a special `_content` key
226:      * for providing a request body in a GET request. This is
227:      * generally not used, but services like ElasticSearch use
228:      * this feature.
229:      *
230:      * @param string $url The url or path you want to request.
231:      * @param array $data The query data you want to send.
232:      * @param array $options Additional options for the request.
233:      * @return \Cake\Http\Client\Response
234:      */
235:     public function get($url, $data = [], array $options = [])
236:     {
237:         $options = $this->_mergeOptions($options);
238:         $body = null;
239:         if (isset($data['_content'])) {
240:             $body = $data['_content'];
241:             unset($data['_content']);
242:         }
243:         $url = $this->buildUrl($url, $data, $options);
244: 
245:         return $this->_doRequest(
246:             Request::METHOD_GET,
247:             $url,
248:             $body,
249:             $options
250:         );
251:     }
252: 
253:     /**
254:      * Do a POST request.
255:      *
256:      * @param string $url The url or path you want to request.
257:      * @param mixed $data The post data you want to send.
258:      * @param array $options Additional options for the request.
259:      * @return \Cake\Http\Client\Response
260:      */
261:     public function post($url, $data = [], array $options = [])
262:     {
263:         $options = $this->_mergeOptions($options);
264:         $url = $this->buildUrl($url, [], $options);
265: 
266:         return $this->_doRequest(Request::METHOD_POST, $url, $data, $options);
267:     }
268: 
269:     /**
270:      * Do a PUT request.
271:      *
272:      * @param string $url The url or path you want to request.
273:      * @param mixed $data The request data you want to send.
274:      * @param array $options Additional options for the request.
275:      * @return \Cake\Http\Client\Response
276:      */
277:     public function put($url, $data = [], array $options = [])
278:     {
279:         $options = $this->_mergeOptions($options);
280:         $url = $this->buildUrl($url, [], $options);
281: 
282:         return $this->_doRequest(Request::METHOD_PUT, $url, $data, $options);
283:     }
284: 
285:     /**
286:      * Do a PATCH request.
287:      *
288:      * @param string $url The url or path you want to request.
289:      * @param mixed $data The request data you want to send.
290:      * @param array $options Additional options for the request.
291:      * @return \Cake\Http\Client\Response
292:      */
293:     public function patch($url, $data = [], array $options = [])
294:     {
295:         $options = $this->_mergeOptions($options);
296:         $url = $this->buildUrl($url, [], $options);
297: 
298:         return $this->_doRequest(Request::METHOD_PATCH, $url, $data, $options);
299:     }
300: 
301:     /**
302:      * Do an OPTIONS request.
303:      *
304:      * @param string $url The url or path you want to request.
305:      * @param mixed $data The request data you want to send.
306:      * @param array $options Additional options for the request.
307:      * @return \Cake\Http\Client\Response
308:      */
309:     public function options($url, $data = [], array $options = [])
310:     {
311:         $options = $this->_mergeOptions($options);
312:         $url = $this->buildUrl($url, [], $options);
313: 
314:         return $this->_doRequest(Request::METHOD_OPTIONS, $url, $data, $options);
315:     }
316: 
317:     /**
318:      * Do a TRACE request.
319:      *
320:      * @param string $url The url or path you want to request.
321:      * @param mixed $data The request data you want to send.
322:      * @param array $options Additional options for the request.
323:      * @return \Cake\Http\Client\Response
324:      */
325:     public function trace($url, $data = [], array $options = [])
326:     {
327:         $options = $this->_mergeOptions($options);
328:         $url = $this->buildUrl($url, [], $options);
329: 
330:         return $this->_doRequest(Request::METHOD_TRACE, $url, $data, $options);
331:     }
332: 
333:     /**
334:      * Do a DELETE request.
335:      *
336:      * @param string $url The url or path you want to request.
337:      * @param mixed $data The request data you want to send.
338:      * @param array $options Additional options for the request.
339:      * @return \Cake\Http\Client\Response
340:      */
341:     public function delete($url, $data = [], array $options = [])
342:     {
343:         $options = $this->_mergeOptions($options);
344:         $url = $this->buildUrl($url, [], $options);
345: 
346:         return $this->_doRequest(Request::METHOD_DELETE, $url, $data, $options);
347:     }
348: 
349:     /**
350:      * Do a HEAD request.
351:      *
352:      * @param string $url The url or path you want to request.
353:      * @param array $data The query string data you want to send.
354:      * @param array $options Additional options for the request.
355:      * @return \Cake\Http\Client\Response
356:      */
357:     public function head($url, array $data = [], array $options = [])
358:     {
359:         $options = $this->_mergeOptions($options);
360:         $url = $this->buildUrl($url, $data, $options);
361: 
362:         return $this->_doRequest(Request::METHOD_HEAD, $url, '', $options);
363:     }
364: 
365:     /**
366:      * Helper method for doing non-GET requests.
367:      *
368:      * @param string $method HTTP method.
369:      * @param string $url URL to request.
370:      * @param mixed $data The request body.
371:      * @param array $options The options to use. Contains auth, proxy, etc.
372:      * @return \Cake\Http\Client\Response
373:      */
374:     protected function _doRequest($method, $url, $data, $options)
375:     {
376:         $request = $this->_createRequest(
377:             $method,
378:             $url,
379:             $data,
380:             $options
381:         );
382: 
383:         return $this->send($request, $options);
384:     }
385: 
386:     /**
387:      * Does a recursive merge of the parameter with the scope config.
388:      *
389:      * @param array $options Options to merge.
390:      * @return array Options merged with set config.
391:      */
392:     protected function _mergeOptions($options)
393:     {
394:         return Hash::merge($this->_config, $options);
395:     }
396: 
397:     /**
398:      * Send a request.
399:      *
400:      * Used internally by other methods, but can also be used to send
401:      * handcrafted Request objects.
402:      *
403:      * @param \Cake\Http\Client\Request $request The request to send.
404:      * @param array $options Additional options to use.
405:      * @return \Cake\Http\Client\Response
406:      */
407:     public function send(Request $request, $options = [])
408:     {
409:         $redirects = 0;
410:         if (isset($options['redirect'])) {
411:             $redirects = (int)$options['redirect'];
412:             unset($options['redirect']);
413:         }
414: 
415:         do {
416:             $response = $this->_sendRequest($request, $options);
417: 
418:             $handleRedirect = $response->isRedirect() && $redirects-- > 0;
419:             if ($handleRedirect) {
420:                 $url = $request->getUri();
421: 
422:                 $location = $response->getHeaderLine('Location');
423:                 $locationUrl = $this->buildUrl($location, [], [
424:                     'host' => $url->getHost(),
425:                     'port' => $url->getPort(),
426:                     'scheme' => $url->getScheme(),
427:                     'protocolRelative' => true
428:                 ]);
429:                 $request = $request->withUri(new Uri($locationUrl));
430:                 $request = $this->_cookies->addToRequest($request, []);
431:             }
432:         } while ($handleRedirect);
433: 
434:         return $response;
435:     }
436: 
437:     /**
438:      * Send a request without redirection.
439:      *
440:      * @param \Cake\Http\Client\Request $request The request to send.
441:      * @param array $options Additional options to use.
442:      * @return \Cake\Http\Client\Response
443:      */
444:     protected function _sendRequest(Request $request, $options)
445:     {
446:         $responses = $this->_adapter->send($request, $options);
447:         $url = $request->getUri();
448:         foreach ($responses as $response) {
449:             $this->_cookies = $this->_cookies->addFromResponse($response, $request);
450:         }
451: 
452:         return array_pop($responses);
453:     }
454: 
455:     /**
456:      * Generate a URL based on the scoped client options.
457:      *
458:      * @param string $url Either a full URL or just the path.
459:      * @param string|array $query The query data for the URL.
460:      * @param array $options The config options stored with Client::config()
461:      * @return string A complete url with scheme, port, host, and path.
462:      */
463:     public function buildUrl($url, $query = [], $options = [])
464:     {
465:         if (empty($options) && empty($query)) {
466:             return $url;
467:         }
468:         if ($query) {
469:             $q = (strpos($url, '?') === false) ? '?' : '&';
470:             $url .= $q;
471:             $url .= is_string($query) ? $query : http_build_query($query);
472:         }
473:         $defaults = [
474:             'host' => null,
475:             'port' => null,
476:             'scheme' => 'http',
477:             'protocolRelative' => false
478:         ];
479:         $options += $defaults;
480: 
481:         if ($options['protocolRelative'] && preg_match('#^//#', $url)) {
482:             $url = $options['scheme'] . ':' . $url;
483:         }
484:         if (preg_match('#^https?://#', $url)) {
485:             return $url;
486:         }
487: 
488:         $defaultPorts = [
489:             'http' => 80,
490:             'https' => 443
491:         ];
492:         $out = $options['scheme'] . '://' . $options['host'];
493:         if ($options['port'] && $options['port'] != $defaultPorts[$options['scheme']]) {
494:             $out .= ':' . $options['port'];
495:         }
496:         $out .= '/' . ltrim($url, '/');
497: 
498:         return $out;
499:     }
500: 
501:     /**
502:      * Creates a new request object based on the parameters.
503:      *
504:      * @param string $method HTTP method name.
505:      * @param string $url The url including query string.
506:      * @param mixed $data The request body.
507:      * @param array $options The options to use. Contains auth, proxy, etc.
508:      * @return \Cake\Http\Client\Request
509:      */
510:     protected function _createRequest($method, $url, $data, $options)
511:     {
512:         $headers = isset($options['headers']) ? (array)$options['headers'] : [];
513:         if (isset($options['type'])) {
514:             $headers = array_merge($headers, $this->_typeHeaders($options['type']));
515:         }
516:         if (is_string($data) && !isset($headers['Content-Type']) && !isset($headers['content-type'])) {
517:             $headers['Content-Type'] = 'application/x-www-form-urlencoded';
518:         }
519: 
520:         $request = new Request($url, $method, $headers, $data);
521:         $cookies = isset($options['cookies']) ? $options['cookies'] : [];
522:         /** @var \Cake\Http\Client\Request $request */
523:         $request = $this->_cookies->addToRequest($request, $cookies);
524:         if (isset($options['auth'])) {
525:             $request = $this->_addAuthentication($request, $options);
526:         }
527:         if (isset($options['proxy'])) {
528:             $request = $this->_addProxy($request, $options);
529:         }
530: 
531:         return $request;
532:     }
533: 
534:     /**
535:      * Returns headers for Accept/Content-Type based on a short type
536:      * or full mime-type.
537:      *
538:      * @param string $type short type alias or full mimetype.
539:      * @return array Headers to set on the request.
540:      * @throws \Cake\Core\Exception\Exception When an unknown type alias is used.
541:      */
542:     protected function _typeHeaders($type)
543:     {
544:         if (strpos($type, '/') !== false) {
545:             return [
546:                 'Accept' => $type,
547:                 'Content-Type' => $type
548:             ];
549:         }
550:         $typeMap = [
551:             'json' => 'application/json',
552:             'xml' => 'application/xml',
553:         ];
554:         if (!isset($typeMap[$type])) {
555:             throw new Exception("Unknown type alias '$type'.");
556:         }
557: 
558:         return [
559:             'Accept' => $typeMap[$type],
560:             'Content-Type' => $typeMap[$type],
561:         ];
562:     }
563: 
564:     /**
565:      * Add authentication headers to the request.
566:      *
567:      * Uses the authentication type to choose the correct strategy
568:      * and use its methods to add headers.
569:      *
570:      * @param \Cake\Http\Client\Request $request The request to modify.
571:      * @param array $options Array of options containing the 'auth' key.
572:      * @return \Cake\Http\Client\Request The updated request object.
573:      */
574:     protected function _addAuthentication(Request $request, $options)
575:     {
576:         $auth = $options['auth'];
577:         $adapter = $this->_createAuth($auth, $options);
578:         $result = $adapter->authentication($request, $options['auth']);
579: 
580:         return $result ?: $request;
581:     }
582: 
583:     /**
584:      * Add proxy authentication headers.
585:      *
586:      * Uses the authentication type to choose the correct strategy
587:      * and use its methods to add headers.
588:      *
589:      * @param \Cake\Http\Client\Request $request The request to modify.
590:      * @param array $options Array of options containing the 'proxy' key.
591:      * @return \Cake\Http\Client\Request The updated request object.
592:      */
593:     protected function _addProxy(Request $request, $options)
594:     {
595:         $auth = $options['proxy'];
596:         $adapter = $this->_createAuth($auth, $options);
597:         $result = $adapter->proxyAuthentication($request, $options['proxy']);
598: 
599:         return $result ?: $request;
600:     }
601: 
602:     /**
603:      * Create the authentication strategy.
604:      *
605:      * Use the configuration options to create the correct
606:      * authentication strategy handler.
607:      *
608:      * @param array $auth The authentication options to use.
609:      * @param array $options The overall request options to use.
610:      * @return object Authentication strategy instance.
611:      * @throws \Cake\Core\Exception\Exception when an invalid strategy is chosen.
612:      */
613:     protected function _createAuth($auth, $options)
614:     {
615:         if (empty($auth['type'])) {
616:             $auth['type'] = 'basic';
617:         }
618:         $name = ucfirst($auth['type']);
619:         $class = App::className($name, 'Http/Client/Auth');
620:         if (!$class) {
621:             throw new Exception(
622:                 sprintf('Invalid authentication type %s', $name)
623:             );
624:         }
625: 
626:         return new $class($this, $options);
627:     }
628: }
629: // @deprecated 3.4.0 Backwards compatibility with earler 3.x versions.
630: class_alias('Cake\Http\Client', 'Cake\Network\Http\Client');
631: 
Follow @CakePHP
#IRC
OpenHub
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