Perl scrip with HTTP request returns bad gateway

Hi everyone!

I’m working on a Perl scrip to perform an action on a ticket and at some point I need to send an HTTP request to an external link (which is an Azure Logic App). However, when I do trigger the request I get a Bad Gateway error as response. Strangely, when I try to replace the url with a webhook.site url it works just fine.

How can I overcome this?
Any help is appreciated.

My code:

use HTTP::Request;
use JSON;
use LWP::UserAgent;

my $ua = LWP::UserAgent->new;
$ua->timeout(150);

my $id = $self->TicketObj->id;

my $to_post = '{"ticketid":'.$id.'}';

my $url = 'https://webhook.site/558eed96-5077-42a6-9937-6d0530a2e1b1';

my $req = HTTP::Request->new(POST => $url);
$req->header('content-type' => 'application/json');
$req->content($to_post);

my $resp = $ua->request($req);

if ($resp->is_success) {

    my $message = $resp->decoded_content;	
}
else {
    my $err = 'Error: '.$resp->code.' - '.$resp->message;
    $self->TicketObj->Comment(Content=>$err);
    }

Doesn’t that mean the response from the server you’re hitting is invalid?

Have you got a standalone script (with a ‘t’, as opposed to a Perl scrip) that works with the Azure URL? Might be worth getting that to work first, taking RT out of the loop. Do you need to authenticate against the Azure end point for example.

I’ve not used Azure Logic App at all, but I do talk to Microsoft Graph API from RT for calendar/event generation. I’ve found that the Microsoft cloud can be pretty flaky sometimes - you get Bad Gateway responses, timeouts, etc from a request which, if retried after a pause, may then work. This seems to happen in bursts, which I’m guessing means something comes gets overloaded or unhinged in MIcrosoft’s cloud and takes a while to be noticed & fixed. We had a few days of it a week or so ago and it’s now fine again, without us touching our local code in our RT at all. Chums I know who do Windows stuff get similar issues from Powershell provisioning of objects in Azure too.

Hi, thanks for the reply!
I actually forgot to mention it, but yes, the script works locally with the exact same code and url. This is what makes this even stranger.

Basically your guess is that it is just unreliable?

Maybe. The other option is that your web server/security is configured to somehow block out going network traffic from code being run in the web server (such as RT), but that wouldn’t explain how you could send it to the webhook.site URL OK.

If you compare the request being sent from your outside-of-RT script to the one sent from from your scrip, is there any difference? Maybe use Data::Dumper to dump the $req structure and compare them?

The code in the local script and the one in RT are exactly the same, basically a copy-paste. I tried what you suggested and the structures have the exact same content. The only difference is that the fields are printed in a different order in the two cases, but I doubt that is of any relevance. I will paste both outputs here anyways.

RT scrip $req structure:

$VAR1 = bless( {
‘_content’ => ‘{“ticketid”:93104}’,
‘_method’ => ‘POST’,
‘_headers’ => bless( {
‘content-type’ => ‘application/json’
}, ‘HTTP::Headers’ ),
‘_uri’ => bless( do{(my $o = ‘https://ticket-app.azurewebsites.net:443/api/xxx’)}, ‘URI::https’ )
}, ‘HTTP::Request’ );

Local script $req structure:

$VAR1 = bless( {
‘_uri’ => bless( do{(my $o = ‘https://ticket-app.azurewebsites.net:443/api/xxx’)}, ‘URI::https’ ),
‘_headers’ => bless( {
‘content-type’ => ‘application/json’
}, ‘HTTP::Headers’ ),
‘_content’ => ‘{“ticketid”:93092}’,
‘_method’ => ‘POST’
}, ‘HTTP::Request’ );

Hmm… OK, that discounts some odd header difference. Is there anything in the web server error log?

Also is SELinux installed/turned on? That can limit outgoing requests from scripts, but I’d guess you’d see a line in the audit log to say it was blocking them.

Hi GreenJimll, thanks a lot for your help.

In the meantime I found out where the error was. The logic app which is being called sends a request to the rt REST in order to retrieve information on the ticket which is being created, but since the code happens under the condition “On Create”, the ticket does not exist yet… so it fails.
It works on the local code because there I was providing a ticket id manually instead of fetching it upon creation.

This leads to my next problem, which would be how to make this work.
Ad mentioned, the logic app needs to fetch information on the ticket, but when it tries to do so, the ticket does not exist yet since creation was not completed. I know this is a different matter, so I should probably make a new topic about this. However, if you have any idea on how to work around this I would appreciate it a lot.

Ah, that’s because the scrip is being run from RT::Transaction associated with the RT::Ticket Create() method, and that is inside a big SQL transaction that isn’t committed to the database fully until after the RT::Transaction is finished.

Do you control the Azure logic app? If so, could you pass the information from the ticket in your initial call? Your scrip will have access to it because it is “inside” the SQL transaction. Alternatively have your scrip talk to something you run locally on your machine that sleeps for a few seconds, checks that the ticket exists and then calls the Azure logic app.

1 Like

I see, thanks a lot for the insight.

The optimal scenario would be if there is a way in rt to just call the logic app after the transaction is finished. I guess that’s not possible?

Alternatively, I will change the logic app and try to pass the information from the scrip, although that would render a lot of work already done useless since the app was meant to get only the ticket id :sweat_smile: