/** * Checks to see if a page should be updated or send Not Modified status * * @param integer Seconds added to the modified time received to calculate what should be sent * @return bool FALSE when the request needs to be updated */ public static function check($seconds = 60) { if (!empty($_SERVER['HTTP_IF_MODIFIED_SINCE']) and expires::check_headers()) { if (($strpos = strpos($_SERVER['HTTP_IF_MODIFIED_SINCE'], ';')) !== FALSE) { // IE6 and perhaps other IE versions send length too, compensate here $mod_time = substr($_SERVER['HTTP_IF_MODIFIED_SINCE'], 0, $strpos); } else { $mod_time = $_SERVER['HTTP_IF_MODIFIED_SINCE']; } $mod_time = strtotime($mod_time); $mod_time_diff = $mod_time + $seconds - time(); if ($mod_time_diff > 0) { // Re-send headers header('Last-Modified: ' . gmdate('D, d M Y H:i:s T', $mod_time)); header('Expires: ' . gmdate('D, d M Y H:i:s T', time() + $mod_time_diff)); header('Cache-Control: max-age=' . $mod_time_diff); header('Status: 304 Not Modified', TRUE, 304); // Prevent any output Event::add('system.display', array('expires', 'prevent_output')); // Exit to prevent other output exit; } } return FALSE; }
static function get($request) { $item = rest::resolve($request->url); $p = $request->params; if (!isset($p->size) || !in_array($p->size, array("thumb", "resize", "full"))) { throw new Rest_Exception("Bad Request", 400, array("errors" => array("size" => "invalid"))); } // Note: this code is roughly duplicated in file_proxy, so if you modify this, please look to // see if you should make the same change there as well. if ($p->size == "full") { if ($item->is_album()) { throw new Kohana_404_Exception(); } access::required("view_full", $item); $file = $item->file_path(); } else { if ($p->size == "resize") { access::required("view", $item); $file = $item->resize_path(); } else { access::required("view", $item); $file = $item->thumb_path(); } } if (!file_exists($file)) { throw new Kohana_404_Exception(); } header("Content-Length: " . filesize($file)); if (isset($p->m)) { header("Pragma:"); // Check that the content hasn't expired or it wasn't changed since cached expires::check(2592000, $item->updated); expires::set(2592000, $item->updated); // 30 days } // We don't need to save the session for this request Session::instance()->abort_save(); // Dump out the image. If the item is a movie or album, then its thumbnail will be a JPG. if (($item->is_movie() || $item->is_album()) && $p->size == "thumb") { header("Content-Type: image/jpeg"); } else { header("Content-Type: {$item->mime_type}"); } if (TEST_MODE) { return $file; } else { Kohana::close_buffers(false); if (isset($p->encoding) && $p->encoding == "base64") { print base64_encode(file_get_contents($file)); } else { readfile($file); } } // We must exit here to keep the regular REST framework reply code from adding more bytes on // at the end or tinkering with headers. exit; }
/** * Checks to see if content should be updated otherwise sends Not Modified status * and exits. * * @uses exit() * @uses expires::get() * * @param integer Maximum age of the content in seconds * @return integer|boolean Timestamp of the If-Modified-Since header or FALSE when header is lacking or malformed */ public static function check($seconds = 60) { if ($last_modified = expires::get()) { $expires = $last_modified + $seconds; $max_age = $expires - time(); if ($max_age > 0) { // Content has not expired header($_SERVER['SERVER_PROTOCOL'] . ' 304 Not Modified'); header('Last-Modified: ' . gmdate('D, d M Y H:i:s T', $last_modified)); // HTTP 1.0 header('Expires: ' . gmdate('D, d M Y H:i:s T', $expires)); // HTTP 1.1 header('Cache-Control: max-age=' . $max_age); // Clear any output Event::add('system.display', create_function('', 'Kohana::$output = "";')); exit; } } return $last_modified; }
public function __construct() { parent::__construct(); expires::set(600); Kohana::config_set('locale', 'ru_RU'); $this->input = new Input(); $this->session = new Session(); // TODO $this->db = new Database(); $this->db->query("SET NAMES 'utf8';"); $this->db->query("SET NAMES 'utf8' COLLATE 'utf8_general_ci'"); $this->db->query("SET SESSION time_zone = '+3:00';"); $this->selected_page = null; $this->selected_subpage = null; $this->error = null; $this->info = null; $this->moderId = 0; if ($this->session->get("access")) { $this->access = $this->session->get("access"); $this->moderId = $this->session->get("moderId"); } else { $this->access = ACCESS_GUEST; } }
public function __call($function, $args) { // request_uri: gallery3/var/trunk/albums/foo/bar.jpg $request_uri = rawurldecode(Input::instance()->server("REQUEST_URI")); $request_uri = preg_replace("/\\?.*/", "", $request_uri); // var_uri: gallery3/var/ $var_uri = url::file("var/"); // Make sure that the request is for a file inside var $offset = strpos(rawurldecode($request_uri), $var_uri); if ($offset !== 0) { throw new Kohana_404_Exception(); } $file_uri = substr($request_uri, strlen($var_uri)); // Make sure that we don't leave the var dir if (strpos($file_uri, "..") !== false) { throw new Kohana_404_Exception(); } list($type, $path) = explode("/", $file_uri, 2); if ($type != "resizes" && $type != "albums" && $type != "thumbs") { throw new Kohana_404_Exception(); } // If the last element is .album.jpg, pop that off since it's not a real item $path = preg_replace("|/.album.jpg\$|", "", $path); $encoded_path = array(); foreach (explode("/", $path) as $path_part) { $encoded_path[] = rawurlencode($path_part); } // We now have the relative path to the item. Search for it in the path cache // The patch cache is urlencoded so re-encode the path. (it was decoded earlier to // insure that the paths are normalized. $item = ORM::factory("item")->where("relative_path_cache", "=", implode("/", $encoded_path))->find(); if (!$item->loaded()) { // We didn't turn it up. It's possible that the relative_path_cache is out of date here. // There was fallback code, but bharat deleted it in 8f1bca74. If it turns out to be // necessary, it's easily resurrected. // If we're looking for a .jpg then it's it's possible that we're requesting the thumbnail // for a movie. In that case, the .flv or .mp4 file would have been converted to a .jpg. // So try some alternate types: if (preg_match('/.jpg$/', $path)) { foreach (array("flv", "mp4") as $ext) { $movie_path = preg_replace('/.jpg$/', ".{$ext}", $path); $item = ORM::factory("item")->where("relative_path_cache", "=", $movie_path)->find(); if ($item->loaded()) { break; } } } } if (!$item->loaded()) { throw new Kohana_404_Exception(); } // Make sure we have access to the item if (!access::can("view", $item)) { throw new Kohana_404_Exception(); } // Make sure we have view_full access to the original if ($type == "albums" && !access::can("view_full", $item)) { throw new Kohana_404_Exception(); } // Don't try to load a directory if ($type == "albums" && $item->is_album()) { throw new Kohana_404_Exception(); } if ($type == "albums") { $file = $item->file_path(); } else { if ($type == "resizes") { $file = $item->resize_path(); } else { $file = $item->thumb_path(); } } if (!file_exists($file)) { throw new Kohana_404_Exception(); } header("Pragma:"); // Check that the content hasn't expired or it wasn't changed since cached expires::check(2592000, $item->updated); // We don't need to save the session for this request Session::abort_save(); expires::set(2592000, $item->updated); // 30 days // Dump out the image. If the item is a movie, then its thumbnail will be a JPG. if ($item->is_movie() && $type != "albums") { header("Content-type: image/jpeg"); } else { header("Content-Type: {$item->mime_type}"); } Kohana::close_buffers(false); $fd = fopen($file, "rb"); fpassthru($fd); fclose($fd); }
public function _send_headers() { // We don't want to mess with the headers on error pages if (!headers_sent() and !Kohana::$has_error) { // If the mimetype isn't manually set ... if (empty($this->content_type)) { // Get mimetype based on extension $mimes = Kohana::config('mimes.' . strtolower($this->extension)); // Use default if none found $this->content_type = isset($mimes[0]) ? $mimes[0] : 'application/octet-stream'; } header('Content-type: ' . $this->content_type); // Set client-side caching time if ($this->expiry_time) { expires::set($this->expiry_time); } } }
public function __call($function, $args) { // Force zlib compression off. Image and movie files are already compressed and // recompressing them is CPU intensive. if (ini_get("zlib.output_compression")) { ini_set("zlib.output_compression", "Off"); } // request_uri: gallery3/var/albums/foo/bar.jpg?m=1234 $request_uri = rawurldecode(Input::instance()->server("REQUEST_URI")); // get rid of query parameters // request_uri: gallery3/var/albums/foo/bar.jpg $request_uri = preg_replace("/\\?.*/", "", $request_uri); // var_uri: gallery3/var/ $var_uri = url::file("var/"); // Make sure that the request is for a file inside var $offset = strpos(rawurldecode($request_uri), $var_uri); if ($offset !== 0) { throw new Kohana_404_Exception(); } // file_uri: albums/foo/bar.jpg $file_uri = substr($request_uri, strlen($var_uri)); // type: albums // path: foo/bar.jpg list($type, $path) = explode("/", $file_uri, 2); if ($type != "resizes" && $type != "albums" && $type != "thumbs") { throw new Kohana_404_Exception(); } // If the last element is .album.jpg, pop that off since it's not a real item $path = preg_replace("|/.album.jpg\$|", "", $path); $item = item::find_by_path($path); if (!$item->loaded()) { // We didn't turn it up. If we're looking for a .jpg then it's it's possible that we're // requesting the thumbnail for a movie. In that case, the .flv, .mp4 or .m4v file would // have been converted to a .jpg. So try some alternate types: if (preg_match('/.jpg$/', $path)) { foreach (array("flv", "mp4", "m4v") as $ext) { $movie_path = preg_replace('/.jpg$/', ".{$ext}", $path); $item = item::find_by_path($movie_path); if ($item->loaded()) { break; } } } } if (!$item->loaded()) { throw new Kohana_404_Exception(); } // Make sure we have access to the item if (!access::can("view", $item)) { throw new Kohana_404_Exception(); } // Make sure we have view_full access to the original if ($type == "albums" && !access::can("view_full", $item)) { throw new Kohana_404_Exception(); } // Don't try to load a directory if ($type == "albums" && $item->is_album()) { throw new Kohana_404_Exception(); } if ($type == "albums") { $file = $item->file_path(); } else { if ($type == "resizes") { $file = $item->resize_path(); } else { $file = $item->thumb_path(); } } if (!file_exists($file)) { throw new Kohana_404_Exception(); } header("Content-Length: " . filesize($file)); header("Pragma:"); // Check that the content hasn't expired or it wasn't changed since cached expires::check(2592000, $item->updated); // We don't need to save the session for this request Session::instance()->abort_save(); expires::set(2592000, $item->updated); // 30 days // Dump out the image. If the item is a movie, then its thumbnail will be a JPG. if ($item->is_movie() && $type != "albums") { header("Content-Type: image/jpeg"); } else { header("Content-Type: {$item->mime_type}"); } // Don't use Kohana::close_buffers(false) here because that only closes all the buffers // that Kohana started. We want to close *all* buffers at this point because otherwise we're // going to buffer up whatever file we're proxying (and it may be very large). This may // affect embedding or systems with PHP's output_buffering enabled. while (ob_get_level()) { Kohana_Log::add("error", "" . print_r(ob_get_level(), 1)); if (!@ob_end_clean()) { // ob_end_clean() can return false if the buffer can't be removed for some reason // (zlib output compression buffers sometimes cause problems). break; } } readfile($file); }
public function __call($function, $args) { // request_uri: gallery3/var/albums/foo/bar.jpg?m=1234 $request_uri = rawurldecode(Input::instance()->server("REQUEST_URI")); // get rid of query parameters // request_uri: gallery3/var/albums/foo/bar.jpg $request_uri = preg_replace("/\\?.*/", "", $request_uri); // var_uri: gallery3/var/ $var_uri = url::file("var/"); // Make sure that the request is for a file inside var $offset = strpos(rawurldecode($request_uri), $var_uri); if ($offset !== 0) { throw new Kohana_404_Exception(); } // file_uri: albums/foo/bar.jpg $file_uri = substr($request_uri, strlen($var_uri)); // type: albums // path: foo/bar.jpg list($type, $path) = explode("/", $file_uri, 2); if ($type != "resizes" && $type != "albums" && $type != "thumbs") { throw new Kohana_404_Exception(); } // If the last element is .album.jpg, pop that off since it's not a real item $path = preg_replace("|/.album.jpg\$|", "", $path); $item = item::find_by_path($path); if (!$item->loaded()) { // We didn't turn it up. If we're looking for a .jpg then it's it's possible that we're // requesting the thumbnail for a movie. In that case, the .flv, .mp4 or .m4v file would // have been converted to a .jpg. So try some alternate types: if (preg_match('/.jpg$/', $path)) { // rWatcher Mod: look for videos with file extensions supported by the videos module in addition to flv mp4 and m4v // Original Line: foreach (array("flv", "mp4", "m4v") as $ext) { foreach (array_merge(array("flv", "mp4", "m4v"), unserialize(module::get_var("videos", "allowed_extensions"))) as $ext) { $movie_path = preg_replace('/.jpg$/', ".{$ext}", $path); $item = item::find_by_path($movie_path); if ($item->loaded()) { break; } } } // rWatcher Mod: // If we're looking for a .flv then it's it's possible that we're requesting a flash resize // for a movie. if (strtolower(substr($path, strlen($path) - 4)) == ".flv") { $movie_path = str_ireplace(".flv", "", $path); $item = ORM::factory("item")->where("relative_path_cache", "=", $movie_path)->find(); } // END rWatcher Mod } if (!$item->loaded()) { throw new Kohana_404_Exception(); } // Make sure we have access to the item if (!access::can("view", $item)) { throw new Kohana_404_Exception(); } // Make sure we have view_full access to the original if ($type == "albums" && !access::can("view_full", $item)) { throw new Kohana_404_Exception(); } // Don't try to load a directory if ($type == "albums" && $item->is_album()) { throw new Kohana_404_Exception(); } if ($type == "albums") { $file = $item->file_path(); } else { if ($type == "resizes") { $file = $item->resize_path(); // rWatcher MOD // If the resize is for a movie, assume it needs a .flv extension. if ($item->is_movie()) { $file = $file . ".flv"; } // End rWatcher MOD } else { $file = $item->thumb_path(); } } if (!file_exists($file)) { throw new Kohana_404_Exception(); } header("Content-Length: " . filesize($file)); header("Pragma:"); // Check that the content hasn't expired or it wasn't changed since cached expires::check(2592000, $item->updated); // We don't need to save the session for this request Session::instance()->abort_save(); expires::set(2592000, $item->updated); // 30 days // Dump out the image. If the item is a movie, then its thumbnail will be a JPG. if ($item->is_movie() && $type != "albums") { header("Content-Type: image/jpeg"); } else { header("Content-Type: {$item->mime_type}"); } Kohana::close_buffers(false); readfile($file); }
public function __call($function, $args) { // Force zlib compression off. Image and movie files are already compressed and // recompressing them is CPU intensive. if (ini_get("zlib.output_compression")) { ini_set("zlib.output_compression", "Off"); } // request_uri: gallery3/var/albums/foo/bar.jpg?m=1234 $request_uri = rawurldecode(Input::instance()->server("REQUEST_URI")); // get rid of query parameters // request_uri: gallery3/var/albums/foo/bar.jpg $request_uri = preg_replace("/\\?.*/", "", $request_uri); // var_uri: gallery3/var/ $var_uri = url::file("var/"); // Make sure that the request is for a file inside var $offset = strpos(rawurldecode($request_uri), $var_uri); if ($offset !== 0) { $e = new Kohana_404_Exception(); $e->test_fail_code = 1; throw $e; } // file_uri: albums/foo/bar.jpg $file_uri = substr($request_uri, strlen($var_uri)); // type: albums // path: foo/bar.jpg list($type, $path) = explode("/", $file_uri, 2); if ($type != "resizes" && $type != "albums" && $type != "thumbs") { $e = new Kohana_404_Exception(); $e->test_fail_code = 2; throw $e; } // Get the item model using the path and type (which corresponds to a var subdir) $item = item::find_by_path($path, $type); if (!$item->loaded()) { $e = new Kohana_404_Exception(); $e->test_fail_code = 3; throw $e; } // Make sure we have access to the item if (!access::can("view", $item)) { $e = new Kohana_404_Exception(); $e->test_fail_code = 4; throw $e; } // Make sure we have view_full access to the original if ($type == "albums" && !access::can("view_full", $item)) { $e = new Kohana_404_Exception(); $e->test_fail_code = 5; throw $e; } // Don't try to load a directory if ($type == "albums" && $item->is_album()) { $e = new Kohana_404_Exception(); $e->test_fail_code = 6; throw $e; } // Note: this code is roughly duplicated in data_rest, so if you modify this, please look to // see if you should make the same change there as well. if ($type == "albums") { $file = $item->file_path(); } else { if ($type == "resizes") { $file = $item->resize_path(); } else { $file = $item->thumb_path(); } } if (!file_exists($file)) { $e = new Kohana_404_Exception(); $e->test_fail_code = 7; throw $e; } if (gallery::show_profiler()) { Profiler::enable(); $profiler = new Profiler(); $profiler->render(); exit; } header("Content-Length: " . filesize($file)); header("Pragma:"); // Check that the content hasn't expired or it wasn't changed since cached expires::check(2592000, $item->updated); // We don't need to save the session for this request Session::instance()->abort_save(); expires::set(2592000, $item->updated); // 30 days // Dump out the image. If the item is a movie or album, then its thumbnail will be a JPG. if (($item->is_movie() || $item->is_album()) && $type == "thumbs") { header("Content-Type: image/jpeg"); } else { header("Content-Type: {$item->mime_type}"); } if (TEST_MODE) { return $file; } else { // Don't use Kohana::close_buffers(false) here because that only closes all the buffers // that Kohana started. We want to close *all* buffers at this point because otherwise we're // going to buffer up whatever file we're proxying (and it may be very large). This may // affect embedding or systems with PHP's output_buffering enabled. while (ob_get_level()) { if (!@ob_end_clean()) { // ob_end_clean() can return false if the buffer can't be removed for some reason // (zlib output compression buffers sometimes cause problems). break; } } readfile($file); } }
public function media($type = NULL, $file = NULL) { // Get the file path from the request $file = implode('/', URI::instance()->segment_array(2)); // Find the file extension $ext = pathinfo($file, PATHINFO_EXTENSION); // Remove the extension from the filename $file = substr($file, 0, -(strlen($ext) + 1)); // Find the file if (!($file = Kohana::find_file('media', $file, FALSE, $ext))) { Event::run('system.404'); } // Tell browsers to cache the file for an hour. Chrome especially seems to not want to cache things expires::check(3600); // Send the file content as the response, and send some basic headers download::send($file); }