|
21 | 21 | IS_UASYNCIO_V3 = hasattr(asyncio, "__version__") and asyncio.__version__ >= (3,) |
22 | 22 |
|
23 | 23 |
|
| 24 | +MIME_TYPES_PER_EXT = { |
| 25 | + ".txt" : "text/plain", |
| 26 | + ".htm" : "text/html", |
| 27 | + ".html" : "text/html", |
| 28 | + ".css" : "text/css", |
| 29 | + ".csv" : "text/csv", |
| 30 | + ".js" : "application/javascript", |
| 31 | + ".xml" : "application/xml", |
| 32 | + ".xhtml" : "application/xhtml+xml", |
| 33 | + ".json" : "application/json", |
| 34 | + ".zip" : "application/zip", |
| 35 | + ".pdf" : "application/pdf", |
| 36 | + ".ts" : "application/typescript", |
| 37 | + ".woff" : "font/woff", |
| 38 | + ".woff2" : "font/woff2", |
| 39 | + ".ttf" : "font/ttf", |
| 40 | + ".otf" : "font/otf", |
| 41 | + ".jpg" : "image/jpeg", |
| 42 | + ".jpeg" : "image/jpeg", |
| 43 | + ".png" : "image/png", |
| 44 | + ".gif" : "image/gif", |
| 45 | + ".svg" : "image/svg+xml", |
| 46 | + ".ico" : "image/x-icon" |
| 47 | +} |
| 48 | + |
| 49 | + |
24 | 50 | def urldecode_plus(s): |
25 | 51 | """Decode urlencoded string (including '+' char). |
26 | 52 |
|
@@ -277,9 +303,16 @@ async def send_file(self, filename, content_type=None, content_encoding=None, ma |
277 | 303 | stat = os.stat(filename) |
278 | 304 | slen = str(stat[6]) |
279 | 305 | self.add_header('Content-Length', slen) |
280 | | - # Find content type |
| 306 | + |
| 307 | + # Set content-type header (if possible) |
281 | 308 | if content_type: |
282 | 309 | self.add_header('Content-Type', content_type) |
| 310 | + else: |
| 311 | + # Auto-detect mime type based on file extension (eg. .css) |
| 312 | + file_extension = "." + filename.split(".")[-1] |
| 313 | + if file_extension in MIME_TYPES_PER_EXT: |
| 314 | + self.add_header('Content-Type', MIME_TYPES_PER_EXT[file_extension]) |
| 315 | + |
283 | 316 | # Add content-encoding, if any |
284 | 317 | if content_encoding: |
285 | 318 | self.add_header('Content-Encoding', content_encoding) |
|
0 commit comments