<?php
class
Sina_Mail_WebAntispam {
const
PREFIX_WHITELIST = 'w:';
const
PREFIX_KILL = 'k:';
const
PREFIX_VERIFYCODE = 'c:';
const
PREFIX_VERIFIED = 'v:';
const
STATUS_UPDATE = '[U]';
private
$mc
= null;
private
$config
= null;
private
$whitelist
=
array
();
private
$keyPrefix
= '';
private
$intervals
=
array
();
private
$updates
=
array
();
private
$status
=
array
();
public
function
__construct(
$mc
,
$config
) {
$this
->mc =
$mc
;
$this
->config =
$config
;
if
(isset(
$this
->config->prefix)) {
$this
->keyPrefix =
$this
->config->prefix;
}
if
(isset(
$this
->config->whitelistKey)) {
$wls
=
$this
->mc->get(
$this
->config->whitelistKey);
if
(!
empty
(
$wls
)) {
$this
->whitelist = &
$wls
;
}
}
}
public
function
setWhitelist(&
$whitelist
) {
$this
->whitelist = &
$whitelist
;
}
public
function
check(
$ip
= null,
$key
= null) {
if
(!
$ip
&& !
$key
) {
return
false;
}
if
(
$key
) {
if
(!
is_array
(
$key
)) {
$keys
=
array
(
$key
);
}
else
{
$keys
=
$key
;
}
}
if
(!
empty
(
$this
->whitelist)) {
if
(
$ip
&&
$this
->filterByWhitelist(
$ip
, 'ip')) {
$this
->status[self::PREFIX_WHITELIST .
$ip
] = 1;
return
true;
}
if
(
$keys
) {
foreach
(
$keys
as
$key
) {
if
(
$this
->filterByWhitelist(
$key
, 'key')) {
$this
->status[self::PREFIX_WHITELIST .
$key
] = 1;
return
true;
}
}
}
}
if
(
$ip
) {
$ip
=
$this
->keyPrefix .
$ip
;
}
if
(!
empty
(
$this
->config->verified)) {
if
(
$ip
&&
$this
->mc->get(self::PREFIX_VERIFIED .
$ip
)) {
$this
->status[self::PREFIX_VERIFIED .
$ip
] = 1;
return
true;
}
if
(
$keys
) {
foreach
(
$keys
as
$key
) {
$verifiedKey
= self::PREFIX_VERIFIED .
$this
->keyPrefix .
$key
;
if
(
$this
->mc->get(
$verifiedKey
)) {
$this
->status[
$verifiedKey
] = 1;
return
true;
}
}
}
}
$kos
= !
empty
(
$this
->config->kill);
if
(
$kos
) {
if
(
$ip
&&
$this
->mc->get(self::PREFIX_KILL .
$ip
)) {
$this
->status[self::PREFIX_KILL .
$ip
] = 1;
return
false;
}
if
(
$keys
) {
foreach
(
$keys
as
$key
) {
$killKey
= self::PREFIX_KILL .
$this
->keyPrefix .
$key
;
if
(
$this
->mc->get(
$killKey
)) {
$this
->status[
$killKey
] = 1;
return
false;
}
}
}
}
if
(
$ip
&& isset(
$this
->config->ip)) {
if
(!
$this
->checkRule(
$ip
,
$this
->config->ip)) {
if
(
$kos
&&
$this
->mc->set(self::PREFIX_KILL .
$ip
, 1,
intval
(
$this
->config->kill))) {
$this
->status[self::PREFIX_KILL .
$ip
] = 1;
}
return
false;
}
}
if
(
$keys
&& isset(
$this
->config->key)) {
foreach
(
$keys
as
$key
) {
if
(!
$this
->checkRule(
$this
->keyPrefix .
$key
,
$this
->config->key)) {
$killKey
= self::PREFIX_KILL .
$this
->keyPrefix .
$key
;
if
(
$kos
&&
$this
->mc->set(
$killKey
, 1,
intval
(
$this
->config->kill))) {
$this
->status[
$killKey
] = 1;
}
return
false;
}
}
}
return
true;
}
public
function
update(
$c
= 1,
$ip
= null,
$key
= null) {
if
(
is_null
(
$ip
) &&
is_null
(
$key
)) {
if
(!
empty
(
$this
->updates)) {
foreach
(
$this
->updates
as
$k
=>
$v
) {
if
(!
$v
&& isset(
$this
->intervals[
$k
])) {
if
(
$this
->mc->add(
$k
,
$c
, false,
$this
->intervals[
$k
])) {
$this
->status[self::STATUS_UPDATE .
$k
] =
$c
;
continue
;
}
}
$r
=
$this
->mc->increment(
$k
,
$c
);
$this
->status[self::STATUS_UPDATE .
$k
] =
$r
;
}
}
}
else
{
if
(!
is_null
(
$ip
) && isset(
$this
->config->ip)) {
$rule
=
$this
->config->ip;
foreach
(
$rule
as
$interval
=>
$limit
) {
$k
=
$this
->keyPrefix .
$ip
. '_' .
$interval
;
if
(
$this
->mc->add(
$k
,
$c
,false,
$interval
)) {
$this
->status[self::STATUS_UPDATE .
$k
] = true;
continue
;
}
$r
=
$this
->mc->increment(
$k
,
$c
);
$this
->status[self::STATUS_UPDATE .
$k
] =
$r
;
}
}
if
(!
is_null
(
$key
) && isset(
$this
->config->key)) {
$rule
=
$this
->config->key;
if
(!
is_array
(
$key
)) {
$keys
=
array
(
$key
);
}
else
{
$keys
=
$key
;
}
foreach
(
$keys
as
$key
) {
foreach
(
$rule
as
$interval
=>
$limit
) {
$k
=
$this
->keyPrefix .
$key
. '_' .
$interval
;
if
(
$this
->mc->add(
$k
,
$c
,false,
$interval
)) {
$this
->status[self::STATUS_UPDATE .
$k
] = true;
continue
;
}
$r
=
$this
->mc->increment(
$k
,
$c
);
$this
->status[self::STATUS_UPDATE .
$k
] =
$r
;
}
}
}
}
}
public
function
checkVerifyCode(
$key
,
$code
) {
$servcode
=
$this
->mc->get(self::PREFIX_VERIFYCODE .
$this
->keyPrefix .
$key
);
if
(
strcasecmp
(
$servcode
,
$code
) == 0) {
$verified
=
intval
(
$this
->config->verified);
if
(
$verified
> 0) {
$r
=
$this
->mc->set(self::PREFIX_VERIFIED .
$this
->keyPrefix .
$key
, 1, false,
$verified
);
}
else
{
$r
= true;
}
if
(
$r
) {
$this
->mc->
delete
(self::PREFIX_VERIFYCODE .
$this
->keyPrefix .
$key
);
}
return
$r
;
}
return
false;
}
public
function
isVerified(
$key
) {
$r
=
$this
->mc->get(self::PREFIX_VERIFIED .
$this
->keyPrefix .
$key
);
if
(!
empty
(
$r
)) {
return
true;
}
else
{
return
false;
}
}
public
function
setVerifyCode(
$key
,
$code
) {
$verifytime
=
intval
(
$this
->config->verifytime);
if
(
$verifytime
< 1) {
return
false;
}
return
$this
->mc->set(self::PREFIX_VERIFYCODE .
$this
->keyPrefix .
$key
,
$code
, false,
$verifytime
);
}
public
function
getStatus() {
return
$this
->status;
}
private
function
filterByWhitelist(
$value
,
$key
) {
$ls
= &
$this
->whitelist;
foreach
(
$ls
as
$i
) {
if
(
$i
[
strlen
(
$i
) - 1] == '.') {
if
(
strpos
(
$value
,
$i
) === 0) {
return
true;
}
}
else
{
if
(
strcmp
(
$i
,
$value
) === 0) {
return
true;
}
}
}
return
false;
}
private
function
checkRule(
$key
,
$rule
) {
$flag
= true;
if
(!
empty
(
$rule
)) {
foreach
(
$rule
as
$interval
=>
$limit
) {
$k
=
$key
. '_' .
$interval
;
$c
=
$this
->mc->get(
$k
);
if
(!
$c
) {
$this
->updates[
$k
] = 0;
$this
->intervals[
$k
] =
$interval
;
$this
->status[
$k
] = 0;
}
else
{
$this
->updates[
$k
] =
$c
;
$this
->status[
$k
] =
$c
;
if
(
$c
>=
$limit
) {
$flag
= false;
}
}
}
}
return
$flag
;
}
public
static
function
getInstance(
$conf
) {
$mc
=
new
Memcache();
$mc
->connect(
"115.159.28.112"
);
$conf
=json_decode(json_encode(
$conf
));
return
new
self(
$mc
,
$conf
);
}
}
$conf
=
array
(
'prefix' => 'selfservice:',
'key' =>
array
(60 => 1,3600=>10),
'ip' =>
array
(60 => 1),
);
$spam
=Sina_Mail_WebAntispam::getInstance(
$conf
);
if
(!
$spam
->check('127.25.12.123',17610725730)){
echo
"limit..."
;
exit
;
}
$spam
->update();