Response detachment test
This commit is contained in:
parent
be521dcd7f
commit
a212bab74f
3 changed files with 44 additions and 7 deletions
|
@ -79,7 +79,10 @@ abstract class ResponseContext<RawResponse>
|
|||
_statusCode = value ?? 200;
|
||||
}
|
||||
|
||||
/// Can we still write to this response?
|
||||
/// Returns `true` if the response is still available for processing by Angel.
|
||||
///
|
||||
/// If it is `false`, then Angel will stop executing handlers, and will only run
|
||||
/// response finalizers if the response [isBuffered].
|
||||
bool get isOpen;
|
||||
|
||||
/// Returns `true` if response data is being written to a buffer, rather than to the underlying stream.
|
||||
|
@ -92,10 +95,10 @@ abstract class ResponseContext<RawResponse>
|
|||
RawResponse get rawResponse;
|
||||
|
||||
/// Signals Angel that the response is being held alive deliberately, and that the framework should not automatically close it.
|
||||
///
|
||||
///
|
||||
/// This is mostly used in situations like WebSocket handlers, where the connection should remain
|
||||
/// open indefinitely.
|
||||
RawResponse detach();
|
||||
FutureOr<RawResponse> detach();
|
||||
|
||||
/// Gets or sets the content type to send back to a client.
|
||||
MediaType contentType = new MediaType('text', 'plain');
|
||||
|
|
|
@ -15,13 +15,13 @@ class HttpResponseContext extends ResponseContext<HttpResponse> {
|
|||
LockableBytesBuilder _buffer;
|
||||
|
||||
final HttpRequestContext _correspondingRequest;
|
||||
bool _detached = false, _isClosed = false, _streamInitialized = false;
|
||||
bool _isDetached = false, _isClosed = false, _streamInitialized = false;
|
||||
|
||||
HttpResponseContext(this.rawResponse, this.app, [this._correspondingRequest]);
|
||||
|
||||
@override
|
||||
HttpResponse detach() {
|
||||
_detached = true;
|
||||
_isDetached = true;
|
||||
return rawResponse;
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@ class HttpResponseContext extends ResponseContext<HttpResponse> {
|
|||
|
||||
@override
|
||||
bool get isOpen {
|
||||
return !_isClosed;
|
||||
return !_isClosed && !_isDetached;
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -172,7 +172,7 @@ class HttpResponseContext extends ResponseContext<HttpResponse> {
|
|||
|
||||
@override
|
||||
Future close() {
|
||||
if (!_detached) {
|
||||
if (!_isDetached) {
|
||||
if (!_isClosed) {
|
||||
if (!isBuffered) {
|
||||
try {
|
||||
|
|
34
test/detach_test.dart
Normal file
34
test/detach_test.dart
Normal file
|
@ -0,0 +1,34 @@
|
|||
import 'dart:convert';
|
||||
import 'package:angel_framework/angel_framework.dart';
|
||||
import 'package:mock_request/mock_request.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
AngelHttp http;
|
||||
|
||||
setUp(() async {
|
||||
var app = new Angel();
|
||||
http = new AngelHttp(app);
|
||||
|
||||
app.get('/detach', (req, res) async {
|
||||
if (res is HttpResponseContext) {
|
||||
var io = await res.detach();
|
||||
io
|
||||
..write('Hey!')
|
||||
..close();
|
||||
} else {
|
||||
throw new StateError('This endpoint only supports HTTP/1.1.');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
tearDown(() => http.close());
|
||||
|
||||
test('detach response', () async {
|
||||
var rq = new MockHttpRequest('GET', Uri.parse('/detach'))..close();
|
||||
var rs = rq.response;
|
||||
await http.handleRequest(rq);
|
||||
var body = await rs.transform(utf8.decoder).join();
|
||||
expect(body, 'Hey!');
|
||||
});
|
||||
}
|
Loading…
Reference in a new issue