(self, file_path, block_size=64 * 1024, send_header=True, header_length=True, header_noscript=False, header_allow_ajax=False, file_size=None, file_obj=None, path_parts=None)
| 676 | |
| 677 | # Stream a file to client |
| 678 | def actionFile(self, file_path, block_size=64 * 1024, send_header=True, header_length=True, header_noscript=False, header_allow_ajax=False, file_size=None, file_obj=None, path_parts=None): |
| 679 | file_name = os.path.basename(file_path) |
| 680 | |
| 681 | if file_size is None: |
| 682 | file_size = helper.getFilesize(file_path) |
| 683 | |
| 684 | if file_size is not None: |
| 685 | # Try to figure out content type by extension |
| 686 | content_type = self.getContentType(file_name) |
| 687 | |
| 688 | range = self.env.get("HTTP_RANGE") |
| 689 | range_start = None |
| 690 | |
| 691 | is_html_file = file_name.endswith(".html") |
| 692 | if is_html_file: |
| 693 | header_length = False |
| 694 | |
| 695 | if send_header: |
| 696 | extra_headers = {} |
| 697 | extra_headers["Accept-Ranges"] = "bytes" |
| 698 | if header_length: |
| 699 | extra_headers["Content-Length"] = str(file_size) |
| 700 | if range: |
| 701 | range_start = int(re.match(".*?([0-9]+)", range).group(1)) |
| 702 | if re.match(".*?-([0-9]+)", range): |
| 703 | range_end = int(re.match(".*?-([0-9]+)", range).group(1)) + 1 |
| 704 | else: |
| 705 | range_end = file_size |
| 706 | extra_headers["Content-Length"] = str(range_end - range_start) |
| 707 | extra_headers["Content-Range"] = "bytes %s-%s/%s" % (range_start, range_end - 1, file_size) |
| 708 | if range: |
| 709 | status = 206 |
| 710 | else: |
| 711 | status = 200 |
| 712 | self.sendHeader(status, content_type=content_type, noscript=header_noscript, allow_ajax=header_allow_ajax, extra_headers=extra_headers) |
| 713 | if self.env["REQUEST_METHOD"] != "OPTIONS": |
| 714 | if not file_obj: |
| 715 | file_obj = open(file_path, "rb") |
| 716 | |
| 717 | if range_start: |
| 718 | file_obj.seek(range_start) |
| 719 | while 1: |
| 720 | try: |
| 721 | block = file_obj.read(block_size) |
| 722 | if is_html_file: |
| 723 | block = self.replaceHtmlVariables(block, path_parts) |
| 724 | if block: |
| 725 | yield block |
| 726 | else: |
| 727 | raise StopIteration |
| 728 | except StopIteration: |
| 729 | file_obj.close() |
| 730 | break |
| 731 | else: # File not exists |
| 732 | for part in self.error404(str(file_path)): |
| 733 | yield part |
| 734 | |
| 735 | # On websocket connection |
no test coverage detected