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

Side by Side Diff: pkg/http_server/lib/src/virtual_directory.dart

Issue 17582002: Add support for IfModifiedSince headers, in http_servers' VirtualDirectory. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 6 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | pkg/http_server/test/virtual_directory_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of http_server; 5 part of http_server;
6 6
7 /** 7 /**
8 * A [VirtualDirectory] can serve files and directory-listing from a root path, 8 * A [VirtualDirectory] can serve files and directory-listing from a root path,
9 * to [HttpRequest]s. 9 * to [HttpRequest]s.
10 * 10 *
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 return _serveErrorPage(HttpStatus.NOT_FOUND, request); 71 return _serveErrorPage(HttpStatus.NOT_FOUND, request);
72 } 72 }
73 73
74 _locateResource(new Path(root), path.segments()) 74 _locateResource(new Path(root), path.segments())
75 .then((entity) { 75 .then((entity) {
76 if (entity == null) { 76 if (entity == null) {
77 _serveErrorPage(HttpStatus.NOT_FOUND, request); 77 _serveErrorPage(HttpStatus.NOT_FOUND, request);
78 return; 78 return;
79 } 79 }
80 if (entity is File) { 80 if (entity is File) {
81 entity.openRead().pipe(request.response).catchError((_) {}); 81 _serveFile(entity, request);
82 } else { 82 } else {
83 _serveErrorPage(HttpStatus.NOT_FOUND, request); 83 _serveErrorPage(HttpStatus.NOT_FOUND, request);
84 } 84 }
85 }); 85 });
86 } 86 }
87 87
88 Future<FileSystemEntity> _locateResource(Path path, 88 Future<FileSystemEntity> _locateResource(Path path,
89 Iterable<String> segments) { 89 Iterable<String> segments) {
90 return FileSystemEntity.type(path.toNativePath(), followLinks: false) 90 return FileSystemEntity.type(path.toNativePath(), followLinks: false)
91 .then((type) { 91 .then((type) {
(...skipping 15 matching lines...) Expand all
107 if (followLinks) { 107 if (followLinks) {
108 // TODO 108 // TODO
109 } 109 }
110 break; 110 break;
111 } 111 }
112 // Return `null` on fall-through, to indicate NOT_FOUND. 112 // Return `null` on fall-through, to indicate NOT_FOUND.
113 return null; 113 return null;
114 }); 114 });
115 } 115 }
116 116
117 void _serveFile(File file, HttpRequest request) {
118 file.lastModified().then((lastModified) {
119 var response = request.response;
120
121 if (request.headers.ifModifiedSince != null &&
122 !lastModified.isAfter(request.headers.ifModifiedSince)) {
123 response.statusCode = HttpStatus.NOT_MODIFIED;
124 response.close();
125 return;
126 }
127
128 response.headers.set(HttpHeaders.LAST_MODIFIED, lastModified);
129 response.headers.set(HttpHeaders.ACCEPT_RANGES, "bytes");
130
131 if (request.method == 'HEAD') {
132 response.close();
133 return;
134 }
135
136 file.length().then((length) {
137 String range = request.headers.value("range");
138 if (range != null) {
139 // We only support one range, where the standard support several.
140 Match matches = new RegExp(r"^bytes=(\d*)\-(\d*)$").firstMatch(range);
141 // If the range header have the right format, handle it.
142 if (matches != null) {
143 // Serve sub-range.
144 int start;
145 int end;
146 if (matches[1].isEmpty) {
147 start = matches[2].isEmpty ?
148 length :
149 length - int.parse(matches[2]);
150 end = length;
151 } else {
152 start = int.parse(matches[1]);
153 end = matches[2].isEmpty ? length : int.parse(matches[2]) + 1;
154 }
155
156 // Override Content-Length with the actual bytes sent.
157 response.headers.set(HttpHeaders.CONTENT_LENGTH, end - start);
158
159 // Set 'Partial Content' status code.
160 response.statusCode = HttpStatus.PARTIAL_CONTENT;
161 response.headers.set(HttpHeaders.CONTENT_RANGE,
162 "bytes $start-${end - 1}/$length");
163
164 // Pipe the 'range' of the file.
165 file.openRead(start, end).pipe(response).catchError((_) {});
166 return;
167 }
168 }
169
170 file.openRead().pipe(response).catchError((_) {});
Søren Gjesse 2013/06/24 08:17:24 I don't think we should just swallow all errors. W
171 }, onError: (_) {});
172 }, onError: (_) {});
173 }
174
117 void _serveErrorPage(int error, HttpRequest request) { 175 void _serveErrorPage(int error, HttpRequest request) {
118 request.response.statusCode = error; 176 request.response.statusCode = error;
119 request.response.close(); 177 request.response.close();
120 } 178 }
121 } 179 }
OLDNEW
« no previous file with comments | « no previous file | pkg/http_server/test/virtual_directory_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698