def restricted(filename):
for path in privates:
if samefile(path, filename): # unify all paths by os.stat
return True # else returns None=false
try:
form = cgi.FieldStorage()
filename = form['filename'].value # URL param or form field
except:
filename = 'cgi-bin\getfile.py' # else default filename
try:
assert not restricted(filename) # load unless private
filetext = open(filename).read() # platform unicode encoding
except AssertionError:
filetext = '(File access denied)'
except:
filetext = '(Error opening file: %s)' % sys.exc_info()[1]
if not formatted:
print('Content-type: text/plain\n') # send plain text
print(filetext) # works on NS, not IE?
else:
print('Content-type: text/html\n') # wrap up in HTML
print(html % (filename, cgi.escape(filetext)))
This Python server-side script simply extracts the filename from the parsed CGI inputs
object and reads and prints the text of the file to send it to the client browser. Depending
on the formatted global variable setting, it sends the file in either plain text mode (using
text/plain in the response header) or wrapped up in an HTML page definition (text/
html).
Both modes (and others) work in general under most browsers, but Internet Explorer
doesn’t handle the plain text mode as gracefully as Netscape does—during testing, it
popped up the Notepad text editor to view the downloaded text, but end-of-line char-
acters in Unix format made the file appear as one long line. (Netscape instead displays
the text correctly in the body of the response web page itself.) HTML display mode
works more portably with current browsers. More on this script’s restricted file logic
in a moment.
Let’s launch this script by typing its URL at the top of a browser, along with a desired
filename appended after the script’s name. Figure 15-28 shows the page we get by
visiting the following URL (the second source link in the language selector page of
Example 15-17 has a similar effect but a different file):
http://localhost/cgi-bin/getfile.py?filename=cgi-bin\languages-src.py
The body of this page shows the text of the server-side file whose name we passed at
the end of the URL; once it arrives, we can view its text, cut-and-paste to save it in a
file on the client, and so on. In fact, now that we have this generalized source code
1212 | Chapter 15: Server-Side Scripting