Skip to content

Commit

Permalink
Automatically re-login if session issue occurs mid-process (#175)
Browse files Browse the repository at this point in the history
* Automatically re-login if session issue occurs mid-process

* Added changelog entries
  • Loading branch information
troydavisson committed Oct 23, 2017
1 parent 34d5ecd commit 999cbb2
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 13 deletions.
2 changes: 2 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
_Release TBD_

- Fix RETS 1.8 login response parsing for optional info-token-type
- Support automatic re-login if session issue occurs mid-process
- New option `disable_auto_retry` (bool) added to optionally disable automatic re-login behavior

## 2.4

Expand Down
87 changes: 74 additions & 13 deletions src/Session.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
use GuzzleHttp\Client;
use GuzzleHttp\Cookie\CookieJar;
use GuzzleHttp\Cookie\CookieJarInterface;
use GuzzleHttp\Exception\ClientException;
use Illuminate\Container\Container;
use Illuminate\Support\Collection;
use PHRETS\Exceptions\CapabilityUnavailable;
Expand Down Expand Up @@ -300,11 +301,12 @@ public function Disconnect()
/**
* @param $capability
* @param array $options
* @throws Exceptions\CapabilityUnavailable
* @throws Exceptions\RETSException
* @param bool $is_retry
* @return ResponseInterface
* @throws CapabilityUnavailable
* @throws RETSException
*/
protected function request($capability, $options = [])
protected function request($capability, $options = [], $is_retry = false)
{
$url = $this->capabilities->get($capability);

Expand All @@ -328,13 +330,46 @@ protected function request($capability, $options = [])
$this->last_request_url = $url;
}

/** @var ResponseInterface $response */
if ($this->configuration->readOption('use_post_method')) {
$this->debug('Using POST method per use_post_method option');
$query = (array_key_exists('query', $options)) ? $options['query'] : null;
$response = $this->client->request('POST', $url, array_merge($options, ['form_params' => $query]));
} else {
$response = $this->client->request('GET', $url, $options);
try {
/** @var ResponseInterface $response */
if ($this->configuration->readOption('use_post_method')) {
$this->debug('Using POST method per use_post_method option');
$query = (array_key_exists('query', $options)) ? $options['query'] : null;
$response = $this->client->request('POST', $url, array_merge($options, ['form_params' => $query]));
} else {
$response = $this->client->request('GET', $url, $options);
}
} catch (ClientException $e) {
$this->debug("ClientException: " . $e->getCode() . ": " . $e->getMessage());

if ($e->getCode() != 401) {
// not an Unauthorized error, so bail
throw $e;
}

if ($capability == 'Login') {
// unauthorized on a Login request, so bail
throw $e;
}

if ($is_retry) {
// this attempt was already a retry, so let's stop here
$this->debug("Request retry failed. Won't retry again");
throw $e;
}

if ($this->getConfiguration()->readOption('disable_auto_retry')) {
// this attempt was already a retry, so let's stop here
$this->debug("Re-logging in disabled. Won't retry");
throw $e;
}

$this->debug("401 Unauthorized exception returned");
$this->debug("Logging in again and retrying request");
// see if logging in again and retrying the request works
$this->Login();

return $this->request($capability, $options, true);
}

$response = new \PHRETS\Http\Response($response);
Expand All @@ -349,21 +384,47 @@ protected function request($capability, $options = [])
}
}
}


$this->debug('Response: HTTP ' . $response->getStatusCode());

if (preg_match('/text\/xml/', $response->getHeader('Content-Type')) and $capability != 'GetObject') {
$parser = $this->grab(Strategy::PARSER_XML);
$xml = $parser->parse($response);

if ($xml and isset($xml['ReplyCode'])) {
$rc = (string)$xml['ReplyCode'];

if ($rc == "20037" and $capability != 'Login') {
// must make Login request again. let's handle this automatically

if ($this->getConfiguration()->readOption('disable_auto_retry')) {
// this attempt was already a retry, so let's stop here
$this->debug("Re-logging in disabled. Won't retry");
throw new RETSException($xml['ReplyText'], (int)$xml['ReplyCode']);
}

if ($is_retry) {
// this attempt was already a retry, so let's stop here
$this->debug("Request retry failed. Won't retry again");
// let this error fall through to the more generic handling below
} else {
$this->debug("RETS 20037 re-auth requested");
$this->debug("Logging in again and retrying request");
// see if logging in again and retrying the request works
$this->Login();

return $this->request($capability, $options, true);
}
}

// 20201 - No records found - not exception worthy in my mind
// 20403 - No objects found - not exception worthy in my mind
if ($rc != "0" and $rc != "20201" and $rc != "20403") {
if (!in_array($rc, [0, 20201, 20403])) {
throw new RETSException($xml['ReplyText'], (int)$xml['ReplyCode']);
}
}
}

$this->debug('Response: HTTP ' . $response->getStatusCode());
return $response;
}

Expand Down

0 comments on commit 999cbb2

Please sign in to comment.