| OLD | NEW |
| 1 # Copyright 2015 The Chromium Authors. All rights reserved. | 1 # Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 import atexit | 5 import atexit |
| 6 import datetime | 6 import datetime |
| 7 import email.utils | 7 import email.utils |
| 8 import errno | 8 import errno |
| 9 import gzip | 9 import gzip |
| 10 import hashlib | 10 import hashlib |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 class RequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler): | 67 class RequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler): |
| 68 """Handler for SocketServer.TCPServer that will serve the files from | 68 """Handler for SocketServer.TCPServer that will serve the files from |
| 69 local directiories over http. | 69 local directiories over http. |
| 70 | 70 |
| 71 A new instance is created for each request. | 71 A new instance is created for each request. |
| 72 """ | 72 """ |
| 73 | 73 |
| 74 def __init__(self, *args, **kwargs): | 74 def __init__(self, *args, **kwargs): |
| 75 self.etag = None | 75 self.etag = None |
| 76 self.gzipped_file = None | 76 self.gzipped_file = None |
| 77 self.original_file_name = None |
| 77 SimpleHTTPServer.SimpleHTTPRequestHandler.__init__(self, *args, **kwargs) | 78 SimpleHTTPServer.SimpleHTTPRequestHandler.__init__(self, *args, **kwargs) |
| 78 | 79 |
| 79 def get_etag(self): | 80 def get_etag(self): |
| 80 if self.etag: | 81 if self.etag: |
| 81 return self.etag | 82 return self.etag |
| 82 | 83 |
| 83 path = self.translate_path(self.path, False) | 84 path = self.translate_path(self.path, False) |
| 84 if not os.path.isfile(path): | 85 if not os.path.isfile(path): |
| 85 return None | 86 return None |
| 86 | 87 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 | 147 |
| 147 for prefix, local_base_path_list in mappings: | 148 for prefix, local_base_path_list in mappings: |
| 148 if normalized_path.startswith(prefix): | 149 if normalized_path.startswith(prefix): |
| 149 for local_base_path in local_base_path_list: | 150 for local_base_path in local_base_path_list: |
| 150 candidate = os.path.join(local_base_path, | 151 candidate = os.path.join(local_base_path, |
| 151 normalized_path[len(prefix):]) | 152 normalized_path[len(prefix):]) |
| 152 if os.path.isfile(candidate): | 153 if os.path.isfile(candidate): |
| 153 if gzipped: | 154 if gzipped: |
| 154 if not self.gzipped_file: | 155 if not self.gzipped_file: |
| 155 self.gzipped_file = tempfile.NamedTemporaryFile(delete=False) | 156 self.gzipped_file = tempfile.NamedTemporaryFile(delete=False) |
| 157 self.original_file_name = candidate |
| 156 with open(candidate, 'rb') as source: | 158 with open(candidate, 'rb') as source: |
| 157 with gzip.GzipFile(fileobj=self.gzipped_file) as target: | 159 with gzip.GzipFile(fileobj=self.gzipped_file) as target: |
| 158 shutil.copyfileobj(source, target) | 160 shutil.copyfileobj(source, target) |
| 159 self.gzipped_file.close() | 161 self.gzipped_file.close() |
| 160 return self.gzipped_file.name | 162 return self.gzipped_file.name |
| 161 return candidate | 163 return candidate |
| 162 else: | 164 else: |
| 163 self.send_response(404) | 165 self.send_response(404) |
| 164 return None | 166 return None |
| 165 self.send_response(404) | 167 self.send_response(404) |
| 166 return None | 168 return None |
| 167 | 169 |
| 168 def guess_type(self, path): | 170 def guess_type(self, path): |
| 169 # This is needed so that exploded Sky apps without shebang can still run | 171 # This is needed so that exploded Sky apps without shebang can still run |
| 170 # thanks to content-type mappings. | 172 # thanks to content-type mappings. |
| 171 # TODO(ppi): drop this part once we can rely on the Sky files declaring | 173 # TODO(ppi): drop this part once we can rely on the Sky files declaring |
| 172 # correct shebang. | 174 # correct shebang. |
| 173 if path.endswith('.dart') or path.endswith('.dart.gz'): | 175 actual_path = self.original_file_name or path |
| 176 |
| 177 if actual_path.endswith('.dart'): |
| 174 return 'application/dart' | 178 return 'application/dart' |
| 175 return SimpleHTTPServer.SimpleHTTPRequestHandler.guess_type(self, path) | 179 return SimpleHTTPServer.SimpleHTTPRequestHandler.guess_type(self, |
| 180 actual_path) |
| 176 | 181 |
| 177 def log_message(self, *_): | 182 def log_message(self, *_): |
| 178 """Override the base class method to disable logging.""" | 183 """Override the base class method to disable logging.""" |
| 179 pass | 184 pass |
| 180 | 185 |
| 181 def __del__(self): | 186 def __del__(self): |
| 182 if self.gzipped_file: | 187 if self.gzipped_file: |
| 183 os.remove(self.gzipped_file.name) | 188 os.remove(self.gzipped_file.name) |
| 184 | 189 |
| 185 RequestHandler.protocol_version = 'HTTP/1.1' | 190 RequestHandler.protocol_version = 'HTTP/1.1' |
| (...skipping 28 matching lines...) Expand all Loading... |
| 214 return httpd.server_address | 219 return httpd.server_address |
| 215 except socket.error as v: | 220 except socket.error as v: |
| 216 error_code = v[0] | 221 error_code = v[0] |
| 217 print 'Failed to start http server for %s on port %d: %s.' % ( | 222 print 'Failed to start http server for %s on port %d: %s.' % ( |
| 218 str(mappings), host_port, os.strerror(error_code)) | 223 str(mappings), host_port, os.strerror(error_code)) |
| 219 if error_code == errno.EADDRINUSE: | 224 if error_code == errno.EADDRINUSE: |
| 220 print (' Run `fuser %d/tcp` to find out which process is using the port.' | 225 print (' Run `fuser %d/tcp` to find out which process is using the port.' |
| 221 % host_port) | 226 % host_port) |
| 222 print '---' | 227 print '---' |
| 223 raise | 228 raise |
| OLD | NEW |