(self, request)
| 565 | |
| 566 | @asyncio.coroutine |
| 567 | def handle(self, request): |
| 568 | filename = request.match_info['filename'] |
| 569 | try: |
| 570 | filepath = self._directory.joinpath(filename).resolve() |
| 571 | filepath.relative_to(self._directory) |
| 572 | except (ValueError, FileNotFoundError) as error: |
| 573 | # relatively safe |
| 574 | raise HTTPNotFound() from error |
| 575 | except Exception as error: |
| 576 | # perm error or other kind! |
| 577 | request.logger.exception(error) |
| 578 | raise HTTPNotFound() from error |
| 579 | |
| 580 | # Make sure that filepath is a file |
| 581 | if not filepath.is_file(): |
| 582 | raise HTTPNotFound() |
| 583 | |
| 584 | st = filepath.stat() |
| 585 | |
| 586 | modsince = request.if_modified_since |
| 587 | if modsince is not None and st.st_mtime <= modsince.timestamp(): |
| 588 | raise HTTPNotModified() |
| 589 | |
| 590 | ct, encoding = mimetypes.guess_type(str(filepath)) |
| 591 | if not ct: |
| 592 | ct = 'application/octet-stream' |
| 593 | |
| 594 | resp = self._response_factory() |
| 595 | resp.content_type = ct |
| 596 | if encoding: |
| 597 | resp.headers[hdrs.CONTENT_ENCODING] = encoding |
| 598 | resp.last_modified = st.st_mtime |
| 599 | |
| 600 | file_size = st.st_size |
| 601 | |
| 602 | resp.content_length = file_size |
| 603 | resp.set_tcp_cork(True) |
| 604 | try: |
| 605 | yield from resp.prepare(request) |
| 606 | |
| 607 | with filepath.open('rb') as f: |
| 608 | yield from self._sendfile(request, resp, f, file_size) |
| 609 | |
| 610 | finally: |
| 611 | resp.set_tcp_nodelay(True) |
| 612 | |
| 613 | return resp |
| 614 | |
| 615 | def __repr__(self): |
| 616 | name = "'" + self.name + "' " if self.name is not None else "" |
nothing calls this directly
no test coverage detected