Beispiel #1
0
 /**
  * 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 [[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 [[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 $this the response object itself
  * @throws HttpException 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 HttpException(416, 'Requested range not satisfiable');
     }
     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;
     }
     $mimeType = isset($options['mimeType']) ? $options['mimeType'] : 'application/octet-stream';
     $this->setDownloadHeaders($attachmentName, $mimeType, !empty($options['inline']), $end - $begin + 1);
     $this->format = self::FORMAT_RAW;
     return $this;
 }
Beispiel #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 InvalidConfigException if OpenSSL extension is required (e.g. on Windows) but not installed.
  * @throws Exception on failure.
  */
 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 InvalidConfigException('The OpenSSL PHP extension is not installed.');
     }
     $bytes .= openssl_random_pseudo_bytes($length, $cryptoStrong);
     if (StringHelper::byteLength($bytes) < $length || !$cryptoStrong) {
         throw new Exception('Unable to generate random bytes.');
     }
     return StringHelper::byteSubstr($bytes, 0, $length);
 }
Beispiel #3
0
 /**
  * Validates CSRF token
  *
  * @param string $token
  * @param string $trueToken
  * @return boolean
  */
 private function validateCsrfTokenInternal($token, $trueToken)
 {
     $token = base64_decode(str_replace('.', '+', $token));
     $n = StringHelper::byteLength($token);
     if ($n <= static::CSRF_MASK_LENGTH) {
         return false;
     }
     $mask = StringHelper::byteSubstr($token, 0, static::CSRF_MASK_LENGTH);
     $token = StringHelper::byteSubstr($token, static::CSRF_MASK_LENGTH, $n - static::CSRF_MASK_LENGTH);
     $token = $this->xorTokens($mask, $token);
     return $token === $trueToken;
 }