PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 2.4.4
Booking for Appointments and Events Calendar – Amelia v2.4.4
2.4.4 2.4.3 2.4.2 2.4.1 2.4 trunk 1.2.1 1.2.10 1.2.11 1.2.12 1.2.13 1.2.14 1.2.15 1.2.16 1.2.17 1.2.18 1.2.19 1.2.2 1.2.20 1.2.21 1.2.22 1.2.23 1.2.24 1.2.25 1.2.26 1.2.27 1.2.28 1.2.29 1.2.3 1.2.30 1.2.31 1.2.32 1.2.33 1.2.34 1.2.35 1.2.36 1.2.37 1.2.38 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 2.0 2.0.1 2.0.2 2.1 2.1.1 2.1.2 2.1.3 2.2 2.2.1 2.3
ameliabooking / vendor / google / apiclient / src / Http / Batch.php
ameliabooking / vendor / google / apiclient / src / Http Last commit date
Batch.php 6 months ago MediaFileUpload.php 6 months ago REST.php 6 months ago
Batch.php
262 lines
1 <?php
2 /*
3 * Copyright 2012 Google Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 namespace AmeliaVendor\Google\Http;
19
20 use AmeliaVendor\Google\Client;
21 use AmeliaVendor\Google\Service\Exception as GoogleServiceException;
22 use AmeliaVendor\GuzzleHttp\Psr7;
23 use AmeliaVendor\GuzzleHttp\Psr7\Request;
24 use AmeliaVendor\GuzzleHttp\Psr7\Response;
25 use AmeliaVendor\Psr\Http\Message\RequestInterface;
26 use AmeliaVendor\Psr\Http\Message\ResponseInterface;
27
28 /**
29 * Class to handle batched requests to the Google API service.
30 *
31 * Note that calls to `Google\Http\Batch::execute()` do not clear the queued
32 * requests. To start a new batch, be sure to create a new instance of this
33 * class.
34 */
35 class Batch
36 {
37 const BATCH_PATH = 'batch';
38
39 private static $CONNECTION_ESTABLISHED_HEADERS = [
40 "HTTP/1.0 200 Connection established\r\n\r\n",
41 "HTTP/1.1 200 Connection established\r\n\r\n",
42 ];
43
44 /** @var string Multipart Boundary. */
45 private $boundary;
46
47 /** @var array service requests to be executed. */
48 private $requests = [];
49
50 /** @var Client */
51 private $client;
52
53 private $rootUrl;
54
55 private $batchPath;
56
57 public function __construct(
58 Client $client,
59 $boundary = false,
60 $rootUrl = null,
61 $batchPath = null
62 ) {
63 $this->client = $client;
64 $this->boundary = $boundary ?: mt_rand();
65 $rootUrl = rtrim($rootUrl ?: $this->client->getConfig('base_path'), '/');
66 $this->rootUrl = str_replace(
67 'UNIVERSE_DOMAIN',
68 $this->client->getUniverseDomain(),
69 $rootUrl
70 );
71 $this->batchPath = $batchPath ?: self::BATCH_PATH;
72 }
73
74 public function add(RequestInterface $request, $key = false)
75 {
76 if (false == $key) {
77 $key = mt_rand();
78 }
79
80 $this->requests[$key] = $request;
81 }
82
83 public function execute()
84 {
85 $body = '';
86 $classes = [];
87 $batchHttpTemplate = <<<EOF
88 --%s
89 Content-Type: application/http
90 Content-Transfer-Encoding: binary
91 MIME-Version: 1.0
92 Content-ID: %s
93
94 %s
95 %s%s
96
97
98 EOF;
99
100 /** @var RequestInterface $request */
101 foreach ($this->requests as $key => $request) {
102 $firstLine = sprintf(
103 '%s %s HTTP/%s',
104 $request->getMethod(),
105 $request->getRequestTarget(),
106 $request->getProtocolVersion()
107 );
108
109 $content = (string) $request->getBody();
110
111 $headers = '';
112 foreach ($request->getHeaders() as $name => $values) {
113 $headers .= sprintf("%s:%s\r\n", $name, implode(', ', $values));
114 }
115
116 $body .= sprintf(
117 $batchHttpTemplate,
118 $this->boundary,
119 $key,
120 $firstLine,
121 $headers,
122 $content ? "\n" . $content : ''
123 );
124
125 $classes['response-' . $key] = $request->getHeaderLine('X-Php-Expected-Class');
126 }
127
128 $body .= "--{$this->boundary}--";
129 $body = trim($body);
130 $url = $this->rootUrl . '/' . $this->batchPath;
131 $headers = [
132 'Content-Type' => sprintf('multipart/mixed; boundary=%s', $this->boundary),
133 'Content-Length' => (string) strlen($body),
134 ];
135
136 $request = new Request(
137 'POST',
138 $url,
139 $headers,
140 $body
141 );
142
143 $response = $this->client->execute($request);
144
145 return $this->parseResponse($response, $classes);
146 }
147
148 public function parseResponse(ResponseInterface $response, $classes = [])
149 {
150 $contentType = $response->getHeaderLine('content-type');
151 $contentType = explode(';', $contentType);
152 $boundary = false;
153 foreach ($contentType as $part) {
154 $part = explode('=', $part, 2);
155 if (isset($part[0]) && 'boundary' == trim($part[0])) {
156 $boundary = $part[1];
157 }
158 }
159
160 $body = (string) $response->getBody();
161 if (!empty($body)) {
162 $body = str_replace("--$boundary--", "--$boundary", $body);
163 $parts = explode("--$boundary", $body);
164 $responses = [];
165 $requests = array_values($this->requests);
166
167 foreach ($parts as $i => $part) {
168 $part = trim($part);
169 if (!empty($part)) {
170 list($rawHeaders, $part) = explode("\r\n\r\n", $part, 2);
171 $headers = $this->parseRawHeaders($rawHeaders);
172
173 $status = substr($part, 0, strpos($part, "\n"));
174 $status = explode(" ", $status);
175 $status = $status[1];
176
177 list($partHeaders, $partBody) = $this->parseHttpResponse($part, 0);
178 $response = new Response(
179 (int) $status,
180 $partHeaders,
181 Psr7\Utils::streamFor($partBody)
182 );
183
184 // Need content id.
185 $key = $headers['content-id'];
186
187 try {
188 $response = REST::decodeHttpResponse($response, $requests[$i-1]);
189 } catch (GoogleServiceException $e) {
190 // Store the exception as the response, so successful responses
191 // can be processed.
192 $response = $e;
193 }
194
195 $responses[$key] = $response;
196 }
197 }
198
199 return $responses;
200 }
201
202 return null;
203 }
204
205 private function parseRawHeaders($rawHeaders)
206 {
207 $headers = [];
208 $responseHeaderLines = explode("\r\n", $rawHeaders);
209 foreach ($responseHeaderLines as $headerLine) {
210 if ($headerLine && strpos($headerLine, ':') !== false) {
211 list($header, $value) = explode(': ', $headerLine, 2);
212 $header = strtolower($header);
213 if (isset($headers[$header])) {
214 $headers[$header] = array_merge((array)$headers[$header], (array)$value);
215 } else {
216 $headers[$header] = $value;
217 }
218 }
219 }
220 return $headers;
221 }
222
223 /**
224 * Used by the IO lib and also the batch processing.
225 *
226 * @param string $respData
227 * @param int $headerSize
228 * @return array
229 */
230 private function parseHttpResponse($respData, $headerSize)
231 {
232 // check proxy header
233 foreach (self::$CONNECTION_ESTABLISHED_HEADERS as $established_header) {
234 if (stripos($respData, $established_header) !== false) {
235 // existed, remove it
236 $respData = str_ireplace($established_header, '', $respData);
237 // Subtract the proxy header size unless the cURL bug prior to 7.30.0
238 // is present which prevented the proxy header size from being taken into
239 // account.
240 // @TODO look into this
241 // if (!$this->needsQuirk()) {
242 // $headerSize -= strlen($established_header);
243 // }
244 break;
245 }
246 }
247
248 if ($headerSize) {
249 $responseBody = substr($respData, $headerSize);
250 $responseHeaders = substr($respData, 0, $headerSize);
251 } else {
252 $responseSegments = explode("\r\n\r\n", $respData, 2);
253 $responseHeaders = $responseSegments[0];
254 $responseBody = isset($responseSegments[1]) ? $responseSegments[1] : null;
255 }
256
257 $responseHeaders = $this->parseRawHeaders($responseHeaders);
258
259 return [$responseHeaders, $responseBody];
260 }
261 }
262