| OLD | NEW |
| 1 ## Web Server Middleware for Dart | 1 ## Web Server Middleware for Dart |
| 2 | 2 |
| 3 ## Introduction | 3 ## Introduction |
| 4 | 4 |
| 5 **Shelf** makes it easy to create and compose **web servers** and **parts of web | 5 **Shelf** makes it easy to create and compose **web servers** and **parts of web |
| 6 servers**. How? | 6 servers**. How? |
| 7 | 7 |
| 8 * Expose a small set of simple types. | 8 * Expose a small set of simple types. |
| 9 * Map server logic into a simple function: a single argument for the request, | 9 * Map server logic into a simple function: a single argument for the request, |
| 10 the response is the return value. | 10 the response is the return value. |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 may include body data for the 500 response, but this body data must not include | 91 may include body data for the 500 response, but this body data must not include |
| 92 information about the error that occurred. This ensures that unexpected errors | 92 information about the error that occurred. This ensures that unexpected errors |
| 93 don't result in exposing internal information in production by default; if the | 93 don't result in exposing internal information in production by default; if the |
| 94 user wants to return detailed error descriptions, they should explicitly include | 94 user wants to return detailed error descriptions, they should explicitly include |
| 95 middleware to do so. | 95 middleware to do so. |
| 96 | 96 |
| 97 An adapter should include information about itself in the Server header of the | 97 An adapter should include information about itself in the Server header of the |
| 98 response by default. If the handler returns a response with the Server header | 98 response by default. If the handler returns a response with the Server header |
| 99 set, that must take precedence over the adapter's default header. | 99 set, that must take precedence over the adapter's default header. |
| 100 | 100 |
| 101 An adapter should include the Date header with the time the handler returns a |
| 102 response. If the handler returns a response with the Date header set, that must |
| 103 take precedence. |
| 104 |
| 101 An adapter should ensure that asynchronous errors thrown by the handler don't | 105 An adapter should ensure that asynchronous errors thrown by the handler don't |
| 102 cause the application to crash, even if they aren't reported by the future | 106 cause the application to crash, even if they aren't reported by the future |
| 103 chain. Specifically, these errors shouldn't be passed to the root zone's error | 107 chain. Specifically, these errors shouldn't be passed to the root zone's error |
| 104 handler; however, if the adapter is run within another error zone, it should | 108 handler; however, if the adapter is run within another error zone, it should |
| 105 allow these errors to be passed to that zone. The following function can be used | 109 allow these errors to be passed to that zone. The following function can be used |
| 106 to capture only errors that would otherwise be top-leveled: | 110 to capture only errors that would otherwise be top-leveled: |
| 107 | 111 |
| 108 ```dart | 112 ```dart |
| 109 /// Run [callback] and capture any errors that would otherwise be top-leveled. | 113 /// Run [callback] and capture any errors that would otherwise be top-leveled. |
| 110 /// | 114 /// |
| 111 /// If [this] is called in a non-root error zone, it will just run [callback] | 115 /// If [this] is called in a non-root error zone, it will just run [callback] |
| 112 /// and return the result. Otherwise, it will capture any errors using | 116 /// and return the result. Otherwise, it will capture any errors using |
| 113 /// [runZoned] and pass them to [onError]. | 117 /// [runZoned] and pass them to [onError]. |
| 114 catchTopLevelErrors(callback(), void onError(error, StackTrace stackTrace)) { | 118 catchTopLevelErrors(callback(), void onError(error, StackTrace stackTrace)) { |
| 115 if (Zone.current.inSameErrorZone(Zone.ROOT)) { | 119 if (Zone.current.inSameErrorZone(Zone.ROOT)) { |
| 116 return runZoned(callback, onError: onError); | 120 return runZoned(callback, onError: onError); |
| 117 } else { | 121 } else { |
| 118 return callback(); | 122 return callback(); |
| 119 } | 123 } |
| 120 } | 124 } |
| 121 ``` | 125 ``` |
| 122 | 126 |
| 123 ## Inspiration | 127 ## Inspiration |
| 124 | 128 |
| 125 * [Connect](http://www.senchalabs.org/connect/) for NodeJS. | 129 * [Connect](http://www.senchalabs.org/connect/) for NodeJS. |
| 126 * Read [this great write-up](http://howtonode.org/connect-it) to understand | 130 * Read [this great write-up](http://howtonode.org/connect-it) to understand |
| 127 the overall philosophy of all of these models. | 131 the overall philosophy of all of these models. |
| 128 * [Rack](http://rack.github.io/) for Ruby. | 132 * [Rack](http://rack.github.io/) for Ruby. |
| 129 * [WSGI](http://legacy.python.org/dev/peps/pep-3333/) for Python. | 133 * [WSGI](http://legacy.python.org/dev/peps/pep-3333/) for Python. |
| OLD | NEW |