1.1 --- a/WebStack/JavaServlet.py Mon Sep 06 21:29:59 2004 +0000
1.2 +++ b/WebStack/JavaServlet.py Mon Sep 06 21:31:04 2004 +0000
1.3 @@ -6,7 +6,7 @@
1.4
1.5 import Generic
1.6 from StringIO import StringIO
1.7 -from Helpers.Request import Cookie, get_body_fields, get_storage_items, get_fields_from_query_string
1.8 +from Helpers.Request import Cookie, get_body_fields, get_storage_items, get_fields_from_query_string, filter_fields
1.9 import javax.servlet.http
1.10
1.11 # Form data decoding.
1.12 @@ -45,7 +45,11 @@
1.13
1.14 "Read a line from the stream, returning it as a string."
1.15
1.16 - return self.stream.readLine() + "\n"
1.17 + line = self.stream.readLine()
1.18 + if line is not None:
1.19 + return line + "\n"
1.20 + else:
1.21 + return ""
1.22
1.23 class Transaction(Generic.Transaction):
1.24
1.25 @@ -75,7 +79,7 @@
1.26
1.27 # Cached information.
1.28
1.29 - self.storage_body = None
1.30 + self.message_fields = None
1.31
1.32 def commit(self):
1.33
1.34 @@ -221,9 +225,9 @@
1.35 def get_fields_from_path(self):
1.36
1.37 """
1.38 - Extracts the form fields from the path specified in the transaction. The
1.39 - underlying framework may refuse to supply fields from the path if
1.40 - handling a POST transaction.
1.41 + Extracts fields (or request parameters) from the path specified in the
1.42 + transaction. The underlying framework may refuse to supply fields from
1.43 + the path if handling a POST transaction.
1.44
1.45 Returns a dictionary mapping field names to lists of values (even if a
1.46 single value is associated with any given field name).
1.47 @@ -239,10 +243,10 @@
1.48 def get_fields_from_body(self, encoding=None):
1.49
1.50 """
1.51 - Extracts the form fields from the message body in the transaction. The
1.52 - optional 'encoding' parameter specifies the character encoding of the
1.53 - message body for cases where no such information is available, but where
1.54 - the default encoding is to be overridden.
1.55 + Extracts fields (or request parameters) from the message body in the
1.56 + transaction. The optional 'encoding' parameter specifies the character
1.57 + encoding of the message body for cases where no such information is
1.58 + available, but where the default encoding is to be overridden.
1.59
1.60 Returns a dictionary mapping field names to lists of values (even if a
1.61 single value is associated with any given field name). Each value is
1.62 @@ -250,6 +254,16 @@
1.63 or a plain string (representing a file upload form field, for example).
1.64 """
1.65
1.66 + # There may not be a reliable means of extracting only the fields
1.67 + # the message body using the API. Remove fields originating from the
1.68 + # path in the mixture provided by the API.
1.69 +
1.70 + all_fields = self._get_fields(encoding)
1.71 + fields_from_path = self.get_fields_from_path()
1.72 + return filter_fields(all_fields, fields_from_path)
1.73 +
1.74 + def _get_fields(self, encoding=None):
1.75 +
1.76 # Override the default encoding if requested.
1.77
1.78 if encoding is not None:
1.79 @@ -260,41 +274,51 @@
1.80 # methods.
1.81
1.82 if self.get_content_type() and self.get_content_type().media_type == "multipart/form-data":
1.83 - fields = self._get_fields_from_message()
1.84 -
1.85 + if self.message_fields is not None:
1.86 + return self.message_fields
1.87 + else:
1.88 + fields = self.message_fields = self._get_fields_from_message()
1.89 else:
1.90 - # There may not be a reliable means of extracting only the fields
1.91 - # the message body using the API. Remove fields originating from the
1.92 - # path in the mixture provided by the API.
1.93 -
1.94 - fields_from_path = self.get_fields_from_path()
1.95 -
1.96 fields = {}
1.97 parameter_map = self.request.getParameterMap()
1.98 if parameter_map:
1.99 for field_name in parameter_map.keySet():
1.100 + fields[field_name] = parameter_map[field_name]
1.101
1.102 - # Find path values for this field.
1.103 + return fields
1.104 +
1.105 + def get_fields(self, encoding=None):
1.106
1.107 - if fields_from_path.has_key(field_name):
1.108 - field_from_path_values = fields_from_path[field_name]
1.109 - if type(field_from_path_values) != type([]):
1.110 - field_from_path_values = [field_from_path_values]
1.111 - else:
1.112 - field_from_path_values = []
1.113 + """
1.114 + Extracts fields (or request parameters) from both the path specified in
1.115 + the transaction as well as the message body. The optional 'encoding'
1.116 + parameter specifies the character encoding of the message body for cases
1.117 + where no such information is available, but where the default encoding
1.118 + is to be overridden.
1.119 +
1.120 + Returns a dictionary mapping field names to lists of values (even if a
1.121 + single value is associated with any given field name). Each value is
1.122 + either a Unicode object (representing a simple form field, for example)
1.123 + or a plain string (representing a file upload form field, for example).
1.124
1.125 - # Filter out path values.
1.126 + Where a given field name is used in both the path and message body to
1.127 + specify values, the values from both sources will be combined into a
1.128 + single list associated with that field name.
1.129 + """
1.130 +
1.131 + # NOTE: The Java Servlet API (like Zope) seems to provide only body
1.132 + # NOTE: fields upon POST requests.
1.133
1.134 - fields[field_name] = []
1.135 - for field_value in parameter_map[field_name]:
1.136 - if field_value not in field_from_path_values:
1.137 - fields[field_name].append(field_value)
1.138 -
1.139 - # Remove filtered entries.
1.140 -
1.141 - if fields[field_name] == []:
1.142 - del fields[field_name]
1.143 -
1.144 + if self.get_request_method() == "GET":
1.145 + return self._get_fields(encoding)
1.146 + else:
1.147 + fields = {}
1.148 + fields.update(self.get_fields_from_path())
1.149 + for name, values in self._get_fields(encoding).items():
1.150 + if not fields.has_key(name):
1.151 + fields[name] = values
1.152 + else:
1.153 + fields[name] += values
1.154 return fields
1.155
1.156 def get_user(self):