File Coverage

blib/lib/HTTP/Request/FromFetch.pm
Criterion Covered Total %
statement 53 54 98.1
branch 4 6 66.6
condition 12 15 80.0
subroutine 11 11 100.0
pod 0 1 0.0
total 80 87 91.9


line stmt bran cond sub pod time code
1             package HTTP::Request::FromFetch;
2 1     1   50631 use strict;
  1         23  
  1         29  
3 1     1   5 use warnings;
  1         1  
  1         23  
4 1     1   7 use Filter::signatures;
  1         2  
  1         5  
5 1     1   23 use feature 'signatures';
  1         2  
  1         60  
6 1     1   5 no warnings 'experimental::signatures';
  1         2  
  1         39  
7 1     1   5 use Carp 'croak';
  1         2  
  1         43  
8 1     1   774 use JSON;
  1         10522  
  1         5  
9 1     1   513 use PerlX::Maybe;
  1         2119  
  1         5  
10 1     1   500 use HTTP::Request::CurlParameters;
  1         5  
  1         221  
11              
12             our $VERSION = '0.50';
13              
14             =head1 NAME
15              
16             HTTP::Request::FromFetch - turn a Javascript fetch() statement into HTTP::Request
17              
18             =head1 SYNOPSIS
19              
20             my $ua = LWP::UserAgent->new();
21             my $req = HTTP::Request::FromFetch->new(<<'JS')->as_request;
22              
23             await fetch("https://www.example.com/index.html", {
24             "credentials": "include",
25             "headers": {
26             "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:74.0) Gecko/20100101 Firefox/74.0",
27             "Accept": "text/javascript, text/html, application/xml, text/xml, */*",
28             "Accept-Language": "de,en-US;q=0.7,en;q=0.3",
29             "X-CSRF-Token": "secret",
30             "X-Requested-With": "XMLHttpRequest"
31             },
32             "referrer": "https://www.example.com/",
33             "method": "GET",
34             "mode": "cors"
35             });
36              
37             JS
38             $ua->request( $req );
39              
40             =head1 DESCRIPTION
41              
42             This module parses a call to the L
43             and returns an object that you can turn into a L to use
44             with L or other user agents to perform a largely identical
45             HTTP request.
46              
47             The parsing of the Javascript stanza is done through a regular expression, so
48             the test must largely follow the pattern shown in the synopsis. Usually, the
49             C stanzas come from a browsers "Copy as fetch" context menu, so there
50             is no problem parsing these.
51              
52             This is mostly a factory class for L objects.
53              
54             =cut
55              
56 5     5 0 322936 sub new( $class, $fetch, @rest ) {
  5         18  
  5         14  
  5         11  
  5         10  
57 5         13 my %options;
58              
59 5 50       42 if( @rest ) {
60 0         0 %options = ($fetch, @rest);
61             } else {
62 5         47 $options{ fetch } = $fetch;
63             };
64              
65 5         28 $fetch = delete $options{ fetch };
66              
67 5 50       120 $fetch =~ m!\A\s*(await\s+)?
68             fetch\s*\(\s*"(?(?:[^[\\"]+|\\.)+)"\s*(?:,\s*
69             (?\{.*\}))?\s*
70             \)\s*;?
71             \s*\z!msx
72             or croak "Couldn't parse fetch string '$fetch'";
73              
74 5         26 my $options;
75 1     1   500 my $o = $+{options};
  1         355  
  1         214  
  5         96  
76 5         35 my $u = $+{uri};
77 5 100 66     83 if( defined $o and $o =~ /\S/ ) {
78 3         86 $options = decode_json($o);
79             } else {
80 2         6 $options = {};
81             };
82              
83 5         38 $options->{uri} = $u;
84 5   100     51 $options->{method} ||= 'GET';
85 5   100     87 $options->{mode} ||= 'cors';
86 5   50     102 $options->{cache} ||= 'default';
87 5   100     59 $options->{credentials} ||= 'same-origin';
88 5   100     59 $options->{headers} ||= {};
89              
90              
91             HTTP::Request::CurlParameters->new({
92             method => delete $options->{method} || 'GET',
93             uri => $options->{uri},
94             headers => $options->{headers},
95             maybe body => $options->{body},
96             #maybe credentials => $options->{ user },
97 5   50     471 });
98             }
99              
100             1;
101              
102             =head1 SEE ALSO
103              
104             L
105              
106             =head1 REPOSITORY
107              
108             The public repository of this module is
109             L.
110              
111             =head1 SUPPORT
112              
113             The public support forum of this module is
114             L.
115              
116             =head1 BUG TRACKER
117              
118             Please report bugs in this module via the RT CPAN bug queue at
119             L
120             or via mail to L.
121              
122             =head1 AUTHOR
123              
124             Max Maischein C
125              
126             =head1 COPYRIGHT (c)
127              
128             Copyright 2018 by Max Maischein C.
129              
130             =head1 LICENSE
131              
132             This module is released under the same terms as Perl itself.
133              
134             =cut