/** * Parses a response body into a PHP object if appropriate. * * @param CFResponse|string $response (Required) The <CFResponse> object to parse, or an XML string that would otherwise be a response body. * @param string $content_type (Optional) The content-type to use when determining how to parse the content. * @return CFResponse|string A parsed <CFResponse> object, or parsed XML. */ public function parse_callback($response, $headers = null) { // Shorten this so we have a (mostly) single code path if (isset($response->body)) { if (is_string($response->body)) { $body = $response->body; } else { return $response; } } elseif (is_string($response)) { $body = $response; } else { return $response; } // Decompress gzipped content if (isset($headers['content-encoding'])) { switch (strtolower(trim($headers['content-encoding'], "\t\n\r "))) { case 'gzip': case 'x-gzip': if (strpos($headers['_info']['url'], 'monitoring.') !== false) { // CloudWatch incorrectly uses the deflate algorithm when they say gzip. if (($uncompressed = gzuncompress($body)) !== false) { $body = $uncompressed; } elseif (($uncompressed = gzinflate($body)) !== false) { $body = $uncompressed; } break; } else { // Everyone else uses gzip correctly. $decoder = new CFGzipDecode($body); if ($decoder->parse()) { $body = $decoder->data; } break; } case 'deflate': if (strpos($headers['_info']['url'], 'monitoring.') !== false) { // CloudWatch incorrectly does nothing when they say deflate. continue; } else { // Everyone else uses deflate correctly. if (($uncompressed = gzuncompress($body)) !== false) { $body = $uncompressed; } elseif (($uncompressed = gzinflate($body)) !== false) { $body = $uncompressed; } } break; } } // Look for XML cues if (isset($headers['content-type']) && ($headers['content-type'] === 'text/xml' || $headers['content-type'] === 'application/xml') || (!isset($headers['content-type']) && (stripos($body, '<?xml') === 0 || strpos($body, '<Error>') === 0) || preg_match('/^<(\\w*) xmlns="http(s?):\\/\\/(\\w*).amazon(aws)?.com/im', $body))) { // Strip the default XML namespace to simplify XPath expressions $body = str_replace("xmlns=", "ns=", $body); // Parse the XML body $body = new $this->parser_class($body); } elseif (isset($headers['content-type']) && $headers['content-type'] === 'application/json' || !isset($headers['content-type']) && $this->util->is_json($body)) { // Normalize JSON to a CFSimpleXML object $body = CFJSON::to_xml($body); } // Put the parsed data back where it goes if (isset($response->body)) { $response->body = $body; } else { $response = $body; } return $response; }
/** * Parses a response body into a PHP object if appropriate. * * @param CFResponse|string $response (Required) The <CFResponse> object to parse, or an XML string that would otherwise be a response body. * @param string $content_type (Optional) The content-type to use when determining how to parse the content. * @return CFResponse|string A parsed <CFResponse> object, or parsed XML. */ public function parse_callback($response, $headers = null) { // Bail out if (!$this->parse_the_response) { return $response; } // Shorten this so we have a (mostly) single code path if (isset($response->body)) { if (is_string($response->body)) { $body = $response->body; } else { return $response; } } elseif (is_string($response)) { $body = $response; } else { return $response; } // Decompress gzipped content if (isset($headers['content-encoding'])) { switch (strtolower(trim($headers['content-encoding'], "\t\n\r "))) { case 'gzip': case 'x-gzip': $decoder = new CFGzipDecode($body); if ($decoder->parse()) { $body = $decoder->data; } break; case 'deflate': if (($uncompressed = gzuncompress($body)) !== false) { $body = $uncompressed; } elseif (($uncompressed = gzinflate($body)) !== false) { $body = $uncompressed; } break; } } // Look for XML cues if (isset($headers['content-type']) && ($headers['content-type'] === 'text/xml' || $headers['content-type'] === 'application/xml') || (!isset($headers['content-type']) && (stripos($body, '<?xml') === 0 || strpos($body, '<Error>') === 0) || preg_match('/^<(\\w*) xmlns="http(s?):\\/\\/(\\w*).amazon(aws)?.com/im', $body))) { // Strip the default XML namespace to simplify XPath expressions $body = str_replace("xmlns=", "ns=", $body); try { // Parse the XML body $body = new $this->parser_class($body); } catch (Exception $e) { throw new Parser_Exception($e->getMessage()); } } elseif (isset($headers['content-type']) && $headers['content-type'] === 'application/json' || $headers['content-type'] === 'application/x-amz-json-1.0' || !isset($headers['content-type']) && $this->util->is_json($body)) { // Normalize JSON to a CFSimpleXML object $body = CFJSON::to_xml($body, $this->parser_class); } // Put the parsed data back where it goes if (isset($response->body)) { $response->body = $body; } else { $response = $body; } return $response; }