Beispiel #1
0
 /**
  * 每个请求层,最终被调用的方法
  *
  * @return mixed
  */
 public function handle()
 {
     Base::getLog()->debug(__METHOD__ . ' handle request flow - start');
     $request = new Request($this->flow->contexts['uri']);
     // 上下文
     $this->flow->contexts['request'] = $request;
     // 处理HTTP相关,例如过滤变量,初始化相关设置
     $flow = Flow::instance('tourze-http');
     $flow->contexts =& $this->flow->contexts;
     $flow->layers = ['tourze\\Bootstrap\\Flow\\Http\\Initialization', 'tourze\\Bootstrap\\Flow\\Http\\Authentication', 'tourze\\Bootstrap\\Flow\\Http\\Authorization'];
     $flow->start();
     // 执行请求
     $response = $request->execute();
     echo $response->sendHeaders(true)->body;
     Base::getLog()->debug(__METHOD__ . ' handle request flow - end');
 }
Beispiel #2
0
 /**
  * 检测execute功能是否正常
  */
 public function testExecute()
 {
     $request = Request::factory('http://www.baidu.com');
     //$request->method = Http::POST;
     $request->query(['v1' => 'v2']);
     //$request->post(['v3' => 'v4']);
     $response = $request->execute();
     $this->assertTrue(strpos($response->body, '百度') !== false);
 }
Beispiel #3
0
 /**
  * 每个请求层,最终被调用的方法
  *
  * @return mixed
  */
 public function handle()
 {
     /** @var Request $request */
     $request =& $this->flow->contexts['request'];
     // 如果当前请求是初始请求,那么对其进行额外处理
     // 如果当前请求是CLI,那么直接当做为初始化请求
     if (PHP_SAPI == 'cli' || $request->isInitial()) {
         if (!empty($_SERVER['HTTPS']) && filter_var($_SERVER['HTTPS'], FILTER_VALIDATE_BOOLEAN) || isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && 'https' === $_SERVER['HTTP_X_FORWARDED_PROTO'] && in_array($_SERVER['REMOTE_ADDR'], Request::$trustedProxies)) {
             $request->secure = true;
         }
         if (isset($_SERVER['REQUEST_METHOD'])) {
             $method = $_SERVER['REQUEST_METHOD'];
         } else {
             $method = Http::GET;
         }
         if (isset($_SERVER['HTTP_REFERER'])) {
             $referrer = $_SERVER['HTTP_REFERER'];
         }
         if (isset($_SERVER['HTTP_USER_AGENT'])) {
             Request::$userAgent = $_SERVER['HTTP_USER_AGENT'];
         }
         if (isset($_SERVER['HTTP_X_REQUESTED_WITH'])) {
             $requestedWith = $_SERVER['HTTP_X_REQUESTED_WITH'];
         }
         Request::$clientIp = Request::getClientIP();
         if ($method !== Http::GET) {
             $body = file_get_contents('php://input');
         }
         $cookies = [];
         if ($cookieKeys = array_keys($_COOKIE)) {
             foreach ($cookieKeys as $key) {
                 $cookies[$key] = Cookie::get($key);
             }
         }
         if (isset($_SERVER['SERVER_PROTOCOL'])) {
             $request->protocol = $_SERVER['SERVER_PROTOCOL'];
         }
         $request->query($_GET)->post($_POST);
         if (isset($method)) {
             $request->method = $method;
         }
         if (isset($referrer)) {
             $request->referrer = $referrer;
         }
         if (isset($requestedWith)) {
             $request->requestedWith = $requestedWith;
         }
         if (isset($body)) {
             $request->body = $body;
         }
         if (isset($cookies)) {
             $request->cookie($cookies);
         }
     }
 }
Beispiel #4
0
 /**
  * 执行外部请求,并返回接口
  *
  *     $request->execute();
  *
  * @param  Request  $request
  * @param  Response $response
  * @return Response
  * @throws Exception
  */
 public function executeRequest(Request $request, Response $response)
 {
     $previous = Request::$current;
     Request::$current = $request;
     // 如果post数据了
     if ($post = $request->post()) {
         $request->body = http_build_query($post, null, '&');
         $request->headers('content-type', 'application/x-www-form-urlencoded; charset=' . $request->charset);
     }
     // 如果需要暴露框架信息
     if (Base::$expose) {
         $request->headers('user-agent', Base::version());
     }
     try {
         // 处理header
         $sendHeaders = [];
         if ($headers = $request->headers()) {
             foreach ($headers as $key => $value) {
                 if (is_array($value)) {
                     $value = implode(', ', $value);
                 }
                 $sendHeaders[$key] = $value;
             }
         }
         // 处理cookie
         if ($cookies = $request->cookie()) {
             $sendHeaders['Cookie'] = http_build_query($cookies, null, '; ');
         }
         $url = $request->uri;
         if ($query = $request->query()) {
             $url .= '?' . http_build_query($query, null, '&');
         }
         // 执行请求
         $result = Requests::request($url, $sendHeaders, $request->body, $request->method, $this->options);
         if (!$result->success) {
             throw new RequestException('Error fetching remote :url [ status :code ]', [':url' => $url, ':code' => $result->status_code]);
         }
         foreach ($result->headers as $k => $v) {
             $response->headers($k, $v);
         }
         $response->status = $result->status_code;
         $response->body = $result->body;
     } catch (Exception $e) {
         Request::$current = $previous;
         throw $e;
     }
     Request::$current = $previous;
     return $response;
 }
Beispiel #5
0
 /**
  * 处理请求
  *
  *     $request->execute();
  *
  * @param   Request  $request
  * @param   Response $response
  * @return \tourze\Http\Response
  * @throws \tourze\Base\Exception\BaseException
  */
 public function executeRequest(Request $request, Response $response)
 {
     $className = 'Controller';
     // 控制器
     $controller = $request->controller;
     $className = Inflector::classify($controller) . $className;
     // 目录
     $directory = $request->directory;
     if ($directory) {
         $directory = str_replace('/', '\\', $directory);
         $className = $directory . $className;
     }
     // 保存请求状态
     $previous = Request::$current;
     Request::$current = $request;
     Base::getLog()->info(__METHOD__ . ' controller class', ['class' => $className]);
     try {
         if (!class_exists($className)) {
             Base::getLog()->debug(__METHOD__ . ' class not found', ['class' => $className]);
             throw HttpException::factory(Http::NOT_FOUND, 'The requested URL :uri was not found on this server.', [':uri' => $request->uri])->request($request);
         }
         $class = new ReflectionClass($className);
         if ($class->isAbstract()) {
             Base::getLog()->error(__METHOD__ . ' calling abstract controller class', ['class' => $className]);
             throw new BaseException('Cannot create instances of abstract :controller', [':controller' => $className]);
         }
         $controller = $class->newInstance(['request' => $request, 'response' => $response]);
         $response = $class->getMethod('execute')->invoke($controller);
         if (!$response instanceof Response) {
             Base::getLog()->error(__METHOD__ . ' unknown response type');
             throw new BaseException('Controller failed to return a Response');
         }
     } catch (HttpException $e) {
         if (null === $e->request()) {
             $e->request($request);
         }
         $response = $e->getResponse();
     }
     Request::$current = $previous;
     return $response;
 }
Beispiel #6
0
 /**
  * 跳转状态码的处理
  *
  * @param Request       $request
  * @param Response      $response
  * @param RequestClient $client
  * @return null|Request
  */
 public static function onHeaderLocation(Request $request, Response $response, RequestClient $client)
 {
     if ($client->follow && in_array($response->status, [Http::CREATED, Http::MOVED_PERMANENTLY, Http::FOUND, Http::SEE_OTHER, Http::TEMPORARY_REDIRECT])) {
         switch ($response->status) {
             default:
             case Http::MOVED_PERMANENTLY:
             case Http::TEMPORARY_REDIRECT:
                 $followMethod = $request->method;
                 break;
             case Http::CREATED:
             case Http::SEE_OTHER:
                 $followMethod = Http::GET;
                 break;
             case Http::FOUND:
                 if ($client->strictRedirect) {
                     $followMethod = $request->method;
                 } else {
                     $followMethod = Http::GET;
                 }
                 break;
         }
         $origHeaders = $request->headers();
         $followHeaders = array_intersect_assoc($origHeaders, array_fill_keys($client->followHeaders, true));
         $followRequest = Request::factory($response->headers('Location'));
         $followRequest->method = $followMethod;
         $followRequest->headers($followHeaders);
         if ($followMethod !== Http::GET) {
             $followRequest->body = $request->body;
         }
         return $followRequest;
     }
     return null;
 }
Beispiel #7
0
 /**
  * 执行请求
  *
  * @return Response
  * @throws HttpException
  * @throws ClientRecursionException
  * @throws RequestException
  */
 public function execute()
 {
     if (!$this->external) {
         Base::getLog()->debug(__METHOD__ . ' execute internal request');
         $processed = Request::process($this, $this->routes);
         if ($processed) {
             // 保存匹配到的路由
             $this->route = Arr::get($processed, 'route');
             $params = Arr::get($processed, 'params');
             // 是否为外部链接
             $this->external = $this->route->isExternal();
             // 控制器放在子目录中的情况
             if (isset($params['directory'])) {
                 $this->directory = $params['directory'];
             }
             // 附加上命名空间
             if (isset($params['namespace'])) {
                 $this->directory = $params['namespace'];
             }
             // 命名空间处理
             if (!$this->directory) {
                 $this->directory = Route::$defaultNamespace;
             }
             // 修正命名空间
             if (false === strpos($this->directory, '\\')) {
                 $this->directory = Route::$defaultNamespace . $this->directory . '\\';
             }
             // 保存控制器
             $this->controller = Arr::get($params, 'controller');
             // 保存动作
             $this->action = Arr::get($params, 'action', Route::$defaultAction);
             // 清理保留字段
             foreach ($this->persistRouteParams as $name) {
                 unset($params[$name]);
             }
             $this->_params = $params;
             Base::getLog()->debug(__METHOD__ . ' execute info', ['directory' => $this->directory, 'controller' => $this->controller, 'action' => $this->action, 'params' => $this->_params]);
         } else {
             Base::getLog()->debug(__METHOD__ . ' not route matched');
         }
     }
     if (!$this->route instanceof Entry) {
         $e = HttpException::factory(Http::NOT_FOUND, 'Unable to find a route to match the URI: :uri', [':uri' => $this->uri]);
         $e->request($this);
         throw $e;
     }
     if (!$this->client instanceof RequestClient) {
         throw new RequestException('Unable to execute :uri without a RequestClient', [':uri' => $this->uri]);
     }
     return $this->client->execute($this);
 }