@@ -66,6 +66,11 @@ public function getIPAddress(): string
6666 // @phpstan-ignore-next-line
6767 $ proxyIPs = $ this ->proxyIPs ?? config (App::class)->proxyIPs ;
6868 // @phpstan-ignore-next-line
69+
70+ // Workaround for old Config\App file. App::$proxyIPs may be empty string.
71+ if ($ proxyIPs === '' ) {
72+ $ proxyIPs = [];
73+ }
6974 if (! empty ($ proxyIPs ) && (! is_array ($ proxyIPs ) || is_int (array_key_first ($ proxyIPs )))) {
7075 throw new ConfigException (
7176 'You must set an array with Proxy IP address key and HTTP header name value in Config\App::$proxyIPs. '
@@ -79,76 +84,74 @@ public function getIPAddress(): string
7984 return $ this ->ipAddress = '0.0.0.0 ' ;
8085 }
8186
82- if ($ proxyIPs ) {
83- // @TODO Extract all this IP address logic to another class.
84- foreach ($ proxyIPs as $ proxyIP => $ header ) {
85- // Check if we have an IP address or a subnet
86- if (strpos ($ proxyIP , '/ ' ) === false ) {
87- // An IP address (and not a subnet) is specified.
88- // We can compare right away.
89- if ($ proxyIP === $ this ->ipAddress ) {
90- $ spoof = $ this ->getClientIP ($ header );
91-
92- if ($ spoof !== null ) {
93- $ this ->ipAddress = $ spoof ;
94- break ;
95- }
96- }
87+ // @TODO Extract all this IP address logic to another class.
88+ foreach ($ proxyIPs as $ proxyIP => $ header ) {
89+ // Check if we have an IP address or a subnet
90+ if (strpos ($ proxyIP , '/ ' ) === false ) {
91+ // An IP address (and not a subnet) is specified.
92+ // We can compare right away.
93+ if ($ proxyIP === $ this ->ipAddress ) {
94+ $ spoof = $ this ->getClientIP ($ header );
9795
98- continue ;
96+ if ($ spoof !== null ) {
97+ $ this ->ipAddress = $ spoof ;
98+ break ;
99+ }
99100 }
100101
101- // We have a subnet ... now the heavy lifting begins
102- if (! isset ($ separator )) {
103- $ separator = $ ipValidator ($ this ->ipAddress , 'ipv6 ' ) ? ': ' : '. ' ;
104- }
102+ continue ;
103+ }
105104
106- // If the proxy entry doesn't match the IP protocol - skip it
107- if (strpos ( $ proxyIP , $ separator ) === false ) {
108- continue ;
109- }
105+ // We have a subnet ... now the heavy lifting begins
106+ if (! isset ( $ separator )) {
107+ $ separator = $ ipValidator ( $ this -> ipAddress , ' ipv6 ' ) ? ' : ' : ' . ' ;
108+ }
110109
111- // Convert the REMOTE_ADDR IP address to binary, if needed
112- if (! isset ($ ip , $ sprintf )) {
113- if ($ separator === ': ' ) {
114- // Make sure we're having the "full" IPv6 format
115- $ ip = explode (': ' , str_replace (':: ' , str_repeat (': ' , 9 - substr_count ($ this ->ipAddress , ': ' )), $ this ->ipAddress ));
110+ // If the proxy entry doesn't match the IP protocol - skip it
111+ if (strpos ($ proxyIP , $ separator ) === false ) {
112+ continue ;
113+ }
116114
117- for ($ j = 0 ; $ j < 8 ; $ j ++) {
118- $ ip [$ j ] = intval ($ ip [$ j ], 16 );
119- }
115+ // Convert the REMOTE_ADDR IP address to binary, if needed
116+ if (! isset ($ ip , $ sprintf )) {
117+ if ($ separator === ': ' ) {
118+ // Make sure we're having the "full" IPv6 format
119+ $ ip = explode (': ' , str_replace (':: ' , str_repeat (': ' , 9 - substr_count ($ this ->ipAddress , ': ' )), $ this ->ipAddress ));
120120
121- $ sprintf = '%016b%016b%016b%016b%016b%016b%016b%016b ' ;
122- } else {
123- $ ip = explode ('. ' , $ this ->ipAddress );
124- $ sprintf = '%08b%08b%08b%08b ' ;
121+ for ($ j = 0 ; $ j < 8 ; $ j ++) {
122+ $ ip [$ j ] = intval ($ ip [$ j ], 16 );
125123 }
126124
127- $ ip = vsprintf ($ sprintf , $ ip );
125+ $ sprintf = '%016b%016b%016b%016b%016b%016b%016b%016b ' ;
126+ } else {
127+ $ ip = explode ('. ' , $ this ->ipAddress );
128+ $ sprintf = '%08b%08b%08b%08b ' ;
128129 }
129130
130- // Split the netmask length off the network address
131- sscanf ( $ proxyIP , ' %[^/]/%d ' , $ netaddr , $ masklen );
131+ $ ip = vsprintf ( $ sprintf , $ ip );
132+ }
132133
133- // Again, an IPv6 address is most likely in a compressed form
134- if ($ separator === ': ' ) {
135- $ netaddr = explode (': ' , str_replace (':: ' , str_repeat (': ' , 9 - substr_count ($ netaddr , ': ' )), $ netaddr ));
134+ // Split the netmask length off the network address
135+ sscanf ($ proxyIP , '%[^/]/%d ' , $ netaddr , $ masklen );
136136
137- for ($ i = 0 ; $ i < 8 ; $ i ++) {
138- $ netaddr [$ i ] = intval ($ netaddr [$ i ], 16 );
139- }
140- } else {
141- $ netaddr = explode ('. ' , $ netaddr );
137+ // Again, an IPv6 address is most likely in a compressed form
138+ if ($ separator === ': ' ) {
139+ $ netaddr = explode (': ' , str_replace (':: ' , str_repeat (': ' , 9 - substr_count ($ netaddr , ': ' )), $ netaddr ));
140+
141+ for ($ i = 0 ; $ i < 8 ; $ i ++) {
142+ $ netaddr [$ i ] = intval ($ netaddr [$ i ], 16 );
142143 }
144+ } else {
145+ $ netaddr = explode ('. ' , $ netaddr );
146+ }
143147
144- // Convert to binary and finally compare
145- if (strncmp ($ ip , vsprintf ($ sprintf , $ netaddr ), $ masklen ) === 0 ) {
146- $ spoof = $ this ->getClientIP ($ header );
148+ // Convert to binary and finally compare
149+ if (strncmp ($ ip , vsprintf ($ sprintf , $ netaddr ), $ masklen ) === 0 ) {
150+ $ spoof = $ this ->getClientIP ($ header );
147151
148- if ($ spoof !== null ) {
149- $ this ->ipAddress = $ spoof ;
150- break ;
151- }
152+ if ($ spoof !== null ) {
153+ $ this ->ipAddress = $ spoof ;
154+ break ;
152155 }
153156 }
154157 }
0 commit comments