File: //proc/self/cwd/wp-content/plugins/wp-mail-smtp/vendor_prefixed/google/apiclient/src/Http/Batch.php
<?php
/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
namespace WPMailSMTP\Vendor\Google\Http;
use WPMailSMTP\Vendor\Google\Client;
use WPMailSMTP\Vendor\Google\Service\Exception as GoogleServiceException;
use WPMailSMTP\Vendor\GuzzleHttp\Psr7;
use WPMailSMTP\Vendor\GuzzleHttp\Psr7\Request;
use WPMailSMTP\Vendor\GuzzleHttp\Psr7\Response;
use WPMailSMTP\Vendor\Psr\Http\Message\RequestInterface;
use WPMailSMTP\Vendor\Psr\Http\Message\ResponseInterface;
/**
* Class to handle batched requests to the Google API service.
*
* Note that calls to `Google\Http\Batch::execute()` do not clear the queued
* requests. To start a new batch, be sure to create a new instance of this
* class.
*/
class Batch
{
const BATCH_PATH = 'batch';
private static $CONNECTION_ESTABLISHED_HEADERS = ["HTTP/1.0 200 Connection established\r\n\r\n", "HTTP/1.1 200 Connection established\r\n\r\n"];
/** @var string Multipart Boundary. */
private $boundary;
/** @var array service requests to be executed. */
private $requests = [];
/** @var Client */
private $client;
private $rootUrl;
private $batchPath;
public function __construct(\WPMailSMTP\Vendor\Google\Client $client, $boundary = \false, $rootUrl = null, $batchPath = null)
{
$this->client = $client;
$this->boundary = $boundary ?: \mt_rand();
$this->rootUrl = \rtrim($rootUrl ?: $this->client->getConfig('base_path'), '/');
$this->batchPath = $batchPath ?: self::BATCH_PATH;
}
public function add(\WPMailSMTP\Vendor\Psr\Http\Message\RequestInterface $request, $key = \false)
{
if (\false == $key) {
$key = \mt_rand();
}
$this->requests[$key] = $request;
}
public function execute()
{
$body = '';
$classes = [];
$batchHttpTemplate = <<<EOF
--%s
Content-Type: application/http
Content-Transfer-Encoding: binary
MIME-Version: 1.0
Content-ID: %s
%s
%s%s
EOF;
/** @var RequestInterface $request */
foreach ($this->requests as $key => $request) {
$firstLine = \sprintf('%s %s HTTP/%s', $request->getMethod(), $request->getRequestTarget(), $request->getProtocolVersion());
$content = (string) $request->getBody();
$headers = '';
foreach ($request->getHeaders() as $name => $values) {
$headers .= \sprintf("%s:%s\r\n", $name, \implode(', ', $values));
}
$body .= \sprintf($batchHttpTemplate, $this->boundary, $key, $firstLine, $headers, $content ? "\n" . $content : '');
$classes['response-' . $key] = $request->getHeaderLine('X-Php-Expected-Class');
}
$body .= "--{$this->boundary}--";
$body = \trim($body);
$url = $this->rootUrl . '/' . $this->batchPath;
$headers = ['Content-Type' => \sprintf('multipart/mixed; boundary=%s', $this->boundary), 'Content-Length' => (string) \strlen($body)];
$request = new \WPMailSMTP\Vendor\GuzzleHttp\Psr7\Request('POST', $url, $headers, $body);
$response = $this->client->execute($request);
return $this->parseResponse($response, $classes);
}
public function parseResponse(\WPMailSMTP\Vendor\Psr\Http\Message\ResponseInterface $response, $classes = [])
{
$contentType = $response->getHeaderLine('content-type');
$contentType = \explode(';', $contentType);
$boundary = \false;
foreach ($contentType as $part) {
$part = \explode('=', $part, 2);
if (isset($part[0]) && 'boundary' == \trim($part[0])) {
$boundary = $part[1];
}
}
$body = (string) $response->getBody();
if (!empty($body)) {
$body = \str_replace("--{$boundary}--", "--{$boundary}", $body);
$parts = \explode("--{$boundary}", $body);
$responses = [];
$requests = \array_values($this->requests);
foreach ($parts as $i => $part) {
$part = \trim($part);
if (!empty($part)) {
list($rawHeaders, $part) = \explode("\r\n\r\n", $part, 2);
$headers = $this->parseRawHeaders($rawHeaders);
$status = \substr($part, 0, \strpos($part, "\n"));
$status = \explode(" ", $status);
$status = $status[1];
list($partHeaders, $partBody) = $this->parseHttpResponse($part, 0);
$response = new \WPMailSMTP\Vendor\GuzzleHttp\Psr7\Response((int) $status, $partHeaders, \WPMailSMTP\Vendor\GuzzleHttp\Psr7\Utils::streamFor($partBody));
// Need content id.
$key = $headers['content-id'];
try {
$response = \WPMailSMTP\Vendor\Google\Http\REST::decodeHttpResponse($response, $requests[$i - 1]);
} catch (\WPMailSMTP\Vendor\Google\Service\Exception $e) {
// Store the exception as the response, so successful responses
// can be processed.
$response = $e;
}
$responses[$key] = $response;
}
}
return $responses;
}
return null;
}
private function parseRawHeaders($rawHeaders)
{
$headers = [];
$responseHeaderLines = \explode("\r\n", $rawHeaders);
foreach ($responseHeaderLines as $headerLine) {
if ($headerLine && \strpos($headerLine, ':') !== \false) {
list($header, $value) = \explode(': ', $headerLine, 2);
$header = \strtolower($header);
if (isset($headers[$header])) {
$headers[$header] = \array_merge((array) $headers[$header], (array) $value);
} else {
$headers[$header] = $value;
}
}
}
return $headers;
}
/**
* Used by the IO lib and also the batch processing.
*
* @param string $respData
* @param int $headerSize
* @return array
*/
private function parseHttpResponse($respData, $headerSize)
{
// check proxy header
foreach (self::$CONNECTION_ESTABLISHED_HEADERS as $established_header) {
if (\stripos($respData, $established_header) !== \false) {
// existed, remove it
$respData = \str_ireplace($established_header, '', $respData);
// Subtract the proxy header size unless the cURL bug prior to 7.30.0
// is present which prevented the proxy header size from being taken into
// account.
// @TODO look into this
// if (!$this->needsQuirk()) {
// $headerSize -= strlen($established_header);
// }
break;
}
}
if ($headerSize) {
$responseBody = \substr($respData, $headerSize);
$responseHeaders = \substr($respData, 0, $headerSize);
} else {
$responseSegments = \explode("\r\n\r\n", $respData, 2);
$responseHeaders = $responseSegments[0];
$responseBody = isset($responseSegments[1]) ? $responseSegments[1] : null;
}
$responseHeaders = $this->parseRawHeaders($responseHeaders);
return [$responseHeaders, $responseBody];
}
}