/** * Parses the request for the necessary, authentication adapter specific, login credentials. * * @param \AppserverIo\Psr\HttpMessage\RequestInterface $request The request with the content of authentication data sent by client * * @return void */ protected function parse(RequestInterface $request) { // load the raw login credentials $rawAuthData = $request->getHeader(Protocol::HEADER_AUTHORIZATION); // init data and matches arrays $data = array(); $matches = array(); // define required data $requiredData = array('realm' => 1, 'nonce' => 1, 'nc' => 1, 'cnonce' => 1, 'qop' => 1, 'username' => 1, 'uri' => 1, 'response' => 1); // prepare key for parsing logic $key = implode('|', array_keys($requiredData)); // parse header value preg_match_all('@(' . $key . ')=(?:([\'"])([^\\2]+?)\\2|([^\\s,]+))@', $rawAuthData, $matches, PREG_SET_ORDER); // iterate all found values for header value foreach ($matches as $match) { // check if match could be found if ($match[3]) { $data[$match[1]] = $match[3]; } else { $data[$match[1]] = $match[4]; } // unset required value because we got it processed unset($requiredData[$match[1]]); } // set if all required data was processed $data['method'] = $this->getRequestMethod(); $this->authData = $requiredData ? false : $data; }
/** * Will call for the measurement protocol endpoint * * @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 * * @return null */ public function call(RequestInterface $request, ResponseInterface $response, RequestContextInterface $requestContext) { // merge default and configured parameters into our list $parameters = array_merge($this->defaultParameters, $this->parameters); // we want the request to be like it came from the same host, so we will reuse part of it $parameters['ua'] = $request->getHeader(HttpProtocol::HEADER_USER_AGENT); $parameters['uip'] = $requestContext->getServerVar(ServerVars::REMOTE_ADDR); // the client will be a random UUID, at least if we do not get a matching cookie if ($request->hasHeader(HttpProtocol::HEADER_COOKIE)) { // the user is known to us $cookie = $request->getHeader(HttpProtocol::HEADER_COOKIE); $matches = array(); preg_match('/_ga=GA[0-9]\\.[0-9]\\.(.+)/', $cookie, $matches); if (isset($matches[1])) { $parameters['cid'] = $matches[1]; // remove the cookie to avoid additional calls $response->removeCookie('_ga'); // filter the parameters for a known cookie $parameters = $this->filterParameters($parameters, self::COOKIE_PRESENT); } } // if there is no known client id we will set one randomly if (!isset($parameters['cid'])) { $uuid4 = Uuid::uuid4(); $parameters['cid'] = $uuid4->toString(); // filter the parameters for usage without cookie $parameters = $this->filterParameters($parameters, self::COOKIE_NOT_PRESENT); } // make the actual call $this->sendToService($parameters); }
/** * Prepares and returns the array with the FastCGI environment variables. * * @param \AppserverIo\Psr\HttpMessage\RequestInterface $request A request object * @param \AppserverIo\Server\Interfaces\RequestContextInterface $requestContext A requests context instance * * @return array The array with the prepared FastCGI environment variables */ protected function prepareEnvironment(RequestInterface $request, RequestContextInterface $requestContext) { // prepare the Fast-CGI environment variables $environment = array(ServerVars::GATEWAY_INTERFACE => 'FastCGI/1.0', ServerVars::REQUEST_METHOD => $requestContext->getServerVar(ServerVars::REQUEST_METHOD), ServerVars::SCRIPT_FILENAME => $requestContext->getServerVar(ServerVars::SCRIPT_FILENAME), ServerVars::QUERY_STRING => $requestContext->getServerVar(ServerVars::QUERY_STRING), ServerVars::SCRIPT_NAME => $requestContext->getServerVar(ServerVars::SCRIPT_NAME), ServerVars::REQUEST_URI => $requestContext->getServerVar(ServerVars::REQUEST_URI), ServerVars::DOCUMENT_ROOT => $requestContext->getServerVar(ServerVars::DOCUMENT_ROOT), ServerVars::SERVER_PROTOCOL => $requestContext->getServerVar(ServerVars::SERVER_PROTOCOL), ServerVars::HTTPS => $requestContext->getServerVar(ServerVars::HTTPS), ServerVars::SERVER_SOFTWARE => $requestContext->getServerVar(ServerVars::SERVER_SOFTWARE), ServerVars::REMOTE_ADDR => $requestContext->getServerVar(ServerVars::REMOTE_ADDR), ServerVars::REMOTE_PORT => $requestContext->getServerVar(ServerVars::REMOTE_PORT), ServerVars::SERVER_ADDR => $requestContext->getServerVar(ServerVars::SERVER_ADDR), ServerVars::SERVER_PORT => $requestContext->getServerVar(ServerVars::SERVER_PORT), ServerVars::SERVER_NAME => $requestContext->getServerVar(ServerVars::SERVER_NAME)); // if we found a redirect status, add it to the environment variables if ($requestContext->hasServerVar(ServerVars::REDIRECT_STATUS)) { $environment[ServerVars::REDIRECT_STATUS] = $requestContext->getServerVar(ServerVars::REDIRECT_STATUS); } // if we found a redirect URL, add it to the environment variables if ($requestContext->hasServerVar(ServerVars::REDIRECT_URL)) { $environment[ServerVars::REDIRECT_URL] = $requestContext->getServerVar(ServerVars::REDIRECT_URL); } // if we found a redirect URI, add it to the environment variables if ($requestContext->hasServerVar(ServerVars::REDIRECT_URI)) { $environment[ServerVars::REDIRECT_URI] = $requestContext->getServerVar(ServerVars::REDIRECT_URI); } // if we found a Content-Type header, add it to the environment variables if ($request->hasHeader(Protocol::HEADER_CONTENT_TYPE)) { $environment['CONTENT_TYPE'] = $request->getHeader(Protocol::HEADER_CONTENT_TYPE); } // if we found a Content-Length header, add it to the environment variables if ($request->hasHeader(Protocol::HEADER_CONTENT_LENGTH)) { $environment['CONTENT_LENGTH'] = $request->getHeader(Protocol::HEADER_CONTENT_LENGTH); } // create an HTTP_ environment variable for each header foreach ($request->getHeaders() as $key => $value) { $environment['HTTP_' . str_replace('-', '_', strtoupper($key))] = $value; } // create an HTTP_ environment variable for each server environment variable foreach ($requestContext->getEnvVars() as $key => $value) { $environment[$key] = $value; } // return the prepared environment return $environment; }
/** * 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 comming do nothing if (ModuleHooks::RESPONSE_PRE !== $hook) { return; } // check if content type header exists if not stop processing if (!$response->hasHeader(Protocol::HEADER_CONTENT_TYPE)) { return; } // check if no accept encoding headers are sent if (!$request->hasHeader(Protocol::HEADER_ACCEPT_ENCODING)) { return; } // check if response was encoded before and exit than if ($response->hasHeader(Protocol::HEADER_CONTENT_ENCODING)) { return; } // do not deflate on proxy requests because proxy servers are responsible for sending correct responses if ($requestContext->getServerVar(ServerVars::SERVER_HANDLER) === 'proxy') { // stop processing return; } // check if request accepts deflate if (strpos($request->getHeader(Protocol::HEADER_ACCEPT_ENCODING), 'deflate') !== false) { // get stream meta data $streamMetaData = stream_get_meta_data($response->getBodyStream()); /** * Currently it's not possible to apply zlib.deflate filter on memory (php://memory) or * temp (php://temp) streams due to a bug in that zlib library., * * So for now we'll check if stream type is not MEMORY in case of static files and add * deflate filter just for static files served via core module. * * @link https://bugs.php.net/bug.php?id=48725 */ if ($streamMetaData['stream_type'] !== 'MEMORY' && $this->isRelevantMimeType($response->getHeader(Protocol::HEADER_CONTENT_TYPE))) { // apply encoding filter to response body stream stream_filter_append($response->getBodyStream(), 'zlib.deflate', STREAM_FILTER_READ); // rewind current body stream @rewind($response->getBodyStream()); // copy body stream to make use of filter in read mode $deflateBodyStream = fopen('php://memory', 'w+b'); // copy stream with appended filter to new deflate body stream stream_copy_to_stream($response->getBodyStream(), $deflateBodyStream); // reset body stream on response $response->setBodyStream($deflateBodyStream); // set encoding header info $response->addHeader(Protocol::HEADER_CONTENT_ENCODING, 'deflate'); } } }
/** * 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 declair the right ones afterwards... /** * @var $request \AppserverIo\Psr\HttpMessage\RequestInterface */ /** * @var $response \AppserverIo\Psr\HttpMessage\ResponseInterface */ // if false hook is comming do nothing if (ModuleHooks::REQUEST_POST !== $hook) { return; } // set req and res object internally $this->request = $request; $this->response = $response; // get default rewrite maps definitions $rewriteMaps = $this->rewriteMaps; // check if there are some volatile rewrite map definitions so add them if ($requestContext->hasModuleVar(ModuleVars::VOLATILE_REWRITE_MAPS)) { $volatileRewriteMaps = $requestContext->getModuleVar(ModuleVars::VOLATILE_REWRITE_MAPS); // merge rewrite maps $rewriteMaps = array_merge($volatileRewriteMaps, $this->rewriteMaps); } // check protocol to be either http or https when secure is going on $protocol = 'http://'; if ($requestContext->getServerVar(ServerVars::HTTPS) === ServerVars::VALUE_HTTPS_ON) { $protocol = 'https://'; } // get clean request path without query string etc... $requestPath = parse_url($requestContext->getServerVar(ServerVars::X_REQUEST_URI), PHP_URL_PATH); // init all rewrite mappers by types and do look up foreach ($rewriteMaps as $rewriteMapType => $rewriteMapParams) { // Include the requested hostname as a param, some mappers might need it $rewriteMapParams['headerHost'] = $request->getHeader(Protocol::HEADER_HOST); // Same for the protocol $rewriteMapParams['protocol'] = $protocol; // Get ourselves a rewriteMapper of the right type $rewriteMapper = new $rewriteMapType($rewriteMapParams); // lookup by request path if ($targetUrl = $rewriteMapper->lookup($requestPath)) { // set enhance uri to response $response->addHeader(Protocol::HEADER_LOCATION, $targetUrl); // send redirect status $response->setStatusCode(301); // add header to be sure that is was us $response->addHeader('X-Rewritten-By', __CLASS__); // set response state to be dispatched after this without calling other modules process $response->setState(HttpResponseStates::DISPATCH); // We found something, stop the loop break; } } return true; }
/** * Will fill the header variables into our pre-collected $serverVars array * * @param \AppserverIo\Psr\HttpMessage\RequestInterface $request The request instance * * @return void */ protected function fillHeaderBackreferences(RequestInterface $request) { $headerArray = $request->getHeaders(); // Iterate over all header vars we know and add them to our serverBackreferences array foreach ($this->supportedServerVars['headers'] as $supportedServerVar) { // As we got them with another name, we have to rename them, so we will not have to do this on the fly if (@isset($headerArray[$supportedServerVar])) { $this->serverBackreferences['$' . $supportedServerVar] = $headerArray[$supportedServerVar]; // Also create for the "dynamic" substitution syntax $this->serverBackreferences['$' . $supportedServerVar] = $headerArray[$supportedServerVar]; } } }
/** * 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) { // get server context to local ref $serverContext = $this->getServerContext(); // check if response post is is comming if (ModuleHooks::RESPONSE_POST === $hook) { $this->checkShouldDisconnect(); return; } // if wrong hook is coming do nothing if (ModuleHooks::REQUEST_POST !== $hook) { return; } try { // init upstreamname and transport $upstreamName = null; $transport = 'tcp'; // check if we've configured module variables if ($requestContext->hasModuleVar(ModuleVars::VOLATILE_FILE_HANDLER_VARIABLES)) { // load the volatile file handler variables and set connection data $fileHandlerVariables = $requestContext->getModuleVar(ModuleVars::VOLATILE_FILE_HANDLER_VARIABLES); // check if upstream is set for proxy function if (isset($fileHandlerVariables['upstream'])) { $upstreamName = $fileHandlerVariables['upstream']; } if (isset($fileHandlerVariables['transport'])) { $transport = $fileHandlerVariables['transport']; } } // if there was no upstream defined if (is_null($upstreamName)) { throw new ModuleException('No upstream configured for proxy filehandler'); } // get upstream instance by configured upstream name $upstream = $serverContext->getUpstream($upstreamName); // find next proxy server by given upstream type $remoteAddr = $requestContext->getServerVar(ServerVars::REMOTE_ADDR); $proxyServer = $upstream->findServer(md5($remoteAddr)); // build proxy socket address for connection $proxySocketAddress = sprintf('%s://%s:%s', $transport, $proxyServer->getAddress(), $proxyServer->getPort()); // check if should reconnect $this->checkShouldDisconnect(); // check if proxy connection object was initialised but connection resource is not ready if ($this->connection && $this->connection->getStatus() === false) { // unset connection if corrupt $this->connection = null; } // check if connection should be established if ($this->connection === null) { // create and connect to defined backend $this->connection = StreamSocket::getClientInstance($proxySocketAddress); // set proxy connection resource as stream source for body stream directly // that avoids huge memory consumtion when transferring big files via proxy connections $response->setBodyStream($this->connection->getConnectionResource()); } // get connection to local var $connection = $this->connection; // build up raw request start line $rawRequestString = sprintf('%s %s %s' . "\r\n", $request->getMethod(), $request->getUri(), HttpProtocol::VERSION_1_1); // populate request headers $headers = $request->getHeaders(); foreach ($headers as $headerName => $headerValue) { // @todo: make keep-alive available for proxy connections if ($headerName === HttpProtocol::HEADER_CONNECTION) { $headerValue = HttpProtocol::HEADER_CONNECTION_VALUE_CLOSE; } $rawRequestString .= $headerName . HttpProtocol::HEADER_SEPARATOR . $headerValue . "\r\n"; } // get current protocol $reqProto = $requestContext->getServerVar(ServerVars::REQUEST_SCHEME); // add proxy depending headers $rawRequestString .= HttpProtocol::HEADER_X_FORWARD_FOR . HttpProtocol::HEADER_SEPARATOR . $remoteAddr . "\r\n"; $rawRequestString .= HttpProtocol::HEADER_X_FORWARDED_PROTO . HttpProtocol::HEADER_SEPARATOR . $reqProto . "\r\n"; $rawRequestString .= "\r\n"; // write headers to proxy connection $connection->write($rawRequestString); // copy raw request body stream to proxy connection $connection->copyStream($request->getBodyStream()); // read status line from proxy connection $statusLine = $connection->readLine(1024, 5); // parse start line list(, $responseStatusCode) = explode(' ', $statusLine); // map everything from proxy response to our response object $response->setStatusCode($responseStatusCode); $line = ''; $messageHeaders = ''; while (!in_array($line, array("\r\n", "\n"))) { // read next line $line = $connection->readLine(); // enhance headers $messageHeaders .= $line; } // remove ending CRLF's before parsing $messageHeaders = trim($messageHeaders); // check if headers are empty if (strlen($messageHeaders) === 0) { throw new HttpException('Missing headers'); } // delimit headers by CRLF $headerLines = explode("\r\n", $messageHeaders); // iterate all headers foreach ($headerLines as $headerLine) { // extract header info $extractedHeaderInfo = explode(HttpProtocol::HEADER_SEPARATOR, trim($headerLine)); if (!$extractedHeaderInfo || $extractedHeaderInfo[0] === $headerLine) { throw new HttpException('Wrong header format'); } // split name and value list($headerName, $headerValue) = $extractedHeaderInfo; // check header name for server // @todo: make this configurable if ($headerName === HttpProtocol::HEADER_SERVER) { continue; } // add header $response->addHeader(trim($headerName), trim($headerValue)); } // set flag false by default $this->shouldDisconnect = false; // check if connection should be closed as given in connection header if ($response->getHeader(HttpProtocol::HEADER_CONNECTION) === HttpProtocol::HEADER_CONNECTION_VALUE_CLOSE) { $this->shouldDisconnect = true; } } catch (\AppserverIo\Psr\Socket\SocketReadException $e) { // close and unset connection and try to process the request again to // not let a white page get delivered to the client $this->shouldDisconnect = true; return $this->process($request, $response, $requestContext, $hook); } catch (\AppserverIo\Psr\Socket\SocketReadTimeoutException $e) { // close and unset connection and try to process the request again to // not let a white page get delivered to the client $this->shouldDisconnect = true; return $this->process($request, $response, $requestContext, $hook); } // set response to be dispatched at this point $response->setState(HttpResponseStates::DISPATCH); }
/** * 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); } }
/** * Returns the array with the $_FILES vars. * * @param \AppserverIo\Psr\HttpMessage\RequestInterface $request The request instance * * @return array The $_FILES vars */ protected function initFileGlobals(\AppserverIo\Psr\HttpMessage\RequestInterface $request) { // init query str $queryStr = ''; // iterate all files foreach ($request->getParts() as $part) { // check if filename is given, write and register it if ($part->getFilename()) { // generate temp filename $tempName = tempnam(ini_get('upload_tmp_dir'), 'php'); // write part $part->write($tempName); // register uploaded file $this->registerFileUpload($tempName); // init error state $errorState = UPLOAD_ERR_OK; } else { // set error state $errorState = UPLOAD_ERR_NO_FILE; // clear tmp file $tempName = ''; } // check if file has array info if (preg_match('/^([^\\[]+)(\\[.+)?/', $part->getName(), $matches)) { // get first part group name and array definition if exists $partGroup = $matches[1]; $partArrayDefinition = ''; if (isset($matches[2])) { $partArrayDefinition = $matches[2]; } $queryStr .= $partGroup . '[name]' . $partArrayDefinition . '=' . $part->getFilename() . '&' . $partGroup . '[type]' . $partArrayDefinition . '=' . $part->getContentType() . '&' . $partGroup . '[tmp_name]' . $partArrayDefinition . '=' . $tempName . '&' . $partGroup . '[error]' . $partArrayDefinition . '=' . $errorState . '&' . $partGroup . '[size]' . $partArrayDefinition . '=' . $part->getSize() . '&'; } } // parse query string to array parse_str($queryStr, $filesArray); // return files array finally. return $filesArray; }
/** * 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) { // if false hook is coming do nothing if (ModuleHooks::REQUEST_POST !== $hook) { return; } // set req and res object internally $this->request = $request; $this->response = $response; // get server context to local var $serverContext = $this->getServerContext(); // Get the authentications locally so we do not mess with inter-request configuration $authenticationSets = array(); // check if there are some volatile rewrite map definitions so add them if ($requestContext->hasModuleVar(ModuleVars::VOLATILE_AUTHENTICATIONS)) { $authenticationSets[] = $requestContext->getModuleVar(ModuleVars::VOLATILE_AUTHENTICATIONS); } // get the global authentications last, as volatile authentications are prefered here as more specific configurations can lessen security $authenticationSets[] = $this->authentications; // get system logger $systemLogger = $serverContext->getLogger(LoggerUtils::SYSTEM); // check authentication information if something matches foreach ($authenticationSets as $authenticationSet) { foreach ($authenticationSet as $uriPattern => $data) { // check if pattern matches uri if (preg_match('/' . $uriPattern . '/', $requestContext->getServerVar(ServerVars::X_REQUEST_URI))) { // set type Instance to local ref $typeInstance = $this->getAuthenticationInstance($uriPattern, $data); // check if auth header is not set in coming request headers if (!$request->hasHeader(Protocol::HEADER_AUTHORIZATION)) { // send header for challenge authentication against client $response->addHeader(Protocol::HEADER_WWW_AUTHENTICATE, $typeInstance->getAuthenticateHeader()); // throw exception for auth required throw new ModuleException(null, 401); } // init type instance by request $typeInstance->init($request->getHeader(Protocol::HEADER_AUTHORIZATION), $request->getMethod()); try { // check if auth works if ($typeInstance->authenticate()) { // set server vars $requestContext->setServerVar(ServerVars::REMOTE_USER, $typeInstance->getUsername()); // break out because everything is fine at this point break; } } catch (\Exception $e) { // log exception as warning to not end up with a 500 response which is not wanted here $systemLogger->warning($e->getMessage()); } // send header for challenge authentication against client $response->addHeader(Protocol::HEADER_WWW_AUTHENTICATE, $typeInstance->getAuthenticateHeader()); // throw exception for auth required throw new ModuleException(null, 401); } } } }
/** * Will fill the header variables into our pre-collected $serverVars array * * @param \AppserverIo\Psr\HttpMessage\RequestInterface $request The request instance * * @return void */ protected function fillHeaderBackreferences(RequestInterface $request) { $headerArray = $request->getHeaders(); // Iterate over all header vars we know and add them to our serverBackreferences array foreach ($this->supportedServerVars['headers'] as $supportedServerVar) { // As we got them with another name, we have to rename them, so we will not have to do this on the fly $tmp = strtoupper(str_replace('HTTP', 'HEADER', $supportedServerVar)); if (@isset($headerArray[constant("AppserverIo\\Psr\\HttpMessage\\Protocol::{$tmp}")])) { $this->serverBackreferences['$' . $supportedServerVar] = $headerArray[constant("AppserverIo\\Psr\\HttpMessage\\Protocol::{$tmp}")]; // Also create for the "dynamic" substitution syntax $this->serverBackreferences['$' . constant("AppserverIo\\Psr\\HttpMessage\\Protocol::{$tmp}")] = $headerArray[constant("AppserverIo\\Psr\\HttpMessage\\Protocol::{$tmp}")]; } } }
/** * Implement's 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) { // profile this request if we've a logger instance if (ModuleHooks::RESPONSE_POST === $hook && $this->profileLogger instanceof ThreadSafeLoggerInterface) { $this->profileLogger->debug($request->getUri()); } }
/** * Will call for the measurement protocol endpoint * * @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 * * @return null */ public function call(RequestInterface $request, ResponseInterface $response, RequestContextInterface $requestContext) { // merge default and configured parameters into our list $parameters = array_merge($this->defaultParameters, $this->parameters); // we want the request to be like it came from the same host, so we will reuse part of it $parameters['ua'] = $request->getHeader(HttpProtocol::HEADER_USER_AGENT); $parameters['uip'] = $requestContext->getServerVar(ServerVars::REMOTE_ADDR); // the client will be a random UUID, at least if we do not get a matching cookie if ($request->hasHeader(HttpProtocol::HEADER_COOKIE)) { $cookie = $request->getHeader(HttpProtocol::HEADER_COOKIE); $matches = array(); preg_match('/_ga=GA[0-9]\\.[0-9]\\.(.+)/', $cookie, $matches); if (isset($matches[1])) { $parameters['cid'] = $matches[1]; } } if (!isset($parameters['cid'])) { $uuid4 = Uuid::uuid4(); $parameters['cid'] = $uuid4->toString(); } // make the actual call $this->sendToService($parameters); }
/** * Initialize by the authentication type with the data from the request. * * @param \AppserverIo\Psr\HttpMessage\RequestInterface $request The request with the content of authentication data sent by client * @param \AppserverIo\Psr\HttpMessage\ResponseInterface $response The response sent back to the client * * @return void * @throws \AppserverIo\Http\Authentication\AuthenticationException If the authentication type can't be initialized */ public function init(RequestInterface $request, ResponseInterface $response) { // set vars internally $this->reqMethod = $request->getMethod(); // parse auth data $this->parse($request, $response); }