def set_headers(self, stream): """Given an HTTP stream, parse and store the message headers. The HTTP stream must be positioned at the second line of a request. The message headers are read and a new Message instance is added to self. This instance will be updated in set_body once the body has been read. We have to do this in two stages because the length of the body is communicated to us via the headers. """ # Read in everything until the next blank line, parsing as we go. # =============================================================== raw_headers = [] parser_ = FeedParser() for line in stream: raw_headers.append(line) parser_.feed(line) if line == '\r\n': break # Now store on self. # ================== self.raw.extend(raw_headers) self.raw_headers = ''.join(raw_headers) self.message = parser_.close()
def lineReceived(self, line): log.debug("Line In: %s"%line) self.parser = FeedParser(Event) self.parser.feed(line) self.message = self.parser.close() #if self.state is not READ_CONTENT (i.e Content-Type is already read) and the Content-Length is present #read rest of the message and set it as payload if self.message.has_key('Content-Length') and self.state!= 'READ_CONTENT': if self.enterRawMode(): log.debug("Entering raw mode to read message payload") return try: self.inspectMessage() except: log.error("Exception in message processing ", exc_info=True)
def parse_headers(self): parser = FeedParser() while True: line = self.f.readline() self.hbuf.write(line) parser.feed(line) if not line.strip(): break self.m = parser.close() L = self.parse_addrs('from') self.h_from = L and L[0] or None self.h_to = self.parse_addrs('to') self.h_cc = self.parse_addrs('cc') self.h_rcpts = self.h_to + self.h_cc self.h_subject = decode_header(self.m.get('subject')) self.h_subject_len1 = len(self.h_subject) self.h_subject = self.h_subject.replace(' ', '') self.h_subject = self.h_subject.replace(u' ', '') self.h_subject_len2 = len(self.h_subject)
def parse(self, fp, headersonly=False): feedparser = FeedParser(self._class) if headersonly: feedparser._set_headersonly() while True: data = fp.read(8192) if not data: break feedparser.feed(data) return feedparser.close()
def parse(self, fp, headersonly = False): feedparser = FeedParser(self._class) if headersonly: feedparser._set_headersonly() while True: data = fp.read(8192) if not data: break feedparser.feed(data) return feedparser.close()
def parse(self, fp, headersonly=False): """Create a message structure from the data in a file. Reads all the data from the file and returns the root of the message structure. Optional headersonly is a flag specifying whether to stop parsing after reading the headers or not. The default is False, meaning it parses the entire contents of the file. """ feedparser = FeedParser(self._class) if headersonly: feedparser._set_headersonly() while True: data = fp.read(8192) if not data: break feedparser.feed(data) return feedparser.close()
def _handle_upload(self, headers, registry, parser): # file upload handling # mime parser from email.FeedParser import FeedParser fp = FeedParser() # need header content_type = headers['content-type'] fp.feed('CONTENT-TYPE: %s\n' % content_type) # size limit size_limit = self.stdin_size_limit # read in chunks chunk_size = 8192 # number of chunks n = size_limit / chunk_size # feed contents from stdin to parser import sys i = 0 succeeded = False while i < n: data = sys.stdin.read(chunk_size) if not data: succeeded = True break fp.feed(data) continue if not succeeded: raise RuntimeError, "stdin too large" # parsed is a mime instance parsed = fp.close() # header = 'Content-Disposition' if self.inventory.debug: self._cgi_inputs['uploaded mime'] = parsed.as_string() args = [] uploads = {} for part in parsed.walk(): if part.get_content_maintype() == 'multipart': # this part is the parent message it self, skip continue filename = part.get_param('filename', header=header) if filename: # this means we are dealing with a real file # save them to a dictionary so that later actors can handle them content = part.get_payload(decode=True) uploads[filename] = content else: # just a key,value pair key = part.get_param('name', header=header) value = part.get_payload() args.append((key, value)) # pass key,value pairs to pyre option registry arg = '&'.join(['%s=%s' % (k, v) for k, v in args]) if arg: parser.parse(registry, arg, 'form') self._uploads = uploads return
def __init__(self,path): fp = FeedParser() charset = chardet.detect(open(path).read()) fp.feed(codecs.open(path,encoding = charset["encoding"]).read()) self.m = fp.close()
class FSProtocol(basic.LineReceiver): """FreeSWITCH EventSocket protocol implementation. All the FreeSWITCH api and dptool commands are defined in this class """ delimiter="\n\n" jobType = False state = "READ_CONTENT" def connectionMade(self): self.contentCallbacks = {"auth/request":self.auth, "api/response":self.onAPIReply, "command/reply":self.onCommandReply, "text/event-plain":self.onEvent, "text/disconnect-notice":self.disconnectNotice } self.pendingJobs = [] self.pendingBackgroundJobs = {} self.eventCallbacks = {} self.customEventCallbacks = {} self.subscribedEvents = [] log.info("Connected to FreeSWITCH") def connectionLost(self, reason): log.info("Cleaning up") self.disconnectedFromFreeSWITCH() def disconnectedFromFreeSWITCH(self): """Over-ride this to get notified of FreeSWITCH disconnection""" pass def registerEvent(self, event,subscribe, function, *args, **kwargs): """Register a callback for the event event -- (str) Event name as sent by FreeSWITCH , Custom events should give subclass also eg : CUSTOM conference::maintenance subsribe -- (bool) if True subscribe to this event function -- callback function accepts a event dictionary as first argument args -- argumnet to be passed to callback function kwargs -- keyword arguments to be passed to callback function returns instance of EventCallback , keep a reference of this around if you want to deregister it later """ if subscribe: if self.needToSubscribe(event): self.subscribeEvents(event) ecb = EventCallback(event, function, *args, **kwargs) ecb_list = self.eventCallbacks.get(event, []) event_callbacks = self.eventCallbacks #handle CUSTOM events if event.startswith("CUSTOM"): subclass = event.split(' ') event = subclass[1] ecb.subclass = event ecb_list = self.customEventCallbacks.get(event, []) event_callbacks = self.customEventCallbacks ecb_list.append(ecb) event_callbacks[event] = ecb_list return ecb def needToSubscribe(self, event): """Decide if we need to subscribe to an event or not by comparing the event provided against already subscribeEvents event -- (str) event name returns bool """ if "all" in self.subscribedEvents: return False if event in self.subscribedEvents: return False if 'myevents' in self.subscribedEvents: return False else: return True def deregisterEvent(self,ecb): """Deregister a callback for the given event ecb -- (EventCallback) instance of EventCallback object """ callbacks_list = self.eventCallbacks if ecb.eventname == 'CUSTOM': callbacks_list = self.customEventCallbacks ecbs = callbacks_list[ecb.eventname] try: ecbs.remove(ecb) except ValueError: log.error("%s already deregistered "%ecb) def dataReceived(self, data): """ We override this twisted method to avoid being disconnected by default MAX_LENGTH for messages which cross that limit """ if self._busyReceiving: self._buffer += data return try: self._busyReceiving = True self._buffer += data while self._buffer and not self.paused: if self.line_mode: try: line, self._buffer = self._buffer.split( self.delimiter, 1) except ValueError: return else: why = self.lineReceived(line) if (why or self.transport and self.transport.disconnecting): return why else: data = self._buffer self._buffer = b'' why = self.rawDataReceived(data) if why: return why finally: self._busyReceiving = False def lineReceived(self, line): log.debug("Line In: %s"%line) self.parser = FeedParser(Event) self.parser.feed(line) self.message = self.parser.close() #if self.state is not READ_CONTENT (i.e Content-Type is already read) and the Content-Length is present #read rest of the message and set it as payload if self.message.has_key('Content-Length') and self.state!= 'READ_CONTENT': if self.enterRawMode(): log.debug("Entering raw mode to read message payload") return try: self.inspectMessage() except: log.error("Exception in message processing ", exc_info=True) def rawDataReceived(self, data): """Read length of raw data specified by self.contentLength and set it as message payload """ log.debug("Data In : %s"%data) self.rawdataCache = ''.join([self.rawdataCache, data]) if len(self.rawdataCache) >= self.contentLength-1: self.clearLineBuffer() extra = self.rawdataCache[self.contentLength:] currentResult = self.rawdataCache[:self.contentLength] self.message.set_payload(currentResult) try: self.inspectMessage() except: log.error("Exception in message processing ", exc_info=True) self.setLineMode(extra) def enterRawMode(self): """ Change to raw mode from line mode if self.contentLength > 0 """ self.contentLength = int(self.message['Content-Length'].strip()) if self.contentLength > 0: self.rawdataCache ='' self.setRawMode() return True return False def inspectMessage(self): """Inspect message and dispatch based on self.state or Content-Type of message """ if self.state == "READ_EVENT": return self.dispatchEvent() if self.state == "READ_CHANNELINFO": return self.onConnect() if self.state == 'READ_API': return self.fireAPIDeferred() if not self.message.has_key("Content-Type"): return ct = self.message['Content-Type'] try: cb = self.contentCallbacks[ct] cb() except KeyError: log.error("Got unimplemented Content-Type : %s"%ct) def dispatchEvent(self): self.state = "READ_CONTENT" eventname = self.message['Event-Name'] #Handle background job event if eventname == "BACKGROUND_JOB": try: df = self.pendingBackgroundJobs.pop(self.message['Job-UUID']) df.callback(self.message) except KeyError: log.error("Stray BACKGROUND_JOB event received %s", self.message['Job-UUID']) except: log.error("Error in BACKGROUND_JOB event handler", exc_info=True) if eventname == 'CUSTOM': self.message.decode() ecbs = self.customEventCallbacks.get(self.message['Event-Subclass'], None) else: ecbs = self.eventCallbacks.get(eventname, None) if ecbs is None: return for ecb in ecbs: try: ecb.func(self.message, *ecb.args, **ecb.kwargs) except: log.error("Message %s\nError in event handler %s on event %s:"%(self.message, ecb.func, eventname), exc_info=True) def onConnect(self): """Channel Information is ready to be read. """ log.info("onconnect") def auth(self): """ FreeSWITCH is requesting to authenticate """ pass def fireAPIDeferred(self): self.state = 'READ_CONTENT' df = self.pendingJobs.pop(0) df.callback(self.message) def onAPIReply(self): """ Handle API reply """ if not self.message.has_key("Content-Length"): self.currentDeferred = self.pendingJobs.pop(0) return self.currentDeferred.callback(self.message) if self.enterRawMode(): self.state = "READ_API" log.debug("Entering raw mode to read API response") return else: self.currentDeferred.callback(self.message) def onCommandReply(self): """ Handle CommandReply """ if self.message.has_key("Job-UUID"): return try: df = self.pendingJobs.pop(0) except IndexError: log.error("Command reply message received with out pending deferred %s"%self.message) return if self.message['Reply-Text'].startswith("+OK"): df.callback(self.message) else: e = CommandError(self.message['Reply-Text']) df.errback(e) def onEvent(self): """ Handle a new event """ self.state = "READ_EVENT" def disconnectNotice(self): """ Handle disconnect notice """ if not self.message.has_key("Content-Length"): return self.disconnectNoticeReceived(self.message) self.contentLength = int(self.message['Content-Length']) if self.contentLength>0: self.currentDeferred = defer.Deferred() log.info("Enter raw mode to read disconnect notice") self.rawdataCache = '' self.setRawMode() else: self.disconnectNoticeReceived(self.message) def disconnectNoticeReceived(self, msg): """Override this to receive disconnect notice from FreeSWITCH""" log.error("disconnectNoticeReceived not implemented") log.info(msg) def sendData(self, cmd, args=''): df = defer.Deferred() #self.pendingJobs.append((cmd, df)) self.pendingJobs.append(df) if args: cmd = ' '.join([cmd, args]) self.sendLine(cmd) log.debug("Line Out: %r"%cmd) return df def sendMsg(self, msg): """Send message to FreeSWITCH msg -- (event) Event object """ df = defer.Deferred() self.pendingJobs.append(df) msg = msg.as_string(True) self.transport.write(msg) log.debug("Line Out: %r"%msg) return df def sendCommand(self, cmd, args='', uuid='', lock=True): msg = Event() if uuid: msg.set_unixfrom("SendMsg %s"%uuid) else: msg.set_unixfrom("SendMsg") msg['call-command'] = "execute" msg['execute-app-name'] = cmd if args: msg['execute-app-arg'] = args if lock: msg['event-lock'] = "true" return self.sendMsg(msg) def sendAPI(self, apicmd, background=jobType): if background: return self.sendBGAPI(apicmd) else: return self.sendData("api", apicmd) def sendBGAPI(self, apicmd): jobid = str(uuid.uuid1()) apicmd = ' '.join(['bgapi', apicmd]) apicmd = '\n'.join([apicmd, "Job-UUID:%s"%jobid]) backgroundJobDeferred = defer.Deferred() self.pendingBackgroundJobs[jobid] = backgroundJobDeferred log.debug("Line Out: %r", apicmd) self.sendLine(apicmd) return backgroundJobDeferred def subscribeEvents(self, events): """Subscribe to FreeSWITCH events. events -(str) 'all' subscribe to all events or event names separated by space this method can subscribe to multiple events but if the event is of CUSTOM type then only one CUSTOM event with subclass should be given """ _events = [] if not events.startswith("CUSTOM"): _events = events.split(' ') for event in _events: self.subscribedEvents.append(events) return self.sendData("event plain", events) def myevents(self, uuid=''): """Tie up the connection to particular channel events""" self.subscribedEvents.append("myevents") if uuid: return self.sendData("myevents %s"%uuid) else: return self.sendData("myevents") def apiAvmd(self, uuid, start=True, background=jobType): """Execute avmd on provided channel. uuid (str) -- uuid of the target channel start (bool) -- If True avmd will start if false avmd will be stopped """ if start: return self.sendAPI("avmd %s start"%uuid, background) else: return self.sendAPI("avmd %s stop"%uuid, background) def apiConferenceDial(self, name, url, background=jobType): """Dial the given url from conference name -- (str) name of the conference url -- (str) FreeSWITCH compatible call URL""" cmd = 'conference %s dial %s'%(name, url) return self.sendAPI(cmd, background) def apiConferenceKick(self,name, member, background=jobType): """Kick the given member from conference name -- (str) name of the conference member -- (str) member id or all or last """ cmd = "conference %s kick %s"%(name, member) return self.sendAPI(cmd, background) def apiConferenceList(self, name=None, delim=None, background=jobType): """List the conference name - (str) name of the conference. if not given all the conferences will be listed delim - (str) delimiter to use for separating values """ cmd = "conference" if name is not None: cmd = ' '.join([cmd, name, 'list']) else: cmd = ' '.join([cmd,'list']) if delim is not None: cmd = ' '.join([cmd, 'delim',delim]) return self.sendAPI(cmd, background) def apiConferenceListCount(self, name, background=True): """Return number of members in the conference name -- (str) name of the conference """ cmd = 'conference %s list count'%name return self.sendAPI(cmd, background) def apiConferenceVolume(self, name, member, value=0, direction='out', background=jobType): """Set volume of conference name -- (str) name of the conference memeber -- (str) member id or all or last value -- (int) 0 - 4 direction -- (str) in or out""" cmd = "conference %s volume_%s %s %s"%(name, direction, member, value) return self.sendAPI(cmd, background) def apiConferenceMute(self, name, member, background=jobType): """Mute given member in a conference name -- (str) name of the conference member -- (str) member id or all or last """ cmd = "conference %s mute %s"%(name, member) return self.sendAPI(cmd, background) def apiConferencePlay(self, name, filename, member=None, background=jobType): """Playback given file in conference name -- (str) name of the conference filename -- (str) name of the audio file to be played in conference member -- (str) member id in conference """ if member: cmd = "conference %s play %s %s"%(name, filename, member) else: cmd = "conference %s play %s"%(name, filename,) return self.sendAPI(cmd, background) def apiConferenceStop(self, name, fid=None, member=None, background=jobType): """Stop an ongoing/queued playback in conference name -- (str) name of the conference fid -- (str) file ID to stop takes all|async|current|last member -- (str) member id in conference """ if member: cmd = "conference %s stop %s %s"%(name, fid, member) elif fid: cmd = "conference %s stop %s"%(name, fid) else: cmd = "conference %s stop"%(name, ) return self.sendAPI(cmd, background) def apiConferenceUnMute(self, name, member, background=jobType): """UnMute given member in a conference name -- (str) name of the conference member -- (str) member id or all or last """ cmd = "conference %s unmute %s"%(name, member) return self.sendAPI(cmd, background) def apiDomainExists(self, domain, background=jobType): cmd = "domain_exists %s"%domain return self.sendAPI(cmd, background) def apiGlobalGetVar(self,variable='', background=jobType): """Get the value of a global variable variable -- name of the variable returns the value of the provided global variable if argument variable is not present then all global variables are returned. """ apicmd = ' '.join(["global_getvar", variable]) df = self.sendAPI(apicmd, background) if variable != '': return df else: finalDF = defer.Deferred() df.addCallback(self._parseGlobalGetVar,finalDF) return finalDF def _parseGlobalGetVar(self, result, df): result = result.get_payload() res = result.strip().split("\n") finalResult = {} try: for r in res: k, v = r.split("=", 1) finalResult[k] = v else: df.callback(finalResult) except Exception, err: log.error(err)