Package backend :: Package common :: Module rhnApache
[hide private]
[frames] | no frames]

Source Code for Module backend.common.rhnApache

  1  # 
  2  # Copyright (c) 2008--2016 Red Hat, Inc. 
  3  # 
  4  # This software is licensed to you under the GNU General Public License, 
  5  # version 2 (GPLv2). There is NO WARRANTY for this software, express or 
  6  # implied, including the implied warranties of MERCHANTABILITY or FITNESS 
  7  # FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 
  8  # along with this software; if not, see 
  9  # http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. 
 10  # 
 11  # Red Hat trademarks are not licensed under GPLv2. No permission is 
 12  # granted to use or replicate Red Hat trademarks that are incorporated 
 13  # in this software or its documentation. 
 14  # 
 15  # Code for the shared apache handler class inherited by the 
 16  # Spacewalk Proxy and server. 
 17  # 
 18   
 19  # system module imports 
 20  import time 
 21   
 22   
 23  # global module imports 
 24  from rhn.UserDictCase import UserDictCase 
 25   
 26   
 27  # Now local module imports 
 28  from spacewalk.common import rhnFlags 
 29  from spacewalk.common import apache 
 30  from spacewalk.common.rhnLog import log_debug, log_error, log_setreq 
 31  from spacewalk.common.rhnTranslate import cat 
32 33 34 -class rhnApache:
35 36 """ Shared rhnApache class: rhnApache classes in proxy and server inherit 37 this class. 38 39 Shared apache handler code: headerParserHandler, 40 handler (defined in class that inherits this), 41 cleanupHandler. 42 """ 43 _lang_catalog = "common" 44
45 - def __init__(self):
46 self.lang = "C" 47 self.domain = None 48 self.clientVersion = 0 49 self.proxyVersion = None 50 self.start_time = 0
51 52 ### 53 # HANDLERS, in the order which they are called 54 ### 55
56 - def headerParserHandler(self, req):
57 """ 58 after a request has been received, first thing we do is to create the 59 input object 60 """ 61 # pylint: disable=R0911 62 63 log_setreq(req) 64 log_debug(3) 65 self.start_time = time.time() 66 # Decline if this is a subrequest: 67 if req.main: 68 return apache.DECLINED 69 log_debug(4, req.method, req.path_info, req.headers_in) 70 71 # Clear the global flags. 72 rhnFlags.reset() 73 # Init the transport options. 74 rhnFlags.set('outputTransportOptions', UserDictCase()) 75 # Init the session token dictionary. 76 rhnFlags.set("AUTH_SESSION_TOKEN", UserDictCase()) 77 78 ret = self._init_request_processor(req) 79 if ret != apache.OK: 80 return ret 81 82 ret = self._set_client_info(req) 83 if ret != apache.OK: 84 return ret 85 86 # Check the protocol version 87 if req.proto_num < 1001: 88 # HTTP protocols prior to 1.1 close the connection 89 rhnFlags.get('outputTransportOptions')["Connection"] = "close" 90 91 ret = self._set_proxy_info(req) 92 if ret != apache.OK: 93 return ret 94 95 # Need to run _set_other first, since _set_lang needs RoodDir set 96 ret = self._set_other(req) 97 if ret != apache.OK: 98 return ret 99 100 ret = self._set_lang(req) 101 if ret != apache.OK: 102 return ret 103 104 return apache.OK
105
106 - def _set_client_info(self, req):
107 # Figure out the client version 108 clientVersionHeader = 'X-RHN-Client-Version' 109 if clientVersionHeader in req.headers_in: 110 # Useful to have it as a separate variable, to see it in a 111 # traceback report 112 clientVersion = req.headers_in[clientVersionHeader] 113 self.clientVersion = int(clientVersion) 114 # NOTE: x-client-version is really the cgiwrap xmlrpc API version 115 # NOT the RHN client version... but it works if nothing else 116 # does. 117 elif 'X-Client-Version' in req.headers_in: 118 clientVersion = req.headers_in['X-Client-Version'] 119 self.clientVersion = int(clientVersion) 120 else: 121 self.clientVersion = 0 122 123 # Make sure the client version gets set in the headers. 124 rhnFlags.get('outputTransportOptions')[clientVersionHeader] = str( 125 self.clientVersion) 126 return apache.OK
127
128 - def _set_proxy_info(self, req):
129 """ Spacewalk Proxy stuff. """ 130 proxyVersion = 'X-RHN-Proxy-Version' 131 if proxyVersion in req.headers_in: 132 self.proxyVersion = req.headers_in[proxyVersion] 133 # Make sure the proxy version gets set in the headers. 134 rhnFlags.get('outputTransportOptions')[proxyVersion] = str( 135 self.proxyVersion) 136 # Make sure the proxy auth-token gets set in global flags. 137 if 'X-RHN-Proxy-Auth' in req.headers_in: 138 rhnFlags.set('X-RHN-Proxy-Auth', 139 req.headers_in['X-RHN-Proxy-Auth']) 140 return apache.OK
141
142 - def _set_lang(self, req):
143 """ determine what language the client prefers """ 144 if "Accept-Language" in req.headers_in: 145 # RFC 2616 #3.10: case insensitive 146 lang = req.headers_in["Accept-Language"].lower() 147 else: 148 lang = "C" 149 self.setlang(lang, self._lang_catalog) 150 151 return apache.OK
152 153 @staticmethod
154 - def _set_other(_req):
155 return apache.OK
156
157 - def _init_request_processor(self, req):
158 # first, make sure we only allow certain methods 159 if req.method == "GET": 160 # This is a request from a cache/client, so verify the signature, 161 # system_id, and expiration exist and push into rhnFlags. 162 token = self._setSessionToken(req.headers_in) 163 if token is None: 164 return apache.HTTP_METHOD_NOT_ALLOWED 165 return apache.OK 166 167 elif req.method == "POST": 168 return apache.OK 169 170 elif req.method == "HEAD": 171 # We should only receive this type of request from ourself. 172 return apache.OK 173 174 log_error("Unknown HTTP method", req.method) 175 return apache.HTTP_METHOD_NOT_ALLOWED
176 177 @staticmethod
179 return apache.OK
180
181 - def handler(self, req):
182 """ 183 a handler - not doing much for the common case, but called from 184 classes that inherit this one. 185 """ 186 log_debug(3) 187 # Set the lang in the output headers 188 if self.lang != "C": 189 req.headers_out["Content-Language"] = self.getlang() 190 191 log_debug(4, "URI", req.unparsed_uri) 192 log_debug(4, "CONFIG", req.get_config()) 193 log_debug(4, "OPTIONS", req.get_options()) 194 log_debug(4, "HEADERS", req.headers_in) 195 return apache.OK
196
197 - def cleanupHandler(self, _req):
198 """ 199 clean up this session 200 """ 201 log_debug(3) 202 self.lang = "C" 203 self.clientVersion = self.proxyVersion = 0 204 # clear the global flags 205 rhnFlags.reset() 206 timer(self.start_time) 207 return self._cleanup_request_processor()
208 209 @staticmethod
210 - def logHandler(_req):
211 """ 212 A dummy log function 213 """ 214 log_debug(3) 215 return apache.OK
216
217 - def setlang(self, lang, domain):
218 """ 219 An entry point for setting the language for the current sesstion 220 """ 221 self.lang = lang 222 self.domain = domain 223 cat.set(domain=domain) 224 # If the language presented by the client does not exist, the 225 # translation object falls back to printing the original string, which 226 # is pretty much the same as translating to en 227 cat.setlangs(self.lang) 228 log_debug(3, self.lang, self.domain)
229 230 @staticmethod
231 - def getlang():
232 """ 233 And another lang function to produce the list of languages we're 234 handling 235 """ 236 return "; ".join(cat.getlangs())
237 238 @staticmethod
239 - def _setSessionToken(headers):
240 """ Pushes token into rhnFlags. If doesn't exist, returns None. 241 Pull session token out of the headers and into rhnFlags. 242 """ 243 log_debug(3) 244 token = UserDictCase() 245 if 'X-RHN-Server-Id' in headers: 246 token['X-RHN-Server-Id'] = headers['X-RHN-Server-Id'] 247 else: 248 # This has to be here, or else we blow-up. 249 return None 250 prefix = "x-rhn-auth" 251 tokenKeys = [x for x in headers.keys() if x[:len(prefix)].lower() == prefix] 252 for k in tokenKeys: 253 token[k] = headers[k] 254 255 rhnFlags.set("AUTH_SESSION_TOKEN", token) 256 return token
257
258 259 -def timer(last):
260 """ 261 a lame timer function for pretty logs 262 """ 263 if not last: 264 return 0 265 log_debug(2, "Request served in %.2f sec" % (time.time() - last, )) 266 return 0
267