/** * Run * * This method invokes the middleware stack, including the core Slim application; * the result is an array of HTTP status, header, and body. These three items * are returned to the HTTP client. * * @return void */ public function run() { //Apply final outer middleware layers $this->add(new Slim_Middleware_PrettyExceptions()); //Invoke middleware and application stack $this->middleware[0]->call(); //Fetch status, header, and body list($status, $header, $body) = $this->response->finalize(); //Send headers if (headers_sent() === false) { //Send status if (strpos(PHP_SAPI, 'cgi') === 0) { header(sprintf('Status: %s', Slim_Http_Response::getMessageForCode($status))); } else { header(sprintf('HTTP/%s %s', $this->config('http.version'), Slim_Http_Response::getMessageForCode($status))); } //Send headers foreach ($header as $name => $value) { $hValues = explode("\n", $value); foreach ($hValues as $hVal) { header("{$name}: {$hVal}", false); } } } //Send body echo $body; }
/** * Call * * Iterate each matching Route until all Routes are exhausted. * Return an array of HTTP status, header, and body. * * @param array $env Key-value array of environment properties * @return array [status, header, body] */ public function call(&$env) { try { if (isset($env['slim.flash'])) { $this->view()->setData('flash', $env['slim.flash']); } $this->applyHook('slim.before'); ob_start(); $this->applyHook('slim.before.router'); $dispatched = false; $httpMethodsAllowed = array(); foreach ($this->router as $route) { if ($route->supportsHttpMethod($env['REQUEST_METHOD'])) { try { $this->applyHook('slim.before.dispatch'); $dispatched = $route->dispatch(); $this->applyHook('slim.after.dispatch'); if ($dispatched) { break; } } catch (Slim_Exception_Pass $e) { continue; } } else { $httpMethodsAllowed = array_merge($httpMethodsAllowed, $route->getHttpMethods()); } } if (!$dispatched) { if ($httpMethodsAllowed) { $this->response['Allow'] = implode(' ', $httpMethodsAllowed); $this->halt(405, 'HTTP method not allowed for the requested resource. Use one of these instead: ' . implode(', ', $httpMethodsAllowed)); } else { $this->notFound(); } } $this->applyHook('slim.after.router'); $this->response->write(ob_get_clean()); $this->applyHook('slim.after'); $this->stop(); } catch (Slim_Exception_Stop $e) { $this->response()->write(ob_get_contents()); return $this->response->finalize(); } catch (Slim_Exception_RequestSlash $e) { $this->response->redirect($this->request->getPath() . '/', 301); return $this->response->finalize(); } catch (Exception $e) { if ($this->config('debug')) { throw $e; } else { try { $this->error($e); } catch (Slim_Exception_Stop $e) { } return $this->response->finalize(); } } }
/** * Call * @param array $env * @return array[status, header, body] */ public function call(&$env) { try { return $this->app->call($env); } catch (Exception $e) { $env['slim.log']->error($e); $response = new Slim_Http_Response($this->renderBody($env, $e), 500); return $response->finalize(); } }
/** * Test finalize * * Pre-conditions: * Case A: Response status is 200 * Case B: Response status is 204 * Case C: Response status is 304 * * Post-conditions: * Case A: Response has body and content-length * Case B: Response does not have body and content-length * Case C: Response does not have body and content-length */ public function testFinalize() { //Case A $r1 = new Slim_Http_Response(new Slim_Http_Request()); $r1->body('body1'); $r1->finalize(); $this->assertEquals('body1', $r1->body()); $this->assertEquals(5, $r1->header('Content-Length')); //Case B $r2 = new Slim_Http_Response(new Slim_Http_Request()); $r2->body('body2'); $r2->status(204); $r2->finalize(); $this->assertEquals('', $r2->body()); $this->assertNull($r2->header('Content-Type')); //Case C $r3 = new Slim_Http_Response(new Slim_Http_Request()); $r3->body('body3'); $r3->status(304); $r3->finalize(); $this->assertEquals('', $r3->body()); $this->assertNull($r3->header('Content-Type')); }
/** * Test finalize */ public function testFinalizeWithoutBody() { $r = new Slim_Http_Response(); $r->status(204); $r['Content-Type'] = 'application/json'; $r->write('Foo'); $result = $r->finalize(); $this->assertEquals(3, count($result)); $this->assertEquals('', $result[2]); }
/** * Save session * @param int $status * @param array $header * @param string $body * @return array[status, header, body] */ protected function saveSession(&$env, $status, $header, $body) { $r = new Slim_Http_Response($body, $status, $header); $value = Slim_Http_Util::encodeSecureCookie(serialize($_SESSION), $this->settings['expires'], $this->settings['secret'], $this->settings['cipher'], $this->settings['cipher_mode']); if (strlen($value) > 4096) { fwrite($env['slim.errors'], 'WARNING! Slim_Middleware_SessionCookie data size is larger than 4KB. Content save failed.'); } else { $r->setCookie($this->settings['name'], $value, $this->settings['expires'], $this->settings['path'], $this->settings['domain'], $this->settings['secure'], $this->settings['httponly']); } return $r->finalize(); }