/** * Implements module logic for given hook * * @param \AppserverIo\Psr\HttpMessage\RequestInterface $request A request object * @param \AppserverIo\Psr\HttpMessage\ResponseInterface $response A response object * @param \AppserverIo\Server\Interfaces\RequestContextInterface $requestContext A requests context instance * @param int $hook The current hook to process logic for * * @return bool * @throws \AppserverIo\Server\Exceptions\ModuleException */ public function process(RequestInterface $request, ResponseInterface $response, RequestContextInterface $requestContext, $hook) { // In php an interface is, by definition, a fixed contract. It is immutable. // So we have to declare the right ones afterwards... /** * @var $request \AppserverIo\Psr\HttpMessage\RequestInterface */ /** * @var $response \AppserverIo\Psr\HttpMessage\ResponseInterface */ // if false hook is coming do nothing if (ModuleHooks::REQUEST_POST !== $hook) { return; } // check if core module should still handle this request // maybe later on this can be overwritten by another core module for some reasons if ($requestContext->getServerVar(ServerVars::SERVER_HANDLER) !== self::MODULE_NAME) { // stop processing return; } // populates request context for possible script calling based on file handler configurations $this->populateRequestContext($requestContext); // check if file handler is not core module anymore if ($requestContext->getServerVar(ServerVars::SERVER_HANDLER) !== self::MODULE_NAME) { // stop processing return; } // if existing file should be served if ($requestContext->hasServerVar(ServerVars::SCRIPT_FILENAME)) { $scriptFilename = $requestContext->getServerVar(ServerVars::SCRIPT_FILENAME); // get file info $fileInfo = new \SplFileInfo($scriptFilename); // build etag $eTag = sprintf('"%x-%x-%x"', $fileInfo->getInode(), $fileInfo->getSize(), (double) str_pad($fileInfo->getMTime(), 16, '0')); // set last modified header $response->addHeader(Protocol::HEADER_LAST_MODIFIED, gmdate(DATE_RFC822, $fileInfo->getMTime())); // set etag header $response->addHeader(Protocol::HEADER_ETAG, $eTag); // set correct mimetype header $response->addHeader(Protocol::HEADER_CONTENT_TYPE, MimeTypes::getMimeTypeByExtension($fileInfo->getExtension())); // caching checks if ($request->hasHeader(Protocol::HEADER_IF_NONE_MATCH) && $request->getHeader(Protocol::HEADER_IF_NONE_MATCH) === $eTag) { // set not modified status without content $response->setStatusCode(304); } else { // serve file by set body stream to file descriptor stream $response->setBodyStream(fopen($scriptFilename, "r")); } // set response state to be dispatched after this without calling other modules process $response->setState(HttpResponseStates::DISPATCH); // if we got here its maybe a directory index surfing request if $validDir is same as uri // todo: implement directory index view and surfing } else { // for now we will throw a 404 as well here for non existing index files in directory throw new ModuleException(sprintf("The requested URL %s was not found on this server.", parse_url($requestContext->getServerVar(ServerVars::X_REQUEST_URI), PHP_URL_PATH)), 404); } }
/** * Tries to load the requested thumbnail from the applications WEB-INF directory * and adds it to the response. * * @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface $servletRequest The request instance * @param \AppserverIo\Psr\Servlet\Http\HttpServletResponseInterface $servletResponse The response instance * * @return void * @see \AppserverIo\Psr\Servlet\Http\HttpServlet::doGet() * * @SWG\Get( * path="/thumbnails.do/{id}", * tags={"applications"}, * summary="The application's thumbnail", * produces={"image/png"}, * @SWG\Parameter( * name="id", * in="path", * description="The name of the application to load the thumbnail for", * required=true, * type="string" * ), * @SWG\Response( * response=200, * description="The application's thumbnail" * ), * @SWG\Response( * response=500, * description="Internal Server Error" * ) * ) */ public function doGet(HttpServletRequestInterface $servletRequest, HttpServletResponseInterface $servletResponse) { // load the requested path info, e. g. /api/thumbnails.do/example/ $pathInfo = trim($servletRequest->getPathInfo(), '/'); // extract the entity and the ID, if available list($id, ) = explode('/', $pathInfo); // load file information and return the file object if possible $fileInfo = new \SplFileInfo($path = $this->getApplicationProcessor()->thumbnail($id)); if ($fileInfo->isDir()) { throw new FoundDirInsteadOfFileException(sprintf("Requested file %s is a directory", $path)); } if ($fileInfo->isFile() === false) { throw new FileNotFoundException(sprintf('File %s not not found', $path)); } if ($fileInfo->isReadable() === false) { throw new FileNotReadableException(sprintf('File %s is not readable', $path)); } // open the file itself $file = $fileInfo->openFile(); // set mimetypes to header $servletResponse->addHeader(HttpProtocol::HEADER_CONTENT_TYPE, MimeTypes::getMimeTypeByExtension(pathinfo($file->getFilename(), PATHINFO_EXTENSION))); // set last modified date from file $servletResponse->addHeader(HttpProtocol::HEADER_LAST_MODIFIED, gmdate('D, d M Y H:i:s \\G\\M\\T', $file->getMTime())); // set expires date $servletResponse->addHeader(HttpProtocol::HEADER_EXPIRES, gmdate('D, d M Y H:i:s \\G\\M\\T', time() + 3600)); // check if If-Modified-Since header info is set if ($servletRequest->getHeader(HttpProtocol::HEADER_IF_MODIFIED_SINCE)) { // check if file is modified since header given header date if (strtotime($servletRequest->getHeader(HttpProtocol::HEADER_IF_MODIFIED_SINCE)) >= $file->getMTime()) { // send 304 Not Modified Header information without content $servletResponse->addHeader(HttpProtocol::HEADER_STATUS, 'HTTP/1.1 304 Not Modified'); $servletResponse->appendBodyStream(PHP_EOL); return; } } // add the thumbnail as response content $servletResponse->appendBodyStream(file_get_contents($file->getRealPath())); }