tracing in pow
I wondered what's happening in pow, so I tried to trace
what it is doing. My conclusion is, how could this be
even more wrong?
Please follow me to see what's happening...
So on it's website, it's telling the users to install it via:
curl get.pow.cx | sh
Aside from the point that you should never do this (pleasedownload the shell script and take a look before running it),
it is basically install.sh, which is trying to download a
tarball for the specific version of pow and untar it,
and run the pow command to install the whole thing.
It would do a number of things. Let's only look at the
important ones, or there would be too much to look at.
So the pow command would pick the system installer,
it would then install a firewall plist, a number of
resolver configs, and a plist for pow itself in its
local installer.
After that, the installer would load the firewall with sudo,
and start pow via pow plist.
Note that since they are doing this in
/Library/LaunchAgents
and
/Library/LaunchDaemons
, they would be running whenMac OSX starts.
*
And what are they doing? There are a number of files
we should be looking at. Let's go through them one by one.
The firewall is probably cx.pow.firewall.plist.eco.
It is trying to forward port 80 to port 20559 by default.
That means, whenever you're hitting http://pow.dev:80 it
would be forwarded to http://127.0.0.1:20559.
Let's look into the DNS resolver, which I believe it's
resolver.eco, which would be installed into
/etc/resolver/dev
with sudo.According to Mac's resolver man page, this means only
domains ending with dev (or whatever it's configured) would
use this pow DNS server, listening on 20560 by default.
Lastly, the pow plist itself, which I think is cx.pow.powd.plist.eco,
which is simply trying to launch Node to run pow command.
*
So by installing pow, it would then install a pow daemon,
which itself is both a DNS server and an HTTP server. We'll
talk about this later. It would also install a special DNS
resolver for domains ending with
.dev
, and a firewall rulefor forwarding port
80
to port 20559
.In the end, what does pow really do for serving a request?
Mac would first look at
/etc/resolver/dev
and realize thatit needs a special DNS server located on
127.0.0.1:20560
,which is a pow DNS server, resolving the IP of the domain to
127.0.0.1
, and the browser would then try to make a requestagainst
127.0.0.1:80
, with header Host: whatever.dev
, whichthen the firewall would forward the request from
127.0.0.1:80
to
127.0.0.1:20559
, which is the pow HTTP server, which wouldtry to look at
~/.pow/whatever
, locating the config.ru
, spawninga
nack_worker
process, which is a Ruby server, listening on aUNIX domain socket, and in the mean time, converting the request
object into a netstring embedding a JSON, writing into the UNIX
domain socket, and the
nack_worker
would parse the netstring,extracting the JSON, parsing the JSON, and builds the Rack
env
object based on the JSON it reads, finally calling the Rack app,
passing the response back to pow, and back to the browser.
Oh wait, it might not really pass the request along to the Rack app.
It could be intercepted by pow if the requested path matches a file
located in the particular Rack app's public directory.
Seriously? Sorry that I am too lazy to link the source line by line.
This is simply too much. It also needs to handle RVM stuffs, yet
another pile of stuffs.
I would much prefer a simple command to launch a server.
If you're developing a number of applications, and need to run them
at the same time, then I believe you must have the ability to solve
this in a more elegant way.
Maybe write a pow equivalent in Ruby, then all the conversions
could be omitted. We could simply spawn Ruby processes. I don't
see what's the point of using Node to run Ruby.
0 retries:
Post a Comment
Note: Only a member of this blog may post a comment.