You are here

class OAuthRequest in OAuth 1.0 6

Same name and namespace in other branches
  1. 6.3 lib/OAuth.php \OAuthRequest
  2. 7.3 lib/OAuth.php \OAuthRequest

Hierarchy

Expanded class hierarchy of OAuthRequest

File

./OAuth.php, line 163

View source
class OAuthRequest {

  /*{{{*/
  private $parameters;
  private $http_method;
  private $http_url;

  // for debug purposes
  public $base_string;
  public static $version = '1.0';
  function __construct($http_method, $http_url, $parameters = NULL) {

    /*{{{*/
    @$parameters or $parameters = array();
    $this->parameters = $parameters;
    $this->http_method = $http_method;
    $this->http_url = $http_url;
  }

  /*}}}*/

  /**
   * attempt to build up a request from what was passed to the server
   */
  public static function from_request($http_method = NULL, $http_url = NULL, $parameters = NULL) {

    /*{{{*/
    $scheme = !isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != "on" ? 'http' : 'https';
    @$http_url or $http_url = $scheme . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
    @$http_method or $http_method = $_SERVER['REQUEST_METHOD'];
    $request_headers = OAuthRequest::get_headers();

    // let the library user override things however they'd like, if they know
    // which parameters to use then go for it, for example XMLRPC might want to
    // do this
    if ($parameters) {
      $req = new OAuthRequest($http_method, $http_url, $parameters);
    }
    else {
      if (@substr($request_headers['Authorization'], 0, 5) == "OAuth") {
        $header_parameters = OAuthRequest::split_header($request_headers['Authorization']);
        if ($http_method == "GET") {
          $req_parameters = $_GET;
        }
        else {
          if ($http_method = "POST") {
            $req_parameters = $_POST;
          }
        }
        $parameters = array_merge($header_parameters, $req_parameters);
        $req = new OAuthRequest($http_method, $http_url, $parameters);
      }
      else {
        if ($http_method == "GET") {
          $req = new OAuthRequest($http_method, $http_url, $_GET);
        }
        else {
          if ($http_method == "POST") {
            $req = new OAuthRequest($http_method, $http_url, $_POST);
          }
        }
      }
    }
    return $req;
  }

  /*}}}*/

  /**
   * pretty much a helper function to set up the request
   */
  public static function from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters = NULL) {

    /*{{{*/
    @$parameters or $parameters = array();
    $defaults = array(
      "oauth_version" => OAuthRequest::$version,
      "oauth_nonce" => OAuthRequest::generate_nonce(),
      "oauth_timestamp" => OAuthRequest::generate_timestamp(),
      "oauth_consumer_key" => $consumer->key,
    );
    $parameters = array_merge($defaults, $parameters);
    if ($token) {
      $parameters['oauth_token'] = $token->key;
    }
    return new OAuthRequest($http_method, $http_url, $parameters);
  }

  /*}}}*/
  public function set_parameter($name, $value) {

    /*{{{*/
    $this->parameters[$name] = $value;
  }

  /*}}}*/
  public function get_parameter($name) {

    /*{{{*/
    return $this->parameters[$name];
  }

  /*}}}*/
  public function get_parameters() {

    /*{{{*/
    return $this->parameters;
  }

  /*}}}*/

  /**
   * Returns the normalized parameters of the request
   *
   * This will be all (except oauth_signature) parameters,
   * sorted first by key, and if duplicate keys, then by
   * value.
   *
   * The returned string will be all the key=value pairs
   * concated by &.
   *
   * @return string
   */
  public function get_signable_parameters() {

    /*{{{*/

    // Grab all parameters
    $params = $this->parameters;

    // Remove oauth_signature if present
    if (isset($params['oauth_signature'])) {
      unset($params['oauth_signature']);
    }

    // Urlencode both keys and values
    $keys = array_map(array(
      'OAuthUtil',
      'urlencodeRFC3986',
    ), array_keys($params));
    $values = array_map(array(
      'OAuthUtil',
      'urlencodeRFC3986',
    ), array_values($params));
    $params = array_combine($keys, $values);

    // Sort by keys (natsort)
    uksort($params, 'strnatcmp');

    // Generate key=value pairs
    $pairs = array();
    foreach ($params as $key => $value) {
      if (is_array($value)) {

        // If the value is an array, it's because there are multiple
        // with the same key, sort them, then add all the pairs
        natsort($value);
        foreach ($value as $v2) {
          $pairs[] = $key . '=' . $v2;
        }
      }
      else {
        $pairs[] = $key . '=' . $value;
      }
    }

    // Return the pairs, concated with &
    return implode('&', $pairs);
  }

  /*}}}*/

  /**
   * Returns the base string of this request
   *
   * The base string defined as the method, the url
   * and the parameters (normalized), each urlencoded
   * and the concated with &.
   */
  public function get_signature_base_string() {

    /*{{{*/
    $parts = array(
      $this
        ->get_normalized_http_method(),
      $this
        ->get_normalized_http_url(),
      $this
        ->get_signable_parameters(),
    );
    $parts = array_map(array(
      'OAuthUtil',
      'urlencodeRFC3986',
    ), $parts);
    return implode('&', $parts);
  }

  /*}}}*/

  /**
   * just uppercases the http method
   */
  public function get_normalized_http_method() {

    /*{{{*/
    return strtoupper($this->http_method);
  }

  /*}}}*/

  /**
   * parses the url and rebuilds it to be
   * scheme://host/path
   */
  public function get_normalized_http_url() {

    /*{{{*/
    $parts = parse_url($this->http_url);

    // FIXME: port should handle according to http://groups.google.com/group/oauth/browse_thread/thread/1b203a51d9590226
    $port = isset($parts['port']) && $parts['port'] != '80' ? ':' . $parts['port'] : '';
    $path = isset($parts['path']) ? $parts['path'] : '';
    return $parts['scheme'] . '://' . $parts['host'] . $port . $path;
  }

  /*}}}*/

  /**
   * builds a url usable for a GET request
   */
  public function to_url() {

    /*{{{*/
    $out = $this
      ->get_normalized_http_url() . "?";
    $out .= $this
      ->to_postdata();
    return $out;
  }

  /*}}}*/

  /**
   * builds the data one would send in a POST request
   */
  public function to_postdata() {

    /*{{{*/
    $total = array();
    foreach ($this->parameters as $k => $v) {
      $total[] = OAuthUtil::urlencodeRFC3986($k) . "=" . OAuthUtil::urlencodeRFC3986($v);
    }
    $out = implode("&", $total);
    return $out;
  }

  /*}}}*/

  /**
   * builds the Authorization: header
   */
  public function to_header() {

    /*{{{*/
    $out = '"Authorization: OAuth realm="",';
    $total = array();
    foreach ($this->parameters as $k => $v) {
      if (substr($k, 0, 5) != "oauth") {
        continue;
      }
      $out .= ',' . OAuthUtil::urlencodeRFC3986($k) . '="' . OAuthUtil::urlencodeRFC3986($v) . '"';
    }
    return $out;
  }

  /*}}}*/
  public function __toString() {

    /*{{{*/
    return $this
      ->to_url();
  }

  /*}}}*/
  public function sign_request($signature_method, $consumer, $token) {

    /*{{{*/
    $this
      ->set_parameter("oauth_signature_method", $signature_method
      ->get_name());
    $signature = $this
      ->build_signature($signature_method, $consumer, $token);
    $this
      ->set_parameter("oauth_signature", $signature);
  }

  /*}}}*/
  public function build_signature($signature_method, $consumer, $token) {

    /*{{{*/
    $signature = $signature_method
      ->build_signature($this, $consumer, $token);
    return $signature;
  }

  /*}}}*/

  /**
   * util function: current timestamp
   */
  private static function generate_timestamp() {

    /*{{{*/
    return time();
  }

  /*}}}*/

  /**
   * util function: current nonce
   */
  private static function generate_nonce() {

    /*{{{*/
    $mt = microtime();
    $rand = mt_rand();
    return md5($mt . $rand);

    // md5s look nicer than numbers
  }

  /*}}}*/

  /**
   * util function for turning the Authorization: header into
   * parameters, has to do some unescaping
   */
  private static function split_header($header) {

    /*{{{*/

    // this should be a regex
    // error cases: commas in parameter values
    $parts = explode(",", $header);
    $out = array();
    foreach ($parts as $param) {
      $param = ltrim($param);

      // skip the "realm" param, nobody ever uses it anyway
      if (substr($param, 0, 5) != "oauth") {
        continue;
      }
      $param_parts = explode("=", $param);

      // rawurldecode() used because urldecode() will turn a "+" in the
      // value into a space
      $out[$param_parts[0]] = rawurldecode(substr($param_parts[1], 1, -1));
    }
    return $out;
  }

  /*}}}*/

  /**
   * helper to try to sort out headers for people who aren't running apache
   */
  private static function get_headers() {

    /*{{{*/
    if (function_exists('apache_request_headers')) {

      // we need this to get the actual Authorization: header
      // because apache tends to tell us it doesn't exist
      return apache_request_headers();
    }

    // otherwise we don't have apache and are just going to have to hope
    // that $_SERVER actually contains what we need
    $out = array();
    foreach ($_SERVER as $key => $value) {
      if (substr($key, 0, 5) == "HTTP_") {

        // this is chaos, basically it is just there to capitalize the first
        // letter of every word that is not an initial HTTP and strip HTTP
        // code from przemek
        $key = str_replace(" ", "-", ucwords(strtolower(str_replace("_", " ", substr($key, 5)))));
        $out[$key] = $value;
      }
    }
    return $out;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
OAuthRequest::$base_string public property
OAuthRequest::$http_method private property
OAuthRequest::$http_url private property
OAuthRequest::$parameters private property
OAuthRequest::$version public static property
OAuthRequest::build_signature public function
OAuthRequest::from_consumer_and_token public static function pretty much a helper function to set up the request
OAuthRequest::from_request public static function attempt to build up a request from what was passed to the server
OAuthRequest::generate_nonce private static function util function: current nonce
OAuthRequest::generate_timestamp private static function util function: current timestamp
OAuthRequest::get_headers private static function helper to try to sort out headers for people who aren't running apache
OAuthRequest::get_normalized_http_method public function just uppercases the http method
OAuthRequest::get_normalized_http_url public function parses the url and rebuilds it to be scheme://host/path
OAuthRequest::get_parameter public function
OAuthRequest::get_parameters public function
OAuthRequest::get_signable_parameters public function Returns the normalized parameters of the request
OAuthRequest::get_signature_base_string public function Returns the base string of this request
OAuthRequest::set_parameter public function
OAuthRequest::sign_request public function
OAuthRequest::split_header private static function util function for turning the Authorization: header into parameters, has to do some unescaping
OAuthRequest::to_header public function builds the Authorization: header
OAuthRequest::to_postdata public function builds the data one would send in a POST request
OAuthRequest::to_url public function builds a url usable for a GET request
OAuthRequest::__construct function
OAuthRequest::__toString public function