OLD | NEW |
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 dart.io; | 5 part of dart.io; |
6 | 6 |
7 class _HttpIncoming extends Stream<List<int>> { | 7 class _HttpIncoming extends Stream<List<int>> { |
8 final int _transferLength; | 8 final int _transferLength; |
9 final Completer _dataCompleter = new Completer(); | 9 final Completer _dataCompleter = new Completer(); |
10 Stream<List<int>> _stream; | 10 Stream<List<int>> _stream; |
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
311 return this; | 311 return this; |
312 } | 312 } |
313 }); | 313 }); |
314 } | 314 } |
315 // No credentials were found and the callback was not set. | 315 // No credentials were found and the callback was not set. |
316 return new Future.immediate(this); | 316 return new Future.immediate(this); |
317 } | 317 } |
318 } | 318 } |
319 | 319 |
320 | 320 |
321 abstract class _HttpOutboundMessage<T> extends IOSink { | 321 abstract class _HttpOutboundMessage<T> implements IOSink { |
322 // Used to mark when the body should be written. This is used for HEAD | 322 // Used to mark when the body should be written. This is used for HEAD |
323 // requests and in error handling. | 323 // requests and in error handling. |
324 bool _ignoreBody = false; | 324 bool _ignoreBody = false; |
| 325 bool _headersWritten = false; |
| 326 bool _chunked = false; |
| 327 |
| 328 final IOSink _ioSink; |
| 329 final _HttpOutgoing _outgoing; |
| 330 |
| 331 final _HttpHeaders headers; |
325 | 332 |
326 _HttpOutboundMessage(String protocolVersion, _HttpOutgoing outgoing) | 333 _HttpOutboundMessage(String protocolVersion, _HttpOutgoing outgoing) |
327 : super(outgoing), | 334 : _outgoing = outgoing, |
328 _outgoing = outgoing, | 335 _ioSink = new IOSink(outgoing), |
329 headers = new _HttpHeaders(protocolVersion); | 336 headers = new _HttpHeaders(protocolVersion); |
330 | 337 |
331 int get contentLength => headers.contentLength; | 338 int get contentLength => headers.contentLength; |
332 void set contentLength(int contentLength) { | 339 void set contentLength(int contentLength) { |
333 headers.contentLength = contentLength; | 340 headers.contentLength = contentLength; |
334 } | 341 } |
335 | 342 |
336 bool get persistentConnection => headers.persistentConnection; | 343 bool get persistentConnection => headers.persistentConnection; |
337 void set persistentConnection(bool p) { | 344 void set persistentConnection(bool p) { |
338 headers.persistentConnection = p; | 345 headers.persistentConnection = p; |
339 } | 346 } |
340 | 347 |
341 Future<T> consume(Stream<List<int>> stream) { | 348 Future<T> consume(Stream<List<int>> stream) { |
342 _writeHeaders(); | 349 _writeHeaders(); |
343 if (_ignoreBody) return new Future.immediate(this); | 350 if (_ignoreBody) return new Future.immediate(this); |
344 if (_chunked) { | 351 if (_chunked) { |
345 // Transform when chunked. | 352 // Transform when chunked. |
346 stream = stream.transform(new _ChunkedTransformer()); | 353 stream = stream.transform(new _ChunkedTransformer()); |
347 } | 354 } |
348 return super.consume(stream).then((_) => this); | 355 return _ioSink.consume(stream).then((_) => this); |
349 } | 356 } |
350 | 357 |
351 void add(List<int> data) { | 358 void add(List<int> data) { |
352 _writeHeaders(); | 359 _writeHeaders(); |
353 if (_ignoreBody || data.length == 0) return; | 360 if (_ignoreBody || data.length == 0) return; |
354 if (_chunked) { | 361 if (_chunked) { |
355 _ChunkedTransformer._addChunk(data, super.add); | 362 _ChunkedTransformer._addChunk(data, _ioSink.add); |
356 } else { | 363 } else { |
357 super.add(data); | 364 _ioSink.add(data); |
358 } | 365 } |
359 } | 366 } |
360 | 367 |
361 Future addStream(Stream<List<int>> stream) { | 368 void addString(String string, [Encoding encoding = Encoding.UTF_8]) { |
| 369 add(_encodeString(string, encoding)); |
| 370 } |
| 371 |
| 372 Future<T> addStream(Stream<List<int>> stream) { |
362 _writeHeaders(); | 373 _writeHeaders(); |
363 if (_ignoreBody) return new Future.immediate(this); | 374 if (_ignoreBody) return new Future.immediate(this); |
364 if (_chunked) { | 375 if (_chunked) { |
365 // Transform when chunked. | 376 // Transform when chunked. |
366 stream = stream.transform(new _ChunkedTransformer(writeEnd: false)); | 377 stream = stream.transform(new _ChunkedTransformer(writeEnd: false)); |
367 } | 378 } |
368 return super.addStream(stream).then((_) => this); | 379 return _ioSink.addStream(stream).then((_) => this); |
369 } | 380 } |
370 | 381 |
371 void close() { | 382 void close() { |
372 if (!_headersWritten && !_ignoreBody && headers.chunkedTransferEncoding) { | 383 if (!_headersWritten && !_ignoreBody && headers.chunkedTransferEncoding) { |
373 // If no body was written, _ignoreBody is false (it's not a HEAD | 384 // If no body was written, _ignoreBody is false (it's not a HEAD |
374 // request) and the content-length is unspecified, set contentLength to 0. | 385 // request) and the content-length is unspecified, set contentLength to 0. |
375 headers.contentLength = 0; | 386 headers.contentLength = 0; |
376 } | 387 } |
377 _writeHeaders(); | 388 _writeHeaders(); |
378 if (!_ignoreBody) { | 389 if (!_ignoreBody) { |
379 if (_chunked) { | 390 if (_chunked) { |
380 _ChunkedTransformer._addChunk([], super.add); | 391 _ChunkedTransformer._addChunk([], _ioSink.add); |
381 } | 392 } |
382 } | 393 } |
383 super.close(); | 394 _ioSink.close(); |
384 } | 395 } |
385 | 396 |
| 397 Future<T> get done => _ioSink.done.then((_) => this); |
| 398 |
386 void _writeHeaders() { | 399 void _writeHeaders() { |
387 if (_headersWritten) return; | 400 if (_headersWritten) return; |
388 bool _tmpIgnoreBody = _ignoreBody; | 401 bool _tmpIgnoreBody = _ignoreBody; |
389 _ignoreBody = false; | 402 _ignoreBody = false; |
390 _headersWritten = true; | 403 _headersWritten = true; |
391 _writeHeader(); | 404 _writeHeader(); |
392 _ignoreBody = _tmpIgnoreBody; | 405 _ignoreBody = _tmpIgnoreBody; |
393 if (_ignoreBody) { | 406 if (_ignoreBody) { |
394 super.close(); | 407 _ioSink.close(); |
395 return; | 408 return; |
396 } | 409 } |
397 _chunked = headers.chunkedTransferEncoding; | 410 _chunked = headers.chunkedTransferEncoding; |
398 if (headers.contentLength >= 0) { | 411 if (headers.contentLength >= 0) { |
399 _outgoing.setTransferLength(headers.contentLength); | 412 _outgoing.setTransferLength(headers.contentLength); |
400 } | 413 } |
401 } | 414 } |
402 | 415 |
403 void _writeHeader(); // TODO(ajohnsen): Better name. | 416 void _writeHeader(); // TODO(ajohnsen): Better name. |
404 | |
405 final _HttpHeaders headers; | |
406 | |
407 final _HttpOutgoing _outgoing; | |
408 bool _headersWritten = false; | |
409 bool _chunked = false; | |
410 } | 417 } |
411 | 418 |
412 | 419 |
413 class _HttpResponse extends _HttpOutboundMessage<HttpResponse> | 420 class _HttpResponse extends _HttpOutboundMessage<HttpResponse> |
414 implements HttpResponse { | 421 implements HttpResponse { |
415 int statusCode = 200; | 422 int statusCode = 200; |
416 String _reasonPhrase; | 423 String _reasonPhrase; |
417 List<Cookie> _cookies; | 424 List<Cookie> _cookies; |
418 _HttpRequest _httpRequest; | 425 _HttpRequest _httpRequest; |
419 | 426 |
(...skipping 1058 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1478 } | 1485 } |
1479 | 1486 |
1480 _HttpConnectionInfo._(); | 1487 _HttpConnectionInfo._(); |
1481 | 1488 |
1482 String remoteHost; | 1489 String remoteHost; |
1483 int remotePort; | 1490 int remotePort; |
1484 int localPort; | 1491 int localPort; |
1485 } | 1492 } |
1486 | 1493 |
1487 | 1494 |
1488 class _DetachedSocket implements Socket { | 1495 class _DetachedSocket extends Stream<List<int>> implements Socket { |
1489 final Stream<List<int>> _incoming; | 1496 final Stream<List<int>> _incoming; |
1490 final Socket _socket; | 1497 final Socket _socket; |
1491 | 1498 |
1492 _DetachedSocket(this._socket, this._incoming); | 1499 _DetachedSocket(this._socket, this._incoming); |
1493 | 1500 |
1494 StreamSubscription<List<int>> listen(void onData(List<int> event), | 1501 StreamSubscription<List<int>> listen(void onData(List<int> event), |
1495 {void onError(AsyncError error), | 1502 {void onError(AsyncError error), |
1496 void onDone(), | 1503 void onDone(), |
1497 bool unsubscribeOnError}) { | 1504 bool unsubscribeOnError}) { |
1498 return _incoming.listen(onData, | 1505 return _incoming.listen(onData, |
(...skipping 11 matching lines...) Expand all Loading... |
1510 } | 1517 } |
1511 | 1518 |
1512 void addString(String string, [Encoding encoding = Encoding.UTF_8]) { | 1519 void addString(String string, [Encoding encoding = Encoding.UTF_8]) { |
1513 return _socket.addString(string, encoding); | 1520 return _socket.addString(string, encoding); |
1514 } | 1521 } |
1515 | 1522 |
1516 void destroy() => _socket.destroy(); | 1523 void destroy() => _socket.destroy(); |
1517 void add(List<int> data) => _socket.add(data); | 1524 void add(List<int> data) => _socket.add(data); |
1518 void close() => _socket.close(); | 1525 void close() => _socket.close(); |
1519 Future<Socket> get done => _socket.done; | 1526 Future<Socket> get done => _socket.done; |
| 1527 int get port => _socket.port; |
| 1528 String get remoteHost => _socket.remoteHost; |
| 1529 int get remotePort => _socket.remotePort; |
1520 } | 1530 } |
1521 | 1531 |
1522 | 1532 |
1523 class _AuthenticationScheme { | 1533 class _AuthenticationScheme { |
1524 static const UNKNOWN = const _AuthenticationScheme(-1); | 1534 static const UNKNOWN = const _AuthenticationScheme(-1); |
1525 static const BASIC = const _AuthenticationScheme(0); | 1535 static const BASIC = const _AuthenticationScheme(0); |
1526 static const DIGEST = const _AuthenticationScheme(1); | 1536 static const DIGEST = const _AuthenticationScheme(1); |
1527 | 1537 |
1528 const _AuthenticationScheme(this._scheme); | 1538 const _AuthenticationScheme(this._scheme); |
1529 | 1539 |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1625 | 1635 |
1626 | 1636 |
1627 class _RedirectInfo implements RedirectInfo { | 1637 class _RedirectInfo implements RedirectInfo { |
1628 const _RedirectInfo(int this.statusCode, | 1638 const _RedirectInfo(int this.statusCode, |
1629 String this.method, | 1639 String this.method, |
1630 Uri this.location); | 1640 Uri this.location); |
1631 final int statusCode; | 1641 final int statusCode; |
1632 final String method; | 1642 final String method; |
1633 final Uri location; | 1643 final Uri location; |
1634 } | 1644 } |
OLD | NEW |