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 // VMOptions= | 5 // VMOptions= |
6 // VMOptions=--short_socket_read | 6 // VMOptions=--short_socket_read |
7 // VMOptions=--short_socket_write | 7 // VMOptions=--short_socket_write |
8 // VMOptions=--short_socket_read --short_socket_write | 8 // VMOptions=--short_socket_read --short_socket_write |
9 | 9 |
10 import "package:expect/expect.dart"; | 10 import "package:expect/expect.dart"; |
11 import "dart:isolate"; | 11 import "dart:isolate"; |
12 import "dart:io"; | 12 import "dart:io"; |
13 | 13 |
14 class IsolatedHttpServer { | 14 class IsolatedHttpServer { |
15 IsolatedHttpServer() | 15 IsolatedHttpServer() |
16 : _statusPort = new ReceivePort(), | 16 : _statusPort = new ReceivePort(), |
17 _serverPort = null { | 17 _serverPort = null; |
18 _serverPort = spawnFunction(startIsolatedHttpServer); | |
19 } | |
20 | 18 |
21 void setServerStartedHandler(void startedCallback(int port)) { | 19 void setServerStartedHandler(void startedCallback(int port)) { |
22 _startedCallback = startedCallback; | 20 _startedCallback = startedCallback; |
23 } | 21 } |
24 | 22 |
25 void start() { | 23 void start([bool chunkedEncoding = false]) { |
| 24 ReceivePort receivePort = new ReceivePort(); |
| 25 var remote = Isolate.spawn(startIsolatedHttpServer, receivePort.sendPort); |
| 26 receivePort.first.then((port) { |
| 27 _serverPort = port; |
| 28 |
| 29 if (chunkedEncoding) { |
| 30 // Send chunked encoding message to the server. |
| 31 port.send([new IsolatedHttpServerCommand.chunkedEncoding(), |
| 32 _statusPort.sendPort]); |
| 33 } |
| 34 |
| 35 // Send server start message to the server. |
| 36 var command = new IsolatedHttpServerCommand.start(); |
| 37 port.send([command, _statusPort.sendPort]); |
| 38 }); |
| 39 |
26 // Handle status messages from the server. | 40 // Handle status messages from the server. |
27 _statusPort.receive((var status, SendPort replyTo) { | 41 _statusPort.listen((var status) { |
28 if (status.isStarted) { | 42 if (status.isStarted) { |
29 _startedCallback(status.port); | 43 _startedCallback(status.port); |
30 } | 44 } |
31 }); | 45 }); |
32 | |
33 // Send server start message to the server. | |
34 var command = new IsolatedHttpServerCommand.start(); | |
35 _serverPort.send(command, _statusPort.toSendPort()); | |
36 } | 46 } |
37 | 47 |
38 void shutdown() { | 48 void shutdown() { |
39 // Send server stop message to the server. | 49 // Send server stop message to the server. |
40 _serverPort.send(new IsolatedHttpServerCommand.stop(), | 50 _serverPort.send([new IsolatedHttpServerCommand.stop(), |
41 _statusPort.toSendPort()); | 51 _statusPort.sendPort]); |
42 _statusPort.close(); | 52 _statusPort.close(); |
43 } | 53 } |
44 | 54 |
45 void chunkedEncoding() { | |
46 // Send chunked encoding message to the server. | |
47 _serverPort.send( | |
48 new IsolatedHttpServerCommand.chunkedEncoding(), | |
49 _statusPort.toSendPort()); | |
50 } | |
51 | |
52 ReceivePort _statusPort; // Port for receiving messages from the server. | 55 ReceivePort _statusPort; // Port for receiving messages from the server. |
53 SendPort _serverPort; // Port for sending messages to the server. | 56 SendPort _serverPort; // Port for sending messages to the server. |
54 var _startedCallback; | 57 var _startedCallback; |
55 } | 58 } |
56 | 59 |
57 | 60 |
58 class IsolatedHttpServerCommand { | 61 class IsolatedHttpServerCommand { |
59 static const START = 0; | 62 static const START = 0; |
60 static const STOP = 1; | 63 static const STOP = 1; |
61 static const CHUNKED_ENCODING = 2; | 64 static const CHUNKED_ENCODING = 2; |
(...skipping 23 matching lines...) Expand all Loading... |
85 bool get isStopped => _state == STOPPED; | 88 bool get isStopped => _state == STOPPED; |
86 bool get isError => _state == ERROR; | 89 bool get isError => _state == ERROR; |
87 | 90 |
88 int get port => _port; | 91 int get port => _port; |
89 | 92 |
90 int _state; | 93 int _state; |
91 int _port; | 94 int _port; |
92 } | 95 } |
93 | 96 |
94 | 97 |
95 void startIsolatedHttpServer() { | 98 void startIsolatedHttpServer(SendPort replyTo) { |
96 var server = new TestServer(); | 99 var server = new TestServer(); |
97 server.init(); | 100 server.init(); |
98 port.receive(server.dispatch); | 101 replyTo.send(server.dispatchSendPort); |
99 } | 102 } |
100 | 103 |
101 class TestServer { | 104 class TestServer { |
102 // Echo the request content back to the response. | 105 // Echo the request content back to the response. |
103 void _echoHandler(HttpRequest request) { | 106 void _echoHandler(HttpRequest request) { |
104 var response = request.response; | 107 var response = request.response; |
105 Expect.equals("POST", request.method); | 108 Expect.equals("POST", request.method); |
106 response.contentLength = request.contentLength; | 109 response.contentLength = request.contentLength; |
107 request.pipe(response); | 110 request.pipe(response); |
108 } | 111 } |
109 | 112 |
110 // Return a 404. | 113 // Return a 404. |
111 void _notFoundHandler(HttpRequest request) { | 114 void _notFoundHandler(HttpRequest request) { |
112 var response = request.response; | 115 var response = request.response; |
113 response.statusCode = HttpStatus.NOT_FOUND; | 116 response.statusCode = HttpStatus.NOT_FOUND; |
114 response.headers.set("Content-Type", "text/html; charset=UTF-8"); | 117 response.headers.set("Content-Type", "text/html; charset=UTF-8"); |
115 response.write("Page not found"); | 118 response.write("Page not found"); |
116 response.close(); | 119 response.close(); |
117 } | 120 } |
118 | 121 |
119 | 122 |
120 void init() { | 123 void init() { |
121 // Setup request handlers. | 124 // Setup request handlers. |
122 _requestHandlers = new Map(); | 125 _requestHandlers = new Map(); |
123 _requestHandlers["/echo"] = _echoHandler; | 126 _requestHandlers["/echo"] = _echoHandler; |
| 127 _dispatchPort = new ReceivePort(); |
| 128 _dispatchPort.listen(dispatch); |
124 } | 129 } |
125 | 130 |
126 void dispatch(message, SendPort replyTo) { | 131 SendPort get dispatchSendPort => _dispatchPort.sendPort; |
127 if (message.isStart) { | 132 |
| 133 void dispatch(message) { |
| 134 IsolatedHttpServerCommand command = message[0]; |
| 135 SendPort replyTo = message[1]; |
| 136 if (command.isStart) { |
128 try { | 137 try { |
129 HttpServer.bind("127.0.0.1", 0).then((server) { | 138 HttpServer.bind("127.0.0.1", 0).then((server) { |
130 _server = server; | 139 _server = server; |
131 _server.listen(_requestReceivedHandler); | 140 _server.listen(_requestReceivedHandler); |
132 replyTo.send( | 141 replyTo.send( |
133 new IsolatedHttpServerStatus.started(_server.port), null); | 142 new IsolatedHttpServerStatus.started(_server.port), null); |
134 }); | 143 }); |
135 } catch (e) { | 144 } catch (e) { |
136 replyTo.send(new IsolatedHttpServerStatus.error(), null); | 145 replyTo.send(new IsolatedHttpServerStatus.error(), null); |
137 } | 146 } |
138 } else if (message.isStop) { | 147 } else if (command.isStop) { |
139 _server.close(); | 148 _server.close(); |
140 port.close(); | 149 _dispatchPort.close(); |
141 replyTo.send(new IsolatedHttpServerStatus.stopped(), null); | 150 replyTo.send(new IsolatedHttpServerStatus.stopped(), null); |
142 } else if (message.isChunkedEncoding) { | 151 } else if (command.isChunkedEncoding) { |
143 _chunkedEncoding = true; | 152 _chunkedEncoding = true; |
144 } | 153 } |
145 } | 154 } |
146 | 155 |
147 void _requestReceivedHandler(HttpRequest request) { | 156 void _requestReceivedHandler(HttpRequest request) { |
148 var requestHandler =_requestHandlers[request.uri.path]; | 157 var requestHandler =_requestHandlers[request.uri.path]; |
149 if (requestHandler != null) { | 158 if (requestHandler != null) { |
150 requestHandler(request); | 159 requestHandler(request); |
151 } else { | 160 } else { |
152 _notFoundHandler(request); | 161 _notFoundHandler(request); |
153 } | 162 } |
154 } | 163 } |
155 | 164 |
156 HttpServer _server; // HTTP server instance. | 165 HttpServer _server; // HTTP server instance. |
| 166 ReceivePort _dispatchPort; |
157 Map _requestHandlers; | 167 Map _requestHandlers; |
158 bool _chunkedEncoding = false; | 168 bool _chunkedEncoding = false; |
159 } | 169 } |
160 | 170 |
161 void testRead(bool chunkedEncoding) { | 171 void testRead(bool chunkedEncoding) { |
162 String data = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | 172 String data = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; |
163 final int kMessageCount = 10; | 173 final int kMessageCount = 10; |
164 | 174 |
165 IsolatedHttpServer server = new IsolatedHttpServer(); | 175 IsolatedHttpServer server = new IsolatedHttpServer(); |
166 | 176 |
(...skipping 26 matching lines...) Expand all Loading... |
193 httpClient.close(); | 203 httpClient.close(); |
194 server.shutdown(); | 204 server.shutdown(); |
195 } | 205 } |
196 }); | 206 }); |
197 }); | 207 }); |
198 } | 208 } |
199 sendRequest(); | 209 sendRequest(); |
200 } | 210 } |
201 | 211 |
202 server.setServerStartedHandler(runTest); | 212 server.setServerStartedHandler(runTest); |
203 if (chunkedEncoding) { | 213 server.start(chunkedEncoding); |
204 server.chunkedEncoding(); | |
205 } | |
206 server.start(); | |
207 } | 214 } |
208 | 215 |
209 void main() { | 216 void main() { |
210 testRead(true); | 217 testRead(true); |
211 testRead(false); | 218 testRead(false); |
212 } | 219 } |
OLD | NEW |