Chromium Code Reviews| 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; |
| + } |
| } |
| } |