OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 import 'dart:async'; | 5 import 'dart:async'; |
6 import 'dart:convert'; | 6 import 'dart:convert'; |
7 | 7 |
8 import 'package:http_parser/http_parser.dart'; | 8 import 'package:http_parser/http_parser.dart'; |
| 9 import 'package:stream_channel/stream_channel.dart'; |
9 | 10 |
10 import 'hijack_exception.dart'; | 11 import 'hijack_exception.dart'; |
11 import 'message.dart'; | 12 import 'message.dart'; |
12 import 'util.dart'; | 13 import 'util.dart'; |
13 | 14 |
14 /// A callback provided by a Shelf handler that's passed to [Request.hijack]. | 15 /// A callback provided by a Shelf handler that's passed to [Request.hijack]. |
| 16 @Deprecated("Will be removed in shelf 0.7.0.") |
15 typedef void HijackCallback( | 17 typedef void HijackCallback( |
16 Stream<List<int>> stream, StreamSink<List<int>> sink); | 18 Stream<List<int>> stream, StreamSink<List<int>> sink); |
17 | 19 |
18 /// A callback provided by a Shelf adapter that's used by [Request.hijack] to | 20 /// A callback provided by a Shelf adapter that's used by [Request.hijack] to |
19 /// provide a [HijackCallback] with a socket. | 21 /// provide a [HijackCallback] with a socket. |
| 22 @Deprecated("Will be removed in shelf 0.7.0.") |
20 typedef void OnHijackCallback(HijackCallback callback); | 23 typedef void OnHijackCallback(HijackCallback callback); |
21 | 24 |
22 /// Represents an HTTP request to be processed by a Shelf application. | 25 /// Represents an HTTP request to be processed by a Shelf application. |
23 class Request extends Message { | 26 class Request extends Message { |
24 /// The URL path from the current handler to the requested resource, relative | 27 /// The URL path from the current handler to the requested resource, relative |
25 /// to [handlerPath], plus any query parameters. | 28 /// to [handlerPath], plus any query parameters. |
26 /// | 29 /// |
27 /// This should be used by handlers for determining which resource to serve, | 30 /// This should be used by handlers for determining which resource to serve, |
28 /// in preference to [requestedUri]. This allows handlers to do the right | 31 /// in preference to [requestedUri]. This allows handlers to do the right |
29 /// thing when they're mounted anywhere in the application. Routers should be | 32 /// thing when they're mounted anywhere in the application. Routers should be |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 /// An adapter can check whether a request was hijacked using [canHijack], | 129 /// An adapter can check whether a request was hijacked using [canHijack], |
127 /// which will be `false` for a hijacked request. The adapter may throw an | 130 /// which will be `false` for a hijacked request. The adapter may throw an |
128 /// error if a [HijackException] is received for a non-hijacked request, or if | 131 /// error if a [HijackException] is received for a non-hijacked request, or if |
129 /// no [HijackException] is received for a hijacked request. | 132 /// no [HijackException] is received for a hijacked request. |
130 /// | 133 /// |
131 /// See also [hijack]. | 134 /// See also [hijack]. |
132 // TODO(kevmoo) finish documenting the rest of the arguments. | 135 // TODO(kevmoo) finish documenting the rest of the arguments. |
133 Request(String method, Uri requestedUri, {String protocolVersion, | 136 Request(String method, Uri requestedUri, {String protocolVersion, |
134 Map<String, String> headers, String handlerPath, Uri url, body, | 137 Map<String, String> headers, String handlerPath, Uri url, body, |
135 Encoding encoding, Map<String, Object> context, | 138 Encoding encoding, Map<String, Object> context, |
136 OnHijackCallback onHijack}) | 139 void onHijack(void hijack( |
| 140 Stream<List<int>> stream, StreamSink<List<int>> sink))}) |
137 : this._(method, requestedUri, | 141 : this._(method, requestedUri, |
138 protocolVersion: protocolVersion, | 142 protocolVersion: protocolVersion, |
139 headers: headers, | 143 headers: headers, |
140 url: url, | 144 url: url, |
141 handlerPath: handlerPath, | 145 handlerPath: handlerPath, |
142 body: body, | 146 body: body, |
143 encoding: encoding, | 147 encoding: encoding, |
144 context: context, | 148 context: context, |
145 onHijack: onHijack == null ? null : new _OnHijack(onHijack)); | 149 onHijack: onHijack == null ? null : new _OnHijack(onHijack)); |
146 | 150 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 handlerPath: handlerPath, | 223 handlerPath: handlerPath, |
220 body: body, | 224 body: body, |
221 context: context, | 225 context: context, |
222 onHijack: _onHijack); | 226 onHijack: _onHijack); |
223 } | 227 } |
224 | 228 |
225 /// Takes control of the underlying request socket. | 229 /// Takes control of the underlying request socket. |
226 /// | 230 /// |
227 /// Synchronously, this throws a [HijackException] that indicates to the | 231 /// Synchronously, this throws a [HijackException] that indicates to the |
228 /// adapter that it shouldn't emit a response itself. Asynchronously, | 232 /// adapter that it shouldn't emit a response itself. Asynchronously, |
229 /// [callback] is called with a [Stream<List<int>>] and | 233 /// [callback] is called with a [StreamChannel<List<int>>] that provides |
230 /// [StreamSink<List<int>>], respectively, that provide access to the | 234 /// access to the underlying request socket. |
231 /// underlying request socket. | |
232 /// | 235 /// |
233 /// If the sink is closed, the stream will be closed as well. The stream and | 236 /// For backwards compatibility, if the callback takes two arguments, it will |
234 /// sink may be the same object, as in the case of a `dart:io` `Socket` | 237 /// be passed a `Stream<List<int>>` and a `StreamSink<List<int>>` separately, |
235 /// object. | 238 /// but this behavior is deprecated. |
236 /// | 239 /// |
237 /// This may only be called when using a Shelf adapter that supports | 240 /// This may only be called when using a Shelf adapter that supports |
238 /// hijacking, such as the `dart:io` adapter. In addition, a given request may | 241 /// hijacking, such as the `dart:io` adapter. In addition, a given request may |
239 /// only be hijacked once. [canHijack] can be used to detect whether this | 242 /// only be hijacked once. [canHijack] can be used to detect whether this |
240 /// request can be hijacked. | 243 /// request can be hijacked. |
241 void hijack(HijackCallback callback) { | 244 void hijack(Function callback) { |
242 if (_onHijack == null) { | 245 if (_onHijack == null) { |
243 throw new StateError("This request can't be hijacked."); | 246 throw new StateError("This request can't be hijacked."); |
244 } | 247 } |
245 | 248 |
| 249 if (callback is ZoneUnaryCallback) { |
| 250 var oldCallback = callback; |
| 251 callback = (stream, sink) { |
| 252 oldCallback(new StreamChannel<List<int>>(stream, sink)); |
| 253 }; |
| 254 } |
| 255 |
246 _onHijack.run(callback); | 256 _onHijack.run(callback); |
247 throw const HijackException(); | 257 throw const HijackException(); |
248 } | 258 } |
249 } | 259 } |
250 | 260 |
251 /// A class containing a callback for [Request.hijack] that also tracks whether | 261 /// A class containing a callback for [Request.hijack] that also tracks whether |
252 /// the callback has been called. | 262 /// the callback has been called. |
253 class _OnHijack { | 263 class _OnHijack { |
254 /// The callback. | 264 /// The callback. |
255 final OnHijackCallback _callback; | 265 final OnHijackCallback _callback; |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
344 return handlerPath; | 354 return handlerPath; |
345 } else if (url != null) { | 355 } else if (url != null) { |
346 if (url.path.isEmpty) return requestedUri.path; | 356 if (url.path.isEmpty) return requestedUri.path; |
347 | 357 |
348 var index = requestedUri.path.indexOf(url.path); | 358 var index = requestedUri.path.indexOf(url.path); |
349 return requestedUri.path.substring(0, index); | 359 return requestedUri.path.substring(0, index); |
350 } else { | 360 } else { |
351 return '/'; | 361 return '/'; |
352 } | 362 } |
353 } | 363 } |
OLD | NEW |