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 | |
10 import hashlib | 9 import hashlib |
11 import logging | 10 import logging |
12 import math | 11 import math |
13 import os.path | 12 import os.path |
14 import shutil | |
15 import socket | 13 import socket |
14 import subprocess | |
15 import tempfile | |
16 import threading | 16 import threading |
17 import tempfile | |
18 | 17 |
19 import SimpleHTTPServer | 18 import SimpleHTTPServer |
20 import SocketServer | 19 import SocketServer |
21 | 20 |
22 _ZERO = datetime.timedelta(0) | 21 _ZERO = datetime.timedelta(0) |
23 | 22 |
24 | 23 |
25 class UTC_TZINFO(datetime.tzinfo): | 24 class UTC_TZINFO(datetime.tzinfo): |
26 """UTC time zone representation.""" | 25 """UTC time zone representation.""" |
27 | 26 |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
139 | 138 |
140 # pylint: disable=W0221 | 139 # pylint: disable=W0221 |
141 def translate_path(self, path, gzipped=True): | 140 def translate_path(self, path, gzipped=True): |
142 # Parent translate_path() will strip away the query string and fragment | 141 # Parent translate_path() will strip away the query string and fragment |
143 # identifier, but also will prepend the cwd to the path. relpath() gives | 142 # identifier, but also will prepend the cwd to the path. relpath() gives |
144 # us the relative path back. | 143 # us the relative path back. |
145 normalized_path = os.path.relpath( | 144 normalized_path = os.path.relpath( |
146 SimpleHTTPServer.SimpleHTTPRequestHandler.translate_path(self, path)) | 145 SimpleHTTPServer.SimpleHTTPRequestHandler.translate_path(self, path)) |
147 | 146 |
148 for prefix, local_base_path_list in mappings: | 147 for prefix, local_base_path_list in mappings: |
149 if normalized_path.startswith(prefix): | 148 if not normalized_path.startswith(prefix): |
150 for local_base_path in local_base_path_list: | 149 continue |
151 candidate = os.path.join(local_base_path, | 150 |
152 normalized_path[len(prefix):]) | 151 for local_base_path in local_base_path_list: |
153 if os.path.isfile(candidate): | 152 candidate = os.path.join(local_base_path, |
154 if gzipped: | 153 normalized_path[len(prefix):]) |
155 if not self.gzipped_file: | 154 if os.path.isfile(candidate): |
156 self.gzipped_file = tempfile.NamedTemporaryFile(delete=False) | 155 if gzipped: |
157 self.original_file_name = candidate | 156 if not self.gzipped_file: |
158 with open(candidate, 'rb') as source: | 157 self.gzipped_file = tempfile.NamedTemporaryFile(delete=False) |
piotrt
2015/08/25 11:55:23
I would consider extracting lines 157-166? to a se
ppi
2015/08/25 12:07:43
Good point, done.
| |
159 with gzip.GzipFile(fileobj=self.gzipped_file) as target: | 158 self.original_file_name = candidate |
160 shutil.copyfileobj(source, target) | 159 try: |
161 self.gzipped_file.close() | 160 subprocess.check_call(['gzip', '-c', candidate], |
162 return self.gzipped_file.name | 161 stdout=self.gzipped_file) |
163 return candidate | 162 except Exception: |
164 else: | 163 print ('http_server: call to gzip failed, make sure that ' |
165 self.send_response(404) | 164 'gzip is installed on the host.') |
166 return None | 165 raise |
166 self.gzipped_file.close() | |
167 return self.gzipped_file.name | |
168 return candidate | |
169 else: | |
170 self.send_response(404) | |
171 return None | |
167 self.send_response(404) | 172 self.send_response(404) |
168 return None | 173 return None |
169 | 174 |
170 def guess_type(self, path): | 175 def guess_type(self, path): |
171 # This is needed so that exploded Sky apps without shebang can still run | 176 # This is needed so that exploded Sky apps without shebang can still run |
172 # thanks to content-type mappings. | 177 # thanks to content-type mappings. |
173 # TODO(ppi): drop this part once we can rely on the Sky files declaring | 178 # TODO(ppi): drop this part once we can rely on the Sky files declaring |
174 # correct shebang. | 179 # correct shebang. |
175 actual_path = self.original_file_name or path | 180 actual_path = self.original_file_name or path |
176 | 181 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
220 except socket.error as v: | 225 except socket.error as v: |
221 error_code = v[0] | 226 error_code = v[0] |
222 print 'Failed to start http server for %s on port %d: %s.' % ( | 227 print 'Failed to start http server for %s on port %d: %s.' % ( |
223 str(mappings), host_port, os.strerror(error_code)) | 228 str(mappings), host_port, os.strerror(error_code)) |
224 if error_code == errno.EADDRINUSE: | 229 if error_code == errno.EADDRINUSE: |
225 print (' Run `fuser %d/tcp` to find out which process is using the port;' | 230 print (' Run `fuser %d/tcp` to find out which process is using the port;' |
226 % host_port) | 231 % host_port) |
227 print (' or `fuser -k %d/tcp` terminate it.' % host_port) | 232 print (' or `fuser -k %d/tcp` terminate it.' % host_port) |
228 print '---' | 233 print '---' |
229 raise | 234 raise |
OLD | NEW |