mod_leech is an Apache 1.3.x module which uses a MySQL database to
enforce per-user download and concurrent-login quotas.
The module uses the following table to track and limit the activity of
users identified by HTTP basic authentication:
create table users (
user varchar(32) not null primary key,
-- How many concurrent connections does this user have?
logins bigint,
-- How many bytes has this user downloaded?
bytes bigint,
-- How many of each are allowed?
maxlogins bigint,
maxbytes bigint
);
When a user exceeds either quota, mod_leech can redirect them to an
error page (à la ErrorDocument), providing "user=name" and
"quota=logins" or "quota=bytes" parameters to enable customised
error handling.
The module maintains a pool of active database connections, and shares
them between Apache processes. (The size of the pool is configurable,
but only globally.)
All other configuration (which database server to talk to, how to
authenticate, which table to use, and where to redirect) is
per-VirtualHost.
Source code
Download mod_leech.tar.gz
This code is provided here with no warranty, and may be freely used,
modified, or redistributed provided that derivative works are clearly
identified as being different from the original, and copyright notices
in the source are preserved. (The package includes a complete license
statement.)
The package includes portions of Konstantin Knizhnik's very useful
POSIX.1b
emulation code, because FreeBSD didn't (at the time) provide a native
implementation of the semaphore operations I was using.
The package also includes a (FreeBSD-specific) patch to implement a
highly dubious "copy protection" feature that compares the MAC address
of the first Ethernet interface to an address stored in the source code,
and refuses to load if they are not the same. Please ignore this patch
(but see the history section below if you're
curious about its origins).
Status
At the time this module was written (in October 2001), it was the only
one I could find that implemented database connection pooling directly
(that is, not counting things like Apache::DBI under
mod_perl).
The module is preserved here because I think it's an interesting example
(and because I put a lot of effort into it, and like the way it turned
out), and not because I expect anyone will want to use it.
That said, the module worked perfectly the last time I tested it, which
was in 2002 under Apache 1.3.2x (under Linux and FreeBSD). I have not
tried to compile it against a recent Apache, but I would be surprised
if there were any non-trivial problems.
(If you want to try it, for some reason, I'd be happy to help.)
A related (but not quite the same) module is mod_bandwidth, which can
impose per-IP bandwidth and connection limits.
On the 29th of September, 2001 (exactly six years ago), I wrote to David
Aninowsky of Choopa, LLC. He wanted
an Apache module written, and a friend had referred me as someone who
could do the job. This module was developed as a result.
Mr. Aninowsky and I reached an agreement over the next month, and I sent
him a signed contract by FedEx near the end of October. Here's a summary
of the terms of our proposed contract:
- US$100/hour for a maximum of 30 hours for the initial development,
with an advance payment of $1000.
- Initial delivery by November 15th, followed by a two-week testing
period, during which I would fix any bugs that were found for no
extra charge.
- A six-month maintenance period, where I would do any additional work
on the module, if required, for a reduced rate of $75/hour.
- Choopa, LLC would own the copyright to the work.
I started working on the module soon afterwards, but the advance payment
(which was delayed by Mr. Aninowsky's work and travel schedules) arrived
only on the 30th of November. I delivered an initial release for testing
on the 3rd of December, despite the fact that I had not yet received my
copy of the contract.
(An aside: Mr. Aninowsky insisted on my including a "copy protection"
feature, whereby the module would refuse to load if the MAC address of
the first Ethernet card did not match an address stored in the source.
I advised him against it, but eventually implemented the check anyway.)
The subsequent testing period extended far beyond what we had originally
planned (partly because I was on vacation in December, but also because
we had to recompile Apache and so on), but I fixed a number of bugs we
found while testing. On the 23rd of February 2002 (after a number of
updates), I delivered a version with working connection pooling and
all known bugs fixed. During this time, we would occasionally talk on
EFnet IRC, and I explained a number of times how to compile, install,
and configure the module, and discussed testing strategies.
At this point, Mr. Aninowsky had still not executed and returned the
contract, despite repeated reminders. He was still testing the module
occasionally, but the only substantial problem he reported was because
of his FreeBSD kernel had SEMMNI set too low. I recommended setting the
"LeechPool" to 8 for testing, and verified that this worked. I did not
make any changes to the module after April 2002, because I had fixed
all the bugs that had been reported.
After mid-April, Mr. Aninowsky stopped responding to email from me. I
sent him mail on the 15th, 20th, 24th, and 28th of April, then on the
7th and 9th of May. On the 21st of May, I sent the following message:
Hi.
David, I think you're being very unprofessional by not replying to my
email, not talking to me on IRC, and not sending me the money (or the
paperwork) I'm owed. I realise that you must be busy with other work,
but that doesn't mean that you can ignore commitments you have made.
I've enjoyed working on mod_leech, and I don't want our relationship
soured. Please write back to me soon, and let us clear this matter up
amicably.
He responded on the same day:
Sorry for the misunderstanding I guess, I've been super busy and I am
closing on my house this month, so I've been running around doing that
plus building the datacenter out with another 30 racks. If you want I
can fax you the contract and I will wire you the funds shortly, I never
rip anyone off and I really do apologize for the delay in getting
everything done... I haven't even had a chance to beta test the darn
module yet! Its disappointing to me because this will be huge when I
launch it.
I sent him a fax number and repeated the instructions on how to transfer
money to my bank account. A week later, neither contract nor money had
arrived. On the 14th of June (after three reminders by email, and many
attempts to contact him on IRC), I sent the following:
Three weeks. Still no money, no fax, no email...
His response was classic.
Yea I'm afraid to send money to India they'll think I'm funding
terrorists.
I had no remaining illusions about Mr. Aninowsky's integrity, so I spoke
to a friend of mine who practices law in Massachusetts. It was clear to
me that pursuing any legal claims against Choopa would be too expensive
to consider, and I had already written off the money owed to me, but I
wanted to see what my options were.
We agreed that she (my lawyer friend, for whose help I am very grateful)
would write to him stating our case, and that we would let the matter
rest if he didn't respond favourably. Among other things, she wrote:
Mr. Menon-Sen informs me that you have expressed concern about paying
him because he resides in India. If this is what is impeding payment,
you may send a check made out to me or a money order to my office in
Boston. I will then forward the payment to Mr. Menon-Sen.
Mr. Aninowsky's response was, not surprisingly, belligerent and full of
bluster.
Dear Sir/Madam,
Mr Menon-Sen was asked to do a small project for us, with a payment of
$1,000.00USD placed up front. As far as I'm concerned we should be
going after him for the $1,000 and the loss of business due to the fact
that the project was never completed as promised by him. The work was
never completed to a satisfactory level and the fact that there was no
contract between Mr Menon-Son and our company meant we could take no
action to have the work completed in a timely and correct fashion. Any
legal claims your client has are fruitless.
Good Day,
David Aninowsky
President
Choopa, LLC
Of course, the only reason we didn't have a contract was because he
refused to sign and return the one I sent him; and the fact that he
reported no problems with the module after April 2002 rather belies
his claim that it was never completed.
Conclusion
David Aninowsky is the CEO of Choopa, LLC, a co-location and hosting
provider. Based on his irresponsible and unprofessional behaviour, and
what seems to be a pattern of ignoring problems and hoping they go away,
I cannot recommend that anyone do business with him.
I am glad that I got to write mod_leech, but I would have been happier
still if my work had not been wasted.
Thank you, Dave. You taught me a valuable lesson.