Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(257)

Side by Side Diff: mojo/public/dart/third_party/shelf/README.md

Issue 1346773002: Stop running pub get at gclient sync time and fix build bugs (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 ## Web Server Middleware for Dart
2
3 [![Build Status](https://travis-ci.org/dart-lang/shelf.svg?branch=master)](https ://travis-ci.org/dart-lang/shelf)
4 [![Coverage Status](https://coveralls.io/repos/dart-lang/shelf/badge.svg?branch= master)](https://coveralls.io/r/dart-lang/shelf)
5
6 ## Introduction
7
8 **Shelf** makes it easy to create and compose **web servers** and **parts of web
9 servers**. How?
10
11 * Expose a small set of simple types.
12 * Map server logic into a simple function: a single argument for the request,
13 the response is the return value.
14 * Trivially mix and match synchronous and asynchronous processing.
15 * Flexibility to return a simple string or a byte stream with the same model.
16
17 ## Example
18
19 See `example/example_server.dart`
20
21 ```dart
22 import 'package:shelf/shelf.dart' as shelf;
23 import 'package:shelf/shelf_io.dart' as io;
24
25 void main() {
26 var handler = const shelf.Pipeline().addMiddleware(shelf.logRequests())
27 .addHandler(_echoRequest);
28
29 io.serve(handler, 'localhost', 8080).then((server) {
30 print('Serving at http://${server.address.host}:${server.port}');
31 });
32 }
33
34 shelf.Response _echoRequest(shelf.Request request) {
35 return new shelf.Response.ok('Request for "${request.url}"');
36 }
37 ```
38
39 ## Handlers and Middleware
40
41 A [handler][] is any function that handles a [shelf.Request][] and returns a
42 [shelf.Response][]. It can either handle the request itself--for example, a
43 static file server that looks up the requested URI on the filesystem--or it can
44 do some processing and forward it to another handler--for example, a logger that
45 prints information about requests and responses to the command line.
46
47 [handler]: http://www.dartdocs.org/documentation/shelf/latest/index.html#shelf/s helf@id_Handler
48
49 [shelf.Request]: http://www.dartdocs.org/documentation/shelf/latest/index.html#s helf/shelf.Request
50
51 [shelf.Response]: http://www.dartdocs.org/documentation/shelf/latest/index.html #shelf/shelf.Response
52
53 The latter kind of handler is called "[middleware][]", since it sits in the
54 middle of the server stack. Middleware can be thought of as a function that
55 takes a handler and wraps it in another handler to provide additional
56 functionality. A Shelf application is usually composed of many layers of
57 middleware with one or more handlers at the very center; the [shelf.Pipeline][]
58 class makes this sort of application easy to construct.
59
60 [middleware]: http://www.dartdocs.org/documentation/shelf/latest/index.html#shel f/shelf@id_Middleware
61
62 [shelf.Pipeline]: http://www.dartdocs.org/documentation/shelf/latest/index.html #shelf/shelf.Pipeline
63
64 Some middleware can also take multiple handlers and call one or more of them for
65 each request. For example, a routing middleware might choose which handler to
66 call based on the request's URI or HTTP method, while a cascading middleware
67 might call each one in sequence until one returns a successful response.
68
69 Middleware that routes requests between handlers should be sure to update each
70 request's [`handlerPath`][handlerPath] and [`url`][url]. This allows inner
71 handlers to know where they are in the application so they can do their own
72 routing correctly. This can be easily accomplished using
73 [`Request.change()`][change]:
74
75 [handlerPath]: http://www.dartdocs.org/documentation/shelf/latest/index.html#she lf/shelf.Request@id_handlerPath
76 [url]: http://www.dartdocs.org/documentation/shelf/latest/index.html#shelf/shelf .Request@id_url
77 [change]: http://www.dartdocs.org/documentation/shelf/latest/index.html#shelf/sh elf.Request@id_change
78
79 ```dart
80 // In an imaginary routing middleware...
81 var component = request.url.pathComponents.first;
82 var handler = _handlers[component];
83 if (handler == null) return new Response.notFound(null);
84
85 // Create a new request just like this one but with whatever URL comes after
86 // [component] instead.
87 return handler(request.change(script: component));
88 ```
89
90 ## Adapters
91
92 An adapter is any code that creates [shelf.Request][] objects, passes them to a
93 handler, and deals with the resulting [shelf.Response][]. For the most part,
94 adapters forward requests from and responses to an underlying HTTP server;
95 [shelf_io.serve][] is this sort of adapter. An adapter might also synthesize
96 HTTP requests within the browser using `window.location` and `window.history`,
97 or it might pipe requests directly from an HTTP client to a Shelf handler.
98
99 [shelf_io.serve]: http://www.dartdocs.org/documentation/shelf/latest/index.html# shelf/shelf-io@id_serve
100
101 When implementing an adapter, some rules must be followed. The adapter must not
102 pass the `url` or `handlerPath` parameters to [new shelf.Request][]; it should
103 only pass `requestedUri`. If it passes the `context` parameter, all keys must
104 begin with the adapter's package name followed by a period. If multiple headers
105 with the same name are received, the adapter must collapse them into a single
106 header separated by commas as per [RFC 2616 section 4.2][].
107
108 [new shelf.Request]: http://www.dartdocs.org/documentation/shelf/latest/index.ht ml#shelf/shelf.Request@id_Request-
109
110 [RFC 2616 section 4.2]: http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html
111
112 An adapter must handle all errors from the handler, including the handler
113 returning a `null` response. It should print each error to the console if
114 possible, then act as though the handler returned a 500 response. The adapter
115 may include body data for the 500 response, but this body data must not include
116 information about the error that occurred. This ensures that unexpected errors
117 don't result in exposing internal information in production by default; if the
118 user wants to return detailed error descriptions, they should explicitly include
119 middleware to do so.
120
121 An adapter should include information about itself in the Server header of the
122 response by default. If the handler returns a response with the Server header
123 set, that must take precedence over the adapter's default header.
124
125 An adapter should include the Date header with the time the handler returns a
126 response. If the handler returns a response with the Date header set, that must
127 take precedence.
128
129 An adapter should ensure that asynchronous errors thrown by the handler don't
130 cause the application to crash, even if they aren't reported by the future
131 chain. Specifically, these errors shouldn't be passed to the root zone's error
132 handler; however, if the adapter is run within another error zone, it should
133 allow these errors to be passed to that zone. The following function can be used
134 to capture only errors that would otherwise be top-leveled:
135
136 ```dart
137 /// Run [callback] and capture any errors that would otherwise be top-leveled.
138 ///
139 /// If [this] is called in a non-root error zone, it will just run [callback]
140 /// and return the result. Otherwise, it will capture any errors using
141 /// [runZoned] and pass them to [onError].
142 catchTopLevelErrors(callback(), void onError(error, StackTrace stackTrace)) {
143 if (Zone.current.inSameErrorZone(Zone.ROOT)) {
144 return runZoned(callback, onError: onError);
145 } else {
146 return callback();
147 }
148 }
149 ```
150
151 ## Inspiration
152
153 * [Connect](http://www.senchalabs.org/connect/) for NodeJS.
154 * Read [this great write-up](http://howtonode.org/connect-it) to understand
155 the overall philosophy of all of these models.
156 * [Rack](http://rack.github.io/) for Ruby.
157 * [WSGI](http://legacy.python.org/dev/peps/pep-3333/) for Python.
OLDNEW
« no previous file with comments | « mojo/public/dart/third_party/shelf/LICENSE ('k') | mojo/public/dart/third_party/shelf/codereview.settings » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698