| OLD | NEW |
| 1 #!mojo mojo:dart_content_handler | 1 #!mojo mojo:dart_content_handler |
| 2 // Copyright 2014 The Chromium Authors. All rights reserved. | 2 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 3 // Use of this source code is governed by a BSD-style license that can be | 3 // Use of this source code is governed by a BSD-style license that can be |
| 4 // found in the LICENSE file. | 4 // found in the LICENSE file. |
| 5 | 5 |
| 6 import 'dart:async'; | 6 import 'dart:async'; |
| 7 import 'dart:core'; | 7 import 'dart:core'; |
| 8 import 'dart:typed_data'; | 8 import 'dart:typed_data'; |
| 9 | 9 |
| 10 import 'package:mojo/application.dart'; | 10 import 'package:mojo/application.dart'; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 NetAddress makeIPv4NetAddress(List<int> addr, int port) { | 26 NetAddress makeIPv4NetAddress(List<int> addr, int port) { |
| 27 var rv = new NetAddress(); | 27 var rv = new NetAddress(); |
| 28 rv.family = NetAddressFamily.ipv4; | 28 rv.family = NetAddressFamily.ipv4; |
| 29 rv.ipv4 = new NetAddressIPv4(); | 29 rv.ipv4 = new NetAddressIPv4(); |
| 30 rv.ipv4.addr = new List<int>.from(addr); | 30 rv.ipv4.addr = new List<int>.from(addr); |
| 31 rv.ipv4.port = port; | 31 rv.ipv4.port = port; |
| 32 return rv; | 32 return rv; |
| 33 } | 33 } |
| 34 | 34 |
| 35 void fputs(files.File f, String s) { | 35 void fputs(files.File f, String s) { |
| 36 ignoreFuture(f.write((s + '\n').codeUnits, 0, files.Whence.fromCurrent)); | 36 f.write((s + '\n').codeUnits, 0, files.Whence.fromCurrent, (e, n) {}); |
| 37 } | 37 } |
| 38 | 38 |
| 39 // Connects the terminal |File| and the socket. | 39 // Connects the terminal |File| and the socket. |
| 40 // TODO(vtl): | 40 // TODO(vtl): |
| 41 // * Error handling: both connection/socket errors and terminal errors. | 41 // * Error handling: both connection/socket errors and terminal errors. |
| 42 // * Relatedly, we should listen for _socketSender's peer being closed (also | 42 // * Relatedly, we should listen for _socketSender's peer being closed (also |
| 43 // _socket, I guess). | 43 // _socket, I guess). |
| 44 // * Handle the socket send pipe being full (currently, we assume it's never | 44 // * Handle the socket send pipe being full (currently, we assume it's never |
| 45 // full). | 45 // full). |
| 46 class Connector { | 46 class Connector { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 58 : _readBuffer = new ByteData(16 * 1024), | 58 : _readBuffer = new ByteData(16 * 1024), |
| 59 _writeBuffer = new ByteData(16 * 1024); | 59 _writeBuffer = new ByteData(16 * 1024); |
| 60 | 60 |
| 61 Future connect(NetAddress remote_address) async { | 61 Future connect(NetAddress remote_address) async { |
| 62 try { | 62 try { |
| 63 var networkService = new NetworkServiceProxy.unbound(); | 63 var networkService = new NetworkServiceProxy.unbound(); |
| 64 _application.connectToService('mojo:network_service', networkService); | 64 _application.connectToService('mojo:network_service', networkService); |
| 65 | 65 |
| 66 NetAddress local_address = makeIPv4NetAddress([0, 0, 0, 0], 0); | 66 NetAddress local_address = makeIPv4NetAddress([0, 0, 0, 0], 0); |
| 67 var boundSocket = new TcpBoundSocketProxy.unbound(); | 67 var boundSocket = new TcpBoundSocketProxy.unbound(); |
| 68 await networkService.createTcpBoundSocket(local_address, boundSocket); | 68 var c = new Completer(); |
| 69 networkService.createTcpBoundSocket(local_address, boundSocket, (_) { |
| 70 c.complete(null); |
| 71 }); |
| 72 await networkService.responseOrError(c.future); |
| 69 await networkService.close(); | 73 await networkService.close(); |
| 70 | 74 |
| 71 var sendDataPipe = new MojoDataPipe(); | 75 var sendDataPipe = new MojoDataPipe(); |
| 72 _socketSender = sendDataPipe.producer; | 76 _socketSender = sendDataPipe.producer; |
| 73 var receiveDataPipe = new MojoDataPipe(); | 77 var receiveDataPipe = new MojoDataPipe(); |
| 74 _socketReceiver = receiveDataPipe.consumer; | 78 _socketReceiver = receiveDataPipe.consumer; |
| 75 _socket = new TcpConnectedSocketProxy.unbound(); | 79 _socket = new TcpConnectedSocketProxy.unbound(); |
| 76 await boundSocket.connect(remote_address, sendDataPipe.consumer, | 80 c = new Completer(); |
| 77 receiveDataPipe.producer, _socket); | 81 boundSocket.connect(remote_address, sendDataPipe.consumer, |
| 82 receiveDataPipe.producer, _socket, (_) { |
| 83 c.complete(null); |
| 84 }); |
| 85 await boundSocket.responseOrError(c.future); |
| 78 await boundSocket.close(); | 86 await boundSocket.close(); |
| 79 | 87 |
| 80 // Set up reading from the terminal. | 88 // Set up reading from the terminal. |
| 81 _startReadingFromTerminal(); | 89 _startReadingFromTerminal(); |
| 82 | 90 |
| 83 // Set up reading from the socket. | 91 // Set up reading from the socket. |
| 84 _socketReceiverEventSubscription = | 92 _socketReceiverEventSubscription = |
| 85 new MojoEventSubscription(_socketReceiver.handle); | 93 new MojoEventSubscription(_socketReceiver.handle); |
| 86 _socketReceiverEventSubscription.subscribe(_onSocketReceiverEvent); | 94 _socketReceiverEventSubscription.subscribe(_onSocketReceiverEvent); |
| 87 } catch (e) { | 95 } catch (e) { |
| 88 _shutDown(); | 96 _shutDown(); |
| 89 } | 97 } |
| 90 } | 98 } |
| 91 | 99 |
| 92 void _startReadingFromTerminal() { | 100 void _startReadingFromTerminal() { |
| 93 // TODO(vtl): Do we have to do something on error? | 101 // TODO(vtl): Do we have to do something on error? |
| 94 _terminal | 102 var c = new Completer(); |
| 95 .read(_writeBuffer.lengthInBytes, 0, files.Whence.fromCurrent) | 103 _terminal.read( |
| 96 .then(_onReadFromTerminal) | 104 _writeBuffer.lengthInBytes, 0, |
| 97 .catchError((e) { | 105 files.Whence.fromCurrent, (error, bytes) { |
| 106 _onReadFromTerminal(error, bytes); |
| 107 c.complete(null); |
| 108 }); |
| 109 _terminal.responseOrError(c.future).catchError((_) { |
| 98 _shutDown(); | 110 _shutDown(); |
| 99 }); | 111 }); |
| 100 } | 112 } |
| 101 | 113 |
| 102 void _onReadFromTerminal(files.FileReadResponseParams p) { | 114 void _onReadFromTerminal(files.Error error, List<int> bytesRead) { |
| 103 if (p.error != files.Error.ok) { | 115 if (error != files.Error.ok) { |
| 104 // TODO(vtl): Do terminal errors. | 116 // TODO(vtl): Do terminal errors. |
| 105 return; | 117 return; |
| 106 } | 118 } |
| 107 | 119 |
| 108 // TODO(vtl): Verify that |bytesRead.length| is within the expected range. | 120 // TODO(vtl): Verify that |bytesRead.length| is within the expected range. |
| 109 for (var i = 0, j = 0; i < p.bytesRead.length; i++, j++) { | 121 for (var i = 0, j = 0; i < bytesRead.length; i++, j++) { |
| 110 // TODO(vtl): Temporary hack: Translate \r to \n, since we don't have | 122 // TODO(vtl): Temporary hack: Translate \r to \n, since we don't have |
| 111 // built-in support for that. | 123 // built-in support for that. |
| 112 if (p.bytesRead[i] == 13) { | 124 if (bytesRead[i] == 13) { |
| 113 _writeBuffer.setUint8(i, 10); | 125 _writeBuffer.setUint8(i, 10); |
| 114 } else { | 126 } else { |
| 115 _writeBuffer.setUint8(i, p.bytesRead[i]); | 127 _writeBuffer.setUint8(i, bytesRead[i]); |
| 116 } | 128 } |
| 117 } | 129 } |
| 118 | 130 |
| 119 // TODO(vtl): Handle the send data pipe being full (or closed). | 131 // TODO(vtl): Handle the send data pipe being full (or closed). |
| 120 _socketSender | 132 _socketSender |
| 121 .write(new ByteData.view(_writeBuffer.buffer, 0, p.bytesRead.length)); | 133 .write(new ByteData.view(_writeBuffer.buffer, 0, bytesRead.length)); |
| 122 | 134 |
| 123 _startReadingFromTerminal(); | 135 _startReadingFromTerminal(); |
| 124 } | 136 } |
| 125 | 137 |
| 126 void _onSocketReceiverEvent(int mojoSignals) { | 138 void _onSocketReceiverEvent(int mojoSignals) { |
| 127 var shouldShutDown = false; | 139 var shouldShutDown = false; |
| 128 if (MojoHandleSignals.isReadable(mojoSignals)) { | 140 if (MojoHandleSignals.isReadable(mojoSignals)) { |
| 129 var numBytesRead = _socketReceiver.read(_readBuffer); | 141 var numBytesRead = _socketReceiver.read(_readBuffer); |
| 130 if (_socketReceiver.status == MojoResult.kOk) { | 142 if (_socketReceiver.status == MojoResult.kOk) { |
| 131 assert(numBytesRead > 0); | 143 assert(numBytesRead > 0); |
| 132 _terminal | 144 var c = new Completer(); |
| 133 .write(_readBuffer.buffer.asUint8List(0, numBytesRead), 0, | 145 _terminal.write(_readBuffer.buffer.asUint8List(0, numBytesRead), 0, |
| 134 files.Whence.fromCurrent) | 146 files.Whence.fromCurrent, (e, n) { |
| 135 .catchError((e) { | 147 c.complete(null); |
| 148 }); |
| 149 _terminal.responseOrError(c.future).catchError((_) { |
| 136 _shutDown(); | 150 _shutDown(); |
| 137 }); | 151 }); |
| 138 _socketReceiverEventSubscription.enableReadEvents(); | 152 _socketReceiverEventSubscription.enableReadEvents(); |
| 139 } else { | 153 } else { |
| 140 shouldShutDown = true; | 154 shouldShutDown = true; |
| 141 } | 155 } |
| 142 } else if (MojoHandleSignals.isPeerClosed(mojoSignals)) { | 156 } else if (MojoHandleSignals.isPeerClosed(mojoSignals)) { |
| 143 shouldShutDown = true; | 157 shouldShutDown = true; |
| 144 } else { | 158 } else { |
| 145 String signals = MojoHandleSignals.string(mojoSignals); | 159 String signals = MojoHandleSignals.string(mojoSignals); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 232 } | 246 } |
| 233 } | 247 } |
| 234 | 248 |
| 235 main(List args, Object handleToken) { | 249 main(List args, Object handleToken) { |
| 236 MojoHandle appHandle = new MojoHandle(handleToken); | 250 MojoHandle appHandle = new MojoHandle(handleToken); |
| 237 new NetcatApplication.fromHandle(appHandle) | 251 new NetcatApplication.fromHandle(appHandle) |
| 238 ..onError = ((Object e) { | 252 ..onError = ((Object e) { |
| 239 MojoHandle.reportLeakedHandles(); | 253 MojoHandle.reportLeakedHandles(); |
| 240 }); | 254 }); |
| 241 } | 255 } |
| OLD | NEW |