| OLD | NEW |
| 1 ## Web Server Middleware for Dart | 1 ## Web Server Middleware for Dart |
| 2 | 2 |
| 3 [](https
://travis-ci.org/dart-lang/shelf) | 3 [](https
://travis-ci.org/dart-lang/shelf) |
| 4 [](https://coveralls.io/r/dart-lang/shelf?branch=travis_coveralls) | 4 [](https://coveralls.io/r/dart-lang/shelf?branch=travis_coveralls) |
| 5 | 5 |
| 6 ## Introduction | 6 ## Introduction |
| 7 | 7 |
| 8 **Shelf** makes it easy to create and compose **web servers** and **parts of web | 8 **Shelf** makes it easy to create and compose **web servers** and **parts of web |
| 9 servers**. How? | 9 servers**. How? |
| 10 | 10 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 | 59 |
| 60 [middleware]: http://www.dartdocs.org/documentation/shelf/latest/index.html#shel
f/shelf@id_Middleware | 60 [middleware]: http://www.dartdocs.org/documentation/shelf/latest/index.html#shel
f/shelf@id_Middleware |
| 61 | 61 |
| 62 [shelf.Pipeline]: http://www.dartdocs.org/documentation/shelf/latest/index.html
#shelf/shelf.Pipeline | 62 [shelf.Pipeline]: http://www.dartdocs.org/documentation/shelf/latest/index.html
#shelf/shelf.Pipeline |
| 63 | 63 |
| 64 Some middleware can also take multiple handlers and call one or more of them for | 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 | 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 | 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. | 67 might call each one in sequence until one returns a successful response. |
| 68 | 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 |
| 69 ## Adapters | 90 ## Adapters |
| 70 | 91 |
| 71 An adapter is any code that creates [shelf.Request][] objects, passes them to a | 92 An adapter is any code that creates [shelf.Request][] objects, passes them to a |
| 72 handler, and deals with the resulting [shelf.Response][]. For the most part, | 93 handler, and deals with the resulting [shelf.Response][]. For the most part, |
| 73 adapters forward requests from and responses to an underlying HTTP server; | 94 adapters forward requests from and responses to an underlying HTTP server; |
| 74 [shelf_io.serve][] is this sort of adapter. An adapter might also synthesize | 95 [shelf_io.serve][] is this sort of adapter. An adapter might also synthesize |
| 75 HTTP requests within the browser using `window.location` and `window.history`, | 96 HTTP requests within the browser using `window.location` and `window.history`, |
| 76 or it might pipe requests directly from an HTTP client to a Shelf handler. | 97 or it might pipe requests directly from an HTTP client to a Shelf handler. |
| 77 | 98 |
| 78 [shelf_io.serve]: http://www.dartdocs.org/documentation/shelf/latest/index.html#
shelf/shelf-io@id_serve | 99 [shelf_io.serve]: http://www.dartdocs.org/documentation/shelf/latest/index.html#
shelf/shelf-io@id_serve |
| 79 | 100 |
| 80 When implementing an adapter, some rules must be followed. The adapter must not | 101 When implementing an adapter, some rules must be followed. The adapter must not |
| 81 pass the `url` or `scriptName` parameters to [new shelf.Request][]; it should | 102 pass the `url` or `handlerPath` parameters to [new shelf.Request][]; it should |
| 82 only pass `requestedUri`. If it passes the `context` parameter, all keys must | 103 only pass `requestedUri`. If it passes the `context` parameter, all keys must |
| 83 begin with the adapter's package name followed by a period. If multiple headers | 104 begin with the adapter's package name followed by a period. If multiple headers |
| 84 with the same name are received, the adapter must collapse them into a single | 105 with the same name are received, the adapter must collapse them into a single |
| 85 header separated by commas as per [RFC 2616 section 4.2][]. | 106 header separated by commas as per [RFC 2616 section 4.2][]. |
| 86 | 107 |
| 87 [new shelf.Request]: http://www.dartdocs.org/documentation/shelf/latest/index.ht
ml#shelf/shelf.Request@id_Request- | 108 [new shelf.Request]: http://www.dartdocs.org/documentation/shelf/latest/index.ht
ml#shelf/shelf.Request@id_Request- |
| 88 | 109 |
| 89 [RFC 2616 section 4.2]: http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html | 110 [RFC 2616 section 4.2]: http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html |
| 90 | 111 |
| 91 An adapter must handle all errors from the handler, including the handler | 112 An adapter must handle all errors from the handler, including the handler |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 127 } | 148 } |
| 128 ``` | 149 ``` |
| 129 | 150 |
| 130 ## Inspiration | 151 ## Inspiration |
| 131 | 152 |
| 132 * [Connect](http://www.senchalabs.org/connect/) for NodeJS. | 153 * [Connect](http://www.senchalabs.org/connect/) for NodeJS. |
| 133 * Read [this great write-up](http://howtonode.org/connect-it) to understand | 154 * Read [this great write-up](http://howtonode.org/connect-it) to understand |
| 134 the overall philosophy of all of these models. | 155 the overall philosophy of all of these models. |
| 135 * [Rack](http://rack.github.io/) for Ruby. | 156 * [Rack](http://rack.github.io/) for Ruby. |
| 136 * [WSGI](http://legacy.python.org/dev/peps/pep-3333/) for Python. | 157 * [WSGI](http://legacy.python.org/dev/peps/pep-3333/) for Python. |
| OLD | NEW |