Called to process headers from URL being proxied
@param resource $ch The curl connection
@param string $data The header data
@return int length of the data from header
515083
protected function headerCallBack($ch, $data){
        
        if (!is_null($data)) {
                if (preg_match("~^HTTP/.*? 404~", $data)) {
                   
                    header(trim($data));
                    while (ob_get_level() > 0) {
                        ob_end_flush();
                    }
                }

                if (preg_match("~^Content-disposition~", $data)) {
                    header(str_replace("filename=", 'filename="', trim($data)) . '"');
                    while (ob_get_level() > 0) {
                        ob_end_flush();
                    }
                }

                if (preg_match("~^Content-Type~i", $data)) {
                    header(trim($data));
                    while (ob_get_level() > 0) {
                        ob_end_flush();
                    }
                }
            }
            return strlen($data); //This means that we handled it, so cURL will keep processing
    }
652238
protected function executePutMultipart($ch) {
        $xml = $this->request_body;

        $uri_string = $this->file_to_upload[0];
        $file_name = $this->file_to_upload[1];

        $post = array(
            'ResourceDescriptor' => $xml,
            $uri_string => '@' . $file_name . ';filename=' . basename($file_name)
        );

        \curl_setopt($ch, CURLOPT_TIMEOUT, 10);
        \curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
        \curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
        \curl_setopt($ch, CURLOPT_URL, $this->url);
        \curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

        $this->response_body = \curl_exec($ch);
        $this->response_info = \curl_getinfo($ch);

        \curl_close($ch);
    }
683187
protected function execute($ch)
    {
        $response = '';

        // Ensure we never send the "Expect: 100-continue" header
        $this->headerArray[] = 'Expect:';
        curl_setopt($ch, CURLOPT_HTTPHEADER, $this->headerArray);

        $response = curl_exec($ch);
        if ($response === false) {
            $error_msg = "Unable to post request, underlying exception of " . curl_error($ch);
            curl_close($ch);
            throw new \Exception($error_msg);
        } else {
            $this->curlResponseInfo = curl_getinfo($ch);
        }
        curl_close($ch);
        return $response;
    }
479517
private function send_http($url, $data, $headers=[])
    {
        if ($this->curl_method == 'async') {
            $this->_curl_handler->enqueue($url, $data, $headers);
        } elseif ($this->curl_method == 'exec') {
            $this->send_http_asynchronous_curl_exec($url, $data, $headers);
        } else {
            $this->send_http_synchronous($url, $data, $headers);
        }
    }
188190
private function getResponseBodyAndStatusCode($ch)
    {
        $response   = curl_exec($ch);
        $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

        return [$response, $statusCode];
    }
846096
private function parseRetryAfter(string $header): int {
        if (preg_match('#^\d+$#', $header)) {
            return (int) $header;
        }

        $time = @strtotime($header);

        if ($time === false) {
            throw new AcmeException("Invalid retry-after header: '{$header}'");
        }

        return max($time - time(), 0);
    }
751562
function isSkippableCurlHeader(&$data) {
		$skipHeaders = array(	'HTTP/1.1 100',
								'HTTP/1.0 301',
								'HTTP/1.1 301',
								'HTTP/1.0 302',
								'HTTP/1.1 302',
								'HTTP/1.0 401',
								'HTTP/1.1 401',
								'HTTP/1.0 200 Connection established');
		foreach ($skipHeaders as $hd) {
			$prefix = substr($data, 0, strlen($hd));
			if ($prefix == $hd) return true;
		}

		return false;
	}
347753
private static function parseHeaderLine($ch, string $data, array &$info, array &$headers, ?array $options, CurlClientState $multi, int $id, ?string &$location, ?callable $resolveRedirect, ?LoggerInterface $logger): int
    {
        if (!\in_array($waitFor = @curl_getinfo($ch, CURLINFO_PRIVATE), ['headers', 'destruct'], true)) {
            return \strlen($data); // Ignore HTTP trailers
        }

        if ("\r\n" !== $data) {
            // Regular header line: add it to the list
            self::addResponseHeaders([substr($data, 0, -2)], $info, $headers);

            if (0 === strpos($data, 'HTTP') && 300 <= $info['http_code'] && $info['http_code'] < 400) {
                if (curl_getinfo($ch, CURLINFO_REDIRECT_COUNT) === $options['max_redirects']) {
                    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
                } elseif (303 === $info['http_code'] || ('POST' === $info['http_method'] && \in_array($info['http_code'], [301, 302], true))) {
                    $info['http_method'] = 'HEAD' === $info['http_method'] ? 'HEAD' : 'GET';
                    curl_setopt($ch, CURLOPT_POSTFIELDS, '');
                }
            }

            if (0 === stripos($data, 'Location:')) {
                $location = trim(substr($data, 9, -2));
            }

            return \strlen($data);
        }

        // End of headers: handle redirects and add to the activity list
        $statusCode = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
        $info['redirect_url'] = null;

        if (300 <= $statusCode && $statusCode < 400 && null !== $location) {
            $info['redirect_url'] = $resolveRedirect($ch, $location);
            $url = parse_url($location ?? ':');

            if (isset($url['host']) && null !== $ip = $multi->dnsCache->hostnames[$url['host'] = strtolower($url['host'])] ?? null) {
                // Populate DNS cache for redirects if needed
                $port = $url['port'] ?? ('http' === ($url['scheme'] ?? parse_url(curl_getinfo($ch, CURLINFO_EFFECTIVE_URL), PHP_URL_SCHEME)) ? 80 : 443);
                curl_setopt($ch, CURLOPT_RESOLVE, ["{$url['host']}:$port:$ip"]);
                $multi->dnsCache->removals["-{$url['host']}:$port"] = "-{$url['host']}:$port";
            }
        }

        $location = null;

        if ($statusCode < 300 || 400 <= $statusCode || curl_getinfo($ch, CURLINFO_REDIRECT_COUNT) === $options['max_redirects']) {
            // Headers and redirects completed, time to get the response's body
            $multi->handlesActivity[$id] = [new FirstChunk()];

            if ('destruct' === $waitFor) {
                return 0;
            }

            if ($certinfo = curl_getinfo($ch, CURLINFO_CERTINFO)) {
                $info['peer_certificate_chain'] = array_map('openssl_x509_read', array_column($certinfo, 'Cert'));
            }

            curl_setopt($ch, CURLOPT_PRIVATE, 'content');
        } elseif (null !== $info['redirect_url'] && $logger) {
            $logger->info(sprintf('Redirecting: "%s %s"', $info['http_code'], $info['redirect_url']));
        }

        return \strlen($data);
    }
1013426
private static function curlExecFollow($ch, $options, $callback)
    {
        if ($callback) {
            curl_setopt_array(
                $ch,
                [
                    CURLOPT_NOPROGRESS       => false,
                    CURLOPT_PROGRESSFUNCTION => ['self', 'progress']
                ]
            );
        }

        // no open_basedir set, we can proceed normally
        if (!ini_get('open_basedir')) {
            curl_setopt_array($ch, $options['curl']);
            return curl_exec($ch);
        }

        $max_redirects = $options['curl'][CURLOPT_MAXREDIRS] ?? 5;
        $options['curl'][CURLOPT_FOLLOWLOCATION] = false;

        // open_basedir set but no redirects to follow, we can disable followlocation and proceed normally
        curl_setopt_array($ch, $options['curl']);
        if ($max_redirects <= 0) {
            return curl_exec($ch);
        }

        $uri = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
        $rch = curl_copy_handle($ch);

        curl_setopt($rch, CURLOPT_HEADER, true);
        curl_setopt($rch, CURLOPT_NOBODY, true);
        curl_setopt($rch, CURLOPT_FORBID_REUSE, false);
        curl_setopt($rch, CURLOPT_RETURNTRANSFER, true);

        do {
            curl_setopt($rch, CURLOPT_URL, $uri);
            $header = curl_exec($rch);

            if (curl_errno($rch)) {
                $code = 0;
            } else {
                $code = (int)curl_getinfo($rch, CURLINFO_HTTP_CODE);
                if ($code === 301 || $code === 302 || $code === 303) {
                    preg_match('/Location:(.*?)\n/', $header, $matches);
                    $uri = trim(array_pop($matches));
                } else {
                    $code = 0;
                }
            }
        } while ($code && --$max_redirects);

        curl_close($rch);

        if (!$max_redirects) {
            if ($max_redirects === null) {
                trigger_error('Too many redirects. When following redirects, libcurl hit the maximum amount.', E_USER_WARNING);
            }

            return false;
        }

        curl_setopt($ch, CURLOPT_URL, $uri);

        return curl_exec($ch);
    }
1198947
function parse($data)
    {
        $_header = strstr($data, self::HTTP_EOF, true);
        if ($_header === false)
        {
            $this->buffer = $data;
        }
        $header = self::parseHeader($_header);
        if ($header === false)
        {
            $this->isError = true;
        }
        $this->header = $header;
        return $header;
    }
1323783
private function handleResponseHeaders($ch, $header) {
        //$this->count++;
        if (strlen($header) > 2) {
            list($key, $value) = explode(" ", rtrim($header, "\r\n"), 2);
            $key = rtrim($key, ':');
            if (!empty($this->responseHeaders[$key])) {
                if (is_array($this->responseHeaders[$key])){
                    $this->responseHeaders[$key][] = $value;
                } else {
                    $tmp = $this->responseHeaders[$key];
                    $this->responseHeaders[$key] = array();
                    $this->responseHeaders[$key][] = $tmp;
                    $this->responseHeaders[$key][] = $value;

                }
            } else {
                $this->responseHeaders[$key] = $value;
            }
        }
        return strlen($header);
    }
48440
public static function chrToInt(string $chr): int
    {
        if (Binary::safeStrlen($chr) !== 1) {
            throw new \RangeException('Must be a string with a length of 1');
        }
        $result = \unpack('C', $chr);
        return (int) $result[1];
    }
1339760
private function executePut($ch)
    {
        if (!is_string($this->requestBody)) {
            $this->buildPostBody();
        }

        $this->requestLength = strlen($this->requestBody);
        $fh = fopen('php://memory', 'rw');
        fwrite($fh, $this->requestBody);
        rewind($fh);

        curl_setopt($ch, CURLOPT_INFILE, $fh);
        curl_setopt($ch, CURLOPT_INFILESIZE, $this->requestLength);
        curl_setopt($ch, CURLOPT_PUT, true);

        $this->doExecute($ch);

        fclose($fh);
    }
242478
protected function request($url, $data, $headers=array()){
        try{
            $result = $this->validate($url, $data);
            if($result !== true){
                return $result;
            }

            $params = array();
            $authObj = $this->auth();

            if($this->isCloudUser === false){
                $params['access_token'] = $authObj['access_token'];
            }

            // 特殊处理
            $this->proccessRequest($url, $params, $data, $headers);
 
            $headers = $this->getAuthHeaders('POST', $url, $params, $headers);
            $response = $this->client->post($url, $data, $params, $headers);
 
            $obj = $this->proccessResult($response['content']);

            if(!$this->isCloudUser && isset($obj['error_code']) && $obj['error_code'] == 110){
                $authObj = $this->auth(true);
                $params['access_token'] = $authObj['access_token'];
                $response = $this->client->post($url, $data, $params, $headers);
                $obj = $this->proccessResult($response['content']);
            }

            if(empty($obj) || !isset($obj['error_code'])){
                $this->writeAuthObj($authObj);
            }
        }catch(Exception $e){
            return array(
                'error_code' => 'SDK108',
                'error_msg' => 'connection or read data timeout',
            );
        }

        return $obj;
    }
516904
protected function _post($data) {
		$ch = curl_init();
		curl_setopt_array($ch, array(
			CURLOPT_URL            => static::ENDPOINT,
			CURLOPT_POST           => true,
			CURLOPT_POSTFIELDS     => json_encode($data),
			CURLOPT_HEADER         => false,
			CURLOPT_RETURNTRANSFER => true,
			CURLOPT_SSL_VERIFYPEER => true,
			CURLOPT_SSL_VERIFYHOST => 2,
			CURLOPT_FOLLOWLOCATION => false,
			CURLOPT_HTTPHEADER => array('Content-Type: application/json')
		));

		$response = curl_exec($ch);
		curl_close($ch);

		if ($response === false) {
			throw new Exception('Failed to contact BrowserID verification service');
		}

		$decodedResponse = json_decode($response);
		if (!$decodedResponse) {
			throw new Exception('Response is not valid JSON');
		}

		return $decodedResponse;
	}
1371588
function curlRedirectExec()
	{
		static $curl_loops = 0;
		static $curl_max_loops = 20;
		if ($curl_loops++ >= $curl_max_loops) {
			$curl_loops = 0;
			return false;
		}

		curl_setopt($this->ch, CURLOPT_HEADER, true);
		curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true);
		$data = curl_exec($this->ch);
		$lastdata = $data;
		$data = str_replace("\r", '', $data);
		list($header, $data) = explode("\n\n", $data, 2);
		$http_code = curl_getinfo($this->ch, CURLINFO_HTTP_CODE);
		if ($http_code == 301 || $http_code == 302) {
			$matches = array();
			preg_match('/Location:(.*?)\n/', $header, $matches);
			$url = @parse_url(trim(array_pop($matches)));
			if (!$url) {
				//couldn't process the url to redirect to
				$curl_loops = 0;
				return $data;
			}
			/*
			$last_url = parse_url(curl_getinfo($this->ch, CURLINFO_EFFECTIVE_URL));
			if (!$url['scheme']) {
				$url['scheme'] = $last_url['scheme'];
			}
			if (!$url['host']) {
				$url['host'] = $last_url['host'];
			}
			if (!$url['path']) {
				$url['path'] = $last_url['path'];
			}
			*/
			$new_url = $url['scheme'] . '://' . $url['host'] . $url['path'] . ($url['query'] ? '?' . $url['query'] : '');
			curl_setopt($this->ch, CURLOPT_URL, $new_url);
			return $this->curlRedirectExec();
		} else {
			$curl_loops=0;
			return $lastdata;
		}
	}
661071
private static function _checkChunk($data, $header, $rn = "\r\n") {
    if (isset($header['Transfer-Encoding'])) {
      $lrn = strlen($rn);
      $p = strpos($data, $rn, 0);
      $len = hexdec(substr($data, 0, $p));
      $data = substr($data, $p + 2, $len);
    }
    return $data;
  }