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 |