Index: trunk/extensions/DonationInterface/payflowpro_gateway/extras/recaptcha/recaptcha-php/recaptchalib.php |
— | — | @@ -1,4 +1,14 @@ |
2 | 2 | <?php |
| 3 | +/** |
| 4 | + * This is a modified PHP library that handles calling reCaptcha |
| 5 | + * |
| 6 | + * This is /different/ from the original PHP API for reCAPTCHA. |
| 7 | + * This version supports cURL and using an http proxy for network |
| 8 | + * communications and takes some settings set by MediaWiki. |
| 9 | + * |
| 10 | + * See below for original license and other info. |
| 11 | + */ |
| 12 | + |
3 | 13 | /* |
4 | 14 | * This is a PHP library that handles calling reCAPTCHA. |
5 | 15 | * - Documentation and latest version |
— | — | @@ -40,6 +50,19 @@ |
41 | 51 | define( "RECAPTCHA_VERIFY_SERVER", "www.google.com" ); |
42 | 52 | |
43 | 53 | /** |
| 54 | + * Proxy settings |
| 55 | + */ |
| 56 | +define( "RECAPTCHA_USE_HTTP_PROXY", $wgPayflowRecaptchaUseHTTPProxy ); |
| 57 | +define( "RECAPTCHA_HTTP_PROXY", $wgPayflowRecaptchaHTTPProxy ); |
| 58 | + |
| 59 | +/** |
| 60 | + * Other reCAPTCHA settings |
| 61 | + */ |
| 62 | +define( "RECAPTCHA_TIMEOUT", $wgPayflowRecaptchaTimeout ); |
| 63 | +define( "RECAPTCHA_PROTOCOL", $wgProto ); //http or https |
| 64 | +define( "RECAPTCHA_RETRY_LIMIT", $wgPayflowRecaptchaComsRetryLimit ); |
| 65 | + |
| 66 | +/** |
44 | 67 | * Encodes the given data into a query string format |
45 | 68 | * @param $data - array of string elements to be encoded |
46 | 69 | * @return string - encoded request |
— | — | @@ -57,7 +80,7 @@ |
58 | 81 | |
59 | 82 | |
60 | 83 | /** |
61 | | - * Submits an HTTP POST to a reCAPTCHA server |
| 84 | + * Wrapper to submit an HTTP POST to a reCAPTCHA server |
62 | 85 | * @param string $host |
63 | 86 | * @param string $path |
64 | 87 | * @param array $data |
— | — | @@ -68,32 +91,104 @@ |
69 | 92 | |
70 | 93 | $req = _recaptcha_qsencode ( $data ); |
71 | 94 | |
72 | | - $http_request = "POST $path HTTP/1.0\r\n"; |
73 | | - $http_request .= "Host: $host\r\n"; |
74 | | - $http_request .= "Content-Type: application/x-www-form-urlencoded;\r\n"; |
75 | | - $http_request .= "Content-Length: " . strlen( $req ) . "\r\n"; |
76 | | - $http_request .= "User-Agent: reCAPTCHA/PHP\r\n"; |
77 | | - $http_request .= "\r\n"; |
78 | | - $http_request .= $req; |
79 | | - |
80 | | - $response = ''; |
81 | | - if ( false == ( $fs = @fsockopen( $host, $port, $errno, $errstr, 10 ) ) ) { |
82 | | - die ( 'Could not open socket' ); |
| 95 | + if ( !extension_loaded( 'curl' ) ) { |
| 96 | + $response = _recaptcha_http_post_fsock( $host, $path, $req, $port ); |
| 97 | + } else { |
| 98 | + $response = _recaptcha_http_post_curl( $host, $path, $req, $port ); |
83 | 99 | } |
84 | | - |
85 | | - fwrite( $fs, $http_request ); |
86 | | - |
87 | | - while ( !feof( $fs ) ) |
88 | | - $response .= fgets( $fs, 1160 ); // One TCP-IP packet |
89 | | - fclose( $fs ); |
| 100 | + |
90 | 101 | $response = explode( "\r\n\r\n", $response, 2 ); |
91 | 102 | |
92 | 103 | return $response; |
93 | 104 | } |
94 | 105 | |
| 106 | +/** |
| 107 | + * Submits an HTTP POST to a reCAPTCHA server using fsockopen() |
| 108 | + * @param $host |
| 109 | + * @param $path |
| 110 | + * @param $data |
| 111 | + * @param int $port |
| 112 | + * @return array response |
| 113 | + */ |
| 114 | +function _recaptcha_http_post_fsock( $host, $path, $data, $port = 80 ) { |
| 115 | + |
| 116 | + $http_request = "POST $path HTTP/1.0\r\n"; |
| 117 | + $http_request .= "Host: $host\r\n"; |
| 118 | + $http_request .= "Content-Type: application/x-www-form-urlencoded;\r\n"; |
| 119 | + $http_request .= "Content-Length: " . strlen( $req ) . "\r\n"; |
| 120 | + $http_request .= "User-Agent: reCAPTCHA/PHP\r\n"; |
| 121 | + $http_request .= "\r\n"; |
| 122 | + $http_request .= $req; |
95 | 123 | |
| 124 | + $response = ''; |
| 125 | + if ( false == ( $fs = @fsockopen( $host, $port, $errno, $errstr, 10 ) ) ) { |
| 126 | + die ( 'Could not open socket' ); |
| 127 | + } |
96 | 128 | |
| 129 | + fwrite( $fs, $http_request ); |
| 130 | + |
| 131 | + while ( !feof( $fs ) ) |
| 132 | + $response .= fgets( $fs, 1160 ); // One TCP-IP packet |
| 133 | + fclose( $fs ); |
| 134 | + |
| 135 | + return $response; |
| 136 | +} |
| 137 | + |
97 | 138 | /** |
| 139 | + * Submits an HTTP POST to a reCAPTCHA server using cURL |
| 140 | + * @param $host |
| 141 | + * @param $path |
| 142 | + * @param $data |
| 143 | + * @param int $port |
| 144 | + * @return array response |
| 145 | + */ |
| 146 | +function _recaptcha_http_post_curl( $host, $path, $data, $port = 80 ) { |
| 147 | + $url = RECAPTCHA_PROTOCOL . "://" . $host . ":" . $port; |
| 148 | + |
| 149 | + $ch = curl_init( $url ); |
| 150 | + curl_setopt( $ch, CURLOPT_POST, true ); |
| 151 | + curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true ); |
| 152 | + curl_setopt( $ch, CURLOPT_TIMEOUT, RECAPTCHA_TIMEOUT ); |
| 153 | + curl_setopt( $ch, CURLOPT_USERAGENT, 'reCAPTCHA/PHP' ); |
| 154 | + curl_setopt($curl, CURLOPT_POSTFIELDS, $data ); |
| 155 | + curl_setopt($curl, CURLOPT_HEADER, true ); |
| 156 | + curl_setopt($curl, CURLOPT_HTTPHEADER, array( "Host: " . $host ) ); |
| 157 | + |
| 158 | + // set proxy settings if necessary |
| 159 | + if ( RECAPTCHA_USE_HTTP_PROXY ) { |
| 160 | + curl_setopt( $ch, CURLOPT_HTTPPROXYTUNNEL, 1 ); |
| 161 | + curl_setopt( $ch, CURLOPT_PROXY, RECAPTCHA_HTTP_PROXY ); |
| 162 | + } |
| 163 | + |
| 164 | + // try up to three times |
| 165 | + for ( $i = 0; $i < RECAPTCHA_RETRY_LIMIT; $i++ ) { |
| 166 | + wfDebug( 'payflowpro_gateway', 'Preparing to communicate with reCaptcha.' ); |
| 167 | + $response = curl_exec( $ch ); |
| 168 | + wfDebug( 'payflowpro_gateway', "Finished communicating with reCaptcha." ); |
| 169 | + if ( $response ) { |
| 170 | + wfDebug( 'payflowpro_gateway', 'Response from reCaptcha: ' . $response ); |
| 171 | + break; |
| 172 | + } |
| 173 | + } |
| 174 | + |
| 175 | + /** |
| 176 | + * This is a nasty hack to pretend like things worked when they really didn't |
| 177 | + * |
| 178 | + * Doing this per instructions from the fundraisers to accept a trxn when we |
| 179 | + * are unsuccesful communicating with reCaptcha. |
| 180 | + * |
| 181 | + * This sets $response to a message that will fool reCaptcha (on our end) into thinking |
| 182 | + * the user entered the correct values. |
| 183 | + */ |
| 184 | + if ( !$response ) { |
| 185 | + wfDebug( 'payflowpro_gateway', 'Failed communicating with reCaptcha: ' . curl_error( $ch ) ); |
| 186 | + $response = "true\r\n\r\ntrue"; |
| 187 | + } |
| 188 | + |
| 189 | + return $response; |
| 190 | +} |
| 191 | + |
| 192 | +/** |
98 | 193 | * Gets the challenge HTML (javascript and non-javascript version). |
99 | 194 | * This is called from the browser, and the resulting reCAPTCHA HTML widget |
100 | 195 | * is embedded within the HTML form it was called from. |
Index: trunk/extensions/DonationInterface/payflowpro_gateway/extras/recaptcha/recaptcha.php |
— | — | @@ -26,6 +26,23 @@ |
27 | 27 | $wgPayflowRecaptchaPublicKey = ''; |
28 | 28 | $wgPayflowRecaptchaPrivateKey = ''; |
29 | 29 | |
| 30 | +// Timeout (in seconds) for communicating with reCatpcha |
| 31 | +$wgPayflowRecaptchaTimeout = 2; |
| 32 | + |
| 33 | +/** |
| 34 | + * HTTP Proxy settings |
| 35 | + * |
| 36 | + * Default to settings in PayflowPro Gateway |
| 37 | + */ |
| 38 | +$wgPayflowRecaptchaUseHTTPProxy = $wgPayflowGatewayUseHTTPProxy; |
| 39 | +$wgPayflowRecaptchaHTTPProxy = $wgPayflowGatewayHTTPProxy; |
| 40 | + |
| 41 | +/** |
| 42 | + * The # of times to retry communicating with reCaptcha if communication fails |
| 43 | + * @var int |
| 44 | + */ |
| 45 | +$wgPayflowRecaptchaComsRetryLimit = 3; |
| 46 | + |
30 | 47 | $dir = dirname( __FILE__ ) . "/"; |
31 | 48 | $wgAutoloadClasses['PayflowProGateway_Extras_ReCaptcha'] = $dir . "recaptcha.body.php"; |
32 | 49 | |