summaryrefslogtreecommitdiff
path: root/tests/ftpmasterapi-static-server
blob: cedc6f7cc580f93ba8197a2530bc691551f1a3de (plain)
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#!/usr/bin/perl -w
#
# This file is part of the dgit test suite.
#
# Copyright (C)2004-2015 Best Practical Solutions, LLC
# Copyright (C)2019      Ian Jackson
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
#
# invocation protocol:
#
#   ftpmasterapi-static-server >port-file tests/tmp/$thing/aq
#
# Will write the allocated port number to port-file.
# Then we fork and the parent exits 0.
# If port-file is unlinked, we exit.

use strict;
use IO::Handle;

our ($webroot) = @ARGV;
our $port = '';

sub stat_type_check () {
    die "[$port, $webroot] stdout not ta plain file"
	unless -f _;
}

stat STDOUT or die $!;
stat_type_check();

sub start_polling_fstat () {
    $SIG{ALRM} = sub {
	stat STDOUT or die $!;
	my $nlink = (stat _)[3];
	exit 0 unless $nlink;
	stat_type_check(); # doesn't seem possible to fail but check anyway
	alarm(1);
    };
    alarm(1);
}

package ServerClass;

use strict;
use Socket qw(AF_INET SOCK_STREAM);
use Socket qw(AF_INET SOCK_STREAM unpack_sockaddr_in);
use IO::Handle;

use base qw(HTTP::Server::Simple::CGI);
use HTTP::Server::Simple::Static;

sub handle_request {
    my ($self, $cgi) = @_;

    if (!$self->serve_static($cgi, $::webroot)) {
	print "HTTP/1.0 404 Not found\r\n";
	print $cgi->header,
	    $cgi->start_html('Not found'),
	    $cgi->h1('Not found'),
	    $cgi->end_html;
    }
}

sub port () { return 0; }

sub after_setup_listener () {
    my $sn = getsockname HTTP::Server::Simple::HTTPDaemon or die $!;
    ($main::port,) = unpack_sockaddr_in $sn;
    print main::STDOUT $port, "\n" or die $!;
    flush main::STDOUT or die $!;
    my $c = fork // die $!;
    exit 0 if $c;
    ::main::start_polling_fstat();
}

package main;

our $server = ServerClass->new();
$server->run();