/**
  * Delivers an image.
  *
  * @param  string  $hash
  * @param  string  $filename
  * @param  boolean  $thumbnail
  * @return Response
  */
 public function getImage($hash = false, $filename = false, $thumbnail = false)
 {
     if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
         header('HTTP/1.1 304 Not Modified');
         die;
     }
     if ($hash !== false && $filename !== false) {
         $FileStorage = FileStorage::getHash($hash);
         $storagePath = !$thumbnail ? $FileStorage->getPath() : $FileStorage->getPathThumb();
         $storagePathFull = !$thumbnail ? $FileStorage->getFullPath() : $FileStorage->getFullPathThumb();
         $cacheTime = 315360000;
         /// 10 years
         if ($FileStorage instanceof FileStorage && Storage::exists($storagePath)) {
             $responseSize = Storage::size($storagePath);
             $responseHeaders = ['Cache-Control' => "public, max-age={$cacheTime}, pre-check={$cacheTime}", 'Expires' => gmdate(DATE_RFC1123, time() + $cacheTime), 'Last-Modified' => gmdate(DATE_RFC1123, File::lastModified($storagePathFull)), 'Content-Disposition' => "inline", 'Content-Length' => $responseSize, 'Content-Type' => $FileStorage->mime, 'Filename' => $filename];
             $response = Response::stream(function () use($storagePathFull) {
                 readfile($storagePathFull);
             }, 200, $responseHeaders);
             return $response;
         }
     }
     return abort(404);
 }
Beispiel #2
0
 public function importInfinityPostAttachments(Post $model, Board &$board, $post)
 {
     $post_id = $model->post_id;
     if (!$post_id) {
         return 0;
     }
     $attachments = @json_decode($post->files, true);
     if (!is_array($attachments)) {
         return 0;
     }
     $aModels = [];
     foreach ($attachments as $aIndex => $attachment) {
         if (isset($attachment['error']) && $attachment['error']) {
             continue;
         }
         if (!isset($attachment['file_path']) || !isset($attachment['thumb_path'])) {
             continue;
         }
         $storage = null;
         $path = "{$this->targetLocation}/{$attachment['file_path']}";
         $thumb = "{$this->targetLocation}/{$attachment['thumb_path']}";
         if (file_exists($path)) {
             if (!isset($attachment['type'])) {
                 continue;
             }
             if (!isset($attachment['hash'])) {
                 $attachment['hash'] = md5(file_get_contents($path));
             }
             $storage = FileStorage::getHash($attachment['hash']);
             if (!$storage || (!file_exists($storage->getFullPath()) || !file_exists($storage->getFullPathThumb()))) {
                 $height = null;
                 $width = null;
                 if (isset($attachment['width']) && isset($attachment['height'])) {
                     $height = $attachment['height'];
                     $width = $attachment['width'];
                 }
                 if (!$storage) {
                     $storage = new FileStorage(['hash' => $attachment['hash'], 'banned' => false, 'filesize' => $attachment['size'], 'file_width' => $width, 'file_height' => $height, 'mime' => $attachment['type'], 'meta' => null, 'first_uploaded_at' => Carbon::now(), 'last_uploaded_at' => Carbon::now(), 'upload_count' => 1]);
                 }
                 Storage::makeDirectory($storage->getDirectory());
                 if (!file_exists($storage->getFullPath())) {
                     if (is_link($storage->getFullPath())) {
                         unlink($storage->getFullPath());
                     }
                     symlink($path, $storage->getFullPath());
                 }
                 if ($attachment['thumbwidth'] && file_exists($thumb)) {
                     $storage->has_thumbnail = true;
                     $storage->thumbnail_width = $attachment['thumbwidth'];
                     $storage->thumbnail_height = $attachment['thumbheight'];
                     Storage::makeDirectory($storage->getDirectoryThumb());
                     if (!file_exists($storage->getFullPathThumb())) {
                         if (is_link($storage->getFullPathThumb())) {
                             unlink($storage->getFullPathThumb());
                         }
                         symlink($thumb, $storage->getFullPathThumb());
                     }
                 }
                 $storage->save();
             }
             if ($storage && $storage->exists) {
                 $aModel = ['post_id' => $post_id, 'file_id' => $storage->file_id, 'filename' => $attachment['filename'], 'is_spoiler' => false, 'is_deleted' => false, 'position' => $aIndex];
                 $aModels[] = $aModel;
             } else {
                 ++$skips;
             }
         }
     }
     FileAttachment::insert($aModels);
     return count($aModels);
 }
 /**
  * Checks if a file exists.
  *
  * @param  Request  $request
  * @param  Board  $board
  * @return json
  */
 public function getFile(Request $request, Board $board)
 {
     $hash = $request->get('md5');
     $storage = FileStorage::getHash($hash);
     if (is_null($storage) || !$storage->hasFile()) {
         return [$hash => null];
     }
     return [$hash => $storage];
 }
 /**
  * Delivers an image.
  *
  * @param  \App\FileAttachment  $attachment
  * @param  string  $filename
  * @param  boolean  $thumbnail
  * @return Response
  */
 public function getImage($hash = false, $filename = false, $thumbnail = false)
 {
     if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
         header('HTTP/1.1 304 Not Modified');
         die;
     }
     $FileStorage = null;
     if (is_string($hash) && is_string($filename)) {
         $FileStorage = FileStorage::getHash($hash);
     }
     if ($FileStorage instanceof FileStorage) {
         $storagePath = !$thumbnail ? $FileStorage->getPath() : $FileStorage->getPathThumb();
         $storagePathFull = !$thumbnail ? $FileStorage->getFullPath() : $FileStorage->getFullPathThumb();
         $cacheTime = 31536000;
         /// 1 year
         if ($thumbnail && (!file_exists($storagePathFull) || is_dir($storagePathFull))) {
             if (is_dir($storagePathFull)) {
                 unlink($storagePathFull);
             }
             $FileStorage->processThumb();
         }
         if (is_link($storagePathFull)) {
             if (!is_readable($storagePathFull)) {
                 abort(500, "Symlink file is unreadable.");
             }
             $storageExists = file_exists($storagePathFull);
         } else {
             $storageExists = Storage::exists($storagePath);
         }
         if ($storageExists) {
             ini_set("zlib.output_compression", "Off");
             $responseSize = filesize($storagePathFull);
             $responseCode = 200;
             $responseHeaders = ['Cache-Control' => "public, max-age={$cacheTime}, pre-check={$cacheTime}", 'Expires' => gmdate(DATE_RFC1123, time() + $cacheTime), 'Last-Modified' => gmdate(DATE_RFC1123, File::lastModified($storagePathFull)), 'Content-Disposition' => Request::get('disposition', "inline"), 'Content-Length' => $responseSize, 'Content-Type' => $FileStorage->mime, 'Filename' => urldecode($filename)];
             if ($thumbnail) {
                 if ($FileStorage->isImage()) {
                     $responseHeaders['Content-Type'] = Settings::get('attachmentThumbnailJpeg') ? "image/jpg" : "image/png";
                 } else {
                     if ($FileStorage->isVideo()) {
                         $responseHeaders['Content-Type'] = "image/jpg";
                     } else {
                         if ($FileStorage->isAudio()) {
                             $responseHeaders['Content-Type'] = "image/png";
                         }
                     }
                 }
             }
             // Determine if we can skip PHP content distribution.
             // This is hugely important.
             $xSendFile = false;
             // APACHE
             // Relies on the mod_xsendfile module.
             if (function_exists("apache_get_modules") && in_array("mod_xsendfile", apache_get_modules())) {
                 $xSendFile = true;
                 $responseHeaders['X-Sendfile'] = $storagePathFull;
             } else {
                 if (preg_match("/nginx\\/1(\\.[0-9]+)+/", $_SERVER['SERVER_SOFTWARE'])) {
                     $xSendFile = true;
                     $responseHeaders['X-Accel-Redirect'] = "/{$storagePath}";
                 } else {
                     if (preg_match("/lighttpd\\/1(\\.[0-9]+)+/", $_SERVER['SERVER_SOFTWARE'])) {
                         $xSendFile = true;
                         $responseHeaders['X-LIGHTTPD-send-file'] = $storagePathFull;
                     }
                 }
             }
             // Seek Audio and Video files.
             $responseStart = 0;
             $responseEnd = $responseSize - 1;
             if ($FileStorage->isVideo()) {
                 $responseHeaders['Accept-Ranges'] = "0-" . ($responseSize - 1);
                 if (isset($_SERVER['HTTP_RANGE'])) {
                     list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);
                     if (strpos($range, ',') !== false) {
                         return Response::make("Requested Range Not Satisfiable", 416, ['Content-Range' => "bytes {$responseStart}-{$responseEnd}/{$responseSize}"]);
                     }
                     if ($range == '-') {
                         $responseStart = $this->size - substr($range, 1);
                     } else {
                         $range = explode('-', $range);
                         $responseStart = $range[0];
                         $responseEnd = isset($range[1]) && is_numeric($range[1]) ? $range[1] : $responseEnd;
                     }
                     if ($responseStart > $responseEnd || $responseStart > $responseSize - 1 || $responseEnd >= $responseSize) {
                         return Response::make("Requested Range Not Satisfiable", 416, ['Content-Range' => "bytes {$responseStart}-{$responseEnd}/{$responseSize}"]);
                     }
                     $responseCode = 206;
                     $responseHeaders['Content-Length'] = $responseSize - $responseStart;
                     $responseHeaders['Content-Range'] = "bytes {$responseStart}-{$responseEnd}/{$responseSize}";
                     unset($responseHeaders['Accept-Ranges']);
                     unset($responseHeaders['Cache-Control']);
                     unset($responseHeaders['Content-Disposition']);
                     unset($responseHeaders['Expires']);
                 }
             }
             // Are we using the webserver to send files?
             if ($xSendFile) {
                 // Yes.
                 // Send an empty 200 response with the headers.
                 return Response::make("", $responseCode, $responseHeaders);
             } else {
                 // No.
                 // Get our hands dirty and stream the file.
                 return Response::make(function () use($storagePathFull, $responseStart, $responseEnd) {
                     if (!($responseStream = fopen($storagePathFull, 'rb'))) {
                         abort(500, "Could not open requested file.");
                     }
                     if ($responseStart > 0) {
                         fseek($responseStream, $responseStart);
                     }
                     $streamCurrent = 0;
                     while (!feof($responseStream) && $streamCurrent < $responseEnd && connection_status() == 0) {
                         echo fread($responseStream, min(1024 * 16, $responseEnd - $responseStart + 1));
                         $streamCurrent += 1024 * 16;
                     }
                     fclose($responseStream);
                 }, $responseCode, $responseHeaders);
             }
         }
     }
     return abort(404);
 }
 /**
  * Checks if a file exists.
  *
  * @param  Request  $request
  * @param  Board  $board
  * @return json
  */
 public function getFile(Request $request, Board $board)
 {
     $hash = $request->get('md5');
     $storage = FileStorage::getHash($hash);
     if (is_null($storage) || !$storage->hasFile()) {
         if (!is_null($storage)) {
             unlink($storage->getFullPath());
             unlink($storage->getFullPathThumb());
         }
         return [$hash => null];
     }
     return [$hash => $storage];
 }
 /**
  * Delivers an image.
  *
  * @param  string  $hash
  * @param  string  $filename
  * @param  boolean  $thumbnail
  * @return Response
  */
 public function getImage($hash = false, $filename = false, $thumbnail = false)
 {
     if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
         header('HTTP/1.1 304 Not Modified');
         die;
     }
     if ($hash !== false && $filename !== false) {
         $FileStorage = FileStorage::getHash($hash);
         $storagePath = !$thumbnail ? $FileStorage->getPath() : $FileStorage->getPathThumb();
         $storagePathFull = !$thumbnail ? $FileStorage->getFullPath() : $FileStorage->getFullPathThumb();
         $cacheTime = 315360000;
         /// 10 years
         if ($FileStorage instanceof FileStorage && Storage::exists($storagePath)) {
             $responseSize = Storage::size($storagePath);
             $responseCode = 200;
             $responseHeaders = ['Cache-Control' => "public, max-age={$cacheTime}, pre-check={$cacheTime}", 'Expires' => gmdate(DATE_RFC1123, time() + $cacheTime), 'Last-Modified' => gmdate(DATE_RFC1123, File::lastModified($storagePathFull)), 'Content-Disposition' => "inline", 'Content-Length' => $responseSize, 'Content-Type' => $FileStorage->mime, 'Filename' => $filename];
             $responseStart = 0;
             $responseEnd = $responseSize - 1;
             if ($FileStorage->isVideo()) {
                 $responseHeaders['Accept-Ranges'] = "0-" . ($responseSize - 1);
                 if (isset($_SERVER['HTTP_RANGE'])) {
                     list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);
                     if (strpos($range, ',') !== false) {
                         return Response::make("Requested Range Not Satisfiable", 416, ['Content-Range' => "bytes {$responseStart}-{$responseEnd}/{$responseSize}"]);
                     }
                     if ($range == '-') {
                         $responseStart = $this->size - substr($range, 1);
                     } else {
                         $range = explode('-', $range);
                         $responseStart = $range[0];
                         $responseEnd = isset($range[1]) && is_numeric($range[1]) ? $range[1] : $responseEnd;
                     }
                     $responseEnd = $responseEnd > $responseEnd ? $responseEnd : $responseEnd;
                     if ($responseStart > $responseEnd || $responseStart > $responseSize - 1 || $responseEnd >= $responseSize) {
                         return Response::make("Requested Range Not Satisfiable", 416, ['Content-Range' => "bytes {$responseStart}-{$responseEnd}/{$responseSize}"]);
                     }
                     $responseCode = 206;
                     $responseHeaders['Content-Length'] = $responseSize - $responseStart;
                     $responseHeaders['Content-Range'] = "bytes {$responseStart}-{$responseEnd}/{$responseSize}";
                     unset($responseHeaders['Accept-Ranges']);
                     unset($responseHeaders['Cache-Control']);
                     unset($responseHeaders['Content-Disposition']);
                     unset($responseHeaders['Expires']);
                 }
             }
             return Response::stream(function () use($storagePathFull, $responseStart, $responseEnd) {
                 if (!($responseStream = fopen($storagePathFull, 'rb'))) {
                     abort(500, "Could not open requested file.");
                 }
                 if ($responseStart > 0) {
                     fseek($responseStream, $responseStart);
                 }
                 $streamCurrent = 0;
                 while (!feof($responseStream) && $streamCurrent < $responseEnd && connection_status() == 0) {
                     echo fread($responseStream, min(1024 * 16, $responseEnd - $responseStart + 1));
                     $streamCurrent += 1024 * 16;
                 }
                 fclose($responseStream);
             }, $responseCode, $responseHeaders);
         }
     }
     return abort(404);
 }