예제 #1
0
파일: Response.php 프로젝트: romeoz/rock
 /**
  * Sends the specified content as a file to the browser.
  *
  * Note that this method only prepares the response for file sending. The file is not sent
  * until {@see \rock\response\Response::send()} is called explicitly or implicitly. The latter is done after you return from a controller action.
  *
  * @param string $content the content to be sent.
  *                        The existing {@see \rock\response\Response::$content} will be discarded.
  * @param string $attachmentName the file name shown to the user.
  * @param array $options additional options for sending the file. The following options are supported:
  *
  *  - `mimeType`: the MIME type of the content. Defaults to 'application/octet-stream'.
  *  - `inline`: boolean, whether the browser should open the file within the browser window. Defaults to false,
  *     meaning a download dialog will pop up.
  *
  * @return static the response object itself
  * @throws ResponseException if the requested range is not satisfiable
  */
 public function sendContentAsFile($content, $attachmentName, $options = [])
 {
     $headers = $this->getHeaders();
     $contentLength = StringHelper::byteLength($content);
     $range = $this->getHttpRange($contentLength);
     if ($range === false) {
         $headers->set('Content-Range', "bytes */{$contentLength}");
         throw new ResponseException('Requested range not satisfiable');
     }
     $mimeType = isset($options['mimeType']) ? $options['mimeType'] : 'application/octet-stream';
     $this->setDownloadHeaders($attachmentName, $mimeType, !empty($options['inline']), $contentLength);
     list($begin, $end) = $range;
     if ($begin != 0 || $end != $contentLength - 1) {
         $this->setStatusCode(206);
         $headers->set('Content-Range', "bytes {$begin}-{$end}/{$contentLength}");
         $this->content = StringHelper::byteSubstr($content, $begin, $end - $begin + 1);
     } else {
         $this->setStatusCode(200);
         $this->content = $content;
     }
     $this->format = self::FORMAT_RAW;
     return $this;
 }
예제 #2
0
 /**
  * Generates specified number of random bytes.
  * Note that output may not be ASCII.
  * @see generateRandomString() if you need a string.
  *
  * @param integer $length the number of bytes to generate
  * @return string the generated random bytes
  * @throws SecurityException if OpenSSL extension is required (e.g. on Windows) but not installed.
  */
 public function generateRandomKey($length = 32)
 {
     /*
      * Strategy
      *
      * The most common platform is Linux, on which /dev/urandom is the best choice. Many other OSs
      * implement a device called /dev/urandom for Linux compat and it is good too. So if there is
      * a /dev/urandom then it is our first choice regardless of OS.
      *
      * Nearly all other modern Unix-like systems (the BSDs, Unixes and OS X) have a /dev/random
      * that is a good choice. If we didn't get bytes from /dev/urandom then we try this next but
      * only if the system is not Linux. Do not try to read /dev/random on Linux.
      *
      * Finally, OpenSSL can supply CSPR bytes. It is our last resort. On Windows this reads from
      * CryptGenRandom, which is the right thing to do. On other systems that don't have a Unix-like
      * /dev/urandom, it will deliver bytes from its own CSPRNG that is seeded from kernel sources
      * of randomness. Even though it is fast, we don't generally prefer OpenSSL over /dev/urandom
      * because an RNG in user space memory is undesirable.
      *
      * For background, see http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/
      */
     $bytes = '';
     // If we are on Linux or any OS that mimics the Linux /dev/urandom device, e.g. FreeBSD or OS X,
     // then read from /dev/urandom.
     if (@file_exists('/dev/urandom')) {
         $handle = fopen('/dev/urandom', 'r');
         if ($handle !== false) {
             $bytes .= fread($handle, $length);
             fclose($handle);
         }
     }
     if (StringHelper::byteLength($bytes) >= $length) {
         return StringHelper::byteSubstr($bytes, 0, $length);
     }
     // If we are not on Linux and there is a /dev/random device then we have a BSD or Unix device
     // that won't block. It's not safe to read from /dev/random on Linux.
     if (PHP_OS !== 'Linux' && @file_exists('/dev/random')) {
         $handle = fopen('/dev/random', 'r');
         if ($handle !== false) {
             $bytes .= fread($handle, $length);
             fclose($handle);
         }
     }
     if (StringHelper::byteLength($bytes) >= $length) {
         return StringHelper::byteSubstr($bytes, 0, $length);
     }
     if (!extension_loaded('openssl')) {
         throw new SecurityException('The OpenSSL PHP extension is not installed.');
     }
     $bytes .= openssl_random_pseudo_bytes($length, $cryptoStrong);
     if (StringHelper::byteLength($bytes) < $length || !$cryptoStrong) {
         throw new SecurityException('Unable to generate random bytes.');
     }
     return StringHelper::byteSubstr($bytes, 0, $length);
 }