40 $this->crypto = $crypto;
41 $this->config = $config;
52 $response =
new Response();
53 $response->prepare($request);
56 if (!preg_match(
'~serve-file/e(\d+)/l(\d+)/d([ia])/c([01])/([a-zA-Z0-9\-_]+)/(.*)$~',
$path,
$m)) {
57 return $response->setStatusCode(400)->setContent(
'Malformatted request URL');
60 list(, $expires, $last_updated, $disposition, $use_cookie,
$mac, $path_from_dataroot) =
$m;
62 if ($expires && $expires <
time()) {
63 return $response->setStatusCode(403)->setContent(
'URL has expired');
67 'expires' => (
int) $expires,
68 'last_updated' => (
int) $last_updated,
69 'disposition' => $disposition,
70 'path' => $path_from_dataroot,
71 'use_cookie' => (
int) $use_cookie,
73 if ((
bool) $use_cookie) {
74 $hmac_data[
'cookie'] = $this->getCookieValue($request);
78 $hmac = $this->crypto->getHmac($hmac_data);
79 if (!$hmac->matchesToken(
$mac)) {
80 return $response->setStatusCode(403)->setContent(
'HMAC mistmatch');
84 if (0 === strpos($path_from_dataroot,
':')) {
85 $path_from_dataroot = Base64Url::decode(substr($path_from_dataroot, 1));
89 $filenameonfilestore =
"{$dataroot}{$path_from_dataroot}";
91 if (!is_readable($filenameonfilestore)) {
92 return $response->setStatusCode(404)->setContent(
'File not found');
95 $actual_last_updated = filemtime($filenameonfilestore);
96 if ($actual_last_updated != $last_updated) {
97 return $response->setStatusCode(403)->setContent(
'URL has expired');
100 $if_none_match = $request->headers->get(
'if_none_match');
101 if (!empty($if_none_match)) {
103 $request->headers->set(
'if_none_match', str_replace(
'-gzip',
'', $if_none_match));
106 $etag =
'"' . $actual_last_updated .
'"';
107 $response->setPublic()->setEtag($etag);
108 if ($response->isNotModified($request)) {
112 $public = $use_cookie ?
false :
true;
113 $content_disposition = $disposition ==
'i' ?
'inline' :
'attachment';
118 $response =
new BinaryFileResponse($filenameonfilestore, 200,
$headers, $public, $content_disposition);
120 $sendfile_type = $this->config->getVolatile(
'X-Sendfile-Type');
121 if ($sendfile_type) {
122 $request->headers->set(
'X-Sendfile-Type', $sendfile_type);
124 $mapping = (string)$this->config->getVolatile(
'X-Accel-Mapping');
125 $request->headers->set(
'X-Accel-Mapping', $mapping);
127 $response->trustXSendfileTypeHeader();
130 $response->prepare($request);
132 if (empty($expires)) {
133 $expires = strtotime(
'+1 year');
135 $expires_dt = (
new DateTime())->setTimestamp($expires);
136 $response->setExpires($expires_dt);
138 $response->setEtag($etag);
148 private function getCookieValue(
Request $request) {
149 $config = $this->config->getCookieConfig();
150 $session_name = $config[
'session'][
'name'];
151 return $request->cookies->get($session_name,
'');
__construct(\ElggCrypto $crypto, Config $config)
Constructor.
getResponse(Request $request)
Handle a request for a file.
Access to configuration values.
getUrlSegments($raw=false)
Get the Elgg URL segments.
Detect the MIME type of a file.
http free of to any person obtaining a copy of this software and associated documentation to deal in the Software without including without limitation the rights to use