Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |