0

I have a website that is supposed to post a report from time to time to a Yuku forum.

The code has been working for really a long time (5 years or more). Just recently, it stopped working.

Stops working as in.... no errors are reported, but the report isn't posted.

It looks like the forum's form page must have changed in some way that my submission is no longer valid.

The form that it is trying to fill in is this one:

http://webandofbrothers.yuku.com/forum/newtopic/id/2

... the form response from this URL (for a logged in user) is pasted here

The code that's doing the post is appended. It reports that it succeeds, but it doesn't - nothing happens (no post is made).

The request that it posts is this:

POST http://webandofbrothers.yuku.com/forum/post
Content-Length: 160
Content-Type: application/x-www-form-urlencoded

identity=2356541&posticon=0&title=IfYouSeeThisItsGood&sig_id=sig_id&topic=2&id=2&convert_urls=1&parse_smilies=1&cancel_url=%2Fforums%2F2&post=Post&body=blahblah

as reported by

 print $cgi->pre($request->as_string);

This seems to compare well with what Chrome "inspect element" says is submitted when I submit the form manually:

identity=2356541&posticon=0&title=More+testing%2C+nothing+to+see+here&body=More+testing&sig_id=sig_id&convert_urls=1&parse_smilies=1&topic=2&id=2&cancel_url=%2Fforums%2F2&post=Post

I can't see either what could be making the form unhappy about the submission, nor why it reports as "no error".

Note that the user agent definitely succeeds logging in (as far as all tests I've done show), and the logged in user can definitely post (permissions-wise) - I've tested that manually.

What I have found, by printing the response even if it's not supposedly an error, is that the response contains this:

HTTP/1.1 200 OK
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection: close
Date: Tue, 14 Apr 2015 13:06:12 GMT
Pragma: no-cache
Server: Apache
Vary: Accept-Encoding
Content-Length: 32
Content-Type: text/html; charset=UTF-8
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Client-Date: Tue, 14 Apr 2015 13:06:11 GMT
Client-Peer: 209.132.196.103:80
Client-Response-Num: 1
Set-Cookie: crwg_rsid=1045; path=/;

forum.php: failed to insert lead

So for some reason my POST sent by perl is not the same as the manual form POSTing, but I can't figure out why...

    my $ua = LWP::UserAgent->new;


    $ua->cookie_jar({ file => "./.cookies.txt" });

    my $loggedIn = LogInToEZBoard($ua);

    if (!$loggedIn)
    {
        print $cgi->p("URK ... looks like I couldn't log into Yuku to post your AAR");
        return;
    }

    # post the message

    # This is the AAR forum POST URL:
    my $formAddTopicURL = 'http://webandofbrothers.yuku.com/forum/post';

    # First we have to ask for a new topic page, so we can grok our yuku "identity"
    # ... so let's find that...

    my $response;

    $response = $ua->get("http://webandofbrothers.yuku.com/forum/newtopic/id/2");

    # Now we will parse this response to find the idenity...

    # first, here is the parser...

    my $p = HTML::Parser->new(api_version => 3,
                              marked_sections => 1,
        );

    # and here is the variable where we will place the final answer we're looking for...
    my $yukuIdentity = 0;

    # Now, set up a start tag handler that will extract the final value that we're looking for
    # from an option tag ... this handler will be installed when we're in the correct select tag...
    # When this anonymous routine is called, during $p->parse (below)
    # closure ensures that  $yukuIdentityRef will be pointing at the right place to let us update
    # $yukuIdentity and bail out from parsing

    my $yukuIdentityRef = \$yukuIdentity;

    my $extractIdentity = sub
    {
        my ($tag, $attrs, $self) = @_;
        if (($tag eq "option") &&
            ($attrs->{'value'}))
        {
            print $cgi->pre("Got identity $attrs->{'value'}");
            $$yukuIdentityRef = $attrs->{'value'};
            $self->eof();
        }
        else
        {
            print $cgi-pre("not what we're looking for $tag " . keys(%$attrs));
        }
    };

    # Now here is a start tag handler to find the correct select tag...
    # ... if we hit the identity select tag then we go looking for the identity.
    my $findIdentitySelect = sub
    {
        my ($tag, $attrs, $self) = @_;
        if (($tag eq "select") &&
            ($attrs->{'name'}) &&
            ($attrs->{'name'} eq 'identity'))
        {
            print $cgi->pre("Now in identity select...");
            $self->handler(start => $extractIdentity, "tagname,attr,self");
        }
        else
        {
            print $cgi->pre("Not what we're looking for: $tag");
        }
    };

    # Now we have handlers, load them up and away we go...

    $p->handler(start => $findIdentitySelect, 'tagname,attr,self');

    $p->parse($response->content);

    # tada.  By the time we get here, $yukuIdentity ought to be set!

    if (!$yukuIdentity)
    {
        die "Hmmm - bit of a problem, wasn't able to understand Yuku's post form.  Better let GaJ know...\n";
    }

    print $cgi->pre("Ok, my ID is $yukuIdentity, sending request...");

    # So at last we can post our AAR...


my $request = POST $formAddTopicURL,
    [identity => $yukuIdentity,
     posticon => '0',#,$postIcon, # 7 = smile
     title => "IfYouSeeThisItsGood", #"$gameType $update: $axisPlayer vs $alliedPlayer in $scenarioName",
     sig_id => 'sig_id',
     topic => '2',
     id => '2',
     convert_urls => '1',
     parse_smilies => '1',
     cancel_url => '/forums/2',
     post => "Post",
     body => $aarBody];


print $cgi->pre($request->as_string);

eval
{
    $response = $ua->request($request);
};

if ($@)
{
    print $cgi->p("Oh-oh: something went wrong sending the request to post the AAR to yuku....");
    print $cgi->pre($@);
}
else
{
    if (!$response->is_error)
    {
        print $cgi->p("...looks like it posted OK... the response was:");
    }
    else
    {
        print $cgi->p("Oh no - yuku didn't like the post requset I sent.  It said:");
    }
    print $cgi->pre($response->status_line);

    print $cgi->pre($response->as_string);

} 
GreenAsJade
  • 14,459
  • 11
  • 63
  • 98
  • 1
    The link to the form serves up a login form. That's probably not the one you mean to fill? Perhaps you could paste the form code (to a pastebin)? – Oldskool Apr 14 '15 at 09:32
  • I did post a pastie of the form code, in this link "... that it responds with is (http://pastie.org/1009143)[here]". – GreenAsJade Apr 14 '15 at 11:59

1 Answers1

1

All you say about the symptoms is " Just recently, it stopped working" and " It reports that it succeeds, but it doesn't". Problem descriptions like that are surprisingly common but, as I hope you can imagine, of no use at all as a aid to solving the problem.

What actually is happening? Is the message simply not being sent? What led you to believe that the problem is in this Perl code?

Without the working system to test with it is very difficult to say anything useful, but I have compared the HTTP POST message with the actual fields in the HTML and they don't match too well

  • The Perl code is sending values for bbcode and tabs which don't exist as inputs in the HTML form

  • The form has inputs cancel, convert_urls, parse_smilies, preview, rpx_share, stay_in_topic, and subscribe which aren't being sent by the software

Most HTML form handlers are fairly robust, and will simply use default values for missing inputs and ignore extraneous values. But I can believe that, amongst so many differences, there is one that is upsetting the site software enough to prevent the message from being sent

Borodin
  • 126,100
  • 9
  • 70
  • 144
  • Sorry about the poor description. I have elucidated: basically, the code doesn't detect any errors, but a post is not made. Thanks for pointing out the difference between the form and the HTML: very helpful, I'll fix that up and hope that does the trick! – GreenAsJade Apr 14 '15 at 12:02
  • I've tidied up the perl code to submit values for all the inputs you mentioned, with the exception of 'cancel' and 'preview' ... these are buttons, like 'post' ... I don't think I have to supply values for them - is that right? (It just occurred to me that I might be inadvertently supplying a 'cancel' response - how would I avoid that!?). Any clues about what values should be provided for checkboxes - is it either 0 or 1, or empty or 1, or something else? Thanks again! – GreenAsJade Apr 14 '15 at 12:36
  • I found out [how to see what the form is submitting](http://stackoverflow.com/questions/15603561/how-can-i-debug-a-http-post-in-chrome), and updated the code to match this. It still doesn't work though. It occured to me to print the response to the submission. I get "200 OK" but a body text that says "formum.php: failed to submit lead". Given that all my post parameters now match, what else could be causing the forum to see my post differently to a manual one? – GreenAsJade Apr 14 '15 at 13:02
  • Sorry for the multiple responses - I have updated the question with all the good new information I found since you set me off in a useful direction. – GreenAsJade Apr 14 '15 at 13:19