'no-store', 'X-Content-Type-Options' => 'nosniff']; #[AnonymousPrefixRoute('/wopi/files/', name: 'wopi.unsupported', methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'])] public function unsupported(Request $request): Response { return $request->getMethod() === 'GET' ? new Response('', 404, self::HEADERS) : new Response('', 405, self::HEADERS + ['Allow' => 'GET']); } #[AnonymousRoute('/wopi/files/{id}', name: 'wopi.retrieve_meta')] public function retrieveMeta(Request $request, string $id): Response { return $this->respond($request, $id, static function (array $session, array $file, array $headers): Response { return new JsonResponse([ 'BaseFileName' => $file['label'], 'Size' => $file['size'], 'Version' => $file['version'], 'OwnerId' => $session['user'], 'UserId' => $session['user'], 'ReadOnly' => true, 'UserCanWrite' => false, 'SupportsUpdate' => false, 'SupportsLocks' => false, 'UserCanNotWriteRelative' => true, ], 200, $headers); }); } #[AnonymousRoute('/wopi/files/{id}/contents', name: 'wopi.retrieve_contents')] public function retrieveContents(Request $request, string $id): Response { return $this->respond($request, $id, static fn (array $session, array $file, array $headers): Response => new Response($file['content'], 200, $headers + ['Content-Type' => 'application/octet-stream', 'Content-Length' => (string) $file['size']]) ); } private function respond(Request $request, string $id, callable $response): Response { $headers = self::HEADERS; if ($request->getMethod() !== 'GET') { return $this->unsupported($request); } if (!preg_match('/^[a-f0-9]{32}$/D', $id)) { return new Response('', 404, $headers); } try { if (!$this->tenant->enabled()) { throw new HostException('Document access is unavailable.', 404); } ['session' => $session, 'file' => $file] = $this->wopi->access($this->tenant->requireIdentifier(), $id, $request); $headers['X-WOPI-ItemVersion'] = $file['version']; return $response($session, $file, $headers); } catch (HostException $error) { return new JsonResponse(['message' => $error->getMessage()], $error->status, $headers); } catch (\Throwable) { // Never log the request, query string, file contents, or access token. return new JsonResponse(['message' => 'Document access is unavailable.'], 503, $headers); } } }