1<?php 2 3namespace MaxMind\WebService\Http; 4 5use MaxMind\Exception\HttpException; 6 7/** 8 * This class is for internal use only. Semantic versioning does not not apply. 9 * 10 * @internal 11 */ 12class CurlRequest implements Request 13{ 14 private $url; 15 private $options; 16 17 /** 18 * @param $url 19 * @param $options 20 */ 21 public function __construct($url, $options) 22 { 23 $this->url = $url; 24 $this->options = $options; 25 } 26 27 /** 28 * @param $body 29 * 30 * @return array 31 */ 32 public function post($body) 33 { 34 $curl = $this->createCurl(); 35 36 curl_setopt($curl, CURLOPT_POST, true); 37 curl_setopt($curl, CURLOPT_POSTFIELDS, $body); 38 39 return $this->execute($curl); 40 } 41 42 public function get() 43 { 44 $curl = $this->createCurl(); 45 46 curl_setopt($curl, CURLOPT_HTTPGET, true); 47 48 return $this->execute($curl); 49 } 50 51 /** 52 * @return resource 53 */ 54 private function createCurl() 55 { 56 $curl = curl_init($this->url); 57 58 if (!empty($this->options['caBundle'])) { 59 $opts[CURLOPT_CAINFO] = $this->options['caBundle']; 60 } 61 $opts[CURLOPT_SSL_VERIFYHOST] = 2; 62 $opts[CURLOPT_FOLLOWLOCATION] = false; 63 $opts[CURLOPT_SSL_VERIFYPEER] = true; 64 $opts[CURLOPT_RETURNTRANSFER] = true; 65 66 $opts[CURLOPT_HTTPHEADER] = $this->options['headers']; 67 $opts[CURLOPT_USERAGENT] = $this->options['userAgent']; 68 $opts[CURLOPT_PROXY] = $this->options['proxy']; 69 70 // The defined()s are here as the *_MS opts are not available on older 71 // cURL versions 72 $connectTimeout = $this->options['connectTimeout']; 73 if (defined('CURLOPT_CONNECTTIMEOUT_MS')) { 74 $opts[CURLOPT_CONNECTTIMEOUT_MS] = ceil($connectTimeout * 1000); 75 } else { 76 $opts[CURLOPT_CONNECTTIMEOUT] = ceil($connectTimeout); 77 } 78 79 $timeout = $this->options['timeout']; 80 if (defined('CURLOPT_TIMEOUT_MS')) { 81 $opts[CURLOPT_TIMEOUT_MS] = ceil($timeout * 1000); 82 } else { 83 $opts[CURLOPT_TIMEOUT] = ceil($timeout); 84 } 85 86 curl_setopt_array($curl, $opts); 87 88 return $curl; 89 } 90 91 private function execute($curl) 92 { 93 $body = curl_exec($curl); 94 if ($errno = curl_errno($curl)) { 95 $errorMessage = curl_error($curl); 96 97 throw new HttpException( 98 "cURL error ({$errno}): {$errorMessage}", 99 0, 100 $this->url 101 ); 102 } 103 104 $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); 105 $contentType = curl_getinfo($curl, CURLINFO_CONTENT_TYPE); 106 curl_close($curl); 107 108 return [$statusCode, $contentType, $body]; 109 } 110} 111