nysus has asked for the wisdom of the Perl Monks concerning the following question:
It turns out that I needed to throw in a blank line (\r\n) at the end of the GET request inside of the POST request. Now the question is, is this a mojolicious bug or not? Is the content inside of a multipart post request required to have a blank line after it?
I'm attempting to hack the Moo::Google module so it will support batch api requests to google (so instead of making 100 separate api calls, you can bundle them all together under a single call). Google's API has a "batch" request feature for this purpose, which is documented here. Moo::Google uses mojolicious to make the Google API calls. Here are the relevant portions of the code:
# keeping it simple with just one nested request. no improvement + with more added here. my $options = [ { content => 'GET /gmail/v1/users/real_address@gmail.com/m +essages/165eb111fcf21503', 'Content-type' => 'application/http', # internal serve +r error when set to 'application/json' }, ]; my $path = 'https://www.googleapis.com/batch/gmail/v1'; # this is the call to Moo Google's lower level api_query function. my $res = $s->_gapi->api_query( { httpMethod => 'POST', path => $path, options => $options, }); print Dumper $res; # then, over in Moo::Google we do some Mojolicious stuff with our api_ +query call # build the transactor (this function is in Moo::Google # $headers was created earlier and contains bearer token # $headers->{content-type} = 'mixed/multipart'; # tried this and +many other content types with no improvement my $tx = $self->ua->build_tx( uc $http_method =>$path => $headers => multipart => $options) +; my $res = $self->ua->start($tx)->res; return $res;
$VAR1 = bless( { 'req' => bless( { 'method' => 'POST', 'url' => bless( { 'scheme' => 'http +s', 'host' => 'www.go +ogleapis.com', 'path' => bless( +{ + 'path' => '/batch/gmail/v1' +}, 'Mojo::Path' ) }, 'Mojo::URL' ), 'content' => bless( { 'events' => { + 'read' => [ + sub { "DUMMY" } + ] } +, 'headers' => +bless( { + 'headers' => { + 'accept-encoding' => [ + 'gzip' + ], + 'authorization' => [ + 'Bearer REAL_TOKEN_GOES_ +HERE' + ], + 'user-agent' => [ + 'Mojolicious (Perl)' + ] + } + }, 'Mojo::Headers' ), 'parts' => [ +bless( { + 'read' => sub { "DUMMY" }, + 'events' => { + 'read' => [ + $VAR1->{'req'}{'content'}{'parts'} +[0]{'read'} + ] + }, + 'asset' => bless( { + 'content' => 'GET /gmail/v1/users/real_e +mail@gmail.com/messages/165eb111fcf21503' + }, 'Mojo::Asset::Memory' ), + 'headers' => bless( { + 'headers' => { + 'content-type' => [ + 'ap +plication/http' + ] + } + }, 'Mojo::Headers' ) + }, 'Mojo::Content::Single' ) ] }, 'Mojo::Conte +nt::MultiPart' ) }, 'Mojo::Message::Request' ) }, 'Mojo::Transaction::HTTP' );
$VAR1 = bless( { 'error' => { 'code' => '400', 'message' => 'Bad Request' }, 'events' => {}, 'finished' => 3, 'message' => 'Bad Request', 'code' => '400', 'state' => 'finished', 'version' => '1.1', 'raw_size' => 757, 'max_line_size' => 8192, 'content' => bless( { 'relaxed' => 1, 'chunk_state' => 'finished', 'post_buffer' => '', 'max_buffer_size' => 262144, 'raw_size' => 731, 'auto_decompress' => 1, 'state' => 'finished', 'header_size' => 365, 'chunk_len' => 0, 'gz' => bless( do{\(my $o = '14 +0714715991136')}, 'Compress::Raw::Zlib::inflateStream' ), 'body' => 6, 'events' => { 'read' => [ sub { + "DUMMY" } ] }, 'size' => 119, 'real_size' => 119, 'auto_relax' => 1, 'read' => $VAR1->{'content'}{'e +vents'}{'read'}[0], 'headers' => bless( { 'headers' + => { + 'date' => [ + 'Tue, 18 Sep 2018 15:04:56 GMT' + ], + 'x-xss-protection' => [ + '1; mode=block' + ], + 'x-frame-options' => [ + 'SAMEORIGIN' + ], + 'content-length' => [ + 145 + ], + 'content-type' => [ + 'text/html; charset=UTF-8' + ], + 'server' => [ + 'GSE' + ], + 'x-content-type-options' => [ + 'nosniff' + ], + 'alt-svc' => [ + 'quic=":443"; ma=2592000; v="44,43,39,35"' + ], + 'cache-control' => [ + 'private, max-age=0' + ], + 'expires' => [ + 'Tue, 18 Sep 2018 15:04:56 GMT' + ] + }, 'max_line +s' => 100, 'max_line +_size' => 8192, 'state' = +> 'finished', 'names' = +> { + 'x-xss-protection' => 'X-XSS-Protection', + 'alt-svc' => 'Alt-Svc', + 'x-frame-options' => 'X-Frame-Options', + 'x-content-type-options' => 'X-Content-Type-Options' + }, 'cache' = +> [] }, 'Mojo::H +eaders' ), 'asset' => bless( { 'content' = +> '<HTML> <HEAD> <TITLE>Bad Request</TITLE> </HEAD> <BODY BGCOLOR="#FFFFFF" TEXT="#000000"> <H1>Bad Request</H1> <H2>Error 400</H2> </BODY> </HTML> ', 'auto_upgra +de' => 1, 'max_memory +_size' => 262144 }, 'Mojo::Ass +et::Memory' ), 'auto_upgrade' => 1, 'buffer' => '' }, 'Mojo::Content::Single' ), 'max_message_size' => 2147483648 }, 'Mojo::Message::Response' );
I've been working on this for hours so any help is greatly appreciated.
I was able to figure out how to print out the actual HTTP request sent to Google:
POST /batch/gmail/v1 HTTP/1.1^M Accept-Encoding: gzip^M Host: www.googleapis.com^M User-Agent: Mojolicious (Perl)^M Content-Length: 120^M Content-Type: multipart/mixed; boundary=WHeuX^M Authorization: Bearer REAL_TOKEN^M ^M --WHeuX^M Content-Type: application/http^M ^M GET /gmail/v1/users/my_real_email@gmail.com/messages/165eb111fcf21503^ +M --WHeuX--^M
Anything look wrong with that?
$PM = "Perl Monk's";
$MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate Priest";
$nysus = $PM . ' ' . $MCF;
Click here if you love Perl Monks
|
|---|