Total Complexity | 61 |
Total Lines | 332 |
Duplicated Lines | 0 % |
Changes | 0 |
Complex classes like HttpClientBase often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use HttpClientBase, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
41 | class HttpClientBase |
||
42 | { |
||
43 | const CRLF = "\r\n"; |
||
44 | |||
45 | const HTTP_OK = 200; |
||
46 | const HTTP_ACCEPTED = 202; |
||
47 | const HTTP_MULTIPLE_CHOICES = 300; |
||
48 | const HTTP_BAD_REQUEST = 400; |
||
49 | const HTTP_UNAUTHORIZED = 401; |
||
50 | |||
51 | protected function stringStartsWith($source, $subString) |
||
52 | { |
||
53 | return 0 === mb_strpos($source, $subString, 0, Constraints::UTF_8); |
||
54 | } |
||
55 | |||
56 | protected function stringEndsWith($source, $subString) |
||
57 | { |
||
58 | $sourceLength = StringUtils::length($source); |
||
59 | $subStringLength = StringUtils::length($subString); |
||
60 | $subStringIndex = $sourceLength - $subStringLength; |
||
61 | |||
62 | if ($subStringLength < 0) { |
||
63 | return false; |
||
64 | } |
||
65 | |||
66 | $newString = (mb_substr($source, $subStringIndex, $subStringLength, Constraints::UTF_8)); |
||
67 | |||
68 | return $newString === $subString; |
||
69 | } |
||
70 | |||
71 | protected function getValueFromArray(array $array, $index, $defaultValue = null) |
||
74 | } |
||
75 | |||
76 | protected function getHttpResponseFromUrl($url, $context) |
||
77 | { |
||
78 | $http_response_header = null; |
||
|
|||
79 | |||
80 | $contents = @file_get_contents($url, false, $context); |
||
81 | if (false === $contents) { |
||
82 | throw new EasyPdfCloudApiException(0, 'Unable to communicate to the server'); |
||
83 | } |
||
84 | |||
85 | return array( |
||
86 | 'header' => $http_response_header, |
||
87 | 'contents' => $contents, |
||
88 | ); |
||
89 | } |
||
90 | |||
91 | protected function mapFirstLineHeaders($header) |
||
92 | { |
||
93 | $array = array(); |
||
94 | |||
95 | $keyValueMap = array_map('trim', explode(':', $header, 2)); |
||
96 | $headerName = (count($keyValueMap) >= 1 ? $keyValueMap[0] : null); |
||
97 | $headerValue = (count($keyValueMap) >= 2 ? $keyValueMap[1] : null); |
||
98 | |||
99 | $firstLineMap = array_map('trim', explode(' ', $headerName, 3)); |
||
100 | |||
101 | if (count($firstLineMap) >= 1) { |
||
102 | $httpVersionHeader = $firstLineMap[0]; |
||
103 | $httpVersionMap = array_map('trim', explode('/', $httpVersionHeader, 2)); |
||
104 | |||
105 | if (count($httpVersionMap) >= 2) { |
||
106 | $headerNameLC = 'http-version'; |
||
107 | $headerValue = $httpVersionMap[1]; |
||
108 | $array += array($headerNameLC => $headerValue); |
||
109 | } |
||
110 | |||
111 | if (count($firstLineMap) >= 2) { |
||
112 | $headerNameLC = 'status-code'; |
||
113 | $headerValue = $firstLineMap[1]; |
||
114 | $array += array($headerNameLC => $headerValue); |
||
115 | |||
116 | if (count($firstLineMap) >= 3) { |
||
117 | $headerNameLC = 'status-description'; |
||
118 | $headerValue = $firstLineMap[2]; |
||
119 | $array += array($headerNameLC => $headerValue); |
||
120 | } |
||
121 | } |
||
122 | } |
||
123 | |||
124 | return $array; |
||
125 | } |
||
126 | |||
127 | protected function mapHttpHeaders($headers) |
||
128 | { |
||
129 | $headersCount = count($headers); |
||
130 | if (0 === $headersCount) { |
||
131 | return array(); |
||
132 | } |
||
133 | |||
134 | $header = $headers[0]; |
||
135 | $array = $this->mapFirstLineHeaders($header); |
||
136 | |||
137 | for ($i = 1; $i < $headersCount; ++$i) { |
||
138 | $header = $headers[$i]; |
||
139 | |||
140 | $keyValueMap = array_map('trim', explode(':', $header, 2)); |
||
141 | $headerName = (count($keyValueMap) >= 1 ? $keyValueMap[0] : null); |
||
142 | $headerValue = (count($keyValueMap) >= 2 ? $keyValueMap[1] : null); |
||
143 | |||
144 | if (null !== $headerName) { |
||
145 | $headerNameLC = mb_strtolower($headerName, Constraints::UTF_8); |
||
146 | $array += array($headerNameLC => $headerValue); |
||
147 | } |
||
148 | } |
||
149 | |||
150 | return $array; |
||
151 | } |
||
152 | |||
153 | protected function getStatusCodeFromResponse($headers) |
||
154 | { |
||
155 | if (!isset($headers['status-code'])) { |
||
156 | return 0; |
||
157 | } |
||
158 | |||
159 | $statusCode = (int) $headers['status-code']; |
||
160 | |||
161 | return $statusCode; |
||
162 | } |
||
163 | |||
164 | protected function isSuccessfulResponse($headers) |
||
165 | { |
||
166 | $statusCode = $this->getStatusCodeFromResponse($headers); |
||
167 | |||
168 | return $statusCode >= self::HTTP_OK && $statusCode < self::HTTP_MULTIPLE_CHOICES; |
||
169 | } |
||
170 | |||
171 | protected function getFileNameFromContentDisposisionHeader($contentDisposition) |
||
172 | { |
||
173 | if (!isset($contentDisposition)) { |
||
174 | return null; |
||
175 | } |
||
176 | |||
177 | $colonSeparatedList = array_map('trim', explode(';', $contentDisposition)); |
||
178 | $array = array(); |
||
179 | |||
180 | foreach ($colonSeparatedList as $item) { |
||
181 | $separatedList = array_map('trim', explode('=', $item, 2)); |
||
182 | |||
183 | if (count($separatedList) >= 2) { |
||
184 | $nameLC = mb_strtolower($separatedList[0], Constraints::UTF_8); |
||
185 | $value = trim($separatedList[1], '"'); |
||
186 | |||
187 | $array += array($nameLC => $value); |
||
188 | } |
||
189 | } |
||
190 | |||
191 | if (isset($array['filename*'])) { |
||
192 | $fileName = $array['filename*']; |
||
193 | |||
194 | $utf8Prefix = 'utf-8\'\''; |
||
195 | |||
196 | if ($this->stringStartsWith($fileName, $utf8Prefix)) { |
||
197 | // trim utf8 prefix |
||
198 | $prefixLength = mb_strlen($utf8Prefix, Constraints::UTF_8); |
||
199 | $fileName = mb_substr($fileName, $prefixLength, null, Constraints::UTF_8); |
||
200 | } |
||
201 | |||
202 | // URL decode and return |
||
203 | $fileName = urldecode($fileName); |
||
204 | |||
205 | return $fileName; |
||
206 | } elseif (isset($array['filename'])) { |
||
207 | $fileName = $array['filename']; |
||
208 | |||
209 | $base64Prefix = '=?utf-8?B?'; |
||
210 | $base64Postfix = '?='; |
||
211 | |||
212 | if ($this->stringStartsWith($fileName, $base64Prefix)) { |
||
213 | // trim base64 prefix |
||
214 | $prefixLength = mb_strlen($base64Prefix, Constraints::UTF_8); |
||
215 | $fileName = mb_substr($fileName, $prefixLength, null, Constraints::UTF_8); |
||
216 | |||
217 | if ($this->stringEndsWith($fileName, $base64Postfix)) { |
||
218 | // trim base64 postfix |
||
219 | $fileNameLength = mb_strlen($fileName, Constraints::UTF_8); |
||
220 | $postfixLength = mb_strlen($base64Postfix, Constraints::UTF_8); |
||
221 | $substrLength = $fileNameLength - $postfixLength; |
||
222 | $fileName = mb_substr($fileName, 0, $substrLength, Constraints::UTF_8); |
||
223 | } |
||
224 | |||
225 | // base64 decode and return |
||
226 | $fileName = base64_decode($fileName, true); |
||
227 | |||
228 | return $fileName; |
||
229 | } |
||
230 | |||
231 | // URL decode and return |
||
232 | $fileName = urldecode($fileName); |
||
233 | |||
234 | return $fileName; |
||
235 | } |
||
236 | |||
237 | return null; |
||
238 | } |
||
239 | |||
240 | protected function parseWwwAuthenticateResonseHeader($wwwAuthenticate) |
||
241 | { |
||
242 | $spaceSeparatedList = array_map('trim', explode(' ', $wwwAuthenticate)); |
||
243 | $commaSeparatedList = array(); |
||
244 | $array = array(); |
||
245 | |||
246 | foreach ($spaceSeparatedList as $item) { |
||
247 | $separatedList = array_map('trim', explode(',', $item)); |
||
248 | |||
249 | if (count($separatedList) >= 2) { |
||
250 | $commaSeparatedList = array_merge($commaSeparatedList, $separatedList); |
||
251 | } |
||
252 | } |
||
253 | |||
254 | foreach ($commaSeparatedList as $item) { |
||
255 | $separatedList = array_map('trim', explode('=', $item, 2)); |
||
256 | |||
257 | if (count($separatedList) >= 2) { |
||
258 | $nameLC = mb_strtolower(trim($separatedList[0]), Constraints::UTF_8); |
||
259 | $value = urldecode(trim(trim($separatedList[1]), '"')); |
||
260 | |||
261 | $array += array($nameLC => $value); |
||
262 | } |
||
263 | } |
||
264 | |||
265 | return $array; |
||
266 | } |
||
267 | |||
268 | protected function checkWwwAuthenticateResponseHeader($headers) |
||
269 | { |
||
270 | $statusCode = $this->getStatusCodeFromResponse($headers); |
||
271 | |||
272 | if (self::HTTP_BAD_REQUEST !== $statusCode && self::HTTP_UNAUTHORIZED !== $statusCode) { |
||
273 | return; |
||
274 | } |
||
275 | |||
276 | if (!isset($headers['www-authenticate'])) { |
||
277 | return; |
||
278 | } |
||
279 | |||
280 | $wwwAuthenticate = $headers['www-authenticate']; |
||
281 | $wwwAuthenticateMap = $this->parseWwwAuthenticateResonseHeader($wwwAuthenticate); |
||
282 | |||
283 | if (isset($wwwAuthenticateMap['error'])) { |
||
284 | $error = $wwwAuthenticateMap['error']; |
||
285 | |||
286 | $errorDescription = ''; |
||
287 | if (isset($wwwAuthenticateMap['error_description'])) { |
||
288 | $errorDescription = $wwwAuthenticateMap['error_description']; |
||
289 | } |
||
290 | |||
291 | throw new ApiAuthorizationException($statusCode, $error, $errorDescription); |
||
292 | } |
||
293 | } |
||
294 | |||
295 | protected function needsToRefreshToken($headers) |
||
309 | } |
||
310 | |||
311 | protected function decodeJsonFromResponse($headers, $contents, $failIfNotJson) |
||
312 | { |
||
313 | if (!isset($headers['content-type'])) { |
||
341 | } |
||
342 | |||
343 | protected function handleResponse($headers, $contents = null) |
||
344 | { |
||
345 | if ($this->isSuccessfulResponse($headers)) { |
||
373 | } |
||
374 | } |
||
375 |