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

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: Merge. 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('.'), path.segments()) 74 _locateResource(new Path('.'), 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 Path fullPath() => new Path(root).join(path); 90 Path fullPath() => new Path(root).join(path);
91 return FileSystemEntity.type(fullPath().toNativePath(), followLinks: false) 91 return FileSystemEntity.type(fullPath().toNativePath(), followLinks: false)
(...skipping 28 matching lines...) Expand all
120 segments.skip(1)); 120 segments.skip(1));
121 }); 121 });
122 } 122 }
123 break; 123 break;
124 } 124 }
125 // Return `null` on fall-through, to indicate NOT_FOUND. 125 // Return `null` on fall-through, to indicate NOT_FOUND.
126 return null; 126 return null;
127 }); 127 });
128 } 128 }
129 129
130 void _serveFile(File file, HttpRequest request) {
131 var response = request.response;
132 // TODO(ajohnsen): Set up Zone support for these errors.
133 file.lastModified().then((lastModified) {
134 if (request.headers.ifModifiedSince != null &&
135 !lastModified.isAfter(request.headers.ifModifiedSince)) {
136 response.statusCode = HttpStatus.NOT_MODIFIED;
137 response.close();
138 return;
139 }
140
141 response.headers.set(HttpHeaders.LAST_MODIFIED, lastModified);
142 response.headers.set(HttpHeaders.ACCEPT_RANGES, "bytes");
143
144 if (request.method == 'HEAD') {
145 response.close();
146 return;
147 }
148
149 return file.length().then((length) {
150 String range = request.headers.value("range");
151 if (range != null) {
152 // We only support one range, where the standard support several.
153 Match matches = new RegExp(r"^bytes=(\d*)\-(\d*)$").firstMatch(range);
154 // If the range header have the right format, handle it.
155 if (matches != null) {
156 // Serve sub-range.
157 int start;
158 int end;
159 if (matches[1].isEmpty) {
160 start = matches[2].isEmpty ?
161 length :
162 length - int.parse(matches[2]);
163 end = length;
164 } else {
165 start = int.parse(matches[1]);
166 end = matches[2].isEmpty ? length : int.parse(matches[2]) + 1;
167 }
168
169 // Override Content-Length with the actual bytes sent.
170 response.headers.set(HttpHeaders.CONTENT_LENGTH, end - start);
171
172 // Set 'Partial Content' status code.
173 response.statusCode = HttpStatus.PARTIAL_CONTENT;
174 response.headers.set(HttpHeaders.CONTENT_RANGE,
175 "bytes $start-${end - 1}/$length");
176
177 // Pipe the 'range' of the file.
178 file.openRead(start, end).pipe(response).catchError((_) {});
179 return;
180 }
181 }
182
183 file.openRead().pipe(response).catchError((_) {});
184 });
185 }).catchError((_) {
186 response.close();
187 });
188 }
189
130 void _serveErrorPage(int error, HttpRequest request) { 190 void _serveErrorPage(int error, HttpRequest request) {
131 request.response.statusCode = error; 191 request.response.statusCode = error;
132 request.response.close(); 192 request.response.close();
133 } 193 }
134 } 194 }
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