Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle PUT data #11

Open
wants to merge 32 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
a222395
Request #18431 Improvements in handling PUT requests
CloCkWeRX Jan 25, 2012
e58502c
Decode parameter names as well as values in provider.
gauthierm Oct 22, 2013
27862cd
Merge pull request #1 from gauthierm/fix-parameter-encoding
gauthierm Oct 31, 2013
21ecb5c
Clean up handling of PUT data.
gauthierm Oct 31, 2013
ed3ab7f
Merge pull request #2 from gauthierm/bug-20106-fix-put-handling
gauthierm Oct 31, 2013
0438cad
Update HTTP_OAuth to work with array query params.
gauthierm Oct 31, 2013
d327ba6
Fix class name capitalization.
gauthierm Nov 1, 2013
fd815ca
Make getBody() public.
gauthierm Nov 1, 2013
ccda182
Update tests to test set/getBody and array param parsing.
gauthierm Nov 1, 2013
415ff14
Merge pull request #3 from gauthierm/bug-20107-add-array-params
gauthierm Nov 1, 2013
fe2448e
Use exception chaining if PHP 5.3 is available.
gauthierm Nov 1, 2013
81abd6e
Merge pull request #4 from gauthierm/bug-18574-exception-chaining
gauthierm Nov 1, 2013
03beb9b
Handle HTTP request body params better.
gauthierm Nov 1, 2013
93cd238
Merge pull request #5 from gauthierm/bug-17806-delete-method
gauthierm Nov 1, 2013
a2dc3a3
Prepare for release of 0.3.0.
gauthierm Nov 1, 2013
f571f79
Add LICENSE file.
gauthierm Nov 5, 2013
86aa886
Merge pull request #6 from gauthierm/add-license-file
gauthierm Nov 5, 2013
e6d0ab3
Cleanup package.xml generator.
gauthierm Nov 5, 2013
70e23cd
Merge pull request #7 from gauthierm/cleanup-package-generator
gauthierm Nov 5, 2013
f91388c
Fix E_STRICT in MessageTest.
gauthierm Nov 5, 2013
f822723
Merge pull request #8 from gauthierm/fix-message-test
gauthierm Nov 5, 2013
5af91b3
Prepare release 0.3.1.
gauthierm Nov 5, 2013
12fab68
Fix parsing of Authorization header values.
gauthierm Oct 14, 2014
f26549f
Merge pull request #9 from gauthierm/fix-auth-header-parsing
saltybeagle Oct 17, 2014
774b938
Travis, modern PHPUnit
CloCkWeRX Oct 23, 2014
d8b751e
Install everything
CloCkWeRX Oct 23, 2014
93c8366
Add composer support.
gauthierm Jan 6, 2016
b5a7c5f
Merge pull request #10 from gauthierm/composer
gauthierm Jan 6, 2016
8e7beea
Fix README design
hypermkt Mar 5, 2018
cd2809a
Fixed the file name to enable Markdown
hypermkt Mar 5, 2018
dc31db8
Wrap by code block
hypermkt Mar 5, 2018
93b0637
Merge pull request #11 from hypermkt/fix-readme
CloCkWeRX Jun 7, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
language: php
install:
- pear install -fa package.xml
php:
- 5.4
script: phpunit tests/
15 changes: 9 additions & 6 deletions HTTP/OAuth.php
Original file line number Diff line number Diff line change
Expand Up @@ -142,15 +142,18 @@ static public function buildHttpQuery(array $params)
return '';
}

$keys = self::urlencode(array_keys($params));
$values = self::urlencode(array_values($params));
$params = array_combine($keys, $values);

uksort($params, 'strcmp');
ksort($params, SORT_STRING);

$pairs = array();
foreach ($params as $key => $value) {
$pairs[] = $key . '=' . $value;
if (is_array($value)) {
sort($value, SORT_STRING);
foreach ($value as $multiValue) {
$pairs[] = self::urlencode($key) . '=' . self::urlencode($multiValue);
}
} else {
$pairs[] = self::urlencode($key) . '=' . self::urlencode($value);
}
}

return implode('&', $pairs);
Expand Down
17 changes: 13 additions & 4 deletions HTTP/OAuth/Consumer/Request.php
Original file line number Diff line number Diff line change
Expand Up @@ -217,10 +217,11 @@ public function send()
$headers = $request->getHeaders();
$contentType = isset($headers['content-type'])
? $headers['content-type'] : '';
if ($this->getMethod() == 'POST'
&& $contentType == 'application/x-www-form-urlencoded'
) {

// RFC 5849 3.4.1.3.1 allows any HTTP method with the correct
// content-type and body content. Don't check method type here.
// See PEAR Bug 17806.
if ($contentType == 'application/x-www-form-urlencoded') {
$body = $this->getHTTPRequest2()->getBody();
$body = str_replace('+', '%20', $body);
$this->getHTTPRequest2()->setBody($body);
Expand All @@ -229,7 +230,12 @@ public function send()
try {
$response = $this->getHTTPRequest2()->send();
} catch (Exception $e) {
throw new HTTP_OAuth_Exception($e->getMessage(), $e->getCode());
if (version_compare(PHP_VERSION, '5.3.0', 'ge')) {
// Use exception chaining if available. See PEAR Bug #18574.
throw new HTTP_OAuth_Exception($e->getMessage(), $e->getCode(), $e);
} else {
throw new HTTP_OAuth_Exception($e->getMessage(), $e->getCode());
}
}

return new HTTP_OAuth_Consumer_Response($response);
Expand Down Expand Up @@ -280,6 +286,8 @@ protected function buildRequest()

switch ($this->getMethod()) {
case 'POST':
case 'PUT':
case 'DELETE':
foreach ($this->getParameters() as $name => $value) {
if (substr($name, 0, 6) == 'oauth_') {
continue;
Expand All @@ -289,6 +297,7 @@ protected function buildRequest()
}
break;
case 'GET':
case 'HEAD':
$url = $this->getUrl();
foreach ($this->getParameters() as $name => $value) {
if (substr($name, 0, 6) == 'oauth_') {
Expand Down
3 changes: 1 addition & 2 deletions HTTP/OAuth/Message.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,7 @@ public function getOAuthParameters()
public function getParameters()
{
$params = $this->parameters;
ksort($params);

ksort($params, SORT_STRING);
return $params;
}

Expand Down
110 changes: 83 additions & 27 deletions HTTP/OAuth/Provider/Request.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,17 +55,53 @@ class HTTP_OAuth_Provider_Request extends HTTP_OAuth_Message
*/
protected $method = '';

/**
* Body data from the incoming request
*
* @var string raw body data from the incoming request
*/
protected $body = '';

/**
* Construct
*
* @param string $body optional. The HTTP request body. Use this if your
* framework automatically reads the php://input
* stream.
*
* @return void
*/
public function __construct()
public function __construct($body = '')
{
$this->setHeaders();
$this->setBody($body);
$this->setParametersFromRequest();
}

/**
* Sets the body data for this request
*
* This is useful if your framework automatically reads the php://input
* stream and your API puts parameters in the request body.
*
* @param string $body the HTTP request body.
*
* @return HTTP_OAuth_Provider_Request the current object, for fluent
* interface.
*/
public function setBody($body = '')
{
if (empty($body)) {
// @codeCoverageIgnoreStart
$this->body = file_get_contents('php://input');
// @codeCoverageIgnoreEnd
} else {
$this->body = (string)$body;
}

return $this;
}

/**
* Set incoming request headers
*
Expand All @@ -83,7 +119,7 @@ public function setHeaders(array $headers = array())
} else if (is_array($this->peclHttpHeaders())) {
$this->debug('Using pecl_http to get request headers');
$this->headers = $this->peclHttpHeaders();
} else {
} else {
$this->debug('Using $_SERVER to get request headers');
foreach ($_SERVER as $name => $value) {
if (substr($name, 0, 5) == 'HTTP_') {
Expand Down Expand Up @@ -149,34 +185,39 @@ public function setParametersFromRequest()
$auth = $this->getHeader('Authorization');
if ($auth !== null) {
$this->debug('Using OAuth data from header');

// strip leading OAuth authentication scheme
$auth = preg_replace('/^oauth /i', '', $auth);

// split auth parameters
$parts = explode(',', $auth);
foreach ($parts as $part) {
list($key, $value) = explode('=', trim($part));
if (strstr(strtolower($key), 'oauth ')
|| strstr(strtolower($key), 'uth re')
|| substr(strtolower($key), 0, 6) != 'oauth_'
) {
list($key, $value) = explode('=', $part, 2);

// strip spaces from around comma and equals delimiters
$key = trim($key);
$value = trim($value);

// ignore auth parameters that are not prefixed with oauth_
if (substr(strtolower($key), 0, 6) != 'oauth_') {
continue;
}

$value = trim($value);
$value = str_replace('"', '', $value);

$params[$key] = $value;
$params[HTTP_OAuth::urldecode($key)] = HTTP_OAuth::urldecode($value);
}
}

if ($this->getRequestMethod() == 'POST') {
$this->debug('getting data from POST');
$contentType = substr($this->getHeader('Content-Type'), 0, 33);
if ($contentType !== 'application/x-www-form-urlencoded') {
throw new HTTP_OAuth_Provider_Exception_InvalidRequest('Invalid ' .
'content type for POST request');
}

// RFC 5849 3.4.1.3.1 allows any HTTP method with the correct
// content-type and body content. Don't check method type here.
// See PEAR Bug 17806.
$contentType = $this->getHeader('Content-Type');
if (strncmp($contentType, 'application/x-www-form-urlencoded', 33) === 0) {
$this->debug('getting application/x-www-form-urlencoded data from request body');
$params = array_merge(
$params,
$this->parseQueryString($this->getPostData())
$this->parseQueryString($this->getBody())
);
}

Expand All @@ -190,7 +231,7 @@ public function setParametersFromRequest()
'data found from request');
}

$this->setParameters(HTTP_OAuth::urldecode($params));
$this->setParameters($params);
}

/**
Expand Down Expand Up @@ -321,22 +362,22 @@ public function getHeaders()
return $this->headers;
}

// @codeCoverageIgnoreStart
/**
* Gets POST data
* Gets request body
*
* @return string Post data
* @return string request data
*/
protected function getPostData()
public function getBody()
{
return file_get_contents('php://input');
return $this->body;
}
// @codeCoverageIgnoreEnd

/**
* Parses a query string
*
* Does not urldecode the name or values like $_GET and $_POST
* Does not use built-in urldecoding of name or values like $_GET and
* $_POST. Instead, names and values are decoded using RFC 3986 as required
* by OAuth.
*
* @param string $string Query string
*
Expand All @@ -355,7 +396,22 @@ protected function parseQueryString($string)
}

list($key, $value) = explode('=', $part);
$data[$key] = self::urldecode($value);

$key = HTTP_OAuth::urldecode($key);
$value = HTTP_OAuth::urldecode($value);

if (isset($data[$key])) {
if (is_array($data[$key])) {
$data[$key][] = $value;
} else {
$data[$key] = array(
$data[$key],
$value
);
}
} else {
$data[$key] = $value;
}
}

return $data;
Expand Down
24 changes: 24 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
Copyright (c) 2009 Jeff Hodsdon, 2009 Bill Shupp, 2013 silverorange Inc.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8 changes: 6 additions & 2 deletions README → README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
# HTTP_OAuth - Implementation of the OAuth specification

HTTP_OAuth is a PEAR package implementing the OAuth 1.0a protocol.
Consumer, Provier (request and response) classes are provided.
See the Consumer examples below:


HTTP_OAuth_Consumer
## HTTP_OAuth_Consumer

Main consumer class that assists consumers in establishing OAuth
creditials and making OAuth requests.

Example:
### Example:

```php
$consumer = new HTTP_OAuth_Consumer('key', 'secret');
$consumer->getRequestToken('http://example.com/oauth/request_token', $callback);

Expand All @@ -31,3 +34,4 @@ $_SESSION['token_secret'] = $consumer->getTokenSecret();

// $response is an instance of HTTP_OAuth_Consumer_Response
$response = $consumer->sendRequest('http://example.com/oauth/protected_resource');
```
42 changes: 42 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"name": "pear/http_oauth",
"description": "Implementation of the OAuth 1.0a specification.",
"type": "library",
"keywords": [ "http", "oauth" ],
"homepage": "https://github.com/pear/HTTP_OAuth",
"license": "BSD-2-Clause",
"authors": [
{
"name": "Michael Gauthier",
"email": "[email protected]"
},
{
"name": "Jeff Hodsdon",
"email": "[email protected]"
},
{
"name": "Bill Shupp",
"email": "[email protected]"
}
],
"require": {
"php": ">=5.1.2",
"ext-date": "*",
"ext-hash": "*",
"ext-spl": "*",
"pear/pear-core-minimal": "^1.9.0",
"pear/http_request2": "^2.0.0"
},
"suggest": {
"pear/log": "Allows logging requests for debugging",
"pear/cache_lite": "Caching of requests."
},
"autoload": {
"psr-0": {
"HTTP_OAuth": ""
}
},
"include-path": [
"./"
]
}
Loading