Extending Vaurien — Vaurien 0.4 documentation

### Navigation

- index
- next |
- previous |
- Vaurien 0.4 documentation »

# Extending Vaurien

Note

Before reading this section, make sure you read Keep-alive vs Disconnect

You can extend Vaurien by writing new protocols or new behaviors.

## Writing Protocols

XXX

## Writing Handlers

Creating new handlers is done by implementing a class with a specific signature:

    from vaurien.handlers import Handler

    class MySuperHandler(object):

        name = 'super'
        options = {}

        def __call__(self, client_sock, backend_sock, to_backend):
            # do something here
            return True

    Handler.register(MySuperHandler)

Vaurien can use this handler and call it everytime data is being seen on one hand or the other.

You must call Handler.register against your class is order to add it to the list of the available plugins.

Let’s see the different attributes and options we have in this class:

- name - the name under which your backend is known
- options - a mapping containing your handler options
- client_sock - the socket opened with the client
- backend_sock - the socket opened with the backend server
- to_backend - a boolean giving the direction of the call. If True it means some data is available in the client socket, that is supposed to go to the backend. If False, it means data is available on the backend socket and should be tramsmitted back to the client.

For the handler options, each option is defined in the options mapping. The key is the option name and the value is a 3-tuple providing:

- a description
- a type
- a default value

every option is optional and need a default value

Everytime a handler is used, it gets two extra attributes:

- settings - the settings loaded for the handler
- proxy - the proxy instance

## The BaseHandler class

XXX

## Full handler example

Here is how the delay handler is specified:

    from vaurien.handlers.base import BaseHandler

    class Dummy(BaseHandler):
        """Dummy handler.

        Every incoming data is passed to the backend with no alteration,
        and vice-versa.
        """
        name = 'dummy'
        options = {'keep_alive': ("Keep-alive protocol",
                                bool, False),
                'reuse_socket': ("If True, the socket is reused.",
                                    bool, False)}

        def __call__(self, client_sock, backend_sock, to_backend):
            data = self._get_data(client_sock, backend_sock, to_backend)
            if data:
                dest = to_backend and backend_sock or client_sock
                source = to_backend and client_sock or backend_sock
                dest.sendall(data)

                # If we are not keeping the connection alive
                # we can suck the answer back and close the socket
                if not self.option('keep_alive'):
                    data = ''
                    while True:
                        data = dest.recv(1024)

                        if data == '':
                            break
                        source.sendall(data)
                    dest.close()
                    dest._closed = True
            elif not to_backend:
                # We want to close the socket if the backend sock is empty
                if not self.option('reuse_socket'):
                    backend_sock.close()
                    backend_sock._closed = True

            return data != ''

## Using handlers

Once the handler is ready, you can point it to Vaurien by providing its fully qualified name - e.g. the class name prefixed by the module and package(s) names.

Then you can use it with the –behavior option:

    $ vaurien --proxy localhost:8000 --backend google.com:80 \
        --behavior 20:path.to.the.callable \
        --handler-delay-sleep 2

Or by using a configuration file:

    [vaurien]
    behavior = 20:foobar

    [handler:foobar]
    callable = path.to.the.callable
    foo=bar

And calling Vaurien with –config:

    $ vaurien --config config.ini

### Navigation

- index
- next |
- previous |
- Vaurien 0.4 documentation »