File Coverage

blib/lib/HTTP/Request/FromFetch.pm
Criterion Covered Total %
statement 43 44 97.7
branch 4 6 66.6
condition 12 15 80.0
subroutine 8 8 100.0
pod 0 1 0.0
total 67 74 90.5


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