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

Side by Side Diff: sdk/lib/io/http_impl.dart

Issue 11645044: Refactor handling of Transfer-Encoding (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years 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 | « sdk/lib/io/http_headers.dart ('k') | sdk/lib/io/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 part of dart.io; 5 part of dart.io;
6 6
7 // The close queue handles graceful closing of HTTP connections. When 7 // The close queue handles graceful closing of HTTP connections. When
8 // a connection is added to the queue it will enter a wait state 8 // a connection is added to the queue it will enter a wait state
9 // waiting for all data written and possibly socket shutdown from 9 // waiting for all data written and possibly socket shutdown from
10 // peer. 10 // peer.
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 headers.add(HttpHeaders.CONNECTION, "keep-alive"); 120 headers.add(HttpHeaders.CONNECTION, "keep-alive");
121 } 121 }
122 } 122 }
123 123
124 124
125 bool _write(List<int> data, bool copyBuffer) { 125 bool _write(List<int> data, bool copyBuffer) {
126 if (_headResponse) return true; 126 if (_headResponse) return true;
127 _ensureHeadersSent(); 127 _ensureHeadersSent();
128 bool allWritten = true; 128 bool allWritten = true;
129 if (data.length > 0) { 129 if (data.length > 0) {
130 if (_headers.contentLength < 0) { 130 if (_headers.chunkedTransferEncoding) {
131 // Write chunk size if transfer encoding is chunked. 131 // Write chunk size if transfer encoding is chunked.
132 _writeHexString(data.length); 132 _writeHexString(data.length);
133 _writeCRLF(); 133 _writeCRLF();
134 _httpConnection._write(data, copyBuffer); 134 _httpConnection._write(data, copyBuffer);
135 allWritten = _writeCRLF(); 135 allWritten = _writeCRLF();
136 } else { 136 } else {
137 _updateContentLength(data.length); 137 _updateContentLength(data.length);
138 allWritten = _httpConnection._write(data, copyBuffer); 138 allWritten = _httpConnection._write(data, copyBuffer);
139 } 139 }
140 } 140 }
141 return allWritten; 141 return allWritten;
142 } 142 }
143 143
144 bool _writeList(List<int> data, int offset, int count) { 144 bool _writeList(List<int> data, int offset, int count) {
145 if (_headResponse) return true; 145 if (_headResponse) return true;
146 _ensureHeadersSent(); 146 _ensureHeadersSent();
147 bool allWritten = true; 147 bool allWritten = true;
148 if (count > 0) { 148 if (count > 0) {
149 if (_headers.contentLength < 0) { 149 if (_headers.chunkedTransferEncoding) {
150 // Write chunk size if transfer encoding is chunked. 150 // Write chunk size if transfer encoding is chunked.
151 _writeHexString(count); 151 _writeHexString(count);
152 _writeCRLF(); 152 _writeCRLF();
153 _httpConnection._writeFrom(data, offset, count); 153 _httpConnection._writeFrom(data, offset, count);
154 allWritten = _writeCRLF(); 154 allWritten = _writeCRLF();
155 } else { 155 } else {
156 _updateContentLength(count); 156 _updateContentLength(count);
157 allWritten = _httpConnection._writeFrom(data, offset, count); 157 allWritten = _httpConnection._writeFrom(data, offset, count);
158 } 158 }
159 } 159 }
160 return allWritten; 160 return allWritten;
161 } 161 }
162 162
163 bool _writeDone() { 163 bool _writeDone() {
164 bool allWritten = true; 164 bool allWritten = true;
165 if (_headers.contentLength < 0) { 165 if (_headers.chunkedTransferEncoding) {
166 // Terminate the content if transfer encoding is chunked. 166 // Terminate the content if transfer encoding is chunked.
167 allWritten = _httpConnection._write(_Const.END_CHUNKED); 167 allWritten = _httpConnection._write(_Const.END_CHUNKED);
168 } else { 168 } else {
169 if (!_headResponse && _bodyBytesWritten < _headers.contentLength) { 169 if (!_headResponse && _bodyBytesWritten < _headers.contentLength) {
170 throw new HttpException("Sending less than specified content length"); 170 throw new HttpException("Sending less than specified content length");
171 } 171 }
172 assert(_headResponse || _bodyBytesWritten == _headers.contentLength); 172 assert(_headResponse || _bodyBytesWritten == _headers.contentLength);
173 } 173 }
174 return allWritten; 174 return allWritten;
175 } 175 }
176 176
177 bool _writeHeaders() { 177 bool _writeHeaders() {
178 _headers._mutable = false;
179 _headers._write(_httpConnection); 178 _headers._write(_httpConnection);
180 // Terminate header. 179 // Terminate header.
181 return _writeCRLF(); 180 return _writeCRLF();
182 } 181 }
183 182
184 bool _writeHexString(int x) { 183 bool _writeHexString(int x) {
185 final List<int> hexDigits = [0x30, 0x31, 0x32, 0x33, 0x34, 184 final List<int> hexDigits = [0x30, 0x31, 0x32, 0x33, 0x34,
186 0x35, 0x36, 0x37, 0x38, 0x39, 185 0x35, 0x36, 0x37, 0x38, 0x39,
187 0x41, 0x42, 0x43, 0x44, 0x45, 0x46]; 186 0x41, 0x42, 0x43, 0x44, 0x45, 0x46];
188 List<int> hex = new Uint8List(10); 187 List<int> hex = new Uint8List(10);
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 if (sessionId != null) { 351 if (sessionId != null) {
353 var sessionManager = _httpConnection._server._sessionManager; 352 var sessionManager = _httpConnection._server._sessionManager;
354 _session = sessionManager.getSession(sessionId); 353 _session = sessionManager.getSession(sessionId);
355 if (_session != null) { 354 if (_session != null) {
356 _session._markSeen(); 355 _session._markSeen();
357 } 356 }
358 } 357 }
359 } 358 }
360 359
361 // Prepare for receiving data. 360 // Prepare for receiving data.
362 _headers._mutable = false;
363 _buffer = new _BufferList(); 361 _buffer = new _BufferList();
364 } 362 }
365 363
366 void _onDataReceived(List<int> data) { 364 void _onDataReceived(List<int> data) {
367 _buffer.add(data); 365 _buffer.add(data);
368 if (_inputStream != null) _inputStream._dataReceived(); 366 if (_inputStream != null) _inputStream._dataReceived();
369 } 367 }
370 368
371 void _onDataEnd() { 369 void _onDataEnd() {
372 if (_inputStream != null) { 370 if (_inputStream != null) {
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
583 _httpConnection._write(_Const.HTTP10); 581 _httpConnection._write(_Const.HTTP10);
584 } 582 }
585 _writeSP(); 583 _writeSP();
586 data = _statusCode.toString().charCodes; 584 data = _statusCode.toString().charCodes;
587 _httpConnection._write(data); 585 _httpConnection._write(data);
588 _writeSP(); 586 _writeSP();
589 data = reasonPhrase.charCodes; 587 data = reasonPhrase.charCodes;
590 _httpConnection._write(data); 588 _httpConnection._write(data);
591 _writeCRLF(); 589 _writeCRLF();
592 590
593 // Determine the value of the "Transfer-Encoding" header based on
594 // whether the content length is known. HTTP/1.0 does not support
595 // chunked.
596 if (_headers.contentLength < 0 && _protocolVersion == "1.1") {
597 _headers.set(HttpHeaders.TRANSFER_ENCODING, "chunked");
598 }
599
600 var session = _httpConnection._request._session; 591 var session = _httpConnection._request._session;
601 if (session != null && !session._destroyed) { 592 if (session != null && !session._destroyed) {
602 // Make sure we only send the current session id. 593 // Make sure we only send the current session id.
603 bool found = false; 594 bool found = false;
604 for (int i = 0; i < cookies.length; i++) { 595 for (int i = 0; i < cookies.length; i++) {
605 if (cookies[i].name.toUpperCase() == _DART_SESSION_ID) { 596 if (cookies[i].name.toUpperCase() == _DART_SESSION_ID) {
606 cookies[i].value = session.id; 597 cookies[i].value = session.id;
607 cookies[i].httpOnly = true; 598 cookies[i].httpOnly = true;
608 found = true; 599 found = true;
609 break; 600 break;
610 } 601 }
611 } 602 }
612 if (!found) { 603 if (!found) {
613 cookies.add(new Cookie(_DART_SESSION_ID, session.id)..httpOnly = true); 604 cookies.add(new Cookie(_DART_SESSION_ID, session.id)..httpOnly = true);
614 } 605 }
615 } 606 }
616 // Add all the cookies set to the headers. 607 // Add all the cookies set to the headers.
617 if (_cookies != null) { 608 if (_cookies != null) {
618 _cookies.forEach((cookie) { 609 _cookies.forEach((cookie) {
619 _headers.add("set-cookie", cookie); 610 _headers.add("set-cookie", cookie);
620 }); 611 });
621 } 612 }
622 613
623 // Write headers. 614 // Write headers.
615 _headers._finalize(_protocolVersion);
624 bool allWritten = _writeHeaders(); 616 bool allWritten = _writeHeaders();
625 _state = _HttpRequestResponseBase.HEADER_SENT; 617 _state = _HttpRequestResponseBase.HEADER_SENT;
626 return allWritten; 618 return allWritten;
627 } 619 }
628 620
629 int _statusCode; // Response status code. 621 int _statusCode; // Response status code.
630 String _reasonPhrase; // Response reason phrase. 622 String _reasonPhrase; // Response reason phrase.
631 _HttpOutputStream _outputStream; 623 _HttpOutputStream _outputStream;
632 Function _streamErrorHandler; 624 Function _streamErrorHandler;
633 } 625 }
(...skipping 610 matching lines...) Expand 10 before | Expand all | Expand 10 after
1244 } 1236 }
1245 data = path.charCodes; 1237 data = path.charCodes;
1246 } else { 1238 } else {
1247 data = _uri.toString().charCodes; 1239 data = _uri.toString().charCodes;
1248 } 1240 }
1249 _httpConnection._write(data); 1241 _httpConnection._write(data);
1250 _writeSP(); 1242 _writeSP();
1251 _httpConnection._write(_Const.HTTP11); 1243 _httpConnection._write(_Const.HTTP11);
1252 _writeCRLF(); 1244 _writeCRLF();
1253 1245
1254 // Determine the value of the "Transfer-Encoding" header based on
1255 // whether the content length is known. If there is no content
1256 // neither "Content-Length" nor "Transfer-Encoding" is set.
1257 if (_headers.contentLength < 0) {
1258 _headers.set(HttpHeaders.TRANSFER_ENCODING, "chunked");
1259 }
1260
1261 // Add the cookies to the headers. 1246 // Add the cookies to the headers.
1262 if (_cookies != null) { 1247 if (_cookies != null) {
1263 StringBuffer sb = new StringBuffer(); 1248 StringBuffer sb = new StringBuffer();
1264 for (int i = 0; i < _cookies.length; i++) { 1249 for (int i = 0; i < _cookies.length; i++) {
1265 if (i > 0) sb.add("; "); 1250 if (i > 0) sb.add("; ");
1266 sb.add(_cookies[i].name); 1251 sb.add(_cookies[i].name);
1267 sb.add("="); 1252 sb.add("=");
1268 sb.add(_cookies[i].value); 1253 sb.add(_cookies[i].value);
1269 } 1254 }
1270 _headers.add("cookie", sb.toString()); 1255 _headers.add("cookie", sb.toString());
1271 } 1256 }
1272 1257
1273 // Write headers. 1258 // Write headers.
1259 _headers._finalize("1.1");
1274 _writeHeaders(); 1260 _writeHeaders();
1275 _state = _HttpRequestResponseBase.HEADER_SENT; 1261 _state = _HttpRequestResponseBase.HEADER_SENT;
1276 } 1262 }
1277 1263
1278 String _method; 1264 String _method;
1279 Uri _uri; 1265 Uri _uri;
1280 _HttpClientConnection _connection; 1266 _HttpClientConnection _connection;
1281 _HttpOutputStream _outputStream; 1267 _HttpOutputStream _outputStream;
1282 Function _streamErrorHandler; 1268 Function _streamErrorHandler;
1283 bool _emptyBody = true; 1269 bool _emptyBody = true;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1329 void _onResponseReceived(int statusCode, 1315 void _onResponseReceived(int statusCode,
1330 String reasonPhrase, 1316 String reasonPhrase,
1331 String version, 1317 String version,
1332 _HttpHeaders headers, 1318 _HttpHeaders headers,
1333 bool hasBody) { 1319 bool hasBody) {
1334 _statusCode = statusCode; 1320 _statusCode = statusCode;
1335 _reasonPhrase = reasonPhrase; 1321 _reasonPhrase = reasonPhrase;
1336 _headers = headers; 1322 _headers = headers;
1337 1323
1338 // Prepare for receiving data. 1324 // Prepare for receiving data.
1339 _headers._mutable = false;
1340 _buffer = new _BufferList(); 1325 _buffer = new _BufferList();
1341 if (isRedirect && _connection.followRedirects) { 1326 if (isRedirect && _connection.followRedirects) {
1342 if (_connection._redirects == null || 1327 if (_connection._redirects == null ||
1343 _connection._redirects.length < _connection.maxRedirects) { 1328 _connection._redirects.length < _connection.maxRedirects) {
1344 // Check the location header. 1329 // Check the location header.
1345 List<String> location = headers[HttpHeaders.LOCATION]; 1330 List<String> location = headers[HttpHeaders.LOCATION];
1346 if (location == null || location.length > 1) { 1331 if (location == null || location.length > 1) {
1347 throw new RedirectException("Invalid redirect", 1332 throw new RedirectException("Invalid redirect",
1348 _connection._redirects); 1333 _connection._redirects);
1349 } 1334 }
(...skipping 965 matching lines...) Expand 10 before | Expand all | Expand 10 after
2315 2300
2316 2301
2317 class _RedirectInfo implements RedirectInfo { 2302 class _RedirectInfo implements RedirectInfo {
2318 const _RedirectInfo(int this.statusCode, 2303 const _RedirectInfo(int this.statusCode,
2319 String this.method, 2304 String this.method,
2320 Uri this.location); 2305 Uri this.location);
2321 final int statusCode; 2306 final int statusCode;
2322 final String method; 2307 final String method;
2323 final Uri location; 2308 final Uri location;
2324 } 2309 }
OLDNEW
« no previous file with comments | « sdk/lib/io/http_headers.dart ('k') | sdk/lib/io/http_parser.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698