paulb@87 | 1 | #!/usr/bin/env python |
paulb@87 | 2 | |
paulb@87 | 3 | "A form submission test." |
paulb@87 | 4 | |
paulb@87 | 5 | import WebStack.Generic |
paulb@87 | 6 | |
paulb@87 | 7 | class FormResource: |
paulb@87 | 8 | |
paulb@87 | 9 | """ |
paulb@87 | 10 | A resource which handles incoming form submissions. |
paulb@87 | 11 | """ |
paulb@87 | 12 | |
paulb@87 | 13 | def respond(self, trans): |
paulb@87 | 14 | |
paulb@87 | 15 | """ |
paulb@87 | 16 | Examine the incoming request, decoding the form information. |
paulb@87 | 17 | """ |
paulb@87 | 18 | |
paulb@87 | 19 | # NOTE: Some frameworks do not pass in the content type. |
paulb@87 | 20 | |
paulb@87 | 21 | content_type = trans.get_content_type() |
paulb@195 | 22 | if content_type: |
paulb@226 | 23 | content_type_str = content_type.media_type |
paulb@222 | 24 | content_type_charset = content_type.charset |
paulb@195 | 25 | else: |
paulb@195 | 26 | content_type_str = None |
paulb@222 | 27 | content_type_charset = None |
paulb@195 | 28 | |
paulb@222 | 29 | # Optional encodings can be employed. |
paulb@222 | 30 | |
paulb@222 | 31 | fields_from_path = trans.get_fields_from_path() |
paulb@222 | 32 | |
paulb@222 | 33 | # Send the appropriate kind of response. |
paulb@87 | 34 | |
paulb@222 | 35 | if fields_from_path.has_key("charset"): |
paulb@222 | 36 | charset = fields_from_path["charset"][0] |
paulb@222 | 37 | trans.set_content_type(WebStack.Generic.ContentType("text/html", charset)) |
paulb@222 | 38 | elif content_type_charset: |
paulb@222 | 39 | charset = content_type_charset |
paulb@222 | 40 | trans.set_content_type(WebStack.Generic.ContentType("text/html", charset)) |
paulb@222 | 41 | else: |
paulb@222 | 42 | charset = None |
paulb@222 | 43 | trans.set_content_type(WebStack.Generic.ContentType("text/html")) |
paulb@87 | 44 | |
paulb@222 | 45 | # Handle charset issues. |
paulb@222 | 46 | |
paulb@222 | 47 | if charset: |
paulb@222 | 48 | fields = trans.get_fields_from_body(charset) |
paulb@251 | 49 | all_fields = trans.get_fields(charset) |
paulb@222 | 50 | else: |
paulb@222 | 51 | fields = trans.get_fields_from_body() |
paulb@251 | 52 | all_fields = trans.get_fields() |
paulb@222 | 53 | |
paulb@87 | 54 | out = trans.get_response_stream() |
paulb@233 | 55 | |
paulb@233 | 56 | # Use Unicode for correct character encoding behaviour. |
paulb@233 | 57 | |
paulb@231 | 58 | out.write(u""" |
paulb@87 | 59 | <html> |
paulb@87 | 60 | <head> |
paulb@87 | 61 | <title>Form Test</title> |
paulb@87 | 62 | </head> |
paulb@87 | 63 | <body> |
paulb@87 | 64 | <h1>Form Test</h1> |
paulb@266 | 65 | <table border="1" cellspacing="0" cellpadding="5"> |
paulb@266 | 66 | <tr> |
paulb@266 | 67 | <th>Normal</th> |
paulb@266 | 68 | <th>Multipart</th> |
paulb@266 | 69 | </tr> |
paulb@266 | 70 | <tr> |
paulb@266 | 71 | <td> |
paulb@266 | 72 | <form method="post" action=""> |
paulb@266 | 73 | <input name="x" type="text" value="1"/><br/> |
paulb@266 | 74 | <input name="x" type="text" value="2"/><br/> |
paulb@266 | 75 | <input name="y" type="text" value="3"/><br/> |
paulb@266 | 76 | <input name="f" type="file"/><br/> |
paulb@266 | 77 | <input name="send" type="submit" value="Send!"/> |
paulb@266 | 78 | </form> |
paulb@266 | 79 | </td> |
paulb@266 | 80 | <td> |
paulb@266 | 81 | <form method="post" action="" enctype="multipart/form-data"> |
paulb@266 | 82 | <input name="x" type="text" value="1"/><br/> |
paulb@266 | 83 | <input name="x" type="text" value="2"/><br/> |
paulb@266 | 84 | <input name="y" type="text" value="3"/><br/> |
paulb@266 | 85 | <input name="f" type="file"/><br/> |
paulb@266 | 86 | <input name="send" type="submit" value="Send!"/> |
paulb@266 | 87 | </form> |
paulb@266 | 88 | </td> |
paulb@266 | 89 | </tr> |
paulb@266 | 90 | <tr> |
paulb@266 | 91 | <th rowspan="2">Content Type</th> |
paulb@266 | 92 | <th colspan="2">Charset</th> |
paulb@266 | 93 | </tr> |
paulb@266 | 94 | <tr> |
paulb@266 | 95 | <th>From Content Type</th> |
paulb@266 | 96 | <th>In Use</th> |
paulb@266 | 97 | </tr> |
paulb@266 | 98 | <tr> |
paulb@266 | 99 | <td>%s</td> |
paulb@266 | 100 | <td>%s</td> |
paulb@266 | 101 | <td>%s</td> |
paulb@266 | 102 | </tr> |
paulb@266 | 103 | <tr> |
paulb@266 | 104 | <th>Fields from Body</th> |
paulb@266 | 105 | <th>Fields from Body and Path</th> |
paulb@266 | 106 | </tr> |
paulb@266 | 107 | <tr> |
paulb@266 | 108 | <td> |
paulb@266 | 109 | <ul>%s</ul> |
paulb@266 | 110 | </td> |
paulb@266 | 111 | <td> |
paulb@266 | 112 | <ul>%s</ul> |
paulb@266 | 113 | </td> |
paulb@266 | 114 | </tr> |
paulb@266 | 115 | </table> |
paulb@87 | 116 | </body> |
paulb@87 | 117 | </html> |
paulb@195 | 118 | """ % ( |
paulb@195 | 119 | content_type_str, |
paulb@222 | 120 | content_type_charset, |
paulb@222 | 121 | charset, |
paulb@251 | 122 | self._format_fields(fields), |
paulb@251 | 123 | self._format_fields(all_fields), |
paulb@195 | 124 | )) |
paulb@195 | 125 | |
paulb@195 | 126 | def _format_fields(self, d): |
paulb@195 | 127 | return "".join([ |
paulb@288 | 128 | "<li>%s<ul>%s</ul></li>" % (key or "<em>empty</em>", self._format_list(value)) |
paulb@195 | 129 | for key, value in d.items() |
paulb@195 | 130 | ]) |
paulb@195 | 131 | |
paulb@195 | 132 | def _format_list(self, l): |
paulb@461 | 133 | l2 = [] |
paulb@461 | 134 | for value in l: |
paulb@465 | 135 | |
paulb@465 | 136 | # Detect uploads. |
paulb@465 | 137 | |
paulb@465 | 138 | if type(value) not in (type(""), type(u"")): |
paulb@725 | 139 | value.reset() |
paul@770 | 140 | details = "file %s of type %s with length %s: %s" % ( |
paul@770 | 141 | value.filename, |
paulb@717 | 142 | value.headers.get("content-type") or "No content type", |
paulb@717 | 143 | value.headers.get("content-length") or "Unknown", |
paulb@717 | 144 | repr(value.stream.read(20)) |
paulb@717 | 145 | ) |
paulb@717 | 146 | else: |
paulb@717 | 147 | details = value |
paulb@465 | 148 | |
paulb@717 | 149 | l2.append("<li>%s</li>" % (details.replace("&", "&").replace("<", "<").replace(">", ">") or "<em>empty</em>")) |
paulb@717 | 150 | |
paulb@461 | 151 | return "".join(l2) |
paulb@87 | 152 | |
paulb@87 | 153 | # vim: tabstop=4 expandtab shiftwidth=4 |