# HG changeset patch # User paulb # Date 1094382752 0 # Node ID fcf7098ad0d2588aa32978e4c91dd78f7a8a3991 # Parent eda1b744eec096b31bfcd729cf4f8aec1233599c [project @ 2004-09-05 11:12:32 by paulb] Introduced a general HeaderValue class, changed ContentType to be a subclass of this new class, added a parse_header_value method. Modified the JavaServlet module to use the parse_header_value method when inspecting multipart/form-data requests. diff -r eda1b744eec0 -r fcf7098ad0d2 WebStack/Generic.py --- a/WebStack/Generic.py Fri Sep 03 21:35:54 2004 +0000 +++ b/WebStack/Generic.py Sun Sep 05 11:12:32 2004 +0000 @@ -15,7 +15,46 @@ directors. """ -class ContentType: +class HeaderValue: + + "A container for header information." + + def __init__(self, principal_value, **attributes): + + """ + Initialise the container with the given 'principal_value' and optional + keyword attributes representing the key=value pairs which accompany the + 'principal_value'. + """ + + self.principal_value = principal_value + self.attributes = attributes + + def __getattr__(self, name): + if self.attributes.has_key(name): + return self.attributes[name] + else: + raise AttributeError, name + + def __str__(self): + + """ + Format the header value object, producing a string suitable for the + response header field. + """ + + l = [] + if self.principal_value: + l.append(self.principal_value) + for name, value in self.attributes.items(): + l.append("; ") + l.append("%s=%s" % (name, value)) + + # Make sure that only ASCII is used. + + return "".join(l).encode("US-ASCII") + +class ContentType(HeaderValue): "A container for content type information." @@ -27,30 +66,19 @@ pairs which qualify content types. """ - self.media_type = media_type - self.charset = charset - self.attributes = attributes - - def __str__(self): - - """ - Format the content type object, producing a string suitable for the - response header field. - """ + if charset is not None: + attributes["charset"] = charset + HeaderValue.__init__(self, media_type, **attributes) - l = [] - if self.media_type: - l.append(self.media_type) - if self.charset: - l.append("; ") - l.append("charset=%s" % self.charset) - for name, value in self.attributes.items(): - l.append("; ") - l.append("%s=%s" % (name, value)) - - # Make sure that only ASCII is used. - - return "".join(l).encode("US-ASCII") + def __getattr__(self, name): + if name == "media_type": + return self.principal_value + elif name == "charset": + return self.attributes.get("charset") + elif self.attributes.has_key(name): + return self.attributes[name] + else: + raise AttributeError, name class Transaction: @@ -74,34 +102,34 @@ # Utility methods. - def parse_content_type(self, content_type_field): + def parse_header_value(self, header_class, header_value_str): """ - Determine the content type and charset from the supplied - 'content_type_field' string. + Create an object of the given 'header_class' by determining the details + of the given 'header_value_str' - a string containing the value of a + particular header. """ - if content_type_field is None: - return ContentType(None) + if header_value_str is None: + return header_class(None) - l = content_type_field.split(";") + l = header_value_str.split(";") attributes = {} - charset = None - # Find the charset and remember all other attributes. + # Find the attributes. - media_type, attributes_str = l[0].strip(), l[1:] + principal_value, attributes_str = l[0].strip(), l[1:] for attribute_str in attributes_str: t = attribute_str.split("=") if len(t) > 1: name, value = t[0].strip(), t[1].strip() - if name == "charset": - charset = value - else: - attributes[name] = value + attributes[name] = value - return ContentType(media_type, charset, **attributes) + return header_class(principal_value, **attributes) + + def parse_content_type(self, content_type_field): + return self.parse_header_value(ContentType, content_type_field) def format_header_value(self, value): diff -r eda1b744eec0 -r fcf7098ad0d2 WebStack/JavaServlet.py --- a/WebStack/JavaServlet.py Fri Sep 03 21:35:54 2004 +0000 +++ b/WebStack/JavaServlet.py Sun Sep 05 11:12:32 2004 +0000 @@ -15,6 +15,7 @@ import javax.mail.Session import java.util.Properties import java.net.URLDecoder +from WebStack.Generic import HeaderValue class Stream: @@ -511,15 +512,14 @@ # Should get: form-data; name="x" - disposition = part.getHeader("Content-Disposition")[0] - name = self._get_header_attribute(disposition, "name") + disposition = self.parse_header_value(HeaderValue, part.getHeader("Content-Disposition")[0]) # Store and optionally convert the field. - if name is not None: - if not fields.has_key(name): - fields[name] = [] - fields[name].append(subcontent) + if disposition.name is not None: + if not fields.has_key(disposition.name[1:-1]): + fields[disposition.name[1:-1]] = [] + fields[disposition.name[1:-1]].append(subcontent) # Otherwise, descend deeper into the multipart hierarchy. @@ -528,15 +528,6 @@ return fields - def _get_header_attribute(self, header_value, attribute_name): - parts = header_value.split(";") - if len(parts) > 1: - for attribute in parts[1:]: - t = attribute.split("=") - if len(t) == 2 and t[0].strip() == attribute_name: - return t[1].strip()[1:-1] - return None - class Session: """