SocketPost.php 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  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. namespace ReCaptcha\RequestMethod;
  27. use ReCaptcha\RequestMethod;
  28. use ReCaptcha\RequestParameters;
  29. /**
  30. * Sends a POST request to the reCAPTCHA service, but makes use of fsockopen()
  31. * instead of get_file_contents(). This is to account for people who may be on
  32. * servers where allow_furl_open is disabled.
  33. */
  34. class SocketPost implements RequestMethod
  35. {
  36. /**
  37. * reCAPTCHA service host.
  38. * @const string
  39. */
  40. const RECAPTCHA_HOST = 'www.google.com';
  41. /**
  42. * @const string reCAPTCHA service path
  43. */
  44. const SITE_VERIFY_PATH = '/recaptcha/api/siteverify';
  45. /**
  46. * @const string Bad request error
  47. */
  48. const BAD_REQUEST = '{"success": false, "error-codes": ["invalid-request"]}';
  49. /**
  50. * @const string Bad response error
  51. */
  52. const BAD_RESPONSE = '{"success": false, "error-codes": ["invalid-response"]}';
  53. /**
  54. * Socket to the reCAPTCHA service
  55. * @var Socket
  56. */
  57. private $socket;
  58. /**
  59. * Constructor
  60. *
  61. * @param \ReCaptcha\RequestMethod\Socket $socket optional socket, injectable for testing
  62. */
  63. public function __construct(Socket $socket = null)
  64. {
  65. if (!is_null($socket)) {
  66. $this->socket = $socket;
  67. } else {
  68. $this->socket = new Socket();
  69. }
  70. }
  71. /**
  72. * Submit the POST request with the specified parameters.
  73. *
  74. * @param RequestParameters $params Request parameters
  75. * @return string Body of the reCAPTCHA response
  76. */
  77. public function submit(RequestParameters $params)
  78. {
  79. $errno = 0;
  80. $errstr = '';
  81. if ($this->socket->fsockopen('ssl://' . self::RECAPTCHA_HOST, 443, $errno, $errstr, 30) !== false) {
  82. $content = $params->toQueryString();
  83. $request = "POST " . self::SITE_VERIFY_PATH . " HTTP/1.1\r\n";
  84. $request .= "Host: " . self::RECAPTCHA_HOST . "\r\n";
  85. $request .= "Content-Type: application/x-www-form-urlencoded\r\n";
  86. $request .= "Content-length: " . strlen($content) . "\r\n";
  87. $request .= "Connection: close\r\n\r\n";
  88. $request .= $content . "\r\n\r\n";
  89. $this->socket->fwrite($request);
  90. $response = '';
  91. while (!$this->socket->feof()) {
  92. $response .= $this->socket->fgets(4096);
  93. }
  94. $this->socket->fclose();
  95. if (0 === strpos($response, 'HTTP/1.1 200 OK')) {
  96. $parts = preg_split("#\n\s*\n#Uis", $response);
  97. return $parts[1];
  98. }
  99. return self::BAD_RESPONSE;
  100. }
  101. return self::BAD_REQUEST;
  102. }
  103. }