Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(267)

Unified Diff: pkg/shelf/lib/shelf_io.dart

Issue 260933004: Support Request hijacking in Shelf, using a similar API to Rack. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: code review Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/shelf/lib/shelf.dart ('k') | pkg/shelf/lib/src/handlers/logger.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/shelf/lib/shelf_io.dart
diff --git a/pkg/shelf/lib/shelf_io.dart b/pkg/shelf/lib/shelf_io.dart
index 1bd4f5164def2a8d6d6dd6b390bf8087d0141355..d8d4d9ca3175e9b0cfea38c36302eeee00bfeb22 100644
--- a/pkg/shelf/lib/shelf_io.dart
+++ b/pkg/shelf/lib/shelf_io.dart
@@ -6,6 +6,8 @@
///
/// One can provide an instance of [HttpServer] as the `requests` parameter in
/// [serveRequests].
+///
+/// The `dart:io` adapter supports request hijacking; see [Request.hijack].
library shelf.io;
import 'dart:async';
@@ -53,15 +55,38 @@ void serveRequests(Stream<HttpRequest> requests, Handler handler) {
Future handleRequest(HttpRequest request, Handler handler) {
var shelfRequest = _fromHttpRequest(request);
+ // TODO(nweiz): abstract out hijack handling to make it easier to implement an
+ // adapter.
return syncFuture(() => handler(shelfRequest))
.catchError((error, stackTrace) {
- return _logError('Error thrown by handler\n$error', stackTrace);
+ if (error is HijackException) {
+ // A HijackException should bypass the response-writing logic entirely.
+ if (!shelfRequest.canHijack) throw error;
+
+ // If the request wasn't hijacked, we shouldn't be seeing this exception.
+ return _logError(
+ "Caught HijackException, but the request wasn't hijacked.",
+ stackTrace);
+ }
+
+ return _logError('Error thrown by handler.\n$error', stackTrace);
}).then((response) {
if (response == null) {
- response = _logError('null response from handler');
+ 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());
}
return _writeResponse(response, request.response);
+ }).catchError((error, stackTrace) {
+ // Ignore HijackExceptions.
+ if (error is! HijackException) throw error;
});
}
@@ -74,9 +99,14 @@ Request _fromHttpRequest(HttpRequest request) {
headers[k] = v.join(',');
});
+ onHijack(callback) {
+ return request.response.detachSocket(writeHeaders: false)
+ .then((socket) => callback(socket, socket));
+ }
+
return new Request(request.method, request.requestedUri,
protocolVersion: request.protocolVersion, headers: headers,
- body: request);
+ body: request, onHijack: onHijack);
}
Future _writeResponse(Response response, HttpResponse httpResponse) {
« no previous file with comments | « pkg/shelf/lib/shelf.dart ('k') | pkg/shelf/lib/src/handlers/logger.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698