ILIAS  trunk Revision v11.0_alpha-2638-g80c1d007f79
PHPResponseBuilder.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
22 
29 
34 {
35  public function getName(): string
36  {
37  return 'php';
38  }
39 
40  public function buildForStream(
41  ServerRequestInterface $request,
42  ResponseInterface $response,
43  FileStream $stream,
44  ): ResponseInterface {
45  $response = $this->buildHeaders($response, $stream);
46  $server_params = $request->getServerParams();
47 
48  if ($request->getMethod() === 'HEAD') {
49  return $response->withStatus(200);
50  }
51 
52  if (isset($server_params['HTTP_RANGE']) && $this->supportPartial()) {
53  return $this->deliverPartial($request, $response, $stream);
54  }
55  return $this->deliverFull($response, $stream);
56  }
57 
58  protected function buildHeaders(
59  ResponseInterface $response,
60  FileStream $stream
61  ): ResponseInterface {
62  $uri = $stream->getMetadata('uri');
63  if ($this->supportPartial()) {
64  $response = $response->withHeader(ResponseHeader::ACCEPT_RANGES, 'bytes');
65  }
66 
67  $response = $response->withHeader(ResponseHeader::CONTENT_LENGTH, $stream->getSize());
68  try {
69  $response = $response->withHeader(
71  date("D, j M Y H:i:s", filemtime($uri) ?: time()) . " GMT"
72  );
73  } catch (\Throwable) {
74  }
75 
76  return $response->withHeader(ResponseHeader::ETAG, md5((string) $uri));
77  }
78 
79  protected function deliverFull(
80  ResponseInterface $response,
81  FileStream $stream,
82  ): ResponseInterface {
83  $stream->rewind();
84  return $response->withBody($stream);
85  }
86 
87  protected function deliverPartial(
89  ResponseInterface $response,
90  FileStream $stream,
91  ): ResponseInterface {
92  if (!$this->supportPartial()) {
93  return $response;
94  }
95  $request->getServerParams();
96 
97  $start = 0;
98  $content_length = $stream->getSize();
99  $end = null;
100 
101  $range_header = $request->getHeaderLine('Range');
102 
103  if ($range_header && preg_match(
104  '%bytes=(\d+)-(\d+)?%i',
105  $range_header,
106  $match
107  )) {
108  $start = (int) $match[1];
109  if (isset($match[2])) {
110  $end = (int) $match[2];
111  }
112  $end ??= $content_length - 1;
113  }
114 
115  $response = $response->withStatus(206);
116 
117  $length = $end - $start + 1;
118  $fh = $stream->detach();
119 
120  // set $buffer_size to 8MB
121  $buffer_size = 8048 * 1000; // 8,048,000 bytes
122 
123  $output_length = 0;
124  if ($stream->isSeekable()) {
125  fseek($fh, $start);
126  while (!feof($fh) && $length > 0) {
127  $chunk_size_requested = min($buffer_size, $end - $start);
128  $content = fread($fh, $length);
129  if ($content === false) {
130  break;
131  }
132  $length -= strlen($content);
133  $response->getBody()->write($content);
134  $output_length = strlen($content);
135  }
136  } else {
137  $length = $buffer_size;
138  $content = stream_get_contents($fh, $length, $start);
139  $output_length = strlen($content);
140  $response = $response->withBody(
141  Streams::ofString($content)
142  );
143  $end = $start + $output_length - 1;
144  }
145 
146  $response = $response->withHeader(
148  "bytes {$start}-{$end}/{$content_length}"
149  );
150 
151  return $response->withHeader(ResponseHeader::CONTENT_LENGTH, $output_length);
152  }
153 
154  public function supportPartial(): bool
155  {
156  return true;
157  }
158 
159  public function supportStreaming(): bool
160  {
161  return true;
162  }
163 
164  public function supportFileDeletion(): bool
165  {
166  return true;
167  }
168 
169  public function supportsInlineDelivery(): bool
170  {
171  return true;
172  }
173 
174  public function supportsAttachmentDelivery(): bool
175  {
176  return true;
177  }
178 }
$response
Definition: xapitoken.php:93
deliverFull(ResponseInterface $response, FileStream $stream,)
deliverPartial(RequestInterface|ServerRequestInterface $request, ResponseInterface $response, FileStream $stream,)
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
buildForStream(ServerRequestInterface $request, ResponseInterface $response, FileStream $stream,)
static ofString(string $string)
Creates a new stream with an initial value.
Definition: Streams.php:41
buildHeaders(ResponseInterface $response, FileStream $stream)
The base interface for all filesystem streams.
Definition: FileStream.php:31