1.1 --- a/WebStack/BaseHTTPRequestHandler.py Sat Apr 24 20:34:47 2004 +0000
1.2 +++ b/WebStack/BaseHTTPRequestHandler.py Sat Apr 24 23:08:38 2004 +0000
1.3 @@ -8,6 +8,7 @@
1.4 from Helpers.Request import MessageBodyStream
1.5 from Helpers.Auth import UserInfo
1.6 from cgi import parse_qs, FieldStorage
1.7 +import Cookie
1.8 from StringIO import StringIO
1.9
1.10 class Transaction(Generic.Transaction):
1.11 @@ -30,7 +31,12 @@
1.12 self.content_type = None
1.13 self.response_code = 200
1.14 self.content = StringIO()
1.15 - self.headers = {}
1.16 + self.headers_out = {}
1.17 + self.cookies_out = Cookie.SimpleCookie()
1.18 +
1.19 + # Define the incoming cookies.
1.20 +
1.21 + self.cookies_in = Cookie.SimpleCookie(self.get_headers().get("cookie"))
1.22
1.23 def commit(self):
1.24
1.25 @@ -42,8 +48,15 @@
1.26 self.trans.send_response(self.response_code)
1.27 if self.content_type is not None:
1.28 self.trans.send_header("Content-Type", self.format_content_type(self.content_type))
1.29 - for header, value in self.headers.items():
1.30 +
1.31 + for header, value in self.headers_out.items():
1.32 self.trans.send_header(self.format_header_value(header), self.format_header_value(value))
1.33 +
1.34 + # NOTE: May not be using the appropriate method.
1.35 +
1.36 + for morsel in self.cookies_out.values():
1.37 + self.trans.send_header("Set-Cookie", morsel.OutputString())
1.38 +
1.39 self.trans.end_headers()
1.40 self.content.seek(0)
1.41 self.trans.wfile.write(self.content.read())
1.42 @@ -95,8 +108,7 @@
1.43 request, along with the charset employed.
1.44 """
1.45
1.46 - return self.parse_content_type(self.trans.headers.get("Content-type") or
1.47 - self.trans.headers.get("Content-Type"))
1.48 + return self.parse_content_type(self.trans.headers.get("content-type"))
1.49
1.50 def get_content_charsets(self):
1.51
1.52 @@ -104,7 +116,7 @@
1.53 Returns the character set preferences.
1.54 """
1.55
1.56 - return self.parse_content_preferences(self.trans.headers.get("Accept-Charset"))
1.57 + return self.parse_content_preferences(self.trans.headers.get("accept-charset"))
1.58
1.59 def get_content_languages(self):
1.60
1.61 @@ -113,7 +125,7 @@
1.62 the transaction.
1.63 """
1.64
1.65 - return self.parse_content_preferences(self.trans.headers.get("Accept-Language"))
1.66 + return self.parse_content_preferences(self.trans.headers.get("accept-language"))
1.67
1.68 def get_path(self):
1.69
1.70 @@ -200,12 +212,35 @@
1.71 Returns a username as a string or None if no user is defined.
1.72 """
1.73
1.74 - auth_header = self.get_headers().get("Authorization")
1.75 + auth_header = self.get_headers().get("authorization")
1.76 if auth_header:
1.77 return UserInfo(auth_header).username
1.78 else:
1.79 return None
1.80
1.81 + def get_cookies(self):
1.82 +
1.83 + """
1.84 + A framework-specific method which obtains cookie information from the
1.85 + request.
1.86 +
1.87 + Returns a dictionary mapping cookie names to cookie objects.
1.88 + """
1.89 +
1.90 + return self.cookies_in
1.91 +
1.92 + def get_cookie(self, cookie_name):
1.93 +
1.94 + """
1.95 + A framework-specific method which obtains cookie information from the
1.96 + request.
1.97 +
1.98 + Returns a cookie object for the given 'cookie_name' or None if no such
1.99 + cookie exists.
1.100 + """
1.101 +
1.102 + return self.cookies_in.get(cookie_name)
1.103 +
1.104 # Response-related methods.
1.105
1.106 def get_response_stream(self):
1.107 @@ -245,7 +280,7 @@
1.108
1.109 # The header is not written out immediately due to the buffering in use.
1.110
1.111 - self.headers[header] = value
1.112 + self.headers_out[header] = value
1.113
1.114 def set_content_type(self, content_type):
1.115
1.116 @@ -260,4 +295,50 @@
1.117
1.118 self.content_type = content_type
1.119
1.120 + def set_cookie(self, cookie):
1.121 +
1.122 + """
1.123 + A framework-specific method which stores the given 'cookie' object in
1.124 + the response.
1.125 + """
1.126 +
1.127 + # NOTE: If multiple cookies of the same name could be specified, this
1.128 + # NOTE: could need changing.
1.129 +
1.130 + self.cookies_out[cookie.name] = cookie.value
1.131 +
1.132 + def set_cookie_value(self, name, value, path=None, expires=None):
1.133 +
1.134 + """
1.135 + A framework-specific method which stores a cookie with the given 'name'
1.136 + and 'value' in the response.
1.137 +
1.138 + The optional 'path' is a string which specifies the scope of the cookie,
1.139 + and the optional 'expires' parameter is a value compatible with the
1.140 + time.time function, and indicates the expiry date/time of the cookie.
1.141 + """
1.142 +
1.143 + self.cookies_out[name] = value
1.144 + if path is not None:
1.145 + self.cookies_out[name]["path"] = path
1.146 + if expires is not None:
1.147 + self.cookies_out[name]["expires"] = expires
1.148 +
1.149 + def delete_cookie(self, cookie_name):
1.150 +
1.151 + """
1.152 + A framework-specific method which adds to the response a request that
1.153 + the cookie with the given 'cookie_name' be deleted/discarded by the
1.154 + client.
1.155 + """
1.156 +
1.157 + # Create a special cookie, given that we do not know whether the browser
1.158 + # has been sent the cookie or not.
1.159 + # NOTE: Magic discovered in Webware.
1.160 +
1.161 + self.cookies_out[cookie_name] = ""
1.162 + self.cookies_out[cookie_name]["path"] = "/"
1.163 + self.cookies_out[cookie_name]["expires"] = 0
1.164 + self.cookies_out[cookie_name]["max-age"] = 0
1.165 +
1.166 # vim: tabstop=4 expandtab shiftwidth=4
2.1 --- a/WebStack/Generic.py Sat Apr 24 20:34:47 2004 +0000
2.2 +++ b/WebStack/Generic.py Sat Apr 24 23:08:38 2004 +0000
2.3 @@ -145,7 +145,8 @@
2.4 def get_headers(self):
2.5
2.6 """
2.7 - A framework-specific method which returns all request headers.
2.8 + A framework-specific method which returns all request headers as a
2.9 + dictionary-like object mapping header names to values.
2.10 """
2.11
2.12 raise NotImplementedError, "get_headers"
2.13 @@ -245,6 +246,8 @@
2.14 """
2.15 A framework-specific method which extracts user information from the
2.16 transaction.
2.17 +
2.18 + Returns a username as a string or None if no user is defined.
2.19 """
2.20
2.21 raise NotImplementedError, "get_user"
3.1 --- a/WebStack/JavaServlet.py Sat Apr 24 20:34:47 2004 +0000
3.2 +++ b/WebStack/JavaServlet.py Sat Apr 24 23:08:38 2004 +0000
3.3 @@ -6,6 +6,8 @@
3.4
3.5 import Generic
3.6 from StringIO import StringIO
3.7 +from Helpers.Request import Cookie
3.8 +import javax.servlet.http.Cookie
3.9
3.10 class Stream:
3.11
3.12 @@ -54,6 +56,14 @@
3.13 self.response = response
3.14 self.status = None
3.15
3.16 + # Remember the cookies received in the request.
3.17 + # NOTE: Discarding much of the information received.
3.18 +
3.19 + self.cookies_in = {}
3.20 + for cookie in self.request.getCookies():
3.21 + cookie_name = cookie.getName()
3.22 + self.cookies_in[cookie_name] = Cookie(cookie_name, cookie.getValue())
3.23 +
3.24 def commit(self):
3.25
3.26 """
3.27 @@ -225,6 +235,29 @@
3.28
3.29 return self.request.getRemoteUser()
3.30
3.31 + def get_cookies(self):
3.32 +
3.33 + """
3.34 + A framework-specific method which obtains cookie information from the
3.35 + request.
3.36 +
3.37 + Returns a dictionary mapping cookie names to cookie objects.
3.38 + """
3.39 +
3.40 + return self.cookies_in
3.41 +
3.42 + def get_cookie(self, cookie_name):
3.43 +
3.44 + """
3.45 + A framework-specific method which obtains cookie information from the
3.46 + request.
3.47 +
3.48 + Returns a cookie object for the given 'cookie_name' or None if no such
3.49 + cookie exists.
3.50 + """
3.51 +
3.52 + return self.cookies_in.get(cookie_name)
3.53 +
3.54 # Response-related methods.
3.55
3.56 def get_response_stream(self):
3.57 @@ -272,4 +305,52 @@
3.58
3.59 return self.response.setHeader("Content-Type", self.format_content_type(content_type))
3.60
3.61 + # Higher level response-related methods.
3.62 +
3.63 + def set_cookie(self, cookie):
3.64 +
3.65 + """
3.66 + A framework-specific method which stores the given 'cookie' object in
3.67 + the response.
3.68 + """
3.69 +
3.70 + new_cookie = javax.servlet.http.Cookie(cookie.name, cookie.value)
3.71 + self.response.addCookie(new_cookie)
3.72 +
3.73 + def set_cookie_value(self, name, value, path=None, expires=None):
3.74 +
3.75 + """
3.76 + A framework-specific method which stores a cookie with the given 'name'
3.77 + and 'value' in the response.
3.78 +
3.79 + The optional 'path' is a string which specifies the scope of the cookie,
3.80 + and the optional 'expires' parameter is a value compatible with the
3.81 + time.time function, and indicates the expiry date/time of the cookie.
3.82 + """
3.83 +
3.84 + cookie = javax.servlet.http.Cookie(name, value)
3.85 + if path is not None:
3.86 + cookie.setPath(path)
3.87 +
3.88 + # NOTE: The expires parameter seems not to be supported.
3.89 +
3.90 + self.response.addCookie(cookie)
3.91 +
3.92 + def delete_cookie(self, cookie_name):
3.93 +
3.94 + """
3.95 + A framework-specific method which adds to the response a request that
3.96 + the cookie with the given 'cookie_name' be deleted/discarded by the
3.97 + client.
3.98 + """
3.99 +
3.100 + # Create a special cookie, given that we do not know whether the browser
3.101 + # has been sent the cookie or not.
3.102 + # NOTE: Magic discovered in Webware.
3.103 +
3.104 + cookie = javax.servlet.http.Cookie(cookie_name, "")
3.105 + cookie.setPath("/")
3.106 + cookie.setMaxAge(0)
3.107 + self.response.addCookie(cookie)
3.108 +
3.109 # vim: tabstop=4 expandtab shiftwidth=4
4.1 --- a/WebStack/Webware.py Sat Apr 24 20:34:47 2004 +0000
4.2 +++ b/WebStack/Webware.py Sat Apr 24 23:08:38 2004 +0000
4.3 @@ -8,6 +8,7 @@
4.4 from cgi import parse_qs
4.5 import StringIO
4.6 from Helpers import Environment
4.7 +from Helpers.Request import Cookie
4.8
4.9 class Transaction(Generic.Transaction):
4.10
4.11 @@ -192,6 +193,35 @@
4.12 except KeyError, exc:
4.13 return None
4.14
4.15 + def get_cookies(self):
4.16 +
4.17 + """
4.18 + A framework-specific method which obtains cookie information from the
4.19 + request.
4.20 +
4.21 + Returns a dictionary mapping cookie names to cookie objects.
4.22 + """
4.23 +
4.24 + cookies = {}
4.25 + for name, value in self.trans.request().cookies().items():
4.26 + cookies[name] = Cookie(name, value)
4.27 + return cookies
4.28 +
4.29 + def get_cookie(self, cookie_name):
4.30 +
4.31 + """
4.32 + A framework-specific method which obtains cookie information from the
4.33 + request.
4.34 +
4.35 + Returns a cookie object for the given 'cookie_name' or None if no such
4.36 + cookie exists.
4.37 + """
4.38 +
4.39 + try:
4.40 + return Cookie(cookie_name, self.trans.request().cookie(cookie_name))
4.41 + except KeyError:
4.42 + return None
4.43 +
4.44 # Response-related methods.
4.45
4.46 def get_response_stream(self):
4.47 @@ -247,4 +277,38 @@
4.48
4.49 return self.trans.response().setHeader("Content-Type", self.format_content_type(content_type))
4.50
4.51 + # Higher level response-related methods.
4.52 +
4.53 + def set_cookie(self, cookie):
4.54 +
4.55 + """
4.56 + A framework-specific method which stores the given 'cookie' object in
4.57 + the response.
4.58 + """
4.59 +
4.60 + self.trans.response().addCookie(cookie)
4.61 +
4.62 + def set_cookie_value(self, name, value, path=None, expires=None):
4.63 +
4.64 + """
4.65 + A framework-specific method which stores a cookie with the given 'name'
4.66 + and 'value' in the response.
4.67 +
4.68 + The optional 'path' is a string which specifies the scope of the cookie,
4.69 + and the optional 'expires' parameter is a value compatible with the
4.70 + time.time function, and indicates the expiry date/time of the cookie.
4.71 + """
4.72 +
4.73 + self.trans.response().setCookie(name, value, path, expires)
4.74 +
4.75 + def delete_cookie(self, cookie_name):
4.76 +
4.77 + """
4.78 + A framework-specific method which adds to the response a request that
4.79 + the cookie with the given 'cookie_name' be deleted/discarded by the
4.80 + client.
4.81 + """
4.82 +
4.83 + self.trans.response().delCookie(cookie_name)
4.84 +
4.85 # vim: tabstop=4 expandtab shiftwidth=4