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