1.1 --- a/WebStack/JavaServlet.py Fri Aug 26 18:08:56 2005 +0000
1.2 +++ b/WebStack/JavaServlet.py Fri Aug 26 18:10:52 2005 +0000
1.3 @@ -20,25 +20,29 @@
1.4 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1.5 """
1.6
1.7 -import Generic
1.8 +import WebStack.Generic
1.9 from StringIO import StringIO
1.10 -from Helpers.Request import Cookie, get_body_fields, get_storage_items, get_fields_from_query_string, filter_fields
1.11 +from WebStack.Helpers.Request import Cookie, FileContent, get_body_fields, \
1.12 + get_storage_items, get_fields_from_query_string, filter_fields, \
1.13 + HeaderValue
1.14 import javax.servlet.http
1.15 +import jarray
1.16
1.17 -# Form data decoding.
1.18 +# Java API form data decoding.
1.19
1.20 import javax.mail.internet
1.21 import javax.mail
1.22 import java.util
1.23 import java.net
1.24 -from WebStack.Generic import HeaderValue
1.25
1.26 class Stream:
1.27
1.28 """
1.29 - Wrapper around java.io.BufferedReader.
1.30 + Wrapper around java.io.ServletInputStream.
1.31 """
1.32
1.33 + bufsize = 100
1.34 +
1.35 def __init__(self, stream):
1.36
1.37 "Initialise the stream with the given underlying 'stream'."
1.38 @@ -61,13 +65,28 @@
1.39
1.40 "Read a line from the stream, returning it as a string."
1.41
1.42 - line = self.stream.readLine()
1.43 - if line is not None:
1.44 - return line + "\n"
1.45 + characters = StringIO()
1.46 + a = jarray.zeros(self.bufsize, 'b')
1.47 + while 1:
1.48 + nread = self.stream.readLine(a, 0, self.bufsize)
1.49 + if nread != -1:
1.50 + self._copy(a, characters, nread)
1.51 + if nread != self.bufsize:
1.52 + return characters.getvalue()
1.53 +
1.54 + def _unsigned(self, i):
1.55 + if i < 0:
1.56 + return chr(256 + i)
1.57 else:
1.58 - return ""
1.59 + return chr(i)
1.60
1.61 -class Transaction(Generic.Transaction):
1.62 + def _copy(self, source, target, length):
1.63 + i = 0
1.64 + while i < length:
1.65 + target.write(self._unsigned(source[i]))
1.66 + i += 1
1.67 +
1.68 +class Transaction(WebStack.Generic.Transaction):
1.69
1.70 """
1.71 Java Servlet transaction interface.
1.72 @@ -129,7 +148,7 @@
1.73 Returns the request stream for the transaction.
1.74 """
1.75
1.76 - return Stream(self.request.getReader())
1.77 + return Stream(self.request.getInputStream())
1.78
1.79 def get_request_method(self):
1.80
1.81 @@ -333,7 +352,7 @@
1.82 if self.message_fields is not None:
1.83 return self.message_fields
1.84 else:
1.85 - fields = self.message_fields = self._get_fields_from_message()
1.86 + fields = self.message_fields = self._get_fields_from_message(encoding)
1.87 else:
1.88 fields = {}
1.89 parameter_map = self.request.getParameterMap()
1.90 @@ -545,7 +564,7 @@
1.91
1.92 # Special Java-specific methods.
1.93
1.94 - def _get_fields_from_message(self):
1.95 + def _get_fields_from_message(self, encoding):
1.96
1.97 "Get fields from a multipart message."
1.98
1.99 @@ -556,7 +575,7 @@
1.100 str_buffer = java.io.StringWriter()
1.101 fp = self.get_request_stream()
1.102 boundary = fp.readline()
1.103 - str_buffer.write('Content-Type: multipart/mixed; boundary="%s"\n\n' % boundary[2:-1])
1.104 + str_buffer.write('Content-Type: multipart/mixed; boundary="%s"\n\n' % boundary[2:-2])
1.105 str_buffer.write(boundary)
1.106 str_buffer.write(fp.read())
1.107 str_buffer.close()
1.108 @@ -566,9 +585,9 @@
1.109 input_stream = java.io.StringBufferInputStream(str_buffer.toString())
1.110 message = javax.mail.internet.MimeMessage(session, input_stream)
1.111 content = message.getContent()
1.112 - return self._get_fields_from_multipart(content)
1.113 + return self._get_fields_from_multipart(content, encoding)
1.114
1.115 - def _get_fields_from_multipart(self, content):
1.116 + def _get_fields_from_multipart(self, content, encoding):
1.117
1.118 "Get fields from multipart 'content'."
1.119
1.120 @@ -593,14 +612,28 @@
1.121 # Store and optionally convert the field.
1.122
1.123 if disposition.name is not None:
1.124 - if not fields.has_key(disposition.name[1:-1]):
1.125 - fields[disposition.name[1:-1]] = []
1.126 - fields[disposition.name[1:-1]].append(subcontent)
1.127 + field_name = disposition.name[1:-1]
1.128 +
1.129 + # Using properly decoded header values.
1.130 +
1.131 + if part.getHeader("Content-Type") is not None:
1.132 + headers = {}
1.133 + for header in part.getAllHeaders():
1.134 + headers[header.getName()] = self.parse_header_value(HeaderValue, header.getValue())
1.135 + field_value = FileContent(subcontent, headers)
1.136 + else:
1.137 + field_value = self.decode_path(subcontent, encoding)
1.138 +
1.139 + # Store the entry in the fields dictionary.
1.140 +
1.141 + if not fields.has_key(field_name):
1.142 + fields[field_name] = []
1.143 + fields[field_name].append(field_value)
1.144
1.145 # Otherwise, descend deeper into the multipart hierarchy.
1.146
1.147 else:
1.148 - fields.update(self._get_fields_from_multipart(subcontent))
1.149 + fields.update(self._get_fields_from_multipart(subcontent, encoding))
1.150
1.151 return fields
1.152