Exception
11 months ago
AbstractParser.php
11 months ago
AbstractRestParser.php
11 months ago
Crc32ValidatingParser.php
11 months ago
DecodingEventStreamIterator.php
11 months ago
EventParsingIterator.php
11 months ago
JsonParser.php
11 months ago
JsonRpcParser.php
11 months ago
MetadataParserTrait.php
11 months ago
PayloadParserTrait.php
11 months ago
QueryParser.php
11 months ago
RestJsonParser.php
11 months ago
RestXmlParser.php
11 months ago
XmlParser.php
11 months ago
AbstractRestParser.php
185 lines
| 1 | <?php |
| 2 | namespace Aws\Api\Parser; |
| 3 | |
| 4 | use Aws\Api\DateTimeResult; |
| 5 | use Aws\Api\Shape; |
| 6 | use Aws\Api\StructureShape; |
| 7 | use Aws\Result; |
| 8 | use Aws\CommandInterface; |
| 9 | use Psr\Http\Message\ResponseInterface; |
| 10 | |
| 11 | /** |
| 12 | * @internal |
| 13 | */ |
| 14 | abstract class AbstractRestParser extends AbstractParser |
| 15 | { |
| 16 | use PayloadParserTrait; |
| 17 | |
| 18 | /** |
| 19 | * Parses a payload from a response. |
| 20 | * |
| 21 | * @param ResponseInterface $response Response to parse. |
| 22 | * @param StructureShape $member Member to parse |
| 23 | * @param array $result Result value |
| 24 | * |
| 25 | * @return mixed |
| 26 | */ |
| 27 | abstract protected function payload( |
| 28 | ResponseInterface $response, |
| 29 | StructureShape $member, |
| 30 | array &$result |
| 31 | ); |
| 32 | |
| 33 | public function __invoke( |
| 34 | CommandInterface $command, |
| 35 | ResponseInterface $response |
| 36 | ) { |
| 37 | $output = $this->api->getOperation($command->getName())->getOutput(); |
| 38 | $result = []; |
| 39 | |
| 40 | if ($payload = $output['payload']) { |
| 41 | $this->extractPayload($payload, $output, $response, $result); |
| 42 | } |
| 43 | |
| 44 | foreach ($output->getMembers() as $name => $member) { |
| 45 | switch ($member['location']) { |
| 46 | case 'header': |
| 47 | $this->extractHeader($name, $member, $response, $result); |
| 48 | break; |
| 49 | case 'headers': |
| 50 | $this->extractHeaders($name, $member, $response, $result); |
| 51 | break; |
| 52 | case 'statusCode': |
| 53 | $this->extractStatus($name, $response, $result); |
| 54 | break; |
| 55 | } |
| 56 | } |
| 57 | |
| 58 | if (!$payload |
| 59 | && $response->getBody()->getSize() > 0 |
| 60 | && count($output->getMembers()) > 0 |
| 61 | ) { |
| 62 | // if no payload was found, then parse the contents of the body |
| 63 | $this->payload($response, $output, $result); |
| 64 | } |
| 65 | |
| 66 | return new Result($result); |
| 67 | } |
| 68 | |
| 69 | private function extractPayload( |
| 70 | $payload, |
| 71 | StructureShape $output, |
| 72 | ResponseInterface $response, |
| 73 | array &$result |
| 74 | ) { |
| 75 | $member = $output->getMember($payload); |
| 76 | |
| 77 | if (!empty($member['eventstream'])) { |
| 78 | $result[$payload] = new EventParsingIterator( |
| 79 | $response->getBody(), |
| 80 | $member, |
| 81 | $this |
| 82 | ); |
| 83 | } else if ($member instanceof StructureShape) { |
| 84 | // Structure members parse top-level data into a specific key. |
| 85 | $result[$payload] = []; |
| 86 | $this->payload($response, $member, $result[$payload]); |
| 87 | } else { |
| 88 | // Streaming data is just the stream from the response body. |
| 89 | $result[$payload] = $response->getBody(); |
| 90 | } |
| 91 | } |
| 92 | |
| 93 | /** |
| 94 | * Extract a single header from the response into the result. |
| 95 | */ |
| 96 | private function extractHeader( |
| 97 | $name, |
| 98 | Shape $shape, |
| 99 | ResponseInterface $response, |
| 100 | &$result |
| 101 | ) { |
| 102 | $value = $response->getHeaderLine($shape['locationName'] ?: $name); |
| 103 | |
| 104 | switch ($shape->getType()) { |
| 105 | case 'float': |
| 106 | case 'double': |
| 107 | $value = (float) $value; |
| 108 | break; |
| 109 | case 'long': |
| 110 | $value = (int) $value; |
| 111 | break; |
| 112 | case 'boolean': |
| 113 | $value = filter_var($value, FILTER_VALIDATE_BOOLEAN); |
| 114 | break; |
| 115 | case 'blob': |
| 116 | $value = base64_decode($value); |
| 117 | break; |
| 118 | case 'timestamp': |
| 119 | try { |
| 120 | $value = DateTimeResult::fromTimestamp( |
| 121 | $value, |
| 122 | !empty($shape['timestampFormat']) ? $shape['timestampFormat'] : null |
| 123 | ); |
| 124 | break; |
| 125 | } catch (\Exception $e) { |
| 126 | // If the value cannot be parsed, then do not add it to the |
| 127 | // output structure. |
| 128 | return; |
| 129 | } |
| 130 | case 'string': |
| 131 | try { |
| 132 | if ($shape['jsonvalue']) { |
| 133 | $value = $this->parseJson(base64_decode($value), $response); |
| 134 | } |
| 135 | |
| 136 | // If value is not set, do not add to output structure. |
| 137 | if (!isset($value)) { |
| 138 | return; |
| 139 | } |
| 140 | break; |
| 141 | } catch (\Exception $e) { |
| 142 | //If the value cannot be parsed, then do not add it to the |
| 143 | //output structure. |
| 144 | return; |
| 145 | } |
| 146 | } |
| 147 | |
| 148 | $result[$name] = $value; |
| 149 | } |
| 150 | |
| 151 | /** |
| 152 | * Extract a map of headers with an optional prefix from the response. |
| 153 | */ |
| 154 | private function extractHeaders( |
| 155 | $name, |
| 156 | Shape $shape, |
| 157 | ResponseInterface $response, |
| 158 | &$result |
| 159 | ) { |
| 160 | // Check if the headers are prefixed by a location name |
| 161 | $result[$name] = []; |
| 162 | $prefix = $shape['locationName']; |
| 163 | $prefixLen = $prefix !== null ? strlen($prefix) : 0; |
| 164 | |
| 165 | foreach ($response->getHeaders() as $k => $values) { |
| 166 | if (!$prefixLen) { |
| 167 | $result[$name][$k] = implode(', ', $values); |
| 168 | } elseif (stripos($k, $prefix) === 0) { |
| 169 | $result[$name][substr($k, $prefixLen)] = implode(', ', $values); |
| 170 | } |
| 171 | } |
| 172 | } |
| 173 | |
| 174 | /** |
| 175 | * Places the status code of the response into the result array. |
| 176 | */ |
| 177 | private function extractStatus( |
| 178 | $name, |
| 179 | ResponseInterface $response, |
| 180 | array &$result |
| 181 | ) { |
| 182 | $result[$name] = (int) $response->getStatusCode(); |
| 183 | } |
| 184 | } |
| 185 |