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 @patch | 5 @patch |
6 class RawServerSocket { | 6 class RawServerSocket { |
7 @patch | 7 @patch |
8 static Future<RawServerSocket> bind(address, int port, | 8 static Future<RawServerSocket> bind(address, int port, |
9 {int backlog: 0, bool v6Only: false, bool shared: false}) { | 9 {int backlog: 0, bool v6Only: false, bool shared: false}) { |
10 return _RawServerSocket.bind(address, port, backlog, v6Only, shared); | 10 return _RawServerSocket.bind(address, port, backlog, v6Only, shared); |
11 } | 11 } |
12 } | 12 } |
13 | 13 |
14 @patch | 14 @patch |
15 class RawSocket { | 15 class RawSocket { |
16 @patch | 16 @patch |
17 static Future<RawSocket> connect(host, int port, {sourceAddress}) { | 17 static Future<RawSocket> connect(host, int port, |
18 return _RawSocket.connect(host, port, sourceAddress); | 18 {sourceAddress, Duration timeout}) { |
| 19 return _RawSocket.connect(host, port, sourceAddress, timeout); |
19 } | 20 } |
20 } | 21 } |
21 | 22 |
22 @patch | 23 @patch |
23 class InternetAddress { | 24 class InternetAddress { |
24 @patch | 25 @patch |
25 static InternetAddress get LOOPBACK_IP_V4 { | 26 static InternetAddress get LOOPBACK_IP_V4 { |
26 return _InternetAddress.LOOPBACK_IP_V4; | 27 return _InternetAddress.LOOPBACK_IP_V4; |
27 } | 28 } |
28 | 29 |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
387 if (!includeLoopback && address.isLoopback) return map; | 388 if (!includeLoopback && address.isLoopback) return map; |
388 map.putIfAbsent(name, () => new _NetworkInterface(name, index)); | 389 map.putIfAbsent(name, () => new _NetworkInterface(name, index)); |
389 map[name].addresses.add(address); | 390 map[name].addresses.add(address); |
390 return map; | 391 return map; |
391 }); | 392 }); |
392 return map.values.toList(); | 393 return map.values.toList(); |
393 } | 394 } |
394 }); | 395 }); |
395 } | 396 } |
396 | 397 |
397 static Future<_NativeSocket> connect(host, int port, sourceAddress) { | 398 static Future<_NativeSocket> connect( |
| 399 host, int port, sourceAddress, Duration timeout) { |
398 _throwOnBadPort(port); | 400 _throwOnBadPort(port); |
399 if (sourceAddress != null && sourceAddress is! _InternetAddress) { | 401 if (sourceAddress != null && sourceAddress is! _InternetAddress) { |
400 if (sourceAddress is String) { | 402 if (sourceAddress is String) { |
401 sourceAddress = new InternetAddress(sourceAddress); | 403 sourceAddress = new InternetAddress(sourceAddress); |
402 } | 404 } |
403 } | 405 } |
404 return new Future.value(host).then((host) { | 406 return new Future.value(host).then((host) { |
405 if (host is _InternetAddress) return [host]; | 407 if (host is _InternetAddress) return [host]; |
406 return lookup(host).then((addresses) { | 408 return lookup(host).then((addresses) { |
407 if (addresses.isEmpty) { | 409 if (addresses.isEmpty) { |
408 throw createError(null, "Failed host lookup: '$host'"); | 410 throw createError(null, "Failed host lookup: '$host'"); |
409 } | 411 } |
410 return addresses; | 412 return addresses; |
411 }); | 413 }); |
412 }).then((addresses) { | 414 }).then((addresses) { |
413 assert(addresses is List); | 415 assert(addresses is List); |
414 var completer = new Completer(); | 416 var completer = new Completer(); |
415 var it = addresses.iterator; | 417 var it = addresses.iterator; |
416 var error = null; | 418 var error = null; |
417 var connecting = new HashMap(); | 419 var connecting = new HashMap(); |
| 420 Timer timeoutTimer = null; |
| 421 void timeoutHandler() { |
| 422 connecting.forEach((s, t) { |
| 423 t.cancel(); |
| 424 s.close(); |
| 425 s.setHandlers(); |
| 426 s.setListening(read: false, write: false); |
| 427 error = createError( |
| 428 null, "Connection timed out, host: ${host}, port: ${port}"); |
| 429 completer.completeError(error); |
| 430 }); |
| 431 } |
| 432 |
418 void connectNext() { | 433 void connectNext() { |
| 434 if ((timeout != null) && (timeoutTimer == null)) { |
| 435 timeoutTimer = new Timer(timeout, timeoutHandler); |
| 436 } |
419 if (!it.moveNext()) { | 437 if (!it.moveNext()) { |
420 if (connecting.isEmpty) { | 438 if (connecting.isEmpty) { |
421 assert(error != null); | 439 assert(error != null); |
| 440 if (timeoutTimer != null) { |
| 441 timeoutTimer.cancel(); |
| 442 } |
422 completer.completeError(error); | 443 completer.completeError(error); |
423 } | 444 } |
424 return; | 445 return; |
425 } | 446 } |
426 var address = it.current; | 447 var address = it.current; |
427 var socket = new _NativeSocket.normal(); | 448 var socket = new _NativeSocket.normal(); |
428 socket.localAddress = address; | 449 socket.localAddress = address; |
429 var result; | 450 var result; |
430 if (sourceAddress == null) { | 451 if (sourceAddress == null) { |
431 result = socket.nativeCreateConnect(address._in_addr, port); | 452 result = socket.nativeCreateConnect(address._in_addr, port); |
(...skipping 26 matching lines...) Expand all Loading... |
458 var duration = | 479 var duration = |
459 address.isLoopback ? _RETRY_DURATION_LOOPBACK : _RETRY_DURATION; | 480 address.isLoopback ? _RETRY_DURATION_LOOPBACK : _RETRY_DURATION; |
460 var timer = new Timer(duration, connectNext); | 481 var timer = new Timer(duration, connectNext); |
461 setupResourceInfo(socket); | 482 setupResourceInfo(socket); |
462 | 483 |
463 connecting[socket] = timer; | 484 connecting[socket] = timer; |
464 // Setup handlers for receiving the first write event which | 485 // Setup handlers for receiving the first write event which |
465 // indicate that the socket is fully connected. | 486 // indicate that the socket is fully connected. |
466 socket.setHandlers(write: () { | 487 socket.setHandlers(write: () { |
467 timer.cancel(); | 488 timer.cancel(); |
| 489 if (timeoutTimer != null) { |
| 490 timeoutTimer.cancel(); |
| 491 } |
468 socket.setListening(read: false, write: false); | 492 socket.setListening(read: false, write: false); |
469 completer.complete(socket); | 493 completer.complete(socket); |
470 connecting.remove(socket); | 494 connecting.remove(socket); |
471 connecting.forEach((s, t) { | 495 connecting.forEach((s, t) { |
472 t.cancel(); | 496 t.cancel(); |
473 s.close(); | 497 s.close(); |
474 s.setHandlers(); | 498 s.setHandlers(); |
475 s.setListening(read: false, write: false); | 499 s.setListening(read: false, write: false); |
476 }); | 500 }); |
477 }, error: (e) { | 501 }, error: (e) { |
(...skipping 700 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1178 | 1202 |
1179 class _RawSocket extends Stream<RawSocketEvent> implements RawSocket { | 1203 class _RawSocket extends Stream<RawSocketEvent> implements RawSocket { |
1180 final _NativeSocket _socket; | 1204 final _NativeSocket _socket; |
1181 StreamController<RawSocketEvent> _controller; | 1205 StreamController<RawSocketEvent> _controller; |
1182 bool _readEventsEnabled = true; | 1206 bool _readEventsEnabled = true; |
1183 bool _writeEventsEnabled = true; | 1207 bool _writeEventsEnabled = true; |
1184 | 1208 |
1185 // Flag to handle Ctrl-D closing of stdio on Mac OS. | 1209 // Flag to handle Ctrl-D closing of stdio on Mac OS. |
1186 bool _isMacOSTerminalInput = false; | 1210 bool _isMacOSTerminalInput = false; |
1187 | 1211 |
1188 static Future<RawSocket> connect(host, int port, sourceAddress) { | 1212 static Future<RawSocket> connect( |
| 1213 host, int port, sourceAddress, Duration timeout) { |
1189 return _NativeSocket | 1214 return _NativeSocket |
1190 .connect(host, port, sourceAddress) | 1215 .connect(host, port, sourceAddress, timeout) |
1191 .then((socket) => new _RawSocket(socket)); | 1216 .then((socket) => new _RawSocket(socket)); |
1192 } | 1217 } |
1193 | 1218 |
1194 _RawSocket(this._socket) { | 1219 _RawSocket(this._socket) { |
1195 var zone = Zone.current; | 1220 var zone = Zone.current; |
1196 _controller = new StreamController( | 1221 _controller = new StreamController( |
1197 sync: true, | 1222 sync: true, |
1198 onListen: _onSubscriptionStateChange, | 1223 onListen: _onSubscriptionStateChange, |
1199 onCancel: _onSubscriptionStateChange, | 1224 onCancel: _onSubscriptionStateChange, |
1200 onPause: _onPauseStateChange, | 1225 onPause: _onPauseStateChange, |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1359 Future close() => _socket.close().then((_) => this); | 1384 Future close() => _socket.close().then((_) => this); |
1360 | 1385 |
1361 void set _owner(owner) { | 1386 void set _owner(owner) { |
1362 _socket._owner = owner; | 1387 _socket._owner = owner; |
1363 } | 1388 } |
1364 } | 1389 } |
1365 | 1390 |
1366 @patch | 1391 @patch |
1367 class Socket { | 1392 class Socket { |
1368 @patch | 1393 @patch |
1369 static Future<Socket> connect(host, int port, {sourceAddress}) { | 1394 static Future<Socket> connect(host, int port, |
| 1395 {sourceAddress, Duration timeout}) { |
1370 return RawSocket | 1396 return RawSocket |
1371 .connect(host, port, sourceAddress: sourceAddress) | 1397 .connect(host, port, sourceAddress: sourceAddress, timeout: timeout) |
1372 .then((socket) => new _Socket(socket)); | 1398 .then((socket) => new _Socket(socket)); |
1373 } | 1399 } |
1374 } | 1400 } |
1375 | 1401 |
1376 class _SocketStreamConsumer extends StreamConsumer<List<int>> { | 1402 class _SocketStreamConsumer extends StreamConsumer<List<int>> { |
1377 StreamSubscription subscription; | 1403 StreamSubscription subscription; |
1378 final _Socket socket; | 1404 final _Socket socket; |
1379 int offset; | 1405 int offset; |
1380 List<int> buffer; | 1406 List<int> buffer; |
1381 bool paused = false; | 1407 bool paused = false; |
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1803 } else { | 1829 } else { |
1804 _socket.close(); | 1830 _socket.close(); |
1805 } | 1831 } |
1806 } | 1832 } |
1807 } | 1833 } |
1808 | 1834 |
1809 Datagram _makeDatagram( | 1835 Datagram _makeDatagram( |
1810 List<int> data, String address, List<int> in_addr, int port) { | 1836 List<int> data, String address, List<int> in_addr, int port) { |
1811 return new Datagram(data, new _InternetAddress(address, null, in_addr), port); | 1837 return new Datagram(data, new _InternetAddress(address, null, in_addr), port); |
1812 } | 1838 } |
OLD | NEW |