Code Samples

The following code snippets come from a Perl script generates a PDF document containing an image file of a user's signature read passed across the socket from the client.

First, note our setup:

			use Net::Server::INET;
			use vars qw(@ISA);
			@ISA = qw(Net::Server::INET);
		
This simply tells Perl that we are extending Server::INET, and we grab the global variables for the package.

The interesting stuff happens within process_request(). This subroutine is called after the socket connection is established between the client and the server and inetd forks the request to our script. Here's a chunk of the processing code:

	# Read the signature file from the client:
      	while (1) {
           # Get the size of the incoming chunk of data:
           $r = sysread $sock, $t, 4;
           if ($r > 0) {
               $size = unpack("N", $t);
               debugPrint("Image chunk size = $size\n", $self);
               # Read the chunk of data:
               $r = sysread $sock, $data, $size;
               # Write the OK response:
               if ($data == -9999) {
                   debugPrint("Received stop signal from client\n", $self);
                   writeData($sock, $ok, $self);
                   last;
               } else {
                   writeData($sock, $ok, $self);
                   print JPEG "$data";
               }
           } # end if ($r > 0)
           if ($r == 0) {    # We've reached the end of the file
               debugPrint("End of read loop reached\n", $self);
               writeData($sock, $ok, $self);
               last;
           }
           
	} # end while (1)
		
This entire chunk will be enclosed within and eval to be sure we clean up after ourselves should the connection to the client be lost. The above chunk reads an image file chunk by chunk across the connection. The size of the chunk is determined by the client, and we know how much to expect thanks to the first sysread() call. The socket itself is gotten with the following:
			$sock = $self->{server}->{client};
		
Just as an FYI.

When we're finished in process_request, that's it. inetd will clean up our socket connection for us, and kill the forked process. But, note in the code snippet above we're written the image to a file. It would be a bad thing to leave the file once we're through with it for security reasons (since it is someone's signature). Later in process_request(), we do unlink() the file, but what if something happens to the connection before that and the process is killed? Well, here's where one of the user-defined hooks in Net::Server::INET come in handy:

			sub post_process_request_hook {
    				# Check if the signature image still exists...if so, delete it:
    				if (-e $signature_file) {
        				unlink($signature_file) or die "Could not unlink $signature_file\n";
    				}
			} # end post_process_request_hook 
		

post_process_request_hook() is called just before the socket connection is disconnected (whether by error or the end of the processing). Within the base class, it is an empty subroutine, but here we simply check if our image file exists, and if it does, we unlink() it. We can clean up after ourselves regardless of whether or not process_request() completes without error.

Practical Applications Conclusion

Lightning Talk by brian janaszek (bmj@anklebiter.net)