1 #!/usr/bin/env python 2 3 """ 4 Webware classes. 5 """ 6 7 import Generic 8 from cgi import parse_qs 9 10 class Transaction(Generic.Transaction): 11 12 """ 13 Webware transaction interface. 14 """ 15 16 def __init__(self, trans): 17 18 "Initialise the transaction using the Webware transaction 'trans'." 19 20 self.trans = trans 21 22 # Request-related methods. 23 24 def get_request_stream(self): 25 26 """ 27 A framework-specific method which returns the request stream for 28 the transaction. 29 """ 30 31 stream = self.trans.request().rawInput(rewind=1) 32 if stream is None: 33 return StringIO.StringIO("") 34 35 return stream 36 37 def get_request_method(self): 38 39 """ 40 A framework-specific method which gets the request method. 41 """ 42 43 return self.trans.request().method() 44 45 def get_headers(self): 46 47 """ 48 A framework-specific method which returns all request headers. 49 """ 50 51 # NOTE: Webware doesn't really provide access to headers in the request. 52 53 return {} 54 55 def get_header_values(self, key): 56 57 """ 58 A framework-specific method which returns a list of all request header 59 values associated with the given 'key'. Note that according to RFC 2616, 60 'key' is treated as a case-insensitive string. 61 """ 62 63 # NOTE: Webware doesn't really provide access to headers in the request. 64 65 return [] 66 67 def get_content_type(self): 68 69 """ 70 A framework-specific method which gets the content type specified on the 71 request, along with the charset employed. 72 """ 73 74 return self.parse_content_type(self.trans.request().contentType()) 75 76 def get_content_charsets(self): 77 78 """ 79 Returns the character set preferences. 80 NOTE: Requires enhancements to HTTPRequest. 81 """ 82 83 return self.trans.request().contentCharsets() 84 85 def get_content_languages(self): 86 87 """ 88 A framework-specific method which extracts language information from 89 the transaction. 90 NOTE: Requires enhancements to HTTPRequest. 91 """ 92 93 return self.trans.request().contentLanguages() 94 95 def get_path(self): 96 97 """ 98 A framework-specific method which gets the entire path from the request. 99 """ 100 101 return self.trans.request().uri() 102 103 def get_path_info(self): 104 105 """ 106 A framework-specific method which gets the "path info" (the part of the 107 URL after the resource name handling the current request) from the 108 request. 109 """ 110 111 # NOTE: Webware does not seem to prefix the "path info" in a way 112 # NOTE: consistent with the other frameworks. 113 114 return "/" + self.trans.request().pathInfo() 115 116 def get_query_string(self): 117 118 """ 119 A framework-specific method which gets the query string from the path in 120 the request. 121 """ 122 123 return self.trans.request().queryString() 124 125 # Higher level request-related methods. 126 127 def get_fields_from_path(self): 128 129 """ 130 A framework-specific method which extracts the form fields from the 131 path specified in the transaction. The underlying framework may refuse 132 to supply fields from the path if handling a POST transaction. 133 134 Returns a dictionary mapping field names to lists of values (even if a 135 single value is associated with any given field name). 136 """ 137 138 return parse_qs(self.get_query_string(), keep_blank_values=1) 139 140 def get_fields_from_body(self): 141 142 """ 143 A framework-specific method which extracts the form fields from the 144 message body in the transaction. 145 146 Returns a dictionary mapping field names to lists of values (even if a 147 single value is associated with any given field name). 148 """ 149 150 # Fix the non-list results. 151 152 fields = {} 153 for field_name, field_value in self.trans.request().fields().items(): 154 if type(field_value) == type([]): 155 fields[field_name] = field_value 156 else: 157 fields[field_name] = [field_value] 158 return fields 159 160 def get_user(self): 161 162 """ 163 A framework-specific method which extracts user information from the 164 transaction. 165 """ 166 167 # NOTE: Webware relies entirely on a CGI-style environment where the 168 # NOTE: actual headers are not available. Therefore, the Web server must 169 # NOTE: itself be set up to provide user support. 170 171 try: 172 return self.trans.request().remoteUser() 173 except KeyError, exc: 174 return None 175 176 # Response-related methods. 177 178 def get_response_stream(self): 179 180 """ 181 A framework-specific method which returns the response stream for 182 the transaction. 183 """ 184 185 return self.trans.response() 186 187 def get_response_code(self): 188 189 """ 190 Get the response code associated with the transaction. If no response 191 code is defined, None is returned. 192 """ 193 194 # NOTE: Webware treats the response code as just another header. 195 196 status = self.trans.response().header("Status", None) 197 try: 198 if status is not None: 199 return int(status) 200 else: 201 return None 202 except ValueError: 203 return None 204 205 def set_response_code(self, response_code): 206 207 """ 208 Set the 'response_code' using a numeric constant defined in the HTTP 209 specification. 210 """ 211 212 self.trans.response().setStatus(response_code) 213 214 def set_header_value(self, header, value): 215 216 """ 217 Set the HTTP 'header' with the given 'value'. 218 """ 219 220 self.trans.response().setHeader(self.format_header_value(header), self.format_header_value(value)) 221 222 def set_content_type(self, content_type): 223 224 """ 225 A framework-specific method which sets the 'content_type' for the 226 response. 227 """ 228 229 return self.trans.response().setHeader("Content-Type", self.format_content_type(content_type)) 230 231 # vim: tabstop=4 expandtab shiftwidth=4