File: localserver.pm

package info (click to toggle)
libcpan-mini-inject-perl 1.012-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 352 kB
  • sloc: perl: 732; makefile: 4
file content (69 lines) | stat: -rw-r--r-- 1,591 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
use Test::More;
BEGIN {
my @needs = grep { ! eval "require $_; 1" } qw(HTTP::Daemon Net::EmptyPort);

if( @needs ) {
	plan 'skip_all' => "Local::localversion needs " . join ' and ', @needs;
	}
}

use File::Spec::Functions qw(catfile);
use HTTP::Response;
use Net::EmptyPort;

sub start_server {
	my( $port ) = @_;

	my $child_pid = fork;

	return $child_pid unless $child_pid == 0;

	require HTTP::Daemon;
	require HTTP::Date;
	require HTTP::Status;

	my $d = HTTP::Daemon->new( LocalPort => $port ) or exit;
	CONNECTION: while (my $c = $d->accept) {
		REQUEST: while (my $r = $c->get_request) {
			my $file = (split m|/|, $r->uri->path)[-1] // 'index.html';
			my $path = catfile 't', 'html', $file;

			if ($r->method eq 'GET') {
				if( -e $path ) {
					$c->send_file_response( catfile 't', 'html', $file);
					}
				elsif( $path eq 'shutdown' ) {
					$c->close; undef $c;
					last CONNECTION;
					}
				else {
					$c->send_error(HTTP::Status::RC_NOT_FOUND())
					}
				}
			elsif ($r->method eq 'HEAD') { # update_mirror does this
				if( -e $path ) {
					my $res = HTTP::Response->new;
					$res->code(200);
					$res->content('');
					$res->header('Last-Modified'  => HTTP::Date::time2str( (stat $path)[9] )),
					$res->header('Content-Length' => (-s $path));
					$c->send_response($res);
					}
				else {
					$c->send_error(HTTP::Status::RC_NOT_FOUND())
					}
				}
			else {
				$c->send_error(HTTP::Status::RC_FORBIDDEN())
				}
			}
		$c->close;
		undef($c);
		}

	exit;
	}

sub can_fetch { require LWP::UserAgent; LWP::UserAgent->new->get( shift )->is_success }

1;