perl - 如何在 Windows 上使用 Perl 读取 https 页面的内容,而不安装 OpenSSL?

标签 perl ssl https proxy

我编写了一个脚本,通过发送 POST 请求来读取 https 页面的内容,并将其转储到文本文件中。它在 Linux 下运行良好,在安装 Shining Light OpenSSL 后也可以在我的 Windows 机器上运行。 。但客户表示他们无法在 Windows 计算机上安装任何 exe,并要求提供替代解决方案。

我们还有其他选择吗?也许某些代理接受 POST 请求,获取 https 内容并将其作为 http 传递?我知道,这是很多一厢情愿的想法,但我只是想在这里探索任何可能的选择。

最佳答案

使用Win32::IE::Mechanize 。如今,所有 Windows 系统都具有某个版本的 Internet Explorer(尽管在某些系统上,管理员可能会阻止功能)。

您还可以使用Win32::OLE可以这么说,“手动”驱动 IE;-)

以下代码在我古老的 Windows XP SP3 系统上“有效”。我不确定它是否适用于 Vista 或 Windows 7 UAC。 showcgi.pl 只是转储 $cgi 对象的状态。您可以看到下面的输出。

我在my blog post中更详细地解释了发生的事情。 .

我没有设置用于测试的 SSL 服务器,但请告诉我脚本在这些修改后是否有效。

#!/usr/bin/env perl

package My::Poster;

use strict; use warnings;

use Const::Fast;
use Try::Tiny;
use Win32::OLE;
use Win32::OLE::Variant;
local $Win32::OLE::Warn = 3;

# http://msdn.microsoft.com/en-us/library/aa768360%28v=vs.85%29.aspx
const my %BrowserNavConstants => (
    navOpenInNewWindow => 0x1,
    navNoHistory => 0x2,
    navNoReadFromCache => 0x4,
    navNoWriteToCache => 0x8,
    navAllowAutosearch => 0x10,
    navBrowserBar => 0x20,
    navHyperlink => 0x40,
    navEnforceRestricted => 0x80,
    navNewWindowsManaged => 0x0100,
    navUntrustedForDownload => 0x0200,
    navTrustedForActiveX => 0x0400,
    navOpenInNewTab => 0x0800,
    navOpenInBackgroundTab => 0x1000,
    navKeepWordWheelText => 0x2000,
    navVirtualTab => 0x4000,
    navBlockRedirectsXDomain => 0x8000,
    navOpenNewForegroundTab => 0x10000,
);

sub new {
    my $class = shift;
    my $self = bless {} => $class;
    $self->init;
    return $self;
}

sub ie {
    my $self = shift;
    my $ie = shift;

    return $self->{ie} unless defined $ie;

    $self->{ie} = $ie;
    return;
}

sub init {
    my $self = shift;

    $self->ie(
        Win32::OLE->new(
            'InternetExplorer.Application',
            sub {
                my $ie = shift;
                try { $ie->Quit if $ie } catch { warn "$_\n" };
            },
        )
    );
    return;
}

sub post {
    my $self = shift;
    my ($url, $data) = @_;

    my $ie = $self->ie;

    my $flags = $BrowserNavConstants{navNoHistory} |
                $BrowserNavConstants{navNoReadFromCache} |
                $BrowserNavConstants{navNoWriteToCache} |
                $BrowserNavConstants{navEnforceRestricted} |
                $BrowserNavConstants{navNewWindowsManaged} |
                $BrowserNavConstants{navUntrustedForDownload} |
                $BrowserNavConstants{navBlockRedirectsXDomain}
    ;

    # $postdata should also be converted to bytes here
    # I don't remember the right way to do it, and it works for ASCII
    # so it should be good enough for now.

    my $postdata = join '&', map join('=', @$_), @$data;

    my $vPostData = Variant(VT_ARRAY|VT_UI1, length $postdata);
    $vPostData->Put($postdata);

    # http://msdn.microsoft.com/en-us/library/aa752133%28v=vs.85%29.aspx
    $ie->Navigate(
        $url,
        $flags,
        '_self',
        $vPostData,
        "Content-Type: application/x-www-form-urlencoded\015\012",
    );

    while ($ie->{ReadyState} != 4) {
        sleep 1;
    }

    return $ie->Document->documentElement->innerHTML;
}

sub DESTROY {
    my $self = shift;
    try { $self->ie->Quit } catch { warn "$_\n" };
    return;
}

package main;

use strict; use warnings;

my $poster = My::Poster->new;

my $html = $poster->post(
    'http://test.localdomain:8080/cgi-bin/showcgi.pl',
    [
        [ thisvar => 'thatvalue', ],
        [ anothervar => 'anothervalue', ],
        [ oh => 'lala', ],
    ],
);

print $html if defined $html;

输出:

$VAR1 = bless( {
     '.parameters' => [
                        'thisvar',
                        'anothervar',
                        'oh'
                      ],
     '.crlf' => '
',
     '.globals' => {
                     'DEBUG' => 0,
                     'NO_UNDEF_PARAMS' => 0,
                     'NO_NULL' => 1,
                     'FATAL' => -1,
                     'USE_PARAM_SEMICOLONS' => 0,
                     'PARAM_UTF8' => 0,
                     'DISABLE_UPLOADS' => 1,
                     'USE_CGI_PM_DEFAULTS' => 0,
                     'NPH' => 0,
                     'POST_MAX' => 102400,
                     'HEADERS_ONCE' => 0
                   },
     'anothervar' => [
                       'anothervalue'
                     ],
     'oh' => [
               'lala'
             ],
     'thisvar' => [
                    'thatvalue'
                  ],
     '.fieldnames' => {
                        'anothervar' => 1,
                        'oh' => 1,
                        'thisvar' => 1
                      },
     '.header_printed' => 1
   }, 'CGI::Simple' );

关于perl - 如何在 Windows 上使用 Perl 读取 https 页面的内容,而不安装 OpenSSL?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10333823/

相关文章:

ssl - 寻找有关 "HTTP to HTTPS"的分步指南

string - 在 Perl 中将所有参数作为字符串传递给子例程

mysql - Perl XML::Smart 内存不足!错误

linux - perl 计时器的静默计时器警报 - 类似于 "visual bell"

Java https 代理(使用 https.proxyPort 和 https.proxyHost)

asp.net - 使用 IE 通过 https(SSL) 导出到 excel 在 asp.net 网站中不起作用

python - 需要一个支持 HTTPS 的 Python XML-RPC 服务器

perl - Try::Tiny:捕获警告的问题

c++ - QSslServer 中客户端的对等证书在 Qt C++ 中始终为 Null

mysql - 使用 Python 3.7 与 MySQL 的 SSL 连接错误。接口(interface)错误 : SSL connection error: Failed to set ciphers to use