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)
process_request_thread(request, client_address)
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 = {'info': <function handle_info at 0x7fbd0e72cd70>, 'whitelist': <function handle_whitelist at 0x7fbd0e72ccf8>, 'ping': None, 'report': <function handle_report at 0x7fbd0e72cc80>, 'pong': <function handle_pong at 0x7fbd0e72cb90>, 'check': <function handle_check at 0x7fbd0e72cc08>}
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)
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.