When these links are clicked, they invoke the simple CGI script in Example 15-25. This
script displays the inputs sent from the client on the standard error stream to avoid any
additional translations (for our locally running web server in Example 15-1, this routes
the printed text to the server’s console window).
Example 15-25. PP4E\Internet\Web\cgi-bin\badlink.py
import cgi, sys
form = cgi.FieldStorage() # print all inputs to stderr; stodout=reply page
for name in form.keys():
print('[%s:%s]' % (name, form[name].value), end=' ', file=sys.stderr)
Following is the (edited for space) output we get in our local Python-coded web server’s
console window for following each of the three links in the HTML page in turn using
Internet Explorer. The second and third yield the correct parameters set on the server
as a result of the HTML escaping or URL conventions employed, but the accidental
HTML escapes cause serious issues for the first unescaped link—the client’s HTML
parser translates these in unintended ways (results are similar under Chrome, but the
first link displays the non-ASCII section mark character with a different escape
sequence):
mark-VAIO - - [16/Jun/2010 10:43:24] b'[:c\xa7=d<=e] [job:b] [name:a] '
mark-VAIO - - [16/Jun/2010 10:43:24] CGI script exited OK
mark-VAIO - - [16/Jun/2010 10:43:27] b'[amp:c] [job:b] [lt:e] [name:a] [sect:d]'
mark-VAIO - - [16/Jun/2010 10:43:27] CGI script exited OK
mark-VAIO - - [16/Jun/2010 10:43:30] b'[amp:c] [job:b] [lt:e] [name:a] [sect:d]'
mark-VAIO - - [16/Jun/2010 10:43:30] CGI script exited OK
The moral of this story is that unless you can be sure that the names of all but the
leftmost URL query parameters embedded in HTML are not the same as the name of
any HTML character escape code like amp, you should generally either use a semicolon
as a separator, if supported by your tools, or run the entire URL through cgi.escape
after escaping its parameter names and values with urllib.parse.quote_plus:
>>> link = 'file.py?name=a&job=b&=c§=d<=e'
# escape for HTML
>>> import cgi
>>> cgi.escape(link)
'file.py?name=a&job=b&=c§=d<=e'
# escape for URL
>>> import urllib.parse
>>> elink = urllib.parse.quote_plus(link)
>>> elink
'file.py%3Fname%3Da%26job%3Db%26amp%3Dc%26sect%3Dd%26lt%3De'
# URL satisfies HTML too: same
>>> cgi.escape(elink)
'file.py%3Fname%3Da%26job%3Db%26amp%3Dc%26sect%3Dd%26lt%3De'
1208 | Chapter 15: Server-Side Scripting
Do
wnload from Wow! eBook <www.wowebook.com>