Ejemplo n.º 1
0
class RequestHandle(object):
    DONE = get_event()
    OVERFLOW = get_event()
    MAX_SIZE = 1024 * 5024

    def __init__(self, spin):
        self.request = None
        xmap(spin, TransferHandle.DONE, self.process)

        # It will not be spawned if it is a websocket connection.
        xmap(
            spin, TmpFile.DONE, lambda spin, fd, data: spawn(
                spin, RequestHandle.DONE, self.request))

    def process(self, spin, request, data):
        self.request = request
        contype = request.headers.get('connection', '').lower()
        uptype = request.headers.get('upgrade', '').lower()

        if contype == 'upgrade' and uptype == 'websocket':
            spawn(spin, RequestHandle.DONE, request)
        else:
            self.accumulate(spin, data)

    def accumulate(self, spin, data):
        size = int(self.request.headers.get('content-length', '0'))

        NonPersistentConnection(spin)
        # PersistentConnection(spin)

        if RequestHandle.MAX_SIZE <= size:
            spawn(spin, RequestHandle.OVERFLOW, self.request)
        else:
            TmpFile(spin, data, size, self.request.fd)
Ejemplo n.º 2
0
class Fixed(object):
    """
    A handle for application layers that demand fixed chunk transmission of data.

    def on_found(spin, data):
        print data

    Fixed(spin, size=4)
    xmap(spin, FOUND, on_found)

    If it arises a chunk of size equal or greater than 4 then FOUND is processed.
    """

    FOUND = get_event()

    def __init__(self, spin, size=4):
        spin.add_map(LOAD, self.update)
        self.arr = bytearray()
        self.size = size

    def update(self, spin, data):
        self.arr.extend(data)

        for ind in xrange(self.size, len(self.arr) + 1, self.size):
            chunk = buffer(self.arr, ind - self.size, self.size)
            spin.drive(Fixed.FOUND, chunk)
        else:
            try:
                del self.arr[:ind]
            except NameError:
                pass
Ejemplo n.º 3
0
class TransferHandle(object):
    DONE = get_event()

    def __init__(self, spin):
        xmap(
            spin, AccUntil.DONE, lambda spin, request, data: spawn(
                spin, TransferHandle.DONE, Request(request), data))
Ejemplo n.º 4
0
class AccUntil(object):
    DONE = get_event()

    def __init__(self, spin, data='', delim='\r\n\r\n'):
        self.delim = delim
        self.arr = bytearray()
        self.spin = spin
        spin.add_map(LOAD, self.update)
        self.update(spin, data)

    def update(self, spin, data):
        self.arr.extend(data)
        if self.delim in self.arr:
            self.process(spin)

    def process(self, spin):
        spin.del_map(LOAD, self.update)
        a, b = self.arr.split(self.delim, 1)
        spin.drive(AccUntil.DONE, str(a), str(b))
Ejemplo n.º 5
0
class TmpFile(object):
    DONE = get_event()

    def __init__(self, spin, data, max_size, fd):
        self.fd = fd
        self.max_size = max_size
        spin.add_map(LOAD, self.update)

        self.update(spin, data)

    def update(self, spin, data):
        pos = self.fd.tell()
        count = self.max_size - pos
        self.fd.write(data[:count])

        if len(data) < count:
            return

        spin.del_map(LOAD, self.update)
        spin.drive(TmpFile.DONE, self.fd, data[count:])
Ejemplo n.º 6
0
class Terminator:
    """
    A handle for application layer protocols that use '\r\n' as token.

    def on_found(spin, data):
        print data

    Terminator(spin, delim='\r\n')
    xmap(spin, FOUND, on_found)

    If it arises the sequence below then on_found is processed.

        'some-data\r\n'
    """

    FOUND = get_event()

    def __init__(self, spin, delim='\r\n'):
        self.delim = delim
        self.arr = bytearray()

        spin.add_map(LOAD, self.update)

    def update(self, spin, data):
        self.arr.extend(data)

        if not self.delim in data:
            return

        data = str(self.arr)
        lst = data.split(self.delim)
        del self.arr[:]
        self.arr.extend(lst.pop(-1))

        for ind in lst:
            spin.drive(Terminator.FOUND, ind)
Ejemplo n.º 7
0
def get_env(header):
    """
    Shouldn't be called outside this module.
    """

    environ = {
        'REQUEST_METHOD': 'POST',
        'CONTENT_LENGTH': header.get('content-length', 0),
        'CONTENT_TYPE': header.get('content-type', 'text')
    }

    return environ


OPEN_FILE_ERR = get_event()


def drop(spin, filename):
    """
    Shouldn't be called outside this module.
    """

    try:
        fd = open(filename, 'rb')
    except IOError as excpt:
        err = excpt.args[0]
        spawn(spin, OPEN_FILE_ERR, err)
    else:
        spin.dumpfile(fd)
Ejemplo n.º 8
0
def get_env(header):
    """
    Shouldn't be called outside this module.
    """

    environ = {
                'REQUEST_METHOD':'POST',
                'CONTENT_LENGTH':header.get('content-length', 0),
                'CONTENT_TYPE':header.get('content-type', 'text')
              }

    return environ


OPEN_FILE_ERR = get_event()
def drop(spin, filename):
    """
    Shouldn't be called outside this module.
    """

    try:
        fd = open(filename, 'rb')             
    except IOError as excpt:
        err = excpt.args[0]
        spawn(spin, OPEN_FILE_ERR, err)
    else:
        spin.dumpfile(fd)

def make(searchpath, folder):
    """
Ejemplo n.º 9
0
from untwisted.event import get_event
from untwisted.splits import Terminator
from re import *

GENERAL_STR = '[^ ]+' 
GENERAL_REG = compile(GENERAL_STR)
SESSION_STR = '\*\*\*\* Starting FICS session as (?P<username>.+) \*\*\*\*'
SESSION_REG = compile(SESSION_STR)
TELL_STR    = '(?P<nick>[a-zA-Z]+)(?P<mode>.*) tells you:(?P<msg>.+)'
TELL_REG    = compile(TELL_STR)
SAY_STR     = '(?P<nick>[a-zA-Z]+)(?P<mode>.*) says:(?P<msg>.+)'
SAY_REG     = compile(SAY_STR)
SHOUT_STR   = '(?P<nick>[a-zA-Z]+)(?P<mode>.*) shouts:(?P<msg>.+)'
SHOUT_REG   = compile(SHOUT_STR)

START_SESSION = get_event()
TELL          = get_event()
SAY           = get_event()
SHOUT         = get_event()

def install(spin):
    spin.add_map(Terminator.FOUND, spliter)

def spliter(spin, data):
    m = findall(GENERAL_REG, data)
    
    if m: spawn(spin, *m)
    
    m = match(SESSION_REG, data)
    try:
        username = m.group('username')