]> git.proxmox.com Git - mirror_edk2.git/blame - AppPkg/Applications/Python/Python-2.7.2/Lib/SimpleHTTPServer.py
EmbeddedPkg: Extend NvVarStoreFormattedLib LIBRARY_CLASS
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.2 / Lib / SimpleHTTPServer.py
CommitLineData
4710c53d 1"""Simple HTTP Server.\r
2\r
3This module builds on BaseHTTPServer by implementing the standard GET\r
4and HEAD requests in a fairly straightforward manner.\r
5\r
6"""\r
7\r
8\r
9__version__ = "0.6"\r
10\r
11__all__ = ["SimpleHTTPRequestHandler"]\r
12\r
13import os\r
14import posixpath\r
15import BaseHTTPServer\r
16import urllib\r
17import cgi\r
18import sys\r
19import shutil\r
20import mimetypes\r
21try:\r
22 from cStringIO import StringIO\r
23except ImportError:\r
24 from StringIO import StringIO\r
25\r
26\r
27class SimpleHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):\r
28\r
29 """Simple HTTP request handler with GET and HEAD commands.\r
30\r
31 This serves files from the current directory and any of its\r
32 subdirectories. The MIME type for files is determined by\r
33 calling the .guess_type() method.\r
34\r
35 The GET and HEAD requests are identical except that the HEAD\r
36 request omits the actual contents of the file.\r
37\r
38 """\r
39\r
40 server_version = "SimpleHTTP/" + __version__\r
41\r
42 def do_GET(self):\r
43 """Serve a GET request."""\r
44 f = self.send_head()\r
45 if f:\r
46 self.copyfile(f, self.wfile)\r
47 f.close()\r
48\r
49 def do_HEAD(self):\r
50 """Serve a HEAD request."""\r
51 f = self.send_head()\r
52 if f:\r
53 f.close()\r
54\r
55 def send_head(self):\r
56 """Common code for GET and HEAD commands.\r
57\r
58 This sends the response code and MIME headers.\r
59\r
60 Return value is either a file object (which has to be copied\r
61 to the outputfile by the caller unless the command was HEAD,\r
62 and must be closed by the caller under all circumstances), or\r
63 None, in which case the caller has nothing further to do.\r
64\r
65 """\r
66 path = self.translate_path(self.path)\r
67 f = None\r
68 if os.path.isdir(path):\r
69 if not self.path.endswith('/'):\r
70 # redirect browser - doing basically what apache does\r
71 self.send_response(301)\r
72 self.send_header("Location", self.path + "/")\r
73 self.end_headers()\r
74 return None\r
75 for index in "index.html", "index.htm":\r
76 index = os.path.join(path, index)\r
77 if os.path.exists(index):\r
78 path = index\r
79 break\r
80 else:\r
81 return self.list_directory(path)\r
82 ctype = self.guess_type(path)\r
83 try:\r
84 # Always read in binary mode. Opening files in text mode may cause\r
85 # newline translations, making the actual size of the content\r
86 # transmitted *less* than the content-length!\r
87 f = open(path, 'rb')\r
88 except IOError:\r
89 self.send_error(404, "File not found")\r
90 return None\r
91 self.send_response(200)\r
92 self.send_header("Content-type", ctype)\r
93 fs = os.fstat(f.fileno())\r
94 self.send_header("Content-Length", str(fs[6]))\r
95 self.send_header("Last-Modified", self.date_time_string(fs.st_mtime))\r
96 self.end_headers()\r
97 return f\r
98\r
99 def list_directory(self, path):\r
100 """Helper to produce a directory listing (absent index.html).\r
101\r
102 Return value is either a file object, or None (indicating an\r
103 error). In either case, the headers are sent, making the\r
104 interface the same as for send_head().\r
105\r
106 """\r
107 try:\r
108 list = os.listdir(path)\r
109 except os.error:\r
110 self.send_error(404, "No permission to list directory")\r
111 return None\r
112 list.sort(key=lambda a: a.lower())\r
113 f = StringIO()\r
114 displaypath = cgi.escape(urllib.unquote(self.path))\r
115 f.write('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">')\r
116 f.write("<html>\n<title>Directory listing for %s</title>\n" % displaypath)\r
117 f.write("<body>\n<h2>Directory listing for %s</h2>\n" % displaypath)\r
118 f.write("<hr>\n<ul>\n")\r
119 for name in list:\r
120 fullname = os.path.join(path, name)\r
121 displayname = linkname = name\r
122 # Append / for directories or @ for symbolic links\r
123 if os.path.isdir(fullname):\r
124 displayname = name + "/"\r
125 linkname = name + "/"\r
126 if os.path.islink(fullname):\r
127 displayname = name + "@"\r
128 # Note: a link to a directory displays with @ and links with /\r
129 f.write('<li><a href="%s">%s</a>\n'\r
130 % (urllib.quote(linkname), cgi.escape(displayname)))\r
131 f.write("</ul>\n<hr>\n</body>\n</html>\n")\r
132 length = f.tell()\r
133 f.seek(0)\r
134 self.send_response(200)\r
135 encoding = sys.getfilesystemencoding()\r
136 self.send_header("Content-type", "text/html; charset=%s" % encoding)\r
137 self.send_header("Content-Length", str(length))\r
138 self.end_headers()\r
139 return f\r
140\r
141 def translate_path(self, path):\r
142 """Translate a /-separated PATH to the local filename syntax.\r
143\r
144 Components that mean special things to the local file system\r
145 (e.g. drive or directory names) are ignored. (XXX They should\r
146 probably be diagnosed.)\r
147\r
148 """\r
149 # abandon query parameters\r
150 path = path.split('?',1)[0]\r
151 path = path.split('#',1)[0]\r
152 path = posixpath.normpath(urllib.unquote(path))\r
153 words = path.split('/')\r
154 words = filter(None, words)\r
155 path = os.getcwd()\r
156 for word in words:\r
157 drive, word = os.path.splitdrive(word)\r
158 head, word = os.path.split(word)\r
159 if word in (os.curdir, os.pardir): continue\r
160 path = os.path.join(path, word)\r
161 return path\r
162\r
163 def copyfile(self, source, outputfile):\r
164 """Copy all data between two file objects.\r
165\r
166 The SOURCE argument is a file object open for reading\r
167 (or anything with a read() method) and the DESTINATION\r
168 argument is a file object open for writing (or\r
169 anything with a write() method).\r
170\r
171 The only reason for overriding this would be to change\r
172 the block size or perhaps to replace newlines by CRLF\r
173 -- note however that this the default server uses this\r
174 to copy binary data as well.\r
175\r
176 """\r
177 shutil.copyfileobj(source, outputfile)\r
178\r
179 def guess_type(self, path):\r
180 """Guess the type of a file.\r
181\r
182 Argument is a PATH (a filename).\r
183\r
184 Return value is a string of the form type/subtype,\r
185 usable for a MIME Content-type header.\r
186\r
187 The default implementation looks the file's extension\r
188 up in the table self.extensions_map, using application/octet-stream\r
189 as a default; however it would be permissible (if\r
190 slow) to look inside the data to make a better guess.\r
191\r
192 """\r
193\r
194 base, ext = posixpath.splitext(path)\r
195 if ext in self.extensions_map:\r
196 return self.extensions_map[ext]\r
197 ext = ext.lower()\r
198 if ext in self.extensions_map:\r
199 return self.extensions_map[ext]\r
200 else:\r
201 return self.extensions_map['']\r
202\r
203 if not mimetypes.inited:\r
204 mimetypes.init() # try to read system mime.types\r
205 extensions_map = mimetypes.types_map.copy()\r
206 extensions_map.update({\r
207 '': 'application/octet-stream', # Default\r
208 '.py': 'text/plain',\r
209 '.c': 'text/plain',\r
210 '.h': 'text/plain',\r
211 })\r
212\r
213\r
214def test(HandlerClass = SimpleHTTPRequestHandler,\r
215 ServerClass = BaseHTTPServer.HTTPServer):\r
216 BaseHTTPServer.test(HandlerClass, ServerClass)\r
217\r
218\r
219if __name__ == '__main__':\r
220 test()\r