/** * The most important method. * Will start the hive engine and listening for requests. * * @param Request $request * @param AbstractResponse $response * @param boolean $sendResponse * * @return void */ public function api($request = null, $response = null, $sendResponse = true) { $this->klein->respond('POST', '/authenticate', $this->authenticate); $this->klein->onHttpError($this->handleError); // see https://github.com/klein/klein.php/wiki/Sub-Directory-Installation if ($request === null) { $request = Request::createFromGlobals(); } // Grab the server-passed "REQUEST_URI" $uri = $request->server()->get('REQUEST_URI'); // Set the request URI to a modified one (without the "subdirectory") in it $request->server()->set('REQUEST_URI', '/' . substr($uri, strlen($this->configuration['basePath']))); // Pass our request to our dispatch method $this->klein->dispatch($request, $response, $sendResponse); }
public function dispatch() { $request = \Klein\Request::createFromGlobals(); foreach ($this->middleware as $middleware) { if (!$middleware->dispatch($request)) { return; } } parent::dispatch($request, $response); }
function dispatch() { $klein = $this->klein; $caught = false; $me = $this; $request = \Klein\Request::createFromGlobals(); // Grab the server-passed "REQUEST_URI" $uri = $request->server()->get('REQUEST_URI'); if (defined('APP_PATH')) { $baseDir = APP_PATH; } else { $baseDir = '/'; } $baseDir = $this->config->get('base.path', '/'); $uri = rtrim($uri, '/'); if (substr($uri, 0, strlen($baseDir)) == $baseDir) { // Set the request URI to a modified one (without the "subdirectory") in it $request->server()->set('REQUEST_URI', substr($uri, strlen($baseDir) + 1)); } else { // Take off the initial slash $request->server()->set('REQUEST_URI', substr($uri, 1)); } usort($this->routes, function ($a, $b) use($me) { return $me->getRouteWeight($a["route"]) - $me->getRouteWeight($b["route"]); }); foreach ($this->routes as $route) { $klein->respond($route['method'], $route['route'], function ($request, $response) use($route, &$caught) { if ($caught === true) { return; } $caught = true; return $route["handler"]($request, $response); }); } $klein->dispatch($request); }
/** * Create a new mock request * * @param string $uri * @param string $req_method * @param array $parameters * @param array $cookies * @param array $server * @param array $files * @param string $body * @return void */ public static function create($uri = '/', $req_method = 'GET', $parameters = array(), $cookies = array(), $server = array(), $files = array(), $body = null) { // Create a new Request object $request = new Request(array(), array(), $cookies, $server, $files, $body); // Reformat $req_method = strtoupper(trim($req_method)); // Set its URI and Method $request->server()->set('REQUEST_URI', $uri); $request->server()->set('REQUEST_METHOD', $req_method); // Set our parameters switch ($req_method) { case 'POST': case 'PUT': case 'PATCH': case 'DELETE': $request->paramsPost()->replace($parameters); break; default: $request->paramsGet()->replace($parameters); break; } return $request; }
/** * Dispatch the request to the approriate route(s) * * Dispatch with optionally injected dependencies * This DI allows for easy testing, object mocking, or class extension * * @param Request $request The request object to give to each callback * @param Response $response The response object to give to each callback * @param boolean $send_response Whether or not to "send" the response after the last route has been matched * @param int $capture Specify a DISPATCH_* constant to change the output capturing behavior * @access public * @return void|string */ public function dispatch(Request $request = null, Response $response = null, $send_response = true, $capture = self::DISPATCH_NO_CAPTURE) { // Set/Initialize our objects to be sent in each callback $this->request = $request ?: Request::createFromGlobals(); $this->response = $response ?: new Response(); // Bind our objects to our service $this->service->bind($this->request, $this->response); // Grab some data from the request $uri = $this->request->uri(true); // Strip the query string $req_method = $this->request->method(); // Set up some variables for matching $matched = 0; $methods_matched = array(); $params = array(); $apc = function_exists('apc_fetch'); ob_start(); foreach ($this->routes as $handler) { list($method, $_route, $callback, $count_match) = $handler; // Keep track of whether this specific request method was matched $method_match = null; // Was a method specified? If so, check it against the current request method if (is_array($method)) { foreach ($method as $test) { if (strcasecmp($req_method, $test) === 0) { $method_match = true; } elseif (strcasecmp($req_method, 'HEAD') === 0 && (strcasecmp($test, 'HEAD') === 0 || strcasecmp($test, 'GET') === 0)) { // Test for HEAD request (like GET) $method_match = true; } } if (null === $method_match) { $method_match = false; } } elseif (null !== $method && strcasecmp($req_method, $method) !== 0) { $method_match = false; // Test for HEAD request (like GET) if (strcasecmp($req_method, 'HEAD') === 0 && (strcasecmp($method, 'HEAD') === 0 || strcasecmp($method, 'GET') === 0)) { $method_match = true; } } elseif (null !== $method && strcasecmp($req_method, $method) === 0) { $method_match = true; } // If the method was matched or if it wasn't even passed (in the route callback) $possible_match = is_null($method_match) || $method_match; // ! is used to negate a match if (isset($_route[0]) && $_route[0] === '!') { $negate = true; $i = 1; } else { $negate = false; $i = 0; } // Check for a wildcard (match all) if ($_route === '*') { $match = true; } elseif ($_route === '404' && !$matched && count($methods_matched) <= 0) { // Easily handle 404's try { $this->response->append(call_user_func($callback, $this->request, $this->response, $this->service, $this->app, $matched, $methods_matched)); } catch (LockedResponseException $e) { // Do nothing, since this is an automated behavior } catch (Exception $e) { $this->error($e); } ++$matched; continue; } elseif ($_route === '405' && !$matched && count($methods_matched) > 0) { // Easily handle 405's try { $this->response->append(call_user_func($callback, $this->request, $this->response, $this->service, $this->app, $matched, $methods_matched)); } catch (LockedResponseException $e) { // Do nothing, since this is an automated behavior } catch (Exception $e) { $this->error($e); } ++$matched; continue; } elseif (isset($_route[$i]) && $_route[$i] === '@') { // @ is used to specify custom regex $match = preg_match('`' . substr($_route, $i + 1) . '`', $uri, $params); } else { // Compiling and matching regular expressions is relatively // expensive, so try and match by a substring first $route = null; $regex = false; $j = 0; $n = isset($_route[$i]) ? $_route[$i] : null; // Find the longest non-regex substring and match it against the URI while (true) { if (!isset($_route[$i])) { break; } elseif (false === $regex) { $c = $n; $regex = $c === '[' || $c === '(' || $c === '.'; if (false === $regex && false !== isset($_route[$i + 1])) { $n = $_route[$i + 1]; $regex = $n === '?' || $n === '+' || $n === '*' || $n === '{'; } if (false === $regex && $c !== '/' && (!isset($uri[$j]) || $c !== $uri[$j])) { continue 2; } $j++; } $route .= $_route[$i++]; } // Check if there's a cached regex string if (false !== $apc) { $regex = apc_fetch("route:{$route}"); if (false === $regex) { $regex = $this->compileRoute($route); apc_store("route:{$route}", $regex); } } else { $regex = $this->compileRoute($route); } $match = preg_match($regex, $uri, $params); } if (isset($match) && $match ^ $negate) { // Keep track of possibly matched methods $methods_matched = array_merge($methods_matched, (array) $method); $methods_matched = array_filter($methods_matched); $methods_matched = array_unique($methods_matched); if ($possible_match) { if (!empty($params)) { $this->request->paramsNamed()->merge($params); } // Try and call our route's callback try { $this->response->append(call_user_func($callback, $this->request, $this->response, $this->service, $this->app, $matched, $methods_matched)); } catch (LockedResponseException $e) { // Do nothing, since this is an automated behavior } catch (Exception $e) { $this->error($e); } if ($_route !== '*') { $count_match && ++$matched; } } } } try { if (!$matched && count($methods_matched) > 0) { if (strcasecmp($req_method, 'OPTIONS') !== 0) { $this->response->code(405); } $this->response->header('Allow', implode(', ', $methods_matched)); } elseif (!$matched) { $this->response->code(404); } if ($this->response->chunked) { $this->response->chunk(); } else { // Output capturing behavior switch ($capture) { case self::DISPATCH_CAPTURE_AND_RETURN: return ob_get_clean(); break; case self::DISPATCH_CAPTURE_AND_REPLACE: $this->response->body(ob_get_clean()); break; case self::DISPATCH_CAPTURE_AND_PREPEND: $this->response->prepend(ob_get_clean()); break; case self::DISPATCH_CAPTURE_AND_APPEND: $this->response->append(ob_get_clean()); break; case self::DISPATCH_NO_CAPTURE: default: ob_end_flush(); break; } } // Test for HEAD request (like GET) if (strcasecmp($req_method, 'HEAD') === 0) { // HEAD requests shouldn't return a body $this->response->body(''); ob_clean(); } } catch (LockedResponseException $e) { // Do nothing, since this is an automated behavior } if ($send_response && !$this->response->isSent()) { $this->response->send(); } }
public function invokeWithRequest($action, \Klein\Request $request, \Klein\Response $response) { $params = $request->params(); $result = $this->invoke($action, $params); $result = $this->_formatResponse($action, $result, $request->format); $response->body($result); }
/** * Dispatch the request to the appropriate route(s) * * Dispatch with optionally injected dependencies * This DI allows for easy testing, object mocking, or class extension * * @param Request $request The request object to give to each callback * @param AbstractResponse $response The response object to give to each callback * @param boolean $send_response Whether or not to "send" the response after the last route has been matched * @param int $capture Specify a DISPATCH_* constant to change the output capturing behavior * @return void|string */ public function dispatch(Request $request = null, AbstractResponse $response = null, $send_response = true, $capture = self::DISPATCH_NO_CAPTURE) { // Set/Initialize our objects to be sent in each callback $this->request = $request ?: Request::createFromGlobals(); $this->response = $response ?: new Response(); // Bind our objects to our service $this->service->bind($this->request, $this->response); // Prepare any named routes $this->routes->prepareNamed(); // Grab some data from the request $uri = $this->request->pathname(); $req_method = $this->request->method(); // Set up some variables for matching $skip_num = 0; $matched = $this->routes->cloneEmpty(); // Get a clone of the routes collection, as it may have been injected $methods_matched = array(); $params = array(); $apc = function_exists('apc_fetch'); ob_start(); try { foreach ($this->routes as $route) { // Are we skipping any matches? if ($skip_num > 0) { $skip_num--; continue; } // Grab the properties of the route handler $method = $route->getMethod(); $path = $route->getPath(); $count_match = $route->getCountMatch(); // Keep track of whether this specific request method was matched $method_match = null; // Was a method specified? If so, check it against the current request method if (is_array($method)) { foreach ($method as $test) { if (strcasecmp($req_method, $test) === 0) { $method_match = true; } elseif (strcasecmp($req_method, 'HEAD') === 0 && (strcasecmp($test, 'HEAD') === 0 || strcasecmp($test, 'GET') === 0)) { // Test for HEAD request (like GET) $method_match = true; } } if (null === $method_match) { $method_match = false; } } elseif (null !== $method && strcasecmp($req_method, $method) !== 0) { $method_match = false; // Test for HEAD request (like GET) if (strcasecmp($req_method, 'HEAD') === 0 && (strcasecmp($method, 'HEAD') === 0 || strcasecmp($method, 'GET') === 0)) { $method_match = true; } } elseif (null !== $method && strcasecmp($req_method, $method) === 0) { $method_match = true; } // If the method was matched or if it wasn't even passed (in the route callback) $possible_match = null === $method_match || $method_match; // ! is used to negate a match if (isset($path[0]) && $path[0] === '!') { $negate = true; $i = 1; } else { $negate = false; $i = 0; } // Check for a wildcard (match all) if ($path === '*') { $match = true; } elseif ($path === '404' && $matched->isEmpty() && count($methods_matched) <= 0 || $path === '405' && $matched->isEmpty() && count($methods_matched) > 0) { // Warn user of deprecation trigger_error('Use of 404/405 "routes" is deprecated. Use $klein->onHttpError() instead.', E_USER_DEPRECATED); // TODO: Possibly remove in future, here for backwards compatibility $this->onHttpError($route); continue; } elseif (isset($path[$i]) && $path[$i] === '@') { // @ is used to specify custom regex $match = preg_match('`' . substr($path, $i + 1) . '`', $uri, $params); } else { // Compiling and matching regular expressions is relatively // expensive, so try and match by a substring first $expression = null; $regex = false; $j = 0; $n = isset($path[$i]) ? $path[$i] : null; // Find the longest non-regex substring and match it against the URI while (true) { if (!isset($path[$i])) { break; } elseif (false === $regex) { $c = $n; $regex = $c === '[' || $c === '(' || $c === '.'; if (false === $regex && false !== isset($path[$i + 1])) { $n = $path[$i + 1]; $regex = $n === '?' || $n === '+' || $n === '*' || $n === '{'; } if (false === $regex && $c !== '/' && (!isset($uri[$j]) || $c !== $uri[$j])) { continue 2; } $j++; } $expression .= $path[$i++]; } try { // Check if there's a cached regex string if (false !== $apc) { $regex = apc_fetch("route:{$expression}"); if (false === $regex) { $regex = $this->compileRoute($expression); apc_store("route:{$expression}", $regex); } } else { $regex = $this->compileRoute($expression); } } catch (RegularExpressionCompilationException $e) { throw RoutePathCompilationException::createFromRoute($route, $e); } $match = preg_match($regex, $uri, $params); } if (isset($match) && $match ^ $negate) { if ($possible_match) { if (!empty($params)) { /** * URL Decode the params according to RFC 3986 * @link http://www.faqs.org/rfcs/rfc3986 * * Decode here AFTER matching as per @chriso's suggestion * @link https://github.com/chriso/klein.php/issues/117#issuecomment-21093915 */ $params = array_map('rawurldecode', $params); $this->request->paramsNamed()->merge($params); } // Handle our response callback try { $this->onBeforeDispatch($route, $this->request, $this->response); $this->handleRouteCallback($route, $matched, $methods_matched); } catch (DispatchHaltedException $e) { switch ($e->getCode()) { case DispatchHaltedException::SKIP_THIS: continue 2; break; case DispatchHaltedException::SKIP_NEXT: $skip_num = $e->getNumberOfSkips(); break; case DispatchHaltedException::SKIP_REMAINING: break 2; default: throw $e; } } if ($path !== '*') { $count_match && $matched->add($route); } } // Don't bother counting this as a method match if the route isn't supposed to match anyway if ($count_match) { // Keep track of possibly matched methods $methods_matched = array_merge($methods_matched, (array) $method); $methods_matched = array_filter($methods_matched); $methods_matched = array_unique($methods_matched); } } } // Handle our 404/405 conditions if ($matched->isEmpty() && count($methods_matched) > 0) { // Add our methods to our allow header $this->response->header('Allow', implode(', ', $methods_matched)); if (strcasecmp($req_method, 'OPTIONS') !== 0) { throw HttpException::createFromCode(405); } } elseif ($matched->isEmpty()) { throw HttpException::createFromCode(404); } } catch (HttpExceptionInterface $e) { // Grab our original response lock state $locked = $this->response->isLocked(); // Call our http error handlers $this->httpError($e, $matched, $methods_matched); // Make sure we return our response to its original lock state if (!$locked) { $this->response->unlock(); } } catch (Exception $e) { $this->error($e); } try { if ($this->response->chunked) { $this->response->chunk(); } else { // Output capturing behavior switch ($capture) { case self::DISPATCH_CAPTURE_AND_RETURN: $buffed_content = null; if (ob_get_level()) { $buffed_content = ob_get_clean(); } return $buffed_content; break; case self::DISPATCH_CAPTURE_AND_REPLACE: if (ob_get_level()) { $this->response->body(ob_get_clean()); } break; case self::DISPATCH_CAPTURE_AND_PREPEND: if (ob_get_level()) { $this->response->prepend(ob_get_clean()); } break; case self::DISPATCH_CAPTURE_AND_APPEND: if (ob_get_level()) { $this->response->append(ob_get_clean()); } break; case self::DISPATCH_NO_CAPTURE: default: if (ob_get_level()) { ob_end_flush(); } } } // Test for HEAD request (like GET) if (strcasecmp($req_method, 'HEAD') === 0) { // HEAD requests shouldn't return a body $this->response->body(''); if (ob_get_level()) { ob_clean(); } } } catch (LockedResponseException $e) { // Do nothing, since this is an automated behavior } // Run our after dispatch callbacks $this->callAfterDispatchCallbacks(); if ($send_response && !$this->response->isSent()) { $this->response->send(); } }
public function testId() { // Create two requests $request_one = new Request(); $request_two = new Request(); // Make sure the ID's aren't null $this->assertNotNull($request_one->id()); $this->assertNotNull($request_two->id()); // Make sure that multiple calls yield the same result $this->assertSame($request_one->id(), $request_one->id()); $this->assertSame($request_one->id(), $request_one->id()); $this->assertSame($request_two->id(), $request_two->id()); $this->assertSame($request_two->id(), $request_two->id()); // Make sure the ID's are unique to each request $this->assertNotSame($request_one->id(), $request_two->id()); }
$bodyData = json_decode($bodyDataStr, true); $_POST = array_merge($_POST, $bodyData); if ($method === 'POST') { $_POST = array_merge($_POST, $bodyData); } elseif ($method === 'GET') { $_GET = array_merge($_GET, $bodyData); } } /*$rememberMeCookie = null; if (!isset($_COOKIE['rememberme']) && empty($_COOKIE['rememberme'])){ if (isset($_POST['REMEMBERMECOOKIE'])) $_COOKIE['rememberme'] = $_POST['REMEMBERMECOOKIE']; else if (isset($_GET['REMEMBERMECOOKIE'])) $_COOKIE['rememberme'] = $_GET['REMEMBERMECOOKIE']; }*/ require_once __DIR__ . '/../libs/router/autoload.php'; require_once __DIR__ . '/../libs/medoo-db/medoo.min.php'; require_once __DIR__ . '/../libs/medoo-db/db.php'; require_once 'load-user-system.php'; require_once 'load-models.php'; global $klein; //$klein = new \Klein\Klein(); define('APP_PATH', '/server'); $klein = new \Klein\Klein(); $request = \Klein\Request::createFromGlobals(); // Grab the server-passed "REQUEST_URI" $uri = $request->server()->get('REQUEST_URI'); // Set the request URI to a modified one (without the "subdirectory") in it $request->server()->set('REQUEST_URI', substr($uri, strlen(APP_PATH))); require_once __DIR__ . '/../routes.php'; $klein->dispatch($request);
/** * Start a validator chain for the specified parameter * * @param string $param The name of the parameter to validate * @param string $err The custom exception message to throw * @access public * @return Validator */ public function validateParam($param, $err = null) { return $this->validate($this->request->param($param), $err); }
public function testBack() { $url = 'http://google.com/'; $request = new Request(); $request->server()->set('HTTP_REFERER', $url); $this->klein_app->respond(function ($request, $response, $service) { $service->back(); }); $this->klein_app->dispatch($request); $this->assertSame($url, $this->klein_app->response()->headers()->get('location')); $this->assertTrue($this->klein_app->response()->isLocked()); // Make sure we got a 3xx response code $this->assertGreaterThan(299, $this->klein_app->response()->code()); $this->assertLessThan(400, $this->klein_app->response()->code()); }
public function getUpdateReport(Request $req) { $params = $req->paramsPost()->all(); $ad = ADLdap::get_connection(); return $ad->searchField($params['adFields'], $params['newVal']); }