Projet

Général

Profil

Paste
Télécharger (3,74 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / recaptcha / recaptcha-php / src / ReCaptcha / RequestMethod / SocketPost.php @ be58a50c

1
<?php
2
/**
3
 * This is a PHP library that handles calling reCAPTCHA.
4
 *
5
 * @copyright Copyright (c) 2015, Google Inc.
6
 * @link      http://www.google.com/recaptcha
7
 *
8
 * Permission is hereby granted, free of charge, to any person obtaining a copy
9
 * of this software and associated documentation files (the "Software"), to deal
10
 * in the Software without restriction, including without limitation the rights
11
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
 * copies of the Software, and to permit persons to whom the Software is
13
 * furnished to do so, subject to the following conditions:
14
 *
15
 * The above copyright notice and this permission notice shall be included in
16
 * all copies or substantial portions of the Software.
17
 *
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
 * THE SOFTWARE.
25
 */
26

    
27
namespace ReCaptcha\RequestMethod;
28

    
29
use ReCaptcha\RequestMethod;
30
use ReCaptcha\RequestParameters;
31

    
32
/**
33
 * Sends a POST request to the reCAPTCHA service, but makes use of fsockopen()
34
 * instead of get_file_contents(). This is to account for people who may be on
35
 * servers where allow_furl_open is disabled.
36
 */
37
class SocketPost implements RequestMethod
38
{
39
    /**
40
     * reCAPTCHA service host.
41
     * @const string
42
     */
43
    const RECAPTCHA_HOST = 'www.google.com';
44

    
45
    /**
46
     * @const string reCAPTCHA service path
47
     */
48
    const SITE_VERIFY_PATH = '/recaptcha/api/siteverify';
49

    
50
    /**
51
     * @const string Bad request error
52
     */
53
    const BAD_REQUEST = '{"success": false, "error-codes": ["invalid-request"]}';
54

    
55
    /**
56
     * @const string Bad response error
57
     */
58
    const BAD_RESPONSE = '{"success": false, "error-codes": ["invalid-response"]}';
59

    
60
    /**
61
     * Socket to the reCAPTCHA service
62
     * @var Socket
63
     */
64
    private $socket;
65

    
66
    /**
67
     * Constructor
68
     *
69
     * @param \ReCaptcha\RequestMethod\Socket $socket optional socket, injectable for testing
70
     */
71
    public function __construct(Socket $socket = null)
72
    {
73
        if (!is_null($socket)) {
74
            $this->socket = $socket;
75
        } else {
76
            $this->socket = new Socket();
77
        }
78
    }
79

    
80
    /**
81
     * Submit the POST request with the specified parameters.
82
     *
83
     * @param RequestParameters $params Request parameters
84
     * @return string Body of the reCAPTCHA response
85
     */
86
    public function submit(RequestParameters $params)
87
    {
88
        $errno = 0;
89
        $errstr = '';
90

    
91
        if (false === $this->socket->fsockopen('ssl://' . self::RECAPTCHA_HOST, 443, $errno, $errstr, 30)) {
92
            return self::BAD_REQUEST;
93
        }
94

    
95
        $content = $params->toQueryString();
96

    
97
        $request = "POST " . self::SITE_VERIFY_PATH . " HTTP/1.1\r\n";
98
        $request .= "Host: " . self::RECAPTCHA_HOST . "\r\n";
99
        $request .= "Content-Type: application/x-www-form-urlencoded\r\n";
100
        $request .= "Content-length: " . strlen($content) . "\r\n";
101
        $request .= "Connection: close\r\n\r\n";
102
        $request .= $content . "\r\n\r\n";
103

    
104
        $this->socket->fwrite($request);
105
        $response = '';
106

    
107
        while (!$this->socket->feof()) {
108
            $response .= $this->socket->fgets(4096);
109
        }
110

    
111
        $this->socket->fclose();
112

    
113
        if (0 !== strpos($response, 'HTTP/1.1 200 OK')) {
114
            return self::BAD_RESPONSE;
115
        }
116

    
117
        $parts = preg_split("#\n\s*\n#Uis", $response);
118

    
119
        return $parts[1];
120
    }
121
}