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

  • Overview
  • Tree
  • Deprecated
  • Version:
    • 3.7
      • 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:      */
162:     public function __construct($config = [])
163:     {
164:         $this->setConfig($config);
165: 
166:         $adapter = $this->_config['adapter'];
167:         if ($adapter === null) {
168:             $adapter = Curl::class;
169: 
170:             if (!extension_loaded('curl')) {
171:                 $adapter = Stream::class;
172:             }
173:         } else {
174:             $this->setConfig('adapter', null);
175:         }
176: 
177:         if (is_string($adapter)) {
178:             $adapter = new $adapter();
179:         }
180: 
181:         if (!$adapter instanceof AdapterInterface) {
182:             throw new InvalidArgumentException('Adapter must be an instance of Cake\Http\Client\AdapterInterface');
183:         }
184:         $this->_adapter = $adapter;
185: 
186:         if (!empty($this->_config['cookieJar'])) {
187:             $this->_cookies = $this->_config['cookieJar'];
188:             $this->setConfig('cookieJar', null);
189:         } else {
190:             $this->_cookies = new CookieCollection();
191:         }
192:     }
193: 
194:     /**
195:      * Get the cookies stored in the Client.
196:      *
197:      * @return \Cake\Http\Cookie\CookieCollection
198:      */
199:     public function cookies()
200:     {
201:         return $this->_cookies;
202:     }
203: 
204:     /**
205:      * Adds a cookie to the Client collection.
206:      *
207:      * @param \Cake\Http\Cookie\CookieInterface $cookie Cookie object.
208:      * @return $this
209:      */
210:     public function addCookie(CookieInterface $cookie)
211:     {
212:         if (!$cookie->getDomain() || !$cookie->getPath()) {
213:             throw new InvalidArgumentException('Cookie must have a domain and a path set.');
214:         }
215:         $this->_cookies = $this->_cookies->add($cookie);
216: 
217:         return $this;
218:     }
219: 
220:     /**
221:      * Do a GET request.
222:      *
223:      * The $data argument supports a special `_content` key
224:      * for providing a request body in a GET request. This is
225:      * generally not used, but services like ElasticSearch use
226:      * this feature.
227:      *
228:      * @param string $url The url or path you want to request.
229:      * @param array $data The query data you want to send.
230:      * @param array $options Additional options for the request.
231:      * @return \Cake\Http\Client\Response
232:      */
233:     public function get($url, $data = [], array $options = [])
234:     {
235:         $options = $this->_mergeOptions($options);
236:         $body = null;
237:         if (isset($data['_content'])) {
238:             $body = $data['_content'];
239:             unset($data['_content']);
240:         }
241:         $url = $this->buildUrl($url, $data, $options);
242: 
243:         return $this->_doRequest(
244:             Request::METHOD_GET,
245:             $url,
246:             $body,
247:             $options
248:         );
249:     }
250: 
251:     /**
252:      * Do a POST request.
253:      *
254:      * @param string $url The url or path you want to request.
255:      * @param mixed $data The post data you want to send.
256:      * @param array $options Additional options for the request.
257:      * @return \Cake\Http\Client\Response
258:      */
259:     public function post($url, $data = [], array $options = [])
260:     {
261:         $options = $this->_mergeOptions($options);
262:         $url = $this->buildUrl($url, [], $options);
263: 
264:         return $this->_doRequest(Request::METHOD_POST, $url, $data, $options);
265:     }
266: 
267:     /**
268:      * Do a PUT request.
269:      *
270:      * @param string $url The url or path you want to request.
271:      * @param mixed $data The request data you want to send.
272:      * @param array $options Additional options for the request.
273:      * @return \Cake\Http\Client\Response
274:      */
275:     public function put($url, $data = [], array $options = [])
276:     {
277:         $options = $this->_mergeOptions($options);
278:         $url = $this->buildUrl($url, [], $options);
279: 
280:         return $this->_doRequest(Request::METHOD_PUT, $url, $data, $options);
281:     }
282: 
283:     /**
284:      * Do a PATCH request.
285:      *
286:      * @param string $url The url or path you want to request.
287:      * @param mixed $data The request data you want to send.
288:      * @param array $options Additional options for the request.
289:      * @return \Cake\Http\Client\Response
290:      */
291:     public function patch($url, $data = [], array $options = [])
292:     {
293:         $options = $this->_mergeOptions($options);
294:         $url = $this->buildUrl($url, [], $options);
295: 
296:         return $this->_doRequest(Request::METHOD_PATCH, $url, $data, $options);
297:     }
298: 
299:     /**
300:      * Do an OPTIONS request.
301:      *
302:      * @param string $url The url or path you want to request.
303:      * @param mixed $data The request data you want to send.
304:      * @param array $options Additional options for the request.
305:      * @return \Cake\Http\Client\Response
306:      */
307:     public function options($url, $data = [], array $options = [])
308:     {
309:         $options = $this->_mergeOptions($options);
310:         $url = $this->buildUrl($url, [], $options);
311: 
312:         return $this->_doRequest(Request::METHOD_OPTIONS, $url, $data, $options);
313:     }
314: 
315:     /**
316:      * Do a TRACE request.
317:      *
318:      * @param string $url The url or path you want to request.
319:      * @param mixed $data The request data you want to send.
320:      * @param array $options Additional options for the request.
321:      * @return \Cake\Http\Client\Response
322:      */
323:     public function trace($url, $data = [], array $options = [])
324:     {
325:         $options = $this->_mergeOptions($options);
326:         $url = $this->buildUrl($url, [], $options);
327: 
328:         return $this->_doRequest(Request::METHOD_TRACE, $url, $data, $options);
329:     }
330: 
331:     /**
332:      * Do a DELETE request.
333:      *
334:      * @param string $url The url or path you want to request.
335:      * @param mixed $data The request data you want to send.
336:      * @param array $options Additional options for the request.
337:      * @return \Cake\Http\Client\Response
338:      */
339:     public function delete($url, $data = [], array $options = [])
340:     {
341:         $options = $this->_mergeOptions($options);
342:         $url = $this->buildUrl($url, [], $options);
343: 
344:         return $this->_doRequest(Request::METHOD_DELETE, $url, $data, $options);
345:     }
346: 
347:     /**
348:      * Do a HEAD request.
349:      *
350:      * @param string $url The url or path you want to request.
351:      * @param array $data The query string data you want to send.
352:      * @param array $options Additional options for the request.
353:      * @return \Cake\Http\Client\Response
354:      */
355:     public function head($url, array $data = [], array $options = [])
356:     {
357:         $options = $this->_mergeOptions($options);
358:         $url = $this->buildUrl($url, $data, $options);
359: 
360:         return $this->_doRequest(Request::METHOD_HEAD, $url, '', $options);
361:     }
362: 
363:     /**
364:      * Helper method for doing non-GET requests.
365:      *
366:      * @param string $method HTTP method.
367:      * @param string $url URL to request.
368:      * @param mixed $data The request body.
369:      * @param array $options The options to use. Contains auth, proxy, etc.
370:      * @return \Cake\Http\Client\Response
371:      */
372:     protected function _doRequest($method, $url, $data, $options)
373:     {
374:         $request = $this->_createRequest(
375:             $method,
376:             $url,
377:             $data,
378:             $options
379:         );
380: 
381:         return $this->send($request, $options);
382:     }
383: 
384:     /**
385:      * Does a recursive merge of the parameter with the scope config.
386:      *
387:      * @param array $options Options to merge.
388:      * @return array Options merged with set config.
389:      */
390:     protected function _mergeOptions($options)
391:     {
392:         return Hash::merge($this->_config, $options);
393:     }
394: 
395:     /**
396:      * Send a request.
397:      *
398:      * Used internally by other methods, but can also be used to send
399:      * handcrafted Request objects.
400:      *
401:      * @param \Cake\Http\Client\Request $request The request to send.
402:      * @param array $options Additional options to use.
403:      * @return \Cake\Http\Client\Response
404:      */
405:     public function send(Request $request, $options = [])
406:     {
407:         $redirects = 0;
408:         if (isset($options['redirect'])) {
409:             $redirects = (int)$options['redirect'];
410:             unset($options['redirect']);
411:         }
412: 
413:         do {
414:             $response = $this->_sendRequest($request, $options);
415: 
416:             $handleRedirect = $response->isRedirect() && $redirects-- > 0;
417:             if ($handleRedirect) {
418:                 $url = $request->getUri();
419:                 $request = $this->_cookies->addToRequest($request, []);
420: 
421:                 $location = $response->getHeaderLine('Location');
422:                 $locationUrl = $this->buildUrl($location, [], [
423:                     'host' => $url->getHost(),
424:                     'port' => $url->getPort(),
425:                     'scheme' => $url->getScheme(),
426:                     'protocolRelative' => true
427:                 ]);
428: 
429:                 $request = $request->withUri(new Uri($locationUrl));
430:             }
431:         } while ($handleRedirect);
432: 
433:         return $response;
434:     }
435: 
436:     /**
437:      * Send a request without redirection.
438:      *
439:      * @param \Cake\Http\Client\Request $request The request to send.
440:      * @param array $options Additional options to use.
441:      * @return \Cake\Http\Client\Response
442:      */
443:     protected function _sendRequest(Request $request, $options)
444:     {
445:         $responses = $this->_adapter->send($request, $options);
446:         $url = $request->getUri();
447:         foreach ($responses as $response) {
448:             $this->_cookies = $this->_cookies->addFromResponse($response, $request);
449:         }
450: 
451:         return array_pop($responses);
452:     }
453: 
454:     /**
455:      * Generate a URL based on the scoped client options.
456:      *
457:      * @param string $url Either a full URL or just the path.
458:      * @param string|array $query The query data for the URL.
459:      * @param array $options The config options stored with Client::config()
460:      * @return string A complete url with scheme, port, host, and path.
461:      */
462:     public function buildUrl($url, $query = [], $options = [])
463:     {
464:         if (empty($options) && empty($query)) {
465:             return $url;
466:         }
467:         if ($query) {
468:             $q = (strpos($url, '?') === false) ? '?' : '&';
469:             $url .= $q;
470:             $url .= is_string($query) ? $query : http_build_query($query);
471:         }
472:         $defaults = [
473:             'host' => null,
474:             'port' => null,
475:             'scheme' => 'http',
476:             'protocolRelative' => false
477:         ];
478:         $options += $defaults;
479: 
480:         if ($options['protocolRelative'] && preg_match('#^//#', $url)) {
481:             $url = $options['scheme'] . ':' . $url;
482:         }
483:         if (preg_match('#^https?://#', $url)) {
484:             return $url;
485:         }
486: 
487:         $defaultPorts = [
488:             'http' => 80,
489:             'https' => 443
490:         ];
491:         $out = $options['scheme'] . '://' . $options['host'];
492:         if ($options['port'] && $options['port'] != $defaultPorts[$options['scheme']]) {
493:             $out .= ':' . $options['port'];
494:         }
495:         $out .= '/' . ltrim($url, '/');
496: 
497:         return $out;
498:     }
499: 
500:     /**
501:      * Creates a new request object based on the parameters.
502:      *
503:      * @param string $method HTTP method name.
504:      * @param string $url The url including query string.
505:      * @param mixed $data The request body.
506:      * @param array $options The options to use. Contains auth, proxy, etc.
507:      * @return \Cake\Http\Client\Request
508:      */
509:     protected function _createRequest($method, $url, $data, $options)
510:     {
511:         $headers = isset($options['headers']) ? (array)$options['headers'] : [];
512:         if (isset($options['type'])) {
513:             $headers = array_merge($headers, $this->_typeHeaders($options['type']));
514:         }
515:         if (is_string($data) && !isset($headers['Content-Type']) && !isset($headers['content-type'])) {
516:             $headers['Content-Type'] = 'application/x-www-form-urlencoded';
517:         }
518: 
519:         $request = new Request($url, $method, $headers, $data);
520:         $cookies = isset($options['cookies']) ? $options['cookies'] : [];
521:         /** @var \Cake\Http\Client\Request $request */
522:         $request = $this->_cookies->addToRequest($request, $cookies);
523:         if (isset($options['auth'])) {
524:             $request = $this->_addAuthentication($request, $options);
525:         }
526:         if (isset($options['proxy'])) {
527:             $request = $this->_addProxy($request, $options);
528:         }
529: 
530:         return $request;
531:     }
532: 
533:     /**
534:      * Returns headers for Accept/Content-Type based on a short type
535:      * or full mime-type.
536:      *
537:      * @param string $type short type alias or full mimetype.
538:      * @return array Headers to set on the request.
539:      * @throws \Cake\Core\Exception\Exception When an unknown type alias is used.
540:      */
541:     protected function _typeHeaders($type)
542:     {
543:         if (strpos($type, '/') !== false) {
544:             return [
545:                 'Accept' => $type,
546:                 'Content-Type' => $type
547:             ];
548:         }
549:         $typeMap = [
550:             'json' => 'application/json',
551:             'xml' => 'application/xml',
552:         ];
553:         if (!isset($typeMap[$type])) {
554:             throw new Exception("Unknown type alias '$type'.");
555:         }
556: 
557:         return [
558:             'Accept' => $typeMap[$type],
559:             'Content-Type' => $typeMap[$type],
560:         ];
561:     }
562: 
563:     /**
564:      * Add authentication headers to the request.
565:      *
566:      * Uses the authentication type to choose the correct strategy
567:      * and use its methods to add headers.
568:      *
569:      * @param \Cake\Http\Client\Request $request The request to modify.
570:      * @param array $options Array of options containing the 'auth' key.
571:      * @return \Cake\Http\Client\Request The updated request object.
572:      */
573:     protected function _addAuthentication(Request $request, $options)
574:     {
575:         $auth = $options['auth'];
576:         $adapter = $this->_createAuth($auth, $options);
577:         $result = $adapter->authentication($request, $options['auth']);
578: 
579:         return $result ?: $request;
580:     }
581: 
582:     /**
583:      * Add proxy authentication headers.
584:      *
585:      * Uses the authentication type to choose the correct strategy
586:      * and use its methods to add headers.
587:      *
588:      * @param \Cake\Http\Client\Request $request The request to modify.
589:      * @param array $options Array of options containing the 'proxy' key.
590:      * @return \Cake\Http\Client\Request The updated request object.
591:      */
592:     protected function _addProxy(Request $request, $options)
593:     {
594:         $auth = $options['proxy'];
595:         $adapter = $this->_createAuth($auth, $options);
596:         $result = $adapter->proxyAuthentication($request, $options['proxy']);
597: 
598:         return $result ?: $request;
599:     }
600: 
601:     /**
602:      * Create the authentication strategy.
603:      *
604:      * Use the configuration options to create the correct
605:      * authentication strategy handler.
606:      *
607:      * @param array $auth The authentication options to use.
608:      * @param array $options The overall request options to use.
609:      * @return mixed Authentication strategy instance.
610:      * @throws \Cake\Core\Exception\Exception when an invalid strategy is chosen.
611:      */
612:     protected function _createAuth($auth, $options)
613:     {
614:         if (empty($auth['type'])) {
615:             $auth['type'] = 'basic';
616:         }
617:         $name = ucfirst($auth['type']);
618:         $class = App::className($name, 'Http/Client/Auth');
619:         if (!$class) {
620:             throw new Exception(
621:                 sprintf('Invalid authentication type %s', $name)
622:             );
623:         }
624: 
625:         return new $class($this, $options);
626:     }
627: }
628: // @deprecated 3.4.0 Backwards compatibility with earler 3.x versions.
629: class_alias('Cake\Http\Client', 'Cake\Network\Http\Client');
630: 
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