/** * Sends response to output. * @return void */ public function send() { Nette\Environment::getHttpResponse()->setContentType($this->contentType); Nette\Environment::getHttpResponse()->setExpiration(FALSE); echo Nette\Json::encode($this->payload); }
/** * Download the file! * @param IDownloader $downloader */ function download(IDownloader $downloader = null) { $req = Environment::getHttpRequest(); $res = Environment::getHttpResponse(); if (self::$closeSession) { $ses = Environment::getSession(); if ($ses->isStarted()) { $ses->close(); } } if ($this->getContentDisposition() == "inline" and is_null($this->enableBrowserCache)) { $this->enableBrowserCache = true; } else { $this->enableBrowserCache = false; } if ($downloader === null) { $downloaders = self::getFileDownloaders(); } else { $downloaders = array($downloader); } if (count($downloaders) <= 0) { throw new InvalidStateException("There is no registred downloader!"); } krsort($downloaders); $lastException = null; foreach ($downloaders as $downloader) { if ($downloader instanceof IDownloader and $downloader->isCompatible($this)) { try { FDTools::clearHeaders($res); // Delete all headers $this->transferredBytes = 0; $this->onBeforeDownloaderStarts($this, $downloader); $downloader->download($this); // Start download $this->onComplete($this, $downloader); die; // If all gone ok -> die } catch (FDSkypeMeException $e) { if ($res->isSent()) { throw new InvalidStateException("Headers are already sent! Can't skip downloader."); } else { continue; } } catch (Exception $e) { if (!$res->isSent()) { FDTools::clearHeaders($res); } throw $e; } } } // Pokud se soubor nějakým způsobem odešle - toto už se nespustí if ($lastException instanceof Exception) { FDTools::clearHeaders(Environment::getHttpResponse(), TRUE); throw $lastException; } if ($req->getHeader("Range")) { FDTools::_HTTPError(416); } else { $res->setCode(500); } throw new InvalidStateException("There is no compatible downloader (all downloader returns downloader->isComplatible()=false or was skipped)!"); }
/** * @return Nette\Web\IHttpResponse */ protected function getHttpResponse() { return Nette\Environment::getHttpResponse(); }
/** * Download file! * @param BaseFileDownload $file */ function download(BaseFileDownload $transfer) { $this->currentTransfer = $transfer; $this->sendStandardFileHeaders($transfer, $this); @ignore_user_abort(true); // For onAbort event $req = Environment::getHttpRequest(); $res = Environment::getHttpResponse(); $filesize = $this->size = $transfer->sourceFileSize; $this->length = $this->size; // Content-length $this->start = 0; $this->end = $this->size - 1; /* ### Headers ### */ // Now that we've gotten so far without errors we send the accept range header /* At the moment we only support single ranges. * Multiple ranges requires some more work to ensure it works correctly * and comply with the spesifications: http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2 * * Multirange support annouces itself with: * header('Accept-Ranges: bytes'); * * Multirange content must be sent with multipart/byteranges mediatype, * (mediatype = mimetype) * as well as a boundry header to indicate the various chunks of data. */ //$res->setHeader("Accept-Ranges", "0-".$this->end); // single-part - now not accepted by mozilla $res->setHeader("Accept-Ranges", "bytes"); // multi-part (through Mozilla) // http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2 if ($req->getHeader("Range", false)) { try { $range_start = $this->start; $range_end = $this->end; // Extract the range string $rangeArray = explode('=', $req->getHeader("Range"), 2); $range = $rangeArray[1]; // Make sure the client hasn't sent us a multibyte range if (strpos($range, ',') !== false) { // (?) Shoud this be issued here, or should the first // range be used? Or should the header be ignored and // we output the whole content? throw new FileDownloaderException("HTTP 416", 416); } // If the range starts with an '-' we start from the beginning // If not, we forward the file pointer // And make sure to get the end byte if spesified if ($range[0] == '-') { // The n-number of the last bytes is requested $range_start = $this->size - (double) substr($range, 1); } else { $range = explode('-', $range); $range_start = $range[0]; $range_end = isset($range[1]) && is_numeric($range[1]) ? $range[1] : $this->size; } /** * Check the range and make sure it's treated according to the specs. * @link http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html */ // End bytes can not be larger than $end. $range_end = $range_end > $this->end ? $this->end : $range_end; // Validate the requested range and return an error if it's not correct. if ($range_start > $range_end || $range_start > $this->size - 1 || $range_end >= $this->size) { throw new FileDownloaderException("HTTP 416", 416); } // All is ok - so assign variables back $this->start = $range_start; $this->end = $range_end; $this->length = $this->end - $this->start + 1; // Calculate new content length } catch (FileDownloaderException $e) { if ($e->getCode() === 416) { $res->setHeader("Content-Range", "bytes {$this->start}-{$this->end}/{$this->size}"); FDTools::_HTTPError(416); } else { throw $e; } } $res->setCode(206); // Partial content } // End of if partial download // Notify the client the byte range we'll be outputting $res->setHeader("Content-Range", "bytes {$this->start}-{$this->end}/{$this->size}"); $res->setHeader("Content-Length", $this->length); /* ### Call callbacks ### */ $transfer->onBeforeOutputStarts($transfer, $this); if ($this->start > 0) { $transfer->onTransferContinue($transfer, $this); } else { $transfer->onNewTransferStart($transfer, $this); } /* ### Send file to browser - document body ### */ $buffer = FDTools::$readFileBuffer; $sleep = false; if (is_int($transfer->speedLimit) and $transfer->speedLimit > 0) { $sleep = true; $buffer = (int) round($transfer->speedLimit); } $this->sleep = $sleep; if ($buffer < 1) { throw new InvalidArgumentException("Buffer must be bigger than zero!"); } if ($buffer > FDTools::getAvailableMemory() - memory_get_usage()) { throw new InvalidArgumentException("Buffer is too big! (bigger than available memory)"); } $this->buffer = $buffer; $fp = fopen($transfer->sourceFile, "rb"); // TODO: Add flock() READ if (!$fp) { throw new InvalidStateException("Can't open file for reading!"); } if ($this->end === null) { $this->end = $filesize - 1; } if (fseek($fp, $this->start, SEEK_SET) === -1) { // Move file pointer to the start of the download // Can not move pointer to begining of the filetransfer if ($this->processByCUrl() === true) { // Request was hadled by curl, clean, exit $this->cleanAfterTransfer(); return; } // Use this hack (fread file to start position) $destPos = $this->position = PHP_INT_MAX - 1; if (fseek($fp, $this->position, SEEK_SET) === -1) { rewind($fp); $this->position = 0; throw new InvalidStateException("Can not move pointer to position ({$destPos})"); } $maxBuffer = 1024 * 1024; while ($this->position < $this->start) { $this->position += strlen(fread($fp, min($maxBuffer, $this->start - $this->position))); } } else { // We are at the begining $this->position = $this->start; } $this->processNative($fp, $sleep); $this->cleanAfterTransfer(); }
/** * @return Nette\Web\IHttpResponse */ public function getResponse() { return Nette\Environment::getHttpResponse(); }
/** * Sends response to output. * @return void */ public function send() { Nette\Environment::getHttpResponse()->redirect($this->uri, $this->code); }
/** * Sends response to output. * @return void */ public function send() { Nette\Environment::getHttpResponse()->setContentType($this->contentType); Nette\Environment::getHttpResponse()->setHeader('Content-Disposition', 'attachment; filename="' . $this->name . '"'); readfile($this->file); }
<?php use Nette\Environment; Environment::getHttpResponse()->setHeader("refresh", "1"); $cache = Environment::getCache("FileDownloader/log"); echo "<html><body>"; echo "<h1>Log console (called events)</h1>"; echo "<p>Clear log = delete temp files</p>"; echo "<style>p{font-size: 11px;font-family: monospace;}</style>"; $reg = $cache["registry"]; $y = 0; if (count($reg) > 0) { krsort($reg); foreach ($reg as $tid => $none) { $y++; $tid = (string) $tid; $log = $cache[$tid]; $i = 0; if (count($log) > 0) { krsort($log); foreach ($log as $key => $val) { if ($i == 0) { echo "<h2>Con. #" . $tid; if (strstr($val, "Abort")) { echo " <span style=\"color: orange;\">(Aborted)</span>"; } elseif (strstr($val, "Lost")) { echo " <span style=\"color: red;\">(Connection losted)</span>"; } elseif (strstr($val, "Complete")) { echo " <span style=\"color: green;\">(Completed)</span>"; } else { echo " (Running)";
/** * Sends http error to client * * @author Jan Kuchař * @param int $code HTTP code * @param string $message HTTP status */ static function _HTTPError($code, $message = null) { $errors = array(416 => "Requested Range not satisfiable"); if ($message === null and isset($errors[$code])) { $message = $errors[$code]; } $res = Environment::getHttpResponse(); $res->setCode($code); $res->setContentType("plain/text", "UTF-8"); die("<html><body><h1>HTTP Error " . $code . " - " . $message . "</h1><p>" . $message . "</p></body></html>"); }
protected function setupNonCacheHeaders(BaseFileDownload $file) { $res = \Nette\Environment::getHttpResponse(); $res->setHeader('Expires', '0'); $res->setHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0'); }