View source
<?php
require_once dirname(__FILE__) . '/OAuthRequestSigner.php';
require_once dirname(__FILE__) . '/body/OAuthBodyContentDisposition.php';
class OAuthRequester extends OAuthRequestSigner {
protected $files;
function __construct($request, $method = null, $params = null, $body = null, $files = null) {
parent::__construct($request, $method, $params, $body);
if (!empty($files)) {
$empty = true;
foreach ($files as $f) {
$empty = $empty && empty($f['file']) && !isset($f['data']);
}
if (!$empty) {
if (!is_null($body)) {
throw new OAuthException2('When sending files, you can\'t send a body as well.');
}
$this->files = $files;
}
}
}
function doRequest($usr_id = 0, $curl_options = array(), $options = array()) {
$name = isset($options['name']) ? $options['name'] : '';
if (isset($options['token_ttl'])) {
$this
->setParam('xoauth_token_ttl', intval($options['token_ttl']));
}
if (!empty($this->files)) {
list($extra_headers, $body) = OAuthBodyContentDisposition::encodeBody($this->files);
$this
->setBody($body);
$curl_options = $this
->prepareCurlOptions($curl_options, $extra_headers);
}
$this
->sign($usr_id, null, $name);
$text = $this
->curl_raw($curl_options);
$result = $this
->curl_parse($text);
if ($result['code'] >= 400) {
throw new OAuthException2('Request failed with code ' . $result['code'] . ': ' . $result['body']);
}
$token_ttl = $this
->getParam('xoauth_token_ttl', false);
if (is_numeric($token_ttl)) {
$this->store
->setServerTokenTtl($this
->getParam('oauth_consumer_key', true), $this
->getParam('oauth_token', true), $token_ttl);
}
return $result;
}
static function requestRequestToken($consumer_key, $usr_id, $params = null, $method = 'POST', $options = array(), $curl_options = array()) {
OAuthRequestLogger::start();
if (isset($options['token_ttl']) && is_numeric($options['token_ttl'])) {
$params['xoauth_token_ttl'] = intval($options['token_ttl']);
}
$store = OAuthStore::instance();
$r = $store
->getServer($consumer_key, $usr_id);
$uri = $r['request_token_uri'];
$oauth = new OAuthRequester($uri, $method, $params);
$oauth
->sign($usr_id, $r, '', 'requestToken');
$text = $oauth
->curl_raw($curl_options);
if (empty($text)) {
throw new OAuthException2('No answer from the server "' . $uri . '" while requesting a request token');
}
$data = $oauth
->curl_parse($text);
if ($data['code'] != 200) {
throw new OAuthException2('Unexpected result from the server "' . $uri . '" (' . $data['code'] . ') while requesting a request token');
}
$token = array();
$params = explode('&', $data['body']);
foreach ($params as $p) {
@(list($name, $value) = explode('=', $p, 2));
$token[$name] = $oauth
->urldecode($value);
}
if (!empty($token['oauth_token']) && !empty($token['oauth_token_secret'])) {
$opts = array();
if (isset($options['name'])) {
$opts['name'] = $options['name'];
}
if (isset($token['xoauth_token_ttl'])) {
$opts['token_ttl'] = $token['xoauth_token_ttl'];
}
$store
->addServerToken($consumer_key, 'request', $token['oauth_token'], $token['oauth_token_secret'], $usr_id, $opts);
}
else {
throw new OAuthException2('The server "' . $uri . '" did not return the oauth_token or the oauth_token_secret');
}
OAuthRequestLogger::flush();
return array(
'authorize_uri' => $r['authorize_uri'],
'token' => $token['oauth_token'],
);
}
static function requestAccessToken($consumer_key, $token, $usr_id, $method = 'POST', $options = array(), $curl_options = array()) {
OAuthRequestLogger::start();
$store = OAuthStore::instance();
$r = $store
->getServerTokenSecrets($consumer_key, $token, 'request', $usr_id);
$uri = $r['access_token_uri'];
$token_name = $r['token_name'];
$store
->deleteServerToken($consumer_key, $r['token'], 0, true);
$oauth = new OAuthRequester($uri, $method);
if (isset($options['oauth_verifier'])) {
$oauth
->setParam('oauth_verifier', $options['oauth_verifier']);
}
if (isset($options['token_ttl']) && is_numeric($options['token_ttl'])) {
$oauth
->setParam('xoauth_token_ttl', intval($options['token_ttl']));
}
OAuthRequestLogger::setRequestObject($oauth);
$oauth
->sign($usr_id, $r, '', 'accessToken');
$text = $oauth
->curl_raw($curl_options);
if (empty($text)) {
throw new OAuthException2('No answer from the server "' . $uri . '" while requesting an access token');
}
$data = $oauth
->curl_parse($text);
if ($data['code'] != 200) {
throw new OAuthException2('Unexpected result from the server "' . $uri . '" (' . $data['code'] . ') while requesting an access token');
}
$token = array();
$params = explode('&', $data['body']);
foreach ($params as $p) {
@(list($name, $value) = explode('=', $p, 2));
$token[$oauth
->urldecode($name)] = $oauth
->urldecode($value);
}
if (!empty($token['oauth_token']) && !empty($token['oauth_token_secret'])) {
$opts = array();
$opts['name'] = $token_name;
if (isset($token['xoauth_token_ttl'])) {
$opts['token_ttl'] = $token['xoauth_token_ttl'];
}
$store
->addServerToken($consumer_key, 'access', $token['oauth_token'], $token['oauth_token_secret'], $usr_id, $opts);
}
else {
throw new OAuthException2('The server "' . $uri . '" did not return the oauth_token or the oauth_token_secret');
}
OAuthRequestLogger::flush();
}
protected function curl_raw($opts = array()) {
if (isset($opts[CURLOPT_HTTPHEADER])) {
$header = $opts[CURLOPT_HTTPHEADER];
}
else {
$header = array();
}
$ch = curl_init();
$method = $this
->getMethod();
$url = $this
->getRequestUrl();
$header[] = $this
->getAuthorizationHeader();
$query = $this
->getQueryString();
$body = $this
->getBody();
$has_content_type = false;
foreach ($header as $h) {
if (strncasecmp($h, 'Content-Type:', 13) == 0) {
$has_content_type = true;
}
}
if (!is_null($body)) {
if ($method == 'TRACE') {
throw new OAuthException2('A body can not be sent with a TRACE operation');
}
if (!empty($query)) {
$url .= '?' . $query;
}
if (!$has_content_type) {
$header[] = 'Content-Type: application/octet-stream';
$has_content_type = true;
}
if ($method == 'PUT') {
$put_file = @tmpfile();
if (!$put_file) {
throw new OAuthException2('Could not create tmpfile for PUT operation');
}
fwrite($put_file, $body);
fseek($put_file, 0);
curl_setopt($ch, CURLOPT_PUT, true);
curl_setopt($ch, CURLOPT_INFILE, $put_file);
curl_setopt($ch, CURLOPT_INFILESIZE, strlen($body));
}
else {
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
}
}
else {
if ($method == 'POST') {
if (!$has_content_type) {
$header[] = 'Content-Type: application/x-www-form-urlencoded';
$has_content_type = true;
}
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $query);
}
else {
if (!empty($query)) {
$url .= '?' . $query;
}
if ($method != 'GET') {
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
}
}
}
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_USERAGENT, 'anyMeta/OAuth 1.0 - ($LastChangedRevision: 174 $)');
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 90);
foreach ($opts as $k => $v) {
if ($k != CURLOPT_HTTPHEADER) {
curl_setopt($ch, $k, $v);
}
}
$txt = curl_exec($ch);
if ($txt === false) {
$error = curl_error($ch);
curl_close($ch);
throw new OAuthException2('CURL error: ' . $error);
}
curl_close($ch);
if (!empty($put_file)) {
fclose($put_file);
}
$data = $method . " {$url}\n" . implode("\n", $header);
if (is_string($body)) {
$data .= "\n\n" . $body;
}
else {
if ($method == 'POST') {
$data .= "\n\n" . $query;
}
}
OAuthRequestLogger::setSent($data, $body);
OAuthRequestLogger::setReceived($txt);
return $txt;
}
protected function curl_parse($response) {
if (empty($response)) {
return array();
}
@(list($headers, $body) = explode("\r\n\r\n", $response, 2));
$lines = explode("\r\n", $headers);
if (preg_match('@^HTTP/[0-9]\\.[0-9] +100@', $lines[0])) {
@(list($headers, $body) = explode("\r\n\r\n", $body, 2));
$lines = explode("\r\n", $headers);
}
$http_line = array_shift($lines);
if (preg_match('@^HTTP/[0-9]\\.[0-9] +([0-9]{3})@', $http_line, $matches)) {
$code = $matches[1];
}
$headers = array();
foreach ($lines as $l) {
list($k, $v) = explode(': ', $l, 2);
$headers[strtolower($k)] = $v;
}
return array(
'code' => $code,
'headers' => $headers,
'body' => $body,
);
}
protected function prepareCurlOptions($curl_options, $extra_headers) {
$hs = array();
if (!empty($curl_options[CURLOPT_HTTPHEADER]) && is_array($curl_options[CURLOPT_HTTPHEADER])) {
foreach ($curl_options[CURLOPT_HTTPHEADER] as $h) {
list($opt, $val) = explode(':', $h, 2);
$opt = str_replace(' ', '-', ucwords(str_replace('-', ' ', $opt)));
$hs[$opt] = $val;
}
}
$curl_options[CURLOPT_HTTPHEADER] = array();
$hs = array_merge($hs, $extra_headers);
foreach ($hs as $h => $v) {
$curl_options[CURLOPT_HTTPHEADER][] = "{$h}: {$v}";
}
return $curl_options;
}
}