def callComponent(self, callProtocol, name, argDict, cache, compType, srcModTime): """ client-side handler for remote component calls """ # we don't need the callProtocol argument in this case unPickled = None host, port, path = self.__parseComponentName(name) args = cPickle.dumps((path, argDict, cache, compType, srcModTime)) msg = "%10d%s" % (len(args), args) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((host, port)) data = sock.recv(1) if data == '\0': SocketScience.send_it_all(sock, msg) length = int(SocketScience.read_this_many(sock, 10)) data = SocketScience.read_this_many(sock, length) unPickled = cPickle.loads(data) DEBUG(REMOTE_CLIENT, 'unp was %s' % str(unPickled)) if unPickled[0] == 0: #ok return unPickled[1] else: raise getRemoteException(unPickled[2]) raise RemoteException, ("remote host did not speak " "protocol: %s:%s") % (host, port)
def marshalRequest(self, sock, sessionDict): """ Sends a handshake byte, obtains the content length from the value of the first ten bytes read, and then reads no more than that amount, which it marshals with the 'marshal' module. Finally, returns the marshalled request data """ SocketScience.send_it_all(sock, '\0') DEBUG(AECGI, 'sent sentinel') lenDataStr = SocketScience.read_this_many(sock, 10) DEBUG(AECGI, 'read length') lenData = int(lenDataStr) data = SocketScience.read_this_many(sock, lenData) DEBUG(AECGI, 'read request data') marcia=marshal.loads(data) return marcia
def delete(self): DEBUG(SESSIONHANDLER, "in delete") args = { 'id': self.__id, 'idCol': self.getIDCol(), 'table': self.getTable() } self.execSql(self.getDeleteSQL() % args)
def reapOldRecords(self): DEBUG(SESSIONHANDLER, "in reapOldRecords") args = { 'timeCol': self.getTimeCol(), 'timeout': Session._timeout, 'table': self.getTable() } self.execSql(self.getReapSQL() % args)
def mungeConnection(*args, **kw): ''' inserts the getSession() and getSessionID() methods into the HTTPConnection class ''' DEBUG(SESSIONHANDLER, "in mungeConnection") HTTPConnection.getSession = getSession HTTPConnection.removeSession = removeSession HTTPConnection.getSessionID = getSessionID
def reap(self): DEBUG(SESSIONHANDLER, "in reap()") args = { 'timeCol': self.timeCol, 'timeout': Session._timeout, 'table': self.table } self.execSql(self.reapSQL % args, expect=0)
def load(self): self.__pydo[TIMESTAMP] = SYSDATE self.__pydo.commit() DEBUG(SESSIONHANDLER, str(self.__pydo.items())) gherkin = self.__pydo[PICKLE] if gherkin != None: return cPickle.loads(gherkin) return {}
def __init__(self, id): tmp = _PGStore.getUnique(**{ID: id}) if tmp: self.__pydo = tmp else: self.__pydo = _PGStore.new(**{ID: id, 'refetch': 1}) DEBUG(SESSIONHANDLER, "creating session with store: %s" % self.__pydo.items())
def _getContentLengthDelimitedRequestBody(self, socketFile, headers): """ reads the request body for the case where a content-length is declared in the request-headers. Does not handle chunked encoding or multipart/byteranges. """ if not headers.has_key("Content-Length"): DEBUG(HTTPD, "no content length in headers") return -1 try: contentLength = int(headers['Content-Length']) except ValueError: DEBUG( HTTPD, "content-length cannot be parsed: %s" % headers['Content-Length']) return -1 return socketFile.read(contentLength)
def _initConnection(self): try: MySQLSessionStoreImpl._dbconn=MySQLdb.Connect(host=self.getHost(), user=self.getUser(), passwd=self.getPass(), db=self.getDB()) except Exception, e: DEBUG(SESSIONHANDLER, "could not connect to database: %s" % e) raise e
def _setPickle(self, sessionHash): db=self.getConnection() c=db.cursor() args={'id' : self.__id, 'idCol' : self.idCol, 'pickleCol' : self.pickleCol, 'gherkin' : self.escapeSQLString(cPickle.dumps(sessionHash, 1)), 'timeCol' : self.timeCol, 'table': self.table} sql=self.setPickleSQL % args DEBUG(SESSIONHANDLER, sql) c.execute(self.setPickleSQL % args) if not c.rowcount: sql=self.insertPickleSQL % args DEBUG(SESSIONHANDLER, sql) c.execute(self.insertPickleSQL % args) db.commit() self._lastTouched=int(time.time())
def authFailed(self, conn): try: page = AE.Component.callComponent(self.loginPage, {'CONNECTION': conn}) # string exception left here for backwards compatibility except ("OK", OK): #this is the magical "do whatever you would've done" bit AE.Component.resetComponentStack() return except: DEBUG(AUTH, 'ACK! exception rendering login page') logException() page = "error occurred rendering login page" conn._output.write(page) resp = conn.response() DEBUG(AUTH, "page is %s" % resp) raise PreemptiveResponse, resp
def checkAuthorization(conn, sessionDict): """ any, and sends a preemptive 401 response, if necessary. """ if not Configuration.authActivated: return DEBUG(AUTH, 'checking authorization') authorizer = getAuthorizer() #if type(authorizer) == type(''): #if string, load module and replace # authorizer = Configuration.authAuthorizer = _getClass(authorizer)( # *Configuration.authAuthorizerCtorArgs) if not authorizer.checkCredentials(conn): DEBUG(AUTH, 'not authenticated') authorizer.authFailed(conn) else: DEBUG(AUTH, 'auth returned true')
def _swap_streams(conn, saved=None): if not saved: saved = sys.stdout, sys.stderr, sys.stdin sys.stdout = sys.stderr = cStringIO.StringIO() sys.stdin = cStringIO.StringIO(conn._stdin) DEBUG(PYCGI, conn._stdin) return saved else: new = (sys.stdout, sys.stderr, sys.stdin) (sys.stdout, sys.stderr, sys.stdin) = saved return new
def _canRead(sock, timeout): sock.setblocking(1) input, output, exc=select.select([sock], [], [], timeout) DEBUG(REQUESTHANDLER, "input for _canRead select: %s" % input) # sanity check if input and not input[0].recv(1, socket.MSG_PEEK): return 0 return len(input)
def _installExecutables(): d = { ('application/x-psp-python-component', DT_INCLUDE): PSPExecutable, ('application/x-psp-python-component', DT_REGULAR): PSPExecutable, ('application/x-psp-python-data-component', DT_DATA): PSPExecutable, } AE.Executables.executableByTypes.update(d) DEBUG(PSP, "exebytype= %s" % AE.Executables.executableByTypes) for i in Configuration.pspTemplateTypes: for j in (DT_INCLUDE, DT_REGULAR, DT_DATA): AE.Executables.executableByTypes[(i, j)] = PSPExecutable
def touch(self): """ resets the timestamp for the session's corresponding record. """ DEBUG(SESSIONHANDLER, "in touch") args={'table' : self.table, 'timeCol' : self.timeCol, 'idCol' : self.idCol, 'id' : self.__id} self.execSql(self.touchSQL % args, expect=0) self._touched=int(time.time())
def plainHandler(connObj, sessionDict): if not hasattr(connObj, 'statInfo'): return #file doesn't exist, screw it if not hasattr(connObj, 'mimeType'): return #file exists, but is a directory if connObj.mimeType in Configuration.hideMimeTypes: return #something that shouldn't be uri accessible connObj.responseHeaders['Content-Type'] = connObj.mimeType DEBUG(TEMPLATING, "spewing raw file") connObj.write(AE.Cache._readDocRoot(connObj.uri)) return connObj.response()
def getAuthorizationFromHeaders(conn, sessionDict): """ pulls REMOTE_USER, REMOTE_PASSWORD, and AUTH_TYPE out of request headers. """ DEBUG(AUTH, "looking for authorization headers") auth = conn.requestHeaders.get( 'Authorization', conn.requestHeaders.get('Proxy-Authorization')) if auth: DEBUG(AUTH, "found authorization") conn.authType, ai = auth.split() ucp = base64.decodestring(ai) colon_idx = ucp.find(':') conn.remoteUser = ucp[:colon_idx] conn.remotePassword = ucp[colon_idx + 1:] # in case a template author is looking for these.... conn.env['REMOTE_USER'] = conn.remoteUser conn.env['REMOTE_PASSWORD'] = conn.remotePassword conn.env['AUTH_TYPE'] = conn.authType else: DEBUG(AUTH, "no authorization found") conn.authType = conn.remotePassword = conn.remoteUser = None
def __setPickle(self, sessionHash): DEBUG(SESSIONHANDLER, "in __setPickle with sessionHash %s" % sessionHash) args = { 'id': self.__id, 'idCol': self.getIDCol(), 'pickleCol': self.getPickleCol(), 'gherkin': self.escapeSQLString(cPickle.dumps(sessionHash, 1)), 'timeCol': self.getTimeCol(), 'table': self.getTable() } self.execSql(self.getSetPickleSQL() % args)
def handle_propfind(path, conn, sessionDict): # this requires parsing the xml body, checking for depth headers; # status is 207, unless it is 404. depth=conn.requestHeaders.get(DEPTH_HEADER, 'infinity') DEBUG(WEBDAV, "unparsed xml document: %s" % conn.stdin) xmlelem=xmlutils.parse(conn._stdin) if not (xmlelem.name==PROPFIND_ELEM and xmlelem.getNamespace()=DAV_NS): raise StatusException, 400 DEBUG(WEBDAV, "parsed xml document: %s" % str(xmlelem)) # determine if resource exists if davfs.exists(path): responseBody, status=_propfindMultistatus(path, depth, _propfindType(xmlelem)) conn.write(responseBody) conn.setContentType(XML_CONTENT_TYPE) conn.setStatus(status) return 1 raise StatusException, 404 return 1
def _convertArgs(self, query): d = {} if query!=None: try: keys=query.keys() except TypeError: # annoyingly thrown by cgi.py in some circumstances DEBUG(WEB, "TypeError thrown in _convertArgs for query %s" % query) return d for k in keys: d[k] = self._convertArg(query[k]) return d
def _processRequest(requestData, sessionDict): """ request handling functioning for requestHandler's HandleRequest hook. """ response = None DEBUG(WEB, 'creating Connection') DEBUG(WEB, 'requestData is %s' % str(requestData)) connection = HTTPConnection(requestData) sessionDict[constants.CONNECTION] = connection sessionDict[constants.HOST] = connection.host sessionDict[constants.LOCATION] = connection.uri try: DEBUG(WEB, 'executing HaveConnection hook') HaveConnection(Configuration.job, connection, sessionDict) DEBUG(WEB, 'survived HaveConnection hook') # overlay of config information Configuration.trim() Configuration.scope(sessionDict) #Configuration.saveMash() DEBUG(WEB, 'executing PreHandleConnection hook') PreHandleConnection(Configuration.job, connection, sessionDict) except PreemptiveResponse, pr: DEBUG(WEB, 'got preemptive response') response = pr.responseData
def checkCredentials(self, conn): DEBUG(AUTH, "looking for authorization headers") auth = conn.requestHeaders.get( 'Authorization', conn.requestHeaders.get('Proxy-Authorization')) if auth: DEBUG(AUTH, "found authorization") dummy, ai = auth.split() ucp = base64.decodestring(ai) colon_idx = ucp.find(':') conn.remoteUser = ucp[:colon_idx] conn.remotePassword = ucp[colon_idx + 1:] # in case a template author is looking for these.... conn.env['REMOTE_USER'] = conn.remoteUser conn.env['REMOTE_PASSWORD'] = conn.remotePassword else: DEBUG(AUTH, "no authorization found") conn.remotePassword = conn.remoteUser = None return None #ok, auth must be true here DEBUG(AUTH, 'checking authorization') return self.validate(conn.remoteUser, conn.remotePassword)
def _sendResponse(sock, responseData, requestData, sessionDict): try: SocketScience.send_it_all(sock, responseData) except: logException() # reset alarm signal.alarm(Configuration.PostResponseTimeout) try: DEBUG(REQUESTHANDLER, 'post request hook') PostRequest(Configuration.job, requestData, sessionDict) except: logException() try: DEBUG(REQUESTHANDLER, "cleaning up") CleanupRequest(Configuration.job, requestData, sessionDict) except: logException()
def _seekTerminus(conn, sessionDict): httpVersion = sessionDict.get(constants.HTTP_VERSION, '') connHeader = conn.requestHeaders.get('Connection', '') if httpVersion == 'HTTP/1.0': close = connHeader != 'Keep-Alive' elif httpVersion == 'HTTP/1.1': close = connHeader == 'Close' else: close = 1 if close: conn.responseHeaders['Connection'] = 'Close' sessionDict[constants.CONNECTION_CLOSE] = close DEBUG(HTTPD, "setting connectionClose flag: %d" % close)
def _add_usertracking_cookie(conn, sessionDict): if Configuration.usertrackingOn: cookiename=Configuration.usertrackingCookieName if not _verify_cookie(conn, cookiename): f=Configuration.usertrackingGenUIDFunc if f is None: conn.responseCookie[cookiename]=uuid() else: conn.responseCookie[cookiename]=f(conn) morsel=conn.responseCookie[cookiename] for c, a in _config_attrs: if a=='expires': # special case if not Configuration.usertrackingExpiresAbsolute: v=getattr(Configuration, c) if v is not None: morsel[a]=Cookie._getdate(v) continue v=getattr(Configuration, c) if v is not None: morsel[a]=v DEBUG(USERTRACKING, str(morsel)) DEBUG(USERTRACKING, str(conn.responseCookie[cookiename]))
def __initPorts(self): from SkunkWeb import Server LOG('initializing ports') for port in self.ports: bits = port.split(':') if bits[0] == 'TCP': bits[2] = int(bits[2]) elif bits[0] == 'UNIX': if len(bits)>=3: bits[2] = int(bits[2], 8) else: raise "unrecognized socket specifier: %s" % port DEBUG(REQUESTHANDLER, 'adding Service: %s, %s' %((tuple(bits)), self)) Server.addService(tuple(bits), self)
def image(path, queryargs=None, kwargs={}, noescape=None): """ Create an image tag """ if Config.autosizeImages and _havePIL and not path.startswith('http://'): w = kwargs.get('width') h = kwargs.get('height') DEBUG(TEMPLATING, "width: %s; height: %s" % (w, h)) if w is None and h is None: try: im = Image.open(Cache._openDocRoot(path)) except: DEBUG(TEMPLATING, "failed to read doc root for path %s" % path) else: kwargs['width'], kwargs['height'] = im.size if Config.tagsGenerateXHTML: template = '<img src="%s"%s />' else: template = '<img src="%s"%s>' ret = template % (_genUrl(path, query=queryargs, noescape=noescape), _genKwArgs(kwargs)) return ret
def execSql(self, sql, args=None, expect=1): DEBUG(SESSIONHANDLER, sql) try: db = self.getConnection() cursor = db.cursor() if args: cursor.execute(sql, args) else: cursor.execute(sql) if expect: retval = cursor.fetchall() else: retval = None cursor.close() db.commit() return retval except Exception, e: DEBUG(SESSIONHANDLER, "sql exception -- see error log") logException() try: db.rollback() except: pass