Response:
%s%s'; 115 | $escapedOutResponseBody = htmlspecialchars($outResponseBody); 116 | $result = sprintf($template, $head, $escapedOutResponseBody, $body); 117 | 118 | $stream = $this->streamFactory->createStream($result); 119 | 120 | return $this->responseFactory->createResponse() 121 | ->withBody($stream) 122 | ->withAddedHeader('Content-type', 'text/html'); 123 | } 124 | 125 | private function attachDebugBarToHtmlResponse(Response $response): Response 126 | { 127 | $head = $this->debugBarRenderer->renderHead(); 128 | $body = $this->debugBarRenderer->render(); 129 | $responseBody = $response->getBody(); 130 | 131 | if (! $responseBody->eof() && $responseBody->isSeekable()) { 132 | $responseBody->seek(0, SEEK_END); 133 | } 134 | $responseBody->write($head . $body); 135 | 136 | return $response; 137 | } 138 | 139 | private function getStaticFile(UriInterface $uri): ?Response 140 | { 141 | $path = $this->extractPath($uri); 142 | 143 | if (strpos($path, $this->debugBarRenderer->getBaseUrl()) !== 0) { 144 | return null; 145 | } 146 | 147 | $pathToFile = substr($path, strlen($this->debugBarRenderer->getBaseUrl())); 148 | 149 | $fullPathToFile = $this->debugBarRenderer->getBasePath() . $pathToFile; 150 | 151 | if (!file_exists($fullPathToFile)) { 152 | return null; 153 | } 154 | 155 | $contentType = $this->getContentTypeByFileName($fullPathToFile); 156 | $stream = $this->streamFactory->createStreamFromResource(fopen($fullPathToFile, 'rb')); 157 | 158 | return $this->responseFactory->createResponse() 159 | ->withBody($stream) 160 | ->withAddedHeader('Content-type', $contentType); 161 | } 162 | 163 | private function extractPath(UriInterface $uri): string 164 | { 165 | // Slim3 compatibility 166 | if ($uri instanceof SlimUri) { 167 | $basePath = $uri->getBasePath(); 168 | if (!empty($basePath)) { 169 | return $basePath; 170 | } 171 | } 172 | return $uri->getPath(); 173 | } 174 | 175 | private function getContentTypeByFileName(string $filename): string 176 | { 177 | $ext = pathinfo($filename, PATHINFO_EXTENSION); 178 | 179 | $map = [ 180 | 'css' => 'text/css', 181 | 'js' => 'text/javascript', 182 | 'otf' => 'font/opentype', 183 | 'eot' => 'application/vnd.ms-fontobject', 184 | 'svg' => 'image/svg+xml', 185 | 'ttf' => 'application/font-sfnt', 186 | 'woff' => 'application/font-woff', 187 | 'woff2' => 'application/font-woff2', 188 | ]; 189 | 190 | return $map[$ext] ?? 'text/plain'; 191 | } 192 | 193 | private function isHtmlResponse(Response $response): bool 194 | { 195 | return $this->isHtml($response, 'Content-Type'); 196 | } 197 | 198 | private function isHtmlAccepted(ServerRequest $request): bool 199 | { 200 | return $this->isHtml($request, 'Accept'); 201 | } 202 | 203 | private function isHtml(MessageInterface $message, string $headerName): bool 204 | { 205 | return strpos($message->getHeaderLine($headerName), 'text/html') !== false; 206 | } 207 | 208 | private function isRedirect(Response $response): bool 209 | { 210 | $statusCode = $response->getStatusCode(); 211 | 212 | return $statusCode >= 300 && $statusCode < 400 && $response->getHeaderLine('Location') !== ''; 213 | } 214 | 215 | private function serializeResponse(Response $response) : string 216 | { 217 | $reasonPhrase = $response->getReasonPhrase(); 218 | $headers = $this->serializeHeaders($response->getHeaders()); 219 | $format = 'HTTP/%s %d%s%s%s'; 220 | 221 | if (! empty($headers)) { 222 | $headers = "\r\n" . $headers; 223 | } 224 | 225 | $headers .= "\r\n\r\n"; 226 | 227 | return sprintf( 228 | $format, 229 | $response->getProtocolVersion(), 230 | $response->getStatusCode(), 231 | ($reasonPhrase ? ' ' . $reasonPhrase : ''), 232 | $headers, 233 | $response->getBody() 234 | ); 235 | } 236 | 237 | /** 238 | * @param array
Response:
HTTP/1.1 200 OK\r\n\r\nResponseBodyRenderBody", (string) $result->getBody()); 82 | } 83 | 84 | public function testForceAttachDebugbarIfCookiePresents(): void 85 | { 86 | $cookies = ['X-Enable-Debug-Bar' => 'true']; 87 | $request = new ServerRequest([], [], null, null, 'php://input', ['Accept' => 'application/json'], $cookies); 88 | $response = new Response(); 89 | $response->getBody()->write('ResponseBody'); 90 | $requestHandler = new RequestHandlerStub($response); 91 | 92 | $result = $this->middleware->process($request, $requestHandler); 93 | 94 | $this->assertSame("RenderHead
Response:
HTTP/1.1 200 OK\r\n\r\nResponseBodyRenderBody", (string) $result->getBody()); 95 | } 96 | 97 | public function testForceAttachDebugbarIfAttributePresents(): void 98 | { 99 | $request = new ServerRequest([], [], null, null, 'php://input', ['Accept' => 'application/json']); 100 | $request = $request->withAttribute('X-Enable-Debug-Bar', 'true'); 101 | $response = new Response(); 102 | $response->getBody()->write('ResponseBody'); 103 | $requestHandler = new RequestHandlerStub($response); 104 | 105 | $result = $this->middleware->process($request, $requestHandler); 106 | 107 | $this->assertSame("RenderHead
Response:
HTTP/1.1 200 OK\r\n\r\nResponseBodyRenderBody", (string) $result->getBody()); 108 | } 109 | 110 | public function testAttachToNoneHtmlResponse(): void 111 | { 112 | $request = new ServerRequest([], [], null, null, 'php://input', ['Accept' => 'text/html']); 113 | $response = (new Response())->withHeader('test-header', 'value'); 114 | $response->getBody()->write('ResponseBody'); 115 | 116 | $requestHandler = new RequestHandlerStub($response); 117 | 118 | $result = $this->middleware->process($request, $requestHandler); 119 | 120 | $this->assertTrue($requestHandler->isCalled(), 'Request handler is not called'); 121 | $this->assertNotSame($response, $result); 122 | $this->assertSame("RenderHead
Response:
HTTP/1.1 200 OK\r\nTest-Header: value\r\n\r\nResponseBodyRenderBody", (string) $result->getBody()); 123 | } 124 | 125 | public function testNotAttachToRedirectResponse(): void 126 | { 127 | $request = new ServerRequest([], [], null, null, 'php://input', ['Accept' => 'text/html']); 128 | $response = (new Response())->withStatus(300)->withAddedHeader('Location', 'some-location'); 129 | 130 | $requestHandler = new RequestHandlerStub($response); 131 | 132 | $result = $this->middleware->process($request, $requestHandler); 133 | 134 | $this->assertSame($response, $result); 135 | } 136 | 137 | public function testAttachToNonRedirectResponse(): void 138 | { 139 | $request = new ServerRequest([], [], null, null, 'php://input', ['Accept' => 'text/html']); 140 | $response = (new Response())->withStatus(299)->withAddedHeader('Location', 'some-location'); 141 | 142 | $requestHandler = new RequestHandlerStub($response); 143 | 144 | $result = $this->middleware->process($request, $requestHandler); 145 | 146 | $this->assertNotSame($response, $result); 147 | } 148 | 149 | public function testAttachToNonRedirectResponse2(): void 150 | { 151 | $request = new ServerRequest([], [], null, null, 'php://input', ['Accept' => 'text/html']); 152 | $response = (new Response())->withStatus(400)->withAddedHeader('Location', 'some-location'); 153 | 154 | $requestHandler = new RequestHandlerStub($response); 155 | 156 | $result = $this->middleware->process($request, $requestHandler); 157 | 158 | $this->assertNotSame($response, $result); 159 | } 160 | 161 | public function testAttachToRedirectResponseWithoutLocation(): void 162 | { 163 | $request = new ServerRequest([], [], null, null, 'php://input', ['Accept' => 'text/html']); 164 | $response = (new Response())->withStatus(302); 165 | 166 | $requestHandler = new RequestHandlerStub($response); 167 | 168 | $result = $this->middleware->process($request, $requestHandler); 169 | 170 | $this->assertTrue($requestHandler->isCalled(), 'Request handler is not called'); 171 | $this->assertNotSame($response, $result); 172 | $this->assertSame("RenderHead
Response:
HTTP/1.1 302 Found\r\n\r\nRenderBody", (string) $result->getBody()); 173 | } 174 | 175 | public function testForceAttachToRedirectResponse(): void 176 | { 177 | $request = new ServerRequest([], [], null, null, 'php://input', ['Accept' => 'text/html', 'X-Enable-Debug-Bar' => 'true']); 178 | $response = (new Response())->withStatus(302)->withAddedHeader('Location', 'some-location'); 179 | 180 | $requestHandler = new RequestHandlerStub($response); 181 | 182 | $result = $this->middleware->process($request, $requestHandler); 183 | 184 | $this->assertTrue($requestHandler->isCalled(), 'Request handler is not called'); 185 | $this->assertNotSame($response, $result); 186 | $this->assertSame("RenderHead
Response:
HTTP/1.1 302 Found\r\nLocation: some-location\r\n\r\nRenderBody", (string) $result->getBody()); 187 | } 188 | 189 | public function testAttachToHtmlResponse(): void 190 | { 191 | $request = new ServerRequest([], [], null, null, 'php://input', ['Accept' => 'text/html']); 192 | $response = new Response('php://memory', 200, ['Content-Type' => 'text/html']); 193 | $response->getBody()->write('ResponseBody'); 194 | $requestHandler = new RequestHandlerStub($response); 195 | 196 | $result = $this->middleware->process($request, $requestHandler); 197 | 198 | $this->assertTrue($requestHandler->isCalled(), 'Request handler is not called'); 199 | $this->assertSame($response, $result); 200 | $this->assertSame('ResponseBodyRenderHeadRenderBody', (string) $result->getBody()); 201 | } 202 | 203 | public function testForceNotAttachDebugbarIfHeaderPresents(): void 204 | { 205 | $request = new ServerRequest([], [], null, null, 'php://input', ['Accept' => 'text/html', 'X-Enable-Debug-Bar' => 'false']); 206 | $response = new Response('php://memory', 200, ['Content-Type' => 'text/html']); 207 | $response->getBody()->write('ResponseBody'); 208 | $requestHandler = new RequestHandlerStub($response); 209 | 210 | $result = $this->middleware->process($request, $requestHandler); 211 | 212 | $this->assertTrue($requestHandler->isCalled(), 'Request handler is not called'); 213 | $this->assertSame($response, $result); 214 | $this->assertSame('ResponseBody', (string) $result->getBody()); 215 | } 216 | 217 | public function testForceNotAttachDebugbarIfCookiePresents(): void 218 | { 219 | $cookie = ['X-Enable-Debug-Bar' => 'false']; 220 | $request = new ServerRequest([], [], null, null, 'php://input', ['Accept' => 'text/html'], $cookie); 221 | $response = new Response('php://memory', 200, ['Content-Type' => 'text/html']); 222 | $response->getBody()->write('ResponseBody'); 223 | $requestHandler = new RequestHandlerStub($response); 224 | 225 | $result = $this->middleware->process($request, $requestHandler); 226 | 227 | $this->assertTrue($requestHandler->isCalled(), 'Request handler is not called'); 228 | $this->assertSame($response, $result); 229 | $this->assertSame('ResponseBody', (string) $result->getBody()); 230 | } 231 | 232 | public function testForceNotAttachDebugbarIfAttributePresents(): void 233 | { 234 | $request = new ServerRequest([], [], null, null, 'php://input', ['Accept' => 'text/html']); 235 | $request = $request->withAttribute('X-Enable-Debug-Bar', 'false'); 236 | $response = new Response('php://memory', 200, ['Content-Type' => 'text/html']); 237 | $response->getBody()->write('ResponseBody'); 238 | $requestHandler = new RequestHandlerStub($response); 239 | 240 | $result = $this->middleware->process($request, $requestHandler); 241 | 242 | $this->assertTrue($requestHandler->isCalled(), 'Request handler is not called'); 243 | $this->assertSame($response, $result); 244 | $this->assertSame('ResponseBody', (string) $result->getBody()); 245 | } 246 | 247 | public function testAppendsToEndOfHtmlResponse(): void 248 | { 249 | $html = '