/** * Send HTTP response * * Send the specific X-Sendfile HTTP headers for internal processing by the server. For Nginx and Lighttpd 1.4 * remove the X-Sendfile header and use the specific header instead. * * If the X-Sendfile header is 1 or TRUE, the response path will be used instead of the path supplied in the * header. If X-Sendfile header is 0 or FALSE the header is ignored and removed. * * - Apache : X-Sendfile * - Nginx : X-Accel-Redirect * - Lightttpd : X-LIGHTTPD-send-file (v1.4) or X-Sendfile (v1.5) * * @param KDispatcherResponseInterface $response * @return boolean */ public function send(KDispatcherResponseInterface $response) { if ($response->headers->has('X-Sendfile')) { $path = $response->headers->get('X-Sendfile'); if ($path === true || $path === 1) { $path = $response->getStream()->getPath(); } if (is_file($path)) { $server = strtolower($_SERVER['SERVER_SOFTWARE']); //Nginx uses X-Accel-Redirect header if (strpos($server, 'nginx') !== FALSE) { $path = preg_replace('/' . preg_quote(Koowa::getRootPath(), '/') . '/', '', $path, 1); $response->headers->set('X-Accel-Redirect', $path); $response->headers->remove('X-Sendfile'); } //Lighttpd 1.4 uses X-LIGHTTPD-send-file header if (strpos($server, 'lightttpd/1.4') !== FALSE) { $response->headers->set('X-LIGHTTPD-send-file', $path); $response->headers->remove('X-Sendfile'); } return parent::send($response); } else { $response->headers->remove('X-Sendfile'); } } }
/** * Send HTTP response * * If this is a redirect response, send the response and stop the transport handler chain. * * @param KDispatcherResponseInterface $response * @return boolean */ public function send(KDispatcherResponseInterface $response) { if ($response->isRedirect()) { $session = $response->getUser()->getSession(); //Set the messages into the session $messages = $response->getMessages(); if (count($messages)) { //Auto start the session if it's not active. if (!$session->isActive()) { $session->start(); } $session->getContainer('message')->add($messages); } //Set the redirect into the response $response->setContent(sprintf('<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="refresh" content="1;url=%1$s" /> <title>Redirecting to %1$s</title> </head> <body> Redirecting to <a href="%1$s">%1$s</a>. </body> </html>', htmlspecialchars($response->headers->get('Location'), ENT_QUOTES, 'UTF-8')), 'text/html'); return parent::send($response); } }
/** * Send HTTP response * * @param KDispatcherResponseInterface $response * @return boolean */ public function send(KDispatcherResponseInterface $response) { $request = $response->getRequest(); if (!$response->isDownloadable() && $request->getFormat() == 'html') { //Render the page $this->getObject('com:koowa.controller.page', array('response' => $response))->layout($request->query->get('tmpl', 'cmd') == 'koowa' ? 'koowa' : 'joomla')->render(); //Pass back to Joomla if ($request->isGet() && $request->query->get('tmpl', 'cmd') != 'koowa') { //Mimetype JFactory::getDocument()->setMimeEncoding($response->getContentType()); //Remove Content-Type header to prevent duplicate header conflict (see #172) $response->headers->remove('Content-Type'); //Headers $headers = explode("\r\n", trim((string) $response->headers)); foreach ($headers as $header) { $parts = explode(':', $header, 2); if (count($parts) !== 2) { // Empty values are not allowed per RFC2616 Sec 4.2 continue; } // JResponse doesn't play well with cookie headers for some reason if ($parts[0] === 'Set-Cookie') { continue; } JResponse::setHeader($parts[0], $parts[1]); } //Cookies foreach ($response->headers->getCookies() as $cookie) { setcookie($cookie->name, $cookie->value, $cookie->expire, $cookie->path, $cookie->domain, $cookie->isSecure(), $cookie->isHttpOnly()); } //Set messages for any request method $messages = $response->getMessages(); foreach ($messages as $type => $group) { if ($type === 'success') { $type = 'message'; } foreach ($group as $message) { JFactory::getApplication()->enqueueMessage($message, $type); } } //Content echo $response->getContent(); return true; } } return parent::send($response); }
/** * Send HTTP response * * @param KDispatcherResponseInterface $response * @return boolean */ public function send(KDispatcherResponseInterface $response) { $request = $response->getRequest(); if ($response->isStreamable()) { //Explicitly set the Accept Ranges header to bytes to inform client we accept range requests $response->headers->set('Accept-Ranges', 'bytes'); //Set a file etag $response->headers->set('etag', $this->getFileEtag($response)); if ($request->isStreaming()) { if ($response->isSuccess()) { //Default Content-Type Header if (!$response->headers->has('Content-Type')) { $response->headers->set('Content-Type', 'application/octet-stream'); } //Content Range Headers $offset = $this->getOffset($response); $range = $this->getRange($response); $size = $this->getFileSize($response); $response->setStatus(KHttpResponse::PARTIAL_CONTENT); $response->headers->set('Content-Length', $range - $offset + 1); $response->headers->set('Content-Range', sprintf('bytes %s-%s/%s', $offset, $range, $size)); } if ($response->isError()) { /** * A server sending a response with status code 416 (Requested range not satisfiable) SHOULD include a * Content-Range field with a byte-range- resp-spec of "*". The instance-length specifies the current * length of the selected resource. * * @see : http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.16 */ if ($response->getStatusCode() == KHttpResponse::REQUESTED_RANGE_NOT_SATISFIED) { $size = $this->getFileSize($response); $response->headers->set('Content-Range', sprintf('bytes */%s', $size)); } } } } return parent::send($response); }