这是一款博客程序(Movable Type)的验证码reCaptcha插件。
用户评论输入验证码总是提示输入错误,反复测试觉得是因为服务器要POST数据到http//www.google.com/recaptcha/api/verify,结果因为服务器在国内,无法访问google.com导致验证失败所致。
偶然发现使用google.cn的80端口做HTTP代理,可以直接访问google.com下面的文件,只是不能打开首页,不能使用搜索功能而已。然后我就想,能不能在 sub validate_captcha 里增加使用google.cn的80端口做HTTP代理的功能,通过google.cn的80端口去访问http//www.google.com/recaptcha/api/verify。
代码:
# Movable Type (r) Open Source (C) 2001-2008 Six Apart, Ltd.
# This program is distributed under the terms of the
# GNU General Public License, version 2.
#
# $Id: reCaptcha.pm 1174 2008-01-08 21:02:50Z bchoate $
# reCaptcha plugin for Movable Type
# Author: Six Apart (
http://www.sixapart.com)
# Released under the Artistic and GPLv2 License
package reCaptcha;
use strict;
use warnings;
use base qw(MT::ErrorHandler);
sub form_fields {
my $self = shift;
my ($blog_id) = @
_;
my $plugin = MT::Plugin::reCaptcha->instance;
my $config = $plugin->get_config_hash("blog:$blog_id");
my $publickey = $config->{recaptcha_publickey};
my $privatekey = $config->{recaptcha_privatekey};
return q() unless $publickey && $privatekey;
return <<FORM_FIELD;
<div id="recaptcha_script" style="display:block">
<script type="text/javascript"
src="//www.google.com/recaptcha/api/challenge?k=$publickey">
</script>
<noscript>
<iframe src="//www.google.com/recaptcha/api/noscript?k=$publickey"
height="300" width="500" frameborder="0"></iframe><br>
<textarea name="recaptcha_challenge_field" rows="3" cols="40">
</textarea>
<input type="hidden" name="recaptcha_response_field"
value="manual_challenge">
</noscript>
</div>
<script type="text/javascript">
if ( typeof(mtCaptchaVisible) != "undefined" )
mtCaptchaVisible = true;
else if ( typeof(commenter_name) != "undefined" ) {
var div = document.getElementById("recaptcha_script");
if (commenter_name)
div.style.display = "none";
else
div.style.display = "block";
}
</script>
FORM_FIELD
}
sub validate_captcha {
my $self = shift;
my ($app) = @
_;
my $entry_id = $app->param('entry_id')
or return 0;
my $entry = $app->model('entry')->load($entry_id)
or return 0;
my $blog_id = $entry->blog_id;
my $config = MT::Plugin::reCaptcha->instance->get_config_hash("blog:$blog_id");
my $privatekey = $config->{recaptcha_privatekey};
my $challenge = $app->param('recaptcha_challenge_field');
my $response = $app->param('recaptcha_response_field');
my $ua = $app->new_ua({ timeout => 15, max_size => undef });
return 0 unless $ua;
require HTTP::Request;
my $req = HTTP::Request->new(POST => 'http//www.google.com/recaptcha/api/verify');
$req->content_type("application/x-www-form-urlencoded");
require MT::Util;
my $content = 'privatekey=' . MT::Util::encode_url($privatekey);
$content .= '&remoteip=' . MT::Util::encode_url($app->remote_ip);
$content .= '&challenge=' . MT::Util::encode_url($challenge);
$content .= '&response=' . MT::Util::encode_url($response);
$req->content($content);
my $res = $ua->request($req);
my $c = $res->content;
if (substr($res->code, 0, 1) eq '2') {
return 1 if $c =~ /^true\n/;
}
0;
}
sub generate_captcha {
#This won't be called since there is no link which requests to "generate_captcha" mode.
my $self = shift;
1;
}
1;