Example #1
0
 /**
  * Sends the HTTP message [Request] to a remote server and processes
  * the response.
  *
  * @param   Request   $request  request to send
  * @param   Response  $request  response to send
  * @return  Response
  */
 public function _send_message(Request $request, Response $response)
 {
     $http_method_mapping = array(HTTP_Request::GET => HTTPRequest::METH_GET, HTTP_Request::HEAD => HTTPRequest::METH_HEAD, HTTP_Request::POST => HTTPRequest::METH_POST, HTTP_Request::PUT => HTTPRequest::METH_PUT, HTTP_Request::DELETE => HTTPRequest::METH_DELETE, HTTP_Request::OPTIONS => HTTPRequest::METH_OPTIONS, HTTP_Request::TRACE => HTTPRequest::METH_TRACE, HTTP_Request::CONNECT => HTTPRequest::METH_CONNECT);
     // Create an http request object
     $http_request = new HTTPRequest($request->uri(), $http_method_mapping[$request->method()]);
     if ($this->_options) {
         // Set custom options
         $http_request->setOptions($this->_options);
     }
     // Set headers
     $http_request->setHeaders($request->headers()->getArrayCopy());
     // Set cookies
     $http_request->setCookies($request->cookie());
     // Set query data (?foo=bar&bar=foo)
     $http_request->setQueryData($request->query());
     // Set the body
     if ($request->method() == HTTP_Request::PUT) {
         $http_request->addPutData($request->body());
     } else {
         $http_request->setBody($request->body());
     }
     try {
         $http_request->send();
     } catch (HTTPRequestException $e) {
         throw new Request_Exception($e->getMessage());
     } catch (HTTPMalformedHeaderException $e) {
         throw new Request_Exception($e->getMessage());
     } catch (HTTPEncodingException $e) {
         throw new Request_Exception($e->getMessage());
     }
     // Build the response
     $response->status($http_request->getResponseCode())->headers($http_request->getResponseHeader())->cookie($http_request->getResponseCookies())->body($http_request->getResponseBody());
     return $response;
 }
Example #2
0
 /**
  * Get the body
  */
 public static function body()
 {
     if (is_null(self::$body)) {
         self::$body = @file_get_contents('php://input');
     }
     return self::$body;
 }
 /**
  * Basic cache key generator that hashes the entire request and returns
  * it. This is fine for static content, or dynamic content where user
  * specific information is encoded into the request.
  * 
  *      // Generate cache key
  *      $cache_key = HTTP_Cache::basic_cache_key_generator($request);
  *
  * @param   Request $request
  * @return  string
  */
 public static function basic_cache_key_generator(Request $request)
 {
     $uri = $request->uri();
     $query = $request->query();
     $headers = $request->headers()->getArrayCopy();
     $body = $request->body();
     return sha1($uri . '?' . http_build_query($query, NULL, '&') . '~' . implode('~', $headers) . '~' . $body);
 }
Example #4
0
 /**
  * Sends the HTTP message [Request] to a remote server and processes
  * the response.
  *
  * @param   Request   request to send
  * @return  Response
  */
 public function _send_message(Request $request)
 {
     // Response headers
     $response_headers = array();
     // Set the request method
     $options[CURLOPT_CUSTOMREQUEST] = $request->method();
     // Set the request body. This is perfectly legal in CURL even
     // if using a request other than POST. PUT does support this method
     // and DOES NOT require writing data to disk before putting it, if
     // reading the PHP docs you may have got that impression. SdF
     $options[CURLOPT_POSTFIELDS] = $request->body();
     // Process headers
     if ($headers = $request->headers()) {
         $http_headers = array();
         foreach ($headers as $key => $value) {
             $http_headers[] = $key . ': ' . $value;
         }
         $options[CURLOPT_HTTPHEADER] = $http_headers;
     }
     // Process cookies
     if ($cookies = $request->cookie()) {
         $options[CURLOPT_COOKIE] = http_build_query($cookies, NULL, '; ');
     }
     // Create response
     $response = $request->create_response();
     $response_header = $response->headers();
     // Implement the standard parsing parameters
     $options[CURLOPT_HEADERFUNCTION] = array($response_header, 'parse_header_string');
     $this->_options[CURLOPT_RETURNTRANSFER] = TRUE;
     $this->_options[CURLOPT_HEADER] = FALSE;
     // Apply any additional options set to
     $options += $this->_options;
     $uri = $request->uri();
     if ($query = $request->query()) {
         $uri .= '?' . http_build_query($query, NULL, '&');
     }
     // Open a new remote connection
     $curl = curl_init($uri);
     // Set connection options
     if (!curl_setopt_array($curl, $options)) {
         throw new Request_Exception('Failed to set CURL options, check CURL documentation: :url', array(':url' => 'http://php.net/curl_setopt_array'));
     }
     // Get the response body
     $body = curl_exec($curl);
     // Get the response information
     $code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
     if ($body === FALSE) {
         $error = curl_error($curl);
     }
     // Close the connection
     curl_close($curl);
     if (isset($error)) {
         throw new Request_Exception('Error fetching remote :url [ status :code ] :error', array(':url' => $request->url(), ':code' => $code, ':error' => $error));
     }
     $response->status($code)->body($body);
     return $response;
 }
Example #5
0
 /**
  * Sends the HTTP message [Request] to a remote server and processes
  * the response.
  *
  * @param   Request   request to send
  * @return  Response
  * @uses    [PHP cURL](http://php.net/manual/en/book.curl.php)
  */
 public function _send_message(Request $request)
 {
     // Calculate stream mode
     $mode = $request->method() === HTTP_Request::GET ? 'r' : 'r+';
     // Process cookies
     if ($cookies = $request->cookie()) {
         $request->headers('cookie', http_build_query($cookies, NULL, '; '));
     }
     // Get the message body
     $body = $request->body();
     if (is_resource($body)) {
         $body = stream_get_contents($body);
     }
     // Set the content length
     $request->headers('content-length', (string) strlen($body));
     list($protocol) = explode('/', $request->protocol());
     // Create the context
     $options = array(strtolower($protocol) => array('method' => $request->method(), 'header' => (string) $request->headers(), 'content' => $body));
     // Create the context stream
     $context = stream_context_create($options);
     stream_context_set_option($context, $this->_options);
     $uri = $request->uri();
     if ($query = $request->query()) {
         $uri .= '?' . http_build_query($query, NULL, '&');
     }
     $stream = fopen($uri, $mode, FALSE, $context);
     $meta_data = stream_get_meta_data($stream);
     // Get the HTTP response code
     $http_response = array_shift($meta_data['wrapper_data']);
     if (preg_match_all('/(\\w+\\/\\d\\.\\d) (\\d{3})/', $http_response, $matches) !== FALSE) {
         $protocol = $matches[1][0];
         $status = (int) $matches[2][0];
     } else {
         $protocol = NULL;
         $status = NULL;
     }
     // Create a response
     $response = $request->create_response();
     $response_header = $response->headers();
     // Process headers
     array_map(array($response_header, 'parse_header_string'), array(), $meta_data['wrapper_data']);
     $response->status($status)->protocol($protocol)->body(stream_get_contents($stream));
     // Close the stream after use
     fclose($stream);
     return $response;
 }
Example #6
0
 /**
  * The default handler for following redirects, triggered by the presence of
  * a Location header in the response.
  *
  * The client's follow property must be set TRUE and the HTTP response status
  * one of 201, 301, 302, 303 or 307 for the redirect to be followed.
  *
  * @param Request $request
  * @param Response $response
  * @param Request_Client $client
  */
 public static function on_header_location(Request $request, Response $response, Request_Client $client)
 {
     // Do we need to follow a Location header ?
     if ($client->follow() and in_array($response->status(), array(201, 301, 302, 303, 307))) {
         // Figure out which method to use for the follow request
         switch ($response->status()) {
             default:
             case 301:
             case 307:
                 $follow_method = $request->method();
                 break;
             case 201:
             case 303:
                 $follow_method = Request::GET;
                 break;
             case 302:
                 // Cater for sites with broken HTTP redirect implementations
                 if ($client->strict_redirect()) {
                     $follow_method = $request->method();
                 } else {
                     $follow_method = Request::GET;
                 }
                 break;
         }
         // Prepare the additional request, copying any follow_headers that were present on the original request
         $orig_headers = $request->headers()->getArrayCopy();
         $follow_header_keys = array_intersect(array_keys($orig_headers), $client->follow_headers());
         $follow_headers = \Arr::extract($orig_headers, $follow_header_keys);
         $follow_request = Request::factory($response->headers('Location'))->method($follow_method)->headers($follow_headers);
         if ($follow_method !== Request::GET) {
             $follow_request->body($request->body());
         }
         return $follow_request;
     }
     return NULL;
 }
 public static function factory($uri = TRUE, $client_params = array(), $allow_external = TRUE, $injected_routes = array())
 {
     if (!Request::$initial) {
         $protocol = HTTP::$protocol;
         if (isset($_SERVER['REQUEST_METHOD'])) {
             $method = $_SERVER['REQUEST_METHOD'];
         } else {
             $method = HTTP_Request::GET;
         }
         if (!empty($_SERVER['HTTPS']) and filter_var($_SERVER['HTTPS'], FILTER_VALIDATE_BOOLEAN) or isset($_SERVER['HTTP_X_FORWARDED_PROTO']) and $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https' and in_array($_SERVER['REMOTE_ADDR'], Request::$trusted_proxies)) {
             $secure = TRUE;
         }
         if (isset($_SERVER['HTTP_REFERER'])) {
             $referrer = $_SERVER['HTTP_REFERER'];
         }
         if (isset($_SERVER['HTTP_USER_AGENT'])) {
             Request::$user_agent = $_SERVER['HTTP_USER_AGENT'];
         }
         if (isset($_SERVER['HTTP_X_REQUESTED_WITH'])) {
             $requested_with = $_SERVER['HTTP_X_REQUESTED_WITH'];
         }
         if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) and isset($_SERVER['REMOTE_ADDR']) and in_array($_SERVER['REMOTE_ADDR'], Request::$trusted_proxies)) {
             $client_ips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
             Request::$client_ip = array_shift($client_ips);
             unset($client_ips);
         } elseif (isset($_SERVER['HTTP_CLIENT_IP']) and isset($_SERVER['REMOTE_ADDR']) and in_array($_SERVER['REMOTE_ADDR'], Request::$trusted_proxies)) {
             $client_ips = explode(',', $_SERVER['HTTP_CLIENT_IP']);
             Request::$client_ip = array_shift($client_ips);
             unset($client_ips);
         } elseif (isset($_SERVER['REMOTE_ADDR'])) {
             // The remote IP address
             Request::$client_ip = $_SERVER['REMOTE_ADDR'];
         }
         if ($method !== HTTP_Request::GET) {
             // Ensure the raw body is saved for future use
             $body = file_get_contents('php://input');
         }
         if ($uri === TRUE) {
             // Attempt to guess the proper URI
             $uri = Request::detect_uri();
         }
         $cookies = array();
         if ($cookie_keys = array_keys($_COOKIE)) {
             foreach ($cookie_keys as $key) {
                 $cookies[$key] = Cookie::get($key);
             }
         }
         // Create the instance singleton
         Request::$initial = $request = new Request($uri, $client_params, $allow_external, $injected_routes);
         // Store global GET and POST data in the initial request only
         $request->protocol($protocol)->query($_GET)->post($_POST);
         if (isset($secure)) {
             // Set the request security
             $request->secure($secure);
         }
         if (isset($method)) {
             // Set the request method
             $request->method($method);
         }
         if (isset($referrer)) {
             // Set the referrer
             $request->referrer($referrer);
         }
         if (isset($requested_with)) {
             // Apply the requested with variable
             $request->requested_with($requested_with);
         }
         if (isset($body)) {
             // Set the request body (probably a PUT type)
             $request->body($body);
         }
         if (isset($cookies)) {
             $request->cookie($cookies);
         }
     } else {
         $request = new Request($uri, $client_params, $allow_external, $injected_routes);
     }
     return $request;
 }
Example #8
0
 /**
  * Creates a new request object for the given URI. New requests should be
  * created using the [Request::instance] or [Request::factory] methods.
  *
  *     $request = Request::factory($uri);
  *
  * If $cache parameter is set, the response for the request will attempt to
  * be retrieved from the cache.
  *
  * @param   string  $uri URI of the request
  * @param   Cache   $cache
  * @param   array   $injected_routes an array of routes to use, for testing
  * @return  void
  * @throws  Request_Exception
  * @uses    Route::all
  * @uses    Route::matches
  */
 public static function factory($uri = TRUE, HTTP_Cache $cache = NULL, $injected_routes = array())
 {
     // If this is the initial request
     if (!Request::$initial) {
         if (Kohana::$is_cli) {
             // Default protocol for command line is cli://
             $protocol = 'cli';
             // Get the command line options
             $options = CLI::options('uri', 'method', 'get', 'post', 'referrer');
             if (isset($options['uri'])) {
                 // Use the specified URI
                 $uri = $options['uri'];
             } elseif ($uri === TRUE) {
                 $uri = '';
             }
             if (isset($options['method'])) {
                 // Use the specified method
                 $method = strtoupper($options['method']);
             } else {
                 // Default to GET requests
                 $method = HTTP_Request::GET;
             }
             if (isset($options['get'])) {
                 // Overload the global GET data
                 parse_str($options['get'], $_GET);
             }
             if (isset($options['post'])) {
                 // Overload the global POST data
                 parse_str($options['post'], $_POST);
             }
             if (isset($options['referrer'])) {
                 $referrer = $options['referrer'];
             }
         } else {
             if (isset($_SERVER['SERVER_PROTOCOL'])) {
                 $protocol = $_SERVER['SERVER_PROTOCOL'];
             } else {
                 $protocol = HTTP::$protocol;
             }
             if (isset($_SERVER['REQUEST_METHOD'])) {
                 // Use the server request method
                 $method = $_SERVER['REQUEST_METHOD'];
             } else {
                 // Default to GET requests
                 $method = HTTP_Request::GET;
             }
             if (!empty($_SERVER['HTTPS']) and filter_var($_SERVER['HTTPS'], FILTER_VALIDATE_BOOLEAN)) {
                 // This request is secure
                 $secure = TRUE;
             }
             if (isset($_SERVER['HTTP_REFERER'])) {
                 // There is a referrer for this request
                 $referrer = $_SERVER['HTTP_REFERER'];
             }
             if (isset($_SERVER['HTTP_USER_AGENT'])) {
                 // Browser type
                 Request::$user_agent = $_SERVER['HTTP_USER_AGENT'];
             }
             if (isset($_SERVER['HTTP_X_REQUESTED_WITH'])) {
                 // Typically used to denote AJAX requests
                 $requested_with = $_SERVER['HTTP_X_REQUESTED_WITH'];
             }
             if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) and isset($_SERVER['REMOTE_ADDR']) and in_array($_SERVER['REMOTE_ADDR'], Request::$trusted_proxies)) {
                 // Use the forwarded IP address, typically set when the
                 // client is using a proxy server.
                 // Format: "X-Forwarded-For: client1, proxy1, proxy2"
                 $client_ips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
                 Request::$client_ip = array_shift($client_ips);
                 unset($client_ips);
             } elseif (isset($_SERVER['HTTP_CLIENT_IP']) and isset($_SERVER['REMOTE_ADDR']) and in_array($_SERVER['REMOTE_ADDR'], Request::$trusted_proxies)) {
                 // Use the forwarded IP address, typically set when the
                 // client is using a proxy server.
                 $client_ips = explode(',', $_SERVER['HTTP_CLIENT_IP']);
                 Request::$client_ip = array_shift($client_ips);
                 unset($client_ips);
             } elseif (isset($_SERVER['REMOTE_ADDR'])) {
                 // The remote IP address
                 Request::$client_ip = $_SERVER['REMOTE_ADDR'];
             }
             if ($method !== HTTP_Request::GET) {
                 // Ensure the raw body is saved for future use
                 $body = file_get_contents('php://input');
             }
             if ($uri === TRUE) {
                 // Attempt to guess the proper URI
                 $uri = Request::detect_uri();
             }
         }
         // Create the instance singleton
         Request::$initial = $request = new Request($uri, $cache);
         // Store global GET and POST data in the initial request only
         $request->protocol($protocol)->query($_GET)->post($_POST);
         if (isset($secure)) {
             // Set the request security
             $request->secure($secure);
         }
         if (isset($method)) {
             // Set the request method
             $request->method($method);
         }
         if (isset($referrer)) {
             // Set the referrer
             $request->referrer($referrer);
         }
         if (isset($requested_with)) {
             // Apply the requested with variable
             $request->requested_with($requested_with);
         }
         if (isset($body)) {
             // Set the request body (probably a PUT type)
             $request->body($body);
         }
     } else {
         $request = new Request($uri, $cache, $injected_routes);
     }
     return $request;
 }
Example #9
0
 /**
  * Processes the request, executing the controller action that handles this
  * request, determined by the [Route].
  *
  * 1. Before the controller action is called, the [Controller::before] method
  * will be called.
  * 2. Next the controller action will be called.
  * 3. After the controller action is called, the [Controller::after] method
  * will be called.
  *
  * By default, the output from the controller is captured and returned, and
  * no headers are sent.
  *
  *     $request->execute();
  *
  * @param   Request   $request   A request object
  * @param   Response  $response  A response object
  * @return  Response
  * @throws  Kohana_Exception
  * @uses    [Kohana::$profiling]
  * @uses    [Profiler]
  */
 public function execute_request(Request $request, Response $response)
 {
     if (Kohana::$profiling) {
         // Set the benchmark name
         $benchmark = '"' . $request->uri() . '"';
         if ($request !== Request::$initial and Request::$current) {
             // Add the parent request uri
             $benchmark .= ' « "' . Request::$current->uri() . '"';
         }
         // Start benchmarking
         $benchmark = Profiler::start('Requests', $benchmark);
     }
     // Store the current active request and replace current with new request
     $previous = Request::$current;
     Request::$current = $request;
     // Resolve the POST fields
     if ($post = $request->post()) {
         $request->body(http_build_query($post, NULL, '&'))->headers('content-type', 'application/x-www-form-urlencoded; charset=' . Kohana::$charset);
     }
     $request->headers('content-length', (string) $request->content_length());
     // If Kohana expose, set the user-agent
     if (Kohana::$expose) {
         $request->headers('user-agent', Kohana::version());
     }
     try {
         $response = $this->_send_message($request, $response);
     } catch (Exception $e) {
         // Restore the previous request
         Request::$current = $previous;
         if (isset($benchmark)) {
             // Delete the benchmark, it is invalid
             Profiler::delete($benchmark);
         }
         // Re-throw the exception
         throw $e;
     }
     // Restore the previous request
     Request::$current = $previous;
     if (isset($benchmark)) {
         // Stop the benchmark
         Profiler::stop($benchmark);
     }
     // Return the response
     return $response;
 }
Example #10
0
 /**
  * Execute the request using PHP stream. (not recommended)
  *
  * @param   Request   $request  Request to execute
  * @return  Response
  */
 protected function _native_execute(Request $request)
 {
     // Reset the headers
     Request_Client_External::$_processed_headers = array();
     // Calculate stream mode
     $mode = $request->method() === HTTP_Request::GET ? 'r' : 'r+';
     // Process cookies
     if ($cookies = $request->cookie()) {
         $request->headers('cookie', http_build_query($cookies, NULL, '; '));
     }
     // Create the context
     $options = array($request->protocol() => array('method' => $request->method(), 'header' => (string) $request->headers(), 'content' => $request->body(), 'user-agent' => 'Kohana Framework ' . Kohana::VERSION . ' (' . Kohana::CODENAME . ')'));
     // Create the context stream
     $context = stream_context_create($options);
     stream_context_set_option($context, $this->_options);
     $stream = fopen($request->uri(), $mode, FALSE, $context);
     $meta_data = stream_get_meta_data($stream);
     // Get the HTTP response code
     $http_response = array_shift($meta_data['wrapper_data']);
     if (preg_match_all('/(\\w+\\/\\d\\.\\d) (\\d{3})/', $http_response, $matches) !== FALSE) {
         $protocol = $matches[1][0];
         $status = (int) $matches[2][0];
     } else {
         $protocol = NULL;
         $status = NULL;
     }
     // Process headers
     array_map(array('Request_Client_External', '_parse_headers'), array(), $meta_data['wrapper_data']);
     // Create a response
     $response = $request->create_response();
     $response->status($status)->protocol($protocol)->headers(Request_Client_External::$_processed_headers)->body(stream_get_contents($stream));
     // Close the stream after use
     fclose($stream);
     return $response;
 }
Example #11
0
 /**
  * Authentication check.
  * 
  * @return bool
  */
 public static function isAuthenticated()
 {
     if (is_null(self::$isAuthenticated)) {
         self::$isAuthenticated = false;
         // Do we have remote authentication data in the request ?
         if (!array_key_exists('signature', $_GET)) {
             return false;
         }
         if (!array_key_exists('timestamp', $_GET)) {
             return false;
         }
         $application = array_key_exists('remote_application', $_GET) ? $_GET['remote_application'] : null;
         $uid = array_key_exists('remote_user', $_GET) ? $_GET['remote_user'] : null;
         if (!$application && !$uid) {
             return false;
         }
         self::$attributes = array();
         // Get data
         $received_signature = $_GET['signature'];
         $timestamp = (int) $_GET['timestamp'];
         if ($application) {
             // Check that application is known
             $applications = Config::get('auth_remote_applications');
             if (!is_array($applications) || !array_key_exists($application, $applications)) {
                 throw new AuthRemoteUknownApplicationException($application);
             }
             $application = new RemoteApplication($application, $applications[$application]);
         }
         // Check request time to avoid replays
         $late = time() - $timestamp - 15;
         if ($late > 0) {
             throw new AuthRemoteTooLateException($late);
         }
         // Get method from headers
         $method = null;
         foreach (array('X_HTTP_METHOD_OVERRIDE', 'REQUEST_METHOD') as $k) {
             if (!array_key_exists($k, $_SERVER)) {
                 continue;
             }
             $method = strtolower($_SERVER[$k]);
         }
         // Build signed data
         $signed = $method . '&' . $_SERVER['SERVER_NAME'] . $_SERVER['SCRIPT_NAME'] . (array_key_exists('PATH_INFO', $_SERVER) ? $_SERVER['PATH_INFO'] : '');
         $args = $_GET;
         unset($args['signature']);
         if (count($args)) {
             $signed .= '?' . implode('&', RestUtilities::flatten($args));
         }
         $input = Request::body();
         if ($input) {
             $signed .= '&' . $input;
         }
         // Check signature
         if ($application) {
             $secret = $application->secret;
         } else {
             // Get user, fail if unknown or no user secret
             try {
                 $user = User::fromId($uid);
             } catch (UserNotFoundException $e) {
                 throw new AuthRemoteUserRejectedException($uid, 'user not found');
             }
             if (!$user->auth_secret) {
                 throw new AuthRemoteUserRejectedException($user->id, 'no secret set');
             }
             $secret = $user->auth_secret;
         }
         $algorithm = Config::get('auth_remote_signature_algorithm');
         if (!$algorithm) {
             $algorithm = 'sha1';
         }
         $signature = hash_hmac($algorithm, $signed, $secret);
         if ($received_signature !== $signature) {
             throw new AuthRemoteSignatureCheckFailedException($signed, $secret, $received_signature, $signature);
         }
         // Register user id if given
         if ($uid) {
             self::$attributes['uid'] = $uid;
         }
         // Register admin level if asked for and enabled
         if ($application) {
             self::$isAdmin = $application->isAdmin;
             self::$application = $application;
             self::$attributes['remote_application'] = $application->name;
         }
         self::$isAuthenticated = true;
     }
     return self::$isAuthenticated;
 }
Example #12
0
 /**
  * @param string $uri
  * @param array $client_params
  * @param bool $allow_external
  * @param array $injected_routes
  * @internal param \HTTP_Cache $cache
  * @return \HAPI_Request|\Request|void
  */
 public static function factory($uri = '', $client_params = array(), $allow_external = TRUE, $injected_routes = array())
 {
     // If this is the initial request
     if (!Request::$initial) {
         if (isset($_SERVER['SERVER_PROTOCOL'])) {
             $protocol = $_SERVER['SERVER_PROTOCOL'];
         } else {
             $protocol = HTTP::$protocol;
         }
         if (isset($_SERVER['REQUEST_METHOD'])) {
             // Use the server request method
             $method = $_SERVER['REQUEST_METHOD'];
         } else {
             // Default to GET requests
             $method = HTTP_Request::GET;
         }
         if (!empty($_SERVER['HTTPS']) and filter_var($_SERVER['HTTPS'], FILTER_VALIDATE_BOOLEAN)) {
             // This request is secure
             $secure = TRUE;
         }
         if (isset($_SERVER['HTTP_REFERER'])) {
             // There is a referrer for this request
             $referrer = $_SERVER['HTTP_REFERER'];
         }
         if (isset($_SERVER['HTTP_USER_AGENT'])) {
             // Browser type
             Request::$user_agent = $_SERVER['HTTP_USER_AGENT'];
         }
         if (isset($_SERVER['HTTP_X_REQUESTED_WITH'])) {
             // Typically used to denote AJAX requests
             $requested_with = $_SERVER['HTTP_X_REQUESTED_WITH'];
         }
         if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) and isset($_SERVER['REMOTE_ADDR']) and in_array($_SERVER['REMOTE_ADDR'], Request::$trusted_proxies)) {
             // Use the forwarded IP address, typically set when the
             // client is using a proxy server.
             // Format: "X-Forwarded-For: client1, proxy1, proxy2"
             $client_ips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
             Request::$client_ip = array_shift($client_ips);
             unset($client_ips);
         } elseif (isset($_SERVER['HTTP_CLIENT_IP']) and isset($_SERVER['REMOTE_ADDR']) and in_array($_SERVER['REMOTE_ADDR'], Request::$trusted_proxies)) {
             // Use the forwarded IP address, typically set when the
             // client is using a proxy server.
             $client_ips = explode(',', $_SERVER['HTTP_CLIENT_IP']);
             Request::$client_ip = array_shift($client_ips);
             unset($client_ips);
         } elseif (isset($_SERVER['REMOTE_ADDR'])) {
             // The remote IP address
             Request::$client_ip = $_SERVER['REMOTE_ADDR'];
         }
         if ($method !== HTTP_Request::GET) {
             // Ensure the raw body is saved for future use
             $body = file_get_contents('php://input');
         }
         $cookies = array();
         if ($cookie_keys = array_keys($_COOKIE)) {
             foreach ($cookie_keys as $key) {
                 $cookies[$key] = Cookie::get($key);
             }
         }
         // Create the instance singleton
         Request::$initial = $request = new Request($uri, $client_params, $allow_external, $injected_routes);
         // Store global GET and POST data in the initial request only
         $request->protocol($protocol)->query($_GET)->post($_POST);
         if (isset($secure)) {
             // Set the request security
             $request->secure($secure);
         }
         if (isset($method)) {
             // Set the request method
             $request->method($method);
         }
         if (isset($referrer)) {
             // Set the referrer
             $request->referrer($referrer);
         }
         if (isset($requested_with)) {
             // Apply the requested with variable
             $request->requested_with($requested_with);
         }
         if (isset($body)) {
             // Set the request body (probably a PUT type)
             $request->body($body);
         }
         if (isset($cookies)) {
             $request->cookie($cookies);
         }
     } else {
         $request = new HAPI_Request($uri, $client_params, $allow_external, $injected_routes);
     }
     return $request;
 }
Example #13
0
 public static function on_header_location(Request $request, Response $response, Request_Client $client)
 {
     if ($client->follow() and in_array($response->status(), array(201, 301, 302, 303, 307))) {
         switch ($response->status()) {
             default:
             case 301:
             case 307:
                 $follow_method = $request->method();
                 break;
             case 201:
             case 303:
                 $follow_method = Request::GET;
                 break;
             case 302:
                 if ($client->strict_redirect()) {
                     $follow_method = $request->method();
                 } else {
                     $follow_method = Request::GET;
                 }
                 break;
         }
         $orig_headers = $request->headers()->getArrayCopy();
         $follow_header_keys = array_intersect(array_keys($orig_headers), $client->follow_headers());
         $follow_headers = \Arr::extract($orig_headers, $follow_header_keys);
         $follow_request = Request::factory($response->headers("Location"))->method($follow_method)->headers($follow_headers);
         if ($follow_method !== Request::GET) {
             $follow_request->body($request->body());
         }
         return $follow_request;
     }
     return NULL;
 }
Example #14
0
 public function refreshAccessToken($refresh_token)
 {
     return $this->base->body(['grant_type' => 'refresh_token', 'refresh_token' => $refresh_token]);
 }
Example #15
0
 public static function factory($uri = TRUE, Cache $cache = NULL)
 {
     // If this is the initial request
     if (!Request::$initial) {
         if (Kohana::$is_cli) {
             // Default protocol for command line is cli://
             $protocol = 'cli';
             // Get the command line options
             $options = CLI::options('uri', 'method', 'get', 'post', 'referrer');
             if (isset($options['uri'])) {
                 // Use the specified URI
                 $uri = $options['uri'];
             }
             if (isset($options['method'])) {
                 // Use the specified method
                 $method = strtoupper($options['method']);
             } else {
                 $method = 'GET';
             }
             if (isset($options['get'])) {
                 // Overload the global GET data
                 parse_str($options['get'], $_GET);
             }
             if (isset($options['post'])) {
                 // Overload the global POST data
                 parse_str($options['post'], $_POST);
             }
             if (isset($options['referrer'])) {
                 $referrer = $options['referrer'];
             } else {
                 $referrer = NULL;
             }
         } else {
             if (isset($_SERVER['REQUEST_METHOD'])) {
                 // Use the server request method
                 $method = $_SERVER['REQUEST_METHOD'];
             } else {
                 // Default to GET
                 $method = Http_Request::GET;
             }
             if (!empty($_SERVER['HTTPS']) and filter_var($_SERVER['HTTPS'], FILTER_VALIDATE_BOOLEAN)) {
                 // This request is secure
                 $protocol = 'https';
             } else {
                 $protocol = 'http';
             }
             if (isset($_SERVER['HTTP_REFERER'])) {
                 // There is a referrer for this request
                 $referrer = $_SERVER['HTTP_REFERER'];
             } else {
                 $referrer = NULL;
             }
             if (isset($_SERVER['HTTP_USER_AGENT'])) {
                 // Set the client user agent
                 Request::$user_agent = $_SERVER['HTTP_USER_AGENT'];
             }
             if (isset($_SERVER['HTTP_X_REQUESTED_WITH'])) {
                 $requested_with = $_SERVER['HTTP_X_REQUESTED_WITH'];
             }
             if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
                 // Use the forwarded IP address, typically set when the
                 // client is using a proxy server.
                 Request::$client_ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
             } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
                 // Use the forwarded IP address, typically set when the
                 // client is using a proxy server.
                 Request::$client_ip = $_SERVER['HTTP_CLIENT_IP'];
             } elseif (isset($_SERVER['REMOTE_ADDR'])) {
                 // The remote IP address
                 Request::$client_ip = $_SERVER['REMOTE_ADDR'];
             }
             if ($method !== 'GET') {
                 // Ensure the raw body is saved for future use
                 $body = file_get_contents('php://input');
             }
             if ($uri === TRUE) {
                 $uri = Request::detect_uri();
             }
         }
         // Create the instance singleton
         $request = new Request($uri, $cache);
         $request->protocol($protocol)->method($method)->referrer($referrer);
         // Apply the requested with variable
         isset($requested_with) and $request->requested_with($requested_with);
         // If there is a body, set it to the model
         isset($body) and $request->body($body);
     } else {
         $request = new Request($uri, $cache);
     }
     // Create the initial request if it does not exist
     if (!Request::$initial) {
         Request::$initial = $request;
         $request->query($_GET)->post($_POST);
     }
     return $request;
 }
Example #16
0
 /**
  * Process the request
  * 
  * @throws lots of various exceptions
  */
 public static function process()
 {
     try {
         @session_start();
         // If undergoing maintenance report it as an error
         if (Config::get('maintenance')) {
             throw new RestUndergoingMaintenanceException();
         }
         // Split request path to get tokens
         $path = array();
         if (array_key_exists('PATH_INFO', $_SERVER)) {
             $path = array_filter(explode('/', $_SERVER['PATH_INFO']));
         }
         // Get method from possible headers
         $method = null;
         foreach (array('X_HTTP_METHOD_OVERRIDE', 'REQUEST_METHOD') as $k) {
             if (!array_key_exists($k, $_SERVER)) {
                 continue;
             }
             $method = strtolower($_SERVER[$k]);
         }
         // Record called method (for log), fail if unknown
         if (!in_array($method, array('get', 'post', 'put', 'delete'))) {
             throw new RestMethodNotAllowedException();
         }
         // Get endpoint (first token), fail if none
         $endpoint = array_shift($path);
         if (!$endpoint) {
             throw RestEndpointNotFound();
         }
         // Request data accessor
         self::$request = new RestRequest($method, $endpoint, $path);
         // Because php://input can only be read once for PUT requests we rely on a shared getter
         $input = Request::body();
         // Get request content type from possible headers
         $type = array_key_exists('CONTENT_TYPE', $_SERVER) ? $_SERVER['CONTENT_TYPE'] : null;
         if (!$type && array_key_exists('HTTP_CONTENT_TYPE', $_SERVER)) {
             $type = $_SERVER['HTTP_CONTENT_TYPE'];
         }
         // Parse content type
         $type_parts = array_map('trim', explode(';', $type));
         $type = array_shift($type_parts);
         self::$request->properties['type'] = $type;
         $type_properties = array();
         foreach ($type_parts as $part) {
             $part = array_map('trim', explode('=', $part));
             if (count($part) == 2) {
                 self::$request->properties[$part[0]] = $part[1];
             }
         }
         Logger::debug('Got "' . $method . '" request for endpoint "' . $endpoint . '/' . implode('/', $path) . '" with ' . strlen($input) . ' bytes payload');
         // Parse body
         switch ($type) {
             case 'text/plain':
                 self::$request->rawinput = trim(Utilities::sanitizeInput($input));
                 break;
             case 'application/octet-stream':
                 // Don't sanitize binary input !
                 self::$request->rawinput = $input;
                 break;
             case 'application/x-www-form-urlencoded':
                 $data = array();
                 parse_str($input, $data);
                 self::$request->input = (object) Utilities::sanitizeInput($data);
                 break;
             case 'application/json':
             default:
                 self::$request->input = json_decode(trim(Utilities::sanitizeInput($input)));
         }
         // Get authentication state (fills auth data in relevant classes)
         Auth::isAuthenticated();
         if (Auth::isRemoteApplication()) {
             // Remote applications must honor ACLs
             $application = AuthRemote::application();
             if (!$application->allowedTo($method, $endpoint)) {
                 throw new RestNotAllowedException();
             }
         } else {
             if (Auth::isRemoteUser()) {
                 // Nothing peculiar to do
             } else {
                 if (in_array($method, array('post', 'put', 'delete'))) {
                     // SP or Guest, lets do XSRF check
                     $token_name = 'HTTP_X_SECURITY_TOKEN';
                     $token = array_key_exists($token_name, $_SERVER) ? $_SERVER[$token_name] : '';
                     if ($method == 'post' && array_key_exists('security-token', $_POST)) {
                         $token = $_POST['security-token'];
                     }
                     if (!$token || !Utilities::checkSecurityToken($token)) {
                         throw new RestXSRFTokenInvalidException($token);
                     }
                 }
             }
         }
         // JSONP specifics
         if (array_key_exists('callback', $_GET) && $method != 'get') {
             throw new RestJSONPonlyGETException();
         }
         // Get response filters
         foreach ($_GET as $k => $v) {
             switch ($k) {
                 case 'count':
                 case 'startIndex':
                     if (preg_match('`^[0-9]+$`', $v)) {
                         self::$request->{$k} = (int) $v;
                     }
                     break;
                 case 'format':
                     break;
                 case 'filterOp':
                     if (is_array($v)) {
                         foreach ($v as $p => $f) {
                             self::$request->filterOp[$p] = array();
                             foreach (array('equals', 'startWith', 'contains', 'present') as $k) {
                                 if (array_key_exists($k, $f)) {
                                     self::$request->filterOp[$p][$k] = $f[$k];
                                 }
                             }
                         }
                     }
                     break;
                 case 'sortOrder':
                     if (in_array($v, array('ascending', 'descending'))) {
                         self::$request->sortOrder = $v;
                     }
                     break;
                 case 'updatedSince':
                     // updatedSince takes ISO date, relative N days|weeks|months|years format and epoch timestamp (UTC)
                     $updatedSince = null;
                     if (preg_match('`^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(Z|[+-][0-9]{2}:[0-9]{2})$`', $v)) {
                         // ISO date
                         $localetz = new DateTimeZone(Config::get('default_timezone'));
                         $offset = $localetz->getOffset(new DateTime($v));
                         $updatedSince = strtotime($v) + $offset;
                     } else {
                         if (preg_match('`^([0-9]+)\\s*(hour|day|week|month|year)s?$`', $v, $m)) {
                             // Relative N day|days|week|weeks|month|months|year|years format
                             $updatedSince = strtotime('-' . $m[1] . ' ' . $m[2]);
                         } else {
                             if (preg_match('`^[0-9]+$`', $v)) {
                                 $updatedSince = (int) $v;
                             }
                         }
                     }
                     // Epoch timestamp
                     if (!$updatedSince || !is_numeric($updatedSince)) {
                         throw new RestUpdatedSinceBadFormatException($updatedSince);
                     }
                     self::$request->updatedSince = $updatedSince;
                     break;
             }
         }
         $event = new Event('rest_request', self::$request);
         $data = $event->trigger(function () {
             $request = RestServer::getRequest();
             // Forward to handler, fail if unknown or method not implemented
             $class = ucfirst($request->endpoint) . 'Endpoint';
             if (!file_exists(APPLICATION_BASE . '/classes/endpoints/' . $class . '.class.php') && !file_exists(APPLICATION_BASE . '/classes/core/endpoints/' . $class . '.class.php')) {
                 throw new RestEndpointNotFoundException();
             }
             if (!method_exists($class, $request->method)) {
                 throw new RestMethodNotImplementedException();
             }
             Logger::debug('Forwarding call to ' . $class . '::' . $request->method . '() handler');
             return call_user_func_array($class . '::' . $request->method, $request->path);
         });
         Logger::debug('Got data to send back');
         // Output data
         if (array_key_exists('callback', $_GET)) {
             header('Content-Type: text/javascript');
             $callback = preg_replace('`[^a-z0-9_\\.-]`i', '', $_GET['callback']);
             echo $callback . '(' . json_encode($data) . ');';
             exit;
         }
         if (array_key_exists('iframe_callback', $_GET)) {
             header('Content-Type: text/html');
             $callback = preg_replace('`[^a-z0-9_\\.-]`i', '', $_GET['iframe_callback']);
             echo '<html><body><script type="text/javascript">window.parent.' . $callback . '(' . json_encode($data) . ');</script></body></html>';
             exit;
         }
         header('Content-Type: application/json');
         if ($method == 'post' && $data) {
             RestUtilities::sendResponseCode(201);
             if (substr($data['path'], 0, 1) != '/') {
                 $data['path'] = '/' . $data['path'];
             }
             header('Location: ' . Config::get('application_url') . 'rest.php' . $data['path']);
             $data = $data['data'];
         }
         echo json_encode($data);
     } catch (Exception $e) {
         // Return exceptions as HTTP errors
         $code = $e->getCode();
         if ($code < 400 || $code >= 600) {
             $code = 500;
         }
         RestUtilities::sendResponseCode($code);
         header('Content-Type: application/json');
         echo json_encode(array('message' => $e->getMessage(), 'uid' => method_exists($e, 'getUid') ? $e->getUid() : null, 'details' => method_exists($e, 'getDetails') ? $e->getDetails() : null));
     }
 }