Feeds:
Posts
Comments

Posts Tagged ‘perl server’

ARCv2

So I’m perhaps 1% of the way to a poorly thought out middleware component like CORBA1. No, it’s more light-weight, maybe a messaging layer, sorry I mean wire-level protocol specification implementation such as AMQP.

And then I think (like hundreds have probably thought before me), you know, this would be more useful if it had authentication. After all, I don’t want just anyone to be able to send kill signals to any processes. That would be like everyone being root. Which terrifies me.

Don’t invent your own authentication mechanism

And the golden rule about authentication, as far as I can work out, is don’t invent your own authentication mechanism. You’ll get it wrong and leave gaping vulnerabilities for the bad guys to have their wicked way with you. That is, if anyone besides you ever uses your code. And besides, I don’t want to waste any of my 1500 lines on coming up with Yet Another Broken Authentication System.

A quick trip to CPAN

Then I’m looking through the Authen::XXX modules on CPAN and none of them behave in exactly the way I want. But somehow I find a perl server that includes authentication and perhaps does everything I want and I should definitely put it on my list of things to look into even though I’m having a lot of fun with AnyEvent right now.

But by the time I come to look again, I can’t find it. And I’ve complained about documentation before, but Emacs really does deserve it, and I know of no system or language that is better documented than Perl. But I guess the classification problem is a bit tricky to overcome.

ARCv2

Anyway, long story short, I found it.

authenticated perl server -http

An Authenticating Perl Server

The first link (warning PDF) is a paper about using Authen::SASL in client/servers and it mentions ARCv2 which sounds like what I’m looking for.

The first thing to do is find out if it does what I want. The second is to check if it works on Windows.


1. Ambiguity left in deliberately

Read Full Post »

A little while ago we were talking about clients and servers. And I’ve finally got back to the interesting thing which is playing with emacs networking.

The comment from Gabriel nicely pointed out emacs’ low-level socket facilities.

(open-network-stream) which is synchronous and
(make-network-process) which can be asynchronous if the parameter is set. I haven’t been able to make the last one work, but check it out yourself.

So, er, I’m not 100% sure how to simulate a crappy internet connection. Maybe making my server pause 2 seconds between line reads will be sufficient.

sub process_request
{
    while () {
        s/\r?\n$//;
        print STDERR "Received [$_]\n";
        last if /quit/i;
        sleep 2;
    }
}

I’m also interested (or perhaps curious?) in when the connection is made and broken.

sub post_accept_hook
{
    print STDERR "Accepted new connection\n";
}

sub post_process_request_hook
{
    print STDERR "Client disconnected\n";
}

Did I mention I think Perl’s bad press is a little unfair?

So what I need now is a basic API for connecting, disconnecting and sending messages. make-network-process makes a process as you can probably infer from the name and for my purposes a single client is enough so I make a wrapper to get the current process. Layering in this way means I can add any error handling at the appropriate point later on. And also it should be fairly easy to generalise client-process to choose between different connections.

(defconst client-process-name "*client*")
(defsubst client-process () (get-process client-process-name))

For maximum asynchronicity we add a sentinel function that will be called back when the connection has completed, either successfully or unsuccessfully.

It turns out that a perl-style chomp function is really handy!

(defun chomp (str)
  (if (and (stringp str) (string-match "\r?\n$" str))
      (replace-match "" t nil str)
    str))

(defun client-notify-connect (&rest args)
  (message (format "Connection message [%s]" (mapcar #'chomp args))))

I added a fairly hacky (sit-for 1) after opening the client as otherwise I could send messages before it was ready due to the sentinel and nowait. Future versions will probably get the sentinel to set an "opened" variable which will determine whether the send message and close functions work.

(defun client-open (host port)
  (make-network-process :name client-process-name
                        :host host
                        :service port
                        :nowait t
                        :sentinel #'client-notify-connect)
  (sit-for 1))

Closing the connection is a simple matter of deleting the process. I confirmed this against my test perl server.

(defun client-close ()
  (delete-process (client-process)))
(defun client-send-string (str)
  (process-send-string (client-process) (concat str "\r\n")))

My test program simply sends 10 hello messages to the server at the same time as inserting 10 hellos in the buffer. The fact that the buffer insertions completed almost instantaneously whereas the server took around 20 seconds to display the messages indicates there is some degree of separation.

(progn
  (client-open 'local 8080)
  (dotimes (var 10)
    (client-send-string (format "Hello %s" var))
    (insert (format "Hello %s\n" var)))
  (client-close))

Next time I’ll look at setting up a filter to receive messages that the server sends back. Any questions or comments let me know.

If you liked this post, why not subscribe to my RSS feed.

Read Full Post »

So much for good intentions. I get myself all geared up to
the problem I need to solve today? Well, I want to find out about how emacs networking works.

So first, I need a simple server to play with. Now normally when I think server I automatically think Apache but this time I want something a bit more basic. And if I was thinking enterprise1 I might reach for C++/ACE. However, for something basic, Perl is ideal.

I’ve just upgraded to Ubuntu 9.04 on this box and Perl is unused so let’s see if it has what I need.

06.52 Ubuntu finishes booting

I waste a few minutes on the internet.

06.57 I start Emacs

and remind myself just how gorgeous emacs-23 looks.

06.59 I check for the Net::Server package
$ perldoc Net::Server
You need to install the perl-doc package to use this program.
$ sudo apt-get install perl-doc

$ perldoc Net::Server
No documentation found for "Net::Server".

It is not installed. I could install it using apt (it is called libnet-server-perl) but I’ve got in the habit of using Perl’s CPAN module which provides package management facilities too. The advantage is that it is somewhat consistent across platforms.

$ sudo perl -MCPAN -e shell

cpan[1]> install YAML
cpan[2]> install CPAN
cpan[3]> reload CPAN
cpan[4]> install Bundle::CPAN

The CPAN bundle installs quite a bit so I go for breakfast.

07.15 Back from breakfast
cpan[5]> install Net::Server

I took this code pretty much straight from perldoc Net::Server.

#!/usr/bin/perl

use strict;
use warnings;

package SimpleServer;

use base qw(Net::Server);

sub process_request
{
    while (<STDIN>) {
        s/\r?\n$//;
        print STDERR "Received [$_]\n";
        last if /quit/i;
    }
}

SimpleServer->run(port => 8080);

I tested it using telnet localhost 8080 to confirm it does what I need.

07.20 All done

Presumably Python and Ruby have similar incantations that will get a server up and running quickly.

And unfortunately at this point I have to go to work. But later on, I can begin experimenting with emacs networking.


1. i.e. some thing that grows humongous over a period of two years and then no-one wants to work with it anymore.

Read Full Post »

Follow

Get every new post delivered to your Inbox.