1.1 --- a/WebStack/BaseHTTPRequestHandler.py Sat Oct 27 22:38:58 2007 +0000
1.2 +++ b/WebStack/BaseHTTPRequestHandler.py Sat Oct 27 22:39:22 2007 +0000
1.3 @@ -21,7 +21,7 @@
1.4 """
1.5
1.6 import WebStack.Generic
1.7 -from WebStack.Helpers.Request import MessageBodyStream, get_body_fields, decode_value, get_storage_items, Cookie
1.8 +from WebStack.Helpers.Request import MessageBodyStream, get_body_fields, decode_value, get_storage_items, Cookie, HeaderDict
1.9 from WebStack.Helpers.Response import ConvertingStream
1.10 from WebStack.Helpers.Auth import UserInfo
1.11 from WebStack.Helpers.Session import SessionStore
1.12 @@ -49,7 +49,7 @@
1.13 self.content_type = None
1.14 self.response_code = 200
1.15 self.content = StringIO()
1.16 - self.headers_out = {}
1.17 + self.headers_out = HeaderDict()
1.18 self.cookies_out = SimpleCookie()
1.19
1.20 # Define the incoming cookies.
1.21 @@ -112,7 +112,7 @@
1.22 """
1.23
1.24 self.content = StringIO()
1.25 - self.headers_out = {}
1.26 + self.headers_out = HeaderDict()
1.27 self.cookies_out = SimpleCookie()
1.28
1.29 # Server-related methods.
2.1 --- a/WebStack/CGI.py Sat Oct 27 22:38:58 2007 +0000
2.2 +++ b/WebStack/CGI.py Sat Oct 27 22:39:22 2007 +0000
2.3 @@ -22,7 +22,8 @@
2.4
2.5 import WebStack.Generic
2.6 import os, sys
2.7 -from WebStack.Helpers.Request import MessageBodyStream, get_body_fields, decode_value, get_storage_items, Cookie
2.8 +from WebStack.Helpers.Request import MessageBodyStream, get_body_fields, \
2.9 + decode_value, get_storage_items, Cookie, HeaderDict
2.10 from WebStack.Helpers.Response import ConvertingStream
2.11 from WebStack.Helpers.Auth import UserInfo
2.12 from WebStack.Helpers.Session import SessionStore
2.13 @@ -54,7 +55,7 @@
2.14 self.content_type = None
2.15 self.response_code = 200
2.16 self.content = StringIO()
2.17 - self.headers_out = {}
2.18 + self.headers_out = HeaderDict()
2.19 self.cookies_out = SimpleCookie()
2.20
2.21 # Define the incoming cookies.
2.22 @@ -109,7 +110,7 @@
2.23 """
2.24
2.25 self.content = StringIO()
2.26 - self.headers_out = {}
2.27 + self.headers_out = HeaderDict()
2.28 self.cookies_out = SimpleCookie()
2.29
2.30 # Server-related methods.
3.1 --- a/WebStack/Helpers/Environment.py Sat Oct 27 22:38:58 2007 +0000
3.2 +++ b/WebStack/Helpers/Environment.py Sat Oct 27 22:39:22 2007 +0000
3.3 @@ -20,6 +20,8 @@
3.4 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
3.5 """
3.6
3.7 +import WebStack.Helpers.Request
3.8 +
3.9 cgi_names = ("CONTENT_LENGTH", "CONTENT_TYPE")
3.10
3.11 def get_headers(env):
3.12 @@ -31,13 +33,14 @@
3.13 Returns a dictionary-like object containing likely headers.
3.14 """
3.15
3.16 - headers = {}
3.17 + headers = WebStack.Helpers.Request.HeaderDict()
3.18 +
3.19 for cgi_key, value in env.items():
3.20 if cgi_key.startswith("HTTP_"):
3.21 - header_name = cgi_key[len("HTTP_"):].replace("_", "-").lower()
3.22 + header_name = cgi_key[len("HTTP_"):].replace("_", "-")
3.23 headers[header_name] = value
3.24 elif cgi_key in cgi_names:
3.25 - header_name = cgi_key.replace("_", "-").lower()
3.26 + header_name = cgi_key.replace("_", "-")
3.27 headers[header_name] = value
3.28
3.29 return headers
4.1 --- a/WebStack/Helpers/Request.py Sat Oct 27 22:38:58 2007 +0000
4.2 +++ b/WebStack/Helpers/Request.py Sat Oct 27 22:39:22 2007 +0000
4.3 @@ -87,6 +87,52 @@
4.4
4.5 self.stream.close()
4.6
4.7 +class HeaderDict:
4.8 +
4.9 + "A dictionary for headers."
4.10 +
4.11 + def __init__(self, headers=None):
4.12 + self.headers = {}
4.13 + if headers is not None:
4.14 + self.update(headers)
4.15 +
4.16 + # Lower-case-string-coercing methods.
4.17 +
4.18 + def __getitem__(self, key):
4.19 + return self.headers[str(key).lower()]
4.20 +
4.21 + def __setitem__(self, key, value):
4.22 + self.headers[str(key).lower()] = value
4.23 +
4.24 + def get(self, key, default=None):
4.25 + return self.headers.get(str(key).lower(), default)
4.26 +
4.27 + def has_key(self, key):
4.28 + return self.headers.has_key(str(key).lower())
4.29 +
4.30 + # Forwarding methods.
4.31 +
4.32 + def keys(self):
4.33 + return self.headers.keys()
4.34 +
4.35 + def values(self):
4.36 + return self.headers.values()
4.37 +
4.38 + def items(self):
4.39 + return self.headers.items()
4.40 +
4.41 + # Derived from the above.
4.42 +
4.43 + def __contains__(self, key):
4.44 + return self.has_key(key)
4.45 +
4.46 + def update(self, other):
4.47 + for k, v in other.items():
4.48 + self[k] = v
4.49 +
4.50 + def __repr__(self):
4.51 + return "HeaderDict(%r)" % self.headers
4.52 +
4.53 class HeaderValue:
4.54
4.55 "A container for header information."
4.56 @@ -108,6 +154,9 @@
4.57 else:
4.58 raise AttributeError, name
4.59
4.60 + def __repr__(self):
4.61 + return "HeaderValue(%r)" % str(self)
4.62 +
4.63 def __str__(self):
4.64
4.65 """
4.66 @@ -191,7 +240,7 @@
4.67 """
4.68
4.69 self.stream = stream
4.70 - self.headers = headers or {}
4.71 + self.headers = headers or HeaderDict()
4.72 self.cache = None
4.73
4.74 def __getattr__(self, name):
4.75 @@ -269,7 +318,7 @@
4.76 returing a dictionary mapping names to HeaderValue objects.
4.77 """
4.78
4.79 - new_headers = {}
4.80 + new_headers = HeaderDict()
4.81 for name, value in headers.items():
4.82 new_headers[name] = parse_header_value(HeaderValue, value)
4.83 return new_headers
5.1 --- a/WebStack/JavaServlet.py Sat Oct 27 22:38:58 2007 +0000
5.2 +++ b/WebStack/JavaServlet.py Sat Oct 27 22:39:22 2007 +0000
5.3 @@ -24,7 +24,7 @@
5.4 from StringIO import StringIO
5.5 from WebStack.Helpers.Request import Cookie, FileContent, get_body_fields, \
5.6 get_storage_items, get_fields_from_query_string, filter_fields, \
5.7 - HeaderValue
5.8 + HeaderDict, HeaderValue
5.9 import javax.servlet.http
5.10 import jarray
5.11
5.12 @@ -183,7 +183,7 @@
5.13 NOTE: need to change.
5.14 """
5.15
5.16 - headers = {}
5.17 + headers = HeaderDict()
5.18 header_names_enum = self.request.getHeaderNames()
5.19 while header_names_enum.hasMoreElements():
5.20
5.21 @@ -520,8 +520,10 @@
5.22 time.time function, and indicates the expiry date/time of the cookie.
5.23 """
5.24
5.25 - cookie = javax.servlet.http.Cookie(self.encode_cookie_value(name),
5.26 - self.encode_cookie_value(value))
5.27 + cookie = javax.servlet.http.Cookie(
5.28 + self.encode_cookie_value(name),
5.29 + self.encode_cookie_value(value)
5.30 + )
5.31 if path is not None:
5.32 cookie.setPath(path)
5.33
5.34 @@ -620,7 +622,6 @@
5.35 boundary = fp.readline()
5.36 str_buffer.write('Content-Type: multipart/mixed; boundary="%s"\n\n' % boundary[2:-2])
5.37 str_buffer.write(boundary)
5.38 - str_buffer.write(fp.read())
5.39 str_buffer.close()
5.40
5.41 # Concatenate the headers with the rest of the stream.
5.42 @@ -664,7 +665,7 @@
5.43
5.44 # Using properly decoded header values.
5.45
5.46 - headers = {}
5.47 + headers = HeaderDict()
5.48 for header in part.getAllHeaders():
5.49 headers[header.getName()] = self.parse_header_value(HeaderValue, header.getValue())
5.50
6.1 --- a/WebStack/WSGI.py Sat Oct 27 22:38:58 2007 +0000
6.2 +++ b/WebStack/WSGI.py Sat Oct 27 22:39:22 2007 +0000
6.3 @@ -22,7 +22,8 @@
6.4
6.5 import WebStack.Generic
6.6 import os, sys
6.7 -from WebStack.Helpers.Request import MessageBodyStream, get_body_fields, decode_value, get_storage_items, Cookie
6.8 +from WebStack.Helpers.Request import MessageBodyStream, get_body_fields, \
6.9 + decode_value, get_storage_items, Cookie, HeaderDict
6.10 from WebStack.Helpers.Response import ConvertingStream
6.11 from WebStack.Helpers.Auth import UserInfo
6.12 from WebStack.Helpers.Session import SessionStore
6.13 @@ -50,7 +51,7 @@
6.14 self.content_type = None
6.15 self.response_code = 200
6.16 self.content = StringIO()
6.17 - self.headers_out = {}
6.18 + self.headers_out = HeaderDict()
6.19 self.cookies_out = SimpleCookie()
6.20
6.21 # Define the incoming cookies.
6.22 @@ -86,7 +87,7 @@
6.23 """
6.24
6.25 self.content = StringIO()
6.26 - self.headers_out = {}
6.27 + self.headers_out = HeaderDict()
6.28 self.cookies_out = SimpleCookie()
6.29
6.30 def get_wsgi_headers(self):