Seditio Source
Root |
./othercms/croogo-4.0.7/vendor/cakephp/cakephp/src/Http/Client/Adapter/Curl.php
<?php
/**
 * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
 * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
 *
 * Licensed under The MIT License
 * Redistributions of files must retain the above copyright notice.
 *
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
 * @link          https://cakephp.org CakePHP(tm) Project
 * @since         3.7.0
 * @license       https://opensource.org/licenses/mit-license.php MIT License
 */
namespace Cake\Http\Client\Adapter;

use
Cake\Http\Client\AdapterInterface;
use
Cake\Http\Client\Request;
use
Cake\Http\Client\Response;
use
Cake\Http\Exception\HttpException;

/**
 * Implements sending Cake\Http\Client\Request via ext/curl.
 *
 * In addition to the standard options documented in Cake\Http\Client,
 * this adapter supports all available curl options. Additional curl options
 * can be set via the `curl` option key when making requests or configuring
 * a client.
 */
class Curl implements AdapterInterface
{
   
/**
     * {@inheritDoc}
     */
   
public function send(Request $request, array $options)
    {
       
$ch = curl_init();
       
$options = $this->buildOptions($request, $options);
       
curl_setopt_array($ch, $options);

       
$body = $this->exec($ch);
        if (
$body === false) {
           
$errorCode = curl_errno($ch);
           
$error = curl_error($ch);
           
curl_close($ch);

           
$status = 500;
            if (
$errorCode === CURLE_OPERATION_TIMEOUTED) {
               
$status = 504;
            }
            throw new
HttpException("cURL Error ({$errorCode}) {$error}", $status);
        }

       
$responses = $this->createResponse($ch, $body);
       
curl_close($ch);

        return
$responses;
    }

   
/**
     * Convert client options into curl options.
     *
     * @param \Cake\Http\Client\Request $request The request.
     * @param array $options The client options
     * @return array
     */
   
public function buildOptions(Request $request, array $options)
    {
       
$headers = [];
        foreach (
$request->getHeaders() as $key => $values) {
           
$headers[] = $key . ': ' . implode(', ', $values);
        }

       
$out = [
           
CURLOPT_URL => (string)$request->getUri(),
           
CURLOPT_HTTP_VERSION => $this->getProtocolVersion($request),
           
CURLOPT_RETURNTRANSFER => true,
           
CURLOPT_HEADER => true,
           
CURLOPT_HTTPHEADER => $headers,
        ];
        switch (
$request->getMethod()) {
            case
Request::METHOD_GET:
               
$out[CURLOPT_HTTPGET] = true;
                break;

            case
Request::METHOD_POST:
               
$out[CURLOPT_POST] = true;
                break;

            default:
               
$out[CURLOPT_POST] = true;
               
$out[CURLOPT_CUSTOMREQUEST] = $request->getMethod();
                break;
        }

       
$body = $request->getBody();
        if (
$body) {
           
$body->rewind();
           
$out[CURLOPT_POSTFIELDS] = $body->getContents();
           
// GET requests with bodies require custom request to be used.
           
if (isset($out[CURLOPT_HTTPGET])) {
               
$out[CURLOPT_CUSTOMREQUEST] = 'get';
            }
        }

        if (empty(
$options['ssl_cafile'])) {
           
$options['ssl_cafile'] = CORE_PATH . 'config' . DIRECTORY_SEPARATOR . 'cacert.pem';
        }
        if (!empty(
$options['ssl_verify_host'])) {
           
// Value of 1 or true is deprecated. Only 2 or 0 should be used now.
           
$options['ssl_verify_host'] = 2;
        }
       
$optionMap = [
           
'timeout' => CURLOPT_TIMEOUT,
           
'ssl_verify_peer' => CURLOPT_SSL_VERIFYPEER,
           
'ssl_verify_host' => CURLOPT_SSL_VERIFYHOST,
           
'ssl_cafile' => CURLOPT_CAINFO,
           
'ssl_local_cert' => CURLOPT_SSLCERT,
           
'ssl_passphrase' => CURLOPT_SSLCERTPASSWD,
        ];
        foreach (
$optionMap as $option => $curlOpt) {
            if (isset(
$options[$option])) {
               
$out[$curlOpt] = $options[$option];
            }
        }
        if (isset(
$options['proxy']['proxy'])) {
           
$out[CURLOPT_PROXY] = $options['proxy']['proxy'];
        }
        if (isset(
$options['proxy']['username'])) {
           
$password = !empty($options['proxy']['password']) ? $options['proxy']['password'] : '';
           
$out[CURLOPT_PROXYUSERPWD] = $options['proxy']['username'] . ':' . $password;
        }
        if (isset(
$options['curl']) && is_array($options['curl'])) {
           
// Can't use array_merge() because keys will be re-ordered.
           
foreach ($options['curl'] as $key => $value) {
               
$out[$key] = $value;
            }
        }

        return
$out;
    }

   
/**
     * Convert HTTP version number into curl value.
     *
     * @param \Cake\Http\Client\Request $request The request to get a protocol version for.
     * @return int
     */
   
protected function getProtocolVersion(Request $request)
    {
        switch (
$request->getProtocolVersion()) {
            case
'1.0':
                return
CURL_HTTP_VERSION_1_0;
            case
'1.1':
                return
CURL_HTTP_VERSION_1_1;
            case
'2':
            case
'2.0':
                if (
defined('CURL_HTTP_VERSION_2TLS')) {
                    return
CURL_HTTP_VERSION_2TLS;
                }
                if (
defined('CURL_HTTP_VERSION_2_0')) {
                    return
CURL_HTTP_VERSION_2_0;
                }
                throw new
HttpException('libcurl 7.33 or greater required for HTTP/2 support');
        }

        return
CURL_HTTP_VERSION_NONE;
    }

   
/**
     * Convert the raw curl response into an Http\Client\Response
     *
     * @param resource $handle Curl handle
     * @param string $responseData string The response data from curl_exec
     * @return \Cake\Http\Client\Response
     */
   
protected function createResponse($handle, $responseData)
    {
       
$headerSize = curl_getinfo($handle, CURLINFO_HEADER_SIZE);
       
$headers = trim(substr($responseData, 0, $headerSize));
       
$body = substr($responseData, $headerSize);
       
$response = new Response(explode("\r\n", $headers), $body);

        return [
$response];
    }

   
/**
     * Execute the curl handle.
     *
     * @param resource $ch Curl Resource handle
     * @return string
     */
   
protected function exec($ch)
    {
        return
curl_exec($ch);
    }
}