基础代码

This commit is contained in:
2021-02-26 22:23:13 +08:00
parent 7884df52f0
commit a719feebba
2585 changed files with 328263 additions and 0 deletions
+28
View File
@@ -0,0 +1,28 @@
Documentation
=============
If you're here, you're looking for documentation for Requests! The documents
here are prose; you might also want to check out the [API documentation][].
[API documentation]: http://requests.ryanmccue.info/api/
* Introduction
* [Goals][goals]
* [Why should I use Requests instead of X?][why-requests]
* Usage
* [Making a request][usage]
* [Advanced usage][usage-advanced]
* [Authenticating your request][authentication]
* Advanced Usage
* [Custom authentication][authentication-custom]
* [Requests through proxy][proxy]
* [Hooking system][hooks]
[goals]: goals.md
[why-requests]: why-requests.md
[usage]: usage.md
[usage-advanced]: usage-advanced.md
[authentication]: authentication.md
[authentication-custom]: authentication-custom.md
[hooks]: hooks.md
[proxy]: proxy.md
+44
View File
@@ -0,0 +1,44 @@
Custom Authentication
=====================
Custom authentication handlers are designed to be extremely simple to write.
In order to write a handler, you'll need to implement the `Requests_Auth`
interface.
An instance of this handler is then passed in by the user via the `auth`
option, just like for normal authentication.
Let's say we have a HTTP endpoint that checks for the `Hotdog` header and
authenticates you if said header is set to `Yummy`. (I don't know of any
services that do this; perhaps this is a market waiting to be tapped?)
```php
class MySoftware_Auth_Hotdog implements Requests_Auth {
protected $password;
public function __construct($password) {
$this->password = $password;
}
public function register(Requests_Hooks &$hooks) {
$hooks->register('requests.before_request', array(&$this, 'before_request'));
}
public function before_request(&$url, &$headers, &$data, &$type, &$options) {
$headers['Hotdog'] = $this->password;
}
}
```
We then use this in our request calls:
```
$options = array(
'auth' => new MySoftware_Auth_Hotdog('yummy')
);
$response = Requests::get('http://hotdogbin.org/admin', array(), $options);
```
(For more information on how to register and use hooks, see the [hooking
system documentation][hooks])
[hooks]: hooks.md
+31
View File
@@ -0,0 +1,31 @@
Authentication
==============
Many requests that you make will require authentication of some type. Requests
includes support out of the box for HTTP Basic authentication, with more
built-ins coming soon.
Making a Basic authenticated call is ridiculously easy:
```php
$options = array(
'auth' => new Requests_Auth_Basic(array('user', 'password'))
);
Requests::get('http://httpbin.org/basic-auth/user/password', array(), $options);
```
As Basic authentication is usually what you want when you specify a username
and password, you can also just pass in an array as a shorthand:
```php
$options = array(
'auth' => array('user', 'password')
);
Requests::get('http://httpbin.org/basic-auth/user/password', array(), $options);
```
Note that POST/PUT can also take a data parameter, so you also need that
before `$options`:
```php
Requests::post('http://httpbin.org/basic-auth/user/password', array(), null, $options);
```
+29
View File
@@ -0,0 +1,29 @@
Goals
=====
1. **Simple interface**
Requests is designed to provide a simple, unified interface to making
requests, regardless of what is available on the system. This means not worrying.
2. **Fully tested code**
Requests strives to have 90%+ code coverage from the unit tests, aiming for
the ideal 100%. Introducing new features always means introducing new tests
(Note: some parts of the code are not covered by design. These sections are
marked with `@codeCoverageIgnore` tags)
3. **Maximum compatibility**
No matter what you have installed on your system, you should be able to run
Requests. We use cURL if it's available, and fallback to sockets otherwise.
We require only a baseline of PHP 5.2, leaving the choice of PHP minimum
requirement fully in your hands, and giving you the ability to support many
more hosts.
4. **No dependencies**
Requests is designed to be entirely self-contained and doesn't require
anything else at all. You can run Requests on an entirely stock PHP build
without any additional extensions outside the standard library.
+96
View File
@@ -0,0 +1,96 @@
Hooks
=====
Requests has a hook system that you can use to manipulate parts of the request
process along with internal transport hooks.
Check out the [API documentation for `Requests_Hooks`][requests_hooks] for more
information on how to use the hook system.
Available Hooks
---------------
* `requests.before_request`
Alter the request before it's sent to the transport.
Parameters: `string &$url`, `array &$headers`, `array|string &$data`,
`string &$type`, `array &$options`
* `requests.before_parse`
Alter the raw HTTP response before parsing
Parameters: `string &$response`
* `requests.after_request`
Alter the response object before it's returned to the user
Parameters: `Requests_Response &$return`
* `curl.before_request`
Set cURL options before the transport sets any (note that Requests may
override these)
Parameters: `cURL resource &$fp`
* `curl.before_send`
Set cURL options just before the request is actually sent via `curl_exec`
Parameters: `cURL resource &$fp`
* `curl.after_request`
Alter the raw HTTP response before returning for parsing
Parameters: `string &$response, array &$info`
`$info` contains the associated array as defined in [curl-getinfo-returnvalues](http://php.net/manual/en/function.curl-getinfo.php#refsect1-function.curl-getinfo-returnvalues)
* `fsockopen.before_request`
Run events before the transport does anything
* `fsockopen.after_headers`
Add extra headers before the body begins (i.e. before `\r\n\r\n`)
Parameters: `string &$out`
* `fsockopen.before_send`
Add body data before sending the request
Parameters: `string &$out`
* `fsockopen.after_send`
Run events after writing the data to the socket
* `fsockopen.after_request`
Alter the raw HTTP response before returning for parsing
Parameters: `string &$response, array &$info`
`$info` contains the associated array as defined in [stream-get-meta-data-returnvalues](http://php.net/manual/en/function.stream-get-meta-data.php#refsect1-function.stream-get-meta-data-returnvalues)
Registering Hooks
-----------------
Note: if you're doing this in an authentication handler, see the [Custom
Authentication guide][authentication-custom] instead.
[authentication-custom]: authentication-custom.md
In order to register your own hooks, you need to instantiate `Requests_hooks`
and pass this in via the 'hooks' option.
```php
$hooks = new Requests_Hooks();
$hooks->register('requests.after_request', 'mycallback');
$request = Requests::get('http://httpbin.org/get', array(), array('hooks' => $hooks));
```
+23
View File
@@ -0,0 +1,23 @@
Proxy Support
=============
You can easily make requests through HTTP proxies.
To make requests through an open proxy, specify the following options:
```php
$options = array(
'proxy' => '127.0.0.1:3128'
);
Requests::get('http://httpbin.org/ip', array(), $options);
```
If your proxy needs you to authenticate, the option will become an array like
the following:
```php
$options = array(
'proxy' => array( '127.0.0.1:3128', 'my_username', 'my_password' )
);
Requests::get('http://httpbin.org/ip', array(), $options);
```
+74
View File
@@ -0,0 +1,74 @@
Advanced Usage
==============
Session Handling
----------------
Making multiple requests to the same site with similar options can be a pain,
since you end up repeating yourself. The Session object can be used to set
default parameters for these.
Let's simulate communicating with GitHub.
```php
$session = new Requests_Session('https://api.github.com/');
$session->headers['X-ContactAuthor'] = 'rmccue';
$session->useragent = 'My-Awesome-App';
$response = $session->get('/zen');
```
You can use the `url`, `headers`, `data` and `options` properties of the Session
object to set the defaults for this session, and the constructor also takes
parameters in the same order as `Requests::request()`. Accessing any other
properties will set the corresponding key in the options array; that is:
```php
// Setting the property...
$session->useragent = 'My-Awesome-App';
// ...is the same as setting the option
$session->options['useragent'] = 'My-Awesome-App';
```
Secure Requests with SSL
------------------------
By default, HTTPS requests will use the most secure options available:
```php
$response = Requests::get('https://httpbin.org/');
```
Requests bundles certificates from the [Mozilla certificate authority list][],
which is the same list of root certificates used in most browsers. If you're
accessing sites with certificates from other CAs, or self-signed certificates,
you can point Requests to a custom CA list in PEM form (the same format
accepted by cURL and OpenSSL):
```php
$options = array(
'verify' => '/path/to/cacert.pem'
);
$response = Requests::get('https://httpbin.org/', array(), $options);
```
Alternatively, if you want to disable verification completely, this is possible
with `'verify' => false`, but note that this is extremely insecure and should be
avoided.
### Security Note
Requests supports SSL across both cURL and fsockopen in a transparent manner.
Unlike other PHP HTTP libraries, support for verifying the certificate name is
built-in; that is, a request for `https://github.com/` will actually verify the
certificate's name even with the fsockopen transport. This makes Requests the
first and currently only PHP HTTP library that supports full SSL verification.
(Note that WordPress now also supports this verification, thanks to efforts by
the Requests development team.)
(See also the [related PHP][php-bug-47030] and [OpenSSL-related][php-bug-55820]
bugs in PHP for more information on Subject Alternate Name field.)
[Mozilla certificate authority list]: http://www.mozilla.org/projects/security/certs/
[php-bug-47030]: https://bugs.php.net/bug.php?id=47030
[php-bug-55820]:https://bugs.php.net/bug.php?id=55820
+154
View File
@@ -0,0 +1,154 @@
Usage
=====
Ready to go? Make sure you have Requests installed before attempting any of the
steps in this guide.
Loading Requests
----------------
Before we can load Requests up, we'll need to make sure it's loaded. This is a
simple two-step:
```php
// First, include Requests
include('/path/to/library/Requests.php');
// Next, make sure Requests can load internal classes
Requests::register_autoloader();
```
If you'd like to bring along your own autoloader, you can forget about this
completely.
Make a GET Request
------------------
One of the most basic things you can do with HTTP is make a GET request.
Let's grab GitHub's public timeline:
```php
$response = Requests::get('https://github.com/timeline.json');
```
`$response` is now a **Requests_Response** object. Response objects are what
you'll be working with whenever you want to get data back from your request.
Using the Response Object
-------------------------
Now that we have the response from GitHub, let's get the body of the response.
```php
var_dump($response->body);
// string(42865) "[{"repository":{"url":"...
```
Custom Headers
--------------
If you want to add custom headers to the request, simply pass them in as an
associative array as the second parameter:
```php
$response = Requests::get('https://github.com/timeline.json', array('X-Requests' => 'Is Awesome!'));
```
Make a POST Request
-------------------
Making a POST request is very similar to making a GET:
```php
$response = Requests::post('http://httpbin.org/post');
```
You'll probably also want to pass in some data. You can pass in either a
string, an array or an object (Requests uses [`http_build_query`][build_query]
internally) as the third parameter (after the URL and headers):
[build_query]: http://php.net/http_build_query
```php
$data = array('key1' => 'value1', 'key2' => 'value2');
$response = Requests::post('http://httpbin.org/post', array(), $data);
var_dump($response->body);
```
This gives the output:
string(503) "{
"origin": "124.191.162.147",
"files": {},
"form": {
"key2": "value2",
"key1": "value1"
},
"headers": {
"Content-Length": "23",
"Accept-Encoding": "deflate;q=1.0, compress;q=0.5, gzip;q=0.5",
"X-Forwarded-Port": "80",
"Connection": "keep-alive",
"User-Agent": "php-requests/1.6-dev",
"Host": "httpbin.org",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
},
"url": "http://httpbin.org/post",
"args": {},
"data": ""
}"
To send raw data, simply pass in a string instead. You'll probably also want to
set the Content-Type header to ensure the remote server knows what you're
sending it:
```php
$url = 'https://api.github.com/some/endpoint';
$headers = array('Content-Type' => 'application/json');
$data = array('some' => 'data');
$response = Requests::post($url, $headers, json_encode($data));
```
Note that if you don't manually specify a Content-Type header, Requests has
undefined behaviour for the header. It may be set to various values depending
on the internal execution path, so it's recommended to set this explicitly if
you need to.
Status Codes
------------
The Response object also gives you access to the status code:
```php
var_dump($response->status_code);
// int(200)
```
You can also easily check if this status code is a success code, or if it's an
error:
```php
var_dump($response->success);
// bool(true)
```
Response Headers
----------------
We can also grab headers pretty easily:
```php
var_dump($response->headers['Date']);
// string(29) "Thu, 09 Feb 2012 15:22:06 GMT"
```
Note that this is case-insensitive, so the following are all equivalent:
* `$response->headers['Date']`
* `$response->headers['date']`
* `$response->headers['DATE']`
* `$response->headers['dAtE']`
If a header isn't set, this will give `null`. You can also check with
`isset($response->headers['date'])`
+192
View File
@@ -0,0 +1,192 @@
Why Requests Instead of X?
==========================
This is a quick look at why you should use Requests instead of another
solution. Keep in mind though that these are my point of view, and they may not
be issues for you.
As always with software, you should choose what you think is best.
Why should I use Requests?
--------------------------
1. **Designed for maximum compatibility**
The realities of working with widely deployable software mean that awesome
PHP features aren't always available. PHP 5.3, cURL, OpenSSL and more are not
necessarily going to be available on every system. While you're welcome to
require PHP 5.3, 5.4 or even 5.5, it's not our job to force you to use those.
(The WordPress project estimates [about 60%][wpstats] of hosts are running
PHP 5.2, so this is a serious issue for developers working on large
deployable projects.)
Don't worry though, Requests will automatically use better features where
possible, giving you an extra speed boost with cURL.
2. **Simple API**
Requests' API is designed to be able to be learnt in 10 minutes. Everything
from basic requests all the way up to advanced usage involving custom SSL
certificates and stored cookies is handled by a simple API.
Other HTTP libraries optimize for the library developer's time; **Requests
optimizes for your time**.
3. **Thoroughly tested**
Requests is [continuously integrated with Travis][travis] and test coverage
is [constantly monitored with Coveralls][coveralls] to give you confidence in
the library. We aim for test coverage **over 90%** at all times, and new
features require new tests to go along with them. This ensures that you can
be confident in the quality of the code, as well as being able to update to
the latest version of Requests without worrying about compatibility.
4. **Secure by default**
Unlike other HTTP libraries, Requests is secure by default. Requests is the
**first and currently only** standalone HTTP library to
**[fully verify][requests_ssl] all HTTPS requests** even without cURL. We
also bundle the latest root certificate authorities to ensure that your
secure requests are actually secure.
(Of note is that WordPress as of version 3.7 also supports full checking of
the certificates, thanks to [evangelism efforts on our behalf][wpssl].
Together, we are the only HTTP libraries in PHP to fully verify certificates
to the same level as browsers.)
5. **Extensible from the core**
If you need low-level access to Requests' internals, simply plug your
callbacks in via the built-in [hooking system][] and mess around as much as
you want. Requests' simple hooking system is so powerful that both
authentication handlers and cookie support is actually handled internally
with hooks.
[coveralls]: https://coveralls.io/r/rmccue/Requests
[hooking system]: hooks.md
[requests_ssl]: https://github.com/rmccue/Requests/blob/master/library/Requests/SSL.php
[travis]: https://travis-ci.org/rmccue/Requests
[wpssl]: http://core.trac.wordpress.org/ticket/25007
Why shouldn't I use...
----------------------
Requests isn't the first or only HTTP library in PHP and it's important to
acknowledge the other solutions out there. Here's why you should use Requests
instead of something else, in our opinion.
### cURL
1. **Not every host has cURL installed**
cURL is far from being ubiquitous, so you can't rely on it always being
available when distributing software. Anecdotal data collected from various
projects indicates that cURL is available on roughly 90% of hosts, but that
leaves 10% of hosts without it.
2. **cURL's interface sucks**
cURL's interface was designed for PHP 4, and hence uses resources with
horrible functions such as `curl_setopt()`. Combined with that, it uses 229
global constants, polluting the global namespace horribly.
Requests, on the other hand, exposes only a handful of classes to the
global namespace, most of which are for internal use. You can learn to use
the `Requests::request()` method and the `Requests_Response` object in the
space of 10 minutes and you already know how to use Requests.
### Guzzle
1. **Requires cURL and PHP 5.3+**
Guzzle is designed to be a client to fit a large number of installations, but
as a result of optimizing for Guzzle developer time, it uses cURL as an
underlying transport. As noted above, this is a majority of systems, but
far from all.
The same is true for PHP 5.3+. While we'd all love to rely on PHP's newer
features, the fact is that a huge percentage of hosts are still running on
PHP 5.2. (The WordPress project estimates [about 60%][wpstats] of hosts are
running PHP 5.2.)
2. **Not just a HTTP client**
Guzzle is not intended to just be a HTTP client, but rather to be a
full-featured REST client. Requests is just a HTTP client, intentionally. Our
development strategy is to act as a low-level library that REST clients can
easily be built on, not to provide the whole kitchen sink for you.
If you want to rapidly develop a web service client using a framework, Guzzle
will suit you perfectly. On the other hand, if you want a HTTP client without
all the rest, Requests is the way to go.
[wpstats]: http://wordpress.org/about/stats/
### Buzz
1. **Requires PHP 5.3+**
As with Guzzle, while PHP 5.3+ is awesome, you can't always rely on it being
on a host. With widely distributable software, this is a huge problem.
2. **Not transport-transparent**
For making certain types of requests, such as multi-requests, you can't rely
on a high-level abstraction and instead have to use the low-level transports.
This really gains nothing (other than a fancy interface) over just using the
methods directly and means that you can't rely on features to be available.
### fsockopen
1. **Very low-level**
fsockopen is used for working with sockets directly, so it only knows about
the transport layer (TCP in our case), not anything higher (i.e. HTTP on the
application layer). To be able to use fsockopen as a HTTP client, you need
to write all the HTTP code yourself, and once you're done, you'll end up
with something that is almost exactly like Requests.
### PEAR HTTP_Request2
1. **Requires PEAR**
PEAR is (in theory) a great distribution system (with a less than wonderful
implementation), however it is not ubiquitous, as many hosts disable it to
save on space that most people aren't going to use anyway.
PEAR is also a pain for users. Users want to be able to download a zip of
your project without needing to install anything else from PEAR.
(If you really want though, Requests is available via PEAR. Check the README
to see how to grab it.)
2. **Depends on other PEAR utilities**
HTTP\_Request2 requires Net_URL2 in order to function, locking you in to
using PEAR for your project.
Requests is entirely self-contained, and includes all the libraries it needs
(for example, Requests\_IRI is based on ComplexPie\_IRI by Geoffrey Sneddon).
### PECL HttpRequest
1. **Requires a PECL extension**
Similar to PEAR, users aren't big fans of installing extra libraries. Unlike
PEAR though, PECL extensions require compiling, which end users will be
unfamiliar with. In addition, on systems where users do not have full
control over PHP, they will be unable to install custom extensions.
### Zend Framework's Zend\_Http\_Client
1. **Requires other parts of the Zend Framework**
Similar to HTTP_Request2, Zend's client is not fully self-contained and
requires other components from the framework.