# pyzor.server

Networked spam-signature detection server.

The server receives the request in the form of a RFC5321 message, and responds with another RFC5321 message. Neither of these messages has a body - all of the data is encapsulated in the headers.

The response headers will always include a “Code” header, which is a HTTP-style response code, and a “Diag” header, which is a human-readable message explaining the response code (typically this will be “OK”).

Both the request and response headers always include a “PV” header, which indicates the protocol version that is being used (in a major.minor format). Both the requestion and response headers also always include a “Thread”, which uniquely identifies the request (this is a requirement of using UDP). Responses to requests may arrive in any order, but the “Thread” header of a response will always match the “Thread” header of the appropriate request.

Authenticated requests must also have “User”, “Time” (timestamp), and “Sig” (signature) headers.

class pyzor.server.BoundedThreadingServer(address, database, passwd_fn, access_fn, max_threads, forwarding_server=None)

  Bases: `ThreadingServer`

  Same as ThreadingServer but this also accepts a limited number of concurrent threads.

  process_request(request, client_address)

    Start a new thread to process the request.

  process_request_thread(request, client_address)

    Same as in BaseServer but as a thread.

    In addition, exception handling is done here.

class pyzor.server.PreForkServer(address, database, passwd_fn, access_fn, prefork=4)

  Bases: `Server`

  The same as Server, but prefork itself when starting the self, by forking a number of child-processes.

  The parent process will then wait for all his child process to complete.

  load_config()

    If this is the parent process send the USR1 signal to all children, else call the super method.

  serve_forever(poll_interval=0.5)

    Fork the current process and wait for all children to finish.

  shutdown()

    If this is the parent process send the TERM signal to all children, else call the super method.

class pyzor.server.ProcessServer(address, database, passwd_fn, access_fn, max_children=40, forwarding_server=None)

  Bases: `ForkingMixIn`, `Server`

  A multi-processing version of the pyzord server. Each connection is served in a new process. This may not be suitable for all database types.

class pyzor.server.RequestHandler(*args, **kwargs)

  Bases: `DatagramRequestHandler`

  Handle a single pyzord request.

  dispatches = {'check': <function RequestHandler.handle_check>, 'info': <function RequestHandler.handle_info>, 'ping': None, 'pong': <function RequestHandler.handle_pong>, 'report': <function RequestHandler.handle_report>, 'whitelist': <function RequestHandler.handle_whitelist>}
  handle()

    Handle a pyzord operation, cleanly handling any errors.

  handle_check(digests)

    Handle the ‘check’ command.

    This command returns the spam/ham counts for the specified digest.

  handle_error(code, message)

    Create an appropriate response for an error.

  handle_info(digests)

    Handle the ‘info’ command.

    This command returns diagnostic data about a digest (timestamps for when the digest was first/last seen as spam/ham, and spam/ham counts).

  handle_pong(digests)

    Handle the ‘pong’ command.

    This command returns maxint for report counts and 0 whitelist.

  handle_report(digests)

    Handle the ‘report’ command in a single step.

    This command increases the spam count for the specified digests.

  handle_whitelist(digests)

    Handle the ‘whitelist’ command in a single step.

    This command increases the ham count for the specified digests.

class pyzor.server.Server(address, database, passwd_fn, access_fn, forwarder=None)

  Bases: `UDPServer`

  The pyzord server. Handles incoming UDP connections in a single thread and single process.

  handle_error(request, client_address)

    Handle an error gracefully. May be overridden.

    The default is to print a traceback and continue.

  load_config()

    Reads the configuration files and loads the accounts and ACLs.

  max_packet_size = 8192
  reload_handler(*args, **kwargs)

    Handler for the SIGUSR1 signal. This should be used to reload the configuration files.

  shutdown_handler(*args, **kwargs)

    Handler for the SIGTERM signal. This should be used to kill the daemon and ensure proper clean-up.

  time_diff_allowance = 180

class pyzor.server.ThreadingServer(address, database, passwd_fn, access_fn, forwarder=None)

  Bases: `ThreadingMixIn`, `Server`

  A threaded version of the pyzord server. Each connection is served in a new thread. This may not be suitable for all database types.