/** * Handles request in order to authenticate. * * @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface $servletRequest The request instance * @param \AppserverIo\Psr\Servlet\Http\HttpServletResponseInterface $servletResponse The response instance * * @return boolean TRUE if the authentication has been successful, else FALSE * * @throws \Exception */ public function handleRequest(HttpServletRequestInterface $servletRequest, HttpServletResponseInterface $servletResponse) { // iterate over all servlets and return the matching one /** * @var string $urlPattern * @var \AppserverIo\Http\Authentication\AuthenticationInterface $authenticationAdapter */ foreach ($this->authenticationAdapters as $urlPattern => $authenticationAdapter) { // we'll match our URI against the URL pattern if (fnmatch($urlPattern, $servletRequest->getServletPath() . $servletRequest->getPathInfo())) { // the URI pattern matches, init the adapter and try to authenticate // check if auth header is not set in coming request headers if (!$servletRequest->hasHeader(Protocol::HEADER_AUTHORIZATION)) { // send header for challenge authentication against client $servletResponse->addHeader(HttpProtocol::HEADER_WWW_AUTHENTICATE, $authenticationAdapter->getAuthenticateHeader()); } // initialize the adapter with the current request $authenticationAdapter->init($servletRequest->getHeader(HttpProtocol::HEADER_AUTHORIZATION), $servletRequest->getMethod()); // try to authenticate the request $authenticated = $authenticationAdapter->authenticate(); if (!$authenticated) { // send header for challenge authentication against client $servletResponse->addHeader(HttpProtocol::HEADER_WWW_AUTHENTICATE, $authenticationAdapter->getAuthenticateHeader()); } return $authenticated; } } // we did not find an adapter for that URI pattern, no authentication required then return true; }
/** * Processes the request by invoking the request handler that executes the servlet * in a protected context. * * @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface $servletRequest The request instance * @param \AppserverIo\Psr\Servlet\Http\HttpServletResponseInterface $servletResponse The response instance * * @return void */ public function invoke(HttpServletRequestInterface $servletRequest, HttpServletResponseInterface $servletResponse) { try { // unpack the remote method call $remoteMethod = RemoteMethodProtocol::unpack($servletRequest->getBodyContent()); // load the application context /** @var \AppserverIo\Appserver\Application\Application $application */ $application = $servletRequest->getContext(); // prepare method name and parameters and invoke method $className = $remoteMethod->getClassName(); $methodName = $remoteMethod->getMethodName(); $parameters = $remoteMethod->getParameters(); $sessionId = $remoteMethod->getSessionId(); // load the bean manager and the bean instance $instance = $application->search($className, array($sessionId, array($application))); // invoke the remote method call on the local instance $response = call_user_func_array(array($instance, $methodName), $parameters); // serialize the remote method and write it to the socket $servletResponse->appendBodyStream(RemoteMethodProtocol::pack($response)); // re-attach the bean instance in the container and unlock it $application->search('BeanContextInterface')->attach($instance, $sessionId); } catch (\Exception $e) { // catch the exception and append it to the body stream $servletResponse->appendBodyStream(RemoteMethodProtocol::pack(RemoteExceptionWrapper::factory($e))); } // finally dispatch this request, because we have finished processing it $servletRequest->setDispatched(true); }
/** * Try to authenticate the user making this request, based on the specified login configuration. * * Return TRUE if any specified constraint has been satisfied, or FALSE if we have created a response * challenge already. * * @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface $servletRequest The servlet request instance * @param \AppserverIo\Psr\Servlet\Http\HttpServletResponseInterface $servletResponse The servlet response instance * * @return boolean TRUE if authentication has already been processed on a request before, else FALSE * @throws \AppserverIo\Http\Authentication\AuthenticationException Is thrown if the request can't be authenticated */ public function authenticate(HttpServletRequestInterface $servletRequest, HttpServletResponseInterface $servletResponse) { // check if auth header is not set in coming request headers if ($servletRequest->hasHeader(Protocol::HEADER_AUTHORIZATION) === false) { // stop processing immediately $servletRequest->setDispatched(true); $servletResponse->setStatusCode(401); $servletResponse->addHeader(Protocol::HEADER_WWW_AUTHENTICATE, $this->getAuthenticateHeader()); return false; } // load the raw login credentials $rawAuthData = $servletRequest->getHeader(Protocol::HEADER_AUTHORIZATION); // set auth hash got from auth data request header and check if username and password has been passed if (strstr($credentials = base64_decode(trim(strstr($rawAuthData, " "))), ':') === false) { // stop processing immediately $servletRequest->setDispatched(true); $servletResponse->setStatusCode(401); $servletResponse->addHeader(Protocol::HEADER_WWW_AUTHENTICATE, $this->getAuthenticateHeader()); return false; } // get out username and password list($username, $password) = explode(':', $credentials); // query whether or not a username and a password has been passed if ($password === null || $username === null) { // stop processing immediately $servletRequest->setDispatched(true); $servletResponse->setStatusCode(401); $servletResponse->addHeader(Protocol::HEADER_WWW_AUTHENTICATE, $this->getAuthenticateHeader()); return false; } // set username and password $this->username = new String($username); $this->password = new String($password); // load the realm to authenticate this request for /** @var AppserverIo\Appserver\ServletEngine\Security\RealmInterface $realm */ $realm = $this->getAuthenticationManager()->getRealm($this->getRealmName()); // authenticate the request and initialize the user principal $userPrincipal = $realm->authenticate($this->getUsername(), $this->getPassword()); // query whether or not the realm returned an authenticated user principal if ($userPrincipal == null) { // stop processing immediately $servletRequest->setDispatched(true); $servletResponse->setStatusCode(401); $servletResponse->setBodyStream('Unauthorized'); $servletResponse->addHeader(Protocol::HEADER_WWW_AUTHENTICATE, $this->getAuthenticateHeader()); return false; } // add the user principal and the authentication type to the request $servletRequest->setUserPrincipal($userPrincipal); $servletRequest->setAuthType($this->getAuthType()); return true; }
/** * Encodes the request using the configured encoding method, e. g. JSON. * * @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface $servletRequest The request instance * @param \AppserverIo\Psr\Servlet\Http\HttpServletResponseInterface $servletResponse The response instance * * @return void */ public function encode(HttpServletRequestInterface $servletRequest, HttpServletResponseInterface $servletResponse) { // load the servlet response status code $statusCode = $servletResponse->getStatusCode(); // load the result to be encoded, but only if we've NO redirect response (response code 300 - 399) if (($statusCode < 299 || $statusCode > 399) && ($result = $servletRequest->getAttribute(RequestKeys::RESULT))) { // encode the result with the configured encoder $viewData = $this->getEncodingHandler()->encode($result); // add the header for the content type and append the encoded content $servletResponse->addHeader(HttpProtocol::HEADER_CONTENT_TYPE, $viewData->getContentType()); $servletResponse->appendBodyStream($viewData->getData()); } }
/** * Processes the request by invoking the request handler that executes the servlet * in a protected context. * * @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface $servletRequest The request instance * @param \AppserverIo\Psr\Servlet\Http\HttpServletResponseInterface $servletResponse The response instance * * @return void */ public function invoke(HttpServletRequestInterface $servletRequest, HttpServletResponseInterface $servletResponse) { try { // unpack the remote method call $remoteMethod = RemoteMethodProtocol::unpack($servletRequest->getBodyContent()); // load the application context /** @var \AppserverIo\Appserver\Application\Application $application */ $application = $servletRequest->getContext(); // invoke the remote method and re-attach the bean instance to the container $response = $application->search(BeanContextInterface::IDENTIFIER)->invoke($remoteMethod, new ArrayList()); // serialize the remote method and write it to the socket $servletResponse->appendBodyStream(RemoteMethodProtocol::pack($response)); } catch (\Exception $e) { // catch the exception and append it to the body stream $servletResponse->appendBodyStream(RemoteMethodProtocol::pack(RemoteExceptionWrapper::factory($e))); } // finally dispatch this request, because we have finished processing it $servletRequest->setDispatched(true); }
/** * Forward's the request to the configured error page. * * @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface $servletRequest The servlet request instance * @param \AppserverIo\Psr\Servlet\Http\HttpServletResponseInterface $servletResponse The servlet response instance * * @return void */ protected function forwardToErrorPage(HttpServletRequestInterface $servletRequest, HttpServletResponseInterface $servletResponse) { // query whether or not we've an error page configured if ($formLoginConfig = $this->getConfigData()->getFormLoginConfig()) { if ($formErrorPage = $formLoginConfig->getFormErrorPage()) { // initialize the location to redirect to $location = $formErrorPage->__toString(); if ($baseModifier = $servletRequest->getBaseModifier()) { $location = $baseModifier . $location; } // redirect to the configured error page $servletRequest->setDispatched(true); $servletResponse->setStatusCode(307); $servletResponse->addHeader(Protocol::HEADER_LOCATION, $location); return; } } // redirect to the default error page $servletRequest->setAttribute(RequestHandlerKeys::ERROR_MESSAGE, 'Please configure a form-error-page when using auth-method \'Form\' in the login-config of your application\'s web.xml'); $servletRequest->setDispatched(true); $servletResponse->setStatusCode(500); }
/** * This method finally handles all PHP and user errors as well as the exceptions that * have been thrown through the servlet processing. * * @param \AppserverIo\Appserver\ServletEngine\RequestHandler $requestHandler The request handler instance * @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface $servletRequest The actual request instance * @param \AppserverIo\Psr\Servlet\Http\HttpServletResponseInterface $servletResponse The actual request instance * * @return void */ public function handleErrors(RequestHandler $requestHandler, HttpServletRequestInterface $servletRequest, HttpServletResponseInterface $servletResponse) { // return immediately if we don't have any errors if (sizeof($errors = $requestHandler->getErrors()) === 0) { return; } // iterate over the errors to process each of them foreach ($errors as $error) { // prepare the error message $message = $this->prepareMessage($error); // query whether or not we have to log the error if (Boolean::valueOf(new String(ini_get('log_errors')))->booleanValue()) { // create a local copy of the application if ($application = $servletRequest->getContext()) { // try to load the system logger from the application if ($systemLogger = $application->getLogger(LoggerUtils::SYSTEM)) { $systemLogger->log($this->mapLogLevel($error), $message); } } } // query whether or not, the error has an status code if ($statusCode = $error->getStatusCode()) { $servletResponse->setStatusCode($statusCode); } } // we add the error to the servlet request $servletRequest->setAttribute(RequestHandlerKeys::ERROR_MESSAGES, $errors); // we append the the errors to the body stream if display_errors is on if (Boolean::valueOf(new String(ini_get('display_errors')))->booleanValue()) { $servletResponse->appendBodyStream(implode('<br/>', $errors)); } // query whether or not we've a client or an server error if ($servletResponse->getStatusCode() > 399) { try { // create a local copy of the application $application = $servletRequest->getContext(); // inject the application and servlet response $servletRequest->injectResponse($servletResponse); $servletRequest->injectContext($application); // load the servlet context instance $servletManager = $application->search(ServletContextInterface::IDENTIFIER); // initialize the request URI for the error page to be rendered $requestUri = null; // iterate over the configured error pages to find a matching one foreach ($servletManager->getErrorPages() as $errorCodePattern => $errorPage) { // query whether or not we found an error page configured for the actual status code if (fnmatch($errorCodePattern, $servletResponse->getStatusCode())) { $requestUri = $errorPage; break; } } // query whether or not we've an found a configured error page if ($requestUri == null) { throw new ServletException(sprintf('Please configure an error page for status code %s', $servletResponse->getStatusCode())); } // initialize the request URI $servletRequest->setRequestUri($requestUri); // prepare the request with the new data $servletRequest->prepare(); // reset the body stream to remove content, that has already been appended $servletResponse->resetBodyStream(); // load the servlet path and session-ID $servletPath = $servletRequest->getServletPath(); $sessionId = $servletRequest->getProposedSessionId(); // load and process the servlet $servlet = $servletManager->lookup($servletPath, $sessionId); $servlet->service($servletRequest, $servletResponse); } catch (\Exception $e) { // finally log the exception $application->getInitialContext()->getSystemLogger()->critical($e->__toString()); // append the exception message to the body stream $servletResponse->appendBodyStream($e->__toString()); } } }
/** * Tries to load the requested file and adds the content 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 */ public function doGet(HttpServletRequestInterface $servletRequest, HttpServletResponseInterface $servletResponse) { // load \Mage $this->load(); // init globals $this->initGlobals($servletRequest); // run \Mage and set content $servletResponse->appendBodyStream($this->run($servletRequest)); // add the status code we've caught from the legacy app $servletResponse->setStatusCode(appserver_get_http_response_code()); // add this header to prevent .php request to be cached $servletResponse->addHeader(Protocol::HEADER_EXPIRES, '19 Nov 1981 08:52:00 GMT'); $servletResponse->addHeader(Protocol::HEADER_CACHE_CONTROL, 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0'); $servletResponse->addHeader(Protocol::HEADER_PRAGMA, 'no-cache'); // set per default text/html mimetype $servletResponse->addHeader(Protocol::HEADER_CONTENT_TYPE, 'text/html'); // grep headers and set to response object foreach (appserver_get_headers(true) as $i => $h) { // set headers defined in sapi headers $h = explode(':', $h, 2); if (isset($h[1])) { // load header key and value $key = trim($h[0]); $value = trim($h[1]); // if no status, add the header normally if ($key === Protocol::HEADER_STATUS) { // set status by Status header value which is only used by fcgi sapi's normally $servletResponse->setStatusCode($value); } elseif ($key === Protocol::HEADER_SET_COOKIE) { $servletResponse->addHeader($key, $value, true); } else { $servletResponse->addHeader($key, $value); } } } }
/** * Tries to load the requested vhosts and adds them 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="/virtualHosts.do", * tags={"virtualHosts"}, * summary="List's all virtual hosts", * @SWG\Response( * response=200, * description="A list with the available virtual hosts", * @SWG\Schema( * type="array", * @SWG\Items(ref="#/definitions/VirtualHostOverviewData") * ) * ), * @SWG\Response( * response="500", * description="Internal Server Error" * ) * ) * * @SWG\Get( * path="/virtualHosts.do/{id}", * tags={"virtualHosts"}, * summary="Loads the virtual host with the passed ID", * @SWG\Parameter( * name="id", * in="path", * description="The UUID of the virtual host to load", * required=true, * type="string" * ), * @SWG\Response( * response=200, * description="The requested virtual host", * @SWG\Schema( * ref="#/definitions/VirtualHostViewData" * ) * ), * @SWG\Response( * response="500", * description="Internal Server Error" * ) * ) */ public function doGet(HttpServletRequestInterface $servletRequest, HttpServletResponseInterface $servletResponse) { try { // load the requested path info, e. g. /api/applications.do/example/ $pathInfo = trim($servletRequest->getPathInfo(), '/'); // extract the entity and the ID, if available list($id, ) = explode('/', $pathInfo); // query whether we've found an ID or not if ($id == null) { $content = $this->getVirtualHostProcessor()->findAll(); } else { $content = $this->getVirtualHostProcessor()->load($id); } } catch (\Exception $e) { // set error message and status code $content = $e->getMessage(); $servletResponse->setStatusCode(500); } // add the result to the request $servletRequest->setAttribute(RequestKeys::RESULT, $content); }
/** * Dummy action implementation. * * @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface $servletRequest The request instance * @param \AppserverIo\Psr\Servlet\Http\HttpServletResponseInterface $servletResponse The response instance * * @return void */ public function testAction(HttpServletRequestInterface $servletRequest, HttpServletResponseInterface $servletResponse) { $servletResponse->appendBodyStream($servletRequest->getPathInfo()); }
/** * 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())); }
public function prepareResponse(HttpServletRequestInterface $servletRequest, HttpServletResponseInterface $servletResponse) { error_log("Now in " . __METHOD__ . " handling request " . $servletRequest->getUri()); // load the session and persist the data from $_SESSION $session = $servletRequest->getSession(); if ($session != null && isset($_SESSION)) { foreach ($_SESSION as $namespace => $data) { if ($namespace !== 'identifier') { error_log("Now add data for session {$session->getId()} and namespace {$namespace}: " . PHP_EOL . var_export($data, true)); $session->putData($namespace, $data); } } } // add the status code we've caught from the legacy app $servletResponse->setStatusCode(appserver_get_http_response_code()); // add this header to prevent .php request to be cached $servletResponse->addHeader(Protocol::HEADER_EXPIRES, '19 Nov 1981 08:52:00 GMT'); $servletResponse->addHeader(Protocol::HEADER_CACHE_CONTROL, 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0'); $servletResponse->addHeader(Protocol::HEADER_PRAGMA, 'no-cache'); // set per default text/html mimetype $servletResponse->addHeader(Protocol::HEADER_CONTENT_TYPE, 'text/html'); error_log("============= RESPONSE before appserver_get_headers(true) ================="); error_log(var_export($servletResponse, true)); // grep headers and set to response object foreach (appserver_get_headers(true) as $i => $h) { // set headers defined in sapi headers $h = explode(':', $h, 2); if (isset($h[1])) { // load header key and value $key = trim($h[0]); $value = trim($h[1]); // if no status, add the header normally if ($key === Protocol::HEADER_STATUS) { // set status by Status header value which is only used by fcgi sapi's normally $servletResponse->setStatus($value); } elseif ($key === Protocol::HEADER_SET_COOKIE) { $servletResponse->addHeader($key, $value, true); } else { $servletResponse->addHeader($key, $value); } } } error_log("============= RESPONSE after appserver_get_headers(true) ================="); error_log(var_export($servletResponse, true)); }