xref: /openbsd/gnu/usr.bin/perl/cpan/HTTP-Tiny/t/Util.pm (revision eac174f2)
19f11ffb7Safresh1package Util;
2898184e3Ssthen
3898184e3Ssthenuse strict;
4898184e3Ssthenuse warnings;
5898184e3Ssthen
6898184e3Ssthenuse IO::File qw(SEEK_SET SEEK_END);
7898184e3Ssthenuse IO::Dir;
8898184e3Ssthen
9898184e3SsthenBEGIN {
10898184e3Ssthen    our @EXPORT_OK = qw(
11898184e3Ssthen        rewind
12898184e3Ssthen        tmpfile
13898184e3Ssthen        dir_list
14898184e3Ssthen        slurp
15898184e3Ssthen        parse_case
16898184e3Ssthen        hashify
17898184e3Ssthen        sort_headers
18898184e3Ssthen        connect_args
19898184e3Ssthen        clear_socket_source
20898184e3Ssthen        set_socket_source
21898184e3Ssthen        monkey_patch
22898184e3Ssthen        $CRLF
23898184e3Ssthen        $LF
24898184e3Ssthen    );
25898184e3Ssthen
26898184e3Ssthen    require Exporter;
27898184e3Ssthen    *import = \&Exporter::import;
28898184e3Ssthen}
29898184e3Ssthen
30898184e3Ssthenour $CRLF = "\x0D\x0A";
31898184e3Ssthenour $LF   = "\x0A";
32898184e3Ssthen
33898184e3Ssthensub rewind(*) {
34898184e3Ssthen    seek($_[0], 0, SEEK_SET)
35898184e3Ssthen      || die(qq/Couldn't rewind file handle: '$!'/);
36898184e3Ssthen}
37898184e3Ssthen
38898184e3Ssthensub tmpfile {
39898184e3Ssthen    my $fh = IO::File->new_tmpfile
40898184e3Ssthen      || die(qq/Couldn't create a new temporary file: '$!'/);
41898184e3Ssthen
42898184e3Ssthen    binmode($fh)
43898184e3Ssthen      || die(qq/Couldn't binmode temporary file handle: '$!'/);
44898184e3Ssthen
45898184e3Ssthen    if (@_) {
46898184e3Ssthen        print({$fh} @_)
47898184e3Ssthen          || die(qq/Couldn't write to temporary file handle: '$!'/);
48898184e3Ssthen
49898184e3Ssthen        seek($fh, 0, SEEK_SET)
50898184e3Ssthen          || die(qq/Couldn't rewind temporary file handle: '$!'/);
51898184e3Ssthen    }
52898184e3Ssthen
53898184e3Ssthen    return $fh;
54898184e3Ssthen}
55898184e3Ssthen
56898184e3Ssthensub dir_list {
57898184e3Ssthen    my ($dir, $filter) = @_;
58898184e3Ssthen    $filter ||= qr/./;
59898184e3Ssthen    my $d = IO::Dir->new($dir)
60898184e3Ssthen        or return;
61898184e3Ssthen    return map { "$dir/$_" } sort grep { /$filter/ } grep { /^[^.]/ } $d->read;
62898184e3Ssthen}
63898184e3Ssthen
64898184e3Ssthensub slurp (*) {
65898184e3Ssthen    my ($fh) = @_;
66898184e3Ssthen
67898184e3Ssthen    seek($fh, 0, SEEK_END)
68898184e3Ssthen      || die(qq/Couldn't navigate to EOF on file handle: '$!'/);
69898184e3Ssthen
70898184e3Ssthen    my $exp = tell($fh);
71898184e3Ssthen
72898184e3Ssthen    rewind($fh);
73898184e3Ssthen
74898184e3Ssthen    binmode($fh)
75898184e3Ssthen      || die(qq/Couldn't binmode file handle: '$!'/);
76898184e3Ssthen
77898184e3Ssthen    my $buf = do { local $/; <$fh> };
78898184e3Ssthen    my $got = length $buf;
79898184e3Ssthen
80898184e3Ssthen    ($exp == $got)
81898184e3Ssthen      || die(qq[I/O read mismatch (expexted: $exp got: $got)]);
82898184e3Ssthen
83898184e3Ssthen    return $buf;
84898184e3Ssthen}
85898184e3Ssthen
86898184e3Ssthensub parse_case {
87898184e3Ssthen    my ($case) = @_;
88898184e3Ssthen    my %args;
89898184e3Ssthen    my $key = '';
90*eac174f2Safresh1    my %seen;
91898184e3Ssthen    for my $line ( split "\n", $case ) {
92898184e3Ssthen        chomp $line;
93898184e3Ssthen        if ( substr($line,0,1) eq q{ } ) {
94898184e3Ssthen            $line =~ s/^\s+//;
95898184e3Ssthen            push @{$args{$key}}, $line;
96898184e3Ssthen        }
97898184e3Ssthen        else {
98898184e3Ssthen            $key = $line;
99*eac174f2Safresh1            $seen{$key}++;
100898184e3Ssthen        }
101898184e3Ssthen    }
102*eac174f2Safresh1    for my $k (keys %seen) {
103*eac174f2Safresh1        $args{$k}=undef unless exists $args{$k};
104*eac174f2Safresh1    }
105898184e3Ssthen    return \%args;
106898184e3Ssthen}
107898184e3Ssthen
108898184e3Ssthensub hashify {
109898184e3Ssthen    my ($lines) = @_;
110898184e3Ssthen    return unless $lines;
111898184e3Ssthen    my %hash;
112898184e3Ssthen    for my $line ( @$lines ) {
113898184e3Ssthen        my ($k,$v) = ($line =~ m{^([^:]+): (.*)$}g);
114898184e3Ssthen        $hash{$k} = [ $hash{$k} ] if exists $hash{$k} && ref $hash{$k} ne 'ARRAY';
115898184e3Ssthen        if ( ref($hash{$k}) eq 'ARRAY' ) {
116898184e3Ssthen            push @{$hash{$k}}, $v;
117898184e3Ssthen        }
118898184e3Ssthen        else {
119898184e3Ssthen            $hash{$k} = $v;
120898184e3Ssthen        }
121898184e3Ssthen    }
122898184e3Ssthen    return %hash;
123898184e3Ssthen}
124898184e3Ssthen
125898184e3Ssthensub sort_headers {
126898184e3Ssthen    my ($text) = shift;
127898184e3Ssthen    my @lines = split /$CRLF/, $text;
128898184e3Ssthen    my $request = shift(@lines) || '';
129898184e3Ssthen    my @headers;
130898184e3Ssthen    while (my $line = shift @lines) {
131898184e3Ssthen        last unless length $line;
132898184e3Ssthen        push @headers, $line;
133898184e3Ssthen    }
134898184e3Ssthen    @headers = sort @headers;
135898184e3Ssthen    return join($CRLF, $request, @headers, '', @lines);
136898184e3Ssthen}
137898184e3Ssthen
138898184e3Ssthen{
139898184e3Ssthen    my (@req_fh, @res_fh, $monkey_host, $monkey_port);
140898184e3Ssthen
141898184e3Ssthen    sub clear_socket_source {
142898184e3Ssthen        @req_fh = ();
143898184e3Ssthen        @res_fh = ();
144898184e3Ssthen    }
145898184e3Ssthen
146898184e3Ssthen    sub set_socket_source {
147898184e3Ssthen        my ($req_fh, $res_fh) = @_;
148898184e3Ssthen        push @req_fh, $req_fh;
149898184e3Ssthen        push @res_fh, $res_fh;
150898184e3Ssthen    }
151898184e3Ssthen
152898184e3Ssthen    sub connect_args { return ($monkey_host, $monkey_port) }
153898184e3Ssthen
154898184e3Ssthen    sub monkey_patch {
155898184e3Ssthen        no warnings qw/redefine once/;
156898184e3Ssthen        *HTTP::Tiny::Handle::can_read = sub {1};
157898184e3Ssthen        *HTTP::Tiny::Handle::can_write = sub {1};
158898184e3Ssthen        *HTTP::Tiny::Handle::connect = sub {
1599f11ffb7Safresh1            my ($self, $scheme, $host, $port, $peer) = @_;
160898184e3Ssthen            $self->{host}   = $monkey_host = $host;
161898184e3Ssthen            $self->{port}   = $monkey_port = $port;
1629f11ffb7Safresh1            $self->{peer}   = $peer;
1636fb12b70Safresh1            $self->{scheme} = $scheme;
164898184e3Ssthen            $self->{fh} = shift @req_fh;
165b8851fccSafresh1            $self->{pid} = $$;
166b8851fccSafresh1            $self->{tid} = HTTP::Tiny::Handle::_get_tid();
167898184e3Ssthen            return $self;
168898184e3Ssthen        };
169898184e3Ssthen        my $original_write_request = \&HTTP::Tiny::Handle::write_request;
170898184e3Ssthen        *HTTP::Tiny::Handle::write_request = sub {
171898184e3Ssthen            my ($self, $request) = @_;
172898184e3Ssthen            $original_write_request->($self, $request);
173898184e3Ssthen            $self->{fh} = shift @res_fh;
174898184e3Ssthen        };
175898184e3Ssthen        *HTTP::Tiny::Handle::close = sub { 1 }; # don't close our temps
176*eac174f2Safresh1        *HTTP::Tiny::Handle::connected = sub { 1 };
177898184e3Ssthen
1786fb12b70Safresh1        # don't try to proxy in mock-mode
179b8851fccSafresh1        delete $ENV{$_} for map { $_, uc($_) } qw/http_proxy https_proxy all_proxy/;
180898184e3Ssthen    }
181898184e3Ssthen}
182898184e3Ssthen
183898184e3Ssthen1;
184898184e3Ssthen
185898184e3Ssthen
186898184e3Ssthen# vim: et ts=4 sts=4 sw=4:
187