Add support for controlling HttpResponse.bufferOutput to shelf_io.
Closes #7
R=kevmoo@google.com
Review URL: https://codereview.chromium.org//1037483002
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 24d9ba1..e66a474 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,9 @@
## 0.6.1
-** Fixed spelling errors in README and code comments.
+* `shelf_io` now takes a `"shelf.io.buffer_output"` `Response.context` parameter
+ that controls `HttpResponse.bufferOutput`.
+
+* Fixed spelling errors in README and code comments.
## 0.6.0
diff --git a/lib/shelf_io.dart b/lib/shelf_io.dart
index 4ca48b6..301050f 100644
--- a/lib/shelf_io.dart
+++ b/lib/shelf_io.dart
@@ -7,7 +7,14 @@
/// One can provide an instance of [HttpServer] as the `requests` parameter in
/// [serveRequests].
///
-/// The `dart:io` adapter supports request hijacking; see [Request.hijack].
+/// This adapter supports request hijacking; see [Request.hijack]. It also
+/// supports the `"shelf.io.buffer_output"` `Response.context` property. If this
+/// property is `true` (the default), streamed responses will be buffered to
+/// improve performance; if it's `false`, all chunks will be pushed over the
+/// wire as they're received. See [`HttpResponse.bufferOutput`][bufferOutput]
+/// for more information.
+///
+/// [bufferOutput]: https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/dart:io.HttpResponse#id_bufferOutput
library shelf.io;
import 'dart:async';
@@ -78,17 +85,17 @@
}).then((response) {
if (response == null) {
response = _logError('null response from handler.');
- } else if (!shelfRequest.canHijack) {
- var message = new StringBuffer()
- ..writeln("Got a response for hijacked request "
- "${shelfRequest.method} ${shelfRequest.requestedUri}:")
- ..writeln(response.statusCode);
- response.headers
- .forEach((key, value) => message.writeln("${key}: ${value}"));
- throw new Exception(message.toString().trim());
+ } else if (shelfRequest.canHijack) {
+ return _writeResponse(response, request.response);
}
- return _writeResponse(response, request.response);
+ var message = new StringBuffer()
+ ..writeln("Got a response for hijacked request "
+ "${shelfRequest.method} ${shelfRequest.requestedUri}:")
+ ..writeln(response.statusCode);
+ response.headers
+ .forEach((key, value) => message.writeln("${key}: ${value}"));
+ throw new Exception(message.toString().trim());
}).catchError((error, stackTrace) {
// Ignore HijackExceptions.
if (error is! HijackException) throw error;
@@ -118,6 +125,10 @@
}
Future _writeResponse(Response response, HttpResponse httpResponse) {
+ if (response.context.containsKey("shelf.io.buffer_output")) {
+ httpResponse.bufferOutput = response.context["shelf.io.buffer_output"];
+ }
+
httpResponse.statusCode = response.statusCode;
response.headers.forEach((header, value) {
diff --git a/pubspec.yaml b/pubspec.yaml
index 5d0e402..0a94fe4 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
name: shelf
-version: 0.6.1-dev
+version: 0.6.1
author: Dart Team <misc@dartlang.org>
description: Web Server Middleware for Dart
homepage: https://github.com/dart-lang/shelf
diff --git a/test/shelf_io_test.dart b/test/shelf_io_test.dart
index 586a961..11c5b7c 100644
--- a/test/shelf_io_test.dart
+++ b/test/shelf_io_test.dart
@@ -10,6 +10,7 @@
import 'package:http/http.dart' as http;
import 'package:http_parser/http_parser.dart' as parser;
+import 'package:scheduled_test/scheduled_stream.dart';
import 'package:scheduled_test/scheduled_test.dart';
import 'package:shelf/shelf.dart';
import 'package:shelf/shelf_io.dart' as shelf_io;
@@ -331,6 +332,35 @@
});
});
});
+
+ test('respects the "shelf.io.buffer_output" context parameter', () {
+ var controller = new StreamController();
+ _scheduleServer((request) {
+ controller.add("Hello, ");
+
+ return new Response.ok(UTF8.encoder.bind(controller.stream),
+ context: {"shelf.io.buffer_output": false});
+ });
+
+ schedule(() {
+ var request = new http.Request(
+ "GET", Uri.parse('http://localhost:$_serverPort/'));
+
+ return request.send().then((response) {
+ var stream = new ScheduledStream(UTF8.decoder.bind(response.stream));
+
+ return stream.next().then((data) {
+ expect(data, equals("Hello, "));
+ controller.add("world!");
+ return stream.next();
+ }).then((data) {
+ expect(data, equals("world!"));
+ controller.close();
+ expect(stream.hasNext, completion(isFalse));
+ });
+ });
+ });
+ });
}
int _serverPort;