ILIAS  trunk Revision v11.0_alpha-1702-gfd3ecb7f852
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
PHPResponseBuilder.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
22 
28 
33 {
34  public function getName(): string
35  {
36  return 'php';
37  }
38 
39  public function buildForStream(
40  ServerRequestInterface $request,
41  ResponseInterface $response,
42  FileStream $stream,
43  ): ResponseInterface {
44  $response = $this->buildHeaders($response, $stream);
45  $server_params = $request->getServerParams();
46  if (isset($server_params['HTTP_RANGE']) && $this->supportPartial()) {
47  return $this->deliverPartial($request, $response, $stream);
48  }
49  return $this->deliverFull($response, $stream);
50  }
51 
52  protected function buildHeaders(
53  ResponseInterface $response,
54  FileStream $stream
55  ): ResponseInterface {
56  $uri = $stream->getMetadata('uri');
57  if ($this->supportPartial()) {
58  $response = $response->withHeader(ResponseHeader::ACCEPT_RANGES, 'bytes');
59  }
60 
61  $response = $response->withHeader(ResponseHeader::CONTENT_LENGTH, $stream->getSize());
62  try {
63  $response = $response->withHeader(
65  date("D, j M Y H:i:s", filemtime($uri) ?: time()) . " GMT"
66  );
67  } catch (\Throwable) {
68  }
69 
70  return $response->withHeader(ResponseHeader::ETAG, md5((string) $uri));
71  }
72 
73  protected function deliverFull(
74  ResponseInterface $response,
75  FileStream $stream,
76  ): ResponseInterface {
77  $stream->rewind();
78  return $response->withBody($stream);
79  }
80 
81  protected function deliverPartial(
83  ResponseInterface $response,
84  FileStream $stream,
85  ): ResponseInterface {
86  if (!$this->supportPartial()) {
87  return $response;
88  }
89  $server_params = $request->getServerParams();
90 
91  $byte_offset = 0;
92  $byte_length = $content_length = $stream->getSize();
93 
94  if (isset($server_params['HTTP_RANGE']) && preg_match(
95  '%bytes=(\d+)-(\d+)?%i',
96  (string) $server_params['HTTP_RANGE'],
97  $match
98  )) {
99  $byte_offset = (int) $match[1];
100  if (isset($match[2])) {
101  $finish_bytes = (int) $match[2];
102  $byte_length = $finish_bytes + 1;
103  } else {
104  $finish_bytes = $content_length;
105  }
106  $response = $response->withStatus(206, 'Partial Content');
107  $response = $response->withHeader(
109  "bytes {$byte_offset}-{$finish_bytes}/{$content_length}"
110  );
111  }
112 
113  $byte_range = $byte_length - $byte_offset;
114 
115  $response = $response->withHeader(ResponseHeader::CONTENT_LENGTH, $byte_length);
116 
117  $buffer_size = 512 * 16;
118  $bite_pool = $byte_range;
119 
120  $fh = $stream->detach();
121 
122  while ($bite_pool > 0) {
123  $chunk_size_requested = min($buffer_size, $bite_pool);
124  $buffer = fread($fh, $chunk_size_requested);
125  $chunk_actual_size = strlen($buffer);
126 
127  if ($chunk_actual_size === 0) {
128  throw new \RuntimeException("Chunksize became 0");
129  }
130 
131  $bite_pool -= $chunk_actual_size;
132 
133  $response->getBody()->write($buffer);
134  }
135 
136  return $response;
137  }
138 
139  public function supportPartial(): bool
140  {
141  return true;
142  }
143 
144  public function supportStreaming(): bool
145  {
146  return true;
147  }
148 
149  public function supportFileDeletion(): bool
150  {
151  return true;
152  }
153 
154  public function supportsInlineDelivery(): bool
155  {
156  return true;
157  }
158 
159  public function supportsAttachmentDelivery(): bool
160  {
161  return true;
162  }
163 }
$response
Definition: xapitoken.php:93
deliverFull(ResponseInterface $response, FileStream $stream,)
deliverPartial(RequestInterface|ServerRequestInterface $request, ResponseInterface $response, FileStream $stream,)
buildForStream(ServerRequestInterface $request, ResponseInterface $response, FileStream $stream,)
buildHeaders(ResponseInterface $response, FileStream $stream)
The base interface for all filesystem streams.
Definition: FileStream.php:31