Skip to content

Commit 28e2a1a

Browse files
authored
Release v1.11.2
2 parents fad8c41 + 4ee55e5 commit 28e2a1a

File tree

6 files changed

+295
-9
lines changed

6 files changed

+295
-9
lines changed

BugsnagBundle.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@ class BugsnagBundle extends Bundle
1111
*
1212
* @return string
1313
*/
14-
const VERSION = '1.11.1';
14+
const VERSION = '1.11.2';
1515
}

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11
Changelog
22
=========
33

4+
## 1.11.2 (2022-02-02)
5+
6+
### Bug Fixes
7+
8+
* Fix PHP 8.1 deprecation from `stripos` in `Request::getInput`
9+
[phillylovepark](https://github.com/phillylovepark)
10+
[#147](https://github.com/bugsnag/bugsnag-symfony/pull/147)
11+
[#149](https://github.com/bugsnag/bugsnag-symfony/pull/149)
12+
413
## 1.11.1 (2022-01-19)
514

615
### Bug Fixes

EventListener/BugsnagShutdown.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
class BugsnagShutdown implements EventSubscriberInterface, ShutdownStrategyInterface
2424
{
2525
/**
26-
* @var Client
26+
* @var Client|null
2727
*/
2828
private $client;
2929

Request/SymfonyRequest.php

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -94,20 +94,18 @@ public function getMetaData()
9494
*
9595
* This is based on Laravel's input source generation.
9696
*
97-
* @return \Symfony\Component\HttpFoundation\ParameterBag
97+
* @return array
9898
*/
9999
protected function getInput()
100100
{
101-
$type = $this->request->headers->get('CONTENT_TYPE');
101+
if ($this->isJsonContentType($this->request->headers->get('CONTENT_TYPE'))) {
102+
$parsed = json_decode($this->request->getContent(), true);
102103

103-
// If it's json, decode it
104-
if (stripos($type, '/json') !== false || stripos($type, '+json') !== false) {
105-
if (is_array($parsed = json_decode($this->request->getContent(), true))) {
104+
if (is_array($parsed)) {
106105
return $parsed;
107106
}
108107
}
109108

110-
// Yes, we really do want request->request
111109
return $this->request->request->all();
112110
}
113111

@@ -130,4 +128,19 @@ public function getUserId()
130128
{
131129
return $this->request->getClientIp();
132130
}
131+
132+
/**
133+
* @param mixed $contentType
134+
*
135+
* @return bool
136+
*/
137+
private function isJsonContentType($contentType)
138+
{
139+
if (is_string($contentType)) {
140+
return stripos($contentType, '/json') !== false
141+
|| stripos($contentType, '+json') !== false;
142+
}
143+
144+
return false;
145+
}
133146
}

Request/SymfonyResolver.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class SymfonyResolver implements ResolverInterface
1818
/**
1919
* Set the current request.
2020
*
21-
* @param \Symfony\Component\HttpFoundation\Request
21+
* @param \Symfony\Component\HttpFoundation\Request $request
2222
*
2323
* @return void
2424
*/

Tests/Request/SymfonyRequestTest.php

Lines changed: 264 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,4 +95,268 @@ public function testResolveSessionWhenPreviousSessionExists()
9595

9696
$this->assertSame(['foobar' => 'baz'], $session);
9797
}
98+
99+
public function testItIsARequest()
100+
{
101+
$request = new SymfonyRequest(new Request());
102+
103+
$this->assertTrue($request->isRequest());
104+
}
105+
106+
public function testItReturnsCookieData()
107+
{
108+
$cookies = ['a_cookie' => 'a value for the first cookie', 'another_cookie' => 'another value'];
109+
110+
$symfonyRequest = new Request([], [], [], $cookies);
111+
112+
$request = new SymfonyRequest($symfonyRequest);
113+
114+
$this->assertSame($cookies, $request->getCookies());
115+
}
116+
117+
public function testItReturnsCookieDataWhenThereAreNoCookies()
118+
{
119+
$symfonyRequest = new Request();
120+
121+
$request = new SymfonyRequest($symfonyRequest);
122+
123+
$this->assertSame([], $request->getCookies());
124+
}
125+
126+
public function testItReturnsMetadataWhenThereIsNoRequestData()
127+
{
128+
$symfonyRequest = new Request();
129+
130+
$request = new SymfonyRequest($symfonyRequest);
131+
132+
$expected = [
133+
'request' => [
134+
'url' => 'http://:/',
135+
'httpMethod' => 'GET',
136+
'params' => [],
137+
'clientIp' => null,
138+
],
139+
];
140+
141+
$this->assertSame($expected, $request->getMetaData());
142+
}
143+
144+
public function testItReturnsMetadataWhenThereIsSomeRequestData()
145+
{
146+
$symfonyRequest = new Request(
147+
['x' => 'y'],
148+
[],
149+
[],
150+
[],
151+
[],
152+
[
153+
'HTTPS' => 'on',
154+
'PHP_SELF' => '/index.php',
155+
'QUERY_STRING' => 'x=y',
156+
'REMOTE_ADDR' => '1.2.3.4',
157+
'REQUEST_METHOD' => 'GET',
158+
'REQUEST_URI' => '/abc',
159+
'SCRIPT_NAME' => '/index.php',
160+
'SERVER_NAME' => 'www.example.com',
161+
'SERVER_PORT' => '1234',
162+
]
163+
);
164+
165+
$request = new SymfonyRequest($symfonyRequest);
166+
167+
$expected = [
168+
'request' => [
169+
'url' => 'https://www.example.com:1234/abc?x=y',
170+
'httpMethod' => 'GET',
171+
'params' => ['x' => 'y'],
172+
'clientIp' => '1.2.3.4',
173+
],
174+
];
175+
176+
$this->assertSame($expected, $request->getMetaData());
177+
}
178+
179+
public function testItIncludesHeadersJsonAndUserAgentInMetadataWhenPresent()
180+
{
181+
$symfonyRequest = new Request(
182+
['x' => 'y'],
183+
[],
184+
[],
185+
[],
186+
[],
187+
[
188+
'HTTPS' => 'on',
189+
'HTTP_ACCEPT' => 'text/html',
190+
'HTTP_ACCEPT_LANGUAGE' => 'en',
191+
'HTTP_ACCEPT_ENCODING' => 'gzip',
192+
'HTTP_CONTENT_TYPE' => 'application/json',
193+
'HTTP_HOST' => 'www.example.com:1234',
194+
'HTTP_USER_AGENT' => 'bugsnag',
195+
'PHP_SELF' => '/index.php',
196+
'QUERY_STRING' => 'x=y',
197+
'REMOTE_ADDR' => '1.2.3.4',
198+
'REQUEST_METHOD' => 'GET',
199+
'REQUEST_URI' => '/abc',
200+
'SCRIPT_NAME' => '/index.php',
201+
'SERVER_NAME' => 'www.example.com',
202+
'SERVER_PORT' => '1234',
203+
],
204+
'{ "a": "b" }'
205+
);
206+
207+
$request = new SymfonyRequest($symfonyRequest);
208+
209+
$expected = [
210+
'request' => [
211+
'url' => 'https://www.example.com:1234/abc?x=y',
212+
'httpMethod' => 'GET',
213+
'params' => ['a' => 'b', 'x' => 'y'],
214+
'clientIp' => '1.2.3.4',
215+
'userAgent' => 'bugsnag',
216+
'headers' => [
217+
'accept' => ['text/html'],
218+
'accept-language' => ['en'],
219+
'accept-encoding' => ['gzip'],
220+
'content-type' => ['application/json'],
221+
'host' => ['www.example.com:1234'],
222+
'user-agent' => ['bugsnag'],
223+
],
224+
],
225+
];
226+
227+
$this->assertSame($expected, $request->getMetaData());
228+
}
229+
230+
/**
231+
* @dataProvider jsonContentTypeProvider
232+
*/
233+
public function testItDecodesJson($contentType)
234+
{
235+
$symfonyRequest = new Request(
236+
[],
237+
[],
238+
[],
239+
[],
240+
[],
241+
['HTTP_CONTENT_TYPE' => $contentType],
242+
'{ "a": "b", "c": "d", "x": { "y": 123 } }'
243+
);
244+
245+
$request = new SymfonyRequest($symfonyRequest);
246+
247+
$expected = ['a' => 'b', 'c' => 'd', 'x' => ['y' => 123]];
248+
$metadata = $request->getMetaData();
249+
250+
$this->assertSame($expected, $metadata['request']['params']);
251+
$this->assertSame($contentType, $metadata['request']['headers']['content-type'][0]);
252+
}
253+
254+
public function jsonContentTypeProvider()
255+
{
256+
return [
257+
'content type: "application/json"' => ['application/json'],
258+
'content type: "/JsOn"' => ['/JsOn'],
259+
'content type: "TEXT/JSON"' => ['TEXT/JSON'],
260+
'content type: "application/stuff+json"' => ['application/stuff+json'],
261+
'content type: "+jSoN"' => ['+jSoN'],
262+
];
263+
}
264+
265+
/**
266+
* @dataProvider nonJsonContentTypeProvider
267+
*/
268+
public function testItDoesNotDecodeNonJsonContentTypes($contentType)
269+
{
270+
$symfonyRequest = new Request(
271+
[],
272+
[],
273+
[],
274+
[],
275+
[],
276+
['HTTP_CONTENT_TYPE' => $contentType],
277+
'{ "a": "b", "c": "d", "x": { "y": 123 } }'
278+
);
279+
280+
$request = new SymfonyRequest($symfonyRequest);
281+
282+
$metadata = $request->getMetaData();
283+
284+
$this->assertEmpty($metadata['request']['params']);
285+
$this->assertSame($contentType, $metadata['request']['headers']['content-type'][0]);
286+
}
287+
288+
public function nonJsonContentTypeProvider()
289+
{
290+
return [
291+
'content type: "application/xml"' => ['application/xml'],
292+
'content type: "/xml"' => ['/xml'],
293+
'content type: "text/xml"' => ['text/xml'],
294+
'content type: "application/stuff+yaml"' => ['application/stuff+yaml'],
295+
'content type: "+yaml"' => ['+yaml'],
296+
];
297+
}
298+
299+
public function testItDoesNotDecodeTheBodyWhenThereIsNoContentType()
300+
{
301+
$symfonyRequest = new Request();
302+
303+
$request = new SymfonyRequest($symfonyRequest);
304+
305+
$metadata = $request->getMetaData();
306+
307+
$this->assertEmpty($metadata['request']['params']);
308+
}
309+
310+
public function testItReturnsTheRequestContext()
311+
{
312+
$symfonyRequest = new Request([], [], [], [], [], [
313+
'REQUEST_METHOD' => 'GET',
314+
'REQUEST_URI' => '/some/route',
315+
]);
316+
317+
$request = new SymfonyRequest($symfonyRequest);
318+
319+
$this->assertSame('GET /some/route', $request->getContext());
320+
}
321+
322+
public function testItReturnsTheRequestContextForAPostRequest()
323+
{
324+
$symfonyRequest = new Request([], [], [], [], [], [
325+
'REQUEST_METHOD' => 'POST',
326+
'REQUEST_URI' => '/some/other/route',
327+
]);
328+
329+
$request = new SymfonyRequest($symfonyRequest);
330+
331+
$this->assertSame('POST /some/other/route', $request->getContext());
332+
}
333+
334+
public function testItReturnsTheRequestContextWhenServerInformationIsMissing()
335+
{
336+
$symfonyRequest = new Request();
337+
338+
$request = new SymfonyRequest($symfonyRequest);
339+
340+
$this->assertSame('GET /', $request->getContext());
341+
}
342+
343+
public function testItReturnsTheUserId()
344+
{
345+
$symfonyRequest = new Request([], [], [], [], [], [
346+
'REMOTE_ADDR' => '1.2.3.4',
347+
]);
348+
349+
$request = new SymfonyRequest($symfonyRequest);
350+
351+
$this->assertSame('1.2.3.4', $request->getUserId());
352+
}
353+
354+
public function testItReturnsTheUserIdWhenServerInformationIsMissing()
355+
{
356+
$symfonyRequest = new Request();
357+
358+
$request = new SymfonyRequest($symfonyRequest);
359+
360+
$this->assertNull($request->getUserId());
361+
}
98362
}

0 commit comments

Comments
 (0)