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

Side by Side Diff: lib/shelf_pubserver.dart

Issue 930513002: Added README, a bin/serve example server which can be used locally. (Closed) Base URL: https://github.com/dart-lang/pub_server.git@master
Patch Set: Moved to old-style async due to another mimepart stream issue, small bugfix' Created 5 years, 10 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
« no previous file with comments | « example/src/examples/http_proxy_repository.dart ('k') | pubspec.yaml » ('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) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 library pub_server.shelf_pubserver; 5 library pub_server.shelf_pubserver;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:convert'; 8 import 'dart:convert';
9 9
10 import 'package:logging/logging.dart'; 10 import 'package:logging/logging.dart';
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 }); 301 });
302 } 302 }
303 303
304 Future<shelf.Response> _uploadSimple( 304 Future<shelf.Response> _uploadSimple(
305 Uri uri, String contentType, Stream<List<int>> stream) { 305 Uri uri, String contentType, Stream<List<int>> stream) {
306 _logger.info('Perform simple upload.'); 306 _logger.info('Perform simple upload.');
307 if (contentType.startsWith('multipart/form-data')) { 307 if (contentType.startsWith('multipart/form-data')) {
308 var match = _boundaryRegExp.matchAsPrefix(contentType); 308 var match = _boundaryRegExp.matchAsPrefix(contentType);
309 if (match != null) { 309 if (match != null) {
310 var boundary = match.group(1); 310 var boundary = match.group(1);
311 return stream 311
312 .transform(new MimeMultipartTransformer(boundary)) 312 // We have to listen to all multiparts: Just doing `parts.first` will
313 .first.then((MimeMultipart part) { 313 // result in the cancelation of the subscription which causes
314 // eventually a destruction of the socket, this is an odd side-effect.
315 // What we would like to have is something like this:
316 // parts.expect(1).then((part) { upload(part); })
317 bool firstPartArrived = false;
318 var completer = new Completer();
319 var subscription;
320
321 var parts = stream.transform(new MimeMultipartTransformer(boundary));
322 subscription = parts.listen((MimeMultipart part) {
323 // If we get more than one part, we'll ignore the rest of the input.
324 if (firstPartArrived) {
325 subscription.cancel();
326 return;
327 }
328 firstPartArrived = true;
329
314 // TODO: Ensure that `part.headers['content-disposition']` is 330 // TODO: Ensure that `part.headers['content-disposition']` is
315 // `form-data; name="file"; filename="package.tar.gz` 331 // `form-data; name="file"; filename="package.tar.gz`
316 return repository.upload(part).then((_) { 332 repository.upload(part).then((_) {
333 _logger.info('Redirecting to found url.');
317 return new shelf.Response.found(_finishUploadSimpleUrl(uri)); 334 return new shelf.Response.found(_finishUploadSimpleUrl(uri));
318 }).catchError((error, stack) { 335 }).catchError((error, stack) {
336 _logger.warning('Error occured: $error\n$stack.');
319 // TODO: Do error checking and return error codes? 337 // TODO: Do error checking and return error codes?
320 return new shelf.Response.found( 338 return new shelf.Response.found(
321 _finishUploadSimpleUrl(uri, error: error)); 339 _finishUploadSimpleUrl(uri, error: error));
322 }); 340 }).then(completer.complete);
323 }); 341 });
342
343 return completer.future;
324 } 344 }
325 } 345 }
326 return 346 return
327 _badRequest('Upload must contain a multipart/form-data content type.'); 347 _badRequest('Upload must contain a multipart/form-data content type.');
328 } 348 }
329 349
330 Future<shelf.Response> _finishUploadSimple(Uri uri) { 350 Future<shelf.Response> _finishUploadSimple(Uri uri) {
331 var error = uri.queryParameters['error']; 351 var error = uri.queryParameters['error'];
332 _logger.info('Finish simple upload (error: $error).'); 352 _logger.info('Finish simple upload (error: $error).');
333 if (error != null) { 353 if (error != null) {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 410
391 Uri _uploadSimpleUrl(Uri url) { 411 Uri _uploadSimpleUrl(Uri url) {
392 return url.resolve('/api/packages/versions/newUpload'); 412 return url.resolve('/api/packages/versions/newUpload');
393 } 413 }
394 414
395 Uri _finishUploadSimpleUrl(Uri url, {String error}) { 415 Uri _finishUploadSimpleUrl(Uri url, {String error}) {
396 var postfix = error == null ? '' : '?error=${Uri.encodeComponent(error)}'; 416 var postfix = error == null ? '' : '?error=${Uri.encodeComponent(error)}';
397 return url.resolve('/api/packages/versions/newUploadFinish$postfix'); 417 return url.resolve('/api/packages/versions/newUploadFinish$postfix');
398 } 418 }
399 } 419 }
OLDNEW
« no previous file with comments | « example/src/examples/http_proxy_repository.dart ('k') | pubspec.yaml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698