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

Side by Side Diff: dart/pkg/dart2js_incremental/lib/server.dart

Issue 863473002: Make server more resilient. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 5 years, 11 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 | no next file » | 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 library dart2js_incremental.server; 5 library dart2js_incremental.server;
6 6
7 import 'dart:io'; 7 import 'dart:io';
8 8
9 import 'dart:async' show 9 import 'dart:async' show
10 Future, 10 Future,
(...skipping 18 matching lines...) Expand all
29 29
30 static Uri packageRoot = Uri.base.resolve('packages/'); 30 static Uri packageRoot = Uri.base.resolve('packages/');
31 31
32 Conversation(this.request, this.response); 32 Conversation(this.request, this.response);
33 33
34 onClosed(_) { 34 onClosed(_) {
35 if (response.statusCode == HttpStatus.OK) return; 35 if (response.statusCode == HttpStatus.OK) return;
36 print('Request for ${request.uri} ${response.statusCode}'); 36 print('Request for ${request.uri} ${response.statusCode}');
37 } 37 }
38 38
39 notFound(path) { 39 Future notFound(Uri uri) {
40 response.headers.set(CONTENT_TYPE, 'text/html'); 40 response
41 response.statusCode = HttpStatus.NOT_FOUND; 41 ..headers.set(CONTENT_TYPE, 'text/html')
42 response.write(htmlInfo('Not Found', 42 ..statusCode = HttpStatus.NOT_FOUND
43 'The file "$path" could not be found.')); 43 ..write(htmlInfo("Not Found", "The file '$uri' could not be found."));
44 response.close(); 44 return response.close();
45 } 45 }
46 46
47 badRequest(String problem) { 47 Future badRequest(String problem) {
48 response.headers.set(CONTENT_TYPE, 'text/html'); 48 response
49 response.statusCode = HttpStatus.BAD_REQUEST; 49 ..headers.set(CONTENT_TYPE, 'text/html')
50 response.write(htmlInfo("Bad request", 50 ..statusCode = HttpStatus.BAD_REQUEST
51 "Bad request '${request.uri}': $problem")); 51 ..write(
52 response.close(); 52 htmlInfo("Bad request", "Bad request '${request.uri}': $problem"));
53 return response.close();
53 } 54 }
54 55
55 handleSocket() { 56 Future handleSocket() {
56 if (false && request.uri.path == '/ws/watch') { 57 if (false && request.uri.path == '/ws/watch') {
57 WebSocketTransformer.upgrade(request).then((WebSocket socket) { 58 return WebSocketTransformer.upgrade(request).then((WebSocket socket) {
58 socket.add(JSON.encode({'create': []})); 59 socket.add(JSON.encode({'create': []}));
59 // WatchHandler handler = new WatchHandler(socket, files); 60 // WatchHandler handler = new WatchHandler(socket, files);
60 // handlers.add(handler); 61 // handlers.add(handler);
61 // socket.listen( 62 // socket.listen(
62 // handler.onData, cancelOnError: true, onDone: handler.onDone); 63 // handler.onData, cancelOnError: true, onDone: handler.onDone);
63 }); 64 });
64 } else { 65 } else {
65 response.done 66 response.done
66 .then(onClosed) 67 .then(onClosed)
67 .catchError(onError); 68 .catchError(onError);
68 notFound(request.uri.path); 69 return notFound(request.uri);
69 } 70 }
70 } 71 }
71 72
72 handle() { 73 Future handle() {
73 response.done 74 response.done
74 .then(onClosed) 75 .then(onClosed)
75 .catchError(onError); 76 .catchError(onError);
76 77
77 Uri uri = request.uri; 78 Uri uri = request.uri;
78 if (uri.path.endsWith('/')) { 79 if (uri.path.endsWith('/')) {
79 uri = uri.resolve('index.html'); 80 uri = uri.resolve('index.html');
80 } 81 }
81 if (uri.path.contains('..') || uri.path.contains('%')) { 82 if (uri.path.contains('..') || uri.path.contains('%')) {
82 return notFound(uri.path); 83 return notFound(uri);
83 } 84 }
84 String path = uri.path; 85 String path = uri.path;
85 Uri root = documentRoot; 86 Uri root = documentRoot;
86 if (path.startsWith('${PACKAGES_PATH}/')) { 87 if (path.startsWith('${PACKAGES_PATH}/')) {
87 root = packageRoot; 88 root = packageRoot;
88 path = path.substring(PACKAGES_PATH.length); 89 path = path.substring(PACKAGES_PATH.length);
89 } 90 }
90 91
91 Uri resolvedRequest = root.resolve('.$path'); 92 Uri resolvedRequest = root.resolve('.$path');
92 switch (request.method) { 93 switch (request.method) {
93 case 'GET': 94 case 'GET':
94 return handleGet(resolvedRequest); 95 return handleGet(resolvedRequest);
95 default: 96 default:
96 String method = const HtmlEscape().convert(request.method); 97 String method = const HtmlEscape().convert(request.method);
97 return badRequest("Unsupported method: '$method'"); 98 return badRequest("Unsupported method: '$method'");
98 } 99 }
99 } 100 }
100 101
101 void handleGet(Uri uri) { 102 Future handleGet(Uri uri) {
102 String path = uri.path; 103 String path = uri.path;
103 var f = new File.fromUri(uri); 104 var f = new File.fromUri(uri);
104 f.exists().then((bool exists) { 105 return f.exists().then((bool exists) {
kasperl 2015/01/19 12:24:44 Maybe use await and mark the method async? bool e
ahe 2015/01/19 12:58:01 Next CL.
105 if (!exists) { 106 if (!exists) {
106 if (path.endsWith('.dart.js')) { 107 if (path.endsWith('.dart.js')) {
107 Uri dartScript = uri.resolve(path.substring(0, path.length - 3)); 108 Uri dartScript = uri.resolve(path.substring(0, path.length - 3));
108 new File.fromUri(dartScript).exists().then((bool exists) { 109 return new File.fromUri(dartScript).exists().then((bool exists) {
109 if (exists) { 110 if (exists) {
110 compileToJavaScript(dartScript); 111 return compileToJavaScript(dartScript);
111 } else { 112 } else {
112 notFound(request.uri); 113 return notFound(request.uri);
113 } 114 }
114 }); 115 });
115 return;
116 } 116 }
117 notFound(request.uri); 117 return notFound(request.uri);
118 return;
119 } 118 }
120 if (path.endsWith('.html')) { 119 if (path.endsWith('.html')) {
121 response.headers.set(CONTENT_TYPE, 'text/html'); 120 response.headers.set(CONTENT_TYPE, 'text/html');
122 } else if (path.endsWith('.dart')) { 121 } else if (path.endsWith('.dart')) {
123 response.headers.set(CONTENT_TYPE, 'application/dart'); 122 response.headers.set(CONTENT_TYPE, 'application/dart');
124 } else if (path.endsWith('.js')) { 123 } else if (path.endsWith('.js')) {
125 response.headers.set(CONTENT_TYPE, 'application/javascript'); 124 response.headers.set(CONTENT_TYPE, 'application/javascript');
126 } else if (path.endsWith('.ico')) { 125 } else if (path.endsWith('.ico')) {
127 response.headers.set(CONTENT_TYPE, 'image/x-icon'); 126 response.headers.set(CONTENT_TYPE, 'image/x-icon');
128 } else if (path.endsWith('.appcache')) { 127 } else if (path.endsWith('.appcache')) {
129 response.headers.set(CONTENT_TYPE, 'text/cache-manifest'); 128 response.headers.set(CONTENT_TYPE, 'text/cache-manifest');
130 } 129 }
131 f.openRead().pipe(response).catchError(onError); 130 return f.openRead().pipe(response);
132 }); 131 });
133 } 132 }
134 133
135 void compileToJavaScript(Uri dartScript) { 134 Future compileToJavaScript(Uri dartScript) {
136 Uri outputUri = request.uri; 135 Uri outputUri = request.uri;
137 print("Compiling $dartScript to $outputUri"); 136 print("Compiling $dartScript to $outputUri");
138 // TODO(ahe): Implement this. 137 // TODO(ahe): Implement this.
139 notFound(request.uri); 138 throw new UnimplementedError("compileToJavaScript");
139 return notFound(request.uri);
140 } 140 }
141 141
142 static onRequest(HttpRequest request) { 142 Future dispatch() {
143 Conversation conversation = new Conversation(request, request.response); 143 return new Future.sync(() {
144 if (WebSocketTransformer.isUpgradeRequest(request)) { 144 return WebSocketTransformer.isUpgradeRequest(request)
145 conversation.handleSocket(); 145 ? handleSocket()
146 } else { 146 : handle();
147 conversation.handle(); 147 }).catchError(onError);
148 }
149 } 148 }
150 149
151 static onError(error) { 150 static Future onRequest(HttpRequest request) {
151 HttpResponse response = request.response;
152 return
153 new Future.sync(() => new Conversation(request, response).dispatch())
154 .catchError((error, [stack]) {
155 onStaticError(error, stack);
156 return
157 new Future.sync(() => response.close()).catchError(onStaticError);
158 });
159 }
160
161 void onError(error, [stack]) {
162 onStaticError(error, stack);
163 new Future.sync(() => response.close()).catchError(onStaticError);
164 }
165
166 static void onStaticError(error, [stack]) {
152 if (error is HttpException) { 167 if (error is HttpException) {
153 print('Error: ${error.message}'); 168 print('Error: ${error.message}');
154 } else { 169 } else {
155 print('Error: ${error}'); 170 print('Error: ${error}');
156 } 171 }
172 if (stack != null) {
173 print(stack);
174 }
157 } 175 }
158 176
159 String htmlInfo(String title, String text) { 177 String htmlInfo(String title, String text) {
160 // No script injection, please. 178 // No script injection, please.
161 title = const HtmlEscape().convert(title); 179 title = const HtmlEscape().convert(title);
162 text = const HtmlEscape().convert(text); 180 text = const HtmlEscape().convert(text);
163 return """ 181 return """
164 <!DOCTYPE html> 182 <!DOCTYPE html>
165 <html lang='en'> 183 <html lang='en'>
166 <head> 184 <head>
(...skipping 14 matching lines...) Expand all
181 exit(1); 199 exit(1);
182 } 200 }
183 if (!options.arguments.isEmpty) { 201 if (!options.arguments.isEmpty) {
184 Conversation.documentRoot = Uri.base.resolve(options.arguments.single); 202 Conversation.documentRoot = Uri.base.resolve(options.arguments.single);
185 } 203 }
186 Conversation.packageRoot = options.packageRoot; 204 Conversation.packageRoot = options.packageRoot;
187 String host = options.host; 205 String host = options.host;
188 int port = options.port; 206 int port = options.port;
189 HttpServer.bind(host, port).then((HttpServer server) { 207 HttpServer.bind(host, port).then((HttpServer server) {
190 print('HTTP server started on http://$host:${server.port}/'); 208 print('HTTP server started on http://$host:${server.port}/');
191 server.listen(Conversation.onRequest, onError: Conversation.onError); 209 server.listen(Conversation.onRequest, onError: Conversation.onStaticError);
192 }).catchError((e) { 210 }).catchError((e) {
193 print("HttpServer.bind error: $e"); 211 print("HttpServer.bind error: $e");
194 exit(1); 212 exit(1);
195 }); 213 });
196 } 214 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698