Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??

A year or so ago, I finally got fed up with selecting CPAN mirrors on my couple dozen hosts. I'm installing the same 10 or 50 modules on all these hosts over and over and it seems silly both to pull down the same modules over and over and to have to go through cutting and pasting the new url to each host every time. Wouldn't it be easier, I thought, if I could just set it to the the URL to my own mirror and use that?

But I don't install modules that often and don't want to share the mirror, so it seemed rude to create an actual rsync mirror just for my tiny hosting situation. My solution was a roll-your-own Caching CGI CPAN proxy system.

#!/usr/bin/perl use strict; use CGI; use CGI::Carp qw(fatalsToBrowser); use Cache::File; use Data::Dumper; use LWP::UserAgent; my $cache_location = "/home/somewhere/writeable/by/httpd/"; my @mirrors = ( # NOTE: I'd use more than one here, but have found that # causes problems "http://yourfavorite/mirror/", ); my $mirror = $mirrors[ rand @mirrors ]; my $cgi = new CGI; my $pinfo = $ENV{PATH_INFO}; $pinfo =~ s/^\///; my $CK = "PPC:$pinfo"; my $again = 0; THE_TOP: # we regen the cache each time just in case things aren't flu +shed correctly... # probably don't need to though my $cache = Cache::File->new(cache_root=>$cache_location, default_expi +res => '2 day' ); if( $cache->exists($CK) and $cache->exists("$CK.hdr") ) { our $VAR1; my $res = eval $cache->get( "$CK.hdr" ); die "problem finding cach +e entry\n" if $@; my $status = $res->status_line; print $cgi->header(-status=>$status, -type=>$res->header( 'content +-type' )); my $fh = $cache->handle( $CK, "<" ) or die "problem finding cache + entry\n"; if( $res->is_success ) { my $buf; while( read $fh, $buf, 4096 ) { print $buf; } } else { print $status; } close $fh; unless( $res->is_success ) { $cache->remove($CK); } exit 0; } elsif( not $again ) { $again = 1; my $ua = new LWP::UserAgent; $ua->agent("PPC/0.1 (paul's proxy cache perlmonks-id=16186)"); $cache->set($CK, 1); # doesn't seem like we should ahve to do this +, but apparently we do my $fh = $cache->handle( $CK, ">" ); my $request = HTTP::Request->new(GET => "$mirror/$pinfo"); my $response = $ua->request($request, sub { my $chunk = shift; pri +nt $fh $chunk }); close $fh; $cache->set("$CK.hdr", Dumper($response)); goto THE_TOP; } die "problem fetching $pinfo. :(\n";

I'd post it directly to the code catacombs or CPAN or something, but I'm not particularly proud of it. I think it'd be useful to others, and it certainly functions, but I'm seeking feedback on it. I'm hopeful that there'll be some insightful comments on it. (Are my module choices sane? Did someone else do this better and I just haven't found it?)

UPDATE: ... or, if there's nothing at all to say about it, then this is a fine resting place for it.

UPDATE: Actually, the final resting place is now here: CPAN::CachingProxy

-Paul


In reply to My CPAN Proxy Mirror [CPAN::CachingProxy] by jettero

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (5)
As of 2024-04-19 23:50 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found