aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/sabre/http/README.md
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/sabre/http/README.md')
-rw-r--r--vendor/sabre/http/README.md746
1 files changed, 746 insertions, 0 deletions
diff --git a/vendor/sabre/http/README.md b/vendor/sabre/http/README.md
new file mode 100644
index 000000000..ae03a796e
--- /dev/null
+++ b/vendor/sabre/http/README.md
@@ -0,0 +1,746 @@
+sabre/http
+==========
+
+This library provides a toolkit to make working with the HTTP protocol easier.
+
+Most PHP scripts run within a HTTP request but accessing information about the
+HTTP request is cumbersome at least.
+
+There's bad practices, inconsistencies and confusion. This library is
+effectively a wrapper around the following PHP constructs:
+
+For Input:
+
+* `$_GET`,
+* `$_POST`,
+* `$_SERVER`,
+* `php://input` or `$HTTP_RAW_POST_DATA`.
+
+For output:
+
+* `php://output` or `echo`,
+* `header()`.
+
+What this library provides, is a `Request` object, and a `Response` object.
+
+The objects are extendable and easily mockable.
+
+Build status
+------------
+
+| branch | status |
+| ------ | ------ |
+| master | [![Build Status](https://travis-ci.org/fruux/sabre-http.svg?branch=master)](https://travis-ci.org/fruux/sabre-http) |
+| 3.0 | [![Build Status](https://travis-ci.org/fruux/sabre-http.svg?branch=3.0)](https://travis-ci.org/fruux/sabre-http) |
+
+Installation
+------------
+
+Make sure you have [composer][1] installed. In your project directory, create,
+or edit a `composer.json` file, and make sure it contains something like this:
+
+```json
+{
+ "require" : {
+ "sabre/http" : "~3.0.0"
+ }
+}
+```
+
+After that, just hit `composer install` and you should be rolling.
+
+Quick history
+-------------
+
+This library came to existence in 2009, as a part of the [`sabre/dav`][2]
+project, which uses it heavily.
+
+It got split off into a separate library to make it easier to manage
+releases and hopefully giving it use outside of the scope of just `sabre/dav`.
+
+Although completely independently developed, this library has a LOT of
+overlap with [Symfony's `HttpFoundation`][3].
+
+Said library does a lot more stuff and is significantly more popular,
+so if you are looking for something to fulfill this particular requirement,
+I'd recommend also considering [`HttpFoundation`][3].
+
+
+Getting started
+---------------
+
+First and foremost, this library wraps the superglobals. The easiest way to
+instantiate a request object is as follows:
+
+```php
+use Sabre\HTTP;
+
+include 'vendor/autoload.php';
+
+$request = HTTP\Sapi::getRequest();
+```
+
+This line should only happen once in your entire application. Everywhere else
+you should pass this request object around using dependency injection.
+
+You should always typehint on it's interface:
+
+```php
+function handleRequest(HTTP\RequestInterface $request) {
+
+ // Do something with this request :)
+
+}
+```
+
+A response object you can just create as such:
+
+```php
+use Sabre\HTTP;
+
+include 'vendor/autoload.php';
+
+$response = new HTTP\Response();
+$response->setStatus(201); // created !
+$response->setHeader('X-Foo', 'bar');
+$response->setBody(
+ 'success!'
+);
+
+```
+
+After you fully constructed your response, you must call:
+
+```php
+HTTP\Sapi::sendResponse($response);
+```
+
+This line should generally also appear once in your application (at the very
+end).
+
+Decorators
+----------
+
+It may be useful to extend the `Request` and `Response` objects in your
+application, if you for example would like them to carry a bit more
+information about the current request.
+
+For instance, you may want to add an `isLoggedIn` method to the Request
+object.
+
+Simply extending Request and Response may pose some problems:
+
+1. You may want to extend the objects with new behaviors differently, in
+ different subsystems of your application,
+2. The `Sapi::getRequest` factory always returns a instance of
+ `Request` so you would have to override the factory method as well,
+3. By controlling the instantation and depend on specific `Request` and
+ `Response` instances in your library or application, you make it harder to
+ work with other applications which also use `sabre/http`.
+
+In short: it would be bad design. Instead, it's recommended to use the
+[decorator pattern][6] to add new behavior where you need it. `sabre/http`
+provides helper classes to quickly do this.
+
+Example:
+
+```php
+use Sabre\HTTP;
+
+class MyRequest extends HTTP\RequestDecorator {
+
+ function isLoggedIn() {
+
+ return true;
+
+ }
+
+}
+```
+
+Our application assumes that the true `Request` object was instantiated
+somewhere else, by some other subsystem. This could simply be a call like
+`$request = Sapi::getRequest()` at the top of your application,
+but could also be somewhere in a unittest.
+
+All we know in the current subsystem, is that we received a `$request` and
+that it implements `Sabre\HTTP\RequestInterface`. To decorate this object,
+all we need to do is:
+
+```php
+$request = new MyRequest($request);
+```
+
+And that's it, we now have an `isLoggedIn` method, without having to mess
+with the core instances.
+
+
+Client
+------
+
+This package also contains a simple wrapper around [cURL][4], which will allow
+you to write simple clients, using the `Request` and `Response` objects you're
+already familiar with.
+
+It's by no means a replacement for something like [Guzzle][7], but it provides
+a simple and lightweight API for making the occasional API call.
+
+### Usage
+
+```php
+use Sabre\HTTP;
+
+$request = new HTTP\Request('GET', 'http://example.org/');
+$request->setHeader('X-Foo', 'Bar');
+
+$client = new HTTP\Client();
+$response = $client->send($request);
+
+echo $response->getBodyAsString();
+```
+
+The client emits 3 event using [`sabre/event`][5]. `beforeRequest`,
+`afterRequest` and `error`.
+
+```php
+$client = new HTTP\Client();
+$client->on('beforeRequest', function($request) {
+
+ // You could use beforeRequest to for example inject a few extra headers.
+ // into the Request object.
+
+});
+
+$client->on('afterRequest', function($request, $response) {
+
+ // The afterRequest event could be a good time to do some logging, or
+ // do some rewriting in the response.
+
+});
+
+$client->on('error', function($request, $response, &$retry, $retryCount) {
+
+ // The error event is triggered for every response with a HTTP code higher
+ // than 399.
+
+});
+
+$client->on('error:401', function($request, $response, &$retry, $retryCount) {
+
+ // You can also listen for specific error codes. This example shows how
+ // to inject HTTP authentication headers if a 401 was returned.
+
+ if ($retryCount > 1) {
+ // We're only going to retry exactly once.
+ }
+
+ $request->setHeader('Authorization', 'Basic xxxxxxxxxx');
+ $retry = true;
+
+});
+```
+
+### Asynchronous requests
+
+The `Client` also supports doing asynchronous requests. This is especially handy
+if you need to perform a number of requests, that are allowed to be executed
+in parallel.
+
+The underlying system for this is simply [cURL's multi request handler][8],
+but this provides a much nicer API to handle this.
+
+Sample usage:
+
+```php
+
+use Sabre\HTTP;
+
+$request = new Request('GET', 'http://localhost/');
+$client = new Client();
+
+// Executing 1000 requests
+for ($i = 0; $i < 1000; $i++) {
+ $client->sendAsync(
+ $request,
+ function(ResponseInterface $response) {
+ // Success handler
+ },
+ function($error) {
+ // Error handler
+ }
+ );
+}
+
+// Wait for all requests to get a result.
+$client->wait();
+
+```
+
+Check out `examples/asyncclient.php` for more information.
+
+Writing a reverse proxy
+-----------------------
+
+With all these tools combined, it becomes very easy to write a simple reverse
+http proxy.
+
+```php
+use
+ Sabre\HTTP\Sapi,
+ Sabre\HTTP\Client;
+
+// The url we're proxying to.
+$remoteUrl = 'http://example.org/';
+
+// The url we're proxying from. Please note that this must be a relative url,
+// and basically acts as the base url.
+//
+// If youre $remoteUrl doesn't end with a slash, this one probably shouldn't
+// either.
+$myBaseUrl = '/reverseproxy.php';
+// $myBaseUrl = '/~evert/sabre/http/examples/reverseproxy.php/';
+
+$request = Sapi::getRequest();
+$request->setBaseUrl($myBaseUrl);
+
+$subRequest = clone $request;
+
+// Removing the Host header.
+$subRequest->removeHeader('Host');
+
+// Rewriting the url.
+$subRequest->setUrl($remoteUrl . $request->getPath());
+
+$client = new Client();
+
+// Sends the HTTP request to the server
+$response = $client->send($subRequest);
+
+// Sends the response back to the client that connected to the proxy.
+Sapi::sendResponse($response);
+```
+
+The Request and Response API's
+------------------------------
+
+### Request
+
+```php
+
+/**
+ * Creates the request object
+ *
+ * @param string $method
+ * @param string $url
+ * @param array $headers
+ * @param resource $body
+ */
+public function __construct($method = null, $url = null, array $headers = null, $body = null);
+
+/**
+ * Returns the current HTTP method
+ *
+ * @return string
+ */
+function getMethod();
+
+/**
+ * Sets the HTTP method
+ *
+ * @param string $method
+ * @return void
+ */
+function setMethod($method);
+
+/**
+ * Returns the request url.
+ *
+ * @return string
+ */
+function getUrl();
+
+/**
+ * Sets the request url.
+ *
+ * @param string $url
+ * @return void
+ */
+function setUrl($url);
+
+/**
+ * Returns the absolute url.
+ *
+ * @return string
+ */
+function getAbsoluteUrl();
+
+/**
+ * Sets the absolute url.
+ *
+ * @param string $url
+ * @return void
+ */
+function setAbsoluteUrl($url);
+
+/**
+ * Returns the current base url.
+ *
+ * @return string
+ */
+function getBaseUrl();
+
+/**
+ * Sets a base url.
+ *
+ * This url is used for relative path calculations.
+ *
+ * The base url should default to /
+ *
+ * @param string $url
+ * @return void
+ */
+function setBaseUrl($url);
+
+/**
+ * Returns the relative path.
+ *
+ * This is being calculated using the base url. This path will not start
+ * with a slash, so it will always return something like
+ * 'example/path.html'.
+ *
+ * If the full path is equal to the base url, this method will return an
+ * empty string.
+ *
+ * This method will also urldecode the path, and if the url was incoded as
+ * ISO-8859-1, it will convert it to UTF-8.
+ *
+ * If the path is outside of the base url, a LogicException will be thrown.
+ *
+ * @return string
+ */
+function getPath();
+
+/**
+ * Returns the list of query parameters.
+ *
+ * This is equivalent to PHP's $_GET superglobal.
+ *
+ * @return array
+ */
+function getQueryParameters();
+
+/**
+ * Returns the POST data.
+ *
+ * This is equivalent to PHP's $_POST superglobal.
+ *
+ * @return array
+ */
+function getPostData();
+
+/**
+ * Sets the post data.
+ *
+ * This is equivalent to PHP's $_POST superglobal.
+ *
+ * This would not have been needed, if POST data was accessible as
+ * php://input, but unfortunately we need to special case it.
+ *
+ * @param array $postData
+ * @return void
+ */
+function setPostData(array $postData);
+
+/**
+ * Returns an item from the _SERVER array.
+ *
+ * If the value does not exist in the array, null is returned.
+ *
+ * @param string $valueName
+ * @return string|null
+ */
+function getRawServerValue($valueName);
+
+/**
+ * Sets the _SERVER array.
+ *
+ * @param array $data
+ * @return void
+ */
+function setRawServerData(array $data);
+
+/**
+ * Returns the body as a readable stream resource.
+ *
+ * Note that the stream may not be rewindable, and therefore may only be
+ * read once.
+ *
+ * @return resource
+ */
+function getBodyAsStream();
+
+/**
+ * Returns the body as a string.
+ *
+ * Note that because the underlying data may be based on a stream, this
+ * method could only work correctly the first time.
+ *
+ * @return string
+ */
+function getBodyAsString();
+
+/**
+ * Returns the message body, as it's internal representation.
+ *
+ * This could be either a string or a stream.
+ *
+ * @return resource|string
+ */
+function getBody();
+
+/**
+ * Updates the body resource with a new stream.
+ *
+ * @param resource $body
+ * @return void
+ */
+function setBody($body);
+
+/**
+ * Returns all the HTTP headers as an array.
+ *
+ * @return array
+ */
+function getHeaders();
+
+/**
+ * Returns a specific HTTP header, based on it's name.
+ *
+ * The name must be treated as case-insensitive.
+ *
+ * If the header does not exist, this method must return null.
+ *
+ * @param string $name
+ * @return string|null
+ */
+function getHeader($name);
+
+/**
+ * Updates a HTTP header.
+ *
+ * The case-sensitity of the name value must be retained as-is.
+ *
+ * @param string $name
+ * @param string $value
+ * @return void
+ */
+function setHeader($name, $value);
+
+/**
+ * Resets HTTP headers
+ *
+ * This method overwrites all existing HTTP headers
+ *
+ * @param array $headers
+ * @return void
+ */
+function setHeaders(array $headers);
+
+/**
+ * Adds a new set of HTTP headers.
+ *
+ * Any header specified in the array that already exists will be
+ * overwritten, but any other existing headers will be retained.
+ *
+ * @param array $headers
+ * @return void
+ */
+function addHeaders(array $headers);
+
+/**
+ * Removes a HTTP header.
+ *
+ * The specified header name must be treated as case-insenstive.
+ * This method should return true if the header was successfully deleted,
+ * and false if the header did not exist.
+ *
+ * @return bool
+ */
+function removeHeader($name);
+
+/**
+ * Sets the HTTP version.
+ *
+ * Should be 1.0 or 1.1.
+ *
+ * @param string $version
+ * @return void
+ */
+function setHttpVersion($version);
+
+/**
+ * Returns the HTTP version.
+ *
+ * @return string
+ */
+function getHttpVersion();
+```
+
+### Response
+
+```php
+/**
+ * Returns the current HTTP status.
+ *
+ * This is the status-code as well as the human readable string.
+ *
+ * @return string
+ */
+function getStatus();
+
+/**
+ * Sets the HTTP status code.
+ *
+ * This can be either the full HTTP status code with human readable string,
+ * for example: "403 I can't let you do that, Dave".
+ *
+ * Or just the code, in which case the appropriate default message will be
+ * added.
+ *
+ * @param string|int $status
+ * @throws \InvalidArgumentExeption
+ * @return void
+ */
+function setStatus($status);
+
+/**
+ * Returns the body as a readable stream resource.
+ *
+ * Note that the stream may not be rewindable, and therefore may only be
+ * read once.
+ *
+ * @return resource
+ */
+function getBodyAsStream();
+
+/**
+ * Returns the body as a string.
+ *
+ * Note that because the underlying data may be based on a stream, this
+ * method could only work correctly the first time.
+ *
+ * @return string
+ */
+function getBodyAsString();
+
+/**
+ * Returns the message body, as it's internal representation.
+ *
+ * This could be either a string or a stream.
+ *
+ * @return resource|string
+ */
+function getBody();
+
+
+/**
+ * Updates the body resource with a new stream.
+ *
+ * @param resource $body
+ * @return void
+ */
+function setBody($body);
+
+/**
+ * Returns all the HTTP headers as an array.
+ *
+ * @return array
+ */
+function getHeaders();
+
+/**
+ * Returns a specific HTTP header, based on it's name.
+ *
+ * The name must be treated as case-insensitive.
+ *
+ * If the header does not exist, this method must return null.
+ *
+ * @param string $name
+ * @return string|null
+ */
+function getHeader($name);
+
+/**
+ * Updates a HTTP header.
+ *
+ * The case-sensitity of the name value must be retained as-is.
+ *
+ * @param string $name
+ * @param string $value
+ * @return void
+ */
+function setHeader($name, $value);
+
+/**
+ * Resets HTTP headers
+ *
+ * This method overwrites all existing HTTP headers
+ *
+ * @param array $headers
+ * @return void
+ */
+function setHeaders(array $headers);
+
+/**
+ * Adds a new set of HTTP headers.
+ *
+ * Any header specified in the array that already exists will be
+ * overwritten, but any other existing headers will be retained.
+ *
+ * @param array $headers
+ * @return void
+ */
+function addHeaders(array $headers);
+
+/**
+ * Removes a HTTP header.
+ *
+ * The specified header name must be treated as case-insenstive.
+ * This method should return true if the header was successfully deleted,
+ * and false if the header did not exist.
+ *
+ * @return bool
+ */
+function removeHeader($name);
+
+/**
+ * Sets the HTTP version.
+ *
+ * Should be 1.0 or 1.1.
+ *
+ * @param string $version
+ * @return void
+ */
+function setHttpVersion($version);
+
+/**
+ * Returns the HTTP version.
+ *
+ * @return string
+ */
+function getHttpVersion();
+```
+
+Made at fruux
+-------------
+
+This library is being developed by [fruux](https://fruux.com/). Drop us a line for commercial services or enterprise support.
+
+[1]: http://getcomposer.org/
+[2]: http://sabre.io/
+[3]: https://github.com/symfony/HttpFoundation
+[4]: http://php.net/curl
+[5]: https://github.com/fruux/sabre-event
+[6]: http://en.wikipedia.org/wiki/Decorator_pattern
+[7]: http://guzzlephp.org/
+[8]: http://php.net/curl_multi_init