/** * Routes the request to a registered page handler * * This function triggers a plugin hook `'route', $identifier` so that plugins can * modify the routing or handle a request. * * @param \Elgg\Http\Request $request The request to handle. * @return boolean Whether the request was routed successfully. * @access private */ public function route(\Elgg\Http\Request $request) { $segments = $request->getUrlSegments(); if ($segments) { $identifier = array_shift($segments); } else { $identifier = ''; // this plugin hook is deprecated. Use elgg_register_page_handler() // to register for the '' (empty string) handler. // allow plugins to override the front page (return true to indicate // that the front page has been served) $result = _elgg_services()->hooks->trigger('index', 'system', null, false); if ($result === true) { elgg_deprecated_notice("The 'index', 'system' plugin has been deprecated. See elgg_front_page_handler()", 1.9); exit; } } // return false to stop processing the request (because you handled it) // return a new $result array if you want to route the request differently $result = array('identifier' => $identifier, 'handler' => $identifier, 'segments' => $segments); if ($this->timer) { $this->timer->begin(['build page']); } $result = $this->hooks->trigger('route', $identifier, $result, $result); if ($result === false) { return true; } if ($identifier != $result['identifier']) { $identifier = $result['identifier']; } else { if ($identifier != $result['handler']) { $identifier = $result['handler']; } } $segments = $result['segments']; $handled = false; ob_start(); if (isset($this->handlers[$identifier]) && is_callable($this->handlers[$identifier])) { $function = $this->handlers[$identifier]; $handled = call_user_func($function, $segments, $identifier); } $output = ob_get_clean(); $ajax_api = _elgg_services()->ajax; if ($ajax_api->isReady()) { $path = implode('/', $request->getUrlSegments()); $ajax_api->respondFromOutput($output, "path:{$path}"); return true; } echo $output; return $handled || headers_sent(); }
/** * {@inheritdoc} */ protected function handle() { $uri = '/' . ltrim($this->argument('uri'), '/'); $method = $this->argument('method') ?: 'GET'; $add_csrf_tokens = $this->option('tokens'); $site_url = elgg_get_site_url(); $uri = substr(elgg_normalize_url($uri), strlen($site_url)); $path_key = Application::GET_PATH_KEY; $parameters = []; $query = trim((string) $this->option('query'), '?'); parse_str($query, $parameters); if ($add_csrf_tokens) { $ts = time(); $parameters['__elgg_ts'] = $ts; $parameters['__elgg_token'] = _elgg_services()->actions->generateActionToken($ts); } $request = Request::create("?{$path_key}=" . urlencode($uri), $method, $parameters); $cookie_name = _elgg_services()->config->getCookieConfig()['session']['name']; $session_id = _elgg_services()->session->getId(); $request->cookies->set($cookie_name, $session_id); $request->headers->set('Referer', elgg_normalize_url()); if ($this->option('export')) { elgg_set_viewtype('json'); $request->headers->set('X-Elgg-Ajax-API', '2'); } _elgg_services()->setValue('request', $request); Application::index(); }
/** * 1. Register a page handler for `/foo` * 2. Register a plugin hook that uses the "handler" result param * to route all `/bar/*` requests to the `/foo` handler. * 3. Route a request for a `/bar` page. * 4. Check that the `/foo` handler was called. */ function testRouteSupportsSettingHandlerInHookResultForBackwardsCompatibility() { $this->router->registerPageHandler('foo', array($this, 'foo_page_handler')); $this->hooks->registerHandler('route', 'bar', array($this, 'bar_route_handler')); $query = http_build_query(array('__elgg_uri' => 'bar/baz')); ob_start(); $this->router->route(\Elgg\Http\Request::create("http://localhost/?{$query}")); ob_end_clean(); $this->assertEquals(1, $this->fooHandlerCalls); }
/** * Routes the request to a registered page handler * * This function triggers a plugin hook `'route', $identifier` so that plugins can * modify the routing or handle a request. * * @param \Elgg\Http\Request $request The request to handle. * @return boolean Whether the request was routed successfully. * @access private */ public function route(\Elgg\Http\Request $request) { $segments = $request->getUrlSegments(); if ($segments) { $identifier = array_shift($segments); } else { $identifier = ''; // this plugin hook is deprecated. Use elgg_register_page_handler() // to register for the '' (empty string) handler. // allow plugins to override the front page (return true to indicate // that the front page has been served) $result = elgg_trigger_plugin_hook('index', 'system', null, false); if ($result === true) { elgg_deprecated_notice("The 'index', 'system' plugin has been deprecated. See elgg_front_page_handler()", 1.9); exit; } } // return false to stop processing the request (because you handled it) // return a new $result array if you want to route the request differently $result = array('identifier' => $identifier, 'handler' => $identifier, 'segments' => $segments); $result = $this->hooks->trigger('route', $identifier, null, $result); if ($result === false) { return true; } if ($identifier != $result['identifier']) { $identifier = $result['identifier']; } else { if ($identifier != $result['handler']) { $identifier = $result['handler']; } } $segments = $result['segments']; $handled = false; if (isset($this->handlers[$identifier]) && is_callable($this->handlers[$identifier])) { $function = $this->handlers[$identifier]; $handled = call_user_func($function, $segments, $identifier); } return $handled || headers_sent(); }
/** * Handle request to /serve-icon handler * * @param bool $allow_removing_headers Alter PHP's global headers to allow caching * @return BinaryFileResponse */ public function handleServeIconRequest($allow_removing_headers = true) { $response = new Response(); $response->setExpires($this->getCurrentTime('-1 day')); $response->prepare($this->request); if ($allow_removing_headers) { // clear cache-boosting headers set by PHP session header_remove('Cache-Control'); header_remove('Pragma'); header_remove('Expires'); } $path = implode('/', $this->request->getUrlSegments()); if (!preg_match('~serve-icon/(\\d+)/(.*+)$~', $path, $m)) { return $response->setStatusCode(400)->setContent('Malformatted request URL'); } list(, $guid, $size) = $m; $entity = $this->entities->get($guid); if (!$entity instanceof \ElggEntity) { return $response->setStatusCode(404)->setContent('Item does not exist'); } $thumbnail = $entity->getIcon($size); if (!$thumbnail->exists()) { return $response->setStatusCode(404)->setContent('Icon does not exist'); } $if_none_match = $this->request->headers->get('if_none_match'); if (!empty($if_none_match)) { // strip mod_deflate suffixes $this->request->headers->set('if_none_match', str_replace('-gzip', '', $if_none_match)); } $filenameonfilestore = $thumbnail->getFilenameOnFilestore(); $last_updated = filemtime($filenameonfilestore); $etag = '"' . $last_updated . '"'; $response->setPrivate()->setEtag($etag)->setExpires($this->getCurrentTime('+1 day'))->setMaxAge(86400); if ($response->isNotModified($this->request)) { return $response; } $headers = ['Content-Type' => (new MimeTypeDetector())->getType($filenameonfilestore)]; $response = new BinaryFileResponse($filenameonfilestore, 200, $headers, false, 'inline'); $response->prepare($this->request); $response->setPrivate()->setEtag($etag)->setExpires($this->getCurrentTime('+1 day'))->setMaxAge(86400); return $response; }
/** * {@inheritdoc} */ protected function handle() { $action = trim($this->argument('action_name'), '/'); $path_key = Application::GET_PATH_KEY; $uri = "action/{$action}"; $parameters = []; $query = trim((string) $this->option('query'), '?'); parse_str($query, $parameters); $ts = time(); $parameters['__elgg_ts'] = $ts; $parameters['__elgg_token'] = _elgg_services()->actions->generateActionToken($ts); $request = Request::create("?{$path_key}=" . urlencode($uri), 'POST', $parameters); $cookie_name = _elgg_services()->config->getCookieConfig()['session']['name']; $session_id = _elgg_services()->session->getId(); $request->cookies->set($cookie_name, $session_id); $request->headers->set('Referer', elgg_normalize_url('cli')); $request->headers->set('X-Elgg-Ajax-API', 2); elgg_set_viewtype('json'); _elgg_services()->setValue('request', $request); Application::index(); }
public function createRequest($uri = '', $method = 'POST', $parameters = [], $xhr = false) { $site_url = elgg_get_site_url(); $path = substr(elgg_normalize_url($uri), strlen($site_url)); $path_key = Application::GET_PATH_KEY; $request = Request::create("?{$path_key}={$path}", $method, $parameters); $cookie_name = $this->config->getCookieConfig()['session']['name']; $session_id = $this->session->getId(); $request->cookies->set($cookie_name, $session_id); if ($xhr) { $request->headers->set('X-Requested-With', 'XMLHttpRequest'); } return $request; }
function testRouteOverridenFromHook() { $this->router->registerPageHandler('foo', array($this, 'foo_page_handler')); $this->hooks->registerHandler('route', 'foo', array($this, 'bar_route_override')); $query = http_build_query(array(Application::GET_PATH_KEY => 'foo')); ob_start(); $this->router->route(\Elgg\Http\Request::create("http://localhost/?{$query}")); $result = ob_get_contents(); ob_end_clean(); $this->assertEquals("Page handler override from hook", $result); $this->assertEquals(0, $this->fooHandlerCalls); }
/** * @group FileService */ public function testSend400WhenUrlIsMalformmatted() { $request = \Elgg\Http\Request::create(''); $response = $this->handler->getResponse($request); $this->assertEquals(400, $response->getStatusCode()); }
/** * Check if the request is an XmlHttpRequest * @return bool */ public function isXhr() { return $this->request->isXmlHttpRequest(); }
/** * Request factory * * @param \Elgg\Di\ServiceProvider $c Dependency injection container * @return \Elgg\Http\Request */ protected function getRequest(\Elgg\Di\ServiceProvider $c) { return \Elgg\Http\Request::createFromGlobals(); }
/** * @group IconService */ public function testCanHandleServeIconRequest() { $file = new \ElggFile(); $file->owner_guid = 1; $file->setFilename('600x300.jpg'); $path_key = \Elgg\Application::GET_PATH_KEY; $this->request = \Elgg\Http\Request::create("?{$path_key}=serve-icon/{$this->entity->guid}/small"); $service = $this->createService(); $service->setCurrentTime(); $service->saveIconFromElggFile($this->entity, $file); $response = $service->handleServeIconRequest(false); $icon = $service->getIcon($this->entity, 'small'); $this->assertInstanceOf(\Symfony\Component\HttpFoundation\BinaryFileResponse::class, $response); $this->assertEquals(200, $response->getStatusCode()); $this->assertEquals('image/jpeg', $response->headers->get('Content-Type')); $filesize = filesize($icon->getFilenameOnFilestore()); $this->assertEquals($filesize, $response->headers->get('Content-Length')); $this->assertContains('inline', $response->headers->get('Content-Disposition')); $this->assertEquals('"' . $icon->getModifiedTime() . '"', $response->headers->get('Etag')); $this->assertEquals($service->getCurrentTime('+1 day'), $response->getExpires()); $this->assertEquals('max-age=86400, private', $response->headers->get('cache-control')); // now try conditional request $this->request->headers->set('if-none-match', '"' . $icon->getModifiedTime() . '"'); $response = $service->handleServeIconRequest(false); $this->assertEquals(304, $response->getStatusCode()); $this->assertEquals($service->getCurrentTime('+1 day'), $response->getExpires()); $this->assertEquals('max-age=86400, private', $response->headers->get('cache-control')); }
/** * Set an initial context if using index.php front controller. * * @param Request $request Elgg HTTP request * @return void * @access private */ function _elgg_set_initial_context(\Elgg\Http\Request $request) { // don't do this for *_handler.php, etc. if (basename($request->server->get('SCRIPT_FILENAME')) === 'index.php') { $context = $request->getFirstUrlSegment(); if (!$context) { $context = 'main'; } _elgg_services()->context->set($context); } }
/** * Create an HTTP request * * @param string $uri URI of the request * @param string $method HTTP method * @param array $parameters Query/Post parameters * @param int $ajax AJAX api version (0 for non-ajax) * @param bool $add_csrf_tokens Add CSRF tokens * @return Request */ public static function prepareHttpRequest($uri = '', $method = 'GET', $parameters = [], $ajax = 0, $add_csrf_tokens = false) { $site_url = elgg_get_site_url(); $path = substr(elgg_normalize_url($uri), strlen($site_url)); $path_key = Application::GET_PATH_KEY; if ($add_csrf_tokens) { $ts = time(); $parameters['__elgg_ts'] = $ts; $parameters['__elgg_token'] = _elgg_services()->actions->generateActionToken($ts); } $request = Request::create("?{$path_key}=" . urlencode($path), $method, $parameters); $cookie_name = _elgg_services()->config->getCookieConfig()['session']['name']; $session_id = _elgg_services()->session->getId(); $request->cookies->set($cookie_name, $session_id); $request->headers->set('Referer', elgg_normalize_url('phpunit')); if ($ajax) { $request->headers->set('X-Requested-With', 'XMLHttpRequest'); if ($ajax >= 2) { $request->headers->set('X-Elgg-Ajax-API', (string) $ajax); } } return $request; }
/** * Gets the normalized query string for the Request. * * It builds a normalized query string, where keys/value pairs are alphabetized * and have consistent escaping. * * @return string|null A normalized query string for the Request */ public function getQueryString() { $qs = \Elgg\Http\Request::normalizeQueryString($this->server->get('QUERY_STRING')); return '' === $qs ? null : $qs; }
/** * Filter a request through the route:rewrite hook * * @param Request $request Elgg request * * @return Request * @access private */ public function allowRewrite(Request $request) { $segments = $request->getUrlSegments(); if ($segments) { $identifier = array_shift($segments); } else { $identifier = ''; } $old = array('identifier' => $identifier, 'segments' => $segments); $new = _elgg_services()->hooks->trigger('route:rewrite', $identifier, $old, $old); if ($new === $old) { return $request; } if (!isset($new['identifier']) || !isset($new['segments']) || !is_string($new['identifier']) || !is_array($new['segments'])) { throw new RuntimeException('rewrite_path handler returned invalid route data.'); } // rewrite request $segments = $new['segments']; array_unshift($segments, $new['identifier']); return $request->setUrlSegments($segments); }