| 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 library shelf.request; | 5 library shelf.request; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:convert'; |
| 8 | 9 |
| 9 import 'package:http_parser/http_parser.dart'; | 10 import 'package:http_parser/http_parser.dart'; |
| 10 | 11 |
| 11 import 'hijack_exception.dart'; | 12 import 'hijack_exception.dart'; |
| 12 import 'message.dart'; | 13 import 'message.dart'; |
| 13 import 'util.dart'; | 14 import 'util.dart'; |
| 14 | 15 |
| 15 /// A callback provided by a Shelf handler that's passed to [Request.hijack]. | 16 /// A callback provided by a Shelf handler that's passed to [Request.hijack]. |
| 16 typedef void HijackCallback( | 17 typedef void HijackCallback( |
| 17 Stream<List<int>> stream, StreamSink<List<int>> sink); | 18 Stream<List<int>> stream, StreamSink<List<int>> sink); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 81 DateTime _ifModifiedSinceCache; | 82 DateTime _ifModifiedSinceCache; |
| 82 | 83 |
| 83 /// Creates a new [Request]. | 84 /// Creates a new [Request]. |
| 84 /// | 85 /// |
| 85 /// If [url] and [scriptName] are omitted, they are inferred from | 86 /// If [url] and [scriptName] are omitted, they are inferred from |
| 86 /// [requestedUri]. | 87 /// [requestedUri]. |
| 87 /// | 88 /// |
| 88 /// Setting one of [url] or [scriptName] and not the other will throw an | 89 /// Setting one of [url] or [scriptName] and not the other will throw an |
| 89 /// [ArgumentError]. | 90 /// [ArgumentError]. |
| 90 /// | 91 /// |
| 92 /// [body] is the request body. It may be either a [String], a |
| 93 /// [Stream<List<int>>], or `null` to indicate no body. |
| 94 /// If it's a [String], [encoding] is used to encode it to a |
| 95 /// [Stream<List<int>>]. The default encoding is UTF-8. |
| 96 /// |
| 97 /// If [encoding] is passed, the "encoding" field of the Content-Type header |
| 98 /// in [headers] will be set appropriately. If there is no existing |
| 99 /// Content-Type header, it will be set to "application/octet-stream". |
| 100 /// |
| 91 /// The default value for [protocolVersion] is '1.1'. | 101 /// The default value for [protocolVersion] is '1.1'. |
| 92 /// | 102 /// |
| 93 /// ## `onHijack` | 103 /// ## `onHijack` |
| 94 /// | 104 /// |
| 95 /// [onHijack] allows handlers to take control of the underlying socket for | 105 /// [onHijack] allows handlers to take control of the underlying socket for |
| 96 /// the request. It should be passed by adapters that can provide access to | 106 /// the request. It should be passed by adapters that can provide access to |
| 97 /// the bidirectional socket underlying the HTTP connection stream. | 107 /// the bidirectional socket underlying the HTTP connection stream. |
| 98 /// | 108 /// |
| 99 /// The [onHijack] callback will only be called once per request. It will be | 109 /// The [onHijack] callback will only be called once per request. It will be |
| 100 /// passed another callback which takes a byte stream and a byte sink. | 110 /// passed another callback which takes a byte stream and a byte sink. |
| 101 /// [onHijack] must pass the stream and sink for the connection stream to this | 111 /// [onHijack] must pass the stream and sink for the connection stream to this |
| 102 /// callback, although it may do so asynchronously. Both parameters may be the | 112 /// callback, although it may do so asynchronously. Both parameters may be the |
| 103 /// same object. If the user closes the sink, the adapter should ensure that | 113 /// same object. If the user closes the sink, the adapter should ensure that |
| 104 /// the stream is closed as well. | 114 /// the stream is closed as well. |
| 105 /// | 115 /// |
| 106 /// If a request is hijacked, the adapter should expect to receive a | 116 /// If a request is hijacked, the adapter should expect to receive a |
| 107 /// [HijackException] from the handler. This is a special exception used to | 117 /// [HijackException] from the handler. This is a special exception used to |
| 108 /// indicate that hijacking has occurred. The adapter should avoid either | 118 /// indicate that hijacking has occurred. The adapter should avoid either |
| 109 /// sending a response or notifying the user of an error if a | 119 /// sending a response or notifying the user of an error if a |
| 110 /// [HijackException] is caught. | 120 /// [HijackException] is caught. |
| 111 /// | 121 /// |
| 112 /// An adapter can check whether a request was hijacked using [canHijack], | 122 /// An adapter can check whether a request was hijacked using [canHijack], |
| 113 /// which will be `false` for a hijacked request. The adapter may throw an | 123 /// which will be `false` for a hijacked request. The adapter may throw an |
| 114 /// error if a [HijackException] is received for a non-hijacked request, or if | 124 /// error if a [HijackException] is received for a non-hijacked request, or if |
| 115 /// no [HijackException] is received for a hijacked request. | 125 /// no [HijackException] is received for a hijacked request. |
| 116 /// | 126 /// |
| 117 /// See also [hijack]. | 127 /// See also [hijack]. |
| 118 // TODO(kevmoo) finish documenting the rest of the arguments. | 128 // TODO(kevmoo) finish documenting the rest of the arguments. |
| 119 Request(String method, Uri requestedUri, {String protocolVersion, | 129 Request(String method, Uri requestedUri, {String protocolVersion, |
| 120 Map<String, String> headers, Uri url, String scriptName, | 130 Map<String, String> headers, Uri url, String scriptName, body, |
| 121 Stream<List<int>> body, Map<String, Object> context, | 131 Encoding encoding, Map<String, Object> context, |
| 122 OnHijackCallback onHijack}) | 132 OnHijackCallback onHijack}) |
| 123 : this._(method, requestedUri, | 133 : this._(method, requestedUri, |
| 124 protocolVersion: protocolVersion, | 134 protocolVersion: protocolVersion, |
| 125 headers: headers, | 135 headers: headers, |
| 126 url: url, | 136 url: url, |
| 127 scriptName: scriptName, | 137 scriptName: scriptName, |
| 128 body: body, | 138 body: body, |
| 139 encoding: encoding, |
| 129 context: context, | 140 context: context, |
| 130 onHijack: onHijack == null ? null : new _OnHijack(onHijack)); | 141 onHijack: onHijack == null ? null : new _OnHijack(onHijack)); |
| 131 | 142 |
| 132 /// This constructor has the same signature as [new Request] except that | 143 /// This constructor has the same signature as [new Request] except that |
| 133 /// accepts [onHijack] as [_OnHijack]. | 144 /// accepts [onHijack] as [_OnHijack]. |
| 134 /// | 145 /// |
| 135 /// Any [Request] created by calling [change] will pass [_onHijack] from the | 146 /// Any [Request] created by calling [change] will pass [_onHijack] from the |
| 136 /// source [Request] to ensure that [hijack] can only be called once, even | 147 /// source [Request] to ensure that [hijack] can only be called once, even |
| 137 /// from a changed [Request]. | 148 /// from a changed [Request]. |
| 138 Request._(this.method, Uri requestedUri, {String protocolVersion, | 149 Request._(this.method, Uri requestedUri, {String protocolVersion, |
| 139 Map<String, String> headers, Uri url, String scriptName, | 150 Map<String, String> headers, Uri url, String scriptName, body, |
| 140 Stream<List<int>> body, Map<String, Object> context, _OnHijack onHijack}) | 151 Encoding encoding, Map<String, Object> context, _OnHijack onHijack}) |
| 141 : this.requestedUri = requestedUri, | 152 : this.requestedUri = requestedUri, |
| 142 this.protocolVersion = protocolVersion == null | 153 this.protocolVersion = protocolVersion == null |
| 143 ? '1.1' | 154 ? '1.1' |
| 144 : protocolVersion, | 155 : protocolVersion, |
| 145 this.url = _computeUrl(requestedUri, url, scriptName), | 156 this.url = _computeUrl(requestedUri, url, scriptName), |
| 146 this.scriptName = _computeScriptName(requestedUri, url, scriptName), | 157 this.scriptName = _computeScriptName(requestedUri, url, scriptName), |
| 147 this._onHijack = onHijack, | 158 this._onHijack = onHijack, |
| 148 super(body == null ? new Stream.fromIterable([]) : body, | 159 super(body, encoding: encoding, headers: headers, context: context) { |
| 149 headers: headers, context: context) { | |
| 150 if (method.isEmpty) throw new ArgumentError('method cannot be empty.'); | 160 if (method.isEmpty) throw new ArgumentError('method cannot be empty.'); |
| 151 | 161 |
| 152 if (!requestedUri.isAbsolute) { | 162 if (!requestedUri.isAbsolute) { |
| 153 throw new ArgumentError('requstedUri must be an absolute URI.'); | 163 throw new ArgumentError('requstedUri must be an absolute URI.'); |
| 154 } | 164 } |
| 155 | 165 |
| 156 // TODO(kevmoo) if defined, check that scriptName is a fully-encoded, valid | 166 // TODO(kevmoo) if defined, check that scriptName is a fully-encoded, valid |
| 157 // path component | 167 // path component |
| 158 if (this.scriptName.isNotEmpty && !this.scriptName.startsWith('/')) { | 168 if (this.scriptName.isNotEmpty && !this.scriptName.startsWith('/')) { |
| 159 throw new ArgumentError('scriptName must be empty or start with "/".'); | 169 throw new ArgumentError('scriptName must be empty or start with "/".'); |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 303 return ''; | 313 return ''; |
| 304 } | 314 } |
| 305 | 315 |
| 306 if (url != null && scriptName != null) { | 316 if (url != null && scriptName != null) { |
| 307 return scriptName; | 317 return scriptName; |
| 308 } | 318 } |
| 309 | 319 |
| 310 throw new ArgumentError( | 320 throw new ArgumentError( |
| 311 'url and scriptName must both be null or both be set.'); | 321 'url and scriptName must both be null or both be set.'); |
| 312 } | 322 } |
| OLD | NEW |