This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | namespace Germania\ClientIpLocation; |
||
3 | |||
4 | use Psr\Http\Client\ClientInterface; |
||
5 | use Psr\Http\Client\ClientExceptionInterface; |
||
6 | |||
7 | use Psr\Http\Message\RequestInterface; |
||
8 | use Psr\Http\Message\RequestFactoryInterface; |
||
9 | use Psr\Http\Message\ResponseInterface; |
||
10 | |||
11 | use Psr\Log\LoggerInterface; |
||
12 | use Psr\Log\NullLogger; |
||
13 | use Psr\Log\LogLevel; |
||
14 | use Psr\Log\LoggerAwareTrait; |
||
15 | |||
16 | class HttpClientLocationCreator |
||
17 | { |
||
18 | use LoggerAwareTrait; |
||
19 | 1 | ||
20 | /** |
||
21 | * @var ClientInterface |
||
22 | */ |
||
23 | protected $client; |
||
24 | |||
25 | |||
26 | /** |
||
27 | * @var RequestFactoryInterface |
||
28 | */ |
||
29 | public $request_factory; |
||
30 | |||
31 | |||
32 | /** |
||
33 | * Geocoder API endpoint. |
||
34 | * |
||
35 | * @var string |
||
36 | */ |
||
37 | public $api; |
||
38 | |||
39 | |||
40 | /** |
||
41 | * IP adress query parameter |
||
42 | * |
||
43 | * @var string |
||
44 | */ |
||
45 | public $ip_var_name = "ip"; |
||
46 | |||
47 | |||
48 | /** |
||
49 | * @var callable |
||
50 | */ |
||
51 | public $response_decoder; |
||
52 | |||
53 | |||
54 | /** |
||
55 | * @var mixed |
||
56 | */ |
||
57 | public $default_location; |
||
58 | |||
59 | |||
60 | /** |
||
61 | * @var string |
||
62 | */ |
||
63 | protected $error_loglevel = LogLevel::ERROR; |
||
64 | |||
65 | |||
66 | /** |
||
67 | * @var string |
||
68 | */ |
||
69 | protected $client_exception_loglevel = LogLevel::NOTICE; |
||
70 | |||
71 | |||
72 | /** |
||
73 | 2 | * @param string $api Geocoder API endpoint |
|
74 | * @param ClientInterface $client PSR-18 HTTP Client |
||
75 | 2 | * @param RequestFactoryInterface $request_factory PSR-17 Request factory |
|
76 | 2 | * @param callable|null $response_decoder Optional: PSR-7 Response decoder callable |
|
77 | 2 | */ |
|
78 | 2 | public function __construct( string $api, ClientInterface $client, RequestFactoryInterface $request_factory, callable $response_decoder = null, LoggerInterface $logger = null) |
|
79 | 2 | { |
|
80 | 2 | $this->setApiEndpoint( $api ) |
|
81 | ->setClient($client) |
||
82 | ->setRequestFactory($request_factory) |
||
83 | ->setResponseDecoder($response_decoder) |
||
84 | ->setLogger( $logger ?: new NullLogger); |
||
85 | } |
||
86 | |||
87 | 2 | ||
88 | |||
89 | 2 | /** |
|
90 | * @param string $client_ip Client IP address |
||
91 | */ |
||
92 | 2 | public function __invoke( string $client_ip ) |
|
93 | 2 | { |
|
94 | $request = $this->createRequest($client_ip); |
||
95 | |||
96 | try { |
||
97 | $response = $this->client->sendRequest( $request); |
||
98 | $response_status = $response->getStatusCode(); |
||
99 | |||
100 | switch($response_status): |
||
101 | case 200: |
||
102 | return $this->decodeResponse($response); |
||
103 | break; |
||
0 ignored issues
–
show
|
|||
104 | |||
105 | case 404: |
||
106 | $msg = sprintf("Could not find location for IP address"); |
||
107 | throw new ClientException($msg, $response_status); |
||
108 | break; |
||
0 ignored issues
–
show
break; does not seem to be reachable.
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed. Unreachable code is most often the result of function fx() {
try {
doSomething();
return true;
}
catch (\Exception $e) {
return false;
}
return false;
}
In the above example, the last ![]() |
|||
109 | |||
110 | default: |
||
111 | $msg = sprintf("Error response with error status code: '%s'", $response_status); |
||
112 | throw new ClientException($msg, $response_status); |
||
113 | |||
114 | endswitch; |
||
115 | 4 | } |
|
116 | catch (ClientExceptionInterface $e) { |
||
117 | 4 | $msg_location = sprintf("%s:%s", $e->getFile(), $e->getLine()); |
|
118 | 4 | ||
119 | $this->logger->log( $this->client_exception_loglevel, $e->getMessage(), [ |
||
120 | 4 | 'type' => get_class($e), |
|
121 | 'code' => $e->getCode(), |
||
122 | 4 | 'request' => $request->getUri()->__toString(), |
|
123 | 'location' => $msg_location, |
||
124 | 'apiEndpoint' => $this->api, |
||
125 | 'clientIp' => $client_ip |
||
126 | ]); |
||
127 | |||
128 | return $this->default_location; |
||
129 | } |
||
130 | catch (\Throwable $e) { |
||
131 | 4 | $msg = sprintf("Exception caught in HttpClientLocationCreator: %s", $e->getMessage()); |
|
132 | $msg_location = sprintf("%s:%s", $e->getFile(), $e->getLine()); |
||
133 | 4 | $this->logger->log( $this->error_loglevel, $msg, [ |
|
134 | 4 | 'type' => get_class($e), |
|
135 | 4 | 'code' => $e->getCode(), |
|
136 | 'request' => $request->getUri()->__toString(), |
||
137 | 'location' => $msg_location, |
||
138 | 'apiEndpoint' => $this->api, |
||
139 | 'clientIp' => $client_ip |
||
140 | ]); |
||
141 | |||
142 | return $this->default_location; |
||
143 | } |
||
144 | } |
||
145 | 2 | ||
146 | |||
147 | 2 | ||
148 | 2 | /** |
|
149 | * @param string $client_ip Client IP address |
||
150 | * @return RequestInterface |
||
151 | */ |
||
152 | public function createRequest( string $client_ip ) : RequestInterface |
||
153 | { |
||
154 | $client_ip_urlencoded = urlencode($client_ip); |
||
155 | $query_parameter_field = "{{" . $this->ip_var_name . "}}"; |
||
156 | |||
157 | $api = str_replace($query_parameter_field, $client_ip_urlencoded, $this->api); |
||
158 | 4 | ||
159 | return $this->request_factory->createRequest("GET", $api); |
||
160 | 4 | } |
|
161 | 4 | ||
162 | |||
163 | |||
164 | /** |
||
165 | * @param ResponseInterface $response |
||
166 | * @return mixed |
||
167 | */ |
||
168 | public function decodeResponse(ResponseInterface $response) |
||
169 | { |
||
170 | return $this->response_decoder |
||
171 | 6 | ? ($this->response_decoder)($response) |
|
172 | : json_decode($response->getBody(), "assoc"); |
||
173 | 6 | } |
|
174 | 6 | ||
175 | |||
176 | |||
177 | /** |
||
178 | * Sets the default location to return on error |
||
179 | * |
||
180 | * @param mixed $location |
||
181 | */ |
||
182 | public function setDefaultLocation( $location ) : self |
||
183 | 4 | { |
|
184 | $this->default_location = $location; |
||
185 | 4 | return $this; |
|
186 | 4 | } |
|
187 | |||
188 | |||
189 | /** |
||
190 | * @param string $error_loglevel PSR-3 Loglevel name |
||
191 | */ |
||
192 | public function setErrorLoglevel( string $error_loglevel ) { |
||
193 | $this->error_loglevel = $error_loglevel; |
||
194 | return $this; |
||
195 | 4 | } |
|
196 | |||
197 | 4 | ||
198 | 4 | ||
199 | /** |
||
200 | * @param string $client_exception_loglevel PSR-3 Loglevel name |
||
201 | */ |
||
202 | public function setClientExceptionLoglevel( string $client_exception_loglevel ) { |
||
203 | $this->client_exception_loglevel = $client_exception_loglevel; |
||
204 | return $this; |
||
205 | } |
||
206 | |||
207 | |||
208 | /** |
||
209 | * Sets the API endpoint |
||
210 | * |
||
211 | * @param string $api |
||
212 | */ |
||
213 | public function setApiEndpoint( string $api ) : self |
||
214 | { |
||
215 | $this->api = $api; |
||
216 | return $this; |
||
217 | } |
||
218 | |||
219 | |||
220 | |||
221 | /** |
||
222 | * Sets the HTTP Client to use. |
||
223 | * |
||
224 | * @param ClientInterface $client |
||
225 | */ |
||
226 | public function setClient( ClientInterface $client ) : self |
||
227 | { |
||
228 | $this->client = $client; |
||
229 | return $this; |
||
230 | } |
||
231 | |||
232 | |||
233 | /** |
||
234 | * Sets the PSR-17 Request factory |
||
235 | * |
||
236 | * @param RequestFactoryInterface $request_factory |
||
237 | */ |
||
238 | public function setRequestFactory( RequestFactoryInterface $request_factory ) : self |
||
239 | { |
||
240 | $this->request_factory = $request_factory; |
||
241 | return $this; |
||
242 | } |
||
243 | |||
244 | |||
245 | /** |
||
246 | * Sets the PSR-7 Response decoder callable. |
||
247 | * |
||
248 | * @param callable $response_decoder |
||
249 | */ |
||
250 | public function setResponseDecoder( callable $response_decoder = null ) : self |
||
251 | { |
||
252 | $this->response_decoder = $response_decoder; |
||
253 | return $this; |
||
254 | } |
||
255 | |||
256 | } |
||
257 |
The break statement is not necessary if it is preceded for example by a return statement:
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.