InstagramUrlDetectionHandler   A
last analyzed

Complexity

Total Complexity 26

Size/Duplication

Total Lines 150
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 40
dl 0
loc 150
rs 10
c 0
b 0
f 0
wmc 26

9 Methods

Rating   Name   Duplication   Size   Complexity  
A isBehindSsl() 0 14 3
A getHttpScheme() 0 3 2
B getHostName() 0 28 9
A protocolWithActiveSsl() 0 5 1
A getServerVar() 0 3 2
A getCurrentPort() 0 14 3
A getHeader() 0 3 1
A getCurrentUrl() 0 3 1
A isValidForwardedHost() 0 8 4
1
<?php
2
3
namespace Maztech\Url;
4
5
/**
6
 * Class InstagramUrlDetectionHandler
7
 *
8
 * @package Instagram
9
 */
10
class InstagramUrlDetectionHandler implements UrlDetectionInterface
11
{
12
    /**
13
     * @inheritdoc
14
     */
15
    public function getCurrentUrl()
16
    {
17
        return $this->getHttpScheme() . '://' . $this->getHostName() . $this->getServerVar('REQUEST_URI');
18
    }
19
20
    /**
21
     * Get the currently active URL scheme.
22
     *
23
     * @return string
24
     */
25
    protected function getHttpScheme()
26
    {
27
        return $this->isBehindSsl() ? 'https' : 'http';
28
    }
29
30
    /**
31
     * Tries to detect if the server is running behind an SSL.
32
     *
33
     * @return boolean
34
     */
35
    protected function isBehindSsl()
36
    {
37
        // Check for proxy first
38
        $protocol = $this->getHeader('X_FORWARDED_PROTO');
39
        if ($protocol) {
40
            return $this->protocolWithActiveSsl($protocol);
41
        }
42
43
        $protocol = $this->getServerVar('HTTPS');
44
        if ($protocol) {
45
            return $this->protocolWithActiveSsl($protocol);
46
        }
47
48
        return (string)$this->getServerVar('SERVER_PORT') === '443';
49
    }
50
51
    /**
52
     * Detects an active SSL protocol value.
53
     *
54
     * @param string $protocol
55
     *
56
     * @return boolean
57
     */
58
    protected function protocolWithActiveSsl($protocol)
59
    {
60
        $protocol = strtolower((string)$protocol);
61
62
        return in_array($protocol, ['on', '1', 'https', 'ssl'], true);
63
    }
64
65
    /**
66
     * Tries to detect the host name of the server.
67
     *
68
     * Some elements adapted from
69
     *
70
     * @see https://github.com/symfony/HttpFoundation/blob/master/Request.php
71
     *
72
     * @return string
73
     */
74
    protected function getHostName()
75
    {
76
        // Check for proxy first
77
        $header = $this->getHeader('X_FORWARDED_HOST');
78
        if ($header && $this->isValidForwardedHost($header)) {
79
            $elements = explode(',', $header);
80
            $host = $elements[count($elements) - 1];
81
        } elseif (!$host = $this->getHeader('HOST')) {
82
            if (!$host = $this->getServerVar('SERVER_NAME')) {
83
                $host = $this->getServerVar('SERVER_ADDR');
84
            }
85
        }
86
87
        // trim and remove port number from host
88
        // host is lowercase as per RFC 952/2181
89
        $host = strtolower(preg_replace('/:\d+$/', '', trim($host)));
90
91
        // Port number
92
        $scheme = $this->getHttpScheme();
93
        $port = $this->getCurrentPort();
94
        $appendPort = ':' . $port;
95
96
        // Don't append port number if a normal port.
97
        if (($scheme == 'http' && $port == '80') || ($scheme == 'https' && $port == '443')) {
98
            $appendPort = '';
99
        }
100
101
        return $host . $appendPort;
102
    }
103
104
    protected function getCurrentPort()
105
    {
106
        // Check for proxy first
107
        $port = $this->getHeader('X_FORWARDED_PORT');
108
        if ($port) {
109
            return (string)$port;
110
        }
111
112
        $protocol = (string)$this->getHeader('X_FORWARDED_PROTO');
113
        if ($protocol === 'https') {
114
            return '443';
115
        }
116
117
        return (string)$this->getServerVar('SERVER_PORT');
118
    }
119
120
    /**
121
     * Returns the a value from the $_SERVER super global.
122
     *
123
     * @param string $key
124
     *
125
     * @return string
126
     */
127
    protected function getServerVar($key)
128
    {
129
        return isset($_SERVER[$key]) ? $_SERVER[$key] : '';
130
    }
131
132
    /**
133
     * Gets a value from the HTTP request headers.
134
     *
135
     * @param string $key
136
     *
137
     * @return string
138
     */
139
    protected function getHeader($key)
140
    {
141
        return $this->getServerVar('HTTP_' . $key);
142
    }
143
144
    /**
145
     * Checks if the value in X_FORWARDED_HOST is a valid hostname
146
     * Could prevent unintended redirections
147
     *
148
     * @param string $header
149
     *
150
     * @return boolean
151
     */
152
    protected function isValidForwardedHost($header)
153
    {
154
        $elements = explode(',', $header);
155
        $host = $elements[count($elements) - 1];
156
157
        return preg_match("/^([a-z\d](-*[a-z\d])*)(\.([a-z\d](-*[a-z\d])*))*$/i", $host) //valid chars check
158
            && 0 < strlen($host) && strlen($host) < 254 //overall length check
159
            && preg_match("/^[^\.]{1,63}(\.[^\.]{1,63})*$/", $host); //length of each label
160
    }
161
}
162