/** * Get the best storage based on request and/or parameters. * * @param UploadContext $context * @throws \SRIO\RestUploadBundle\Exception\UploadException * @throws \RuntimeException * @return FileStorage */ public function getStorage(UploadContext $context) { if (count($this->storages) == 0) { throw new UploadException('No storage found'); } if (($storageName = $context->getStorageName()) !== null || ($storageName = $this->defaultStorage) !== null) { if (!array_key_exists($storageName, $this->storages)) { throw new \RuntimeException(sprintf('Storage with name %s do not exists', $storageName)); } return $this->storages[$storageName]; } return current($this->storages); }
/** * Handle an upload resume. * * @param Request $request * @param ResumableUploadSession $uploadSession * @throws \SRIO\RestUploadBundle\Exception\UploadProcessorException * @return UploadResult */ protected function handleResume(Request $request, ResumableUploadSession $uploadSession) { $filePath = $uploadSession->getFilePath(); $context = new UploadContext(); $context->setStorageName($uploadSession->getStorageName()); $contentLength = $request->headers->get('Content-Length'); if ($request->headers->has('Content-Range')) { $range = $this->parseContentRange($request->headers->get('Content-Range')); if ($range['total'] != $uploadSession->getContentLength()) { throw new UploadProcessorException(sprintf('File size must be "%d", range total length is %d', $uploadSession->getContentLength(), $range['total'])); } elseif ($range['start'] === '*') { if ($contentLength == 0) { $file = $this->storageHandler->get($context, $filePath); return $this->requestUploadStatus($context, $uploadSession, $file, $range); } throw new UploadProcessorException('Content-Length must be 0 if asking upload status'); } $uploaded = $this->storageHandler->size($context, $filePath); if ($range['start'] != $uploaded) { throw new UploadProcessorException(sprintf('Unable to start at %d while uploaded is %d', $range['start'], $uploaded)); } } else { $range = array('start' => 0, 'end' => $uploadSession->getContentLength() - 1, 'total' => $uploadSession->getContentLength() - 1); } // Handle upload from $handler = $this->getRequestContentHandler($request); $writer = $this->storageHandler->getStream($context, $filePath); if ($writer->open(new StreamMode('c')) !== true) { throw new UploadProcessorException('Unable to open stream'); } $writer->seek($range['start']); $wrote = 0; while (!$handler->eof()) { if (($bytes = $writer->write($handler->gets())) !== false) { $wrote += $bytes; } else { throw new UploadProcessorException('Unable to wrote to file'); } } $writer->close(); // Get file in context and its size $file = $this->storageHandler->get($context, $filePath); $size = $file->getSize(); // If upload is completed, create the upload file, else // return like the request upload status if ($size < $uploadSession->getContentLength()) { return $this->requestUploadStatus($context, $uploadSession, $file, $range); } elseif ($size == $uploadSession->getContentLength()) { return $this->handleCompletedUpload($context, $uploadSession, $file); } else { throw new UploadProcessorException('Wrote file size is greater that expected Content-Length'); } }