# 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: `pyzor.server.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: `pyzor.server.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: `socketserver.ForkingMixIn`, `pyzor.server.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: `socketserver.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: `socketserver.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: `socketserver.ThreadingMixIn`, `pyzor.server.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.