Search code examples
perlmojolicious

How can I get the port that Mojolicious::Lite chooses?


Joel Berger posted this little program to start a web server to serve local files, and it works great:

use Mojolicious::Lite;

@ARGV = qw(daemon);

use Cwd;
app->static->paths->[0] = getcwd;

any '/' => sub {
    shift->render_static('index.html');
    };

app->start;

I prepopulated the command line in @ARGV because I forget to do that. When it starts, it gives a message telling you which port it chose, using 3000 if it can:

$ perl ~/bin/mojo_cwd
[Fri Mar 29 19:14:09 2013] [info] Listening at "http://*:3000".
Server available at http://127.0.0.1:3000.

I'd like to get that port programmatically so a test suite can know where to look for it, and I'd prefer not to do it by scrapping output. None of my experiments for this were useful and I think I was always going in the wrong direction. It appears that it doesn't choose the port until it starts, and once I call start, that's the end of it.

I don't want to specify the port myself, either.

This isn't an urgent matter. I have a current solution to this with another simple HTTP framework, but I've been looking at replacing most of that stuff with Mojo if I can. Since the old stuff still works, this is really just something nice to have rather than something in my way.


Solution

  • You can't, but the daemon command only binds to port 3000 and will not try anything else unless you tell it to. If you're using Test::Mojo you don't need to know the port in advance anyway, for anything else you can always wrap your application in a little Mojo::Server::Daemon script.

    use Mojolicious::Lite;
    use Mojo::IOLoop;
    use Mojo::Server::Daemon;
    
    get '/' => {text => 'Hello World!'};
    
    my $port   = Mojo::IOLoop->generate_port;
    my $daemon = Mojo::Server::Daemon->new(
      app    => app,
      listen => ["http://*:$port"]
    );
    $daemon->run;