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

Side by Side Diff: runtime/bin/http_impl.dart

Issue 10449020: Support using the HEAD request in the HTTP library (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 7 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 | runtime/bin/http_parser.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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 class _HttpHeaders implements HttpHeaders { 5 class _HttpHeaders implements HttpHeaders {
6 _HttpHeaders() : _headers = new Map<String, List<String>>(); 6 _HttpHeaders() : _headers = new Map<String, List<String>>();
7 7
8 List<String> operator[](String name) { 8 List<String> operator[](String name) {
9 name = name.toLowerCase(); 9 name = name.toLowerCase();
10 return _headers[name]; 10 return _headers[name];
(...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after
569 569
570 class _HttpRequestResponseBase { 570 class _HttpRequestResponseBase {
571 final int START = 0; 571 final int START = 0;
572 final int HEADER_SENT = 1; 572 final int HEADER_SENT = 1;
573 final int DONE = 2; 573 final int DONE = 2;
574 final int UPGRADED = 3; 574 final int UPGRADED = 3;
575 575
576 _HttpRequestResponseBase(_HttpConnectionBase this._httpConnection) 576 _HttpRequestResponseBase(_HttpConnectionBase this._httpConnection)
577 : _headers = new _HttpHeaders() { 577 : _headers = new _HttpHeaders() {
578 _state = START; 578 _state = START;
579 _headResponse = false;
579 } 580 }
580 581
581 int get contentLength() => _contentLength; 582 int get contentLength() => _contentLength;
582 HttpHeaders get headers() => _headers; 583 HttpHeaders get headers() => _headers;
583 584
584 bool get persistentConnection() { 585 bool get persistentConnection() {
585 List<String> connection = headers[HttpHeaders.CONNECTION]; 586 List<String> connection = headers[HttpHeaders.CONNECTION];
586 if (_protocolVersion == "1.1") { 587 if (_protocolVersion == "1.1") {
587 if (connection == null) return true; 588 if (connection == null) return true;
588 return !headers[HttpHeaders.CONNECTION].some( 589 return !headers[HttpHeaders.CONNECTION].some(
(...skipping 13 matching lines...) Expand all
602 headers.remove(HttpHeaders.CONNECTION, "keep-alive"); 603 headers.remove(HttpHeaders.CONNECTION, "keep-alive");
603 if (_protocolVersion == "1.1" && !persistentConnection) { 604 if (_protocolVersion == "1.1" && !persistentConnection) {
604 headers.add(HttpHeaders.CONNECTION, "close"); 605 headers.add(HttpHeaders.CONNECTION, "close");
605 } else if (_protocolVersion == "1.0" && persistentConnection) { 606 } else if (_protocolVersion == "1.0" && persistentConnection) {
606 headers.add(HttpHeaders.CONNECTION, "keep-alive"); 607 headers.add(HttpHeaders.CONNECTION, "keep-alive");
607 } 608 }
608 } 609 }
609 610
610 611
611 bool _write(List<int> data, bool copyBuffer) { 612 bool _write(List<int> data, bool copyBuffer) {
613 if (_headResponse) return;
612 _ensureHeadersSent(); 614 _ensureHeadersSent();
613 bool allWritten = true; 615 bool allWritten = true;
614 if (data.length > 0) { 616 if (data.length > 0) {
615 if (_contentLength < 0) { 617 if (_contentLength < 0) {
616 // Write chunk size if transfer encoding is chunked. 618 // Write chunk size if transfer encoding is chunked.
617 _writeHexString(data.length); 619 _writeHexString(data.length);
618 _writeCRLF(); 620 _writeCRLF();
619 _httpConnection._write(data, copyBuffer); 621 _httpConnection._write(data, copyBuffer);
620 allWritten = _writeCRLF(); 622 allWritten = _writeCRLF();
621 } else { 623 } else {
622 _updateContentLength(data.length); 624 _updateContentLength(data.length);
623 allWritten = _httpConnection._write(data, copyBuffer); 625 allWritten = _httpConnection._write(data, copyBuffer);
624 } 626 }
625 } 627 }
626 return allWritten; 628 return allWritten;
627 } 629 }
628 630
629 bool _writeList(List<int> data, int offset, int count) { 631 bool _writeList(List<int> data, int offset, int count) {
632 if (_headResponse) return;
630 _ensureHeadersSent(); 633 _ensureHeadersSent();
631 bool allWritten = true; 634 bool allWritten = true;
632 if (count > 0) { 635 if (count > 0) {
633 if (_contentLength < 0) { 636 if (_contentLength < 0) {
634 // Write chunk size if transfer encoding is chunked. 637 // Write chunk size if transfer encoding is chunked.
635 _writeHexString(count); 638 _writeHexString(count);
636 _writeCRLF(); 639 _writeCRLF();
637 _httpConnection._writeFrom(data, offset, count); 640 _httpConnection._writeFrom(data, offset, count);
638 allWritten = _writeCRLF(); 641 allWritten = _writeCRLF();
639 } else { 642 } else {
640 _updateContentLength(count); 643 _updateContentLength(count);
641 allWritten = _httpConnection._writeFrom(data, offset, count); 644 allWritten = _httpConnection._writeFrom(data, offset, count);
642 } 645 }
643 } 646 }
644 return allWritten; 647 return allWritten;
645 } 648 }
646 649
647 bool _writeDone() { 650 bool _writeDone() {
648 bool allWritten = true; 651 bool allWritten = true;
649 if (_contentLength < 0) { 652 if (_contentLength < 0) {
650 // Terminate the content if transfer encoding is chunked. 653 // Terminate the content if transfer encoding is chunked.
651 allWritten = _httpConnection._write(_Const.END_CHUNKED); 654 allWritten = _httpConnection._write(_Const.END_CHUNKED);
652 } else { 655 } else {
653 if (_bodyBytesWritten < _contentLength) { 656 if (!_headResponse && _bodyBytesWritten < _contentLength) {
654 throw new HttpException("Sending less than specified content length"); 657 throw new HttpException("Sending less than specified content length");
655 } 658 }
656 assert(_bodyBytesWritten == _contentLength); 659 assert(_headResponse || _bodyBytesWritten == _contentLength);
657 } 660 }
658 if (!persistentConnection) _httpConnection._close(); 661 if (!persistentConnection) _httpConnection._close();
659 return allWritten; 662 return allWritten;
660 } 663 }
661 664
662 bool _writeHeaders() { 665 bool _writeHeaders() {
663 _headers._mutable = false; 666 _headers._mutable = false;
664 _headers._write(_httpConnection); 667 _headers._write(_httpConnection);
665 // Terminate header. 668 // Terminate header.
666 return _writeCRLF(); 669 return _writeCRLF();
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
698 } 701 }
699 702
700 void _updateContentLength(int bytes) { 703 void _updateContentLength(int bytes) {
701 if (_bodyBytesWritten + bytes > _contentLength) { 704 if (_bodyBytesWritten + bytes > _contentLength) {
702 throw new HttpException("Writing more than specified content length"); 705 throw new HttpException("Writing more than specified content length");
703 } 706 }
704 _bodyBytesWritten += bytes; 707 _bodyBytesWritten += bytes;
705 } 708 }
706 709
707 int _state; 710 int _state;
711 bool _headResponse;
708 712
709 _HttpConnectionBase _httpConnection; 713 _HttpConnectionBase _httpConnection;
710 _HttpHeaders _headers; 714 _HttpHeaders _headers;
711 List<Cookie> _cookies; 715 List<Cookie> _cookies;
712 String _protocolVersion = "1.1"; 716 String _protocolVersion = "1.1";
713 717
714 // Length of the content body. If this is set to -1 (default value) 718 // Length of the content body. If this is set to -1 (default value)
715 // when starting to send data chunked transfer encoding will be 719 // when starting to send data chunked transfer encoding will be
716 // used. 720 // used.
717 int _contentLength = -1; 721 int _contentLength = -1;
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
1057 _headers.add("set-cookie", cookie); 1061 _headers.add("set-cookie", cookie);
1058 }); 1062 });
1059 } 1063 }
1060 1064
1061 // Write headers. 1065 // Write headers.
1062 bool allWritten = _writeHeaders(); 1066 bool allWritten = _writeHeaders();
1063 _state = HEADER_SENT; 1067 _state = HEADER_SENT;
1064 return allWritten; 1068 return allWritten;
1065 } 1069 }
1066 1070
1067 // Response status code. 1071 int _statusCode; // Response status code.
1068 int _statusCode; 1072 String _reasonPhrase; // Response reason phrase.
1069 String _reasonPhrase;
1070 _HttpOutputStream _outputStream; 1073 _HttpOutputStream _outputStream;
1071 Function _streamErrorHandler; 1074 Function _streamErrorHandler;
1072 } 1075 }
1073 1076
1074 1077
1075 class _HttpInputStream extends _BaseDataInputStream implements InputStream { 1078 class _HttpInputStream extends _BaseDataInputStream implements InputStream {
1076 _HttpInputStream(_HttpRequestResponseBase this._requestOrResponse) { 1079 _HttpInputStream(_HttpRequestResponseBase this._requestOrResponse) {
1077 _checkScheduleCallbacks(); 1080 _checkScheduleCallbacks();
1078 } 1081 }
1079 1082
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
1309 } 1312 }
1310 } 1313 }
1311 1314
1312 void _onRequestStart(String method, String uri, String version) { 1315 void _onRequestStart(String method, String uri, String version) {
1313 // Create new request and response objects for this request. 1316 // Create new request and response objects for this request.
1314 _request = new _HttpRequest(this); 1317 _request = new _HttpRequest(this);
1315 _response = new _HttpResponse(this); 1318 _response = new _HttpResponse(this);
1316 _request._onRequestStart(method, uri, version); 1319 _request._onRequestStart(method, uri, version);
1317 _request._protocolVersion = version; 1320 _request._protocolVersion = version;
1318 _response._protocolVersion = version; 1321 _response._protocolVersion = version;
1322 _response._headResponse = method == "HEAD";
1319 } 1323 }
1320 1324
1321 void _onResponseStart(int statusCode, String reasonPhrase, String version) { 1325 void _onResponseStart(int statusCode, String reasonPhrase, String version) {
1322 // TODO(sgjesse): Error handling. 1326 // TODO(sgjesse): Error handling.
1323 } 1327 }
1324 1328
1325 void _onHeaderReceived(String name, String value) { 1329 void _onHeaderReceived(String name, String value) {
1326 _request._onHeaderReceived(name, value); 1330 _request._onHeaderReceived(name, value);
1327 } 1331 }
1328 1332
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
1476 } 1480 }
1477 1481
1478 1482
1479 class _HttpClientRequest 1483 class _HttpClientRequest
1480 extends _HttpRequestResponseBase implements HttpClientRequest { 1484 extends _HttpRequestResponseBase implements HttpClientRequest {
1481 _HttpClientRequest(String this._method, 1485 _HttpClientRequest(String this._method,
1482 String this._uri, 1486 String this._uri,
1483 _HttpClientConnection connection) 1487 _HttpClientConnection connection)
1484 : super(connection) { 1488 : super(connection) {
1485 _connection = connection; 1489 _connection = connection;
1486 // Default GET requests to have no content. 1490 // Default GET and HEAD requests to have no content.
1487 if (_method == "GET") { 1491 if (_method == "GET" || _method == "HEAD") {
1488 _contentLength = 0; 1492 _contentLength = 0;
1489 } 1493 }
1490 } 1494 }
1491 1495
1492 void set contentLength(int contentLength) { 1496 void set contentLength(int contentLength) {
1493 if (_state >= HEADER_SENT) throw new HttpException("Header already sent"); 1497 if (_state >= HEADER_SENT) throw new HttpException("Header already sent");
1494 _contentLength = contentLength; 1498 _contentLength = contentLength;
1495 } 1499 }
1496 1500
1497 List<Cookie> get cookies() { 1501 List<Cookie> get cookies() {
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
1628 // TODO(sgjesse): Error handling 1632 // TODO(sgjesse): Error handling
1629 } 1633 }
1630 1634
1631 void _onResponseStart(int statusCode, String reasonPhrase, String version) { 1635 void _onResponseStart(int statusCode, String reasonPhrase, String version) {
1632 _statusCode = statusCode; 1636 _statusCode = statusCode;
1633 _reasonPhrase = reasonPhrase; 1637 _reasonPhrase = reasonPhrase;
1634 } 1638 }
1635 1639
1636 void _onHeaderReceived(String name, String value) { 1640 void _onHeaderReceived(String name, String value) {
1637 _headers.add(name, value); 1641 _headers.add(name, value);
1642 if (name == "content-length") {
1643 _contentLength = Math.parseInt(value);
1644 }
1638 } 1645 }
1639 1646
1640 void _onHeadersComplete() { 1647 void _onHeadersComplete() {
1641 _headers._mutable = false; 1648 _headers._mutable = false;
1642 _buffer = new _BufferList(); 1649 _buffer = new _BufferList();
1643 if (isRedirect && _connection.followRedirects) { 1650 if (isRedirect && _connection.followRedirects) {
1644 if (_connection._redirects == null || 1651 if (_connection._redirects == null ||
1645 _connection._redirects.length < _connection.maxRedirects) { 1652 _connection._redirects.length < _connection.maxRedirects) {
1646 // Check the location header. 1653 // Check the location header.
1647 List<String> location = headers[HttpHeaders.LOCATION]; 1654 List<String> location = headers[HttpHeaders.LOCATION];
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1721 (method, uri, version) => _onRequestStart(method, uri, version); 1728 (method, uri, version) => _onRequestStart(method, uri, version);
1722 _httpParser.responseStart = 1729 _httpParser.responseStart =
1723 (statusCode, reasonPhrase, version) => 1730 (statusCode, reasonPhrase, version) =>
1724 _onResponseStart(statusCode, reasonPhrase, version); 1731 _onResponseStart(statusCode, reasonPhrase, version);
1725 _httpParser.headerReceived = 1732 _httpParser.headerReceived =
1726 (name, value) => _onHeaderReceived(name, value); 1733 (name, value) => _onHeaderReceived(name, value);
1727 _httpParser.headersComplete = () => _onHeadersComplete(); 1734 _httpParser.headersComplete = () => _onHeadersComplete();
1728 _httpParser.dataReceived = (data) => _onDataReceived(data); 1735 _httpParser.dataReceived = (data) => _onDataReceived(data);
1729 _httpParser.dataEnd = (closed) => _onDataEnd(closed); 1736 _httpParser.dataEnd = (closed) => _onDataEnd(closed);
1730 _httpParser.error = (e) => _onError(e); 1737 _httpParser.error = (e) => _onError(e);
1731 // Tell the HTTP parser the method it is expecting a response to.
1732 _httpParser.responseToMethod = _method;
1733 } 1738 }
1734 1739
1735 void _responseDone() { 1740 void _responseDone() {
1736 if (_closing) { 1741 if (_closing) {
1737 if (_socket != null) { 1742 if (_socket != null) {
1738 _socket.close(); 1743 _socket.close();
1739 } 1744 }
1740 } else { 1745 } else {
1741 _client._returnSocketConnection(_socketConn); 1746 _client._returnSocketConnection(_socketConn);
1742 } 1747 }
1743 _socket = null; 1748 _socket = null;
1744 _socketConn = null; 1749 _socketConn = null;
1745 } 1750 }
1746 1751
1747 HttpClientRequest open(String method, String uri) { 1752 HttpClientRequest open(String method, String uri) {
1748 _method = method; 1753 _method = method;
1754 // Tell the HTTP parser the method it is expecting a response to.
1755 _httpParser.responseToMethod = method;
1749 _request = new _HttpClientRequest(method, uri, this); 1756 _request = new _HttpClientRequest(method, uri, this);
1750 _response = new _HttpClientResponse(this); 1757 _response = new _HttpClientResponse(this);
1751 return _request; 1758 return _request;
1752 } 1759 }
1753 1760
1754 DetachedSocket detachSocket() { 1761 DetachedSocket detachSocket() {
1755 return _detachSocket(); 1762 return _detachSocket();
1756 } 1763 }
1757 1764
1758 void _onConnectionClosed(e) { 1765 void _onConnectionClosed(e) {
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after
2094 2101
2095 2102
2096 class _RedirectInfo implements RedirectInfo { 2103 class _RedirectInfo implements RedirectInfo {
2097 const _RedirectInfo(int this.statusCode, 2104 const _RedirectInfo(int this.statusCode,
2098 String this.method, 2105 String this.method,
2099 Uri this.location); 2106 Uri this.location);
2100 final int statusCode; 2107 final int statusCode;
2101 final String method; 2108 final String method;
2102 final Uri location; 2109 final Uri location;
2103 } 2110 }
OLDNEW
« no previous file with comments | « no previous file | runtime/bin/http_parser.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698