24 02/11
22:55

Some Perl to redirect HTTP requests

After almost a year without publishing a single post, it seems this week I’m going to beat all my records.

A week ago, I wanted to prank my brother for a while. Nothing sophisticated… just some Iptables rules, Tinyproxy and HTTP magic. To go ahead with my evil plans, I needed “something” able to redirect a HTTP request. Actually, there are several ways to do that: Apache redirects, Tornado, Netcat* and so on. These alternatives are fast, bulletproof and time-saving, but not fun.

As many of you probably know, I didn’t get a job yet. That necessary means that I’ve got plenty of free time to waste. So… what did I do? I wrote some Perl and today I’m publishing the source code just in case someone finds it useful somehow. Like the previous entry, it’s published in the public domain.

The script just collects connections, issues 301 back (Moved Permanently) and sets Location to the URI specified as a command line argument (option -u). It lacks some security checks (left as an exercise to the reader) but it does what it is supposed to do. You may likely spot some silly bugs as I haven’t spent much time reading it again. Reports are welcome!

For those wondering, the prank was a big success. I’m afraid I can’t spare any detail by now but it turns out my bro is still thinking that his computer has been cracked.

Example invocation:

$ perl redir.pl -p 7070 -v -t 3 -u http://31337.pl
2011/02/24 21:41:54 Listening on port 7070
2011/02/24 21:41:54 Redirecting HTTP requests to: ‘http://31337.pl’
2011/02/24 21:41:54 3 thread(s) working under the hood

And finally the source code:

use warnings;
use threads;
 
use Thread::Queue;
use POSIX;
 
use IO::Socket::INET;
use HTTP::Request;
use HTTP::Status qw(:constants status_message);
 
use Getopt::Long;
use DateTime::Format::HTTP;
use Data::Validate::URI qw(is_http_uri);
use Log::Log4perl qw(:easy);
 
use constant MAX_THREADS => 10;
use constant MAX_LEN_HEADERS_BUFFER => 8*1024;
use constant DEFAULT_REDIRECT_URI => "http://www.example.org";
use constant DEFAULT_PORT => 80;
use constant DEFAULT_POOL_SIZE => 3;
 
my $redir_uri = DEFAULT_REDIRECT_URI;
my $server_port = DEFAULT_PORT;
my $thread_pool_size = DEFAULT_POOL_SIZE;
my $verbose;
 
GetOptions('url=s' => \$redir_uri, 
           'port=i' => \$server_port,
           'threads=i' => \$thread_pool_size,
           'verbose'  => \$verbose) or exit -1;
 
die "Invalid redirect URI (e.g. http://www.example.org)\n" unless is_http_uri($redir_uri);
die "Invalid port (e.g. 8080)\n" unless 0 < $server_port && $server_port < 2**16;
die "Invalid pool size (should be in [1..".MAX_THREADS."])\n" 
            unless 0 < $thread_pool_size && $thread_pool_size <= MAX_THREADS;
 
Log::Log4perl->easy_init( level => $verbose? $DEBUG : $INFO );
 
my $pending = Thread::Queue->new(); 
 
my $lsock = IO::Socket::INET->new( LocalPort => $server_port,
                                   Proto => 'tcp',
                                   Listen => 1,
                                   Reuse => 1 ) or die "Couldn't bind listening socket ($!)\n"; 
 
INFO("Listening on port $server_port\n");
INFO("Redirecting HTTP requests to: '$redir_uri'\n");
 
my @workers = ();
for (1..$thread_pool_size) {
    if ($thread = threads->create("worker")) {
        push(@workers, $thread);
    }
}
 
DEBUG(sprintf("%d thread(s) working under the hood\n", $#workers+1));
 
# Set a tidy shutdown just in case an external agent SIG{INT,TERM}s the process
$SIG{'INT'} = $SIG{'TERM'} = sub {
    # Dirty hack. threads->kill() does not wake up the thread :(
    for (1..@workers) {
        $pending->enqueue(-1);
    }
    for (@workers) {
        DEBUG(sprintf("Worker %d terminated: %d clients served\n", $_->tid, $_->join())); 
    }
    close($lsock); 
    exit 0; 
};
 
while(1) {
    my $csock = $lsock->accept() or next;
    $pending->enqueue(POSIX::dup(fileno $csock));
    DEBUG(sprintf("New client enqueued: %s:%s\n", $csock->peerhost, $csock->peerport));
    close($csock);
}
 
sub worker {
    my $clients_served = 0;
    while(my $fd = $pending->dequeue) { # API promises thread safety :-)
        if ($fd == -1) {
            return $clients_served;
        }
 
        my $sock = IO::Socket::INET->new_from_fd($fd, "r+");
        DEBUG(sprintf("Dequeued client %s:%d by worker %d.\n", $sock->peerhost,
                            $sock->peerport, threads->tid()));
 
        my $buf = "";
        while(<$sock>) {
            # CAUTION: there isn't any self protection against very long lines
            last if /^\r\n$/;
            $buf .= $_;
            goto BYE if length $buf > MAX_LEN_HEADERS_BUFFER;
        }
 
        if (my $request = HTTP::Request->parse($buf)) {
            INFO(sprintf("[%s] %s {%s}\n", $request->method, $request->uri, $sock->peerhost));
        }
 
        printf $sock "HTTP/1.1 %d %s\r\n", 
            HTTP_MOVED_PERMANENTLY, status_message(HTTP_MOVED_PERMANENTLY);
        printf $sock "Date: %s\r\n", DateTime::Format::HTTP->format_datetime;
        print $sock "Location: $redir_uri\r\n";
        print $sock "Server: Simple HTTP Redirection/0.1 ($^O)\r\n";
        print $sock "Connection: close\r\n";
        print $sock "\r\n";
 
BYE:  
        $clients_served++;
        close($sock);
    }
}

(*) just an approach, may drop connections:

while [ 1 ]; 
 do echo -e "HTTP/1.1 301 Moved Permanently\r\nLocation: http://31337.pl\r\n\r\n" | nc -l 7070; 
done

13 04/09
13:56

X Aniversario de AsturLiNUX

Esta semana comienzan las actividades conmemorativas del décimo aniversario de la AsturLiNUX.

Durante toda la semana hay programadas diversas actividades (charlas, talleres y conferencias) y como colofón, un gran acto central, el próximo sábado 18 de abril donde intervendrán Iván Frade (”Maemo; Software Libre Movil”) de Nokia y Rodrigo Salvador (”El Software Libre para la Gestión de la Red Educativa de la Junta de Andalucía”) de la Junta de Andalucía.

Además de estas ponencias, tendrá lugar una mesa redonda (“El Software Libre dentro y fuera de Asturias”) con una lista de participantes muy interesante.

Más información en la página principal y en el programa.

30 08/07
11:27

Example: How to statically and dynamically link your executables

People usually uses Google, among other things, to look for hints about how to do small tasks. Hopefully, you will find the hint you were looking for in somebody’s blog, because he or she had the same problem time ago and decided to talk about it.

Last night, I was a bit bored and started writing a dumb set of files to introduce people how static and dynamic linking work, so trying to put my two cents and add a new hint to the wild wild web, I’m sharing it. The C source files are practically useless, therefore pay attention to the Makefile, the magic is in there.

If you’re downloading it only to compile, execute and see what happens forget about it, the program is completely silly. Otherwise, probably the Makefile is buggy somewhere so bug reports are welcome. For teaching purposes, try, for example, breaking the ABI and see what happens.

Google, index this post please!

Update: This example does not cover autotools/libtool

24 04/07
19:51

DudesConf

Dear Lazyweb,

I’m sorry, I know I’m late but here it is my promised report about DudesConf.

It was simply cool, even though it was my first Debian-related real [0] event everything was in a good, familiar and friendly shape. I’m really happy to had met all the Debian developers who attended, GPUL people and others, pleased to meet you guys!

Talks, BOFs, meals, accommodation, everything was impressive, so my gratitude goes to everyone who helped made DudesConf possible :). If you feel curious, you should be able to watch some pictures in the gallery or read the live (I know, it’s not really live at the moment, my fault) event coverage.

Of course, Ricardo, thank you for take me to A coruña, it was a pleasure for me to share some kilometers (some? all of them!) with you ;)

[0] Real comes from real life, Daniel pointed me out days ago to the actual difference between real an virtual life.

08 04/07
16:52

Thanks

13:55 -!- aba changed the topic of #debian-release to: Done.

Superb guys! Thanks again to everybody who made it possible, release team, translators, bug reporters, Debian CD, ftp team, QA team,… and to everyone who is part of this wonderful project called Debian!

See you next weekend at Dudesconf!

By the way, the #debian-release’s topic change notice was stolen from Steve’s blog.

08 04/07
10:25

New DPL

Congratulations Sam! It’s time to make Debian fun again, best of luck!.

19 03/07
17:23

Hello again my old dude!

My mail agent is Mutt again! (again mainly because it was my first MUA). Let’s fetchmail and procmail do the hard work while I happily browse my mailboxes!

Good bye Pine, Evolution, Sylpheed Claws… and now, Kmail!. (note Evolution link…)

BTW, xfmail2mbox.sh works fine, my mails moved smoothly to Mutt as well, so thanks to Jörg Reinhardt.

14 03/07
11:36

Debian developer

Yes, that’s it, I’m finally Debian developer. I would like to use this post to say thanks to everyone who helped me to achieve this goal since I applied in 2005-10-05, here we go!

Thanks to…

  • Ricardo Cárdenes, the man who linked me to Debian development world and, of course, my advocate.
  • Moray Allan, my responsible AM.
  • The NM Staff (Myon, HE, Ganneff, Elmo…)
  • My usual sponsors: Ricardo, Ana, Amaya, Mones, Gunnar….

I hope to write an small report about the NM process with my impressions and opinions soon, so stay tuned. By the way, if you are planning to join Debian and you’re able to meet me, I’m offering GPG key signing since today :)

Finally, thanks to all my #dudes!

21 12/06
13:27

Discover, rename and launch!

This is exactly what OSX developers did with Leopard and Spaces. Isn’t this feature available for ages in lots of GNU/Linux desktops? Are OSX users definitely (re-)discovering how to work natively with virtual-desktops?, let’s see what Apple says in Leopard’s main website:

You do a lot on your Mac. So what happens when all those projects pile up? Easy. Use Spaces to organize all your windows into groups and banish clutter completely. A Space for everything and everything in its Space. Only with Mac OS X Leopard.

What the fuck? Only with Mac OS X Leopard? AAAAAAAAA!

11 12/06
13:50

Etch is very cold (like local weather)

Yay! Release team reported that Etch (current testing branch) is now frozen, Andreas Barth announced it.

13 11/06
14:52

Debian NM process movements

I was approved by Debian NM FrontDesk team today, then, only one step remaining to dispatch my application.

  • Step 1: Application
  • Step 2: Identification
  • Step 3: Philosophy and Procedures
  • Step 4: Tasks and Skills
  • Step 5: Recommendation
  • Step 6: Front Desk Check
  • Step 7: Debian Account Manager check and account creation

I hope to be DAM approved soon, go go! :)

By the way, tomorrow I will have a skills test to get a driving license, wish me luck!

08 11/06
12:41

Airs of change

Hello Konqui, pleased to meet you!

Hello KDE!

05 10/06
00:03

Extending my Firefox’s capabilities!

This is just another list of Firefox extensions I’m using at the moment:

  • Google Toolbar for Firefox – Useful Google utils pack (includes search, of course).
  • del.icio.us – All I need to manage my social bookmarks.
  • ColorZilla – Interesting extension to extract colour codes directly from websites.
  • VideoDownloader – Well known add-on.
  • Forecastfox – And if it rains tomorrow?.
  • PDF Download – Just a dialog to choose between open, download, or show as HTML the downloaded PDF files.
  • Download Statusbar – Enhanced and interesting download manager.
  • Colorful Tabs – Put colours in your life!
  • Flashblock – Flash really sucks, prevent it for me!
  • Extended Statusbar – Adds more information about the loaded website, for example spent time or download speed.
  • Tab X – Adds an independent kill button to each tab.
  • Link Alert – Prevents me to download rubbish, like Microsoft Word documents.

Excuse me, I forgot all the links to these extensions, feel free to search them yourself ;)

This ultraextended Firefox makes my life easier!

08 09/06
11:32

UNIX is funny as well

Will it work at any time? It would be wonderful!

sudo make me a sandwitch, LOL


- Hey man, let me fly this aircraft!
- What? Are you joking? Who are you?
- Sudo let me fly this aircraft!
- Ok, take the control sir.
- LOL

By courtesy of Rastreador

17 04/06
21:43

1/3

In the last 30 minutes i received this fresh news, ID check and P&P marked as passed on Debian NM, yehaaaa!