500 SSL read timeout error in LWP perl - perl

I have a perl script which will post HTTP request to specified server URL (Say: http://some-ip/here_action_url ). My problem is, Sometimes I am getting the below error.
Error:
500 SSL read timeout.
Sample Code:
my $ua = new LWP::UserAgent;
$ua->timeout(30);
my $res = $ua->post( $url, { 'data' => $my_data } );
if(! $res->is_success ) {
# Error Logging
print $res->status_line."\n";
}
else {
$response_content = $res->content;
}
I read about the error. Most of the documents are saying that it is because of the response delay in server side.
I just want to confirm, whether this error is coming because of server response delay? (or) Can be the problem with my perl script?

If you get a result some of the time, and the error at other times, then it looks like your code is working.
If you alway get the 500 error, it indicates a connection problem. Would need to know more about the service you are trying to connect to, does it require certificates or other authentication (which may be needed for secure socket layer connection)

Related

Perl WWW::Mechanize for HTTPS over proxy

I am trying to scrape a website using WWW::Mechanize module. I have configured the mechanize agent with a proxy URL and setting the proxy credentials using credentials method.
Code snippet :
my $url = 'https://abcde.com';
my $proxy_username = 'abc';
my $proxy_password = 'xyz';
my $proxy_url = 'http://xx.xxx.xxx.xxx:13228';
my $mechanize_agent = new WWW::Mechanize('cookie_jar' => {}, 'noproxy' => 1, 'ssl_opts' => { 'verify_hostname' => 0 });
$mechanize_agent->credentials( $proxy_username, $proxy_password );
$mechanize_agent->proxy(['http', 'https'], $proxy_url);
$mechanize_agent->get($url) or die 'Error in get request of $url: $#';
When URL is a plain HTTP, the script fetches and gives back the result. But when I try to hit HTTPS url I get the error
establishing SSL tunnel failed: 407 Proxy Authentication Required
I credentials are valid and I can view the website using proxy URL in Mozilla browser. Also i need t avoid using call to env_proxy() function since the proxy URL is dynamic. How can I get let my script fetch HTTPS request?
All suggestions are welcome!
thanks in advance.

Connect perl script to a websocket (using mojolicious)

Here is my issue : I have got an API using mojolicious, an external script perl and a JS file, and I would like to connect them this way: the external script launch a random POST request, if it is a success it have to send the message "Success" throught a websocket. If an error occures, It will have to send "Error". The websocket on the API will just relay the message for the JS which will use it.
How I imagine the code to be :
Inside the Mojolicious launcher script:
websocket '/foo' => sub {
$self->on(message => sub {
my ($self, $msg) = #_;
$self->send($msg);
});
};
when get a message send it
Inside the JS file:
var ws = new WebSocket('ws://api/foo');
ws.onmessage = function(msg){
if(msg == "Error") {console.log("got an error")};
else if(msg == "Success") {console.log("got a success")};
};
So, how can I connect my external script to the websocket, and be able to send "Error" or "Success"? (This external script has nothing to do with the web server, it s somewhere else, doing something else).
I understand that you want a plain perl-script who connects to the Mojolicious webserver where you have a websocket endpoint.
The external perl script should connect to the websocket server and send some messages. The websocket server can then redistribute those messages to other clients.
Check my github where you can find the above screnario.
Perl Mojolicious websockets

Perl IO::Socket::SSL with web server hang

I've got a problem when using IO::Socket::SSL.
Everything works fine under normal operation but I had an issue where the web server (IIS) locked up and Perl got stuck, even after the web server became active again.
I'm running the Perl script as an exe under Windows and I can't actually see the program running as it is hidden - here is the code:
sub api_action
{
$api_action = $_[0];
use IO::Socket::SSL;
$EOL = "\015\012";
$BLANK = $EOL x 2;
$remote = IO::Socket::SSL->new( Proto => "tcp",
PeerAddr => "api.xxxxx",
PeerPort => "443",
SSL_verify_mode => SSL_VERIFY_NONE,
verify_hostname => 0,
Timeout => 120,
);
unless ($remote) { print "cannot connect to API\n"; return "ERROR"
}
$remote->autoflush(1);
print $remote "GET /API/?action=$api_action" . $BLANK;
return <$remote>;
close $remote;
}
My thought is that it has made the initial connection, but is still waiting for a return from the GET command. I would have thought setting the Timeout would just cause it to return the error but it doesn't look like it works.
Any ideas on where I'm going wrong or what I've missed?
You actually send this to the server inside the SSL connection:
GET /path\r\n
\r\n
This is no valid HTTP/1.0 or HTTP/1.1 request but a HTTP/0.9 request. Since HTTP/0.9 is obsolete since 20 years I would not expect to IIS still support this old protocol so it might just show unexpected behavior when confronted with such a request. A proper HTTP/1.0 request would look like this:
GET /path HTTP/1.0\r\n
Host: www.example.com\r\n
\r\n
For more information on how to send proper requests and how to properly deal with the response see the HTTP/1.0 and HTTP/1.1 standards.
Apart from that:
SSL_verify_mode => SSL_VERIFY_NONE,
verify_hostname => 0,
verify_hostname has no meaning in IO::Socket::SSL. You probably saw this with LWP::UserAgent and it is only relevant there.
Everything works fine under normal operation but I had an issue where the web server (IIS) locked up and Perl got stuck, even after the web server became active again.
Unfortunately this is not usable as an error description because it is unclear what you consider as "locked up" and "active again" but essentially if the server behaves erratically then the client might be affected by this.
Currently your are dealing with the request by reading until end of TCP connection. If the server behaves erratically and will not close this connection then you will wait forever.
Note, that the timeout you set might only be relevant for the initial connect and not for further reads. And it might not even work properly on Windows depending on the version of IO::Socket::SSL you use. You might instead add a alarm(60) or similar to make sure that the client does not wait forever on a broken server or you might try to work with non-blocking sockets to deal with the issue.

How to connect to a Gmail inbox

I am currently trying to connect to a gmail inbox using Perl and
Net::IMAP::Client
with the following code
use strict;
use warnings;
use Net::IMAP::Client;
my $user = '[address]#gmail.com';
my $pwd = '[password]';
my $imap = Net::IMAP::Client->new(
server => 'imap.gmail.com',
user => $user,
pass => $pwd,
ssl => 1, # (use SSL? default no)
ssl_verify_peer => 0, # (use ca to verify server, default yes)
port => 993 # (but defaults are sane)
) or die "Could not connect to IMAP server: $_";
$imap->login or
die('Login failed: ' . $imap->last_error)
But the $imap variable is undef and I am getting this error:
Use of uninitialized value $_ in concatenation (.) or string at testIMAP.pl line 9.
Could not connect to IMAP server: at testIMAP.pl line 9.
I have successfully connected to the mailbox using Outlook, but as I'm not getting an error message I'm not sure where to look. Does anyone know what I'm doing wrong here?
A big thanks to zdim for help troubleshooting.
Firstly, zdim pointed out that I had the incorrect error variable. $_ should have been $!
This revealed the error message "Network is unreachable", however I was able to pint and telnet to 'imap.gmail.com' successfully.
The solution to this was found here
Perl IO::Socket::SSL: connect: Network is unreachable .
Changing the use statement in the Net::IMAP::Client module to the following worked:
use IO::Socket::SSL 'inet4';
After this, the connection was established, but the login would fail with
Login failed: [ALERT] Please log in via your web browser: https://support.google.com/mail/accounts/answer/78754 (Failure)
This is due to Gmail's security features. I received an email that allowed me to confirm that the connection was not malicious, and then subsequent logins were successful.
For others, there may be a few solutions to this last one. You may need to issue an 'app password' If two-step authentication is activated, or you might need to toggle on 'allow less secure apps'

Perl File::Fetch Failed HTTP response: 500 Internal Server Error

I'm using a simple perl script to try and download a file from the following URL:
http://www.londonstockexchange.com/products-and-services/trading-services/setsqx/ccp-securities.xls
use File::Fetch;
my $url = 'http://www.londonstockexchange.com/products-and-services/trading-services/setsqx/ccp-securities.xls';
my $ff = File::Fetch->new(uri => $url);
my $file = $ff->fetch() or die $ff->error;
I am getting:
Fetch failed! HTTP response: 500 Internal Server Error [500 Can't connect to www.londonstockexchange.com:80 (connect: Connection refused)]
Could not open socket to 'www.londonstockexchange.com', 'Connection refused
Any ideas how i can get past this?
Could not open socket to 'www.londonstockexchange.com', 'Connection refused
Any ideas how i can get past this?
Direct connection to this site is blocked somewhere.
If you are inside a company there is probably a firewall and some proxy you are required to use. Ask your system administrator.