| OLD | NEW |
| 1 """HTTP server classes. | 1 """HTTP server classes. |
| 2 | 2 |
| 3 Note: BaseHTTPRequestHandler doesn't implement any HTTP request; see | 3 Note: BaseHTTPRequestHandler doesn't implement any HTTP request; see |
| 4 SimpleHTTPRequestHandler for simple implementations of GET, HEAD and POST, | 4 SimpleHTTPRequestHandler for simple implementations of GET, HEAD and POST, |
| 5 and CGIHTTPRequestHandler for CGI scripts. | 5 and CGIHTTPRequestHandler for CGI scripts. |
| 6 | 6 |
| 7 It does, however, optionally implement HTTP/1.1 persistent connections, | 7 It does, however, optionally implement HTTP/1.1 persistent connections, |
| 8 as of version 0.3. | 8 as of version 0.3. |
| 9 | 9 |
| 10 Notes on CGIHTTPRequestHandler | 10 Notes on CGIHTTPRequestHandler |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 77 # | | 77 # | |
| 78 # | You can determine the name of the file accessed through request. | 78 # | You can determine the name of the file accessed through request. |
| 79 # | 79 # |
| 80 # (Actually, the latter is only true if you know the server configuration | 80 # (Actually, the latter is only true if you know the server configuration |
| 81 # at the time the request was made!) | 81 # at the time the request was made!) |
| 82 | 82 |
| 83 __version__ = "0.6" | 83 __version__ = "0.6" |
| 84 | 84 |
| 85 __all__ = ["HTTPServer", "BaseHTTPRequestHandler"] | 85 __all__ = ["HTTPServer", "BaseHTTPRequestHandler"] |
| 86 | 86 |
| 87 import cgi | 87 import html |
| 88 import email.message | 88 import email.message |
| 89 import email.parser | 89 import email.parser |
| 90 import http.client | 90 import http.client |
| 91 import io | 91 import io |
| 92 import mimetypes | 92 import mimetypes |
| 93 import os | 93 import os |
| 94 import posixpath | 94 import posixpath |
| 95 import select | 95 import select |
| 96 import shutil | 96 import shutil |
| 97 import socket # For gethostbyaddr() | 97 import socket # For gethostbyaddr() |
| (...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 670 interface the same as for send_head(). | 670 interface the same as for send_head(). |
| 671 | 671 |
| 672 """ | 672 """ |
| 673 try: | 673 try: |
| 674 list = os.listdir(path) | 674 list = os.listdir(path) |
| 675 except os.error: | 675 except os.error: |
| 676 self.send_error(404, "No permission to list directory") | 676 self.send_error(404, "No permission to list directory") |
| 677 return None | 677 return None |
| 678 list.sort(key=lambda a: a.lower()) | 678 list.sort(key=lambda a: a.lower()) |
| 679 r = [] | 679 r = [] |
| 680 displaypath = cgi.escape(urllib.parse.unquote(self.path)) | 680 displaypath = html.escape(urllib.parse.unquote(self.path)) |
| 681 r.append('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">') | 681 r.append('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">') |
| 682 r.append("<html>\n<title>Directory listing for %s</title>\n" % displaypa
th) | 682 r.append("<html>\n<title>Directory listing for %s</title>\n" % displaypa
th) |
| 683 r.append("<body>\n<h2>Directory listing for %s</h2>\n" % displaypath) | 683 r.append("<body>\n<h2>Directory listing for %s</h2>\n" % displaypath) |
| 684 r.append("<hr>\n<ul>\n") | 684 r.append("<hr>\n<ul>\n") |
| 685 for name in list: | 685 for name in list: |
| 686 fullname = os.path.join(path, name) | 686 fullname = os.path.join(path, name) |
| 687 displayname = linkname = name | 687 displayname = linkname = name |
| 688 # Append / for directories or @ for symbolic links | 688 # Append / for directories or @ for symbolic links |
| 689 if os.path.isdir(fullname): | 689 if os.path.isdir(fullname): |
| 690 displayname = name + "/" | 690 displayname = name + "/" |
| 691 linkname = name + "/" | 691 linkname = name + "/" |
| 692 if os.path.islink(fullname): | 692 if os.path.islink(fullname): |
| 693 displayname = name + "@" | 693 displayname = name + "@" |
| 694 # Note: a link to a directory displays with @ and links with / | 694 # Note: a link to a directory displays with @ and links with / |
| 695 r.append('<li><a href="%s">%s</a>\n' | 695 r.append('<li><a href="%s">%s</a>\n' |
| 696 % (urllib.parse.quote(linkname), cgi.escape(displayname))) | 696 % (urllib.parse.quote(linkname), html.escape(displayname))) |
| 697 r.append("</ul>\n<hr>\n</body>\n</html>\n") | 697 r.append("</ul>\n<hr>\n</body>\n</html>\n") |
| 698 enc = sys.getfilesystemencoding() | 698 enc = sys.getfilesystemencoding() |
| 699 encoded = ''.join(r).encode(enc) | 699 encoded = ''.join(r).encode(enc) |
| 700 f = io.BytesIO() | 700 f = io.BytesIO() |
| 701 f.write(encoded) | 701 f.write(encoded) |
| 702 f.seek(0) | 702 f.seek(0) |
| 703 self.send_response(200) | 703 self.send_response(200) |
| 704 self.send_header("Content-type", "text/html; charset=%s" % enc) | 704 self.send_header("Content-type", "text/html; charset=%s" % enc) |
| 705 self.send_header("Content-Length", str(len(encoded))) | 705 self.send_header("Content-Length", str(len(encoded))) |
| 706 self.end_headers() | 706 self.end_headers() |
| (...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1132 print("Serving HTTP on", sa[0], "port", sa[1], "...") | 1132 print("Serving HTTP on", sa[0], "port", sa[1], "...") |
| 1133 try: | 1133 try: |
| 1134 httpd.serve_forever() | 1134 httpd.serve_forever() |
| 1135 except KeyboardInterrupt: | 1135 except KeyboardInterrupt: |
| 1136 print("\nKeyboard interrupt received, exiting.") | 1136 print("\nKeyboard interrupt received, exiting.") |
| 1137 httpd.server_close() | 1137 httpd.server_close() |
| 1138 sys.exit(0) | 1138 sys.exit(0) |
| 1139 | 1139 |
| 1140 if __name__ == '__main__': | 1140 if __name__ == '__main__': |
| 1141 test(HandlerClass=SimpleHTTPRequestHandler) | 1141 test(HandlerClass=SimpleHTTPRequestHandler) |
| OLD | NEW |