@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Improve Amazon SES code error handling behavior

Summary:
Fixes T10728. Fixes T10476. SES uses third-party code with unique, creative ideas about error handling.

- Make the error handling behavior more correct, so it doesn't try to use undefined variables.
- Simplify the error handling behavior (throw exceptions sooner, remove redundant code).
- Explicitly test for `-smtp` misconfigurations. These can arise if you read the wrong column out of the table in the AWS docs, as in T10728.
- Explicitly test for SimpleXML, to catch T10476 before it does damage.

Test Plan:
- Configured SES to use a bogus SMTP endpoint.
- Faked past the SMTP check, hit sane error on the connection.
- Undid faking, hit immediate hard stop on the STMP check.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T10476, T10728

Differential Revision: https://secure.phabricator.com/D15632

+37 -57
+37 -57
externals/amazon-ses/ses.php
··· 80 80 * @return void 81 81 */ 82 82 public function __construct($accessKey = null, $secretKey = null, $host = 'email.us-east-1.amazonaws.com') { 83 + if (!function_exists('simplexml_load_string')) { 84 + throw new Exception( 85 + pht( 86 + 'The PHP SimpleXML extension is not available, but this '. 87 + 'extension is required to send mail via Amazon SES, because '. 88 + 'Amazon SES returns API responses in XML format. Install or '. 89 + 'enable the SimpleXML extension.')); 90 + } 91 + 92 + // Catch mistakes with reading the wrong column out of the SES 93 + // documentation. See T10728. 94 + if (preg_match('(-smtp)', $host)) { 95 + throw new Exception( 96 + pht( 97 + 'Amazon SES is not configured correctly: the configured SES '. 98 + 'endpoint ("%s") is an SMTP endpoint. Instead, use an API (HTTPS) '. 99 + 'endpoint.', 100 + $host)); 101 + } 102 + 83 103 if ($accessKey !== null && $secretKey !== null) { 84 104 $this->setAuth($accessKey, $secretKey); 85 105 } 106 + 86 107 $this->__host = $host; 87 108 } 88 109 ··· 108 129 $rest->setParameter('Action', 'ListVerifiedEmailAddresses'); 109 130 110 131 $rest = $rest->getResponse(); 111 - if($rest->error === false && $rest->code !== 200) { 112 - $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); 113 - } 114 - if($rest->error !== false) { 115 - $this->__triggerError('listVerifiedEmailAddresses', $rest->error); 116 - return false; 117 - } 118 132 119 133 $response = array(); 120 134 if(!isset($rest->body)) { ··· 148 162 $rest->setParameter('EmailAddress', $email); 149 163 150 164 $rest = $rest->getResponse(); 151 - if($rest->error === false && $rest->code !== 200) { 152 - $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); 153 - } 154 - if($rest->error !== false) { 155 - $this->__triggerError('verifyEmailAddress', $rest->error); 156 - return false; 157 - } 158 165 159 166 $response['RequestId'] = (string)$rest->body->ResponseMetadata->RequestId; 160 167 return $response; ··· 172 179 $rest->setParameter('EmailAddress', $email); 173 180 174 181 $rest = $rest->getResponse(); 175 - if($rest->error === false && $rest->code !== 200) { 176 - $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); 177 - } 178 - if($rest->error !== false) { 179 - $this->__triggerError('deleteVerifiedEmailAddress', $rest->error); 180 - return false; 181 - } 182 182 183 183 $response['RequestId'] = (string)$rest->body->ResponseMetadata->RequestId; 184 184 return $response; ··· 195 195 $rest->setParameter('Action', 'GetSendQuota'); 196 196 197 197 $rest = $rest->getResponse(); 198 - if($rest->error === false && $rest->code !== 200) { 199 - $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); 200 - } 201 - if($rest->error !== false) { 202 - $this->__triggerError('getSendQuota', $rest->error); 203 - return false; 204 - } 205 198 206 199 $response = array(); 207 200 if(!isset($rest->body)) { ··· 227 220 $rest->setParameter('Action', 'GetSendStatistics'); 228 221 229 222 $rest = $rest->getResponse(); 230 - if($rest->error === false && $rest->code !== 200) { 231 - $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); 232 - } 233 - if($rest->error !== false) { 234 - $this->__triggerError('getSendStatistics', $rest->error); 235 - return false; 236 - } 237 223 238 224 $response = array(); 239 225 if(!isset($rest->body)) { ··· 265 251 $rest->setParameter('RawMessage.Data', base64_encode($raw)); 266 252 267 253 $rest = $rest->getResponse(); 268 - if($rest->error === false && $rest->code !== 200) { 269 - $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); 270 - } 271 - if($rest->error !== false) { 272 - $this->__triggerError('sendRawEmail', $rest->error); 273 - return false; 274 - } 275 254 276 255 $response['MessageId'] = (string)$rest->body->SendEmailResult->MessageId; 277 256 $response['RequestId'] = (string)$rest->body->ResponseMetadata->RequestId; ··· 351 330 } 352 331 353 332 $rest = $rest->getResponse(); 354 - if($rest->error === false && $rest->code !== 200) { 355 - $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); 356 - } 357 - if($rest->error !== false) { 358 - $this->__triggerError('sendEmail', $rest->error); 359 - return false; 360 - } 361 333 362 334 $response['MessageId'] = (string)$rest->body->SendEmailResult->MessageId; 363 335 $response['RequestId'] = (string)$rest->body->ResponseMetadata->RequestId; ··· 523 495 curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); 524 496 525 497 // Execute, grab errors 526 - if (curl_exec($curl)) { 527 - $this->response->code = curl_getinfo($curl, CURLINFO_HTTP_CODE); 528 - } else { 529 - $this->response->error = array( 530 - 'curl' => true, 531 - 'code' => curl_errno($curl), 532 - 'message' => curl_error($curl), 533 - ); 498 + if (!curl_exec($curl)) { 499 + throw new SimpleEmailServiceException( 500 + pht( 501 + 'Encountered an error while making an HTTP request to Amazon SES '. 502 + '(cURL Error #%d): %s', 503 + curl_errno($curl), 504 + curl_error($curl))); 505 + } 506 + 507 + $this->response->code = curl_getinfo($curl, CURLINFO_HTTP_CODE); 508 + if ($this->response->code != 200) { 509 + throw new SimpleEmailServiceException( 510 + pht( 511 + 'Unexpected HTTP status while making request to Amazon SES: '. 512 + 'expected 200, got %s.', 513 + $this->response->code)); 534 514 } 535 515 536 516 @curl_close($curl);