# shelf 0.7.8

A model for web server middleware that encourages composition and easy reuse




## Installing
```
export PUB_HOSTED_URL=https://pub.mirror.p-hatan.ir
flutter pub add 'shelf:0.7.8'
```
Published: 2020-08-12T15:59:44.584570Z
Expected archive SHA-256: 257f7b850c9278dee6d63a1f553e8ff080f0d95e6b37f30ae39303f4d030988a

Available in cache; verification: upstream_checksum
## Direct dependencies
- async: ^2.0.7
- collection: ^1.5.0
- http_parser: ^3.1.0
- path: ^1.0.0
- stack_trace: ^1.0.0
- stream_channel: >=1.0.0 <3.0.0

## Package README (untrusted upstream documentation)
## Web Server Middleware for Dart

[![Build Status](https://travis-ci.org/dart-lang/shelf.svg?branch=master)](https://travis-ci.org/dart-lang/shelf)
[![Coverage Status](https://coveralls.io/repos/dart-lang/shelf/badge.svg?branch=master)](https://coveralls.io/r/dart-lang/shelf)

## Introduction

**Shelf** makes it easy to create and compose **web servers** and **parts of web
servers**. How?

* Expose a small set of simple types.
* Map server logic into a simple function: a single argument for the request,
the response is the return value.
* Trivially mix and match synchronous and asynchronous processing.
* Flexibility to return a simple string or a byte stream with the same model.

## Example

See `example/example.dart`

```dart
import 'package:shelf/shelf.dart' as shelf;
import 'package:shelf/shelf_io.dart' as io;

void main() {
  var handler = const shelf.Pipeline().addMiddleware(shelf.logRequests())
      .addHandler(_echoRequest);

  io.serve(handler, 'localhost', 8080).then((server) {
    print('Serving at http://${server.address.host}:${server.port}');
  });
}

shelf.Response _echoRequest(shelf.Request request) {
  return new shelf.Response.ok('Request for "${request.url}"');
}
```

## Handlers and Middleware

A [handler][] is any function that handles a [shelf.Request][] and returns a
[shelf.Response][]. It can either handle the request itself--for example, a
static file server that looks up the requested URI on the filesystem--or it can
do some processing and forward it to another handler--for example, a logger that
prints information about requests and responses to the command line.

[handler]: https://pub.dev/documentation/shelf/latest/shelf/Handler.html

[shelf.Request]: https://pub.dev/documentation/shelf/latest/shelf/Request-class.html

[shelf.Response]: https://pub.dev/documentation/shelf/latest/shelf/Response-class.html

The latter kind of handler is called "[middleware][]", since it sits in the
middle of the server stack. Middleware can be thought of as a function that
takes a handler and wraps it in another handler to provide additional
functionality. A Shelf application is usually composed of many layers of
middleware with one or more handlers at the very center; the [shelf.Pipeline][]
class makes this sort of application easy to construct.

[middleware]: https://pub.dev/documentation/shelf/latest/shelf/Middleware.html

[shelf.Pipeline]: https://pub.dev/documentation/shelf/latest/shelf/Pipeline-class.html

Some middleware can also take multiple handlers and call one or more of them for
each request. For example, a routing middleware might choose which handler to
call based on the request's URI or HTTP method, while a cascading middleware
might call each one in sequence until one returns a successful response.

Middleware that routes requests between handlers should be sure to update each
request's [`handlerPath`][handlerPath] and [`url`][url]. This allows inner
handlers to know where they are in the application so they can do their own
routing correctly. This can be easily accomplished using
[`Request.change()`][change]:

[handlerPath]: https://pub.dev/documentation/shelf/latest/shelf/Request/handlerPath.html
[url]: https://pub.dev/documentation/shelf/latest/shelf/Request/url.html
[change]: https://pub.dev/documentation/shelf/latest/shelf/Request/change.html

```dart
// In an imaginary routing middleware...
var component = request.url.pathComponents.first;
var handler = _handlers[component];
if (handler == null) return new Response.notFound(null);

// Create a new request just like this one but with whatever URL comes after
// [component] instead.
return handler(request.change(script: component));
```

## Adapters

An adapter is any code that creates [shelf.Request][] objects, passes them to a
handler, and deals with the resulting [shelf.Response][]. For the most part,
adapters forward requests from and responses to an underlying HTTP server;
[shelf_io.serve][] is this sort of adapter. An adapter might also synthesize
HTTP requests within the browser using `window.location` and `window.history`,
or it might pipe requests directly from an HTTP client to a Shelf handler.

[shelf_io.serve]: https://pub.dev/documentation/shelf/latest/shelf_io/serve.html

### API Requirements

An adapter must handle all errors from the handler, including the handler
returning a `null` response. It should print each error to the console if
possible, then act as though the handler returned a 500 response. The adapter
may include body data for the 500 response, but this body data must not include
information about the error that occurred. This ensures that unexpected errors
don't result in exposing internal information in production by default; if the
user wants to return detailed error descriptions, they should explicitly include
middleware to do so.

An adapter should ensure that asynchronous errors thrown by the handler don't
cause the application to crash, even if they aren't reported by the future
chain. Specifically, these errors shouldn't be passed to the root zone's error
handler; however, if the adapter is run within another error zone, it should
allow these errors to be passed to that zone. The following function can be used
to capture only errors that would otherwise be top-leveled:

```dart
/// Run [callback] and capture any errors that would otherwise be top-leveled.
///
/// If [this] is called in a non-root error zone, it will just run [callback]
/// and return the result. Otherwise, it will capture any errors using
/// [runZoned] and pass them to [onError].
catchTopLevelErrors(callback(), void onError(error, StackTrace stackTrace)) {
  if (Zone.current.inSameErrorZone(Zone.ROOT)) {
    return runZoned(callback, onError: onError);
  } else {
    return callback();
  }
}
```

An adapter that knows its own URL should provide an implementation of the
[`Server`][server] interface.

[server]: https://pub.dev/documentation/shelf/latest/shelf/Server-class.html

### Request Requirements

When implementing an adapter, some rules must be followed. The adapter must not
pass the `url` or `handlerPath` parameters to [new shelf.Request][]; it should
only pass `requestedUri`. If it passes the `context` parameter, all keys must
begin with the adapter's package name followed by a period. If multiple headers
with the same name are received, the adapter must collapse them into a single
header separated by commas as per [RFC 2616 section 4.2][].

[new shelf.Request]: https://pub.dev/documentation/shelf/latest/shelf/Request/Request.html

[RFC 2616 section 4.2]: http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html

If the underlying request uses a chunked transfer coding, the adapter must
decode the body before passing it to [new shelf.Request][] and should remove the
`Transfer-Encoding` header. This ensures that message bodies are chunked if and
only if the headers declare that they are.

### Response Requirements

An adapter must not add or modify any [entity headers][] for a response.

[entity headers]: https://www.w3.org/Protocols/rfc2616/rfc2616-sec7.html#sec7.1

If *none* of the following conditions are true, the adapter must apply
[chunked transfer coding][] to a response's body and set its Transfer-Encoding header to `chunked`:

* The status code is less than 200, or equal to 204 or 304.
* A Content-Length header is provided.
* The Content-Type header indicates the MIME type `multipart/byteranges`.
* The Transfer-Encoding header is set to anything other than `identity`.

[chunked transfer coding]: https://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6.1

Adapters may find the [`addChunkedEncoding()`][addChunkedEncoding] middleware
useful for implementing this behavior, if the underlying server doesn't
implement it manually.

When responding to a HEAD request, the adapter must not emit an entity body.
Otherwise, it shouldn't modify the entity body in any way.

An adapter should include information about itself in the Server header of the
response by default. If the handler returns a response with the Server header
set, that must take precedence over the adapter's default header.

An adapter should include the Date header with the time the handler returns a
response. If the handler returns a response with the Date header set, that must
take precedence.

## Inspiration

* [Connect](http://www.senchalabs.org/connect/) for NodeJS.
    * Read [this great write-up](http://howtonode.org/connect-it) to understand
      the overall philosophy of all of these models.
* [Rack](http://rack.github.io/) for Ruby.
* [WSGI](http://legacy.python.org/dev/peps/pep-3333/) for Python.

## Changelog
## 0.7.8

* Handle malformed URLs (400 instead of 500).

## 0.7.7

* Fix internal error in `Request` when `.change()` matches the full path.

## 0.7.6

*   Supports multiple header values in `Request` and `Response`:
    *   `headersAll` field contains all the header values
    *   `headers` field contains the same values as previously (appending values
        with `,`)
    *   `headers` parameter in the constructor and in the `.change()` method
        accepts both `String` and `List<String>` values.

## 0.7.5

* Return the correct HTTP status code for badly formatted requests.

## 0.7.4+1

* Allow `stream_channel` version 2.x

## 0.7.4

* Allow passing `shared` parameter to underlying `HttpServer.bind` calls via
  `shelf_io.serve`.
* Correctly pass `encoding` in `Response` constructors `forbidden`, `notFound`,
  and `internalServerError`.
* Update `README.md` to point to latest docs.

## 0.7.3+3

* Set max SDK version to `<3.0.0`, and adjust other dependencies.

## 0.7.3+2

* Fix constant evaluation analyzer error in `shelf_unmodifiable_map.dart`.

* Update usage of HTTP constants from the Dart SDK. Now require 2.0.0-dev.61.

## 0.7.3+1

* Updated SDK version to 2.0.0-dev.55.0.

## 0.7.3

* Fix some Dart 2 runtime errors.

## 0.7.2

* Update `createMiddleware` arguments to use `FutureOr`.

  * Note: this change is not breaking for the runtime behavior, but it might
    cause new errors during static analysis due the the type changes.

* Updated minimum Dart SDK to `1.24.0`, which added `FutureOr`.

* Improved formatting of the `logRequests` default logger.

## 0.7.1

* The `shelf_io` server now adds a `shelf.io.connection_info` field to
  `Request.context`, which provides access to the underlying
  `HttpConnectionInfo` object.

## 0.7.0

* Give a return type to the `Handler` typedef. This may cause static warnings
  where there previously were none, but all handlers should have already been
  returning a `Response` or `Future<Response>`.

* Remove `HijackCallback` and `OnHijackCallback` typedefs.

* **Breaking**: Change type of `onHijack` in the `Request` constructor to take
  an argument of `StreamChannel`.

## 0.6.8

* Add a `securityContext` parameter to `self_io.serve()`.

## 0.6.7+2

* Go back to auto-generating a `Content-Length` header when the length is known
  ahead-of-time *and* the user hasn't explicitly specified a `Transfer-Encoding:
  chunked`.

* Clarify adapter requirements around transfer codings.

* Make `shelf_io` consistent with the clarified adapter requirements. In
  particular, it removes the `Transfer-Encoding` header from chunked requests,
  and it doesn't apply additional chunking to responses that already declare
  `Transfer-Encoding: chunked`.

## 0.6.7+1

* Never auto-generate a `Content-Length` header.

## 0.6.7

* Add `Request.isEmpty` and `Response.isEmpty` getters which indicate whether a
  message has an empty body.

* Don't automatically generate `Content-Length` headers on messages where they
  may not be allowed.

* User-specified `Content-Length` headers now always take precedence over
  automatically-generated headers.

## 0.6.6

* Allow `List<int>`s to be passed as request or response bodies.

* Requests and responses now automatically set `Content-Length` headers when the
  body length is known ahead of time.

* Work around [sdk#27660][] by manually setting
  `HttpResponse.chunkedTransferEncoding` to `false` for requests known to have
  no content.

[sdk#27660]: https://github.com/dart-lang/sdk/issues/27660

## 0.6.5+3

* Improve the documentation of `logRequests()`.

## 0.6.5+2

* Support `http_parser` 3.0.0.

## 0.6.5+1

* Fix all strong-mode warnings and errors.

## 0.6.5

* `Request.hijack()` now takes a callback that accepts a single `StreamChannel`
  argument rather than separate `Stream` and `StreamSink` arguments. The old
  callback signature is still supported, but should be considered deprecated.

* The `HijackCallback` and `OnHijackCallback` typedefs are deprecated.

## 0.6.4+3

* Support `http_parser` 2.0.0.

## 0.6.4+2

* Fix a bug where the `Content-Type` header didn't interact properly with the
  `encoding` parameter for `new Request()` and `new Response()` if it wasn't
  lowercase.

## 0.6.4+1

* When the `shelf_io` adapter detects an error, print the request context as
  well as the error itself.

## 0.6.4

* Add a `Server` interface representing an adapter that knows its own URL.

* Add a `ServerHandler` class that exposes a `Server` backed by a `Handler`.

* Add an `IOServer` class that implements `Server` in terms of `dart:io`'s
  `HttpServer`.

## 0.6.3+1

* Cleaned up handling of certain `Map` instances and related dependencies.

## 0.6.3

* Messages returned by `Request.change()` and `Response.change()` are marked
  read whenever the original message is read, and vice-versa. This means that
  it's possible to read a message on which `change()` has been called and to
  call `change()` on a message more than once, as long as `read()` is called on
  only one of those messages.

## 0.6.2+1

* Support `http_parser` 1.0.0.

## 0.6.2

* Added a `body` named argument to `change` method on `Request` and `Response`.

## 0.6.1+3

* Updated minimum SDK to `1.9.0`.

* Allow an empty `url` parameter to be passed in to `new Request()`. This fits
  the stated semantics of the class, and should not have been forbidden.

## 0.6.1+2

* `logRequests` outputs a better message a request has a query string.

## 0.6.1+1

* Don't throw a bogus exception for `null` responses.

## 0.6.1

* `shelf_io` now takes a `"shelf.io.buffer_output"` `Response.context` parameter
  that controls `HttpResponse.bufferOutput`.

* Fixed spelling errors in README and code comments.

## 0.6.0

**Breaking change:** The semantics of `Request.scriptName` and
[`Request.url`][url] have been overhauled, and the former has been renamed to
[`Request.handlerPath`][handlerPath]. `handlerPath` is now the root-relative URL
path to the current handler, while `url`'s path is the relative path from the
current handler to the requested. The new semantics are easier to describe and
to understand.

[url]: https://pub.dev/documentation/shelf/latest/shelf/Request/url.html
[handlerPath]: https://pub.dev/documentation/shelf/latest/shelf/Request/handlerPath.html

Practically speaking, the main difference is that the `/` at the beginning of
`url`'s path has been moved to the end of `handlerPath`. This makes `url`'s path
easier to parse using the `path` package.

[`Request.change`][change]'s handling of `handlerPath` and `url` has also
changed. Instead of taking both parameters separately and requiring that the
user manually maintain all the associated guarantees, it now takes a single
`path` parameter. This parameter is the relative path from the current
`handlerPath` to the next one, and sets both `handlerPath` and `url` on the new
`Request` accordingly.

[change]: https://pub.dev/documentation/shelf/latest/shelf/Request/change.html

## 0.5.7

* Updated `Request` to support the `body` model from `Response`.

## 0.5.6

* Fixed `createMiddleware` to only catch errors if `errorHandler` is provided.

* Updated `handleRequest` in `shelf_io` to more gracefully handle errors when
  parsing `HttpRequest`.

## 0.5.5+1

* Updated `Request.change` to include the original `onHijack` callback if one
  exists.

## 0.5.5

* Added default body text for `Response.forbidden` and `Response.notFound` if
  null is provided.

* Clarified documentation on a number of `Response` constructors.

* Updated `README` links to point to latest docs.

## 0.5.4+3

* Widen the version constraint on the `collection` package.

## 0.5.4+2

* Updated headers map to use a more efficient case-insensitive backing store.

## 0.5.4+1

* Widen the version constraint for `stack_trace`.

## 0.5.4

* The `shelf_io` adapter now sends the `Date` HTTP header by default.

* Fixed logic for setting Server header in `shelf_io`.

## 0.5.3

* Add new named parameters to `Request.change`: `scriptName` and `url`.

## 0.5.2

* Add a `Cascade` helper that runs handlers in sequence until one returns a
  response that's neither a 404 nor a 405.

* Add a `Request.change` method that copies a request with new header values.

* Add a `Request.hijack` method that allows handlers to gain access to the
  underlying HTTP socket.

## 0.5.1+1

* Capture all asynchronous errors thrown by handlers if they would otherwise be
  top-leveled.

* Add more detail to the README about handlers, middleware, and the rules for
  implementing an adapter.

## 0.5.1

* Add a `context` map to `Request` and `Response` for passing data among
  handlers and middleware.

## 0.5.0+1

* Allow `scheduled_test` development dependency up to v0.12.0

## 0.5.0

* Renamed `Stack` to `Pipeline`.

## 0.4.0

* Access to headers for `Request` and `Response` is now case-insensitive.

* The constructor for `Request` has been simplified.

* `Request` now exposes `url` which replaces `pathInfo`, `queryString`, and
  `pathSegments`.

## 0.3.0+9

* Removed old testing infrastructure.

* Updated documentation address.

## 0.3.0+8

* Added a dependency on the `http_parser` package.

## 0.3.0+7

* Removed unused dependency on the `mime` package.

## 0.3.0+6

* Added a dependency on the `string_scanner` package.

## 0.3.0+5

* Updated `pubspec` details for move to Dart SDK.

## 0.3.0 2014-03-25

* `Response`
    * **NEW!** `int get contentLength`
    * **NEW!** `DateTime get expires`
    * **NEW!** `DateTime get lastModified`
* `Request`
    * **BREAKING** `contentLength` is now read from `headers`. The constructor
      argument has been removed.
    * **NEW!** supports an optional `Stream<List<int>> body` constructor argument.
    * **NEW!** `Stream<List<int>> read()` and
      `Future<String> readAsString([Encoding encoding])`
    * **NEW!** `DateTime get ifModifiedSince`
    * **NEW!** `String get mimeType`
    * **NEW!** `Encoding get encoding`

## 0.2.0 2014-03-06

* **BREAKING** Removed `Shelf` prefix from all classes.
* **BREAKING** `Response` has drastically different constructors.
* *NEW!* `Response` now accepts a body of either `String` or
  `Stream<List<int>>`.
* *NEW!* `Response` now exposes `encoding` and `mimeType`.

## 0.1.0 2014-03-02

* First reviewed release







 
