1 | <?php |
||
40 | class Whip |
||
41 | { |
||
42 | |||
43 | /** Indicates all header methods will be used. */ |
||
44 | const ALL_METHODS = 255; |
||
45 | /** Indicates the REMOTE_ADDR method will be used. */ |
||
46 | const REMOTE_ADDR = 1; |
||
47 | /** Indicates a set of possible proxy headers will be used. */ |
||
48 | const PROXY_HEADERS = 2; |
||
49 | /** Indicates any CloudFlare specific headers will be used. */ |
||
50 | const CLOUDFLARE_HEADERS = 4; |
||
51 | /** Indicates any Incapsula specific headers will be used. */ |
||
52 | const INCAPSULA_HEADERS = 8; |
||
53 | /** Indicates custom listed headers will be used. */ |
||
54 | const CUSTOM_HEADERS = 128; |
||
55 | |||
56 | /** The array of mapped header strings. */ |
||
57 | private static $headers = array( |
||
58 | self::CUSTOM_HEADERS => array(), |
||
59 | self::INCAPSULA_HEADERS => array( |
||
60 | 'HTTP_INCAP_CLIENT_IP' |
||
61 | ), |
||
62 | self::CLOUDFLARE_HEADERS => array( |
||
63 | 'HTTP_CF_CONNECTING_IP' |
||
64 | ), |
||
65 | self::PROXY_HEADERS => array( |
||
66 | 'HTTP_CLIENT_IP', |
||
67 | 'HTTP_X_FORWARDED_FOR', |
||
68 | 'HTTP_X_FORWARDED', |
||
69 | 'HTTP_X_CLUSTER_CLIENT_IP', |
||
70 | 'HTTP_FORWARDED_FOR', |
||
71 | 'HTTP_FORWARDED', |
||
72 | 'HTTP_X_REAL_IP', |
||
73 | ), |
||
74 | self::REMOTE_ADDR => array( |
||
75 | 'REMOTE_ADDR' |
||
76 | ), |
||
77 | ); |
||
78 | |||
79 | /** the bitmask of enabled methods */ |
||
80 | private $enabled; |
||
81 | |||
82 | /** the array of IP whitelist ranges to check against */ |
||
83 | private $whitelist; |
||
84 | |||
85 | /** an array holding the source of addresses we will check */ |
||
86 | private $source; |
||
87 | |||
88 | /** |
||
89 | * Constructor for the class. |
||
90 | * @param int $enabled The bitmask of enabled headers. |
||
91 | * @param array $whitelists The array of IP ranges to be whitelisted. |
||
92 | */ |
||
93 | 18 | public function __construct($enabled = self::ALL_METHODS, array $whitelists = array()) |
|
102 | |||
103 | /** |
||
104 | * Adds a custom header to the list. |
||
105 | * @param string $header The custom header to add. |
||
106 | * @return Whip Returns $this. |
||
107 | */ |
||
108 | 1 | public function addCustomHeader($header) |
|
113 | |||
114 | /** |
||
115 | * Sets the source array to use to lookup the addresses. If not specified, |
||
116 | * the class will fallback to $_SERVER. |
||
117 | * @param array $source The source array. |
||
118 | * @return Whip Returns $this. |
||
119 | */ |
||
120 | 1 | public function setSource(array $source) |
|
125 | |||
126 | /** |
||
127 | * Returns the IP address of the client using the given methods. |
||
128 | * @param array $source (optional) The source array. By default, the class |
||
129 | * will use the value passed to Whip::setSource or fallback to |
||
130 | * $_SERVER. |
||
131 | * @return string Returns the IP address as a string or false if no |
||
132 | * IP address could be found. |
||
133 | */ |
||
134 | 18 | public function getIpAddress($source = null) |
|
148 | |||
149 | /** |
||
150 | * Returns the valid IP address or false if no valid IP address was found. |
||
151 | * @param array $source (optional) The source array. By default, the class |
||
152 | * will use the value passed to Whip::setSource or fallback to |
||
153 | * $_SERVER. |
||
154 | * @return string|false Returns the IP address (as a string) of the client or false |
||
155 | * if no valid IP address was found. |
||
156 | */ |
||
157 | 3 | public function getValidIpAddress($source = null) |
|
165 | |||
166 | /** |
||
167 | * Finds the first element in $headers that is present in $_SERVER and |
||
168 | * returns the IP address mapped to that value. |
||
169 | * If the IP address is a list of comma separated values, the last value |
||
170 | * in the list will be returned. |
||
171 | * If no IP address is found, we return false. |
||
172 | * @param array $source The source array to pull the data from. |
||
173 | * @param array $headers The list of headers to check. |
||
174 | * @return string|false Returns the IP address as a string or false if no IP |
||
175 | * IP address was found. |
||
176 | */ |
||
177 | 14 | private function extractAddressFromHeaders($source, $headers) |
|
188 | |||
189 | /** |
||
190 | * Returns whether or not the given IP address is whitelisted for the given |
||
191 | * source key. |
||
192 | * @param string $key The source key. |
||
193 | * @param string $ipAddress The IP address. |
||
194 | * @return boolean Returns true if the IP address is whitelisted and false |
||
195 | * otherwise. Returns true if the source does not have a whitelist |
||
196 | * specified. |
||
197 | */ |
||
198 | 18 | private function isIpWhitelisted($key, $ipAddress) |
|
205 | } |
||
206 |
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: