in reply to Rest::Client Headers not getting through

Hi Random Walk, try to separate urlpath from POST params in the POST() call.

The manpage says:

POST ( $url, [$body_content, %$headers] )

[] meaning optional

I suggest you do something like this and see how it goes (untested):

my $client = REST::Client->new(); $client->setHost($wiki); ... # got token # preparing a request: $request = "action=edit&title=LookupAutomationTest&summary=test%20summ +ary&text=article%20content"; $request .= '&format=json'; $request .= "&token=$token"; $client->POST($api, $request); # << separate path (e.g. "/mediawiki/ap +i.php") from the request-params e.g. the ? part which is now in strin +g $request.

'token' must be the last item in the params list according to the MediaWiki.

there is a pass in your code!

Replies are listed 'Best First'.
Re^2: Rest::Client Headers not getting through
by Random_Walk (Prior) on May 18, 2018 at 22:14 UTC

    Hi bliako,
    Thanks for taking the time to answer me. I tried your suggestion splitting the host and API path from the request and I also put the '&format=json' into each request string before calling post, so the "&token=$token" is then put last in the edit request.

    I'm afraid the result is a step back. Now I get an API help page in HTML from the first post. This I get at the first log attempt to get the token, which worked fine before. I updated the post sub like this

    sub post { my $query = shift @_; # my $req = "$api?$query"; # This removed print "Fetching data with: POST $api $query\n" if $debug; print Dumper $client; $client->POST($api, $query); if ( $client->responseCode() == 200 ) { print "Got Data OK, decoding ... " if $debug; print Dumper $client->responseContent() ; my $data = $JSON->decode( $client->responseContent() ); print Dumper $data; return $data; } else { print "Failed with code $client->responseCode()\n"; print Dumper $client->responseContent(); } }
    If Is switch this line:
    $client->POST($api, $query);
    To This
    $client->POST("$api?$query");
    Then I get back to where I was before. I get the Token, but can't get wiki to accept it for the edit

    Cheers,
    R.

    Pereant, qui ante nos nostra dixerunt!

      Hi Random Walk,

      The API you are using is pretty clear about this:

      The token parameter was found in the query
      string, but must be in the POST body

      .

      So, the token must go to the body. Which is by using POST($api, $body_content);

      I would add also the header "Content-type", "application/x-www-form-urlencoded" to become this:

      POST($api, "...token=the_token". {"Content-type" => "application/x-www +-form-urlencoded"});

      Now the above is for whenever you are making a request involving a token. The 1st param is the api path, the 2nd param is the post-body as a query string (you can use $client->buildQuery([a=>$a,b=>$b...]) for this) and the 3rd param is a hashref of headers.

      If the login phase worked somehow differently, then keep using that method and ... end up having two different post() - what can I say?

      Let me know if there is a public url to test this from my side.

        Hi bliako,

        Update

        Please ignore the original version of this node. It is left there for completeness. In my haste I missed the part about adding: {'Content-type' => 'application/x-www-form-urlencoded'} to my REST call. I did and now things have moved along. Now I get all JSON results back, and the attempt to edit gives this error:
        'error' => { 'code' => 'badtoken', '*' => 'See http://somehost.got.internal.net/mediawiki/api.php f +or API usage', 'info' => 'Invalid token' }
        I'm sure I can work that out in a couple of minutes.

        Thanks a million for you time.
        R.
        Original Node
        thanks for taking your time on this. I see what you mean about the docco saying to put the query in the POST body and it makes sense. Something I am doing is still wrong though. I have added a print to show what the is being sent, and I have the URI and body split. Here is the post sub as is now

        sub post { my $query = shift @_; print Dumper $client; $client->POST($api, $query); print "\$client->POST($api, $query)\n"; if ( $client->responseCode() == 200 ) { print "Got Data OK, decoding ... " if $debug; print Dumper $client->responseContent() ; my $data = $JSON->decode( $client->responseContent() ); print Dumper $data; return $data; } else { print "Failed with code $client->responseCode()\n"; print Dumper $client->responseContent(); } }
        And here is the output, skip past the dump of the client to see that I am invoking:

        $client->POST(/mediawiki/api.php, action=login&lgname=Marvin&lgpassword=diode&format=json)
        random@gotsvl1140:~> ./LookupsToWiki.pl $VAR1 = bless( { '_config' => { 'host' => 'http://somehost.got.internal.net', 'useragent' => bless( { 'proxy' => {}, 'timeout' => 180, 'ssl_opts' => { 'verify_hostname' => 1 }, 'handlers' => { 'response_header' => bless( [ { 'owner' => 'LWP::UserAgent::parse_he +ad', 'callback' => sub { "DUMMY" }, 'm_media_type' => 'html', 'line' => '/usr/lib/perl5/vendor_per +l/5.18.2/LWP/UserAgent.pm:683' } ], 'HTTP::Config' ) }, 'protocols_forbidden' => undef, 'max_redirect' => 7, 'use_eval' => 1, 'max_size' => undef, 'show_progress' => undef, 'local_address' => undef, 'def_headers' => bless( { 'user-agent' => 'REST::Client/273' }, 'HTTP::Headers' ), 'no_proxy' => [], 'protocols_allowed' => undef, 'requests_redirectable' => [ 'GET', 'HEAD' ] }, 'LWP::UserAgent' ) } }, 'REST::Client' ); $client->POST(/mediawiki/api.php, action=login&lgname=Marvin&lgpasswor +d=volvo123&format=json) $VAR1 = '<!DOCTYPE html> <html lang="en" dir="ltr" class="client-nojs"> <head> <meta charset="UTF-8"/> <title>MediaWiki API help - Monitoring Services</title> <script>document.documentElement.className = document.documentElement. +className.replace( /(^|\\s)client-nojs(\\s|$)/, "$1client-js$2" );</s +cript> ","wgRelevantArticleId":0,"wgRequestId":"WwLj2gr-QFMAAE7vrZwAAAAF","wg +IsProbablyEditable":false,"wgVisualEditor":... Plenty more html here +...
        there is a Sandbox here: https://www.mediawiki.org/wiki/Special:ApiSandbox Medi Wiki Sandbox but as its a web interface, I am not sure if you can hit it with Perl. I got some kids to feed now. I will log back in in a couple of hours and see if I can progress.

        Cheers,
        R.

        Pereant, qui ante nos nostra dixerunt!