[BUGFIX] Akismet check takes a lot of time 10/33310/2
authortritum_rz <ralf.zimmermann@tritum.de>
Tue, 14 Oct 2014 17:04:05 +0000 (19:04 +0200)
committerRalf Zimmermann <ralf.zimmermann@tritum.de>
Tue, 14 Oct 2014 17:05:05 +0000 (19:05 +0200)
Resolves: #62238
Releases: 6.2
Change-Id: If30b76325e4673e04149a5305dfd1259ae982aa8
Reviewed-on: http://review.typo3.org/33310
Reviewed-by: Ralf Zimmermann <ralf.zimmermann@tritum.de>
Tested-by: Ralf Zimmermann <ralf.zimmermann@tritum.de>
ChangeLog
Classes/Methodes/class.tx_wtspamshield_method_akismet.php [changed mode: 0644->0755]
Classes/System/class.tx_wtspamshield_akismet.php [changed mode: 0644->0755]
Classes/System/class.tx_wtspamshield_akismet_httpclient.php [changed mode: 0644->0755]

index 6ca0267..410e952 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,11 +1,15 @@
 1.3.0-dev
-       2014-05-04
+       2014-10-14
+       Ralf Zimmermann <ralf.zimmermann@tritum.de>
+
+       * FIX feature #62238: Akismet check takes a lot of time
+
+       2014-09-24
        Ralf Zimmermann <ralf.zimmermann@tritum.de>
 
        * ADD feature #61854: default mailform: dont include honeypot field in email
 
-1.3.0-dev
-       2014-05-04
+       2014-09-01
        Ralf Zimmermann <ralf.zimmermann@tritum.de>
 
        * ADD feature #57513: add formhandler support 
old mode 100644 (file)
new mode 100755 (executable)
index b35203f..aa73fbb
@@ -71,8 +71,11 @@ class tx_wtspamshield_method_akismet extends tx_wtspamshield_method_abstract {
                        'user_agent' => t3lib_div::getIndpEnv('HTTP_USER_AGENT')
                );
 
-               $akismet = new tx_wtspamshield_akismet('http://' . t3lib_div::getIndpEnv('HTTP_HOST') . '/',
-                                                                                               $tsConf['akismetCheck.']['akismetKey'], $akismetArray);
+               $akismet = new tx_wtspamshield_akismet(
+                       'http://' . t3lib_div::getIndpEnv('HTTP_HOST') . '/',
+                       $tsConf['akismetCheck.']['akismetKey'],
+                       $akismetArray
+               );
 
                if (!$akismet->isError() && $akismet->isSpam()) {
                        $error = $this->renderCobj($tsConf['errors.'], 'akismet');
old mode 100644 (file)
new mode 100755 (executable)
index 4a20864..f3a6fb7
@@ -97,9 +97,31 @@ class tx_wtspamshield_akismet extends tx_wtspamshield_akismet_object {
         * @return void
         */
        public function __construct($blogUrl, $apiKey, $comment) {
+
                $this->blogUrl = $blogUrl;
                $this->apiKey  = $apiKey;
 
+               $this->urls = array (
+                       'verify' => $this->akismetServer . '/'
+                                               . $this->akismetVersion
+                                               . '/verify-key',
+
+                       'commentCheck' => $this->apiKey . '.'
+                                                       . $this->akismetServer . '/'
+                                                       . $this->akismetVersion
+                                                       . '/comment-check',
+
+                       'submitSpam' => $this->apiKey . '.' 
+                                                       . $this->akismetServer . '/'
+                                                       . $this->akismetVersion
+                                                       . '/submit-spam',
+
+                       'submitHam' => $this->apiKey . '.'
+                                                       . $this->akismetServer . '/'
+                                                       . $this->akismetVersion
+                                                       . '/submit-ham'
+               );
+
                        // Populate the comment array with information needed by Akismet
                $this->comment = $comment;
                $this->formatCommentArray();
@@ -109,16 +131,18 @@ class tx_wtspamshield_akismet extends tx_wtspamshield_akismet_object {
                                ? $_SERVER['REMOTE_ADDR']
                                : getenv('HTTP_X_FORWARDED_FOR');
                }
+
                if (!isset($this->comment['user_agent'])) {
                        $this->comment['user_agent'] = $_SERVER['HTTP_USER_AGENT'];
                }
+
                if (!isset($this->comment['referrer'])) {
                        $this->comment['referrer'] = $_SERVER['HTTP_REFERER'];
                }
                $this->comment['blog'] = $blogUrl;
 
                        // Connect to the Akismet server and populate errors if they exist
-               $this->http = new tx_wtspamshield_akismet_httpclient($this->akismetServer, $blogUrl, $apiKey);
+               $this->http = new tx_wtspamshield_akismet_httpclient();
                if ($this->http->errorsExist()) {
                        $this->errors = array_merge($this->errors, $this->http->getErrors());
                }
@@ -135,8 +159,7 @@ class tx_wtspamshield_akismet extends tx_wtspamshield_akismet_object {
         * @return boolean
         */
        public function isSpam() {
-               $response = $this->http->getResponse($this->getQueryString(), 'comment-check');
-
+               $response = $this->http->getResponse($this->getQueryString(), $this->urls['commentCheck']);
                return ($response == 'true');
        }
 
@@ -146,7 +169,7 @@ class tx_wtspamshield_akismet extends tx_wtspamshield_akismet_object {
         * @return void
         */
        public function submitSpam() {
-               $this->http->getResponse($this->getQueryString(), 'submit-spam');
+               $this->http->getResponse($this->getQueryString(), $this->urls['submitSpam']);
        }
 
        /**
@@ -155,7 +178,7 @@ class tx_wtspamshield_akismet extends tx_wtspamshield_akismet_object {
         * @return void
         */
        public function submitHam() {
-               $this->http->getResponse($this->getQueryString(), 'submit-ham');
+               $this->http->getResponse($this->getQueryString(), $this->urls['submitHam']);
        }
 
        /**
@@ -164,7 +187,7 @@ class tx_wtspamshield_akismet extends tx_wtspamshield_akismet_object {
         * @return boolean
         */
        protected function isValidApiKey() {
-               $keyCheck = $this->http->getResponse('key=' . $this->apiKey . '&blog=' . $this->blogUrl, 'verify-key');
+               $keyCheck = $this->http->getResponse('key=' . $this->apiKey . '&blog=' . $this->blogUrl, $this->urls['verify']);
                return ($keyCheck == 'valid');
        }
 
old mode 100644 (file)
new mode 100755 (executable)
index 57d96d9..0c54113
@@ -68,17 +68,11 @@ class tx_wtspamshield_akismet_httpclient extends tx_wtspamshield_akismet_object
        /**
         * Constructor
         *
-        * @param string $host
-        * @param string $blogUrl
-        * @param string $apiKey
         * @param integer $port
         * @return void
         */
-       public function __construct($host, $blogUrl, $apiKey, $port = 80) {
-               $this->host = $host;
+       public function __construct($port = 80) {
                $this->port = $port;
-               $this->blogUrl = $blogUrl;
-               $this->apiKey = $apiKey;
        }
 
        /**
@@ -86,60 +80,54 @@ class tx_wtspamshield_akismet_httpclient extends tx_wtspamshield_akismet_object
         * server and return that response
         *
         * @param mixed $request
-        * @param string $path
+        * @param string $url
         * @param string $type
-        * @param integer $responseLength
         * @return mixed
         */
-       public function getResponse($request, $path, $type = 'post', $responseLength = 1160) {
+       public function getResponse($request, $url) {
                $this->connect();
 
                if ($this->con && !$this->isError(AKISMET_SERVER_NOT_FOUND)) {
-                       $request  =
-                                       strToUpper($type) . ' /' .
-                                       $this->akismetVersion . '/' .
-                                       $path .
-                                       " HTTP/1.1\r\n" .
-                                       'Host: ' .
-                                       ( ( strlen($this->apiKey) > 0 )
-                                               ? $this->apiKey  . '.'
-                                               : NULL
-                                       ) .
-                                       $this->host . "\r\n" .
-                                       "Content-Type: application/x-www-form-urlencoded; charset=utf-8\r\n" .
-                                       'Content-Length: ' . strlen($request) . "\r\n" .
-                                       "User-Agent: Akismet PHP4 Class\r\n" .
-                                       "\r\n" .
-                                       $request;
-                       $response = '';
-
-                       @fwrite($this->con, $request);
-
-                       while (!feof($this->con)) {
-                               $response .= @fgets($this->con, $responseLength);
+                       curl_setopt($this->con, CURLOPT_URL, $url);
+                       curl_setopt($this->con, CURLOPT_POSTFIELDS, $request);
+
+                       if(!$response = curl_exec($this->con)) {
+                               $this->setError(AKISMET_RESPONSE_FAILED, 'The response could not be retrieved.');
+                               return;
                        }
 
-                       $response = explode("\r\n\r\n", $response, 2);
-                       return $response[1];
-               } else {
-                       $this->setError(AKISMET_RESPONSE_FAILED, 'The response could not be retrieved.');
+                       $this->disconnect();
+                       return $response;
                }
-
-               $this->disconnect();
-               return NULL;
        }
 
-       /**
-        * Connect to the Akismet server and store that connection in the
-        * instance variable $con
-        *
-        * @return void
-        */
-       public function connect() {
-               if (!($this->con = @fsockopen($this->host, $this->port))) {
-                       $this->setError(AKISMET_SERVER_NOT_FOUND, 'Could not connect to akismet server.');
+    /**
+     * Initializes a new cURL session/handle
+     *
+     * @return boolean
+    */
+    public function connect() {
+               if (!is_resource($this->con)) {
+                       if(!$this->con = curl_init()) {
+                          $this->setError(AKISMET_SERVER_NOT_FOUND, 'Could not connect to akismet server.');
+                          return;
+                       }
                }
-       }
+
+               curl_setopt($this->con, CURLOPT_HEADER, 0);
+               curl_setopt($this->con, CURLOPT_POST, 1);
+               curl_setopt($this->con, CURLOPT_TIMEOUT, 0); 
+               curl_setopt($this->con, CURLOPT_RETURNTRANSFER, 1);
+               curl_setopt($this->con, CURLOPT_USERAGENT, 
+                                       "Akismet PHP4 Class");
+               curl_setopt($this->con, CURLOPT_FRESH_CONNECT, 1);
+
+               if ($this->port != 80) {
+                       curl_setopt($this->con, CURLOPT_PORT, $this->port);
+               }
+
+               return true;
+    }
 
        /**
         * Close the connection to the Akismet server
@@ -147,7 +135,14 @@ class tx_wtspamshield_akismet_httpclient extends tx_wtspamshield_akismet_object
         * @return void
         */
        public function disconnect() {
-               @fclose($this->con);
+               if (is_resource($this->con)) {
+                       if (!curl_close($this->con)) {
+                               $this->setError(AKISMET_SERVER_NOT_FOUND, 'Could not close the CURL instance');
+                               return;
+                       }
+               }
+
+               return true;
        }
 }