HTTP-AnyUA

 view release on metacpan or  search on metacpan

lib/HTTP/AnyUA/Util.pm  view on Meta::CPAN

        substr $host, 0, 1, '';          # knock the @ off the host

        # userinfo might be percent escaped, so recover real auth info
        $auth =~ s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg;
    }
    my $port = $host =~ s/:(\d*)\z// && length $1 ? $1
             : $scheme eq 'http'                  ? 80
             : $scheme eq 'https'                 ? 443
             : undef;

    return ($scheme, (length $host ? lc $host : "localhost") , $port, $path_query, $auth);
}


# Date conversions adapted from HTTP::Date
# adapted from HTTP/Tiny.pm
my $DoW = 'Sun|Mon|Tue|Wed|Thu|Fri|Sat';
my $MoY = 'Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec';
sub http_date {
    my $time = shift or _usage(q{http_date($time)});
    my ($sec, $min, $hour, $mday, $mon, $year, $wday) = gmtime($time);
    return sprintf('%s, %02d %s %04d %02d:%02d:%02d GMT',
        substr($DoW,$wday*4,3),
        $mday, substr($MoY,$mon*4,3), $year+1900,
        $hour, $min, $sec
    );
}


# adapted from HTTP/Tiny.pm
sub parse_http_date {
    my $str = shift or _usage(q{parse_http_date($str)});
    my @tl_parts;
    if ($str =~ /^[SMTWF][a-z]+, +(\d{1,2}) ($MoY) +(\d\d\d\d) +(\d\d):(\d\d):(\d\d) +GMT$/) {
        @tl_parts = ($6, $5, $4, $1, (index($MoY,$2)/4), $3);
    }
    elsif ($str =~ /^[SMTWF][a-z]+, +(\d\d)-($MoY)-(\d{2,4}) +(\d\d):(\d\d):(\d\d) +GMT$/ ) {
        @tl_parts = ($6, $5, $4, $1, (index($MoY,$2)/4), $3);
    }
    elsif ($str =~ /^[SMTWF][a-z]+ +($MoY) +(\d{1,2}) +(\d\d):(\d\d):(\d\d) +(?:[^0-9]+ +)?(\d\d\d\d)$/ ) {
        @tl_parts = ($5, $4, $3, $2, (index($MoY,$1)/4), $6);
    }
    require Time::Local;
    return eval {
        my $t = @tl_parts ? Time::Local::timegm(@tl_parts) : -1;
        $t < 0 ? undef : $t;
    };
}


# URI escaping adapted from URI::Escape
# c.f. http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.1
# perl 5.6 ready UTF-8 encoding adapted from JSON::PP
# adapted from HTTP/Tiny.pm
my %escapes = map { chr($_) => sprintf('%%%02X', $_) } 0..255;
$escapes{' '} = '+';
my $unsafe_char = qr/[^A-Za-z0-9\-\._~]/;

sub uri_escape {
    my $str = shift or _usage(q{uri_escape($str)});
    if ($] ge '5.008') {
        utf8::encode($str);
    }
    else {
        $str = pack('U*', unpack('C*', $str))   # UTF-8 encode a byte string
            if (length $str == do { use bytes; length $str });
        $str = pack('C*', unpack('C*', $str));  # clear UTF-8 flag
    }
    $str =~ s/($unsafe_char)/$escapes{$1}/ge;
    return $str;
}


# adapted from HTTP/Tiny.pm
sub www_form_urlencode {
    my $data = shift;
    ($data && ref $data)
        or _usage(q{www_form_urlencode($dataref)});
    (ref $data eq 'HASH' || ref $data eq 'ARRAY')
        or _croak("form data must be a hash or array reference\n");

    my @params = ref $data eq 'HASH' ? %$data : @$data;
    @params % 2 == 0
        or _croak("form data reference must have an even number of terms\n");

    my @terms;
    while (@params) {
        my ($key, $value) = splice(@params, 0, 2);
        if (ref $value eq 'ARRAY') {
            unshift @params, map { $key => $_ } @$value;
        }
        else {
            push @terms, join('=', map { uri_escape($_) } $key, $value);
        }
    }

    return join('&', ref($data) eq 'ARRAY' ? @terms : sort @terms);
}

1;

__END__

=pod

=encoding UTF-8

=head1 NAME

HTTP::AnyUA::Util - Utility subroutines for HTTP::AnyUA backends and middleware

=head1 VERSION

version 0.904

=head1 FUNCTIONS

=head2 coderef_content_to_string

    $content = coderef_content_to_string(\&code);
    $content = coderef_content_to_string($content);     # noop



( run in 1.734 second using v1.01-cache-2.11-cpan-a49fcb8fa48 )