42 $this->config = $config;
53 $response =
new Response();
54 $response->prepare($request);
57 if (!preg_match(
'~serve-file/e(\d+)/l(\d+)/d([ia])/c([01])/([a-zA-Z0-9\-_]+)/(.*)$~',
$path, $m)) {
58 return $response->setStatusCode(400)->setContent(
'Malformatted request URL');
61 list(, $expires, $last_updated, $disposition, $use_cookie,
$mac, $path_from_dataroot) = $m;
63 if ($expires && $expires < time()) {
64 return $response->setStatusCode(403)->setContent(
'URL has expired');
69 $path_from_dataroot = str_replace(
'%20',
' ', $path_from_dataroot);
72 'expires' => (int) $expires,
73 'last_updated' => (
int) $last_updated,
74 'disposition' => $disposition,
75 'path' => $path_from_dataroot,
76 'use_cookie' => (int) $use_cookie,
78 if ((
bool) $use_cookie) {
79 $hmac_data[
'cookie'] = $this->getCookieValue($request);
83 $hmac = $this->hmac->getHmac($hmac_data);
84 if (!$hmac->matchesToken(
$mac)) {
85 return $response->setStatusCode(403)->setContent(
'HMAC mismatch');
89 if (0 === strpos($path_from_dataroot,
':')) {
90 $path_from_dataroot = Base64Url::decode(substr($path_from_dataroot, 1));
93 $filenameonfilestore =
"{$this->config->dataroot}{$path_from_dataroot}";
95 if (!is_readable($filenameonfilestore)) {
96 return $response->setStatusCode(404)->setContent(
'File not found');
99 $actual_last_updated = filemtime($filenameonfilestore);
100 if ($actual_last_updated != $last_updated) {
101 return $response->setStatusCode(403)->setContent(
'URL has expired');
104 $if_none_match = $request->headers->get(
'if_none_match');
105 if (!empty($if_none_match)) {
107 $request->headers->set(
'if_none_match', str_replace(
'-gzip',
'', $if_none_match));
110 $etag =
'"' . $actual_last_updated .
'"';
111 $response->setPublic()->setEtag($etag);
112 if ($response->isNotModified($request)) {
116 $public = $use_cookie ?
false :
true;
117 $content_disposition = $disposition ==
'i' ?
'inline' :
'attachment';
122 $response =
new BinaryFileResponse($filenameonfilestore, 200,
$headers, $public, $content_disposition);
124 $sendfile_type = $this->config->x_sendfile_type;
125 if ($sendfile_type) {
126 $request->headers->set(
'X-Sendfile-Type', $sendfile_type);
128 $mapping = (string) $this->config->x_accel_mapping;
129 $request->headers->set(
'X-Accel-Mapping', $mapping);
131 $response->trustXSendfileTypeHeader();
134 $response->prepare($request);
136 if (empty($expires)) {
137 $expires = strtotime(
'+1 year');
139 $expires_dt = (
new DateTime())->setTimestamp($expires);
140 $response->setExpires($expires_dt);
142 $response->setEtag($etag);
153 $config = $this->config->getCookieConfig();
154 $session_name = $config[
'session'][
'name'];
155 return $request->cookies->get($session_name,
'');
$request
Page handler for autocomplete endpoint.
getResponse(Request $request)
Handle a request for a file.
getUrlSegments($raw=false)
Get the Elgg URL segments.
__construct(HmacFactory $hmac, Config $config)
Constructor.
Detect the MIME type of a file.
Provides a factory for HMAC objects.