krz/vox-populi
A Tumblr web client.
clone: git clone https://gitbay.org/krz/vox-populi.git
main: vendor/eher/oauth/src/Eher/OAuth/Request.php · raw
1<?php
2
3namespace Eher\OAuth;
4
5class Request {
6 protected $parameters;
7 protected $http_method;
8 protected $http_url;
9 // for debug purposes
10 public $base_string;
11 public static $version = '1.0';
12 public static $POST_INPUT = 'php://input';
13
14 function __construct($http_method, $http_url, $parameters=NULL) {
15 $parameters = ($parameters) ? $parameters : array();
16 $parameters = array_merge( Util::parse_parameters(parse_url($http_url, PHP_URL_QUERY)), $parameters);
17 $this->parameters = $parameters;
18 $this->http_method = $http_method;
19 $this->http_url = $http_url;
20 }
21
22
23 /**
24 * attempt to build up a request from what was passed to the server
25 */
26 public static function from_request($http_method=NULL, $http_url=NULL, $parameters=NULL) {
27 $scheme = (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != "on")
28 ? 'http'
29 : 'https';
30 $http_url = ($http_url) ? $http_url : $scheme .
31 '://' . $_SERVER['HTTP_HOST'] .
32 ':' .
33 $_SERVER['SERVER_PORT'] .
34 $_SERVER['REQUEST_URI'];
35 $http_method = ($http_method) ? $http_method : $_SERVER['REQUEST_METHOD'];
36
37 // We weren't handed any parameters, so let's find the ones relevant to
38 // this request.
39 // If you run XML-RPC or similar you should use this to provide your own
40 // parsed parameter-list
41 if (!$parameters) {
42 // Find request headers
43 $request_headers = Util::get_headers();
44
45 // Parse the query-string to find GET parameters
46 $parameters = Util::parse_parameters($_SERVER['QUERY_STRING']);
47
48 // It's a POST request of the proper content-type, so parse POST
49 // parameters and add those overriding any duplicates from GET
50 if ($http_method == "POST"
51 && isset($request_headers['Content-Type'])
52 && strstr($request_headers['Content-Type'],
53 'application/x-www-form-urlencoded')
54 ) {
55 $post_data = Util::parse_parameters(
56 file_get_contents(self::$POST_INPUT)
57 );
58 $parameters = array_merge($parameters, $post_data);
59 }
60
61 // We have a Authorization-header with OAuth data. Parse the header
62 // and add those overriding any duplicates from GET or POST
63 if (isset($request_headers['Authorization']) && substr($request_headers['Authorization'], 0, 6) == 'OAuth ') {
64 $header_parameters = Util::split_header(
65 $request_headers['Authorization']
66 );
67 $parameters = array_merge($parameters, $header_parameters);
68 }
69
70 }
71
72 return new Request($http_method, $http_url, $parameters);
73 }
74
75 /**
76 * pretty much a helper function to set up the request
77 */
78 public static function from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters=NULL) {
79 $parameters = ($parameters) ? $parameters : array();
80 $defaults = array("oauth_version" => Request::$version,
81 "oauth_nonce" => Request::generate_nonce(),
82 "oauth_timestamp" => Request::generate_timestamp(),
83 "oauth_consumer_key" => $consumer->key);
84 if ($token)
85 $defaults['oauth_token'] = $token->key;
86
87 $parameters = array_merge($defaults, $parameters);
88
89 return new Request($http_method, $http_url, $parameters);
90 }
91
92 public function set_parameter($name, $value, $allow_duplicates = true) {
93 if ($allow_duplicates && isset($this->parameters[$name])) {
94 // We have already added parameter(s) with this name, so add to the list
95 if (is_scalar($this->parameters[$name])) {
96 // This is the first duplicate, so transform scalar (string)
97 // into an array so we can add the duplicates
98 $this->parameters[$name] = array($this->parameters[$name]);
99 }
100
101 $this->parameters[$name][] = $value;
102 } else {
103 $this->parameters[$name] = $value;
104 }
105 }
106
107 public function get_parameter($name) {
108 return isset($this->parameters[$name]) ? $this->parameters[$name] : null;
109 }
110
111 public function get_parameters() {
112 return $this->parameters;
113 }
114
115 public function unset_parameter($name) {
116 unset($this->parameters[$name]);
117 }
118
119 /**
120 * The request parameters, sorted and concatenated into a normalized string.
121 * @return string
122 */
123 public function get_signable_parameters() {
124 // Grab all parameters
125 $params = $this->parameters;
126
127 // Remove oauth_signature if present
128 // Ref: Spec: 9.1.1 ("The oauth_signature parameter MUST be excluded.")
129 if (isset($params['oauth_signature'])) {
130 unset($params['oauth_signature']);
131 }
132
133 return Util::build_http_query($params);
134 }
135
136 /**
137 * Returns the base string of this request
138 *
139 * The base string defined as the method, the url
140 * and the parameters (normalized), each urlencoded
141 * and the concated with &.
142 */
143 public function get_signature_base_string() {
144 $parts = array(
145 $this->get_normalized_http_method(),
146 $this->get_normalized_http_url(),
147 $this->get_signable_parameters()
148 );
149
150 $parts = Util::urlencode_rfc3986($parts);
151
152 return implode('&', $parts);
153 }
154
155 /**
156 * just uppercases the http method
157 */
158 public function get_normalized_http_method() {
159 return strtoupper($this->http_method);
160 }
161
162 /**
163 * parses the url and rebuilds it to be
164 * scheme://host/path
165 */
166 public function get_normalized_http_url() {
167 $parts = parse_url($this->http_url);
168
169 $scheme = (isset($parts['scheme'])) ? $parts['scheme'] : 'http';
170 $port = (isset($parts['port'])) ? $parts['port'] : (($scheme == 'https') ? '443' : '80');
171 $host = (isset($parts['host'])) ? $parts['host'] : '';
172 $path = (isset($parts['path'])) ? $parts['path'] : '';
173
174 if (($scheme == 'https' && $port != '443')
175 || ($scheme == 'http' && $port != '80')) {
176 $host = "$host:$port";
177 }
178 return "$scheme://$host$path";
179 }
180
181 /**
182 * builds a url usable for a GET request
183 */
184 public function to_url() {
185 $post_data = $this->to_postdata();
186 $out = $this->get_normalized_http_url();
187 if ($post_data) {
188 $out .= '?'.$post_data;
189 }
190 return $out;
191 }
192
193 /**
194 * builds the data one would send in a POST request
195 */
196 public function to_postdata() {
197 return Util::build_http_query($this->parameters);
198 }
199
200 /**
201 * builds the Authorization: header
202 */
203 public function to_header($realm=null) {
204 $first = true;
205 if($realm) {
206 $out = 'Authorization: OAuth realm="' . Util::urlencode_rfc3986($realm) . '"';
207 $first = false;
208 } else
209 $out = 'Authorization: OAuth';
210
211 $total = array();
212 foreach ($this->parameters as $k => $v) {
213 if (substr($k, 0, 5) != "oauth") continue;
214 if (is_array($v)) {
215 throw new OAuthException('Arrays not supported in headers');
216 }
217 $out .= ($first) ? ' ' : ',';
218 $out .= Util::urlencode_rfc3986($k) .
219 '="' .
220 Util::urlencode_rfc3986($v) .
221 '"';
222 $first = false;
223 }
224 return $out;
225 }
226
227 public function __toString() {
228 return $this->to_url();
229 }
230
231
232 public function sign_request($signature_method, $consumer, $token) {
233 $this->set_parameter(
234 "oauth_signature_method",
235 $signature_method->get_name(),
236 false
237 );
238 $signature = $this->build_signature($signature_method, $consumer, $token);
239 $this->set_parameter("oauth_signature", $signature, false);
240 }
241
242 public function build_signature($signature_method, $consumer, $token) {
243 $signature = $signature_method->build_signature($this, $consumer, $token);
244 return $signature;
245 }
246
247 /**
248 * util function: current timestamp
249 */
250 private static function generate_timestamp() {
251 return time();
252 }
253
254 /**
255 * util function: current nonce
256 */
257 private static function generate_nonce() {
258 $mt = microtime();
259 $rand = mt_rand();
260
261 return md5($mt . $rand); // md5s look nicer than numbers
262 }
263}
264