Verzeichnisstruktur phpBB-3.1.0


Veröffentlicht
27.10.2014

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

BinaryFileResponse.php

Zuletzt modifiziert: 09.10.2024, 12:58 - Dateigröße: 9.68 KiB


001  <?php
002   
003  /**
004   * This file is part of the Symfony package.
005   *
006   * (c) Fabien Potencier <fabien@symfony.com>
007   *
008   * For the full copyright and license information, please view the LICENSE
009   * file that was distributed with this source code.
010   */
011   
012  namespace Symfony\Component\HttpFoundation;
013   
014  use Symfony\Component\HttpFoundation\File\File;
015  use Symfony\Component\HttpFoundation\File\Exception\FileException;
016   
017  /**
018   * BinaryFileResponse represents an HTTP response delivering a file.
019   *
020   * @author Niklas Fiekas <niklas.fiekas@tu-clausthal.de>
021   * @author stealth35 <stealth35-php@live.fr>
022   * @author Igor Wiedler <igor@wiedler.ch>
023   * @author Jordan Alliot <jordan.alliot@gmail.com>
024   * @author Sergey Linnik <linniksa@gmail.com>
025   */
026  class BinaryFileResponse extends Response
027  {
028      protected static $trustXSendfileTypeHeader = false;
029   
030      protected $file;
031      protected $offset;
032      protected $maxlen;
033   
034      /**
035       * Constructor.
036       *
037       * @param \SplFileInfo|string $file               The file to stream
038       * @param int                 $status             The response status code
039       * @param array               $headers            An array of response headers
040       * @param bool                $public             Files are public by default
041       * @param null|string         $contentDisposition The type of Content-Disposition to set automatically with the filename
042       * @param bool                $autoEtag           Whether the ETag header should be automatically set
043       * @param bool                $autoLastModified   Whether the Last-Modified header should be automatically set
044       */
045      public function __construct($file, $status = 200, $headers = array(), $public = true, $contentDisposition = null, $autoEtag = false, $autoLastModified = true)
046      {
047          parent::__construct(null, $status, $headers);
048   
049          $this->setFile($file, $contentDisposition, $autoEtag, $autoLastModified);
050   
051          if ($public) {
052              $this->setPublic();
053          }
054      }
055   
056      /**
057       * @param \SplFileInfo|string $file               The file to stream
058       * @param int                 $status             The response status code
059       * @param array               $headers            An array of response headers
060       * @param bool                $public             Files are public by default
061       * @param null|string         $contentDisposition The type of Content-Disposition to set automatically with the filename
062       * @param bool                $autoEtag           Whether the ETag header should be automatically set
063       * @param bool                $autoLastModified   Whether the Last-Modified header should be automatically set
064       *
065       * @return BinaryResponse The created response
066       */
067      public static function create($file = null, $status = 200, $headers = array(), $public = true, $contentDisposition = null, $autoEtag = false, $autoLastModified = true)
068      {
069          return new static($file, $status, $headers, $public, $contentDisposition, $autoEtag, $autoLastModified);
070      }
071   
072      /**
073       * Sets the file to stream.
074       *
075       * @param \SplFileInfo|string $file The file to stream
076       * @param string              $contentDisposition
077       * @param bool                $autoEtag
078       * @param bool                $autoLastModified
079       *
080       * @return BinaryFileResponse
081       *
082       * @throws FileException
083       */
084      public function setFile($file, $contentDisposition = null, $autoEtag = false, $autoLastModified = true)
085      {
086          if (!$file instanceof File) {
087              if ($file instanceof \SplFileInfo) {
088                  $file = new File($file->getPathname());
089              } else {
090                  $file = new File((string) $file);
091              }
092          }
093   
094          if (!$file->isReadable()) {
095              throw new FileException('File must be readable.');
096          }
097   
098          $this->file = $file;
099   
100          if ($autoEtag) {
101              $this->setAutoEtag();
102          }
103   
104          if ($autoLastModified) {
105              $this->setAutoLastModified();
106          }
107   
108          if ($contentDisposition) {
109              $this->setContentDisposition($contentDisposition);
110          }
111   
112          return $this;
113      }
114   
115      /**
116       * Gets the file.
117       *
118       * @return File The file to stream
119       */
120      public function getFile()
121      {
122          return $this->file;
123      }
124   
125      /**
126       * Automatically sets the Last-Modified header according the file modification date.
127       */
128      public function setAutoLastModified()
129      {
130          $this->setLastModified(\DateTime::createFromFormat('U', $this->file->getMTime()));
131   
132          return $this;
133      }
134   
135      /**
136       * Automatically sets the ETag header according to the checksum of the file.
137       */
138      public function setAutoEtag()
139      {
140          $this->setEtag(sha1_file($this->file->getPathname()));
141   
142          return $this;
143      }
144   
145      /**
146       * Sets the Content-Disposition header with the given filename.
147       *
148       * @param string $disposition      ResponseHeaderBag::DISPOSITION_INLINE or ResponseHeaderBag::DISPOSITION_ATTACHMENT
149       * @param string $filename         Optionally use this filename instead of the real name of the file
150       * @param string $filenameFallback A fallback filename, containing only ASCII characters. Defaults to an automatically encoded filename
151       *
152       * @return BinaryFileResponse
153       */
154      public function setContentDisposition($disposition, $filename = '', $filenameFallback = '')
155      {
156          if ($filename === '') {
157              $filename = $this->file->getFilename();
158          }
159   
160          $dispositionHeader = $this->headers->makeDisposition($disposition, $filename, $filenameFallback);
161          $this->headers->set('Content-Disposition', $dispositionHeader);
162   
163          return $this;
164      }
165   
166      /**
167       * {@inheritdoc}
168       */
169      public function prepare(Request $request)
170      {
171          $this->headers->set('Content-Length', $this->file->getSize());
172          $this->headers->set('Accept-Ranges', 'bytes');
173          $this->headers->set('Content-Transfer-Encoding', 'binary');
174   
175          if (!$this->headers->has('Content-Type')) {
176              $this->headers->set('Content-Type', $this->file->getMimeType() ?: 'application/octet-stream');
177          }
178   
179          if ('HTTP/1.0' != $request->server->get('SERVER_PROTOCOL')) {
180              $this->setProtocolVersion('1.1');
181          }
182   
183          $this->ensureIEOverSSLCompatibility($request);
184   
185          $this->offset = 0;
186          $this->maxlen = -1;
187   
188          if (self::$trustXSendfileTypeHeader && $request->headers->has('X-Sendfile-Type')) {
189              // Use X-Sendfile, do not send any content.
190              $type = $request->headers->get('X-Sendfile-Type');
191              $path = $this->file->getRealPath();
192              if (strtolower($type) == 'x-accel-redirect') {
193                  // Do X-Accel-Mapping substitutions.
194                  foreach (explode(',', $request->headers->get('X-Accel-Mapping', ''))  as $mapping) {
195                      $mapping = explode('=', $mapping, 2);
196   
197                      if (2 == count($mapping)) {
198                          $location = trim($mapping[0]);
199                          $pathPrefix = trim($mapping[1]);
200   
201                          if (substr($path, 0, strlen($pathPrefix)) == $pathPrefix) {
202                              $path = $location.substr($path, strlen($pathPrefix));
203                              break;
204                          }
205                      }
206                  }
207              }
208              $this->headers->set($type, $path);
209              $this->maxlen = 0;
210          } elseif ($request->headers->has('Range')) {
211              // Process the range headers.
212              if (!$request->headers->has('If-Range') || $this->getEtag() == $request->headers->get('If-Range')) {
213                  $range = $request->headers->get('Range');
214                  $fileSize = $this->file->getSize();
215   
216                  list($start, $end) = explode('-', substr($range, 6), 2) + array(0);
217   
218                  $end = ('' === $end) ? $fileSize - 1 : (int) $end;
219   
220                  if ('' === $start) {
221                      $start = $fileSize - $end;
222                      $end = $fileSize - 1;
223                  } else {
224                      $start = (int) $start;
225                  }
226   
227                  if ($start <= $end) {
228                      if ($start < 0 || $end > $fileSize - 1) {
229                          $this->setStatusCode(416);
230                      } elseif ($start !== 0 || $end !== $fileSize - 1) {
231                          $this->maxlen = $end < $fileSize ? $end - $start + 1 : -1;
232                          $this->offset = $start;
233   
234                          $this->setStatusCode(206);
235                          $this->headers->set('Content-Range', sprintf('bytes %s-%s/%s', $start, $end, $fileSize));
236                          $this->headers->set('Content-Length', $end - $start + 1);
237                      }
238                  }
239              }
240          }
241   
242          return $this;
243      }
244   
245      /**
246       * Sends the file.
247       */
248      public function sendContent()
249      {
250          if (!$this->isSuccessful()) {
251              parent::sendContent();
252   
253              return;
254          }
255   
256          if (0 === $this->maxlen) {
257              return;
258          }
259   
260          $out = fopen('php://output', 'wb');
261          $file = fopen($this->file->getPathname(), 'rb');
262   
263          stream_copy_to_stream($file, $out, $this->maxlen, $this->offset);
264   
265          fclose($out);
266          fclose($file);
267      }
268   
269      /**
270       * {@inheritdoc}
271       *
272       * @throws \LogicException when the content is not null
273       */
274      public function setContent($content)
275      {
276          if (null !== $content) {
277              throw new \LogicException('The content cannot be set on a BinaryFileResponse instance.');
278          }
279      }
280   
281      /**
282       * {@inheritdoc}
283       *
284       * @return false
285       */
286      public function getContent()
287      {
288          return false;
289      }
290   
291      /**
292       * Trust X-Sendfile-Type header.
293       */
294      public static function trustXSendfileTypeHeader()
295      {
296          self::$trustXSendfileTypeHeader = true;
297      }
298  }
299