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

Unified Diff: pkg/http_server/lib/src/virtual_directory.dart

Issue 721213002: Fix a number of issues with the Range header handling for serving files (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix test Created 6 years, 1 month 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 | « no previous file | pkg/http_server/test/http_mock.dart » ('j') | pkg/http_server/test/http_mock.dart » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/http_server/lib/src/virtual_directory.dart
diff --git a/pkg/http_server/lib/src/virtual_directory.dart b/pkg/http_server/lib/src/virtual_directory.dart
index 6dfec5d9124d7644a9e4479edcf331e0833a7754..7ed4db80edebcc3ae5d01207161c3a44ed7a619d 100644
--- a/pkg/http_server/lib/src/virtual_directory.dart
+++ b/pkg/http_server/lib/src/virtual_directory.dart
@@ -211,44 +211,58 @@ class VirtualDirectory {
if (request.method == 'HEAD') {
response.close();
kustermann 2014/11/14 13:25:26 Maybe set the content-length header in case of HEA
Søren Gjesse 2014/11/14 15:27:29 Yes, done. Also added it for serving the whole fil
- return null;
+ return;
}
return file.length().then((length) {
- String range = request.headers.value("range");
+ String range = request.headers.value(HttpHeaders.RANGE);
if (range != null) {
Anders Johnsen 2014/11/13 16:12:31 This range handling is getting quite complicated.
Søren Gjesse 2014/11/14 15:27:29 I will postpone this to a separate CL, as I will a
// We only support one range, where the standard support several.
Match matches = new RegExp(r"^bytes=(\d*)\-(\d*)$").firstMatch(range);
// If the range header have the right format, handle it.
- if (matches != null) {
+ if (matches != null &&
+ (matches[1].isNotEmpty || matches[2].isNotEmpty)) {
// Serve sub-range.
- int start;
- int end;
+ int start; // First byte position - inclusive.
+ int end; // Last byte position - inclusive.
if (matches[1].isEmpty) {
- start = matches[2].isEmpty ?
- length :
- length - int.parse(matches[2]);
- end = length;
+ start = length - int.parse(matches[2]);
+ if (start < 0) start = 0;
+ end = length - 1;
} else {
start = int.parse(matches[1]);
- end = matches[2].isEmpty ? length : int.parse(matches[2]) + 1;
+ end = matches[2].isEmpty ? length - 1: int.parse(matches[2]);
}
+ // If the range is syntactically invalid the Range header
+ // MUST be ignored (RFC 2616 section 14.35.1).
+ if (start <= end) {
+ if (end > length) {
kustermann 2014/11/14 13:25:26 Since end is inclusive, shouldn't this be "end >=
Søren Gjesse 2014/11/14 15:27:29 Yes. Good catch. Added additional test.
+ end = length - 1;
+ }
- // Override Content-Length with the actual bytes sent.
- response.headers.set(HttpHeaders.CONTENT_LENGTH, end - start);
-
- // Set 'Partial Content' status code.
- response.statusCode = HttpStatus.PARTIAL_CONTENT;
- response.headers.set(HttpHeaders.CONTENT_RANGE,
- "bytes $start-${end - 1}/$length");
+ if (start >= length) {
+ response.statusCode =
+ HttpStatus.REQUESTED_RANGE_NOT_SATISFIABLE;
+ response.close();
+ return;
kustermann 2014/11/14 13:25:27 Maybe use cascades: response ..statusCode =
Søren Gjesse 2014/11/14 15:27:29 Done.
+ }
- // Pipe the 'range' of the file.
- file.openRead(start, end)
- .pipe(new _VirtualDirectoryFileStream(response, file.path))
- .catchError((_) {
- // TODO(kevmoo): log errors
- });
- return;
+ // Override Content-Length with the actual bytes sent.
+ response.headers.set(HttpHeaders.CONTENT_LENGTH, end - start + 1);
+
+ // Set 'Partial Content' status code.
+ response.statusCode = HttpStatus.PARTIAL_CONTENT;
+ response.headers.set(HttpHeaders.CONTENT_RANGE,
+ "bytes $start-$end/$length");
kustermann 2014/11/14 13:25:27 Cascades?
Søren Gjesse 2014/11/14 15:27:29 Done.
+
+ // Pipe the 'range' of the file.
+ file.openRead(start, end + 1)
+ .pipe(new _VirtualDirectoryFileStream(response, file.path))
+ .catchError((_) {
+ // TODO(kevmoo): log errors
+ });
+ return;
+ }
}
}
« no previous file with comments | « no previous file | pkg/http_server/test/http_mock.dart » ('j') | pkg/http_server/test/http_mock.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698