PluginProbe
WP-Stateless – Google Cloud Storage / 2.2.1
WP-Stateless – Google Cloud Storage v2.2.1
4.4.3 2.1.7 2.1.8 2.1.9 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.2.7 2.3.0 2.3.1 2.3.2 3.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.2.0 3.2.1 3.2.2 All 62 releases
wp-stateless / lib / Google / src / Google / Http / Batch.php

Batch.php in WP-Stateless – Google Cloud Storage 2.2.1, at lib/Google/src/Google/Http/Batch.php

251 lines 6.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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 namespace wpCloud\StatelessMedia\Google_Client;
18
19 use GuzzleHttp\Psr7;
20 use GuzzleHttp\Psr7\Request;
21 use GuzzleHttp\Psr7\Response;
22 use Psr\Http\Message\RequestInterface;
23 use Psr\Http\Message\ResponseInterface;
24
25 /**
26 * Class to handle batched requests to the Google API service.
27 */
28 class Google_Http_Batch
29 {
30 const BATCH_PATH = 'batch';
31
32 private static $CONNECTION_ESTABLISHED_HEADERS = array(
33 "HTTP/1.0 200 Connection established\r\n\r\n",
34 "HTTP/1.1 200 Connection established\r\n\r\n",
35 );
36
37 /** @var string Multipart Boundary. */
38 private $boundary;
39
40 /** @var array service requests to be executed. */
41 private $requests = array();
42
43 /** @var Google_Client */
44 private $client;
45
46 private $rootUrl;
47
48 private $batchPath;
49
50 public function __construct(
51 Google_Client $client,
52 $boundary = false,
53 $rootUrl = null,
54 $batchPath = null
55 ) {
56 $this->client = $client;
57 $this->boundary = $boundary ?: mt_rand();
58 $this->rootUrl = rtrim($rootUrl ?: $this->client->getConfig('base_path'), '/');
59 $this->batchPath = $batchPath ?: self::BATCH_PATH;
60 }
61
62 public function add(RequestInterface $request, $key = false)
63 {
64 if (false == $key) {
65 $key = mt_rand();
66 }
67
68 $this->requests[$key] = $request;
69 }
70
71 public function execute()
72 {
73 $body = '';
74 $classes = array();
75 $batchHttpTemplate = <<<EOF
76 --%s
77 Content-Type: application/http
78 Content-Transfer-Encoding: binary
79 MIME-Version: 1.0
80 Content-ID: %s
81
82 %s
83 %s%s
84
85
86 EOF;
87
88 /** @var Google_Http_Request $req */
89 foreach ($this->requests as $key => $request) {
90 $firstLine = sprintf(
91 '%s %s HTTP/%s',
92 $request->getMethod(),
93 $request->getRequestTarget(),
94 $request->getProtocolVersion()
95 );
96
97 $content = (string) $request->getBody();
98
99 $headers = '';
100 foreach ($request->getHeaders() as $name => $values) {
101 $headers .= sprintf("%s:%s\r\n", $name, implode(', ', $values));
102 }
103
104 $body .= sprintf(
105 $batchHttpTemplate,
106 $this->boundary,
107 $key,
108 $firstLine,
109 $headers,
110 $content ? "\n".$content : ''
111 );
112
113 $classes['response-' . $key] = $request->getHeaderLine('X-Php-Expected-Class');
114 }
115
116 $body .= "--{$this->boundary}--";
117 $body = trim($body);
118 $url = $this->rootUrl . '/' . $this->batchPath;
119 $headers = array(
120 'Content-Type' => sprintf('multipart/mixed; boundary=%s', $this->boundary),
121 'Content-Length' => strlen($body),
122 );
123
124 $request = new Request(
125 'POST',
126 $url,
127 $headers,
128 $body
129 );
130
131 $response = $this->client->execute($request);
132
133 return $this->parseResponse($response, $classes);
134 }
135
136 public function parseResponse(ResponseInterface $response, $classes = array())
137 {
138 $contentType = $response->getHeaderLine('content-type');
139 $contentType = explode(';', $contentType);
140 $boundary = false;
141 foreach ($contentType as $part) {
142 $part = explode('=', $part, 2);
143 if (isset($part[0]) && 'boundary' == trim($part[0])) {
144 $boundary = $part[1];
145 }
146 }
147
148 $body = (string) $response->getBody();
149 if (!empty($body)) {
150 $body = str_replace("--$boundary--", "--$boundary", $body);
151 $parts = explode("--$boundary", $body);
152 $responses = array();
153 $requests = array_values($this->requests);
154
155 foreach ($parts as $i => $part) {
156 $part = trim($part);
157 if (!empty($part)) {
158 list($rawHeaders, $part) = explode("\r\n\r\n", $part, 2);
159 $headers = $this->parseRawHeaders($rawHeaders);
160
161 $status = substr($part, 0, strpos($part, "\n"));
162 $status = explode(" ", $status);
163 $status = $status[1];
164
165 list($partHeaders, $partBody) = $this->parseHttpResponse($part, false);
166 $response = new Response(
167 $status,
168 $partHeaders,
169 Psr7\stream_for($partBody)
170 );
171
172 // Need content id.
173 $key = $headers['content-id'];
174
175 try {
176 $response = Google_Http_REST::decodeHttpResponse($response, $requests[$i-1]);
177 } catch (Google_Service_Exception $e) {
178 // Store the exception as the response, so successful responses
179 // can be processed.
180 $response = $e;
181 }
182
183 $responses[$key] = $response;
184 }
185 }
186
187 return $responses;
188 }
189
190 return null;
191 }
192
193 private function parseRawHeaders($rawHeaders)
194 {
195 $headers = array();
196 $responseHeaderLines = explode("\r\n", $rawHeaders);
197 foreach ($responseHeaderLines as $headerLine) {
198 if ($headerLine && strpos($headerLine, ':') !== false) {
199 list($header, $value) = explode(': ', $headerLine, 2);
200 $header = strtolower($header);
201 if (isset($headers[$header])) {
202 $headers[$header] .= "\n" . $value;
203 } else {
204 $headers[$header] = $value;
205 }
206 }
207 }
208 return $headers;
209 }
210
211 /**
212 * Used by the IO lib and also the batch processing.
213 *
214 * @param $respData
215 * @param $headerSize
216 * @return array
217 */
218 private function parseHttpResponse($respData, $headerSize)
219 {
220 // check proxy header
221 foreach (self::$CONNECTION_ESTABLISHED_HEADERS as $established_header) {
222 if (stripos($respData, $established_header) !== false) {
223 // existed, remove it
224 $respData = str_ireplace($established_header, '', $respData);
225 // Subtract the proxy header size unless the cURL bug prior to 7.30.0
226 // is present which prevented the proxy header size from being taken into
227 // account.
228 // @TODO look into this
229 // if (!$this->needsQuirk()) {
230 // $headerSize -= strlen($established_header);
231 // }
232 break;
233 }
234 }
235
236 if ($headerSize) {
237 $responseBody = substr($respData, $headerSize);
238 $responseHeaders = substr($respData, 0, $headerSize);
239 } else {
240 $responseSegments = explode("\r\n\r\n", $respData, 2);
241 $responseHeaders = $responseSegments[0];
242 $responseBody = isset($responseSegments[1]) ? $responseSegments[1] :
243 null;
244 }
245
246 $responseHeaders = $this->parseRawHeaders($responseHeaders);
247
248 return array($responseHeaders, $responseBody);
249 }
250 }
251