blob: 8e7806e2c517c3bf7e8e1629999f36306ca3ac1f [file] [log] [blame]
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +01001<?php
2
3namespace 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 */
8class 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}