Matthias Andreas Benkard | b382b10 | 2021-01-02 15:32:21 +0100 | [diff] [blame^] | 1 | <?php |
| 2 | |
| 3 | namespace RobThree\Auth\Providers\Time; |
| 4 | |
| 5 | /** |
| 6 | * Takes the time from any webserver by doing a HEAD request on the specified URL and extracting the 'Date:' header |
| 7 | */ |
| 8 | class HttpTimeProvider implements ITimeProvider |
| 9 | { |
| 10 | public $url; |
| 11 | public $options; |
| 12 | public $expectedtimeformat; |
| 13 | |
| 14 | function __construct($url = 'https://google.com', $expectedtimeformat = 'D, d M Y H:i:s O+', array $options = null) |
| 15 | { |
| 16 | $this->url = $url; |
| 17 | $this->expectedtimeformat = $expectedtimeformat; |
| 18 | $this->options = $options; |
| 19 | if ($this->options === null) { |
| 20 | $this->options = array( |
| 21 | 'http' => array( |
| 22 | 'method' => 'HEAD', |
| 23 | 'follow_location' => false, |
| 24 | 'ignore_errors' => true, |
| 25 | 'max_redirects' => 0, |
| 26 | 'request_fulluri' => true, |
| 27 | 'header' => array( |
| 28 | 'Connection: close', |
| 29 | 'User-agent: TwoFactorAuth HttpTimeProvider (https://github.com/RobThree/TwoFactorAuth)', |
| 30 | 'Cache-Control: no-cache' |
| 31 | ) |
| 32 | ) |
| 33 | ); |
| 34 | } |
| 35 | } |
| 36 | |
| 37 | public function getTime() { |
| 38 | try { |
| 39 | $context = stream_context_create($this->options); |
| 40 | $fd = fopen($this->url, 'rb', false, $context); |
| 41 | $headers = stream_get_meta_data($fd); |
| 42 | fclose($fd); |
| 43 | |
| 44 | foreach ($headers['wrapper_data'] as $h) { |
| 45 | if (strcasecmp(substr($h, 0, 5), 'Date:') === 0) |
| 46 | return \DateTime::createFromFormat($this->expectedtimeformat, trim(substr($h,5)))->getTimestamp(); |
| 47 | } |
| 48 | throw new \TimeException(sprintf('Unable to retrieve time from %s (Invalid or no "Date:" header found)', $this->url)); |
| 49 | } |
| 50 | catch (Exception $ex) { |
| 51 | throw new \TimeException(sprintf('Unable to retrieve time from %s (%s)', $this->url, $ex->getMessage())); |
| 52 | } |
| 53 | } |
| 54 | } |